Need only one set of debug info versions enum.
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfWriter.cpp
index 1ef8bec4d18e6462182d84d32e69d0c9a9aa7d89..cbe8d7048b04a44fd2565cba430a4330480acdcb 100644 (file)
@@ -67,24 +67,24 @@ class DIEValue;
 //===----------------------------------------------------------------------===//
 /// Utility routines.
 ///
-/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the            
-/// specified value in their initializer somewhere.                                       
+/// getGlobalVariablesUsing - Return all of the GlobalVariables which have the
+/// specified value in their initializer somewhere.
 static void
 getGlobalVariablesUsing(Value *V, std::vector<GlobalVariable*> &Result) {
-  // Scan though value users.                                                             
+  // Scan though value users. 
   for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I) {
     if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*I)) {
-      // If the user is a GlobalVariable then add to result.                              
+      // If the user is a GlobalVariable then add to result. 
       Result.push_back(GV);
     } else if (Constant *C = dyn_cast<Constant>(*I)) {
-      // If the user is a constant variable then scan its users                           
+      // If the user is a constant variable then scan its users.
       getGlobalVariablesUsing(C, Result);
     }
   }
 }
 
-/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the              
-/// named GlobalVariable.                                                                 
+/// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
+/// named GlobalVariable. 
 static void
 getGlobalVariablesUsing(Module &M, const std::string &RootName,
                         std::vector<GlobalVariable*> &Result) {
@@ -92,11 +92,11 @@ getGlobalVariablesUsing(Module &M, const std::string &RootName,
   FieldTypes.push_back(Type::Int32Ty);
   FieldTypes.push_back(Type::Int32Ty);
 
-  // Get the GlobalVariable root.                                                         
+  // Get the GlobalVariable root.
   GlobalVariable *UseRoot = M.getGlobalVariable(RootName,
                                                 StructType::get(FieldTypes));
 
-  // If present and linkonce then scan for users.                                         
+  // If present and linkonce then scan for users.
   if (UseRoot && UseRoot->hasLinkOnceLinkage())
     getGlobalVariablesUsing(UseRoot, Result);
 }
@@ -779,11 +779,11 @@ private:
 
   /// GVToDieMap - Tracks the mapping of unit level debug informaton
   /// variables to debug information entries.
-  DenseMap<GlobalVariable *, DIE *> GVToDieMap;
+  std::map<GlobalVariable *, DIE *> GVToDieMap;
 
   /// GVToDIEntryMap - Tracks the mapping of unit level debug informaton
   /// descriptors to debug information entries using a DIEntry proxy.
-  DenseMap<GlobalVariable *, DIEntry *> GVToDIEntryMap;
+  std::map<GlobalVariable *, DIEntry *> GVToDIEntryMap;
 
   /// Globals - A map of globally visible named entities for this unit.
   ///
@@ -793,21 +793,14 @@ private:
   ///
   FoldingSet<DIE> DiesSet;
 
-  /// Dies - List of all dies in the compile unit.
-  ///
-  std::vector<DIE *> Dies;
-
 public:
   CompileUnit(unsigned I, DIE *D)
     : ID(I), Die(D), GVToDieMap(),
-      GVToDIEntryMap(), Globals(), DiesSet(InitDiesSetSize), Dies()
+      GVToDIEntryMap(), Globals(), DiesSet(InitDiesSetSize)
   {}
 
   ~CompileUnit() {
     delete Die;
-
-    for (unsigned i = 0, N = Dies.size(); i < N; ++i)
-      delete Dies[i];
   }
 
   // Accessors.
@@ -1277,9 +1270,8 @@ private:
   // Attributes used to construct specific Dwarf sections.
   //
 
-  /// CompileUnits - All the compile units involved in this build.  The index
+  /// DW_CUs - All the compile units involved in this build.  The index
   /// of each entry in this vector corresponds to the sources in MMI.
-  std::vector<CompileUnit *> CompileUnits;
   DenseMap<Value *, CompileUnit *> DW_CUs;
 
   /// AbbreviationsSet - Used to uniquely define abbreviations.
@@ -1290,10 +1282,10 @@ private:
   ///
   std::vector<DIEAbbrev *> Abbreviations;
 
-  /// Directories - Uniquing vector for directories.                                       
+  /// Directories - Uniquing vector for directories.
   UniqueVector<std::string> Directories;
 
-  /// SourceFiles - Uniquing vector for source files.                                      
+  /// SourceFiles - Uniquing vector for source files.
   UniqueVector<SrcFileInfo> SrcFiles;
 
   /// Lines - List of of source line correspondence.
@@ -1567,7 +1559,7 @@ private:
   void AddSourceLine(DIE *Die, const DIVariable *V) {
     unsigned FileID = 0;
     unsigned Line = V->getLineNumber();
-    if (V->getVersion() < DIDescriptor::Version7) {
+    if (V->getVersion() <= LLVMDebugVersion6) {
       // Version6 or earlier. Use compile unit info to get file id.
       CompileUnit *Unit = FindCompileUnit(V->getCompileUnit());
       FileID = Unit->getID();
@@ -1586,7 +1578,7 @@ private:
   void AddSourceLine(DIE *Die, const DIGlobal *G) {
     unsigned FileID = 0;
     unsigned Line = G->getLineNumber();
-    if (G->getVersion() < DIDescriptor::Version7) {
+    if (G->getVersion() < LLVMDebugVersion6) {
       // Version6 or earlier. Use compile unit info to get file id.
       CompileUnit *Unit = FindCompileUnit(G->getCompileUnit());
       FileID = Unit->getID();
@@ -1603,7 +1595,7 @@ private:
   void AddSourceLine(DIE *Die, const DIType *Ty) {
     unsigned FileID = 0;
     unsigned Line = Ty->getLineNumber();
-    if (Ty->getVersion() < DIDescriptor::Version7) {
+    if (Ty->getVersion() <= LLVMDebugVersion6) {
       // Version6 or earlier. Use compile unit info to get file id.
       CompileUnit *Unit = FindCompileUnit(Ty->getCompileUnit());
       FileID = Unit->getID();
@@ -1751,10 +1743,7 @@ private:
   void ConstructTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
                         DICompositeType CTy) {
 
-    /// FIXME - Enable this asap.
-    return;
-
-    // Get core information.                                                              
+    // Get core information.
     const std::string &Name = CTy.getName();
     uint64_t Size = CTy.getSizeInBits() >> 3;
     unsigned Tag = CTy.getTag();
@@ -1763,13 +1752,18 @@ private:
     case DW_TAG_array_type:
       ConstructArrayTypeDIE(DW_Unit, Buffer, &CTy);
       break;
-    //FIXME - Enable this. 
-    // case DW_TAG_enumeration_type:
-    //  DIArray Elements = CTy.getTypeArray();
-    //  // Add enumerators to enumeration type.
-    //  for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) 
-    //   ConstructEnumTypeDIE(Buffer, &Elements.getElement(i));
-    //  break;
+    case DW_TAG_enumeration_type:
+      {
+        DIArray Elements = CTy.getTypeArray();
+        // Add enumerators to enumeration type.
+        for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
+          DIE *ElemDie = NULL;
+          DIEnumerator Enum(Elements.getElement(i).getGV());
+          ElemDie = ConstructEnumTypeDIE(DW_Unit, &Enum);
+          Buffer.AddChild(ElemDie);
+        }
+      }
+      break;
     case DW_TAG_subroutine_type: 
       {
         // Add prototype flag.
@@ -1779,12 +1773,11 @@ private:
         DIDescriptor RTy = Elements.getElement(0);
         AddType(DW_Unit, &Buffer, DIType(RTy.getGV()));
 
-        //AddType(DW_Unit, &Buffer, Elements.getElement(0));
         // Add arguments.
         for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
           DIE *Arg = new DIE(DW_TAG_formal_parameter);
           DIDescriptor Ty = Elements.getElement(i);
-          AddType(DW_Unit, &Buffer, DIType(Ty.getGV()));
+          AddType(DW_Unit, Arg, DIType(Ty.getGV()));
           Buffer.AddChild(Arg);
         }
       }
@@ -1802,16 +1795,21 @@ private:
         // Add elements to structure type.
         for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
           DIDescriptor Element = Elements.getElement(i);
+          DIE *ElemDie = NULL;
           if (Element.getTag() == dwarf::DW_TAG_subprogram)
-            ConstructFieldTypeDIE(DW_Unit, Buffer, DISubprogram(Element.getGV()));
-          else if (Element.getTag() == dwarf::DW_TAG_variable)
-            ConstructFieldTypeDIE(DW_Unit, Buffer, 
-                                  DIGlobalVariable(Element.getGV()));
+            ElemDie = CreateSubprogramDIE(DW_Unit, 
+                                          DISubprogram(Element.getGV()));
+          else if (Element.getTag() == dwarf::DW_TAG_variable) // ???
+            ElemDie = CreateGlobalVariableDIE(DW_Unit, 
+                                              DIGlobalVariable(Element.getGV()));
           else {
             DIDerivedType DT = DIDerivedType(Element.getGV());
-            assert (DT.isDerivedType(DT.getTag()) && "Unexpected strcut element");
-            ConstructFieldTypeDIE(DW_Unit, Buffer, DT);
+            assert (DT.isDerivedType(DT.getTag()) 
+                    && "Unexpected struct element type");
+            ElemDie = new DIE(DT.getTag());
+            AddType(DW_Unit, ElemDie, DT);
           }
+          Buffer.AddChild(ElemDie);
         }
       }
       break;
@@ -1849,8 +1847,8 @@ private:
     if (L != H) {
       AddDIEntry(DW_Subrange, DW_AT_type, DW_FORM_ref4, IndexTy);
       if (L)
-       AddSInt(DW_Subrange, DW_AT_lower_bound, 0, L);
-        AddSInt(DW_Subrange, DW_AT_upper_bound, 0, H);
+        AddSInt(DW_Subrange, DW_AT_lower_bound, 0, L);
+      AddSInt(DW_Subrange, DW_AT_upper_bound, 0, H);
     }
     Buffer.AddChild(DW_Subrange);
   }
@@ -1863,7 +1861,6 @@ private:
       AddUInt(&Buffer, DW_AT_GNU_vector, DW_FORM_flag, 1);
     
     DIArray Elements = CTy->getTypeArray();
-    // FIXME - Enable this. 
     AddType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom());
 
     // Construct an anonymous type for index type.
@@ -1882,96 +1879,65 @@ private:
 
   /// ConstructEnumTypeDIE - Construct enum type DIE from 
   /// DIEnumerator.
-  void ConstructEnumTypeDIE(CompileUnit *DW_Unit, 
-                            DIE &Buffer, DIEnumerator *ETy) {
+  DIE *ConstructEnumTypeDIE(CompileUnit *DW_Unit, DIEnumerator *ETy) {
 
     DIE *Enumerator = new DIE(DW_TAG_enumerator);
     AddString(Enumerator, DW_AT_name, DW_FORM_string, ETy->getName());
     int64_t Value = ETy->getEnumValue();                             
     AddSInt(Enumerator, DW_AT_const_value, DW_FORM_sdata, Value);
-    Buffer.AddChild(Enumerator);
+    return Enumerator;
   }
 
-  /// ConstructFieldTypeDIE - Construct variable DIE for a struct field.
-  void ConstructFieldTypeDIE(CompileUnit *DW_Unit,
-                             DIE &Buffer, DIGlobalVariable V) {
-
-    DIE *VariableDie = new DIE(DW_TAG_variable);
-    const std::string &LinkageName = V.getLinkageName();
+  /// CreateGlobalVariableDIE - Create new DIE using GV.
+  DIE *CreateGlobalVariableDIE(CompileUnit *DW_Unit, const DIGlobalVariable &GV) 
+  {
+    DIE *GVDie = new DIE(DW_TAG_variable);
+    AddString(GVDie, DW_AT_name, DW_FORM_string, GV.getName());
+    const std::string &LinkageName = GV.getLinkageName();
     if (!LinkageName.empty())
-      AddString(VariableDie, DW_AT_MIPS_linkage_name, DW_FORM_string,
-                LinkageName);
-    // FIXME - Enable this. AddSourceLine(VariableDie, V);
-    AddType(DW_Unit, VariableDie, V.getType());
-    if (!V.isLocalToUnit())
-      AddUInt(VariableDie, DW_AT_external, DW_FORM_flag, 1);
-    AddUInt(VariableDie, DW_AT_declaration, DW_FORM_flag, 1);
-    Buffer.AddChild(VariableDie);
-  }
-
-  /// ConstructFieldTypeDIE - Construct subprogram DIE for a struct field.
-  void ConstructFieldTypeDIE(CompileUnit *DW_Unit,
-                             DIE &Buffer, DISubprogram SP,
-                             bool IsConstructor = false) {
-    DIE *Method = new DIE(DW_TAG_subprogram);
-    AddString(Method, DW_AT_name, DW_FORM_string, SP.getName());
+      AddString(GVDie, DW_AT_MIPS_linkage_name, DW_FORM_string, LinkageName);
+    AddType(DW_Unit, GVDie, GV.getType());
+    if (!GV.isLocalToUnit())
+      AddUInt(GVDie, DW_AT_external, DW_FORM_flag, 1);
+    AddSourceLine(GVDie, &GV);
+    return GVDie;
+  }
+
+  /// CreateSubprogramDIE - Create new DIE using SP.
+  DIE *CreateSubprogramDIE(CompileUnit *DW_Unit,
+                           const  DISubprogram &SP,
+                           bool IsConstructor = false) {
+    DIE *SPDie = new DIE(DW_TAG_subprogram);
+    AddString(SPDie, DW_AT_name, DW_FORM_string, SP.getName());
     const std::string &LinkageName = SP.getLinkageName();
     if (!LinkageName.empty())
-      AddString(Method, DW_AT_MIPS_linkage_name, DW_FORM_string, LinkageName);
-    // FIXME - Enable this. AddSourceLine(Method, SP);
-
-    DICompositeType MTy = SP.getType();
-    DIArray Args = MTy.getTypeArray();
+      AddString(SPDie, DW_AT_MIPS_linkage_name, DW_FORM_string, 
+                LinkageName);
+    AddSourceLine(SPDie, &SP);
 
+    DICompositeType SPTy = SP.getType();
+    DIArray Args = SPTy.getTypeArray();
+    
     // Add Return Type.
     if (!IsConstructor) 
-      AddType(DW_Unit, Method, DIType(Args.getElement(0).getGV()));
-
+      AddType(DW_Unit, SPDie, DIType(Args.getElement(0).getGV()));
+    
     // Add arguments.
-    for (unsigned i = 1, N =  Args.getNumElements(); i < N; ++i) {
-      DIE *Arg = new DIE(DW_TAG_formal_parameter);
-      AddType(DW_Unit, Method, DIType(Args.getElement(i).getGV()));
-      AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ???
-      Method->AddChild(Arg);
-    }
-
+    if (!Args.isNull())
+      for (unsigned i = 1, N =  Args.getNumElements(); i < N; ++i) {
+        DIE *Arg = new DIE(DW_TAG_formal_parameter);
+        AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV()));
+        AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ???
+        SPDie->AddChild(Arg);
+      }
+    
     if (!SP.isLocalToUnit())
-      AddUInt(Method, DW_AT_external, DW_FORM_flag, 1);                     
-    Buffer.AddChild(Method);
+      AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1);                     
+    return SPDie;
   }
 
-  /// ConstructFieldTypeDIE - Construct derived type DIE for a struct field.
- void ConstructFieldTypeDIE(CompileUnit *DW_Unit, DIE &Buffer,
-                            DIDerivedType DTy) {
-    unsigned Tag = DTy.getTag();
-    DIE *MemberDie = new DIE(Tag);
-    if (!DTy.getName().empty())
-      AddString(MemberDie, DW_AT_name, DW_FORM_string, DTy.getName());
-    // FIXME - Enable this. AddSourceLine(MemberDie, DTy);
-
-    DIType FromTy = DTy.getTypeDerivedFrom();
-    AddType(DW_Unit, MemberDie, FromTy);
-
-    uint64_t Size = DTy.getSizeInBits();
-    uint64_t Offset = DTy.getOffsetInBits();
-
-    // FIXME Handle bitfields                                                      
-
-    // Add size.
-    AddUInt(MemberDie, DW_AT_bit_size, 0, Size);
-    // Add computation for offset.                                                        
-    DIEBlock *Block = new DIEBlock();
-    AddUInt(Block, 0, DW_FORM_data1, DW_OP_plus_uconst);
-    AddUInt(Block, 0, DW_FORM_udata, Offset >> 3);
-    AddBlock(MemberDie, DW_AT_data_member_location, 0, Block);
-
-    // FIXME Handle DW_AT_accessibility.
-
-    Buffer.AddChild(MemberDie);
-  }
-
-  /// FindCompileUnit - Get the compile unit for the given descriptor.                    
-  ///                                                                                     
+  /// FindCompileUnit - Get the compile unit for the given descriptor. 
+  ///
   CompileUnit *FindCompileUnit(DICompileUnit Unit) {
     CompileUnit *DW_Unit = DW_CUs[Unit.getGV()];
     assert(DW_Unit && "Missing compile unit.");
@@ -2639,7 +2605,8 @@ private:
                    "func_begin", DebugFrameInfo.Number);
     Asm->EOL("FDE address range");
 
-    EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, false);
+    EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, 
+                   false);
 
     Asm->EmitAlignment(2, 0, 0, false);
     EmitLabel("debug_frame_end", DebugFrameInfo.Number);
@@ -2669,7 +2636,8 @@ private:
                         Unit->getID(), 0, true, false);
       Asm->EOL("Offset of Compilation Unit Info");
       
