DebugInfo: Do not include variables only referenced by templates in aranges.
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfCompileUnit.cpp
index 2489002f7fde3cd2039d126f3ac43894033e6faa..e6b3331cf6280b157602f9917d52584c3f4f4a87 100644 (file)
@@ -40,16 +40,16 @@ static cl::opt<bool> GenerateTypeUnits("generate-type-units", cl::Hidden,
 /// CompileUnit - Compile unit constructor.
 CompileUnit::CompileUnit(unsigned UID, DIE *D, DICompileUnit Node,
                          AsmPrinter *A, DwarfDebug *DW, DwarfUnits *DWU)
-    : UniqueID(UID), Node(Node), CUDie(D), Asm(A), DD(DW), DU(DWU),
-      IndexTyDie(0), Language(Node.getLanguage()) {
+    : UniqueID(UID), Node(Node), Language(Node.getLanguage()), CUDie(D),
+      DebugInfoOffset(0), Asm(A), DD(DW), DU(DWU), IndexTyDie(0) {
   DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
   insertDIE(Node, D);
 }
 
 CompileUnit::CompileUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,
                          DwarfDebug *DD, DwarfUnits *DU)
-    : UniqueID(UID), Node(NULL), CUDie(D), Asm(A), DD(DD), DU(DU),
-      IndexTyDie(0), Language(Language) {
+    : UniqueID(UID), Node(NULL), Language(Language), CUDie(D),
+      DebugInfoOffset(0), Asm(A), DD(DD), DU(DU), IndexTyDie(0) {
   DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
 }
 
@@ -112,8 +112,13 @@ int64_t CompileUnit::getDefaultLowerBound() const {
 
 /// Check whether the DIE for this MDNode can be shared across CUs.
 static bool isShareableAcrossCUs(DIDescriptor D) {
-  // When the MDNode can be part of the type system, the DIE can be
-  // shared across CUs.
+  // When the MDNode can be part of the type system, the DIE can be shared
+  // across CUs.
+  // Combining type units and cross-CU DIE sharing is lower value (since
+  // cross-CU DIE sharing is used in LTO and removes type redundancy at that
+  // level already) but may be implementable for some value in projects
+  // building multiple independent libraries with LTO and then linking those
+  // together.
   return (D.isType() ||
           (D.isSubprogram() && !DISubprogram(D).isDefinition())) &&
          !GenerateTypeUnits;
@@ -240,6 +245,26 @@ void CompileUnit::addLabel(DIEBlock *Die, dwarf::Form Form,
   addLabel(Die, (dwarf::Attribute)0, Form, Label);
 }
 
+/// addSectionLabel - Add a Dwarf section label attribute data and value.
+///
+void CompileUnit::addSectionLabel(DIE *Die, dwarf::Attribute Attribute,
+                                  const MCSymbol *Label) {
+  if (DD->getDwarfVersion() >= 4)
+    addLabel(Die, Attribute, dwarf::DW_FORM_sec_offset, Label);
+  else
+    addLabel(Die, Attribute, dwarf::DW_FORM_data4, Label);
+}
+
+/// addSectionOffset - Add an offset into a section attribute data and value.
+///
+void CompileUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute,
+                                   uint64_t Integer) {
+  if (DD->getDwarfVersion() >= 4)
+    addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer);
+  else
+    addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer);
+}
+
 /// addLabelAddress - Add a dwarf label attribute data and value using
 /// DW_FORM_addr or DW_FORM_GNU_addr_index.
 ///
@@ -267,7 +292,6 @@ void CompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
 /// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
 ///
 void CompileUnit::addOpAddress(DIEBlock *Die, const MCSymbol *Sym) {
-  DD->addArangeLabel(SymbolCU(this, Sym));
   if (!DD->useSplitDwarf()) {
     addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
     addLabel(Die, dwarf::DW_FORM_udata, Sym);
@@ -277,13 +301,15 @@ void CompileUnit::addOpAddress(DIEBlock *Die, const MCSymbol *Sym) {
   }
 }
 
-/// addDelta - Add a label delta attribute data and value.
+/// addSectionDelta - Add a section label delta attribute data and value.
 ///
-void CompileUnit::addDelta(DIE *Die, dwarf::Attribute Attribute,
-                           dwarf::Form Form, const MCSymbol *Hi,
-                           const MCSymbol *Lo) {
+void CompileUnit::addSectionDelta(DIE *Die, dwarf::Attribute Attribute,
+                                  const MCSymbol *Hi, const MCSymbol *Lo) {
   DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
-  Die->addValue(Attribute, Form, Value);
+  if (DD->getDwarfVersion() >= 4)
+    Die->addValue(Attribute, dwarf::DW_FORM_sec_offset, Value);
+  else
+    Die->addValue(Attribute, dwarf::DW_FORM_data4, Value);
 }
 
 /// addDIEEntry - Add a DIE attribute data and value.
@@ -886,7 +912,8 @@ DIE *CompileUnit::getOrCreateContextDIE(DIScope Context) {
 }
 
 DIE *CompileUnit::createTypeDIE(DICompositeType Ty) {
-  DIE *ContextDIE = getOrCreateContextDIE(resolve(Ty.getContext()));
+  DIScope Context = resolve(Ty.getContext());
+  DIE *ContextDIE = getOrCreateContextDIE(Context);
 
   DIE *TyDIE = getDIE(Ty);
   if (TyDIE)
@@ -895,12 +922,46 @@ DIE *CompileUnit::createTypeDIE(DICompositeType Ty) {
   // Create new type.
   TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
 
-  constructTypeDIEImpl(*TyDIE, Ty);
+  constructTypeDIE(*TyDIE, Ty);
 
-  updateAcceleratorTables(Ty, TyDIE);
+  updateAcceleratorTables(Context, Ty, TyDIE);
   return TyDIE;
 }
 
+/// Return true if the type is appropriately scoped to be contained inside
+/// its own type unit.
+static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) {
+  DIScope Parent = DD->resolve(Ty.getContext());
+  while (Parent) {
+    // Don't generate a hash for anything scoped inside a function.
+    if (Parent.isSubprogram())
+      return false;
+    Parent = DD->resolve(Parent.getContext());
+  }
+  return true;
+}
+
+/// Return true if the type should be split out into a type unit.
+static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) {
+  if (!GenerateTypeUnits)
+    return false;
+
+  uint16_t Tag = CTy.getTag();
+
+  switch (Tag) {
+  case dwarf::DW_TAG_structure_type:
+  case dwarf::DW_TAG_union_type:
+  case dwarf::DW_TAG_enumeration_type:
+  case dwarf::DW_TAG_class_type:
+    // If this is a class, structure, union, or enumeration type
+    // that is a definition (not a declaration), and not scoped
+    // inside a function then separate this out as a type unit.
+    return !CTy.isForwardDecl() && isTypeUnitScoped(CTy, DD);
+  default:
+    return false;
+  }
+}
+
 /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
 /// given DIType.
 DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
@@ -912,7 +973,8 @@ DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
 
   // Construct the context before querying for the existence of the DIE in case
   // such construction creates the DIE.
-  DIE *ContextDIE = getOrCreateContextDIE(resolve(Ty.getContext()));
+  DIScope Context = resolve(Ty.getContext());
+  DIE *ContextDIE = getOrCreateContextDIE(Context);
   assert(ContextDIE);
 
   DIE *TyDIE = getDIE(Ty);
@@ -924,19 +986,26 @@ DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
 
   if (Ty.isBasicType())
     constructTypeDIE(*TyDIE, DIBasicType(Ty));
-  else if (Ty.isCompositeType())
-    constructTypeDIE(*TyDIE, DICompositeType(Ty));
-  else {
+  else if (Ty.isCompositeType()) {
+    DICompositeType CTy(Ty);
+    if (shouldCreateTypeUnit(CTy, DD)) {
+      DD->addTypeUnitType(TyDIE, CTy);
+      // Skip updating the accellerator tables since this is not the full type
+      return TyDIE;
+    }
+    constructTypeDIE(*TyDIE, CTy);
+  } else {
     assert(Ty.isDerivedType() && "Unknown kind of DIType");
     constructTypeDIE(*TyDIE, DIDerivedType(Ty));
   }
 
-  updateAcceleratorTables(Ty, TyDIE);
+  updateAcceleratorTables(Context, Ty, TyDIE);
 
   return TyDIE;
 }
 
-void CompileUnit::updateAcceleratorTables(DIType Ty, const DIE *TyDIE) {
+void CompileUnit::updateAcceleratorTables(DIScope Context, DIType Ty,
+                                          const DIE *TyDIE) {
   if (!Ty.getName().empty() && !Ty.isForwardDecl()) {
     bool IsImplementation = 0;
     if (Ty.isCompositeType()) {
@@ -947,6 +1016,10 @@ void CompileUnit::updateAcceleratorTables(DIType Ty, const DIE *TyDIE) {
     }
     unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0;
     addAccelType(Ty.getName(), std::make_pair(TyDIE, Flags));
+
+    if (!Context || Context.isCompileUnit() || Context.isFile() ||
+        Context.isNameSpace())
+      GlobalTypes[getParentContextString(Context) + Ty.getName().str()] = TyDIE;
   }
 }
 
@@ -969,10 +1042,6 @@ void CompileUnit::addType(DIE *Entity, DIType Ty, dwarf::Attribute Attribute) {
   Entry = createDIEEntry(Buffer);
   insertDIEEntry(Ty, Entry);
   addDIEEntry(Entity, Attribute, Entry);
-
-  // If this is a complete composite type then include it in the
-  // list of global types.
-  addGlobalType(Ty);
 }
 
 // Accelerator table mutators - add each name along with its companion
@@ -1010,20 +1079,6 @@ void CompileUnit::addGlobalName(StringRef Name, DIE *Die, DIScope Context) {
   GlobalNames[FullName] = Die;
 }
 
-/// addGlobalType - Add a new global type to the compile unit.
-///
-void CompileUnit::addGlobalType(DIType Ty) {
-  DIScope Context = resolve(Ty.getContext());
-  if (!Ty.getName().empty() && !Ty.isForwardDecl() &&
-      (!Context || Context.isCompileUnit() || Context.isFile() ||
-       Context.isNameSpace()))
-    if (DIEEntry *Entry = getDIEEntry(Ty)) {
-      std::string FullName =
-          getParentContextString(Context) + Ty.getName().str();
-      GlobalTypes[FullName] = Entry->getEntry();
-    }
-}
-
 /// getParentContextString - Walks the metadata parent chain in a language
 /// specific manner (using the compile unit language) and returns
 /// it as a string. This is done at the metadata level because DIEs may
@@ -1064,22 +1119,6 @@ std::string CompileUnit::getParentContextString(DIScope Context) const {
   return CS;
 }
 
-/// addPubTypes - Add subprogram argument types for pubtypes section.
-void CompileUnit::addPubTypes(DISubprogram SP) {
-  DICompositeType SPTy = SP.getType();
-  uint16_t SPTag = SPTy.getTag();
-  if (SPTag != dwarf::DW_TAG_subroutine_type)
-    return;
-
-  DIArray Args = SPTy.getTypeArray();
-  for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
-    DIType ATy(Args.getElement(i));
-    if (!ATy.isType())
-      continue;
-    addGlobalType(ATy);
-  }
-}
-
 /// constructTypeDIE - Construct basic type die from DIBasicType.
 void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
   // Get core information.
@@ -1127,51 +1166,8 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
     addSourceLine(&Buffer, DTy);
 }
 
-/// Return true if the type is appropriately scoped to be contained inside
-/// its own type unit.
-static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) {
-  DIScope Parent = DD->resolve(Ty.getContext());
-  while (Parent) {
-    // Don't generate a hash for anything scoped inside a function.
-    if (Parent.isSubprogram())
-      return false;
-    Parent = DD->resolve(Parent.getContext());
-  }
-  return true;
-}
-
-/// Return true if the type should be split out into a type unit.
-static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) {
-  if (!GenerateTypeUnits)
-    return false;
-
-  uint16_t Tag = CTy.getTag();
-
-  switch (Tag) {
-  case dwarf::DW_TAG_structure_type:
-  case dwarf::DW_TAG_union_type:
-  case dwarf::DW_TAG_enumeration_type:
-  case dwarf::DW_TAG_class_type:
-    // If this is a class, structure, union, or enumeration type
-    // that is a definition (not a declaration), and not scoped
-    // inside a function then separate this out as a type unit.
-    return !CTy.isForwardDecl() && isTypeUnitScoped(CTy, DD);
-  default:
-    return false;
-  }
-}
-
 /// constructTypeDIE - Construct type DIE from DICompositeType.
 void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
