Add debug info support for Swift/Clang APINotes.
In order for dsymutil to collect .apinotes files (which capture
attributes such as nullability, Swift import names, and availability),
I want to propose adding an apinotes: field to DIModule that gets
translated into a DW_AT_LLVM_apinotes (path) nested inside
DW_TAG_module. This will be primarily used by LLDB to indirectly
extract the Swift names of Clang declarations that were deserialized
from DWARF.
<rdar://problem/59514626>
Differential Revision: https://reviews.llvm.org/D75585
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index ea603a6..733fc10 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2061,6 +2061,7 @@
Printer.printString("name", N->getName());
Printer.printString("configMacros", N->getConfigurationMacros());
Printer.printString("includePath", N->getIncludePath());
+ Printer.printString("apinotes", N->getAPINotesFile());
Out << ")";
}
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 2fcdcd9..b6446f4 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -831,9 +831,10 @@
DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name,
StringRef ConfigurationMacros,
- StringRef IncludePath) {
+ StringRef IncludePath,
+ StringRef APINotesFile) {
return DIModule::get(VMContext, getNonCompileUnitScope(Scope), Name,
- ConfigurationMacros, IncludePath);
+ ConfigurationMacros, IncludePath, APINotesFile);
}
DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope,
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index f893ea9..aaa8443 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -791,11 +791,13 @@
LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope,
const char *Name, size_t NameLen,
const char *ConfigMacros, size_t ConfigMacrosLen,
- const char *IncludePath, size_t IncludePathLen) {
+ const char *IncludePath, size_t IncludePathLen,
+ const char *APINotesFile, size_t APINotesFileLen) {
return wrap(unwrap(Builder)->createModule(
unwrapDI<DIScope>(ParentScope), StringRef(Name, NameLen),
StringRef(ConfigMacros, ConfigMacrosLen),
- StringRef(IncludePath, IncludePathLen)));
+ StringRef(IncludePath, IncludePathLen),
+ StringRef(APINotesFile, APINotesFileLen)));
}
LLVMMetadataRef LLVMDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder,
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 48e38db..0c0ea50 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -717,12 +717,13 @@
DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope,
MDString *Name, MDString *ConfigurationMacros,
- MDString *IncludePath, StorageType Storage,
- bool ShouldCreate) {
+ MDString *IncludePath, MDString *APINotesFile,
+ StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
- DEFINE_GETIMPL_LOOKUP(DIModule,
- (Scope, Name, ConfigurationMacros, IncludePath));
- Metadata *Ops[] = {Scope, Name, ConfigurationMacros, IncludePath};
+ DEFINE_GETIMPL_LOOKUP(
+ DIModule, (Scope, Name, ConfigurationMacros, IncludePath, APINotesFile));
+ Metadata *Ops[] = {Scope, Name, ConfigurationMacros, IncludePath,
+ APINotesFile};
DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIModule, Ops);
}
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 7f324b1..e136bd5 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -819,20 +819,23 @@
MDString *Name;
MDString *ConfigurationMacros;
MDString *IncludePath;
+ MDString *APINotesFile;
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
- MDString *IncludePath)
+ MDString *IncludePath, MDString *APINotesFile)
: Scope(Scope), Name(Name), ConfigurationMacros(ConfigurationMacros),
- IncludePath(IncludePath) {}
+ IncludePath(IncludePath), APINotesFile(APINotesFile) {}
MDNodeKeyImpl(const DIModule *N)
: Scope(N->getRawScope()), Name(N->getRawName()),
ConfigurationMacros(N->getRawConfigurationMacros()),
- IncludePath(N->getRawIncludePath()) {}
+ IncludePath(N->getRawIncludePath()),
+ APINotesFile(N->getRawAPINotesFile()) {}
bool isKeyOf(const DIModule *RHS) const {
return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
ConfigurationMacros == RHS->getRawConfigurationMacros() &&
- IncludePath == RHS->getRawIncludePath();
+ IncludePath == RHS->getRawIncludePath() &&
+ APINotesFile == RHS->getRawAPINotesFile();
}
unsigned getHashValue() const {