|
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"
|
@@ -1645,9 +1647,72 @@ void RemoveExplicitModules(std::vector<std::string> &args) {
|
1645 | 1647 |
|
1646 | 1648 | } // namespace
|
1647 | 1649 |
|
1648 |
| -void SwiftASTContext::AddExtraClangArgs(const std::vector<std::string> &ExtraArgs) { |
| 1650 | +/// LLDB wrapper for `clang::driver::applyOverrideOptions` (which implements |
| 1651 | +/// CCC_OVERRIDE_OPTIONS behavior). |
| 1652 | +static void applyOverrideOptions(std::vector<std::string> &args, |
| 1653 | + llvm::StringRef overrideOpts) { |
| 1654 | + if (overrideOpts.empty()) |
| 1655 | + return; |
| 1656 | + |
| 1657 | + // Convert input args to the type required by applyOverrideOptions. |
| 1658 | + llvm::SmallVector<const char *, 64> raw_args; |
| 1659 | + // Add placeholder clang executable, which applyOverrideOptions expects to be |
| 1660 | + // the first argument. |
| 1661 | + raw_args.push_back("clang"); |
| 1662 | + for (const std::string &arg : args) |
| 1663 | + raw_args.push_back(arg.data()); |
| 1664 | + |
| 1665 | + // LLVM stream backed by a callback. This is used to redirect |
| 1666 | + // applyOverrideOptions logging to LLDB. |
| 1667 | + struct CallbackStream : public llvm::raw_ostream { |
| 1668 | + using callback_t = std::function<void(const char *, size_t)>; |
| 1669 | + callback_t m_callback; |
| 1670 | + uint64_t m_pos = 0; |
| 1671 | + |
| 1672 | + CallbackStream(callback_t callback) : m_callback(callback) {} |
| 1673 | + ~CallbackStream() override { flush(); } |
| 1674 | + |
| 1675 | + void write_impl(const char *Ptr, size_t Size) override { |
| 1676 | + m_callback(Ptr, Size); |
| 1677 | + m_pos += Size; |
| 1678 | + } |
| 1679 | + |
| 1680 | + uint64_t current_pos() const override { return m_pos; } |
| 1681 | + }; |
| 1682 | + |
| 1683 | + // Perform the override operations. |
| 1684 | + llvm::StringSet<> savedStrings; |
| 1685 | + auto *log = GetLog(LLDBLog::Expressions); |
| 1686 | + CallbackStream log_stream{[log](const char *Ptr, size_t Size) { |
| 1687 | + if (!log) |
| 1688 | + return; |
| 1689 | + if (Ptr[Size] == '\n') |
| 1690 | + // Skip the newline because LLDB logging writes a newline. |
| 1691 | + Size--; |
| 1692 | + log->PutString({Ptr, Size}); |
| 1693 | + }}; |
| 1694 | + |
| 1695 | + clang::driver::applyOverrideOptions(raw_args, overrideOpts.data(), |
| 1696 | + savedStrings, &log_stream); |
| 1697 | + |
| 1698 | + // Delete the placeholder "clang" executable argument. |
| 1699 | + raw_args.erase(raw_args.begin()); |
| 1700 | + |
| 1701 | + // Copy `raw_args` into a new args vector. |
| 1702 | + std::vector<std::string> new_args; |
| 1703 | + for (const char *arg : raw_args) |
| 1704 | + new_args.emplace_back(arg); |
| 1705 | + |
| 1706 | + // Only now that `raw_args` has been copied into `new_args`, can `args` be |
| 1707 | + // overwritten. This is because `args` owns the data pointed to by `raw_args`. |
| 1708 | + args = new_args; |
| 1709 | +} |
| 1710 | + |
| 1711 | +void SwiftASTContext::AddExtraClangArgs( |
| 1712 | + const std::vector<std::string> &ExtraArgs, StringRef overrideOpts) { |
1649 | 1713 | swift::ClangImporterOptions &importer_options = GetClangImporterOptions();
|
1650 | 1714 | AddExtraClangArgs(ExtraArgs, importer_options.ExtraArgs);
|
| 1715 | + applyOverrideOptions(importer_options.ExtraArgs, overrideOpts); |
1651 | 1716 | if (HasNonexistentExplicitModule(importer_options.ExtraArgs))
|
1652 | 1717 | RemoveExplicitModules(importer_options.ExtraArgs);
|
1653 | 1718 | }
|
@@ -2075,7 +2140,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
|
2075 | 2140 | // Apply the working directory to all relative paths.
|
2076 | 2141 | std::vector<std::string> DeserializedArgs = swift_ast_sp->GetClangArguments();
|
2077 | 2142 | swift_ast_sp->GetClangImporterOptions().ExtraArgs.clear();
|
2078 |
| - swift_ast_sp->AddExtraClangArgs(DeserializedArgs); |
| 2143 | + StringRef overrideOpts = target ? target->GetSwiftClangOverrideOptions() : ""; |
| 2144 | + swift_ast_sp->AddExtraClangArgs(DeserializedArgs, overrideOpts); |
2079 | 2145 | if (target)
|
2080 | 2146 | swift_ast_sp->AddUserClangArgs(*target);
|
2081 | 2147 | else
|
@@ -2565,7 +2631,8 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
|
2565 | 2631 | use_all_compiler_flags, module_filter, target, triple,
|
2566 | 2632 | plugin_search_options, module_search_paths,
|
2567 | 2633 | framework_search_paths, extra_clang_args);
|
2568 |
| - swift_ast_sp->AddExtraClangArgs(extra_clang_args); |
| 2634 | + swift_ast_sp->AddExtraClangArgs(extra_clang_args, |
| 2635 | + target.GetSwiftClangOverrideOptions()); |
2569 | 2636 | }
|
2570 | 2637 |
|
2571 | 2638 | for (const FileSpec &path : target.GetSwiftModuleSearchPaths())
|
@@ -2879,7 +2946,8 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
|
2879 | 2946 | use_all_compiler_flags, module_filter, target, triple,
|
2880 | 2947 | plugin_search_options, module_search_paths,
|
2881 | 2948 | framework_search_paths, extra_clang_args);
|
2882 |
| - swift_ast_sp->AddExtraClangArgs(extra_clang_args); |
| 2949 | + swift_ast_sp->AddExtraClangArgs(extra_clang_args, |
| 2950 | + target.GetSwiftClangOverrideOptions()); |
2883 | 2951 | }
|
2884 | 2952 |
|
2885 | 2953 | // Now fold any extra options we were passed. This has to be done
|
|
0 commit comments