diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/test/tools/dsymutil/Inputs/modules/1.o | bin | 2444 -> 2596 bytes | |||
| -rw-r--r-- | llvm/test/tools/dsymutil/Inputs/modules/2.o | bin | 0 -> 1788 bytes | |||
| -rw-r--r-- | llvm/test/tools/dsymutil/X86/modules.m | 49 | ||||
| -rw-r--r-- | llvm/tools/dsymutil/DwarfLinker.cpp | 22 |
4 files changed, 53 insertions, 18 deletions
diff --git a/llvm/test/tools/dsymutil/Inputs/modules/1.o b/llvm/test/tools/dsymutil/Inputs/modules/1.o Binary files differindex eca930c905c..ef368b85d8f 100644 --- a/llvm/test/tools/dsymutil/Inputs/modules/1.o +++ b/llvm/test/tools/dsymutil/Inputs/modules/1.o diff --git a/llvm/test/tools/dsymutil/Inputs/modules/2.o b/llvm/test/tools/dsymutil/Inputs/modules/2.o Binary files differnew file mode 100644 index 00000000000..0a7100f4651 --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/modules/2.o diff --git a/llvm/test/tools/dsymutil/X86/modules.m b/llvm/test/tools/dsymutil/X86/modules.m index 046a8c1304a..f693ef9019b 100644 --- a/llvm/test/tools/dsymutil/X86/modules.m +++ b/llvm/test/tools/dsymutil/X86/modules.m @@ -11,9 +11,11 @@ EOF clang -D BAR_H -E -o Bar.h modules.m clang -D FOO_H -E -o Foo.h modules.m - clang -cc1 -emit-obj -fmodules -fmodule-map-file=modules.modulemap \ - -fmodule-format=obj -g -dwarf-ext-refs -fmodules-cache-path=. \ - -fdisable-module-hash modules.m -o 1.o + clang -D ODR_VIOLATION_C -E -o odr_violation.c modules.m + clang -c -fmodules -fmodule-map-file=modules.modulemap \ + -g -gmodules -fmodules-cache-path=. \ + -Xclang -fdisable-module-hash modules.m -o 1.o + clang -c -g odr_violation.c -o 2.o */ // RUN: llvm-dsymutil -f -oso-prepend-path=%p/../Inputs/modules \ @@ -57,7 +59,7 @@ struct PruneMeNot; // CHECK: 0x0[[FOO:.*]]: DW_TAG_module // CHECK-NEXT: DW_AT_name{{.*}}"Foo" // CHECK-NOT: DW_TAG -// CHECK: DW_TAG_typedef +// CHECK: 0x0[[BARTD:.*]]: DW_TAG_typedef // CHECK-NOT: DW_TAG // CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BAR]]) // CHECK: DW_TAG_structure_type @@ -75,19 +77,25 @@ struct S {}; } @end +#else +// --------------------------------------------------------------------- +#ifdef ODR_VIOLATION_C +// --------------------------------------------------------------------- + +struct Bar { + int i; +}; +typedef struct Bar Bar; +Bar odr_violation = { 42 }; + // --------------------------------------------------------------------- #else // --------------------------------------------------------------------- // CHECK: DW_TAG_compile_unit // CHECK: DW_AT_low_pc -// CHECK-NOT:DW_TAG -// CHECK: DW_TAG_module -// CHECK-NEXT: DW_AT_name{{.*}}"Foo" -// CHECK-NOT: DW_TAG -// CHECK: DW_TAG_typedef -// CHECK-NOT: DW_TAG -// CHECK: NULL +// CHECK-NOT: DW_TAG_module +// CHECK-NOT: DW_TAG_typedef // // CHECK: DW_TAG_imported_declaration // CHECK-NOT: DW_TAG @@ -97,6 +105,10 @@ struct S {}; // CHECK: DW_AT_name {{.*}}"main" // // CHECK: DW_TAG_variable +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name{{.*}}"bar" +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BARTD]] // CHECK: DW_TAG_variable // CHECK-NOT: DW_TAG // CHECK: DW_AT_name{{.*}}"foo" @@ -105,13 +117,26 @@ struct S {}; // // CHECK: 0x{{0*}}[[PTR]]: DW_TAG_pointer_type // CHECK-NEXT DW_AT_type [DW_FORM_ref_addr] {0x{{0*}}[[INTERFACE]]) +extern int odr_violation; @import Foo; int main(int argc, char **argv) { Bar bar; Foo *foo = 0; - bar.value = 42; + bar.value = odr_violation; return bar.value; } #endif #endif +#endif + +// CHECK: DW_TAG_compile_unit +// CHECK: DW_AT_name {{.*}}"odr_violation.c" +// CHECK: DW_TAG_variable +// CHECK: DW_AT_name {{.*}}"odr_violation" +// CHECK: DW_AT_type [DW_FORM_ref4] ({{.*}}{0x{{0*}}[[BAR2:.*]]}) +// CHECK: 0x{{0*}}[[BAR2]]: DW_TAG_typedef +// CHECK: DW_AT_type [DW_FORM_ref4] ({{.*}}{0x{{0*}}[[BAR3:.*]]}) +// CHECK: DW_AT_name {{.*}}"Bar" +// CHECK: 0x{{0*}}[[BAR3]]: DW_TAG_structure_type +// CHECK-NEXT: DW_AT_name {{.*}}"Bar" diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index 94428bcab51..d82149e50b4 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -98,6 +98,7 @@ class DeclContext { uint32_t Line; uint32_t ByteSize; uint16_t Tag; + unsigned DefinedInClangModule : 1; StringRef Name; StringRef File; const DeclContext &Parent; @@ -112,15 +113,17 @@ public: DeclContext() : QualifiedNameHash(0), Line(0), ByteSize(0), - Tag(dwarf::DW_TAG_compile_unit), Name(), File(), Parent(*this), - LastSeenDIE(), LastSeenCompileUnitID(0), CanonicalDIEOffset(0) {} + Tag(dwarf::DW_TAG_compile_unit), DefinedInClangModule(0), Name(), + File(), Parent(*this), LastSeenDIE(), LastSeenCompileUnitID(0), + CanonicalDIEOffset(0) {} DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag, StringRef Name, StringRef File, const DeclContext &Parent, DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0) : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag), - Name(Name), File(File), Parent(Parent), LastSeenDIE(LastSeenDIE), - LastSeenCompileUnitID(CUId), CanonicalDIEOffset(0) {} + DefinedInClangModule(0), Name(Name), File(File), Parent(Parent), + LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId), + CanonicalDIEOffset(0) {} uint32_t getQualifiedNameHash() const { return QualifiedNameHash; } @@ -129,6 +132,9 @@ public: uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; } void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; } + bool isDefinedInClangModule() const { return DefinedInClangModule; } + void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; } + uint16_t getTag() const { return Tag; } StringRef getName() const { return Name; } }; @@ -1801,6 +1807,8 @@ static bool analyzeContextInfo(const DWARFDie &DIE, CurrentDeclContext = PtrInvalidPair.getPointer(); Info.Ctxt = PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer(); + if (Info.Ctxt) + Info.Ctxt->setDefinedInClangModule(InClangModule); } else Info.Ctxt = CurrentDeclContext = nullptr; } @@ -2172,7 +2180,6 @@ unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr, return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags); case dwarf::DW_TAG_subprogram: return shouldKeepSubprogramDIE(RelocMgr, DIE, Unit, MyInfo, Flags); - case dwarf::DW_TAG_module: case dwarf::DW_TAG_imported_module: case dwarf::DW_TAG_imported_declaration: case dwarf::DW_TAG_imported_unit: @@ -2232,6 +2239,8 @@ void DwarfLinker::keepDIEAndDependencies(RelocationManager &RelocMgr, resolveDIEReference(*this, Units, Val, Unit, Die, ReferencedCU)) { uint32_t RefIdx = ReferencedCU->getOrigUnit().getDIEIndex(RefDIE); CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefIdx); + bool IsModuleRef = Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() && + Info.Ctxt->isDefinedInClangModule(); // If the referenced DIE has a DeclContext that has already been // emitted, then do not keep the one in this CU. We'll link to // the canonical DIE in cloneDieReferenceAttribute. @@ -2240,7 +2249,8 @@ void DwarfLinker::keepDIEAndDependencies(RelocationManager &RelocMgr, // ReferencedCU->hasODR() && CU.hasODR(). // FIXME: compatibility with dsymutil-classic. There is no // reason not to unique ref_addr references. - if (AttrSpec.Form != dwarf::DW_FORM_ref_addr && UseODR && Info.Ctxt && + if (AttrSpec.Form != dwarf::DW_FORM_ref_addr && (UseODR || IsModuleRef) && + Info.Ctxt && Info.Ctxt != ReferencedCU->getInfo(Info.ParentIdx).Ctxt && Info.Ctxt->getCanonicalDIEOffset() && isODRAttribute(AttrSpec.Attr)) continue; |

