Skip to content

Commit b8ce84d

Browse files
Merge pull request #8682 from apple/dl/lldb-Add-setting-to-override-ClangImporter-driver-options
[lldb] Add setting to override ClangImporter driver options
2 parents 17ebaf8 + b9a9711 commit b8ce84d

File tree

8 files changed

+114
-5
lines changed

8 files changed

+114
-5
lines changed

lldb/include/lldb/Target/Target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ class TargetProperties : public Properties {
174174

175175
llvm::StringRef GetSwiftExtraClangFlags() const;
176176

177+
llvm::StringRef GetSwiftClangOverrideOptions() const;
178+
177179
bool GetSwiftReadMetadataFromFileCache() const;
178180

179181
bool GetSwiftUseReflectionSymbols() const;

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Plugins/TypeSystem/Swift/StoringDiagnosticConsumer.h"
1616
#include "Plugins/ExpressionParser/Swift/SwiftPersistentExpressionState.h"
1717

18+
#include "lldb/Utility/Log.h"
1819
#include "swift/AST/ASTContext.h"
1920
#include "swift/AST/ASTDemangler.h"
2021
#include "swift/AST/ASTMangler.h"
@@ -58,6 +59,7 @@
5859

5960
#include "llvm/ADT/ArrayRef.h"
6061
#include "llvm/ADT/STLExtras.h"
62+
#include "llvm/ADT/SmallVector.h"
6163
#include "llvm/ADT/StringRef.h"
6264
#include "llvm/ADT/StringSet.h"
6365
#include "llvm/CodeGen/TargetSubtargetInfo.h"
@@ -1672,9 +1674,72 @@ void RemoveExplicitModules(std::vector<std::string> &args) {
16721674

16731675
} // namespace
16741676

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) {
16761740
swift::ClangImporterOptions &importer_options = GetClangImporterOptions();
16771741
AddExtraClangArgs(ExtraArgs, importer_options.ExtraArgs);
1742+
applyOverrideOptions(importer_options.ExtraArgs, overrideOpts);
16781743
if (HasNonexistentExplicitModule(importer_options.ExtraArgs))
16791744
RemoveExplicitModules(importer_options.ExtraArgs);
16801745
}
@@ -2105,7 +2170,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
21052170
// Apply the working directory to all relative paths.
21062171
std::vector<std::string> DeserializedArgs = swift_ast_sp->GetClangArguments();
21072172
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);
21092175
if (target)
21102176
swift_ast_sp->AddUserClangArgs(*target);
21112177
else
@@ -2628,7 +2694,8 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
26282694
use_all_compiler_flags, module_filter, target, triple,
26292695
plugin_search_options, module_search_paths,
26302696
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());
26322699
}
26332700

26342701
for (const FileSpec &path : target.GetSwiftModuleSearchPaths())
@@ -2940,7 +3007,8 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
29403007
use_all_compiler_flags, module_filter, target, triple,
29413008
plugin_search_options, module_search_paths,
29423009
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());
29443012
}
29453013

29463014
// Now fold any extra options we were passed. This has to be done

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ class SwiftASTContext : public TypeSystemSwift {
270270

271271
/// Add a list of Clang arguments to the ClangImporter options and
272272
/// apply the working directory to any relative paths.
273-
void AddExtraClangArgs(const std::vector<std::string> &ExtraArgs);
273+
void AddExtraClangArgs(const std::vector<std::string> &ExtraArgs,
274+
llvm::StringRef overrideOpts = "");
274275
static void AddExtraClangArgs(const std::vector<std::string>& source,
275276
std::vector<std::string>& dest);
276277
static std::string GetPluginServer(llvm::StringRef plugin_library_path);

lldb/source/Target/Target.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5225,6 +5225,11 @@ llvm::StringRef TargetProperties::GetSwiftExtraClangFlags() const {
52255225
return GetPropertyAtIndexAs<llvm::StringRef>(idx, "");
52265226
}
52275227

5228+
llvm::StringRef TargetProperties::GetSwiftClangOverrideOptions() const {
5229+
const uint32_t idx = ePropertySwiftClangOverrideOptions;
5230+
return GetPropertyAtIndexAs<llvm::StringRef>(idx, "");
5231+
}
5232+
52285233
FileSpecList TargetProperties::GetClangModuleSearchPaths() {
52295234
const uint32_t idx = ePropertyClangModuleSearchPaths;
52305235
return GetPropertyAtIndexAs<FileSpecList>(idx, {});

lldb/source/Target/TargetProperties.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,9 @@ let Definition = "target" in {
219219
def SwiftExtraClangFlags: Property<"swift-extra-clang-flags", "String">,
220220
DefaultStringValue<"">,
221221
Desc<"Additional -Xcc flags to be passed to the Swift ClangImporter.">;
222+
def SwiftClangOverrideOptions: Property<"swift-clang-override-options", "String">,
223+
DefaultStringValue<"">,
224+
Desc<"Specify CCC_OVERRIDE_OPTIONS for ClangImporter flags.">;
222225
def SwiftAutoImportFrameworks : Property<"swift-auto-import-frameworks", "Boolean">,
223226
DefaultFalse,
224227
Desc<"Automatically import all frameworks and dynamic libraries that are autolinked by Swift modules in the target.">;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFTFLAGS_EXTRAS = -Xcc -DDELETEME=1
3+
4+
include Makefile.rules
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbtest as lldbtest
4+
import lldbsuite.test.lldbutil as lldbutil
5+
6+
7+
class TestCase(lldbtest.TestBase):
8+
@swiftTest
9+
@skipUnlessFoundation
10+
def test(self):
11+
"""Check that ClangImporter options can be overridden."""
12+
self.build()
13+
14+
log = self.getBuildArtifact("lldb.log")
15+
self.runCmd(f"log enable lldb types -f '{log}'")
16+
self.runCmd("settings set target.swift-clang-override-options x-DDELETEME=1")
17+
18+
lldbutil.run_to_name_breakpoint(self, "main", bkpt_module="a.out")
19+
self.expect("expression 1")
20+
21+
self.filecheck(f"platform shell cat {log}", __file__)
22+
# CHECK: CCC_OVERRIDE_OPTIONS: x-DDELETEME=1
23+
# CHECK: Deleting argument -DDELETEME=1
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Foundation
2+
3+
// empty main

0 commit comments

Comments
 (0)