[llvm-commits] [llvm] r90805 - in /llvm/trunk: include/llvm/Analysis/DebugInfo.h lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfDebug.cpp lib/CodeGen/AsmPrinter/DwarfDebug.h

Devang Patel dpatel at apple.com
Mon Dec 7 13:41:32 PST 2009


Author: dpatel
Date: Mon Dec  7 15:41:32 2009
New Revision: 90805

URL: http://llvm.org/viewvc/llvm-project?rev=90805&view=rev
Log:
Add support to emit debug info for c++ style namespaces.


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

Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=90805&r1=90804&r2=90805&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Dec  7 15:41:32 2009
@@ -99,6 +99,7 @@
     bool isGlobalVariable() const;
     bool isScope() const;
     bool isCompileUnit() const;
+    bool isNameSpace() const;
     bool isLexicalBlock() const;
     bool isSubrange() const;
     bool isEnumerator() const;
@@ -218,7 +219,7 @@
     virtual ~DIType() {}
 
     DIDescriptor getContext() const     { return getDescriptorField(1); }
-    StringRef getName() const         { return getStringField(2);     }
+    StringRef getName() const           { return getStringField(2);     }
     DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
     unsigned getLineNumber() const      { return getUnsignedField(4); }
     uint64_t getSizeInBits() const      { return getUInt64Field(5); }
@@ -470,6 +471,22 @@
     StringRef getFilename() const  { return getContext().getFilename(); }
   };
 
+  /// DINameSpace - A wrapper for a C++ style name space.
+  class DINameSpace : public DIScope { 
+  public:
+    explicit DINameSpace(MDNode *N = 0) : DIScope(N) {
+      if (DbgNode && !isNameSpace())
+        DbgNode = 0;
+    }
+
+    DIScope getContext() const     { return getFieldAs<DIScope>(1);      }
+    StringRef getName() const      { return getStringField(2);           }
+    StringRef getDirectory() const { return getContext().getDirectory(); }
+    StringRef getFilename() const  { return getContext().getFilename();  }
+    DICompileUnit getCompileUnit() const { return getFieldAs<DICompileUnit>(3); }
+    unsigned getLineNumber() const { return getUnsignedField(4);         }
+  };
+
   /// DILocation - This object holds location information. This object
   /// is not associated with any DWARF tag.
   class DILocation : public DIDescriptor {
@@ -624,6 +641,11 @@
     /// with the specified parent context.
     DILexicalBlock CreateLexicalBlock(DIDescriptor Context);
 
+    /// CreateNameSpace - This creates new descriptor for a namespace
+    /// with the specified parent context.
+    DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name,
+                                DICompileUnit CU, unsigned LineNo);
+
     /// CreateLocation - Creates a debug info location.
     DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo,
                               DIScope S, DILocation OrigLoc);

Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=90805&r1=90804&r2=90805&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/DebugInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Dec  7 15:41:32 2009
@@ -227,6 +227,7 @@
     case dwarf::DW_TAG_compile_unit:
     case dwarf::DW_TAG_lexical_block:
     case dwarf::DW_TAG_subprogram:
+    case dwarf::DW_TAG_namespace:
       return true;
     default:
       break;
@@ -242,6 +243,14 @@
   return Tag == dwarf::DW_TAG_compile_unit;
 }
 
+/// isNameSpace - Return true if the specified tag is DW_TAG_namespace.
+bool DIDescriptor::isNameSpace() const {
+  assert (!isNull() && "Invalid descriptor!");
+  unsigned Tag = getTag();
+
+  return Tag == dwarf::DW_TAG_namespace;
+}
+
 /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block.
 bool DIDescriptor::isLexicalBlock() const {
   assert (!isNull() && "Invalid descriptor!");
@@ -438,6 +447,8 @@
     return DISubprogram(DbgNode).getFilename();
   else if (isCompileUnit())
     return DICompileUnit(DbgNode).getFilename();
+  else if (isNameSpace())
+    return DINameSpace(DbgNode).getFilename();
   else 
     assert (0 && "Invalid DIScope!");
   return StringRef();
@@ -450,6 +461,8 @@
     return DISubprogram(DbgNode).getDirectory();
   else if (isCompileUnit())
     return DICompileUnit(DbgNode).getDirectory();
+  else if (isNameSpace())
+    return DINameSpace(DbgNode).getDirectory();
   else 
     assert (0 && "Invalid DIScope!");
   return StringRef();
@@ -996,6 +1009,21 @@
   return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 2));
 }
 
+/// CreateNameSpace - This creates new descriptor for a namespace
+/// with the specified parent context.
+DINameSpace DIFactory::CreateNameSpace(DIDescriptor Context, StringRef Name,
+                                       DICompileUnit CompileUnit, 
+                                       unsigned LineNo) {
+  Value *Elts[] = {
+    GetTagConstant(dwarf::DW_TAG_namespace),
+    Context.getNode(),
+    MDString::get(VMContext, Name),
+    CompileUnit.getNode(),
+    ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)
+  };
+  return DINameSpace(MDNode::get(VMContext, &Elts[0], 5));
+}
+
 /// CreateLocation - Creates a debug info location.
 DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo,
                                      DIScope S, DILocation OrigLoc) {

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=90805&r1=90804&r2=90805&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Dec  7 15:41:32 2009
@@ -446,6 +446,23 @@
   addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
 }
 
