return *SPDie;
}
+// Construct a DIE for this scope.
+void DwarfCompileUnit::constructScopeDIE(
+ LexicalScope *Scope, SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren) {
+ if (!Scope || !Scope->getScopeNode())
+ return;
+
+ DIScope DS(Scope->getScopeNode());
+
+ assert((Scope->getInlinedAt() || !DS.isSubprogram()) &&
+ "Only handle inlined subprograms here, use "
+ "constructSubprogramScopeDIE for non-inlined "
+ "subprograms");
+
+ SmallVector<std::unique_ptr<DIE>, 8> Children;
+
+ // We try to create the scope DIE first, then the children DIEs. This will
+ // avoid creating un-used children then removing them later when we find out
+ // the scope DIE is null.
+ std::unique_ptr<DIE> ScopeDIE;
+ if (Scope->getParent() && DS.isSubprogram()) {
+ ScopeDIE = DD->constructInlinedScopeDIE(*this, Scope);
+ if (!ScopeDIE)
+ return;
+ // We create children when the scope DIE is not null.
+ DD->createScopeChildrenDIE(*this, Scope, Children);
+ } else {
+ // Early exit when we know the scope DIE is going to be null.
+ if (DD->isLexicalScopeDIENull(Scope))
+ 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.
+ DD->createScopeChildrenDIE(*this, Scope, Children, &ChildScopeCount);
+
+ // There is no need to emit empty lexical block DIE.
+ for (const auto &E : DD->findImportedEntitiesForScope(DS))
+ Children.push_back(
+ constructImportedEntityDIE(DIImportedEntity(E.second)));
+ // 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 = DD->constructLexicalScopeDIE(*this, Scope);
+ assert(ScopeDIE && "Scope DIE should not be null.");
+ }
+
+ // Add children
+ for (auto &I : Children)
+ ScopeDIE->addChild(std::move(I));
+
+ FinalChildren.push_back(std::move(ScopeDIE));
+}
+
} // end llvm namespace
void ensureAbstractVariableIsCreatedIfScoped(const DIVariable &Var,
const MDNode *Scope);
- /// \brief A helper function to check whether the DIE for a given Scope is
- /// going to be null.
- bool isLexicalScopeDIENull(LexicalScope *Scope);
-
/// \brief A helper function to construct a RangeSpanList for a given
/// lexical scope.
void addScopeRangeList(DwarfCompileUnit &TheCU, DIE &ScopeDIE,
const SmallVectorImpl<InsnRange> &Range);
- /// \brief Construct new DW_TAG_lexical_block for this scope and
- /// attach DW_AT_low_pc/DW_AT_high_pc labels.
- std::unique_ptr<DIE> constructLexicalScopeDIE(DwarfCompileUnit &TheCU,
- LexicalScope *Scope);
-
- /// \brief This scope represents inlined body of a function. Construct
- /// DIE to represent this concrete inlined copy of the function.
- std::unique_ptr<DIE> constructInlinedScopeDIE(DwarfCompileUnit &TheCU,
- LexicalScope *Scope);
-
/// \brief Construct a DIE for this scope.
void constructScopeDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope,
SmallVectorImpl<std::unique_ptr<DIE>> &FinalChildren);
/// \brief Construct a DIE for this subprogram scope.
void constructSubprogramScopeDIE(DwarfCompileUnit &TheCU,
LexicalScope *Scope);
- /// A helper function to create children of a Scope DIE.
- DIE *createScopeChildrenDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope,
- SmallVectorImpl<std::unique_ptr<DIE>> &Children,
- unsigned *ChildScopeCount = nullptr);
/// \brief Emit initial Dwarf sections with a label at the start of each one.
void emitSectionLabels();
const MachineFunction *getCurrentFunction() const { return CurFn; }
const MCSymbol *getFunctionBeginSym() const { return FunctionBeginSym; }
const MCSymbol *getFunctionEndSym() const { return FunctionEndSym; }
+
+ iterator_range<ImportedEntityMap::const_iterator> findImportedEntitiesForScope(const MDNode *Scope) const {
+ return make_range(std::equal_range(
+ ScopesWithImportedEntities.begin(), ScopesWithImportedEntities.end(),
+ std::pair<const MDNode *, const MDNode *>(Scope, nullptr), less_first()));
+ }
+
+ /// \brief A helper function to check whether the DIE for a given Scope is
+ /// going to be null.
+ bool isLexicalScopeDIENull(LexicalScope *Scope);
+
+ // FIXME: Sink these functions down into DwarfFile/Dwarf*Unit.
+
+ /// \brief Construct new DW_TAG_lexical_block for this scope and
+ /// attach DW_AT_low_pc/DW_AT_high_pc labels.
+ std::unique_ptr<DIE> constructLexicalScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope);
+
+ /// \brief This scope represents inlined body of a function. Construct
+ /// DIE to represent this concrete inlined copy of the function.
+ std::unique_ptr<DIE> constructInlinedScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope);
+
+ /// A helper function to create children of a Scope DIE.
+ DIE *createScopeChildrenDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope,
+ SmallVectorImpl<std::unique_ptr<DIE>> &Children,
+ unsigned *ChildScopeCount = nullptr);
};
} // End of namespace llvm