diff options
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 54 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.h | 10 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 2 |
3 files changed, 66 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; |