-      EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(),true);
+      EmitDifference("info_end", Unit->getID(), "info_begin", Unit->getID(),
+                     true);
       Asm->EOL("Compilation Unit Length");
       
       std::map<std::string, DIE *> &Globals = Unit->getGlobals();
@@ -2817,25 +2785,13 @@ private:
       DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
       if (Slot) continue;
 
-      DIE *VariableDie = new DIE(DW_TAG_variable);
-      AddString(VariableDie, DW_AT_name, DW_FORM_string, DI_GV.getName());
-      const std::string &LinkageName  = DI_GV.getLinkageName();
-      if (!LinkageName.empty())
-        AddString(VariableDie, DW_AT_MIPS_linkage_name, DW_FORM_string,
-                  LinkageName);
-      AddType(DW_Unit, VariableDie, DI_GV.getType());
-
-      if (!DI_GV.isLocalToUnit())
-        AddUInt(VariableDie, DW_AT_external, DW_FORM_flag, 1);              
-
-      // Add source line info, if available.
-      AddSourceLine(VariableDie, &DI_GV);
+      DIE *VariableDie = CreateGlobalVariableDIE(DW_Unit, DI_GV);
 
       // Add address.
       DIEBlock *Block = new DIEBlock();
       AddUInt(Block, 0, DW_FORM_data1, DW_OP_addr);
       AddObjectLabel(Block, 0, DW_FORM_udata,
-                     Asm->getGlobalLinkName(DI_GV.getGV()));
+                     Asm->getGlobalLinkName(DI_GV.getGlobal()));
       AddBlock(VariableDie, DW_AT_location, 0, Block);
 
       //Add to map.
