Index: include/llvm/IR/DIBuilder.h =================================================================== --- include/llvm/IR/DIBuilder.h +++ include/llvm/IR/DIBuilder.h @@ -568,14 +568,14 @@ DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, bool isLocalToUnit, DIExpression *Expr = nullptr, MDNode *Decl = nullptr, - uint32_t AlignInBits = 0); + MDTuple *templateParams = nullptr, uint32_t AlignInBits = 0); /// Identical to createGlobalVariable /// except that the resulting DbgNode is temporary and meant to be RAUWed. DIGlobalVariable *createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, bool isLocalToUnit, MDNode *Decl = nullptr, - uint32_t AlignInBits = 0); + MDTuple *templateParams = nullptr, uint32_t AlignInBits = 0); /// Create a new descriptor for an auto variable. This is a local variable /// that is not a subprogram parameter. Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -2464,30 +2464,30 @@ IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {} ~DIGlobalVariable() = default; - static DIGlobalVariable *getImpl(LLVMContext &Context, DIScope *Scope, - StringRef Name, StringRef LinkageName, - DIFile *File, unsigned Line, DITypeRef Type, - bool IsLocalToUnit, bool IsDefinition, - DIDerivedType *StaticDataMemberDeclaration, - uint32_t AlignInBits, StorageType Storage, - bool ShouldCreate = true) { + static DIGlobalVariable * + getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name, + StringRef LinkageName, DIFile *File, unsigned Line, DITypeRef Type, + bool IsLocalToUnit, bool IsDefinition, + DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, + uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - AlignInBits, Storage, ShouldCreate); + cast_or_null(TemplateParams), AlignInBits, Storage, + ShouldCreate); } static DIGlobalVariable * getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, - Metadata *StaticDataMemberDeclaration, uint32_t AlignInBits, - StorageType Storage, bool ShouldCreate = true); + Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, + uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true); TempDIGlobalVariable cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), getLinkageName(), getFile(), getLine(), getType(), isLocalToUnit(), isDefinition(), getStaticDataMemberDeclaration(), - getAlignInBits()); + getTemplateParams(), getAlignInBits()); } public: @@ -2496,17 +2496,19 @@ DIFile *File, unsigned Line, DITypeRef Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, - uint32_t AlignInBits), + MDTuple *TemplateParams, uint32_t AlignInBits), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, AlignInBits)) + IsDefinition, StaticDataMemberDeclaration, TemplateParams, + AlignInBits)) DEFINE_MDNODE_GET(DIGlobalVariable, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, - uint32_t AlignInBits), + Metadata *TemplateParams, uint32_t AlignInBits), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, AlignInBits)) + IsDefinition, StaticDataMemberDeclaration, TemplateParams, + AlignInBits)) TempDIGlobalVariable clone() const { return cloneImpl(); } @@ -2520,6 +2522,8 @@ MDString *getRawLinkageName() const { return getOperandAs(5); } Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); } + Metadata *getRawTemplateParams() const { return getOperand(7); } + MDTuple *getTemplateParams() const { return getOperandAs(7); } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DIGlobalVariableKind; Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -4519,7 +4519,8 @@ /// ParseDIGlobalVariable: /// ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo", /// file: !1, line: 7, type: !2, isLocal: false, -/// isDefinition: true, declaration: !3, align: 8) +/// isDefinition: true, templateParams: !3, +/// declaration: !4, align: 8) bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \ @@ -4530,15 +4531,17 @@ OPTIONAL(type, MDField, ); \ OPTIONAL(isLocal, MDBoolField, ); \ OPTIONAL(isDefinition, MDBoolField, (true)); \ + OPTIONAL(templateParams, MDField, ); \ OPTIONAL(declaration, MDField, ); \ OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DIGlobalVariable, - (Context, scope.Val, name.Val, linkageName.Val, - file.Val, line.Val, type.Val, isLocal.Val, - isDefinition.Val, declaration.Val, align.Val)); + Result = + GET_OR_DISTINCT(DIGlobalVariable, + (Context, scope.Val, name.Val, linkageName.Val, file.Val, + line.Val, type.Val, isLocal.Val, isDefinition.Val, + declaration.Val, templateParams.Val, align.Val)); return false; } Index: lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- lib/Bitcode/Reader/MetadataLoader.cpp +++ lib/Bitcode/Reader/MetadataLoader.cpp @@ -1556,21 +1556,33 @@ break; } case bitc::METADATA_GLOBAL_VAR: { - if (Record.size() < 11 || Record.size() > 12) + if (Record.size() < 11 || Record.size() > 13) return error("Invalid record"); IsDistinct = Record[0] & 1; unsigned Version = Record[0] >> 1; if (Version == 1) { - MetadataList.assignValue( - GET_OR_DISTINCT(DIGlobalVariable, - (Context, getMDOrNull(Record[1]), - getMDString(Record[2]), getMDString(Record[3]), - getMDOrNull(Record[4]), Record[5], - getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), Record[11])), - NextMetadataNo); + if (Record.size() == 12) + MetadataList.assignValue( + GET_OR_DISTINCT( + DIGlobalVariable, + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[10]), nullptr, Record[11])), + NextMetadataNo); + + if (Record.size() == 13) + MetadataList.assignValue( + GET_OR_DISTINCT( + DIGlobalVariable, + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[10]), getMDOrNull(Record[11]), Record[12])), + NextMetadataNo); + NextMetadataNo++; } else if (Version == 0) { // Upgrade old metadata, which stored a global variable reference or a @@ -1601,7 +1613,7 @@ (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), AlignInBits)); + getMDOrNull(Record[10]), nullptr, AlignInBits)); DIGlobalVariableExpression *DGVE = nullptr; if (Attach || Expr) Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1747,6 +1747,7 @@ Record.push_back(N->isDefinition()); Record.push_back(/* expr */ 0); Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration())); + Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams())); Record.push_back(N->getAlignInBits()); Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev); Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -160,6 +160,9 @@ addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata, AlignInBytes); + if (MDTuple *TP = GV->getTemplateParams()) + addTemplateParams(*VariableDIE, DINodeArray(TP)); + // Add location. bool addToAccelTable = false; DIELoc *Loc = nullptr; Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -1950,6 +1950,7 @@ Printer.printBool("isLocal", N->isLocalToUnit()); Printer.printBool("isDefinition", N->isDefinition()); Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration()); + Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printInt("align", N->getAlignInBits()); Out << ")"; } Index: lib/IR/DIBuilder.cpp =================================================================== --- lib/IR/DIBuilder.cpp +++ lib/IR/DIBuilder.cpp @@ -627,13 +627,13 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNumber, DIType *Ty, bool isLocalToUnit, DIExpression *Expr, - MDNode *Decl, uint32_t AlignInBits) { + MDNode *Decl, MDTuple *templateParams, uint32_t AlignInBits) { checkGlobalVariableScope(Context); auto *GV = DIGlobalVariable::getDistinct( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, isLocalToUnit, true, cast_or_null(Decl), - AlignInBits); + templateParams, AlignInBits); if (!Expr) Expr = createExpression(); auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); @@ -644,13 +644,13 @@ DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNumber, DIType *Ty, bool isLocalToUnit, MDNode *Decl, - uint32_t AlignInBits) { + MDTuple *templateParams, uint32_t AlignInBits) { checkGlobalVariableScope(Context); return DIGlobalVariable::getTemporary( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, isLocalToUnit, false, - cast_or_null(Decl), AlignInBits) + cast_or_null(Decl), templateParams, AlignInBits) .release(); } Index: lib/IR/DebugInfoMetadata.cpp =================================================================== --- lib/IR/DebugInfoMetadata.cpp +++ lib/IR/DebugInfoMetadata.cpp @@ -596,16 +596,22 @@ MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, - uint32_t AlignInBits, StorageType Storage, - bool ShouldCreate) { + Metadata *TemplateParams, uint32_t AlignInBits, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, - (Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); - Metadata *Ops[] = { - Scope, Name, File, Type, Name, LinkageName, StaticDataMemberDeclaration}; + DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, + TemplateParams, AlignInBits)); + Metadata *Ops[] = {Scope, + Name, + File, + Type, + Name, + LinkageName, + StaticDataMemberDeclaration, + TemplateParams}; DEFINE_GETIMPL_STORE(DIGlobalVariable, (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops); Index: lib/IR/LLVMContextImpl.h =================================================================== --- lib/IR/LLVMContextImpl.h +++ lib/IR/LLVMContextImpl.h @@ -865,23 +865,26 @@ bool IsLocalToUnit; bool IsDefinition; Metadata *StaticDataMemberDeclaration; + Metadata *TemplateParams; uint32_t AlignInBits; MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, - Metadata *StaticDataMemberDeclaration, uint32_t AlignInBits) + Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, + uint32_t AlignInBits) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), StaticDataMemberDeclaration(StaticDataMemberDeclaration), - AlignInBits(AlignInBits) {} + TemplateParams(TemplateParams), AlignInBits(AlignInBits) {} MDNodeKeyImpl(const DIGlobalVariable *N) : Scope(N->getRawScope()), Name(N->getRawName()), LinkageName(N->getRawLinkageName()), File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()), IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()), + TemplateParams(N->getRawTemplateParams()), AlignInBits(N->getAlignInBits()) {} bool isKeyOf(const DIGlobalVariable *RHS) const { @@ -892,6 +895,7 @@ IsDefinition == RHS->isDefinition() && StaticDataMemberDeclaration == RHS->getRawStaticDataMemberDeclaration() && + TemplateParams == RHS->getRawTemplateParams() && AlignInBits == RHS->getAlignInBits(); } Index: test/DebugInfo/X86/template.ll =================================================================== --- test/DebugInfo/X86/template.ll +++ test/DebugInfo/X86/template.ll @@ -12,10 +12,18 @@ ; CHECK-NEXT: DW_AT_name{{.*}} = "int" ; CHECK: DW_TAG_structure_type -; CHECK-NEXT: DW_AT_name{{.*}}"y_impl" +; CHECK: DW_AT_name{{.*}}"y_impl" ; CHECK-NOT: NULL ; CHECK: DW_TAG_template_type_parameter +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_name{{.*}}"var" +; CHECK-NOT: NULL +; CHECK: DW_TAG_template_type_parameter +; CHECK-NEXT: DW_AT_type{{.*}}=> {[[INT]]} +; CHECK-NEXT: DW_AT_name{{.*}}= "T" + + ; CHECK: DW_AT_name{{.*}}"func<3, &glbl, y_impl, nullptr, 1, 2>" ; CHECK-NOT: NULL ; CHECK: DW_TAG_template_value_parameter @@ -62,72 +70,88 @@ %"struct.y_impl::nested" = type { i8 } -@glbl = global i32 0, align 4, !dbg !0 -@n = global %"struct.y_impl::nested" zeroinitializer, align 1, !dbg !4 -@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_template.cpp, i8* null }] +$_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv = comdat any + +$_Z3varIiE = comdat any + +@glbl = dso_local global i32 0, align 4, !dbg !0 +@n = dso_local global %"struct.y_impl::nested" zeroinitializer, align 1, !dbg !6 +@_Z3varIiE = linkonce_odr dso_local global i32 0, comdat, align 4, !dbg !13 +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_upstream_test.cpp, i8* null }] -define internal void @__cxx_global_var_init() section ".text.startup" !dbg !17 { +; Function Attrs: noinline uwtable +define internal void @__cxx_global_var_init() #0 section ".text.startup" !dbg !21 { entry: - %call = call i32 @_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv(), !dbg !20 - store i32 %call, i32* @glbl, align 4, !dbg !20 - ret void, !dbg !20 + %call = call i32 @_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv(), !dbg !24 + store i32 %call, i32* @glbl, align 4, !dbg !24 + ret void, !dbg !24 } -; Function Attrs: nounwind uwtable -define linkonce_odr i32 @_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv() #0 !dbg !21 { +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local i32 @_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv() #1 comdat !dbg !25 { entry: - ret i32 3, !dbg !35 + store i32 5, i32* @_Z3varIiE, align 4, !dbg !39 + %0 = load i32, i32* @_Z3varIiE, align 4, !dbg !40 + ret i32 %0, !dbg !41 } -define internal void @_GLOBAL__sub_I_template.cpp() section ".text.startup" { +; Function Attrs: noinline uwtable +define internal void @_GLOBAL__sub_I_upstream_test.cpp() #0 section ".text.startup" !dbg !42 { entry: - call void @__cxx_global_var_init(), !dbg !36 + call void @__cxx_global_var_init(), !dbg !44 ret void } -attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #0 = { noinline uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } -!llvm.dbg.cu = !{!11} -!llvm.module.flags = !{!14, !15} -!llvm.ident = !{!16} +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!17, !18, !19} +!llvm.ident = !{!20} !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = !DIGlobalVariable(name: "glbl", scope: null, file: !2, line: 3, type: !3, isLocal: false, isDefinition: true) -!2 = !DIFile(filename: "template.cpp", directory: "/tmp/dbginfo") -!3 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) -!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression()) -!5 = !DIGlobalVariable(name: "n", scope: null, file: !2, line: 4, type: !6, isLocal: false, isDefinition: true) -!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "nested", scope: !7, file: !2, line: 2, size: 8, align: 8, elements: !8, identifier: "_ZTSN6y_implIiE6nestedE") -!7 = !DICompositeType(tag: DW_TAG_structure_type, name: "y_impl", file: !2, line: 2, size: 8, align: 8, elements: !8, templateParams: !9, identifier: "_ZTS6y_implIiE") -!8 = !{} -!9 = !{!10} -!10 = !DITemplateTypeParameter(type: !3) -!11 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "clang version 3.6.0 (trunk 224394) (llvm/trunk 224384)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !8, retainedTypes: !12, globals: !13, imports: !8) -!12 = !{!7, !6} -!13 = !{!0, !4} -!14 = !{i32 2, !"Dwarf Version", i32 4} -!15 = !{i32 2, !"Debug Info Version", i32 3} -!16 = !{!"clang version 3.6.0 (trunk 224394) (llvm/trunk 224384)"} -!17 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !2, file: !2, line: 3, type: !18, isLocal: true, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !11, variables: !8) -!18 = !DISubroutineType(types: !19) -!19 = !{null} -!20 = !DILocation(line: 3, column: 12, scope: !17) -!21 = distinct !DISubprogram(name: "func<3, &glbl, y_impl, nullptr, 1, 2>", linkageName: "_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv", scope: !2, file: !2, line: 1, type: !22, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !11, templateParams: !24, variables: !8) +!1 = distinct !DIGlobalVariable(name: "glbl", scope: !2, file: !3, line: 7, type: !12, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 (trunk 328341)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!3 = !DIFile(filename: "upstream_test.cpp", directory: "/home/mvoss/src/resolve-92562") +!4 = !{} +!5 = !{!0, !6, !13} +!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!7 = distinct !DIGlobalVariable(name: "n", scope: !2, file: !3, line: 8, type: !8, isLocal: false, isDefinition: true) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "nested", scope: !9, file: !3, line: 6, size: 8, flags: DIFlagTypePassByValue, elements: !4, identifier: "_ZTSN6y_implIiE6nestedE") +!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "y_impl", file: !3, line: 6, size: 8, flags: DIFlagTypePassByValue, elements: !4, templateParams: !10, identifier: "_ZTS6y_implIiE") +!10 = !{!11} +!11 = !DITemplateTypeParameter(type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression()) +!14 = distinct !DIGlobalVariable(name: "var", linkageName: "_Z3varIiE", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true, templateParams: !15) +!15 = !{!16} +!16 = !DITemplateTypeParameter(name: "T", type: !12) +!17 = !{i32 2, !"Dwarf Version", i32 4} +!18 = !{i32 2, !"Debug Info Version", i32 3} +!19 = !{i32 1, !"wchar_size", i32 4} +!20 = !{!"clang version 7.0.0 (trunk 328341)"} +!21 = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !3, file: !3, line: 7, type: !22, isLocal: true, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, unit: !2, variables: !4) !22 = !DISubroutineType(types: !23) -!23 = !{!3} -!24 = !{!25, !26, !28, !29, !31} -!25 = !DITemplateValueParameter(name: "x", type: !3, value: i32 3) -!26 = !DITemplateValueParameter(type: !27, value: i32* @glbl) -!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3, size: 64, align: 64) -!28 = !DITemplateValueParameter(tag: DW_TAG_GNU_template_template_param, name: "y", value: !"y_impl") -!29 = !DITemplateValueParameter(name: "n", type: !30, value: i8 0) -!30 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)") -!31 = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "z", value: !32) -!32 = !{!33, !34} -!33 = !DITemplateValueParameter(type: !3, value: i32 1) -!34 = !DITemplateValueParameter(type: !3, value: i32 2) -!35 = !DILocation(line: 1, column: 96, scope: !21) -!36 = !DILocation(line: 0, scope: !37) -!37 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_template.cpp", scope: !2, file: !2, type: !38, isLocal: true, isDefinition: true, flags: DIFlagArtificial, isOptimized: false, unit: !11, variables: !8) -!38 = !DISubroutineType(types: !8) +!23 = !{null} +!24 = !DILocation(line: 7, column: 12, scope: !21) +!25 = distinct !DISubprogram(name: "func<3, &glbl, y_impl, nullptr, 1, 2>", linkageName: "_Z4funcILi3EXadL_Z4glblEE6y_implLDn0EJLi1ELi2EEEiv", scope: !3, file: !3, line: 2, type: !26, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !2, templateParams: !28, variables: !4) +!26 = !DISubroutineType(types: !27) +!27 = !{!12} +!28 = !{!29, !30, !32, !33, !35} +!29 = !DITemplateValueParameter(name: "x", type: !12, value: i32 3) +!30 = !DITemplateValueParameter(type: !31, value: i32* @glbl) +!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!32 = !DITemplateValueParameter(tag: DW_TAG_GNU_template_template_param, name: "y", value: !"y_impl") +!33 = !DITemplateValueParameter(name: "n", type: !34, value: i8 0) +!34 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)") +!35 = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "z", value: !36) +!36 = !{!37, !38} +!37 = !DITemplateValueParameter(type: !12, value: i32 1) +!38 = !DITemplateValueParameter(type: !12, value: i32 2) +!39 = !DILocation(line: 3, column: 12, scope: !25) +!40 = !DILocation(line: 4, column: 10, scope: !25) +!41 = !DILocation(line: 4, column: 3, scope: !25) +!42 = distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_upstream_test.cpp", scope: !3, file: !3, type: !43, isLocal: true, isDefinition: true, flags: DIFlagArtificial, isOptimized: false, unit: !2, variables: !4) +!43 = !DISubroutineType(types: !4) +!44 = !DILocation(line: 0, scope: !42) Index: unittests/IR/MetadataTest.cpp =================================================================== --- unittests/IR/MetadataTest.cpp +++ unittests/IR/MetadataTest.cpp @@ -83,6 +83,7 @@ return DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, getNode(nullptr)); } + DISubprogram *getSubprogram() { return DISubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0, nullptr, false, false, 0, nullptr, 0, 0, 0, @@ -1929,13 +1930,16 @@ DIType *Type = getDerivedType(); bool IsLocalToUnit = false; bool IsDefinition = true; + MDTuple *templateParams = getTuple(); DIDerivedType *StaticDataMemberDeclaration = cast(getDerivedType()); + uint32_t AlignInBits = 8; - auto *N = DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits); + auto *N = DIGlobalVariable::get( + Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, + IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); + EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag()); EXPECT_EQ(Scope, N->getScope()); EXPECT_EQ(Name, N->getName()); @@ -1946,47 +1950,57 @@ EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit()); EXPECT_EQ(IsDefinition, N->isDefinition()); EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration()); + EXPECT_EQ(templateParams, N->getTemplateParams()); EXPECT_EQ(AlignInBits, N->getAlignInBits()); EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); + StaticDataMemberDeclaration, + templateParams, AlignInBits)); - EXPECT_NE(N, - DIGlobalVariable::get(Context, getSubprogram(), Name, LinkageName, - File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); + EXPECT_NE(N, DIGlobalVariable::get( + Context, getSubprogram(), Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, templateParams, AlignInBits)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); + StaticDataMemberDeclaration, + templateParams, AlignInBits)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); - EXPECT_NE(N, - DIGlobalVariable::get(Context, Scope, Name, LinkageName, getFile(), - Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); - EXPECT_NE(N, - DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, - Line + 1, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); - EXPECT_NE(N, - DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, - getDerivedType(), IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); + StaticDataMemberDeclaration, + templateParams, AlignInBits)); + EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, + getFile(), Line, Type, IsLocalToUnit, + IsDefinition, StaticDataMemberDeclaration, + templateParams, AlignInBits)); + EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, + Line + 1, Type, IsLocalToUnit, + IsDefinition, StaticDataMemberDeclaration, + templateParams, AlignInBits)); + EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, + Line, getDerivedType(), IsLocalToUnit, + IsDefinition, StaticDataMemberDeclaration, + templateParams, AlignInBits)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, !IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); + StaticDataMemberDeclaration, + templateParams, AlignInBits)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, !IsDefinition, - StaticDataMemberDeclaration, AlignInBits)); + StaticDataMemberDeclaration, + templateParams, AlignInBits)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, cast(getDerivedType()), + templateParams, AlignInBits)); + EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, + Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, nullptr, AlignInBits)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - (AlignInBits << 1))); + templateParams, (AlignInBits << 1))); TempDIGlobalVariable Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -2003,18 +2017,19 @@ DIType *Type = getDerivedType(); bool IsLocalToUnit = false; bool IsDefinition = true; + MDTuple *templateParams = getTuple(); auto *Expr = DIExpression::get(Context, {1, 2}); auto *Expr2 = DIExpression::get(Context, {1, 2, 3}); DIDerivedType *StaticDataMemberDeclaration = cast(getDerivedType()); uint32_t AlignInBits = 8; - auto *Var = DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, - Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits); - auto *Var2 = DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, - Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, AlignInBits); + auto *Var = DIGlobalVariable::get( + Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, + IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); + auto *Var2 = DIGlobalVariable::get( + Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, + IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); auto *N = DIGlobalVariableExpression::get(Context, Var, Expr); EXPECT_EQ(Var, N->getVariable());