|
15 | 15 | #include "Plugins/TypeSystem/Swift/StoringDiagnosticConsumer.h"
|
16 | 16 | #include "Plugins/ExpressionParser/Swift/SwiftPersistentExpressionState.h"
|
17 | 17 |
|
| 18 | +#include "lldb/Utility/Log.h" |
18 | 19 | #include "swift/AST/ASTContext.h"
|
19 | 20 | #include "swift/AST/ASTDemangler.h"
|
20 | 21 | #include "swift/AST/ASTMangler.h"
|
|
58 | 59 |
|
59 | 60 | #include "llvm/ADT/ArrayRef.h"
|
60 | 61 | #include "llvm/ADT/STLExtras.h"
|
| 62 | +#include "llvm/ADT/SmallVector.h" |
61 | 63 | #include "llvm/ADT/StringRef.h"
|
62 | 64 | #include "llvm/ADT/StringSet.h"
|
63 | 65 | #include "llvm/CodeGen/TargetSubtargetInfo.h"
|
@@ -1672,9 +1674,72 @@ void RemoveExplicitModules(std::vector<std::string> &args) {
|
1672 | 1674 |
|
1673 | 1675 | } // namespace
|
1674 | 1676 |
|
1675 |
| -void SwiftASTContext::AddExtraClangArgs(const std::vector<std::string> &ExtraArgs) { |
| 1677 | +/// LLDB wrapper for `clang::driver::applyOverrideOptions` (which implements |
| 1678 | +/// CCC_OVERRIDE_OPTIONS behavior). |
| 1679 | +static void applyOverrideOptions(std::vector<std::string> &args, |
| 1680 | + llvm::StringRef overrideOpts) { |
| 1681 | + if (overrideOpts.empty()) |
| 1682 | + return; |
| 1683 | + |
| 1684 | + // Convert input args to the type required by applyOverrideOptions. |
| 1685 | + llvm::SmallVector<const char *, 64> raw_args; |
| 1686 | + // Add placeholder clang executable, which applyOverrideOptions expects to be |
| 1687 | + // the first argument. |
| 1688 | + raw_args.push_back("clang"); |
| 1689 | + for (const std::string &arg : args) |
| 1690 | + raw_args.push_back(arg.data()); |
| 1691 | + |
| 1692 | + /// LLVM stream backed by a callback. This is used to redirect |
| 1693 | + /// applyOverrideOptions logging to LLDB. |
| 1694 | + struct CallbackStream : public llvm::raw_ostream { |
| 1695 | + using callback_t = std::function<void(const char *, size_t)>; |
| 1696 | + callback_t m_callback; |
| 1697 | + uint64_t m_pos = 0; |
| 1698 | + |
| 1699 | + CallbackStream(callback_t callback) : m_callback(callback) {} |
| 1700 | + ~CallbackStream() override { flush(); } |
| 1701 | + |
| 1702 | + void write_impl(const char *Ptr, size_t Size) override { |
| 1703 | + m_callback(Ptr, Size); |
| 1704 | + m_pos += Size; |
| 1705 | + } |
| 1706 | + |
| 1707 | + uint64_t current_pos() const override { return m_pos; } |
| 1708 | + }; |
| 1709 | + |
| 1710 | + // Perform the override operations. |
| 1711 | + llvm::StringSet<> savedStrings; |
| 1712 | + auto *log = GetLog(LLDBLog::Types); |
| 1713 | + CallbackStream log_stream{[log](const char *Ptr, size_t Size) { |
| 1714 | + if (!log) |
| 1715 | + return; |
| 1716 | + if (Ptr[Size] == '\n') |
| 1717 | + // Skip the newline because LLDB logging writes a newline. |
| 1718 | + Size--; |
| 1719 | + log->PutString({Ptr, Size}); |
| 1720 | + }}; |
| 1721 | + |
| 1722 | + clang::driver::applyOverrideOptions(raw_args, overrideOpts.data(), |
| 1723 | + savedStrings, &log_stream); |
| 1724 | + |
| 1725 | + // Delete the placeholder "clang" executable argument. |
| 1726 | + raw_args.erase(raw_args.begin()); |
| 1727 | + |
| 1728 | + // Copy `raw_args` into a new args vector. |
| 1729 | + std::vector<std::string> new_args; |
| 1730 | + for (const char *arg : raw_args) |
| 1731 | + new_args.emplace_back(arg); |
| 1732 | + |
| 1733 | + // Only now that `raw_args` has been copied into `new_args`, it's safe to |
| 1734 | + // overwrite `args` (which owns the data pointed to by `raw_args`). |
| 1735 | + args = new_args; |
| 1736 | +} |
| 1737 | + |
| 1738 | +void SwiftASTContext::AddExtraClangArgs( |
| 1739 | + const std::vector<std::string> &ExtraArgs, StringRef overrideOpts) { |
1676 | 1740 | swift::ClangImporterOptions &importer_options = GetClangImporterOptions();
|
1677 | 1741 | AddExtraClangArgs(ExtraArgs, importer_options.ExtraArgs);
|
| 1742 | + applyOverrideOptions(importer_options.ExtraArgs, overrideOpts); |
1678 | 1743 | if (HasNonexistentExplicitModule(importer_options.ExtraArgs))
|
1679 | 1744 | RemoveExplicitModules(importer_options.ExtraArgs);
|
1680 | 1745 | }
|
@@ -2105,7 +2170,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
|
2105 | 2170 | // Apply the working directory to all relative paths.
|
2106 | 2171 | std::vector<std::string> DeserializedArgs = swift_ast_sp->GetClangArguments();
|
2107 | 2172 | swift_ast_sp->GetClangImporterOptions().ExtraArgs.clear();
|
2108 |
| - swift_ast_sp->AddExtraClangArgs(DeserializedArgs); |
| 2173 | + StringRef overrideOpts = target ? target->GetSwiftClangOverrideOptions() : ""; |
| 2174 | + swift_ast_sp->AddExtraClangArgs(DeserializedArgs, overrideOpts); |
2109 | 2175 | if (target)
|
2110 | 2176 | swift_ast_sp->AddUserClangArgs(*target);
|
2111 | 2177 | else
|
@@ -2628,7 +2694,8 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
|
2628 | 2694 | use_all_compiler_flags, module_filter, target, triple,
|
2629 | 2695 | plugin_search_options, module_search_paths,
|
2630 | 2696 | framework_search_paths, extra_clang_args);
|
2631 |
| - swift_ast_sp->AddExtraClangArgs(extra_clang_args); |
| 2697 | + swift_ast_sp->AddExtraClangArgs(extra_clang_args, |
| 2698 | + target.GetSwiftClangOverrideOptions()); |
2632 | 2699 | }
|
2633 | 2700 |
|
2634 | 2701 | for (const FileSpec &path : target.GetSwiftModuleSearchPaths())
|
@@ -2940,7 +3007,8 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
|
2940 | 3007 | use_all_compiler_flags, module_filter, target, triple,
|
2941 | 3008 | plugin_search_options, module_search_paths,
|
2942 | 3009 | framework_search_paths, extra_clang_args);
|
2943 |
| - swift_ast_sp->AddExtraClangArgs(extra_clang_args); |
| 3010 | + swift_ast_sp->AddExtraClangArgs(extra_clang_args, |
| 3011 | + target.GetSwiftClangOverrideOptions()); |
2944 | 3012 | }
|
2945 | 3013 |
|
2946 | 3014 | // Now fold any extra options we were passed. This has to be done
|
|
0 commit comments