@@ -2862,23 +2818,12 @@ private:
       DISubprogram SP(*RI);
       CompileUnit *Unit = FindCompileUnit(SP.getCompileUnit());
 
-      // Check for pre-existence.                                                         
+      // Check for pre-existence.
       DIE *&Slot = Unit->getDieMapSlotFor(SP.getGV());
       if (Slot) continue;
 
-      DIE *SubprogramDie = new DIE(DW_TAG_subprogram);
-      AddString(SubprogramDie, DW_AT_name, DW_FORM_string, SP.getName());
-      const std::string &LinkageName = SP.getLinkageName();
-      if (!LinkageName.empty())
-        AddString(SubprogramDie, DW_AT_MIPS_linkage_name, DW_FORM_string,
-                  LinkageName);
-      DIType SPTy = SP.getType();
-      AddType(Unit, SubprogramDie, SPTy);
-      if (!SP.isLocalToUnit())
-        AddUInt(SubprogramDie, DW_AT_external, DW_FORM_flag, 1);
-      AddUInt(SubprogramDie, DW_AT_prototyped, DW_FORM_flag, 1);
-
-      AddSourceLine(SubprogramDie, &SP);
+      DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP);
+
       //Add to map.
       Slot = SubprogramDie;
       //Add to context owner.
@@ -2894,7 +2839,6 @@ public:
   //
   DwarfDebug(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T)
   : Dwarf(OS, A, T, "dbg")
