summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp54
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.h10
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--clang/test/Modules/Inputs/DebugModule.h1
-rw-r--r--clang/test/Modules/Inputs/module.map5
-rw-r--r--clang/test/Modules/debug-info-moduleimport.m7
6 files changed, 79 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index a139ce0e073..8daf8af4e18 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -27,6 +27,8 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Constants.h"
@@ -1661,6 +1663,49 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
return CreateTypeDefinition(Ty, Unit);
}
+llvm::DIModule *
+CGDebugInfo::getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod) {
+ llvm::DIModule *ModuleRef = nullptr;
+ auto it = ModuleRefCache.find(Mod.Signature);
+ if (it != ModuleRefCache.end())
+ ModuleRef = it->second;
+ else {
+ // Macro definitions that were defined with "-D" on the command line.
+ SmallString<128> ConfigMacros;
+ {
+ llvm::raw_svector_ostream OS(ConfigMacros);
+ const auto &PPOpts = CGM.getPreprocessorOpts();
+ unsigned I = 0;
+ // Translate the macro definitions back into a commmand line.
+ for (auto &M : PPOpts.Macros) {
+ if (++I > 1)
+ OS << " ";
+ const std::string &Macro = M.first;
+ bool Undef = M.second;
+ OS << "\"-" << (Undef ? 'U' : 'D');
+ for (char c : Macro)
+ switch (c) {
+ case '\\' : OS << "\\\\"; break;
+ case '"' : OS << "\\\""; break;
+ default: OS << c;
+ }
+ OS << '\"';
+ }
+ }
+ llvm::DIBuilder DIB(CGM.getModule());
+ auto *CU = DIB.createCompileUnit(
+ TheCU->getSourceLanguage(), internString(Mod.ModuleName),
+ internString(Mod.Path), TheCU->getProducer(), true, StringRef(), 0,
+ internString(Mod.ASTFile), llvm::DIBuilder::FullDebug, Mod.Signature);
+ ModuleRef = DIB.createModule(
+ CU, Mod.ModuleName, ConfigMacros, internString(Mod.Path),
+ internString(CGM.getHeaderSearchOpts().Sysroot));
+ DIB.finalize();
+ ModuleRefCache.insert(std::make_pair(Mod.Signature, ModuleRef));
+ }
+ return ModuleRef;
+}
+
llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
llvm::DIFile *Unit) {
ObjCInterfaceDecl *ID = Ty->getDecl();
@@ -3304,6 +3349,15 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) {
getLineNumber(USD.getLocation()));
}
+void CGDebugInfo::EmitImportDecl(const ImportDecl &ID) {
+ auto *Reader = CGM.getContext().getExternalSource();
+ auto Info = Reader->getSourceDescriptor(*ID.getImportedModule());
+ DBuilder.createImportedDeclaration(
+ getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
+ getOrCreateModuleRef(Info),
+ getLineNumber(ID.getLocation()));
+}
+
llvm::DIImportedEntity *
CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo)
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 8509e0770db..10d3b0d9ab0 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -83,6 +83,9 @@ class CGDebugInfo {
/// which may change.
llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache;
+ /// \brief Cache of references to AST files such as PCHs or modules.
+ llvm::DenseMap<uint64_t, llvm::DIModule *> ModuleRefCache;
+
/// \brief list of interfaces we want to keep even if orphaned.
std::vector<void *> RetainedTypes;
@@ -289,6 +292,9 @@ public:
/// \brief Emit C++ using declaration.
void EmitUsingDecl(const UsingDecl &UD);
+ /// \brief Emit an @import declaration.
+ void EmitImportDecl(const ImportDecl &ID);
+
/// \brief Emit C++ namespace alias.
llvm::DIImportedEntity *EmitNamespaceAlias(const NamespaceAliasDecl &NA);
@@ -344,6 +350,10 @@ private:
/// necessary.
llvm::DIType *getOrCreateType(QualType Ty, llvm::DIFile *Fg);
+ /// \brief Get a reference to a clang module.
+ llvm::DIModule *
+ getOrCreateModuleRef(ExternalASTSource::ASTSourceDescriptor Mod);
+
/// \brief Get the type from the cache or create a new
/// partial type if necessary.
llvm::DIType *getOrCreateLimitedType(const RecordType *Ty, llvm::DIFile *F);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index ea09ba8d4fb..b905bd2b36b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3362,6 +3362,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
Owner->getTopLevelModule()->Name == getLangOpts().CurrentModule)
break;
}
+ if (CGDebugInfo *DI = getModuleDebugInfo())
+ DI->EmitImportDecl(*Import);
ImportedModules.insert(Import->getImportedModule());
break;
diff --git a/clang/test/Modules/Inputs/DebugModule.h b/clang/test/Modules/Inputs/DebugModule.h
new file mode 100644
index 00000000000..5612b73a8cf
--- /dev/null
+++ b/clang/test/Modules/Inputs/DebugModule.h
@@ -0,0 +1 @@
+@class F;
diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.map
index fe762f54a11..b9c8e72cfa9 100644
--- a/clang/test/Modules/Inputs/module.map
+++ b/clang/test/Modules/Inputs/module.map
@@ -327,3 +327,8 @@ module recursive2 {
module crash {
header "crash.h"
}
+
+module DebugModule {
+ header "DebugModule.h"
+}
+
diff --git a/clang/test/Modules/debug-info-moduleimport.m b/clang/test/Modules/debug-info-moduleimport.m
new file mode 100644
index 00000000000..9580af08498
--- /dev/null
+++ b/clang/test/Modules/debug-info-moduleimport.m
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -g -fmodules -DGREETING="Hello World" -UNDEBUG -fimplicit-module-maps -fmodules-cache-path=%t %s -I %S/Inputs -isysroot /tmp/.. -I %t -emit-llvm -o - | FileCheck %s
+
+// CHECK: ![[CU:.*]] = !DICompileUnit
+@import DebugModule;
+// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: ![[CU]], entity: ![[MODULE:.*]], line: 5)
+// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugModule", configMacros: "\22-DGREETING=Hello World\22 \22-UNDEBUG\22", includePath: "{{.*}}/test/Modules/Inputs", isysroot: "/tmp/..")
OpenPOWER on IntegriCloud