Add support to describe template parameter type in debug info.
authorDevang Patel <dpatel@apple.com>
Wed, 2 Feb 2011 21:38:25 +0000 (21:38 +0000)
committerDevang Patel <dpatel@apple.com>
Wed, 2 Feb 2011 21:38:25 +0000 (21:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124752 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/DIBuilder.h
include/llvm/Analysis/DebugInfo.h
lib/Analysis/DIBuilder.cpp
lib/Analysis/DebugInfo.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h

index 2fb9ed0e966db148306d077d34d1d0754f1d5abd..a948ce2c1d0e2b801a98842f217807c2c541be44 100644 (file)
@@ -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.
index f0effb756715c47c19377bef87ffa94a2ea410f5..b547263669cbe184504f99dbc606744fa6ff6753 100644 (file)
@@ -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<DICompositeType>(12);
     }
+    DIArray getTemplateParams() const { return getFieldAs<DIArray>(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<DIScope>(1); }
+    StringRef getName() const        { return getStringField(2); }
+    DIType getType() const           { return getFieldAs<DIType>(3); }
+    StringRef getFilename() const    { 
+      return getFieldAs<DIFile>(4).getFilename();
+    }
+    StringRef getDirectory() const   { 
+      return getFieldAs<DIFile>(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:
index c59e8285ff1dc110caa45478134c79b5e5a10f26..14147b88f33411c352663ce54cf536d4c4a3e005 100644 (file)
@@ -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, 
index 9e802c64b0e41a4b6f68460b2c2511b172062699..1aaa60ebd268c110301e696d54d94c2388f163d2 100644 (file)
@@ -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;
index 5c63ab5563cda14b75efd49c4c74eff10b42c194..28c41f8a26671dacb24a4f1b83caa14a8a6ef80d 100644 (file)
@@ -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();
index 73451ef670519deca894582fac3af41eddef1d9a..5d2fb5bdea15d02f751e14e2e8fe52d5aa9c080e 100644 (file)
@@ -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.