-  , CompileUnits()
   , AbbreviationsSet(InitAbbreviationsSetSize)
   , Abbreviations()
   , ValuesSet(InitValuesSetSize)
@@ -2908,8 +2852,6 @@ public:
   {
   }
   virtual ~DwarfDebug() {
-    for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i)
-      delete CompileUnits[i];
     for (unsigned j = 0, M = Values.size(); j < M; ++j)
       delete Values[j];
   }
@@ -3087,6 +3029,9 @@ public:
   /// ValidDebugInfo - Return true if V represents valid debug info value.
   bool ValidDebugInfo(Value *V) {
 
+    if (!V)
+      return false;
+
     if (!shouldEmit)
       return false;
 
@@ -3101,10 +3046,24 @@ public:
     DIDescriptor DI(GV);
     // Check current version. Allow Version6 for now.
     unsigned Version = DI.getVersion();
-    if (Version != DIDescriptor::Version7 && Version != DIDescriptor::Version6)
+    if (Version != LLVMDebugVersion && Version != LLVMDebugVersion6)
       return false;
 
-    //FIXME - Check individual descriptors.
+    unsigned Tag = DI.getTag();
+    switch (Tag) {
+    case DW_TAG_variable:
+      assert (DIVariable(GV).Verify() && "Invalid DebugInfo value");
+      break;
+    case DW_TAG_compile_unit:
+      assert (DICompileUnit(GV).Verify() && "Invalid DebugInfo value");
+      break;
+    case DW_TAG_subprogram:
+      assert (DISubprogram(GV).Verify() && "Invalid DebugInfo value");
+      break;
+    default:
+      break;
+    }
+
     return true;
   }
 
@@ -3324,7 +3283,7 @@ private:
     // If the corresponding function is static, this should not be
     // externally visible.
     if (linkage != Function::InternalLinkage &&
-       linkage != Function::PrivateLinkage) {
+        linkage != Function::PrivateLinkage) {
       if (const char *GlobalEHDirective = TAI->getGlobalEHDirective())
         O << GlobalEHDirective << EHFrameInfo.FnName << "\n";
     }
@@ -3401,7 +3360,8 @@ private:
 
       // Indicate locations of function specific  callee saved registers in
       // frame.
-      EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, true);
+      EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, 
+                     true);
 
       // On Darwin the linker honors the alignment of eh_frame, which means it
       // must be 8-byte on 64-bit targets to match what gcc does.  Otherwise