+/// addSourceLine - Add location information to specified debug information
+/// entry.
+void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) {
+  // If there is no compile unit specified, don't add a line #.
+  if (NS->getCompileUnit().isNull())
+    return;
+
+  unsigned Line = NS->getLineNumber();
+  StringRef FN = NS->getFilename();
+  StringRef Dir = NS->getDirectory();
+
+  unsigned FileID = GetOrCreateSourceID(Dir, FN);
+  assert(FileID && "Invalid file id");
+  addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
+  addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
+}
+
 /* Byref variables, in Blocks, are declared by the programmer as
    "SomeType VarName;", but the compiler creates a
    __Block_byref_x_VarName struct, and gives the variable VarName
@@ -771,9 +788,13 @@
   // Add debug information entry to entity and appropriate context.
   DIE *Die = NULL;
   DIDescriptor Context = Ty.getContext();
-  if (!Context.isNull())
-    Die = DW_Unit->getDIE(Context.getNode());
-
+  if (!Context.isNull()) {
+    if (Context.isNameSpace()) {
+      DINameSpace NS(Context.getNode());
+      Die = getOrCreateNameSpace(NS);
+    } else
+      Die = DW_Unit->getDIE(Context.getNode());
+  }
   if (Die)
     Die->addChild(Buffer);
   else
@@ -1643,6 +1664,29 @@
   return SrcId;
 }
 
+/// getOrCreateNameSpace - Create a DIE for DINameSpace.
+DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace &NS) {
+  DIE *NDie = ModuleCU->getDIE(NS.getNode());
+  if (NDie)
+    return NDie;
+
+  NDie = new DIE(dwarf::DW_TAG_namespace);
+  ModuleCU->insertDIE(NS.getNode(), NDie);
+  if (!NS.getName().empty())
+    addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
+  addSourceLine(NDie, &NS);
+  DIDescriptor NSContext = NS.getContext();
+  DIE *Context = NULL;
+  if (NSContext.isNameSpace()) {
+    DINameSpace NS2(NSContext.getNode());
+    Context = getOrCreateNameSpace(NS2);
+  }
+  else
+    Context = ModuleCU->getCUDie();
+  Context->addChild(NDie);
+  return NDie;
+}
+
 void DwarfDebug::constructCompileUnit(MDNode *N) {
   DICompileUnit DIUnit(N);
   StringRef FN = DIUnit.getFilename();
@@ -1734,10 +1778,17 @@
   ModuleCU->insertDIE(N, SubprogramDie);
 
   // Add to context owner.
-  if (SP.getContext().getNode() == SP.getCompileUnit().getNode())
+  DIDescriptor SPContext = SP.getContext();
+  if (SPContext.isCompileUnit() 
+      && SPContext.getNode() == SP.getCompileUnit().getNode()) {
     if (TopLevelDIEs.insert(SubprogramDie))
       TopLevelDIEsVector.push_back(SubprogramDie);
-
+  } else if (SPContext.isNameSpace()) {
+    DINameSpace NS(SPContext.getNode());
+    DIE *NDie = getOrCreateNameSpace(NS);
+    NDie->addChild(SubprogramDie);
+  }
+  
   // Expose as global.
   ModuleCU->addGlobal(SP.getName(), SubprogramDie);
 
@@ -1780,10 +1831,18 @@
   for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
          E = DbgFinder.global_variable_end(); I != E; ++I) {
     DIGlobalVariable GV(*I);
-    if (GV.getContext().getNode() != GV.getCompileUnit().getNode())
-      ScopedGVs.push_back(*I);
-    else
+    DIDescriptor GVContext = GV.getContext();
+    if (GVContext.isCompileUnit() 
+        && GVContext.getNode() == GV.getCompileUnit().getNode())
       constructGlobalVariableDIE(*I);
+    else if (GVContext.isNameSpace()) {
+      DIE *GVDie = createGlobalVariableDIE(ModuleCU, GV);
+      DINameSpace NS(GVContext.getNode());
+      DIE *NDie = getOrCreateNameSpace(NS);
+      NDie->addChild(GVDie);
+    }
+    else 
+      ScopedGVs.push_back(*I);
   }
 
   // Create DIEs for each subprogram.

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=90805&r1=90804&r2=90805&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Mon Dec  7 15:41:32 2009
@@ -289,6 +289,7 @@
   void addSourceLine(DIE *Die, const DIGlobal *G);
   void addSourceLine(DIE *Die, const DISubprogram *SP);
   void addSourceLine(DIE *Die, const DIType *Ty);
+  void addSourceLine(DIE *Die, const DINameSpace *NS);
 
   /// addAddress - Add an address attribute to a die based on the location
   /// provided.
@@ -340,6 +341,9 @@
   /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
   DIE *constructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy);
 
+  /// getOrCreateNameSpace - Create a DIE for DINameSpace.
+  DIE *getOrCreateNameSpace(DINameSpace &NS);
+
   /// createGlobalVariableDIE - Create new DIE using GV.
   DIE *createGlobalVariableDIE(CompileUnit *DW_Unit,
                                const DIGlobalVariable &GV);





More information about the llvm-commits mailing list