Add support to emit debug info for virtual functions and virtual base classes.
authorDevang Patel <dpatel@apple.com>
Thu, 3 Dec 2009 19:11:07 +0000 (19:11 +0000)
committerDevang Patel <dpatel@apple.com>
Thu, 3 Dec 2009 19:11:07 +0000 (19:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90474 91177308-0d34-0410-b5e6-96231b3b80d8

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

index b67468d855708256fc93388a6ed816708d8e0ab8..c560ec2e3594ec3bab4e2de4671a5c3b299e58f6 100644 (file)
@@ -197,7 +197,8 @@ namespace llvm {
       FlagProtected        = 1 << 1,
       FlagFwdDecl          = 1 << 2,
       FlagAppleBlock       = 1 << 3,
-      FlagBlockByrefStruct = 1 << 4
+      FlagBlockByrefStruct = 1 << 4,
+      FlagVirtual          = 1 << 5
     };
 
   protected:
@@ -242,6 +243,9 @@ namespace llvm {
     bool isBlockByrefStruct() const {
       return (getFlags() & FlagBlockByrefStruct) != 0;
     }
+    bool isVirtual() const {
+      return (getFlags() & FlagVirtual) != 0;
+    }
 
     /// dump - print type.
     void dump() const;
@@ -366,6 +370,24 @@ namespace llvm {
     /// compile unit, like 'static' in C.
     unsigned isLocalToUnit() const     { return getUnsignedField(9); }
     unsigned isDefinition() const      { return getUnsignedField(10); }
+
+    unsigned getVirtuality() const {
+      if (DbgNode->getNumElements() < 14)
+        return 0;
+      return getUnsignedField(11);
+    }
+
+    unsigned getVirtualIndex() const { 
+      if (DbgNode->getNumElements() < 14)
+        return 0;
+      return getUnsignedField(12);
+    }
+
+    DICompositeType getContainingType() const {
+      assert (DbgNode->getNumElements() >= 14 && "Invalid type!");
+      return getFieldAs<DICompositeType>(13);
+    }
+
     StringRef getFilename() const    { return getCompileUnit().getFilename();}
     StringRef getDirectory() const   { return getCompileUnit().getDirectory();}
 
@@ -565,7 +587,10 @@ namespace llvm {
                                   StringRef LinkageName,
                                   DICompileUnit CompileUnit, unsigned LineNo,
                                   DIType Type, bool isLocalToUnit,
-                                  bool isDefinition);
+                                  bool isDefinition,
+                                  unsigned VK = 0,
+                                  unsigned VIndex = 0,
+                                  DIType = DIType());
 
     /// CreateSubprogramDefinition - Create new subprogram descriptor for the
     /// given declaration. 
index b1eff9efe16a8ca932e280233d1af9aeb26409b6..4a012ce484f01e9fced800fc73b2ffb7af686177 100644 (file)
@@ -866,7 +866,9 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
                                          DICompileUnit CompileUnit,
                                          unsigned LineNo, DIType Type,
                                          bool isLocalToUnit,
-                                         bool isDefinition) {
+                                         bool isDefinition,
+                                         unsigned VK, unsigned VIndex,
+                                         DIType ContainingType) {
 
   Value *Elts[] = {
     GetTagConstant(dwarf::DW_TAG_subprogram),
@@ -879,9 +881,12 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
     ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
     Type.getNode(),
     ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
-    ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition)
+    ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
+    ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK),
+    ConstantInt::get(Type::getInt32Ty(VMContext), VIndex),
+    ContainingType.getNode()
   };
-  return DISubprogram(MDNode::get(VMContext, &Elts[0], 11));
+  return DISubprogram(MDNode::get(VMContext, &Elts[0], 14));
 }
 
 /// CreateSubprogramDefinition - Create new subprogram descriptor for the
@@ -902,9 +907,12 @@ DISubprogram DIFactory::CreateSubprogramDefinition(DISubprogram &SPDeclaration)
     DeclNode->getElement(7), // LineNo
     DeclNode->getElement(8), // Type
     DeclNode->getElement(9), // isLocalToUnit
