Remove DwarfDebug::PrevSection, PrevCU is sufficient for handling address range holes.
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfDebug.cpp
index cfffef7e747edb7b0a8e922562568ba9d4ff8209..663ebef250bfab5a7269d070f80b5991e4894f05 100644 (file)
@@ -455,48 +455,35 @@ static std::unique_ptr<DIE> constructVariableDIE(DwarfCompileUnit &TheCU,
 
 DIE *DwarfDebug::createScopeChildrenDIE(
     DwarfCompileUnit &TheCU, LexicalScope *Scope,
-    SmallVectorImpl<std::unique_ptr<DIE>> &Children) {
+    SmallVectorImpl<std::unique_ptr<DIE>> &Children,
+    unsigned *ChildScopeCount) {
   DIE *ObjectPointer = nullptr;
 
-  // Collect arguments for current function.
-  if (LScopes.isCurrentFunctionScope(Scope)) {
-    for (DbgVariable *ArgDV : CurrentFnArguments)
-      if (ArgDV)
-        Children.push_back(
-            constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer));
-
-    // If this is a variadic function, add an unspecified parameter.
-    DISubprogram SP(Scope->getScopeNode());
-    DITypeArray FnArgs = SP.getType().getTypeArray();
-    // If we have a single element of null, it is a function that returns void.
-    // If we have more than one elements and the last one is null, it is a
-    // variadic function.
-    if (FnArgs.getNumElements() > 1 &&
-        !FnArgs.getElement(FnArgs.getNumElements() - 1))
-      Children.push_back(
-          make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
-  }
-
-  // Collect lexical scope children first.
   for (DbgVariable *DV : ScopeVariables.lookup(Scope))
     Children.push_back(constructVariableDIE(TheCU, *DV, *Scope, ObjectPointer));
 
+  unsigned ChildCountWithoutScopes = Children.size();
+
   for (LexicalScope *LS : Scope->getChildren())
-    if (std::unique_ptr<DIE> Nested = constructScopeDIE(TheCU, LS))
-      Children.push_back(std::move(Nested));
+    constructScopeDIE(TheCU, LS, Children);
+
+  if (ChildScopeCount)
+    *ChildScopeCount = Children.size() - ChildCountWithoutScopes;
+
   return ObjectPointer;
 }
 
-void DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU,
+DIE *DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU,
                                            LexicalScope *Scope, DIE &ScopeDIE) {
   // We create children when the scope DIE is not null.
   SmallVector<std::unique_ptr<DIE>, 8> Children;
-  if (DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children))
-    TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
+  DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children);
 
   // Add children
   for (auto &I : Children)
     ScopeDIE.addChild(std::move(I));
+
+  return ObjectPointer;
 }
 
 void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU,
@@ -535,7 +522,8 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU,
   SPCU.applySubprogramAttributesToDefinition(SP, *AbsDef);
 
   SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
-  createAndAddScopeChildren(SPCU, Scope, *AbsDef);
+  if (DIE *ObjectPointer = createAndAddScopeChildren(SPCU, Scope, *AbsDef))
+    SPCU.addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
 }
 
 DIE &DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU,
@@ -551,16 +539,43 @@ DIE &DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU,
 
   DIE &ScopeDIE = updateSubprogramScopeDIE(TheCU, Sub);
 
-  createAndAddScopeChildren(TheCU, Scope, ScopeDIE);
+  // Collect arguments for current function.
+  assert(LScopes.isCurrentFunctionScope(Scope));
+  DIE *ObjectPointer = nullptr;
+  for (DbgVariable *ArgDV : CurrentFnArguments)
+    if (ArgDV)
+      ScopeDIE.addChild(
+          constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer));
+
+  // If this is a variadic function, add an unspecified parameter.
+  DITypeArray FnArgs = Sub.getType().getTypeArray();
+  // If we have a single element of null, it is a function that returns void.
+  // If we have more than one elements and the last one is null, it is a
+  // variadic function.
+  if (FnArgs.getNumElements() > 1 &&
+      !FnArgs.getElement(FnArgs.getNumElements() - 1))
+    ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
+
+  // Collect lexical scope children first.
+  // ObjectPointer might be a local (non-argument) local variable if it's a
+  // block's synthetic this pointer.
+  if (DIE *BlockObjPtr = createAndAddScopeChildren(TheCU, Scope, ScopeDIE)) {
+    assert(!ObjectPointer && "multiple object pointers can't be described");
+    ObjectPointer = BlockObjPtr;
+  }
+
+  if (ObjectPointer)
+    TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
 
   return ScopeDIE;
 }
 
 // Construct a DIE for this scope.
-std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
-                                                   LexicalScope *Scope) {
+void DwarfDebug::constructScopeDIE(
+    DwarfCompileUnit &TheCU, LexicalScope *Scope,
+    SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) {
   if (!Scope || !Scope->getScopeNode())
-    return nullptr;
+    return;
 
   DIScope DS(Scope->getScopeNode());
 
@@ -578,17 +593,19 @@ std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
   if (Scope->getParent() && DS.isSubprogram()) {
     ScopeDIE = constructInlinedScopeDIE(TheCU, Scope);
     if (!ScopeDIE)
-      return nullptr;
+      return;
     // We create children when the scope DIE is not null.
     createScopeChildrenDIE(TheCU, Scope, Children);
   } else {
     // Early exit when we know the scope DIE is going to be null.
     if (isLexicalScopeDIENull(Scope))
-      return nullptr;
+      return;
+
+    unsigned ChildScopeCount;
 
     // We create children here when we know the scope DIE is not going to be
     // null and the children will be added to the scope DIE.
-    createScopeChildrenDIE(TheCU, Scope, Children);
+    createScopeChildrenDIE(TheCU, Scope, Children, &ChildScopeCount);
 
     // There is no need to emit empty lexical block DIE.
     std::pair<ImportedEntityMap::const_iterator,
@@ -601,8 +618,14 @@ std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
          ++i)
       Children.push_back(
           constructImportedEntityDIE(TheCU, DIImportedEntity(i->second)));
-    if (Children.empty())
-      return nullptr;
+    // If there are only other scopes as children, put them directly in the
+    // parent instead, as this scope would serve no purpose.
+    if (Children.size() == ChildScopeCount) {
+      FinalChildren.insert(FinalChildren.end(),
+                           std::make_move_iterator(Children.begin()),
+                           std::make_move_iterator(Children.end()));
+      return;
+    }
     ScopeDIE = constructLexicalScopeDIE(TheCU, Scope);
     assert(ScopeDIE && "Scope DIE should not be null.");
   }
@@ -611,7 +634,7 @@ std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
   for (auto &I : Children)
     ScopeDIE->addChild(std::move(I));
 
-  return ScopeDIE;
+  FinalChildren.push_back(std::move(ScopeDIE));
 }
 
 void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {
@@ -1644,7 +1667,6 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
     // If we don't have a lexical scope for this function then there will
     // be a hole in the range information. Keep note of this by setting the
     // previously used section to nullptr.
-    PrevSection = nullptr;
     PrevCU = nullptr;
     CurFn = nullptr;
     return;
@@ -1687,7 +1709,6 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   // Add the range of this function to the list of ranges for the CU.
   RangeSpan Span(FunctionBeginSym, FunctionEndSym);
   TheCU.addRange(std::move(Span));
-  PrevSection = Asm->getCurrentSection();
   PrevCU = &TheCU;
 
   // Clear debug info