diff options
90 files changed, 223 insertions, 103 deletions
diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h index 4f0aa07130..407ee70ceb 100644 --- a/include/llvm/DIBuilder.h +++ b/include/llvm/DIBuilder.h @@ -37,11 +37,13 @@ namespace llvm { class DIType; class DIArray; class DIGlobalVariable; + class DIImportedModule; class DINameSpace; class DIVariable; class DISubrange; class DILexicalBlockFile; class DILexicalBlock; + class DIScope; class DISubprogram; class DITemplateTypeParameter; class DITemplateValueParameter; @@ -57,6 +59,7 @@ namespace llvm { MDNode *TempRetainTypes; MDNode *TempSubprograms; MDNode *TempGVs; + MDNode *TempImportedModules; Function *DeclareFn; // llvm.dbg.declare Function *ValueFn; // llvm.dbg.value @@ -65,6 +68,7 @@ namespace llvm { SmallVector<Value *, 4> AllRetainTypes; SmallVector<Value *, 4> AllSubprograms; SmallVector<Value *, 4> AllGVs; + SmallVector<Value *, 4> AllImportedModules; DIBuilder(const DIBuilder &) LLVM_DELETED_FUNCTION; void operator=(const DIBuilder &) LLVM_DELETED_FUNCTION; @@ -566,6 +570,13 @@ namespace llvm { DILexicalBlock createLexicalBlock(DIDescriptor Scope, DIFile File, unsigned Line, unsigned Col); + /// \brief Create a descriptor for an imported module. + /// @param Context The scope this module is imported into + /// @param NS The namespace being imported here + /// @param LineNumber Line number + DIImportedModule createImportedModule(DIScope Context, DINameSpace NS, + unsigned Line); + /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. /// @param Storage llvm::Value of the variable /// @param VarInfo Variable's debug info descriptor. diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h index 15f91870a5..3737d2aa26 100644 --- a/include/llvm/DebugInfo.h +++ b/include/llvm/DebugInfo.h @@ -125,6 +125,7 @@ namespace llvm { bool isTemplateTypeParameter() const; bool isTemplateValueParameter() const; bool isObjCProperty() const; + bool isImportedModule() const; /// print - print descriptor. void print(raw_ostream &OS) const; @@ -199,8 +200,9 @@ namespace llvm { DIArray getRetainedTypes() const; DIArray getSubprograms() const; DIArray getGlobalVariables() const; + DIArray getImportedModules() const; - StringRef getSplitDebugFilename() const { return getStringField(11); } + StringRef getSplitDebugFilename() const { return getStringField(12); } /// Verify - Verify that a compile unit is well formed. bool Verify() const; @@ -678,6 +680,18 @@ namespace llvm { bool Verify() const; }; + /// \brief An imported module (C++ using directive or similar). + class DIImportedModule : public DIDescriptor { + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + public: + explicit DIImportedModule(const MDNode *N) : DIDescriptor(N) { } + DIScope getContext() const { return getFieldAs<DIScope>(1); } + DINameSpace getNameSpace() const { return getFieldAs<DINameSpace>(2); } + unsigned getLineNumber() const { return getUnsignedField(3); } + bool Verify() const; + }; + /// getDISubprogram - Find subprogram that is enclosing this scope. DISubprogram getDISubprogram(const MDNode *Scope); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 762c475c8e..c3f475178b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -763,6 +763,23 @@ void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU, TheCU->addGlobalName(SP.getName(), SubprogramDie); } +void DwarfDebug::constructImportedModuleDIE(CompileUnit *TheCU, + const MDNode *N) { + DIImportedModule Module(N); + if (!Module.Verify()) + return; + DIE *IMDie = new DIE(dwarf::DW_TAG_imported_module); + TheCU->insertDIE(Module, IMDie); + DIE *NSDie = TheCU->getOrCreateNameSpace(Module.getNameSpace()); + unsigned FileID = getOrCreateSourceID(Module.getContext().getFilename(), + Module.getContext().getDirectory(), + TheCU->getUniqueID()); + TheCU->addUInt(IMDie, dwarf::DW_AT_decl_file, 0, FileID); + TheCU->addUInt(IMDie, dwarf::DW_AT_decl_line, 0, Module.getLineNumber()); + TheCU->addDIEEntry(IMDie, dwarf::DW_AT_import, dwarf::DW_FORM_ref4, NSDie); + TheCU->addToContextOwner(IMDie, Module.getContext()); +} + // Emit all Dwarf sections that should come prior to the content. Create // global DIEs and emit initial debug info sections. This is invoked by // the target AsmPrinter. @@ -796,6 +813,11 @@ void DwarfDebug::beginModule() { DIArray RetainedTypes = CUNode.getRetainedTypes(); for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) CU->getOrCreateTypeDIE(RetainedTypes.getElement(i)); + // Emit imported_modules last so that the relevant context is already + // available. + DIArray ImportedModules = CUNode.getImportedModules(); + for (unsigned i = 0, e = ImportedModules.getNumElements(); i != e; ++i) + constructImportedModuleDIE(CU, ImportedModules.getElement(i)); // If we're splitting the dwarf out now that we've got the entire // CU then construct a skeleton CU based upon it. if (useSplitDwarf()) { diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 9a38256d8e..1eb7e3ecea 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -555,6 +555,9 @@ private: /// \brief Construct subprogram DIE. void constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N); + /// \brief Construct import_module DIE. + void constructImportedModuleDIE(CompileUnit *TheCU, const MDNode *N); + /// \brief Register a source line with debug info. Returns the unique /// label that was emitted and which provides correspondence to the /// source line list. diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 9d6e840729..2e981a5d68 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -61,6 +61,9 @@ void DIBuilder::finalize() { DIArray GVs = getOrCreateArray(AllGVs); DIType(TempGVs).replaceAllUsesWith(GVs); + + DIArray IMs = getOrCreateArray(AllImportedModules); + DIType(TempImportedModules).replaceAllUsesWith(IMs); } /// getNonCompileUnitScope - If N is compile unit return NULL otherwise return @@ -101,6 +104,8 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, TempGVs = MDNode::getTemporary(VMContext, TElts); + TempImportedModules = MDNode::getTemporary(VMContext, TElts); + Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit), createFilePathPair(VMContext, Filename, Directory), @@ -113,6 +118,7 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, TempRetainTypes, TempSubprograms, TempGVs, + TempImportedModules, MDString::get(VMContext, SplitName) }; TheCU = DICompileUnit(MDNode::get(VMContext, Elts)); @@ -122,6 +128,21 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, NMD->addOperand(TheCU); } +DIImportedModule DIBuilder::createImportedModule(DIScope Context, + DINameSpace NS, + unsigned Line) { + Value *Elts[] = { + GetTagConstant(VMContext, dwarf::DW_TAG_imported_module), + Context, + NS, + ConstantInt::get(Type::getInt32Ty(VMContext), Line), + }; + DIImportedModule M(MDNode::get(VMContext, Elts)); + assert(M.Verify() && "Imported module should be valid"); + AllImportedModules.push_back(M); + return M; +} + /// createFile - Create a file descriptor to hold debugging information /// for a file. DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) { diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index 10beb69824..ec83dcaf52 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -64,7 +64,8 @@ bool DIDescriptor::Verify() const { DISubrange(DbgNode).Verify() || DIEnumerator(DbgNode).Verify() || DIObjCProperty(DbgNode).Verify() || DITemplateTypeParameter(DbgNode).Verify() || - DITemplateValueParameter(DbgNode).Verify()); + DITemplateValueParameter(DbgNode).Verify() || + DIImportedModule(DbgNode).Verify()); } static Value *getField(const MDNode *DbgNode, unsigned Elt) { @@ -336,6 +337,12 @@ bool DIDescriptor::isEnumerator() const { bool DIDescriptor::isObjCProperty() const { return DbgNode && getTag() == dwarf::DW_TAG_APPLE_property; } + +/// \brief Return true if the specified tag is DW_TAG_imported_module. +bool DIDescriptor::isImportedModule() const { + return DbgNode && getTag() == dwarf::DW_TAG_imported_module; +} + //===------------------- |