diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h index 2fb9ed0e966..a948ce2c1d0 100644 --- a/include/llvm/Analysis/DIBuilder.h +++ b/include/llvm/Analysis/DIBuilder.h @@ -38,6 +38,7 @@ namespace llvm { class DISubrange; class DILexicalBlock; class DISubprogram; + class DITemplateTypeParameter; class DIBuilder { private: @@ -157,11 +158,13 @@ namespace llvm { /// for this type. This is used in /// DW_AT_containing_type. See DWARF documentation /// for more info. + /// @param TemplateParms Template type parameters. DIType CreateClassType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, - DIArray Elements, MDNode *VTableHolder = 0); + DIArray Elements, MDNode *VTableHolder = 0, + MDNode *TemplateParms = 0); /// CreateStructType - Create debugging information entry for a struct. /// @param Scope Scope in which this struct is defined. @@ -193,6 +196,19 @@ namespace llvm { uint64_t AlignInBits, unsigned Flags, DIArray Elements, unsigned RunTimeLang = 0); + /// CreateTemplateTypeParameter - Create debugging information for template + /// type parameter. + /// @param Scope Scope in which this type is dfiend + /// @param Name Type parameter name. + /// @param Ty Parameter type. + /// @param File File where this type parameter is defined. + /// @param LineNo Line number. + /// @param ColumnNo Column Number. + DITemplateTypeParameter + CreateTemplateTypeParameter(DIDescriptor Scope, StringRef Name, DIType Ty, + MDNode *File = 0, unsigned LineNo = 0, + unsigned ColumnNo = 0); + /// CreateArrayType - Create debugging information entry for an array. /// @param Size Array size. /// @param AlignInBits Alignment. diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index f0effb75671..b547263669c 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -122,6 +122,7 @@ namespace llvm { bool isType() const; bool isGlobal() const; bool isUnspecifiedParameter() const; + bool isTemplateTypeParameter() const; }; /// DISubrange - This is used to represent ranges, for array bounds. @@ -356,6 +357,7 @@ namespace llvm { DICompositeType getContainingType() const { return getFieldAs(12); } + DIArray getTemplateParams() const { return getFieldAs(13); } /// Verify - Verify that a composite type descriptor is well formed. bool Verify() const; @@ -367,6 +369,24 @@ namespace llvm { void dump() const; }; + /// DITemplateTypeParameter - This is a wrapper for template type parameter. + class DITemplateTypeParameter : public DIDescriptor { + public: + explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {} + + DIScope getContext() const { return getFieldAs(1); } + StringRef getName() const { return getStringField(2); } + DIType getType() const { return getFieldAs(3); } + StringRef getFilename() const { + return getFieldAs(4).getFilename(); + } + StringRef getDirectory() const { + return getFieldAs(4).getDirectory(); + } + unsigned getLineNumber() const { return getUnsignedField(5); } + unsigned getColumnNumber() const { return getUnsignedField(6); } + }; + /// DISubprogram - This is a wrapper for a subprogram (e.g. a function). class DISubprogram : public DIScope { public: diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp index c59e8285ff1..14147b88f33 100644 --- a/lib/Analysis/DIBuilder.cpp +++ b/lib/Analysis/DIBuilder.cpp @@ -242,7 +242,7 @@ DIType DIBuilder::CreateClassType(DIDescriptor Context, StringRef Name, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, - MDNode *VTableHoder) { + MDNode *VTableHoder, MDNode *TemplateParams) { // TAG_class_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_class_type), @@ -257,11 +257,31 @@ DIType DIBuilder::CreateClassType(DIDescriptor Context, StringRef Name, DerivedFrom, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), 0), - VTableHoder + VTableHoder, + TemplateParams }; return DIType(MDNode::get(VMContext, &Elts[0], array_lengthof(Elts))); } +/// CreateTemplateTypeParameter - Create debugging information for template +/// type parameter. +DITemplateTypeParameter +DIBuilder::CreateTemplateTypeParameter(DIDescriptor Context, StringRef Name, + DIType Ty, MDNode *File, unsigned LineNo, + unsigned ColumnNo) { + Value *Elts[] = { + GetTagConstant(VMContext, dwarf::DW_TAG_template_type_parameter), + Context, + MDString::get(VMContext, Name), + Ty, + File, + ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), + ConstantInt::get(Type::getInt32Ty(VMContext), ColumnNo) + }; + return DITemplateTypeParameter(MDNode::get(VMContext, &Elts[0], + array_lengthof(Elts))); +} + /// CreateStructType - Create debugging information entry for a struct. DIType DIBuilder::CreateStructType(DIDescriptor Context, StringRef Name, DIFile File, unsigned LineNumber, diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 9e802c64b0e..1aaa60ebd26 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -221,6 +221,12 @@ bool DIDescriptor::isScope() const { return false; } +/// isTemplateTypeParameter - Return true if the specified tag is +/// DW_TAG_template_type_parameter. +bool DIDescriptor::isTemplateTypeParameter() const { + return DbgNode && getTag() == dwarf::DW_TAG_template_type_parameter; +} + /// isCompileUnit - Return true if the specified tag is DW_TAG_compile_unit. bool DIDescriptor::isCompileUnit() const { return DbgNode && getTag() == dwarf::DW_TAG_compile_unit; diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 5c63ab5563c..28c41f8a266 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1151,6 +1151,18 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { DIDescriptor Context = CTy.getContext(); addToContextOwner(&Buffer, Context); } + + if (Tag == dwarf::DW_TAG_class_type) { + DIArray TParams = CTy.getTemplateParams(); + unsigned N = TParams.getNumElements(); + // Add template parameters. + for (unsigned i = 0; i < N; ++i) { + DIDescriptor Element = TParams.getElement(i); + if (Element.isTemplateTypeParameter()) + Buffer.addChild(getOrCreateTemplateTypeParameterDIE( + DITemplateTypeParameter(Element))); + } + } break; } default: @@ -1181,6 +1193,21 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { } } +/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE +/// for the given DITemplateTypeParameter. +DIE * +DwarfDebug::getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP) { + CompileUnit *TypeCU = getCompileUnit(TP); + DIE *ParamDIE = TypeCU->getDIE(TP); + if (ParamDIE) + return ParamDIE; + + ParamDIE = new DIE(dwarf::DW_TAG_template_type_parameter); + addType(ParamDIE, TP.getType()); + addString(ParamDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, TP.getName()); + return ParamDIE; +} + /// constructSubrangeDIE - Construct subrange DIE from DISubrange. void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){ int64_t L = SR.getLo(); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 73451ef6705..5d2fb5bdea1 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -52,6 +52,7 @@ class DIType; class DINameSpace; class DISubrange; class DICompositeType; +class DITemplateTypeParameter; //===----------------------------------------------------------------------===// /// SrcLineInfo - This class is used to record source line correspondence. @@ -342,6 +343,10 @@ private: /// given DIType. DIE *getOrCreateTypeDIE(DIType Ty); + /// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE + /// for the given DITemplateTypeParameter. + DIE *getOrCreateTemplateTypeParameterDIE(DITemplateTypeParameter TP); + void addPubTypes(DISubprogram SP); /// constructTypeDIE - Construct basic type die from DIBasicType.