-    ConstantInt::get(Type::getInt1Ty(VMContext), true)
+    ConstantInt::get(Type::getInt1Ty(VMContext), true),
+    DeclNode->getElement(11), // Virtuality
+    DeclNode->getElement(12), // VIndex
+    DeclNode->getElement(13)  // Containting Type
   };
-  return DISubprogram(MDNode::get(VMContext, &Elts[0], 11));
+  return DISubprogram(MDNode::get(VMContext, &Elts[0], 14));
 }
 
 /// CreateGlobalVariable - Create a new descriptor for the specified global.
index 0c31d4671d79c30890a05e5d6d3869b7c7afc51e..e16bc2adf2ca4df703eb24f5d07dc3cf50abbb99 100644 (file)
@@ -779,6 +779,7 @@ void DwarfDebug::addType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
     DW_Unit->addDie(Buffer);
   Entry->setEntry(Buffer);
   Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
+  ModuleCU->insertDIE(Ty.getNode(), Buffer);
 }
 
 /// constructTypeDIE - Construct basic type die from DIBasicType.
@@ -1073,12 +1074,17 @@ DIE *DwarfDebug::createMemberDIE(CompileUnit *DW_Unit, const DIDerivedType &DT){
   addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
 
   if (DT.isProtected())
-    addUInt(MemberDie, dwarf::DW_AT_accessibility, 0,
+    addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
             dwarf::DW_ACCESS_protected);
   else if (DT.isPrivate())
-    addUInt(MemberDie, dwarf::DW_AT_accessibility, 0,
+    addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
             dwarf::DW_ACCESS_private);
-
+  else if (DT.getTag() == dwarf::DW_TAG_inheritance)
+    addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
+            dwarf::DW_ACCESS_public);
+  if (DT.isVirtual())
+    addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
+            dwarf::DW_VIRTUALITY_virtual);
   return MemberDie;
 }
 
@@ -1113,11 +1119,22 @@ DIE *DwarfDebug::createRawSubprogramDIE(CompileUnit *DW_Unit,
   DICompositeType SPTy = SP.getType();
   DIArray Args = SPTy.getTypeArray();
   unsigned SPTag = SPTy.getTag();
+
   if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type)
     addType(DW_Unit, SPDie, SPTy);
   else
     addType(DW_Unit, SPDie, DIType(Args.getElement(0).getNode()));
 
+  unsigned VK = SP.getVirtuality();
+  if (VK) {
+    addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
+    DIEBlock *Block = new DIEBlock();
+    addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
+    addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
+    addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
+    ContainingTypeMap.insert(std::make_pair(SPDie, WeakVH(SP.getContainingType().getNode())));
+  }
+
   return SPDie;
 }
 
@@ -1826,6 +1843,17 @@ void DwarfDebug::endModule() {
          TE = TopLevelDIEsVector.end(); TI != TE; ++TI)
     ModuleCU->getCUDie()->addChild(*TI);
 
+  for (DenseMap<DIE *, WeakVH>::iterator CI = ContainingTypeMap.begin(),
+         CE = ContainingTypeMap.end(); CI != CE; ++CI) {
+    DIE *SPDie = CI->first;
+    MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
+    if (!N) continue;
+    DIE *NDie = ModuleCU->getDIE(N);
+    if (!NDie) continue;
+    addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
+    addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
+  }
+
   // Standard sections final addresses.
   Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
   EmitLabel("text_end", 0);
index 002e7772546c9ebc5b92e27b6711c21521a71b44..6c8a28d68319b10e132802b78435d8f5b4c89571 100644 (file)
@@ -154,6 +154,8 @@ class DwarfDebug : public Dwarf {
   /// (at the end of the module) as DW_AT_inline.
   SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
 
+  DenseMap<DIE *, WeakVH> ContainingTypeMap;
+
   /// AbstractSubprogramDIEs - Collection of abstruct subprogram DIEs.
   SmallPtrSet<DIE *, 4> AbstractSubprogramDIEs;