-  // If this is a type applicable to a type unit it then add it to the
-  // list of types we'll compute a hash for later.
-  if (shouldCreateTypeUnit(CTy, DD))
-    DD->addTypeUnitType(&Buffer, CTy);
-  else
-    constructTypeDIEImpl(Buffer, CTy);
-}
-
-void CompileUnit::constructTypeDIEImpl(DIE &Buffer, DICompositeType CTy) {
   // Add name if not anonymous or intermediate type.
   StringRef Name = CTy.getName();
 
@@ -1621,8 +1617,10 @@ void CompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
       }
       // 3) followed by a custom OP to make the debugger do a TLS lookup.
       addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address);
-    } else
+    } else {
+      DD->addArangeLabel(SymbolCU(this, Sym));
       addOpAddress(Block, Sym);
+    }
     // Do not create specification DIE if context is either compile unit
     // or a subprogram.
     if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
@@ -1659,7 +1657,9 @@ void CompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
     // GV is a merged global.
     DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
     Value *Ptr = CE->getOperand(0);
-    addOpAddress(Block, Asm->getSymbol(cast<GlobalValue>(Ptr)));
+    MCSymbol *Sym = Asm->getSymbol(cast<GlobalValue>(Ptr));
+    DD->addArangeLabel(SymbolCU(this, Sym));
+    addOpAddress(Block, Sym);
     addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
     SmallVector<Value *, 3> Idx(CE->op_begin() + 1, CE->op_end());
     addUInt(Block, dwarf::DW_FORM_udata,
@@ -1809,10 +1809,8 @@ DIE *CompileUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstract) {
 
   unsigned Offset = DV.getDotDebugLocOffset();
   if (Offset != ~0U) {
-    addLabel(VariableDie, dwarf::DW_AT_location,
-             DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
-                                        : dwarf::DW_FORM_data4,
-             Asm->GetTempSymbol("debug_loc", Offset));
+    addSectionLabel(VariableDie, dwarf::DW_AT_location,
+                    Asm->GetTempSymbol("debug_loc", Offset));
     DV.setDIE(VariableDie);
     return VariableDie;
   }