Represent Clang macro definitions from -Xcc options in the debug info.

Currently -Xcc options are serialized in Swift modules, but they are
not saved as attributes to the DW_TAG_module representing the imported
clang module. This patch saves all *user-specified* -D macros there,
but it does not save any macros that are added by the ClangImporter
itself.

<rdar://problem/31990102>
This commit is contained in:
Adrian Prantl
2017-05-09 16:41:56 -07:00
parent 62e80281f2
commit e2784cbb87
4 changed files with 40 additions and 5 deletions

View File

@@ -76,6 +76,9 @@ public:
/// The command line string that is to be stored in the DWARF debug info. /// The command line string that is to be stored in the DWARF debug info.
std::string DWARFDebugFlags; std::string DWARFDebugFlags;
/// List of -Xcc -D macro definitions.
std::vector<std::string> ClangDefines;
/// The libraries and frameworks specified on the command line. /// The libraries and frameworks specified on the command line.
SmallVector<LinkLibrary, 4> LinkLibraries; SmallVector<LinkLibrary, 4> LinkLibraries;

View File

@@ -1470,6 +1470,14 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
} }
} }
for (const Arg *A : make_range(Args.filtered_begin(OPT_Xcc),
Args.filtered_end())) {
StringRef Opt = A->getValue();
if (Opt.startswith("-D") || Opt.startswith("-U"))
Opts.ClangDefines.push_back(Opt);
}
for (const Arg *A : make_range(Args.filtered_begin(OPT_l, OPT_framework), for (const Arg *A : make_range(Args.filtered_begin(OPT_l, OPT_framework),
Args.filtered_end())) { Args.filtered_end())) {
LibraryKind Kind; LibraryKind Kind;

View File

@@ -93,6 +93,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
llvm::BumpPtrAllocator DebugInfoNames; llvm::BumpPtrAllocator DebugInfoNames;
StringRef CWDName; /// The current working directory. StringRef CWDName; /// The current working directory.
SmallString<0> ConfigMacros; /// User-provided -D macro definitions.
llvm::DICompileUnit *TheCU = nullptr; /// The current compilation unit. llvm::DICompileUnit *TheCU = nullptr; /// The current compilation unit.
llvm::DIFile *MainFile = nullptr; /// The main file. llvm::DIFile *MainFile = nullptr; /// The main file.
llvm::DIModule *MainModule = nullptr; /// The current module. llvm::DIModule *MainModule = nullptr; /// The current module.
@@ -582,13 +583,13 @@ private:
} }
llvm::DIModule *getOrCreateModule(StringRef Key, llvm::DIScope *Parent, llvm::DIModule *getOrCreateModule(StringRef Key, llvm::DIScope *Parent,
StringRef Name, StringRef IncludePath) { StringRef Name, StringRef IncludePath,
StringRef ConfigMacros = StringRef()) {
// Look in the cache first. // Look in the cache first.
auto Val = DIModuleCache.find(Key); auto Val = DIModuleCache.find(Key);
if (Val != DIModuleCache.end()) if (Val != DIModuleCache.end())
return cast<llvm::DIModule>(Val->second); return cast<llvm::DIModule>(Val->second);
StringRef ConfigMacros;
StringRef Sysroot = IGM.Context.SearchPathOpts.SDKPath; StringRef Sysroot = IGM.Context.SearchPathOpts.SDKPath;
auto M = auto M =
DBuilder.createModule(Parent, Name, ConfigMacros, IncludePath, Sysroot); DBuilder.createModule(Parent, Name, ConfigMacros, IncludePath, Sysroot);
@@ -606,11 +607,12 @@ private:
Parent = getOrCreateModule(PM); Parent = getOrCreateModule(PM);
} }
return getOrCreateModule(ClangModule->getFullModuleName(), Parent, return getOrCreateModule(ClangModule->getFullModuleName(), Parent,
Desc.getModuleName(), Desc.getPath()); Desc.getModuleName(), Desc.getPath(),
ConfigMacros);
} }
// Handle PCH. // Handle PCH.
return getOrCreateModule(Desc.getASTFile(), nullptr, Desc.getModuleName(), return getOrCreateModule(Desc.getASTFile(), nullptr, Desc.getModuleName(),
Desc.getPath()); Desc.getPath(), ConfigMacros);
}; };
TypeAliasDecl *getMetadataType() { TypeAliasDecl *getMetadataType() {
@@ -1534,6 +1536,24 @@ IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts,
MainModule = MainModule =
getOrCreateModule(Opts.ModuleName, TheCU, Opts.ModuleName, AbsMainFile); getOrCreateModule(Opts.ModuleName, TheCU, Opts.ModuleName, AbsMainFile);
DBuilder.createImportedModule(MainFile, MainModule, 1); DBuilder.createImportedModule(MainFile, MainModule, 1);
// Macro definitions that were defined by the user with "-Xcc -D" on the
// command line. This does not include any macros defined by ClangImporter.
llvm::raw_svector_ostream OS(ConfigMacros);
unsigned I = 0;
// Translate the macro definitions back into a commmand line.
for (auto &Macro : Opts.ClangDefines) {
if (++I > 1)
OS << ' ';
OS << '"';
for (char c : Macro)
switch (c) {
case '\\': OS << "\\\\"; break;
case '"': OS << "\\\""; break;
default: OS << c;
}
OS << '"';
}
} }
void IRGenDebugInfoImpl::finalize() { void IRGenDebugInfoImpl::finalize() {

View File

@@ -1,4 +1,5 @@
// RUN: %target-swift-frontend -emit-ir %s -g -I %S/Inputs -o - | %FileCheck %s // RUN: %target-swift-frontend -emit-ir %s -g -I %S/Inputs \
// RUN: -Xcc -DFOO="foo" -Xcc -UBAR -o - | %FileCheck %s
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Bar", // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Bar",
// CHECK-SAME: scope: ![[SUBMODULE:[0-9]+]] // CHECK-SAME: scope: ![[SUBMODULE:[0-9]+]]
@@ -6,6 +7,9 @@
// CHECK: ![[SUBMODULE]] = !DIModule(scope: ![[CLANGMODULE:[0-9]+]], // CHECK: ![[SUBMODULE]] = !DIModule(scope: ![[CLANGMODULE:[0-9]+]],
// CHECK-SAME: name: "SubModule", // CHECK-SAME: name: "SubModule",
// CHECK: ![[CLANGMODULE]] = !DIModule(scope: null, name: "ClangModule", // CHECK: ![[CLANGMODULE]] = !DIModule(scope: null, name: "ClangModule",
// CHECK-SAME: configMacros:
// CHECK-SAME: {{..}}-DFOO=foo{{..}}
// CHECK-SAME: {{..}}-UBAR{{..}}
// CHECK: !DIImportedEntity({{.*}}, entity: ![[SUBMODULE]], line: [[@LINE+1]]) // CHECK: !DIImportedEntity({{.*}}, entity: ![[SUBMODULE]], line: [[@LINE+1]])
import ClangModule.SubModule import ClangModule.SubModule