diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index e171082942f6e..404ecfa975a1c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1787,18 +1787,36 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, for (unsigned i = 0, e = TAList.size(); i != e; ++i) { const TemplateArgument &TA = TAList[i]; StringRef Name; + bool defaultParameter = false; if (TPList) Name = TPList->getParam(i)->getName(); switch (TA.getKind()) { case TemplateArgument::Type: { llvm::DIType *TTy = getOrCreateType(TA.getAsType(), Unit); - TemplateParams.push_back( - DBuilder.createTemplateTypeParameter(TheCU, Name, TTy)); + + if (TPList) + if (auto *templateType = + dyn_cast_or_null(TPList->getParam(i))) + if (templateType->hasDefaultArgument()) + defaultParameter = + templateType->getDefaultArgument() == TA.getAsType(); + + TemplateParams.push_back(DBuilder.createTemplateTypeParameter( + TheCU, Name, TTy, defaultParameter)); + } break; case TemplateArgument::Integral: { llvm::DIType *TTy = getOrCreateType(TA.getIntegralType(), Unit); + if (TPList) + if (auto *templateType = + dyn_cast_or_null(TPList->getParam(i))) + if (templateType->hasDefaultArgument()) + defaultParameter = + templateType->getDefaultArgument()->EvaluateKnownConstInt( + CGM.getContext()) == TA.getAsIntegral(); + TemplateParams.push_back(DBuilder.createTemplateValueParameter( - TheCU, Name, TTy, + TheCU, Name, TTy, defaultParameter, llvm::ConstantInt::get(CGM.getLLVMContext(), TA.getAsIntegral()))); } break; case TemplateArgument::Declaration: { @@ -1837,7 +1855,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, V = V->stripPointerCasts(); } TemplateParams.push_back(DBuilder.createTemplateValueParameter( - TheCU, Name, TTy, cast_or_null(V))); + TheCU, Name, TTy, defaultParameter, cast_or_null(V))); } break; case TemplateArgument::NullPtr: { QualType T = TA.getNullPtrType(); @@ -1855,8 +1873,8 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, V = CGM.getCXXABI().EmitNullMemberPointer(MPT); if (!V) V = llvm::ConstantInt::get(CGM.Int8Ty, 0); - TemplateParams.push_back( - DBuilder.createTemplateValueParameter(TheCU, Name, TTy, V)); + TemplateParams.push_back(DBuilder.createTemplateValueParameter( + TheCU, Name, TTy, defaultParameter, V)); } break; case TemplateArgument::Template: TemplateParams.push_back(DBuilder.createTemplateTemplateParameter( @@ -1877,7 +1895,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, assert(V && "Expression in template argument isn't constant"); llvm::DIType *TTy = getOrCreateType(T, Unit); TemplateParams.push_back(DBuilder.createTemplateValueParameter( - TheCU, Name, TTy, V->stripPointerCasts())); + TheCU, Name, TTy, defaultParameter, V->stripPointerCasts())); } break; // And the following should never occur: case TemplateArgument::TemplateExpansion: diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index cbc96a483f91f..604740dcdfb30 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -443,19 +443,22 @@ namespace llvm { /// \param Scope Scope in which this type is defined. /// \param Name Type parameter name. /// \param Ty Parameter type. - DITemplateTypeParameter * - createTemplateTypeParameter(DIScope *Scope, StringRef Name, DIType *Ty); + /// \param IsDefault Parameter is default or not + DITemplateTypeParameter *createTemplateTypeParameter(DIScope *Scope, + StringRef Name, + DIType *Ty, + bool IsDefault); /// Create debugging information for template /// value parameter. /// \param Scope Scope in which this type is defined. /// \param Name Value parameter name. /// \param Ty Parameter type. + /// \param IsDefault Parameter is default or not /// \param Val Constant parameter value. - DITemplateValueParameter *createTemplateValueParameter(DIScope *Scope, - StringRef Name, - DIType *Ty, - Constant *Val); + DITemplateValueParameter * + createTemplateValueParameter(DIScope *Scope, StringRef Name, DIType *Ty, + bool IsDefault, Constant *Val); /// Create debugging information for a template template parameter. /// \param Scope Scope in which this type is defined. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index acc518445585e..032ae598c1d45 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -2131,9 +2131,11 @@ class DIModule : public DIScope { /// Base class for template parameters. class DITemplateParameter : public DINode { protected: + bool IsDefault; + DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage, - unsigned Tag, ArrayRef Ops) - : DINode(Context, ID, Storage, Tag, Ops) {} + unsigned Tag, bool IsDefault, ArrayRef Ops) + : DINode(Context, ID, Storage, Tag, Ops), IsDefault(IsDefault) {} ~DITemplateParameter() = default; public: @@ -2142,6 +2144,7 @@ class DITemplateParameter : public DINode { MDString *getRawName() const { return getOperandAs(0); } Metadata *getRawType() const { return getOperand(1); } + bool isDefault() const { return IsDefault; } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DITemplateTypeParameterKind || @@ -2154,30 +2157,35 @@ class DITemplateTypeParameter : public DITemplateParameter { friend class MDNode; DITemplateTypeParameter(LLVMContext &Context, StorageType Storage, - ArrayRef Ops) + bool IsDefault, ArrayRef Ops) : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage, - dwarf::DW_TAG_template_type_parameter, Ops) {} + dwarf::DW_TAG_template_type_parameter, IsDefault, + Ops) {} ~DITemplateTypeParameter() = default; static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name, - DIType *Type, StorageType Storage, + DIType *Type, bool IsDefault, + StorageType Storage, bool ShouldCreate = true) { - return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage, - ShouldCreate); + return getImpl(Context, getCanonicalMDString(Context, Name), Type, + IsDefault, Storage, ShouldCreate); } static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name, - Metadata *Type, StorageType Storage, + Metadata *Type, bool IsDefault, + StorageType Storage, bool ShouldCreate = true); TempDITemplateTypeParameter cloneImpl() const { - return getTemporary(getContext(), getName(), getType()); + return getTemporary(getContext(), getName(), getType(), isDefault()); } public: - DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DIType *Type), - (Name, Type)) - DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type), - (Name, Type)) + DEFINE_MDNODE_GET(DITemplateTypeParameter, + (StringRef Name, DIType *Type, bool IsDefault), + (Name, Type, IsDefault)) + DEFINE_MDNODE_GET(DITemplateTypeParameter, + (MDString *Name, Metadata *Type, bool IsDefault), + (Name, Type, IsDefault)) TempDITemplateTypeParameter clone() const { return cloneImpl(); } @@ -2191,36 +2199,40 @@ class DITemplateValueParameter : public DITemplateParameter { friend class MDNode; DITemplateValueParameter(LLVMContext &Context, StorageType Storage, - unsigned Tag, ArrayRef Ops) + unsigned Tag, bool IsDefault, + ArrayRef Ops) : DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag, - Ops) {} + IsDefault, Ops) {} ~DITemplateValueParameter() = default; static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIType *Type, - Metadata *Value, StorageType Storage, + bool IsDefault, Metadata *Value, + StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type, - Value, Storage, ShouldCreate); + IsDefault, Value, Storage, ShouldCreate); } static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type, - Metadata *Value, StorageType Storage, + bool IsDefault, Metadata *Value, + StorageType Storage, bool ShouldCreate = true); TempDITemplateValueParameter cloneImpl() const { return getTemporary(getContext(), getTag(), getName(), getType(), - getValue()); + isDefault(), getValue()); } public: DEFINE_MDNODE_GET(DITemplateValueParameter, - (unsigned Tag, StringRef Name, DIType *Type, + (unsigned Tag, StringRef Name, DIType *Type, bool IsDefault, Metadata *Value), - (Tag, Name, Type, Value)) - DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name, - Metadata *Type, Metadata *Value), - (Tag, Name, Type, Value)) + (Tag, Name, Type, IsDefault, Value)) + DEFINE_MDNODE_GET(DITemplateValueParameter, + (unsigned Tag, MDString *Name, Metadata *Type, + bool IsDefault, Metadata *Value), + (Tag, Name, Type, IsDefault, Value)) TempDITemplateValueParameter clone() const { return cloneImpl(); } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index a9ccc350052cc..ad74303a784da 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4842,33 +4842,38 @@ bool LLParser::ParseDIModule(MDNode *&Result, bool IsDistinct) { } /// ParseDITemplateTypeParameter: -/// ::= !DITemplateTypeParameter(name: "Ty", type: !1) +/// ::= !DITemplateTypeParameter(name: "Ty", type: !1, defaulted: false) bool LLParser::ParseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(name, MDStringField, ); \ - REQUIRED(type, MDField, ); + REQUIRED(type, MDField, ); \ + OPTIONAL(defaulted, MDBoolField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = - GET_OR_DISTINCT(DITemplateTypeParameter, (Context, name.Val, type.Val)); + Result = GET_OR_DISTINCT(DITemplateTypeParameter, + (Context, name.Val, type.Val, defaulted.Val)); return false; } /// ParseDITemplateValueParameter: /// ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter, -/// name: "V", type: !1, value: i32 7) +/// name: "V", type: !1, defaulted: false, +/// value: i32 7) bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_template_value_parameter)); \ OPTIONAL(name, MDStringField, ); \ OPTIONAL(type, MDField, ); \ + OPTIONAL(defaulted, MDBoolField, ); \ REQUIRED(value, MDField, ); + PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DITemplateValueParameter, - (Context, tag.Val, name.Val, type.Val, value.Val)); + Result = GET_OR_DISTINCT( + DITemplateValueParameter, + (Context, tag.Val, name.Val, type.Val, defaulted.Val, value.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 3cff468dca892..9a78a2bbcb4fd 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1668,27 +1668,34 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_TEMPLATE_TYPE: { - if (Record.size() != 3) + if (Record.size() < 3 || Record.size() > 4) return error("Invalid record"); IsDistinct = Record[0]; - MetadataList.assignValue(GET_OR_DISTINCT(DITemplateTypeParameter, - (Context, getMDString(Record[1]), - getDITypeRefOrNull(Record[2]))), - NextMetadataNo); + MetadataList.assignValue( + GET_OR_DISTINCT(DITemplateTypeParameter, + (Context, getMDString(Record[1]), + getDITypeRefOrNull(Record[2]), + (Record.size() == 4) ? getMDOrNull(Record[3]) + : getMDOrNull(false))), + NextMetadataNo); NextMetadataNo++; break; } case bitc::METADATA_TEMPLATE_VALUE: { - if (Record.size() != 5) + if (Record.size() < 5 || Record.size() > 6) return error("Invalid record"); IsDistinct = Record[0]; + MetadataList.assignValue( - GET_OR_DISTINCT(DITemplateValueParameter, - (Context, Record[1], getMDString(Record[2]), - getDITypeRefOrNull(Record[3]), - getMDOrNull(Record[4]))), + GET_OR_DISTINCT( + DITemplateValueParameter, + (Context, Record[1], getMDString(Record[2]), + getDITypeRefOrNull(Record[3]), + (Record.size() == 6) ? getMDOrNull(Record[4]) : getMDOrNull(false), + (Record.size() == 6) ? getMDOrNull(Record[5]) + : getMDOrNull(Record[4]))), NextMetadataNo); NextMetadataNo++; break; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 6f3ff32279f17..f2ee1fd930a8d 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1792,6 +1792,7 @@ void ModuleBitcodeWriter::writeDITemplateTypeParameter( Record.push_back(N->isDistinct()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getType())); + Record.push_back(N->isDefault()); Stream.EmitRecord(bitc::METADATA_TEMPLATE_TYPE, Record, Abbrev); Record.clear(); @@ -1804,6 +1805,7 @@ void ModuleBitcodeWriter::writeDITemplateValueParameter( Record.push_back(N->getTag()); Record.push_back(VE.getMetadataOrNullID(N->getRawName())); Record.push_back(VE.getMetadataOrNullID(N->getType())); + Record.push_back(N->isDefault()); Record.push_back(VE.getMetadataOrNullID(N->getValue())); Stream.EmitRecord(bitc::METADATA_TEMPLATE_VALUE, Record, Abbrev); diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 049aedd754ab1..7c0b79fcabd93 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2073,6 +2073,7 @@ static void writeDITemplateTypeParameter(raw_ostream &Out, MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); Printer.printString("name", N->getName()); Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false); + Printer.printBool("defaulted", N->isDefault(), /* Default= */ false); Out << ")"; } @@ -2087,6 +2088,7 @@ static void writeDITemplateValueParameter(raw_ostream &Out, Printer.printTag(N); Printer.printString("name", N->getName()); Printer.printMetadata("type", N->getRawType()); + Printer.printBool("defaulted", N->isDefault(), /* Default= */ false); Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false); Out << ")"; } diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index 60003991307d8..762d9a1c1b46a 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -406,25 +406,26 @@ DIBuilder::createObjCProperty(StringRef Name, DIFile *File, unsigned LineNumber, DITemplateTypeParameter * DIBuilder::createTemplateTypeParameter(DIScope *Context, StringRef Name, - DIType *Ty) { + DIType *Ty, bool isDefault) { assert((!Context || isa(Context)) && "Expected compile unit"); - return DITemplateTypeParameter::get(VMContext, Name, Ty); + return DITemplateTypeParameter::get(VMContext, Name, Ty, isDefault); } static DITemplateValueParameter * createTemplateValueParameterHelper(LLVMContext &VMContext, unsigned Tag, DIScope *Context, StringRef Name, DIType *Ty, - Metadata *MD) { + bool IsDefault, Metadata *MD) { assert((!Context || isa(Context)) && "Expected compile unit"); - return DITemplateValueParameter::get(VMContext, Tag, Name, Ty, MD); + return DITemplateValueParameter::get(VMContext, Tag, Name, Ty, IsDefault, MD); } DITemplateValueParameter * DIBuilder::createTemplateValueParameter(DIScope *Context, StringRef Name, - DIType *Ty, Constant *Val) { + DIType *Ty, bool isDefault, + Constant *Val) { return createTemplateValueParameterHelper( VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty, - getConstantOrNull(Val)); + isDefault, getConstantOrNull(Val)); } DITemplateValueParameter * @@ -432,7 +433,7 @@ DIBuilder::createTemplateTemplateParameter(DIScope *Context, StringRef Name, DIType *Ty, StringRef Val) { return createTemplateValueParameterHelper( VMContext, dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty, - MDString::get(VMContext, Val)); + false, MDString::get(VMContext, Val)); } DITemplateValueParameter * @@ -440,7 +441,7 @@ DIBuilder::createTemplateParameterPack(DIScope *Context, StringRef Name, DIType *Ty, DINodeArray Val) { return createTemplateValueParameterHelper( VMContext, dwarf::DW_TAG_GNU_template_parameter_pack, Context, Name, Ty, - Val.get()); + false, Val.get()); } DICompositeType *DIBuilder::createClassType( diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index c470a9696c3d3..b630a2893b4d9 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -724,24 +724,24 @@ DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *Scope, DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIModule, Ops); } -DITemplateTypeParameter *DITemplateTypeParameter::getImpl(LLVMContext &Context, - MDString *Name, - Metadata *Type, - StorageType Storage, - bool ShouldCreate) { +DITemplateTypeParameter * +DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name, + Metadata *Type, bool isDefault, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type)); + DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type, isDefault)); Metadata *Ops[] = {Name, Type}; - DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DITemplateTypeParameter, Ops); + DEFINE_GETIMPL_STORE(DITemplateTypeParameter, (isDefault), Ops); } DITemplateValueParameter *DITemplateValueParameter::getImpl( LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type, - Metadata *Value, StorageType Storage, bool ShouldCreate) { + bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter, (Tag, Name, Type, Value)); + DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter, + (Tag, Name, Type, isDefault, Value)); Metadata *Ops[] = {Name, Type, Value}; - DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag), Ops); + DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag, isDefault), Ops); } DIGlobalVariable * diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index e912c4ba1f709..7f324b1039976 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -843,36 +843,45 @@ template <> struct MDNodeKeyImpl { template <> struct MDNodeKeyImpl { MDString *Name; Metadata *Type; + bool IsDefault; - MDNodeKeyImpl(MDString *Name, Metadata *Type) : Name(Name), Type(Type) {} + MDNodeKeyImpl(MDString *Name, Metadata *Type, bool IsDefault) + : Name(Name), Type(Type), IsDefault(IsDefault) {} MDNodeKeyImpl(const DITemplateTypeParameter *N) - : Name(N->getRawName()), Type(N->getRawType()) {} + : Name(N->getRawName()), Type(N->getRawType()), + IsDefault(N->isDefault()) {} bool isKeyOf(const DITemplateTypeParameter *RHS) const { - return Name == RHS->getRawName() && Type == RHS->getRawType(); + return Name == RHS->getRawName() && Type == RHS->getRawType() && + IsDefault == RHS->isDefault(); } - unsigned getHashValue() const { return hash_combine(Name, Type); } + unsigned getHashValue() const { return hash_combine(Name, Type, IsDefault); } }; template <> struct MDNodeKeyImpl { unsigned Tag; MDString *Name; Metadata *Type; + bool IsDefault; Metadata *Value; - MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, Metadata *Value) - : Tag(Tag), Name(Name), Type(Type), Value(Value) {} + MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *Type, bool IsDefault, + Metadata *Value) + : Tag(Tag), Name(Name), Type(Type), IsDefault(IsDefault), Value(Value) {} MDNodeKeyImpl(const DITemplateValueParameter *N) : Tag(N->getTag()), Name(N->getRawName()), Type(N->getRawType()), - Value(N->getValue()) {} + IsDefault(N->isDefault()), Value(N->getValue()) {} bool isKeyOf(const DITemplateValueParameter *RHS) const { return Tag == RHS->getTag() && Name == RHS->getRawName() && - Type == RHS->getRawType() && Value == RHS->getValue(); + Type == RHS->getRawType() && IsDefault == RHS->isDefault() && + Value == RHS->getValue(); } - unsigned getHashValue() const { return hash_combine(Tag, Name, Type, Value); } + unsigned getHashValue() const { + return hash_combine(Tag, Name, Type, IsDefault, Value); + } }; template <> struct MDNodeKeyImpl { diff --git a/llvm/test/Assembler/DITemplateParameter.ll b/llvm/test/Assembler/DITemplateParameter.ll new file mode 100644 index 0000000000000..d78377adfada8 --- /dev/null +++ b/llvm/test/Assembler/DITemplateParameter.ll @@ -0,0 +1,65 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s +; RUN: verify-uselistorder %s + +; ModuleID = '/dir/test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%class.foo = type { i8 } +%class.foo.0 = type { i8 } +; Function Attrs: noinline norecurse nounwind optnone uwtable +define dso_local i32 @main() #0 !dbg !7 { +entry: + %retval = alloca i32, align 4 + %f1 = alloca %class.foo, align 1 + %f2 = alloca %class.foo.0, align 1 + store i32 0, i32* %retval, align 4 + call void @llvm.dbg.declare(metadata %class.foo* %f1, metadata !11, metadata !DIExpression()), !dbg !16 + call void @llvm.dbg.declare(metadata %class.foo.0* %f2, metadata !17, metadata !DIExpression()), !dbg !23 + ret i32 0, !dbg !24 +} +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline norecurse nounwind optnone uwtable } +attributes #1 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.cpp", directory: "/dir/", checksumkind: CSK_MD5, checksum: "863d08522c2300490dea873efc4b2369") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 5} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 11.0.0"} +!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 29, type: !8, scopeLine: 29, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DILocalVariable(name: "f1", scope: !7, file: !1, line: 30, type: !12) +!12 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "foo", file: !1, line: 26, size: 8, flags: DIFlagTypePassByValue, elements: !2, templateParams: !13, identifier: "_ZTS3fooIiLi6EE") +!13 = !{!14, !15} + +; CHECK: 14 = !DITemplateTypeParameter(name: "T", type: !{{[0-9]*}}) +!14 = !DITemplateTypeParameter(name: "T", type: !10) + +; CHECK: 15 = !DITemplateValueParameter(name: "i", type: !{{[0-9]*}}, value: i32 6) +!15 = !DITemplateValueParameter(name: "i", type: !10, value: i32 6) + +!16 = !DILocation(line: 30, column: 14, scope: !7) +!17 = !DILocalVariable(name: "f2", scope: !7, file: !1, line: 31, type: !18) +!18 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "foo", file: !1, line: 26, size: 8, flags: DIFlagTypePassByValue, elements: !2, templateParams: !19, identifier: "_ZTS3fooIcLi3EE") +!19 = !{!20, !22} + +; CHECK: 20 = !DITemplateTypeParameter({{.*}}, defaulted: true +!20 = !DITemplateTypeParameter(name: "T", type: !21, defaulted: true) +!21 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) + +; CHECK: 22 = !DITemplateValueParameter({{.*}}, defaulted: true +!22 = !DITemplateValueParameter(name: "i", type: !10, defaulted: true, value: i32 3) +!23 = !DILocation(line: 31, column: 9, scope: !7) +!24 = !DILocation(line: 32, column: 3, scope: !7) diff --git a/llvm/test/Bitcode/DITemplateParameter-5.0.ll b/llvm/test/Bitcode/DITemplateParameter-5.0.ll new file mode 100644 index 0000000000000..1659bd6d84a3f --- /dev/null +++ b/llvm/test/Bitcode/DITemplateParameter-5.0.ll @@ -0,0 +1,69 @@ +; RUN: llvm-dis -o - %s.bc | FileCheck %s + +; ModuleID = '/dir/test.cpp' +source_filename = "test.cpp" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%class.foo = type { i8 } +%class.foo.0 = type { i8 } +; Function Attrs: noinline norecurse nounwind optnone uwtable +define dso_local i32 @main() #0 !dbg !7 { +entry: + %retval = alloca i32, align 4 + %f1 = alloca %class.foo, align 1 + %f2 = alloca %class.foo.0, align 1 + store i32 0, i32* %retval, align 4 + call void @llvm.dbg.declare(metadata %class.foo* %f1, metadata !11, metadata !DIExpression()), !dbg !16 + call void @llvm.dbg.declare(metadata %class.foo.0* %f2, metadata !17, metadata !DIExpression()), !dbg !23 + ret i32 0, !dbg !24 +} +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline norecurse nounwind optnone uwtable } +attributes #1 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.cpp", directory: "/dir/", checksumkind: CSK_MD5, checksum: "863d08522c2300490dea873efc4b2369") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 5} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 11.0.0"} +!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 29, type: !8, scopeLine: 29, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{!10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !DILocalVariable(name: "f1", scope: !7, file: !1, line: 30, type: !12) +!12 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "foo", file: !1, line: 26, size: 8, flags: DIFlagTypePassByValue, elements: !2, templateParams: !13, identifier: "_ZTS3fooIiLi6EE") +!13 = !{!14, !15} + +; Old-style DITemplateTypeParameter and DITemplateValueParameter should be +; upgraded to include defaulted flag. + +; CHECK: !DITemplateTypeParameter({{.*}} +!14 = !DITemplateTypeParameter(name: "T", type: !10) + +; CHECK: !DITemplateValueParameter({{.*}} +!15 = !DITemplateValueParameter(name: "i", type: !10, value: i32 6) + +!16 = !DILocation(line: 30, column: 14, scope: !7) +!17 = !DILocalVariable(name: "f2", scope: !7, file: !1, line: 31, type: !18) +!18 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "foo", file: !1, line: 26, size: 8, flags: DIFlagTypePassByValue, elements: !2, templateParams: !19, identifier: "_ZTS3fooIcLi3EE") +!19 = !{!20, !22} + +; CHECK: !DITemplateTypeParameter({{.*}} defaulted: true +!20 = !DITemplateTypeParameter(name: "T", type: !21, defaulted: true) + +!21 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) + +; CHECK: !DITemplateValueParameter({{.*}} defaulted: true +!22 = !DITemplateValueParameter(name: "i", type: !10, defaulted: true, value: i32 3) + +!23 = !DILocation(line: 31, column: 9, scope: !7) +!24 = !DILocation(line: 32, column: 3, scope: !7) diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp index 6c06af8bd71e2..0480f97617311 100644 --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -2076,17 +2076,19 @@ typedef MetadataTest DITemplateTypeParameterTest; TEST_F(DITemplateTypeParameterTest, get) { StringRef Name = "template"; DIType *Type = getBasicType("basic"); + bool defaulted = false; - auto *N = DITemplateTypeParameter::get(Context, Name, Type); + auto *N = DITemplateTypeParameter::get(Context, Name, Type, defaulted); EXPECT_EQ(dwarf::DW_TAG_template_type_parameter, N->getTag()); EXPECT_EQ(Name, N->getName()); EXPECT_EQ(Type, N->getType()); - EXPECT_EQ(N, DITemplateTypeParameter::get(Context, Name, Type)); + EXPECT_EQ(N, DITemplateTypeParameter::get(Context, Name, Type, defaulted)); - EXPECT_NE(N, DITemplateTypeParameter::get(Context, "other", Type)); - EXPECT_NE(N, - DITemplateTypeParameter::get(Context, Name, getBasicType("other"))); + EXPECT_NE(N, DITemplateTypeParameter::get(Context, "other", Type, defaulted)); + EXPECT_NE(N, DITemplateTypeParameter::get(Context, Name, + getBasicType("other"), defaulted)); + EXPECT_NE(N, DITemplateTypeParameter::get(Context, Name, Type, true)); TempDITemplateTypeParameter Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -2098,24 +2100,31 @@ TEST_F(DITemplateValueParameterTest, get) { unsigned Tag = dwarf::DW_TAG_template_value_parameter; StringRef Name = "template"; DIType *Type = getBasicType("basic"); + bool defaulted = false; Metadata *Value = getConstantAsMetadata(); - auto *N = DITemplateValueParameter::get(Context, Tag, Name, Type, Value); + auto *N = + DITemplateValueParameter::get(Context, Tag, Name, Type, defaulted, Value); EXPECT_EQ(Tag, N->getTag()); EXPECT_EQ(Name, N->getName()); EXPECT_EQ(Type, N->getType()); EXPECT_EQ(Value, N->getValue()); - EXPECT_EQ(N, DITemplateValueParameter::get(Context, Tag, Name, Type, Value)); + EXPECT_EQ(N, DITemplateValueParameter::get(Context, Tag, Name, Type, + defaulted, Value)); EXPECT_NE(N, DITemplateValueParameter::get( Context, dwarf::DW_TAG_GNU_template_template_param, Name, - Type, Value)); - EXPECT_NE(N, - DITemplateValueParameter::get(Context, Tag, "other", Type, Value)); + Type, defaulted, Value)); + EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, "other", Type, + defaulted, Value)); EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, Name, - getBasicType("other"), Value)); - EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, Name, Type, - getConstantAsMetadata())); + getBasicType("other"), defaulted, + Value)); + EXPECT_NE(N, + DITemplateValueParameter::get(Context, Tag, Name, Type, defaulted, + getConstantAsMetadata())); + EXPECT_NE( + N, DITemplateValueParameter::get(Context, Tag, Name, Type, true, Value)); TempDITemplateValueParameter Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));