diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 8 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 22 |
4 files changed, 53 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 4b2b7b01f17..a03da3c452a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -364,6 +364,7 @@ bool DwarfDebug::isSubprogramContext(const MDNode *Context) { // scope then create and insert DIEs for these variables. DIE *DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit *SPCU, DISubprogram SP) { + SP = SPCU->getOdrUniqueSubprogram(resolve(SP.getContext()), SP); DIE *SPDie = SPCU->getDIE(SP); assert(SPDie && "Unable to find subprogram DIE!"); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index bd1d304b71d..baf87323178 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -353,6 +353,9 @@ class DwarfDebug : public AsmPrinterHandler { /// of in DwarfCompileUnit. DenseMap<const MDNode *, DIE *> MDTypeNodeToDieMap; + // Used to unique C++ member function declarations. + StringMap<const MDNode *> OdrMemberMap; + // Stores the current file ID for a given compile unit. DenseMap<unsigned, unsigned> FileIDCUMap; // Source id map, i.e. CUID, source filename and directory, @@ -702,6 +705,11 @@ public: return MDTypeNodeToDieMap.lookup(TypeMD); } + /// \brief Look up or create an entry in the OdrMemberMap. + const MDNode *&getOrCreateOdrMember(StringRef Key) { + return OdrMemberMap.GetOrCreateValue(Key).getValue(); + } + /// \brief Emit all Dwarf sections that should come prior to the /// content. void beginModule(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index dbdcf9d2e11..836beb89b45 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1405,12 +1405,33 @@ DIE *DwarfUnit::getOrCreateNameSpace(DINameSpace NS) { return NDie; } +/// Unique C++ member function declarations based on their +/// context and mangled name. +DISubprogram +DwarfUnit::getOdrUniqueSubprogram(DIScope Context, DISubprogram SP) const { + if (!hasODR() || + !Context.isCompositeType() || + SP.getLinkageName().empty() || + SP.isDefinition()) + return SP; + // Create a key with the UID of the parent class and this SP's name. + Twine Key = SP.getContext().getName() + SP.getLinkageName(); + const MDNode *&Entry = DD->getOrCreateOdrMember(Key.str()); + if (!Entry) + Entry = &*SP; + + return DISubprogram(Entry); +} + /// getOrCreateSubprogramDIE - Create new DIE using SP. DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) { // Construct the context before querying for the existence of the DIE in case // such construction creates the DIE (as is the case for member function // declarations). - DIE *ContextDIE = getOrCreateContextDIE(resolve(SP.getContext())); + DIScope Context = resolve(SP.getContext()); + DIE *ContextDIE = getOrCreateContextDIE(Context); + // Unique declarations based on the ODR, where applicable. + SP = getOdrUniqueSubprogram(Context, SP); DIE *SPDie = getDIE(SP); if (SPDie) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index af465c006ed..d8208737663 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -485,6 +485,28 @@ public: virtual DwarfCompileUnit &getCU() = 0; + /// \brief Return whether this compilation unit has the + /// one-definition-rule (ODR). In C++ this allows the compiler to + /// perform type unique during LTO. + bool hasODR() const { + switch (getLanguage()) { + case dwarf::DW_LANG_C_plus_plus: + case dwarf::DW_LANG_C_plus_plus_03: + case dwarf::DW_LANG_C_plus_plus_11: + // For all we care, the C++ part of the language has the ODR and + // ObjC methods are not represented in a way that they could be + // confused with C++ member functions. + case dwarf::DW_LANG_ObjC_plus_plus: + return true; + default: + return false; + } + } + + /// \brief Unique C++ member function declarations based on their + /// context+mangled name. + DISubprogram getOdrUniqueSubprogram(DIScope Context, DISubprogram SP) const; + protected: /// getOrCreateStaticMemberDIE - Create new static data member DIE. DIE *getOrCreateStaticMemberDIE(DIDerivedType DT); |