getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align, 0,
FullName);
+ // Elements of composite types usually have back to the type, creating
+ // uniquing cycles. Distinct nodes are more efficient.
+ switch (RealDecl->getTag()) {
+ default:
+ llvm_unreachable("invalid composite type tag");
+
+ case llvm::dwarf::DW_TAG_array_type:
+ case llvm::dwarf::DW_TAG_enumeration_type:
+ // Array elements and most enumeration elements don't have back references,
+ // so they don't tend to be involved in uniquing cycles and there is some
+ // chance of merging them when linking together two modules. Only make
+ // them distinct if they are ODR-uniqued.
+ if (FullName.empty())
+ break;
+
+ case llvm::dwarf::DW_TAG_structure_type:
+ case llvm::dwarf::DW_TAG_union_type:
+ case llvm::dwarf::DW_TAG_class_type:
+ // Immediatley resolve to a distinct node.
+ RealDecl =
+ llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
+ break;
+ }
+
RegionMap[Ty->getDecl()].reset(RealDecl);
TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
// CHECK: !DILocalVariable(
// CHECK-NOT: name:
// CHECK: type: ![[UNION:[0-9]+]]
-// CHECK: ![[UNION]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK-NOT: name:
// CHECK: elements
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]],
A reallyA (500);
}
-// CHECK: ![[CLASSTYPE:.*]] = !DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK: ![[CLASSTYPE:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A",
// CHECK-SAME: identifier: "_ZTS1A"
// CHECK: ![[ARTARG:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1A",
// CHECK-SAME: DIFlagArtificial
// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
-// CHECK: [[C:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "C",
+// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
// CHECK-NOT: DIFlagFwdDecl
// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
// CHECK-SAME: vtableHolder: !"_ZTS1C"
// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple %itanium_abi_triple %s -o - | FileCheck %s
// Check that this pointer type is TC<int>
-// CHECK: ![[LINE:[0-9]+]] = !DICompositeType(tag: DW_TAG_class_type, name: "TC<int>"{{.*}}, identifier: "_ZTS2TCIiE")
+// CHECK: ![[LINE:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "TC<int>"{{.*}}, identifier: "_ZTS2TCIiE")
// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS2TCIiE"
template<typename T>
// CHECK-SAME: type: [[FOO_FUNC_TYPE:![0-9]*]]
// CHECK: [[FOO_FUNC_TYPE]] = !DISubroutineType(types: [[FOO_FUNC_PARAMS:![0-9]*]])
// CHECK: [[FOO_FUNC_PARAMS]] = !{null, !{{[0-9]*}}, !"[[OUTER_FOO_INNER_ID:.*]]"}
-// CHECK: !{{[0-9]*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier: "[[OUTER_FOO_INNER_ID]]")
+// CHECK: !{{[0-9]*}} = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier: "[[OUTER_FOO_INNER_ID]]")
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "virt<elem>"
// CHECK-SAME: elements: [[VIRT_MEM:![0-9]*]]
// CHECK: [[VIRT_TEMP_PARAM]] = !{[[VIRT_T:![0-9]*]]}
// CHECK: [[VIRT_T]] = !DITemplateTypeParameter(name: "T", type: !"_ZTS4elem")
-// CHECK: [[C:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"
+// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"
// CHECK-SAME: elements: [[C_MEM:![0-9]*]]
// CHECK-SAME: vtableHolder: !"_ZTS7MyClass"
// CHECK-SAME: identifier: "_ZTS7MyClass")
// CHECK: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 7,
-// CHECK: [[ELEM:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "elem"
+// CHECK: [[ELEM:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "elem"
// CHECK-SAME: elements: [[ELEM_MEM:![0-9]*]]
// CHECK-SAME: identifier: "_ZTS4elem"
// CHECK: [[ELEM_MEM]] = !{[[ELEM_X:![0-9]*]]}
str.assign(c, str);
}
-// CHECK: [[BS:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "basic_string<char>"
+// CHECK: [[BS:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "basic_string<char>"
// CHECK-SAME: line: 4
// CHECK-SAME: size: 8, align: 8
// CHECK: [[TYPE:![0-9]*]] = !DISubroutineType(types: [[ARGS:.*]])
// CHECK: [[RETAIN]] = !{!{{[0-9]]*}}, [[FOO:![0-9]*]],
-// CHECK: [[TC:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>"
+// CHECK: [[TC:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>"
// CHECK-SAME: templateParams: [[TCARGS:![0-9]*]]
// CHECK: [[TCARGS]] = !{[[TCARG1:![0-9]*]], [[TCARG2:![0-9]*]], [[TCARG3:![0-9]*]], [[TCARG4:![0-9]*]], [[TCARG5:![0-9]*]], [[TCARG6:![0-9]*]], [[TCARG7:![0-9]*]]}
//
// We could just emit a declaration of 'foo' here, rather than the entire
// definition (same goes for any time we emit a member (function or data)
// pointer type)
-// CHECK: [[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}identifier: "_ZTS3foo")
+// CHECK: [[FOO]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}identifier: "_ZTS3foo")
// CHECK: !DISubprogram(name: "f", linkageName: "_ZN3foo1fEv", {{.*}}type: [[FTYPE:![0-9]*]]
//
// CHECK: !DIGlobalVariable(name: "cvar"
// CHECK-SAME: line: [[CVAR_LINE:[0-9]+]]
// CHECK-SAME: type: ![[CVAR_T:[0-9]+]]
-// CHECK: ![[CVAR_T]] = !DICompositeType(tag: DW_TAG_class_type
+// CHECK: ![[CVAR_T]] = distinct !DICompositeType(tag: DW_TAG_class_type
// CHECK-SAME: line: [[CVAR_LINE]],
// CHECK-SAME: elements: ![[CVAR_ARGS:[0-9]+]]
// CHECK: ![[CVAR_ARGS]] = !{!{{[0-9]+}}}
// CHECK: !DIGlobalVariable(name: "var"
// CHECK-SAME: line: [[VAR_LINE:[0-9]+]]
// CHECK-SAME: type: ![[VAR_T:[0-9]+]]
-// CHECK: ![[VAR_T]] = !DICompositeType(tag: DW_TAG_class_type
+// CHECK: ![[VAR_T]] = distinct !DICompositeType(tag: DW_TAG_class_type
// CHECK-SAME: line: [[VAR_LINE]],
// CHECK-SAME: elements: ![[VAR_ARGS:[0-9]+]]
// CHECK: ![[VAR_ARGS]] = !{!{{[0-9]+}}}
// CHECK: ![[A_FUNC:.*]] = distinct !DISubprogram(name: "a"{{.*}}, line: [[A_LINE:[0-9]+]]{{.*}}, isDefinition: true
// Back to A. -- 78
-// CHECK: ![[LAM_A:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[A_FUNC]]{{.*}}, line: [[A_LINE]],
+// CHECK: ![[LAM_A:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[A_FUNC]]{{.*}}, line: [[A_LINE]],
// CHECK-SAME: elements: ![[LAM_A_ARGS:[0-9]+]]
// CHECK: ![[LAM_A_ARGS]] = !{![[CON_LAM_A:[0-9]+]]}
// CHECK: ![[CON_LAM_A]] = !DISubprogram(name: "operator()"
// CHECK: ![[B_FUNC:.*]] = distinct !DISubprogram(name: "b"{{.*}}, line: [[B_LINE:[0-9]+]]{{.*}}, isDefinition: true
// Back to B. -- 67
-// CHECK: ![[LAM_B:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[B_FUNC]]{{.*}}, line: [[B_LINE]],
+// CHECK: ![[LAM_B:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[B_FUNC]]{{.*}}, line: [[B_LINE]],
// CHECK-SAME: elements: ![[LAM_B_ARGS:[0-9]+]]
// CHECK: ![[LAM_B_ARGS]] = !{![[CAP_B:[0-9]+]], ![[CON_LAM_B:[0-9]+]]}
// CHECK: ![[CAP_B]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
// CHECK: ![[C_FUNC:.*]] = distinct !DISubprogram(name: "c"{{.*}}, line: [[C_LINE:[0-9]+]]{{.*}}, isDefinition: true
// Back to C. -- 55
-// CHECK: ![[LAM_C:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[C_FUNC]]{{.*}}, line: [[C_LINE]],
+// CHECK: ![[LAM_C:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[C_FUNC]]{{.*}}, line: [[C_LINE]],
// CHECK-SAME: elements: ![[LAM_C_ARGS:[0-9]+]]
// CHECK: ![[LAM_C_ARGS]] = !{![[CAP_C:[0-9]+]], ![[CON_LAM_C:[0-9]+]]}
// CHECK: ![[CAP_C]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
// CHECK: ![[D_FUNC:.*]] = distinct !DISubprogram(name: "d"{{.*}}, line: [[D_LINE:[0-9]+]]{{.*}}, isDefinition: true
// Back to D. -- 24
-// CHECK: ![[LAM_D:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[D_FUNC]]{{.*}}, line: [[D_LINE]],
+// CHECK: ![[LAM_D:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[D_FUNC]]{{.*}}, line: [[D_LINE]],
// CHECK-SAME: elements: ![[LAM_D_ARGS:[0-9]+]]
// CHECK: ![[LAM_D_ARGS]] = !{![[CAP_D_X:[0-9]+]], ![[CAP_D_Y:[0-9]+]], ![[CON_LAM_D:[0-9]+]]}
// CHECK: ![[CAP_D_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
// CHECK: !DIGlobalVariable(name: "GlobalUnion",
// CHECK-SAME: type: ![[GLOBAL_UNION:[0-9]+]]
-// CHECK: ![[GLOBAL_UNION]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[GLOBAL_UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK-SAME: elements: !{{[0-9]+}})
// CHECK: !DIGlobalVariable(name: "GlobalStruct",
// CHECK-SAME: type: ![[GLOBAL_STRUCT:[0-9]+]]
-// CHECK: ![[GLOBAL_STRUCT]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK: ![[GLOBAL_STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-SAME: elements: !{{[0-9]+}})
// CHECK: !DIGlobalVariable(name: "anon",
// CHECK: !DIGlobalVariable(name: "GlobalUnion",
// CHECK-SAME: type: ![[GLOBAL_UNION:[0-9]+]]
// CHECK: ![[MOD:.*]] = !DIModule(scope: null, name: "DebugObjC
-// CHECK: ![[GLOBAL_UNION]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[GLOBAL_UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK-SAME: elements: !{{[0-9]+}})
// CHECK: !DIGlobalVariable(name: "GlobalStruct",
// CHECK-SAME: type: ![[GLOBAL_STRUCT:[0-9]+]]
-// CHECK: ![[GLOBAL_STRUCT]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK: ![[GLOBAL_STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-SAME: elements: !{{[0-9]+}})
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefUnion",
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "FwdDeclared"
// CHECK-SAME: elements:
-// CHECK: ![[TD_UNION:.*]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[TD_UNION:.*]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK-NOT: name:
// CHECK-SAME: elements:
// CHECK-SAME: )
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefEnum",
// CHECK-SAME: baseType: ![[TD_ENUM:.*]])
-// CHECK: ![[TD_STRUCT:.*]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK: ![[TD_STRUCT:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
// CHECK-NOT: name:
// CHECK-SAME: elements:
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefStruct",