mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 00:36:06 +00:00
Reland "[DebugMetadata][DwarfDebug] Fix DWARF emisson of function-local imported entities (3/7)"
Got rid of non-determinism in MetadataLoader.cpp. Authored-by: Kristina Bessonova <kbessonova@accesssoftek.com> Differential Revision: https://reviews.llvm.org/D144004
This commit is contained in:
parent
6a8e2538af
commit
06a0ae6524
@ -81,44 +81,43 @@ void C::c() {}
|
||||
// CHECK: !DINamespace(scope: null)
|
||||
// CHECK: [[CU:![0-9]+]] = distinct !DICompileUnit(
|
||||
// CHECK-SAME: imports: [[MODULES:![0-9]*]]
|
||||
// CHECK: [[MODULES]] = !{[[M1:![0-9]+]], [[M2:![0-9]+]], [[M3:![0-9]+]], [[M4:![0-9]+]], [[M5:![0-9]+]], [[M6:![0-9]+]], [[M7:![0-9]+]], [[M8:![0-9]+]], [[M9:![0-9]+]], [[M10:![0-9]+]], [[M11:![0-9]+]], [[M12:![0-9]+]], [[M13:![0-9]+]], [[M14:![0-9]+]], [[M15:![0-9]+]], [[M16:![0-9]+]], [[M17:![0-9]+]]
|
||||
// CHECK: [[MODULES]] = !{[[M1:![0-9]+]], [[M2:![0-9]+]], [[M3:![0-9]+]], [[M4:![0-9]+]]}
|
||||
// CHECK: [[M1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CTXT]], entity: [[NS]], file: [[FOOCPP]], line: 15)
|
||||
|
||||
// CHECK: [[M2]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[CTXT]],
|
||||
// CHECK: [[M3]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "E", scope: [[CU]], entity: [[CTXT]], file: [[FOOCPP]], line: 19)
|
||||
// CHECK: [[M4]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[LEX2:![0-9]+]], entity: [[NS]], file: [[FOOCPP]], line: 23)
|
||||
// CHECK: [[M4]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]]
|
||||
// CHECK: [[F1:![0-9]+]] = distinct !DISubprogram(name: "f1",{{.*}} line: 4
|
||||
// CHECK-SAME: DISPFlagDefinition
|
||||
// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func",{{.*}} DISPFlagDefinition
|
||||
// CHECK-SAME: retainedNodes: [[FUNC_NODES:![0-9]*]]
|
||||
// CHECK: [[FUNC_NODES]] = !{[[M5:![0-9]+]], [[M6:![0-9]+]], [[M7:![0-9]+]], [[M8:![0-9]+]], [[M9:![0-9]+]], [[M10:![0-9]+]], [[M11:![0-9]+]], [[M12:![0-9]+]], [[M13:![0-9]+]], [[M14:![0-9]+]], [[M15:![0-9]+]], [[M16:![0-9]+]], [[M17:![0-9]+]]}
|
||||
// CHECK: [[M5]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[LEX2:![0-9]+]], entity: [[NS]], file: [[FOOCPP]], line: 23)
|
||||
// CHECK: [[LEX2]] = distinct !DILexicalBlock(scope: [[LEX1:![0-9]+]], file: [[FOOCPP]],
|
||||
// CHECK: [[LEX1]] = distinct !DILexicalBlock(scope: [[FUNC:![0-9]+]], file: [[FOOCPP]],
|
||||
|
||||
// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func",{{.*}} DISPFlagDefinition
|
||||
// CHECK: [[M5]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[FUNC]], entity: [[CTXT:![0-9]+]],
|
||||
// CHECK: [[M6]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FOO:![0-9]+]], file: [[FOOCPP]], line: 27)
|
||||
// CHECK: [[M6]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[FUNC]], entity: [[CTXT]],
|
||||
// CHECK: [[M7]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FOO:![0-9]+]], file: [[FOOCPP]], line: 27)
|
||||
// CHECK: [[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
|
||||
// CHECK-SAME: line: 5
|
||||
// CHECK-SAME: DIFlagFwdDecl
|
||||
// CHECK: [[M7]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAR:![0-9]+]]
|
||||
// CHECK: [[M8]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAR:![0-9]+]]
|
||||
// CHECK: [[BAR]] = !DICompositeType(tag: DW_TAG_structure_type, name: "bar",
|
||||
// CHECK-SAME: line: 6
|
||||
// CHECK-SAME: DIFlagFwdDecl
|
||||
|
||||
// CHECK: [[M8]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[F1:![0-9]+]]
|
||||
// CHECK: [[F1:![0-9]+]] = distinct !DISubprogram(name: "f1",{{.*}} line: 4
|
||||
// CHECK-SAME: DISPFlagDefinition
|
||||
// CHECK: [[M9]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[I]]
|
||||
// CHECK: [[M10]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAZ:![0-9]+]]
|
||||
// CHECK: [[M9]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[F1]]
|
||||
// CHECK: [[M10]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[I]]
|
||||
// CHECK: [[M11]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAZ:![0-9]+]]
|
||||
// CHECK: [[BAZ]] = !DIDerivedType(tag: DW_TAG_typedef, name: "baz", scope: [[NS]], file: [[FOOCPP]],
|
||||
// CHECK-SAME: baseType: [[BAR]]
|
||||
// CHECK: [[M11]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "X", scope: [[FUNC]], entity: [[CTXT]]
|
||||
// CHECK: [[M12]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "Y", scope: [[FUNC]], entity: [[M11]]
|
||||
// CHECK: [[M13]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_DECL:![0-9]+]]
|
||||
// CHECK: [[M12]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "X", scope: [[FUNC]], entity: [[CTXT]]
|
||||
// CHECK: [[M13]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "Y", scope: [[FUNC]], entity: [[M12]]
|
||||
// CHECK: [[M14]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_DECL:![0-9]+]]
|
||||
// CHECK: [[VAR_DECL]] = !DIGlobalVariable(name: "var_decl", linkageName: "{{[^"]*var_decl[^"]*}}", scope: [[NS]],{{.*}} line: 8,
|
||||
// CHECK: [[M14]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_DECL:![0-9]+]]
|
||||
// CHECK: [[M15]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_DECL:![0-9]+]]
|
||||
// CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func_decl",
|
||||
// CHECK-SAME: scope: [[NS]], file: [[FOOCPP]], line: 9
|
||||
// CHECK: [[M15]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_FWD:![0-9]+]]
|
||||
// CHECK: [[M16]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_FWD:![0-9]+]]
|
||||
// CHECK: [[M16]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_FWD:![0-9]+]]
|
||||
// CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_FWD:![0-9]+]]
|
||||
// CHECK: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 53,{{.*}} DISPFlagDefinition
|
||||
// CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]]
|
||||
// CHECK: distinct !DISubprogram(name: "c",{{.*}}, scope: ![[C:[0-9]+]],{{.*}}, line: 60,{{.*}} DISPFlagDefinition
|
||||
// CHECK: ![[C]] = !DINamespace(name: "C",
|
||||
|
||||
|
@ -54,7 +54,7 @@ namespace llvm {
|
||||
SmallVector<TrackingMDNodeRef, 4> AllRetainTypes;
|
||||
SmallVector<DISubprogram *, 4> AllSubprograms;
|
||||
SmallVector<Metadata *, 4> AllGVs;
|
||||
SmallVector<TrackingMDNodeRef, 4> AllImportedModules;
|
||||
SmallVector<TrackingMDNodeRef, 4> ImportedModules;
|
||||
/// Map Macro parent (which can be DIMacroFile or nullptr) to a list of
|
||||
/// Metadata all of type DIMacroNode.
|
||||
/// DIMacroNode's with nullptr parent are DICompileUnit direct children.
|
||||
@ -64,7 +64,8 @@ namespace llvm {
|
||||
SmallVector<TrackingMDNodeRef, 4> UnresolvedNodes;
|
||||
bool AllowUnresolvedNodes;
|
||||
|
||||
/// Each subprogram's preserved local variables and labels.
|
||||
/// Each subprogram's preserved local variables, labels and imported
|
||||
/// entities.
|
||||
///
|
||||
/// Do not use a std::vector. Some versions of libc++ apparently copy
|
||||
/// instead of move on grow operations, and TrackingMDRef is expensive to
|
||||
@ -72,6 +73,12 @@ namespace llvm {
|
||||
DenseMap<DISubprogram *, SmallVector<TrackingMDNodeRef, 4>>
|
||||
SubprogramTrackedNodes;
|
||||
|
||||
SmallVectorImpl<TrackingMDNodeRef> &
|
||||
getImportTrackingVector(const DIScope *S) {
|
||||
return isa_and_nonnull<DILocalScope>(S)
|
||||
? getSubprogramNodesTrackingVector(S)
|
||||
: ImportedModules;
|
||||
}
|
||||
SmallVectorImpl<TrackingMDNodeRef> &
|
||||
getSubprogramNodesTrackingVector(const DIScope *S) {
|
||||
return SubprogramTrackedNodes[cast<DILocalScope>(S)->getSubprogram()];
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/STLFunctionalExtras.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
@ -53,6 +54,7 @@
|
||||
#include <deque>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
@ -463,6 +465,9 @@ class MetadataLoader::MetadataLoaderImpl {
|
||||
bool NeedUpgradeToDIGlobalVariableExpression = false;
|
||||
bool NeedDeclareExpressionUpgrade = false;
|
||||
|
||||
/// Map DILocalScope to the enclosing DISubprogram, if any.
|
||||
DenseMap<DILocalScope *, DISubprogram *> ParentSubprogram;
|
||||
|
||||
/// True if metadata is being parsed for a module being ThinLTO imported.
|
||||
bool IsImporting = false;
|
||||
|
||||
@ -521,6 +526,84 @@ class MetadataLoader::MetadataLoaderImpl {
|
||||
}
|
||||
}
|
||||
|
||||
DISubprogram *findEnclosingSubprogram(DILocalScope *S) {
|
||||
if (!S)
|
||||
return nullptr;
|
||||
if (auto *SP = ParentSubprogram[S]) {
|
||||
return SP;
|
||||
}
|
||||
|
||||
DILocalScope *InitialScope = S;
|
||||
DenseSet<DILocalScope *> Visited;
|
||||
while (S && !isa<DISubprogram>(S)) {
|
||||
S = dyn_cast_or_null<DILocalScope>(S->getScope());
|
||||
if (Visited.contains(S))
|
||||
break;
|
||||
Visited.insert(S);
|
||||
}
|
||||
ParentSubprogram[InitialScope] = llvm::dyn_cast_or_null<DISubprogram>(S);
|
||||
|
||||
return ParentSubprogram[InitialScope];
|
||||
}
|
||||
|
||||
/// Move local imports from DICompileUnit's 'imports' field to
|
||||
/// DISubprogram's retainedNodes.
|
||||
void upgradeCULocals() {
|
||||
if (NamedMDNode *CUNodes = TheModule.getNamedMetadata("llvm.dbg.cu")) {
|
||||
for (unsigned I = 0, E = CUNodes->getNumOperands(); I != E; ++I) {
|
||||
auto *CU = dyn_cast<DICompileUnit>(CUNodes->getOperand(I));
|
||||
if (!CU)
|
||||
continue;
|
||||
|
||||
if (auto *RawImported = CU->getRawImportedEntities()) {
|
||||
// Collect a set of imported entities to be moved.
|
||||
SetVector<Metadata *> EntitiesToRemove;
|
||||
for (Metadata *Op : CU->getImportedEntities()->operands()) {
|
||||
auto *IE = cast<DIImportedEntity>(Op);
|
||||
if (auto *S = dyn_cast_or_null<DILocalScope>(IE->getScope())) {
|
||||
EntitiesToRemove.insert(IE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!EntitiesToRemove.empty()) {
|
||||
// Make a new list of CU's 'imports'.
|
||||
SmallVector<Metadata *> NewImports;
|
||||
for (Metadata *Op : CU->getImportedEntities()->operands()) {
|
||||
if (!EntitiesToRemove.contains(cast<DIImportedEntity>(Op))) {
|
||||
NewImports.push_back(Op);
|
||||
}
|
||||
}
|
||||
|
||||
// Find DISubprogram corresponding to each entity.
|
||||
std::map<DISubprogram *, SmallVector<Metadata *>> SPToEntities;
|
||||
for (auto *I : EntitiesToRemove) {
|
||||
auto *Entity = cast<DIImportedEntity>(I);
|
||||
if (auto *SP = findEnclosingSubprogram(
|
||||
cast<DILocalScope>(Entity->getScope()))) {
|
||||
SPToEntities[SP].push_back(Entity);
|
||||
}
|
||||
}
|
||||
|
||||
// Update DISubprograms' retainedNodes.
|
||||
for (auto I = SPToEntities.begin(); I != SPToEntities.end(); ++I) {
|
||||
auto *SP = I->first;
|
||||
auto RetainedNodes = SP->getRetainedNodes();
|
||||
SmallVector<Metadata *> MDs(RetainedNodes.begin(),
|
||||
RetainedNodes.end());
|
||||
MDs.append(I->second);
|
||||
SP->replaceRetainedNodes(MDNode::get(Context, MDs));
|
||||
}
|
||||
|
||||
// Remove entities with local scope from CU.
|
||||
CU->replaceImportedEntities(MDTuple::get(Context, NewImports));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParentSubprogram.clear();
|
||||
}
|
||||
|
||||
/// Remove a leading DW_OP_deref from DIExpressions in a dbg.declare that
|
||||
/// describes a function argument.
|
||||
void upgradeDeclareExpressions(Function &F) {
|
||||
@ -625,6 +708,7 @@ class MetadataLoader::MetadataLoaderImpl {
|
||||
void upgradeDebugInfo() {
|
||||
upgradeCUSubprograms();
|
||||
upgradeCUVariables();
|
||||
upgradeCULocals();
|
||||
}
|
||||
|
||||
void callMDTypeCallback(Metadata **Val, unsigned TypeID);
|
||||
|
@ -694,7 +694,7 @@ DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,
|
||||
auto *InlinedSP = getDISubprogram(DS);
|
||||
// Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
|
||||
// was inlined from another compile unit.
|
||||
DIE *OriginDIE = getAbstractSPDies()[InlinedSP];
|
||||
DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP];
|
||||
assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
|
||||
|
||||
auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
|
||||
@ -726,10 +726,20 @@ DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope,
|
||||
DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
|
||||
if (DD->isLexicalScopeDIENull(Scope))
|
||||
return nullptr;
|
||||
const auto *DS = Scope->getScopeNode();
|
||||
|
||||
auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
|
||||
if (Scope->isAbstractScope())
|
||||
if (Scope->isAbstractScope()) {
|
||||
assert(!getAbstractScopeDIEs().count(DS) &&
|
||||
"Abstract DIE for this scope exists!");
|
||||
getAbstractScopeDIEs()[DS] = ScopeDIE;
|
||||
return ScopeDIE;
|
||||
}
|
||||
if (!Scope->getInlinedAt()) {
|
||||
assert(!LexicalBlockDIEs.count(DS) &&
|
||||
"Concrete out-of-line DIE for this scope exists!");
|
||||
LexicalBlockDIEs[DS] = ScopeDIE;
|
||||
}
|
||||
|
||||
attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
|
||||
|
||||
@ -1097,35 +1107,35 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
|
||||
for (DbgVariable *DV : Locals)
|
||||
ScopeDIE.addChild(constructVariableDIE(*DV, *Scope, ObjectPointer));
|
||||
|
||||
// Emit imported entities (skipped in gmlt-like data).
|
||||
if (!includeMinimalInlineScopes()) {
|
||||
for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
|
||||
ScopeDIE.addChild(constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
|
||||
}
|
||||
|
||||
// Emit labels.
|
||||
for (DbgLabel *DL : DU->getScopeLabels().lookup(Scope))
|
||||
ScopeDIE.addChild(constructLabelDIE(*DL, *Scope));
|
||||
|
||||
// Track other local entities (skipped in gmlt-like data).
|
||||
// This creates mapping between CU and a set of local declarations that
|
||||
// should be emitted for subprograms in this CU.
|
||||
if (!includeMinimalInlineScopes() && !Scope->getInlinedAt()) {
|
||||
auto &LocalDecls = DD->getLocalDeclsForScope(Scope->getScopeNode());
|
||||
DeferredLocalDecls.insert(LocalDecls.begin(), LocalDecls.end());
|
||||
}
|
||||
|
||||
// Emit inner lexical scopes.
|
||||
auto needToEmitLexicalScope = [this](LexicalScope *LS) {
|
||||
if (isa<DISubprogram>(LS->getScopeNode()))
|
||||
return true;
|
||||
auto Vars = DU->getScopeVariables().lookup(LS);
|
||||
auto skipLexicalScope = [this](LexicalScope *S) -> bool {
|
||||
if (isa<DISubprogram>(S->getScopeNode()))
|
||||
return false;
|
||||
auto Vars = DU->getScopeVariables().lookup(S);
|
||||
if (!Vars.Args.empty() || !Vars.Locals.empty())
|
||||
return true;
|
||||
if (!includeMinimalInlineScopes() &&
|
||||
!ImportedEntities[LS->getScopeNode()].empty())
|
||||
return true;
|
||||
return false;
|
||||
return false;
|
||||
return includeMinimalInlineScopes() ||
|
||||
DD->getLocalDeclsForScope(S->getScopeNode()).empty();
|
||||
};
|
||||
for (LexicalScope *LS : Scope->getChildren()) {
|
||||
// If the lexical block doesn't have non-scope children, skip
|
||||
// its emission and put its children directly to the parent scope.
|
||||
if (needToEmitLexicalScope(LS))
|
||||
constructScopeDIE(LS, ScopeDIE);
|
||||
else
|
||||
if (skipLexicalScope(LS))
|
||||
createAndAddScopeChildren(LS, ScopeDIE);
|
||||
else
|
||||
constructScopeDIE(LS, ScopeDIE);
|
||||
}
|
||||
|
||||
return ObjectPointer;
|
||||
@ -1133,11 +1143,9 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
|
||||
|
||||
void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
|
||||
LexicalScope *Scope) {
|
||||
DIE *&AbsDef = getAbstractSPDies()[Scope->getScopeNode()];
|
||||
if (AbsDef)
|
||||
return;
|
||||
|
||||
auto *SP = cast<DISubprogram>(Scope->getScopeNode());
|
||||
if (getAbstractScopeDIEs().count(SP))
|
||||
return;
|
||||
|
||||
DIE *ContextDIE;
|
||||
DwarfCompileUnit *ContextCU = this;
|
||||
@ -1161,14 +1169,19 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
|
||||
|
||||
// Passing null as the associated node because the abstract definition
|
||||
// shouldn't be found by lookup.
|
||||
AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
|
||||
ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
|
||||
ContextCU->addSInt(*AbsDef, dwarf::DW_AT_inline,
|
||||
DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
|
||||
*ContextDIE, nullptr);
|
||||
|
||||
// Store the DIE before creating children.
|
||||
ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef;
|
||||
|
||||
ContextCU->applySubprogramAttributesToDefinition(SP, AbsDef);
|
||||
ContextCU->addSInt(AbsDef, dwarf::DW_AT_inline,
|
||||
DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()
|
||||
: dwarf::DW_FORM_implicit_const,
|
||||
dwarf::DW_INL_inlined);
|
||||
if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
|
||||
ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
|
||||
if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, AbsDef))
|
||||
ContextCU->addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
|
||||
}
|
||||
|
||||
bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
|
||||
@ -1312,12 +1325,20 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
|
||||
EntityDie = getOrCreateNameSpace(NS);
|
||||
else if (auto *M = dyn_cast<DIModule>(Entity))
|
||||
EntityDie = getOrCreateModule(M);
|
||||
else if (auto *SP = dyn_cast<DISubprogram>(Entity))
|
||||
EntityDie = getOrCreateSubprogramDIE(SP);
|
||||
else if (auto *T = dyn_cast<DIType>(Entity))
|
||||
else if (auto *SP = dyn_cast<DISubprogram>(Entity)) {
|
||||
// If there is an abstract subprogram, refer to it. Note that this assumes
|
||||
// that all the abstract subprograms have been already created (which is
|
||||
// correct until imported entities get emitted in DwarfDebug::endModule()).
|
||||
if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP))
|
||||
EntityDie = AbsSPDie;
|
||||
else
|
||||
EntityDie = getOrCreateSubprogramDIE(SP);
|
||||
} else if (auto *T = dyn_cast<DIType>(Entity))
|
||||
EntityDie = getOrCreateTypeDIE(T);
|
||||
else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
|
||||
EntityDie = getOrCreateGlobalVariableDIE(GV, {});
|
||||
else if (auto *IE = dyn_cast<DIImportedEntity>(Entity))
|
||||
EntityDie = getOrCreateImportedEntityDIE(IE);
|
||||
else
|
||||
EntityDie = getDIE(Entity);
|
||||
assert(EntityDie);
|
||||
@ -1348,9 +1369,24 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
|
||||
return IMDie;
|
||||
}
|
||||
|
||||
DIE *DwarfCompileUnit::getOrCreateImportedEntityDIE(
|
||||
const DIImportedEntity *IE) {
|
||||
|
||||
// Check for pre-existence.
|
||||
if (DIE *Die = getDIE(IE))
|
||||
return Die;
|
||||
|
||||
DIE *ContextDIE = getOrCreateContextDIE(IE->getScope());
|
||||
assert(ContextDIE && "Empty scope for the imported entity!");
|
||||
|
||||
DIE *IMDie = constructImportedEntityDIE(IE);
|
||||
ContextDIE->addChild(IMDie);
|
||||
return IMDie;
|
||||
}
|
||||
|
||||
void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
|
||||
DIE *D = getDIE(SP);
|
||||
if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
|
||||
if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) {
|
||||
if (D)
|
||||
// If this subprogram has an abstract definition, reference that
|
||||
addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
|
||||
@ -1644,3 +1680,29 @@ void DwarfCompileUnit::createBaseTypeDIEs() {
|
||||
Btr.Die = &Die;
|
||||
}
|
||||
}
|
||||
|
||||
DIE *DwarfCompileUnit::getLexicalBlockDIE(const DILexicalBlock *LB) {
|
||||
// Assume if there is an abstract tree all the DIEs are already emitted.
|
||||
bool isAbstract = getAbstractScopeDIEs().count(LB->getSubprogram());
|
||||
if (isAbstract && getAbstractScopeDIEs().count(LB))
|
||||
return getAbstractScopeDIEs()[LB];
|
||||
assert(!isAbstract && "Missed lexical block DIE in abstract tree!");
|
||||
|
||||
// Return a concrete DIE if it exists or nullptr otherwise.
|
||||
return LexicalBlockDIEs.lookup(LB);
|
||||
}
|
||||
|
||||
DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) {
|
||||
if (isa_and_nonnull<DILocalScope>(Context)) {
|
||||
if (auto *LFScope = dyn_cast<DILexicalBlockFile>(Context))
|
||||
Context = LFScope->getNonLexicalBlockFileScope();
|
||||
if (auto *LScope = dyn_cast<DILexicalBlock>(Context))
|
||||
return getLexicalBlockDIE(LScope);
|
||||
|
||||
// Otherwise the context must be a DISubprogram.
|
||||
auto *SPScope = cast<DISubprogram>(Context);
|
||||
if (getAbstractScopeDIEs().count(SPScope))
|
||||
return getAbstractScopeDIEs()[SPScope];
|
||||
}
|
||||
return DwarfUnit::getOrCreateContextDIE(Context);
|
||||
}
|
||||
|
@ -61,11 +61,6 @@ class DwarfCompileUnit final : public DwarfUnit {
|
||||
/// The start of the unit macro info within macro section.
|
||||
MCSymbol *MacroLabelBegin;
|
||||
|
||||
using ImportedEntityList = SmallVector<const MDNode *, 8>;
|
||||
using ImportedEntityMap = DenseMap<const MDNode *, ImportedEntityList>;
|
||||
|
||||
ImportedEntityMap ImportedEntities;
|
||||
|
||||
/// GlobalNames - A map of globally visible named entities for this unit.
|
||||
StringMap<const DIE *> GlobalNames;
|
||||
|
||||
@ -79,7 +74,20 @@ class DwarfCompileUnit final : public DwarfUnit {
|
||||
// ranges/locs.
|
||||
const MCSymbol *BaseAddress = nullptr;
|
||||
|
||||
DenseMap<const MDNode *, DIE *> AbstractSPDies;
|
||||
using MDNodeSetVector =
|
||||
SetVector<const MDNode *, SmallVector<const MDNode *, 4>,
|
||||
SmallPtrSet<const MDNode *, 4>>;
|
||||
|
||||
// List of entities (either static locals, types or imports) that
|
||||
// belong to subprograms within this CU.
|
||||
MDNodeSetVector DeferredLocalDecls;
|
||||
|
||||
// List of concrete lexical block scopes belong to subprograms within this CU.
|
||||
DenseMap<const DILocalScope *, DIE *> LexicalBlockDIEs;
|
||||
|
||||
// List of abstract local scopes (either DISubprogram or DILexicalBlock).
|
||||
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
|
||||
|
||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
|
||||
|
||||
/// DWO ID for correlating skeleton and split units.
|
||||
@ -94,10 +102,10 @@ class DwarfCompileUnit final : public DwarfUnit {
|
||||
|
||||
bool isDwoUnit() const override;
|
||||
|
||||
DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
|
||||
DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {
|
||||
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
|
||||
return AbstractSPDies;
|
||||
return DU->getAbstractSPDies();
|
||||
return AbstractLocalScopeDIEs;
|
||||
return DU->getAbstractScopeDIEs();
|
||||
}
|
||||
|
||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
|
||||
@ -175,17 +183,6 @@ public:
|
||||
|
||||
unsigned getOrCreateSourceID(const DIFile *File) override;
|
||||
|
||||
void addImportedEntity(const DIImportedEntity* IE) {
|
||||
DIScope *Scope = IE->getScope();
|
||||
assert(Scope && "Invalid Scope encoding!");
|
||||
if (!isa<DILocalScope>(Scope))
|
||||
// No need to add imported enities that are not local declaration.
|
||||
return;
|
||||
|
||||
auto *LocalScope = cast<DILocalScope>(Scope)->getNonLexicalBlockFileScope();
|
||||
ImportedEntities[LocalScope].push_back(IE);
|
||||
}
|
||||
|
||||
/// addRange - Add an address range to the list of ranges for this unit.
|
||||
void addRange(RangeSpan Range);
|
||||
|
||||
@ -217,6 +214,11 @@ public:
|
||||
/// attach DW_AT_low_pc/DW_AT_high_pc labels.
|
||||
DIE *constructLexicalScopeDIE(LexicalScope *Scope);
|
||||
|
||||
/// Get a DIE for the given DILexicalBlock.
|
||||
/// Note that this function assumes that the DIE has been already created
|
||||
/// and it's an error, if it hasn't.
|
||||
DIE *getLexicalBlockDIE(const DILexicalBlock *LB);
|
||||
|
||||
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
|
||||
DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false);
|
||||
|
||||
@ -228,6 +230,10 @@ public:
|
||||
|
||||
void createBaseTypeDIEs();
|
||||
|
||||
/// Construct a DIE for a given scope.
|
||||
/// This instance of 'getOrCreateContextDIE()' can handle DILocalScope.
|
||||
DIE *getOrCreateContextDIE(const DIScope *Ty) override;
|
||||
|
||||
/// Construct a DIE for this subprogram scope.
|
||||
DIE &constructSubprogramScopeDIE(const DISubprogram *Sub,
|
||||
LexicalScope *Scope);
|
||||
@ -266,8 +272,9 @@ public:
|
||||
void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE,
|
||||
SmallVector<DbgCallSiteParam, 4> &Params);
|
||||
|
||||
/// Construct import_module DIE.
|
||||
DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
|
||||
/// Get or create a DIE for an imported entity.
|
||||
DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE);
|
||||
DIE *constructImportedEntityDIE(const DIImportedEntity *IE);
|
||||
|
||||
void finishSubprogramDefinition(const DISubprogram *SP);
|
||||
void finishEntityDefinition(const DbgEntity *Entity);
|
||||
@ -364,6 +371,8 @@ public:
|
||||
bool hasDwarfPubSections() const;
|
||||
|
||||
void addBaseTypeRef(DIEValueList &Die, int64_t Idx);
|
||||
|
||||
MDNodeSetVector &getDeferredLocalDecls() { return DeferredLocalDecls; }
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -507,7 +507,7 @@ void DwarfDebug::addSubprogramNames(const DICompileUnit &CU,
|
||||
// well into the name table. Only do that if we are going to actually emit
|
||||
// that name.
|
||||
if (SP->getLinkageName() != "" && SP->getName() != SP->getLinkageName() &&
|
||||
(useAllLinkageNames() || InfoHolder.getAbstractSPDies().lookup(SP)))
|
||||
(useAllLinkageNames() || InfoHolder.getAbstractScopeDIEs().lookup(SP)))
|
||||
addAccelName(CU, SP->getLinkageName(), Die);
|
||||
|
||||
// If this is an Objective-C selector name add it to the ObjC accelerator
|
||||
@ -1105,9 +1105,6 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
|
||||
DwarfCompileUnit &NewCU = *OwnedUnit;
|
||||
InfoHolder.addUnit(std::move(OwnedUnit));
|
||||
|
||||
for (auto *IE : DIUnit->getImportedEntities())
|
||||
NewCU.addImportedEntity(IE);
|
||||
|
||||
// LTO with assembly output shares a single line table amongst multiple CUs.
|
||||
// To avoid the compilation directory being ambiguous, let the line table
|
||||
// explicitly describe the directory of all files, never relying on the
|
||||
@ -1130,14 +1127,6 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
|
||||
return NewCU;
|
||||
}
|
||||
|
||||
void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
|
||||
const DIImportedEntity *N) {
|
||||
if (isa<DILocalScope>(N->getScope()))
|
||||
return;
|
||||
if (DIE *D = TheCU.getOrCreateContextDIE(N->getScope()))
|
||||
D->addChild(TheCU.constructImportedEntityDIE(N));
|
||||
}
|
||||
|
||||
/// Sort and unique GVEs by comparing their fragment offset.
|
||||
static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &
|
||||
sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) {
|
||||
@ -1215,16 +1204,8 @@ void DwarfDebug::beginModule(Module *M) {
|
||||
DebugLocs.setSym(Asm->createTempSymbol("loclists_table_base"));
|
||||
|
||||
for (DICompileUnit *CUNode : M->debug_compile_units()) {
|
||||
// FIXME: Move local imported entities into a list attached to the
|
||||
// subprogram, then this search won't be needed and a
|
||||
// getImportedEntities().empty() test should go below with the rest.
|
||||
bool HasNonLocalImportedEntities = llvm::any_of(
|
||||
CUNode->getImportedEntities(), [](const DIImportedEntity *IE) {
|
||||
return !isa<DILocalScope>(IE->getScope());
|
||||
});
|
||||
|
||||
if (!HasNonLocalImportedEntities && CUNode->getEnumTypes().empty() &&
|
||||
CUNode->getRetainedTypes().empty() &&
|
||||
if (CUNode->getImportedEntities().empty() &&
|
||||
CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
|
||||
CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
|
||||
continue;
|
||||
|
||||
@ -1442,8 +1423,17 @@ void DwarfDebug::endModule() {
|
||||
DwarfCompileUnit *CU = &*P.second;
|
||||
|
||||
// Emit imported entities.
|
||||
for (auto *IE : CUNode->getImportedEntities())
|
||||
constructAndAddImportedEntityDIE(*CU, IE);
|
||||
for (auto *IE : CUNode->getImportedEntities()) {
|
||||
assert(!isa_and_nonnull<DILocalScope>(IE->getScope()) &&
|
||||
"Unexpected function-local entity in 'imports' CU field.");
|
||||
CU->getOrCreateImportedEntityDIE(IE);
|
||||
}
|
||||
for (const auto *D : CU->getDeferredLocalDecls()) {
|
||||
if (auto *IE = dyn_cast<DIImportedEntity>(D))
|
||||
CU->getOrCreateImportedEntityDIE(IE);
|
||||
else
|
||||
llvm_unreachable("Unexpected local retained node!");
|
||||
}
|
||||
|
||||
// Emit base types.
|
||||
CU->createBaseTypeDIEs();
|
||||
@ -1520,16 +1510,6 @@ void DwarfDebug::endModule() {
|
||||
// FIXME: AbstractVariables.clear();
|
||||
}
|
||||
|
||||
void DwarfDebug::ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
|
||||
const DINode *Node,
|
||||
const MDNode *ScopeNode) {
|
||||
if (CU.getExistingAbstractEntity(Node))
|
||||
return;
|
||||
|
||||
CU.createAbstractEntity(Node, LScopes.getOrCreateAbstractScope(
|
||||
cast<DILocalScope>(ScopeNode)));
|
||||
}
|
||||
|
||||
void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
|
||||
const DINode *Node, const MDNode *ScopeNode) {
|
||||
if (CU.getExistingAbstractEntity(Node))
|
||||
@ -1540,6 +1520,21 @@ void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
|
||||
CU.createAbstractEntity(Node, Scope);
|
||||
}
|
||||
|
||||
static const DILocalScope *getRetainedNodeScope(const MDNode *N) {
|
||||
const DIScope *S;
|
||||
if (const auto *LV = dyn_cast<DILocalVariable>(N))
|
||||
S = LV->getScope();
|
||||
else if (const auto *L = dyn_cast<DILabel>(N))
|
||||
S = L->getScope();
|
||||
else if (const auto *IE = dyn_cast<DIImportedEntity>(N))
|
||||
S = IE->getScope();
|
||||
else
|
||||
llvm_unreachable("Unexpected retained node!");
|
||||
|
||||
// Ensure the scope is not a DILexicalBlockFile.
|
||||
return cast<DILocalScope>(S)->getNonLexicalBlockFileScope();
|
||||
}
|
||||
|
||||
// Collect variable information from side table maintained by MF.
|
||||
void DwarfDebug::collectVariableInfoFromMFTable(
|
||||
DwarfCompileUnit &TheCU, DenseSet<InlinedEntity> &Processed) {
|
||||
@ -1984,19 +1979,18 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
|
||||
createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);
|
||||
}
|
||||
|
||||
// Collect info for variables/labels that were optimized out.
|
||||
// Collect info for retained nodes.
|
||||
for (const DINode *DN : SP->getRetainedNodes()) {
|
||||
if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
|
||||
continue;
|
||||
LexicalScope *Scope = nullptr;
|
||||
if (auto *DV = dyn_cast<DILocalVariable>(DN)) {
|
||||
Scope = LScopes.findLexicalScope(DV->getScope());
|
||||
} else if (auto *DL = dyn_cast<DILabel>(DN)) {
|
||||
Scope = LScopes.findLexicalScope(DL->getScope());
|
||||
const auto *LS = getRetainedNodeScope(DN);
|
||||
if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
|
||||
if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
|
||||
continue;
|
||||
LexicalScope *LexS = LScopes.findLexicalScope(LS);
|
||||
if (LexS)
|
||||
createConcreteEntity(TheCU, *LexS, DN, nullptr);
|
||||
} else {
|
||||
LocalDeclsPerLS[LS].insert(DN);
|
||||
}
|
||||
|
||||
if (Scope)
|
||||
createConcreteEntity(TheCU, *Scope, DN, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2311,27 +2305,28 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
size_t NumAbstractScopes = LScopes.getAbstractScopesList().size();
|
||||
size_t NumAbstractSubprograms = LScopes.getAbstractScopesList().size();
|
||||
#endif
|
||||
// Construct abstract scopes.
|
||||
for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
|
||||
const auto *SP = cast<DISubprogram>(AScope->getScopeNode());
|
||||
for (const DINode *DN : SP->getRetainedNodes()) {
|
||||
if (!Processed.insert(InlinedEntity(DN, nullptr)).second)
|
||||
continue;
|
||||
|
||||
const MDNode *Scope = nullptr;
|
||||
if (auto *DV = dyn_cast<DILocalVariable>(DN))
|
||||
Scope = DV->getScope();
|
||||
else if (auto *DL = dyn_cast<DILabel>(DN))
|
||||
Scope = DL->getScope();
|
||||
else
|
||||
llvm_unreachable("Unexpected DI type!");
|
||||
|
||||
// Collect info for variables/labels that were optimized out.
|
||||
ensureAbstractEntityIsCreated(TheCU, DN, Scope);
|
||||
assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
|
||||
&& "ensureAbstractEntityIsCreated inserted abstract scopes");
|
||||
const auto *LS = getRetainedNodeScope(DN);
|
||||
// Ensure LexicalScope is created for the scope of this node.
|
||||
auto *LexS = LScopes.getOrCreateAbstractScope(LS);
|
||||
assert(LexS && "Expected the LexicalScope to be created.");
|
||||
if (isa<DILocalVariable>(DN) || isa<DILabel>(DN)) {
|
||||
// Collect info for variables/labels that were optimized out.
|
||||
if (!Processed.insert(InlinedEntity(DN, nullptr)).second ||
|
||||
TheCU.getExistingAbstractEntity(DN))
|
||||
continue;
|
||||
TheCU.createAbstractEntity(DN, LexS);
|
||||
} else {
|
||||
// Remember the node if this is a local declarations.
|
||||
LocalDeclsPerLS[LS].insert(DN);
|
||||
}
|
||||
assert(
|
||||
LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&
|
||||
"getOrCreateAbstractScope() inserted an abstract subprogram scope");
|
||||
}
|
||||
constructAbstractSubprogramScopeDIE(TheCU, AScope);
|
||||
}
|
||||
@ -2352,6 +2347,7 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
||||
// can be used cross-function)
|
||||
InfoHolder.getScopeVariables().clear();
|
||||
InfoHolder.getScopeLabels().clear();
|
||||
LocalDeclsPerLS.clear();
|
||||
PrevLabel = nullptr;
|
||||
CurFn = nullptr;
|
||||
}
|
||||
|
@ -320,6 +320,13 @@ class DwarfDebug : public DebugHandlerBase {
|
||||
/// create DIEs.
|
||||
SmallSetVector<const DISubprogram *, 16> ProcessedSPNodes;
|
||||
|
||||
/// Map function-local imported entities to their parent local scope
|
||||
/// (either DILexicalBlock or DISubprogram) for a processed function
|
||||
/// (including inlined subprograms).
|
||||
using MDNodeSet = SetVector<const MDNode *, SmallVector<const MDNode *, 2>,
|
||||
SmallPtrSet<const MDNode *, 2>>;
|
||||
DenseMap<const DILocalScope *, MDNodeSet> LocalDeclsPerLS;
|
||||
|
||||
/// If nonnull, stores the current machine function we're processing.
|
||||
const MachineFunction *CurFn = nullptr;
|
||||
|
||||
@ -454,9 +461,6 @@ private:
|
||||
|
||||
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
|
||||
|
||||
void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU,
|
||||
const DINode *Node,
|
||||
const MDNode *Scope);
|
||||
void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,
|
||||
const DINode *Node,
|
||||
const MDNode *Scope);
|
||||
@ -596,10 +600,6 @@ private:
|
||||
void finishUnitAttributes(const DICompileUnit *DIUnit,
|
||||
DwarfCompileUnit &NewCU);
|
||||
|
||||
/// Construct imported_module or imported_declaration DIE.
|
||||
void constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
|
||||
const DIImportedEntity *N);
|
||||
|
||||
/// Register a source line with debug info. Returns the unique
|
||||
/// label that was emitted and which provides correspondence to the
|
||||
/// source line list.
|
||||
@ -838,6 +838,10 @@ public:
|
||||
/// If the \p File has an MD5 checksum, return it as an MD5Result
|
||||
/// allocated in the MCContext.
|
||||
std::optional<MD5::MD5Result> getMD5AsBytes(const DIFile *File) const;
|
||||
|
||||
MDNodeSet &getLocalDeclsForScope(const DILocalScope *S) {
|
||||
return LocalDeclsPerLS[S];
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -26,6 +26,7 @@ class DbgEntity;
|
||||
class DbgVariable;
|
||||
class DbgLabel;
|
||||
class DINode;
|
||||
class DILocalScope;
|
||||
class DwarfCompileUnit;
|
||||
class DwarfUnit;
|
||||
class LexicalScope;
|
||||
@ -87,7 +88,7 @@ class DwarfFile {
|
||||
DenseMap<LexicalScope *, LabelList> ScopeLabels;
|
||||
|
||||
// Collection of abstract subprogram DIEs.
|
||||
DenseMap<const MDNode *, DIE *> AbstractSPDies;
|
||||
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
|
||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
|
||||
|
||||
/// Maps MDNodes for type system with the corresponding DIEs. These DIEs can
|
||||
@ -162,8 +163,8 @@ public:
|
||||
return ScopeLabels;
|
||||
}
|
||||
|
||||
DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
|
||||
return AbstractSPDies;
|
||||
DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {
|
||||
return AbstractLocalScopeDIEs;
|
||||
}
|
||||
|
||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {
|
||||
|
@ -1223,7 +1223,7 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
|
||||
"decl has a linkage name and it is different");
|
||||
if (DeclLinkageName.empty() &&
|
||||
// Always emit it for abstract subprograms.
|
||||
(DD->useAllLinkageNames() || DU->getAbstractSPDies().lookup(SP)))
|
||||
(DD->useAllLinkageNames() || DU->getAbstractScopeDIEs().lookup(SP)))
|
||||
addLinkageName(SPDie, LinkageName);
|
||||
|
||||
if (!DeclDie)
|
||||
|
@ -245,10 +245,10 @@ public:
|
||||
DIE *createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty);
|
||||
|
||||
/// Find existing DIE or create new DIE for the given type.
|
||||
DIE *getOrCreateTypeDIE(const MDNode *TyNode);
|
||||
virtual DIE *getOrCreateTypeDIE(const MDNode *TyNode);
|
||||
|
||||
/// Get context owner's DIE.
|
||||
DIE *getOrCreateContextDIE(const DIScope *Context);
|
||||
virtual DIE *getOrCreateContextDIE(const DIScope *Context);
|
||||
|
||||
/// Construct DIEs for types that contain vtables.
|
||||
void constructContainingTypeDIEs();
|
||||
|
@ -35,7 +35,7 @@ DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)
|
||||
if (const auto &GVs = CUNode->getGlobalVariables())
|
||||
AllGVs.assign(GVs.begin(), GVs.end());
|
||||
if (const auto &IMs = CUNode->getImportedEntities())
|
||||
AllImportedModules.assign(IMs.begin(), IMs.end());
|
||||
ImportedModules.assign(IMs.begin(), IMs.end());
|
||||
if (const auto &MNs = CUNode->getMacros())
|
||||
AllMacrosPerParent.insert({nullptr, {MNs.begin(), MNs.end()}});
|
||||
}
|
||||
@ -93,10 +93,10 @@ void DIBuilder::finalize() {
|
||||
if (!AllGVs.empty())
|
||||
CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs));
|
||||
|
||||
if (!AllImportedModules.empty())
|
||||
if (!ImportedModules.empty())
|
||||
CUNode->replaceImportedEntities(MDTuple::get(
|
||||
VMContext, SmallVector<Metadata *, 16>(AllImportedModules.begin(),
|
||||
AllImportedModules.end())));
|
||||
VMContext, SmallVector<Metadata *, 16>(ImportedModules.begin(),
|
||||
ImportedModules.end())));
|
||||
|
||||
for (const auto &I : AllMacrosPerParent) {
|
||||
// DIMacroNode's with nullptr parent are DICompileUnit direct children.
|
||||
@ -160,7 +160,7 @@ static DIImportedEntity *
|
||||
createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context,
|
||||
Metadata *NS, DIFile *File, unsigned Line, StringRef Name,
|
||||
DINodeArray Elements,
|
||||
SmallVectorImpl<TrackingMDNodeRef> &AllImportedModules) {
|
||||
SmallVectorImpl<TrackingMDNodeRef> &ImportedModules) {
|
||||
if (Line)
|
||||
assert(File && "Source location has line number but no file");
|
||||
unsigned EntitiesCount = C.pImpl->DIImportedEntitys.size();
|
||||
@ -169,7 +169,7 @@ createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context,
|
||||
if (EntitiesCount < C.pImpl->DIImportedEntitys.size())
|
||||
// A new Imported Entity was just added to the context.
|
||||
// Add it to the Imported Modules list.
|
||||
AllImportedModules.emplace_back(M);
|
||||
ImportedModules.emplace_back(M);
|
||||
return M;
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,
|
||||
DINodeArray Elements) {
|
||||
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
|
||||
Context, NS, File, Line, StringRef(), Elements,
|
||||
AllImportedModules);
|
||||
getImportTrackingVector(Context));
|
||||
}
|
||||
|
||||
DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,
|
||||
@ -188,7 +188,7 @@ DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,
|
||||
DINodeArray Elements) {
|
||||
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
|
||||
Context, NS, File, Line, StringRef(), Elements,
|
||||
AllImportedModules);
|
||||
getImportTrackingVector(Context));
|
||||
}
|
||||
|
||||
DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M,
|
||||
@ -196,7 +196,7 @@ DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M,
|
||||
DINodeArray Elements) {
|
||||
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
|
||||
Context, M, File, Line, StringRef(), Elements,
|
||||
AllImportedModules);
|
||||
getImportTrackingVector(Context));
|
||||
}
|
||||
|
||||
DIImportedEntity *
|
||||
@ -207,7 +207,7 @@ DIBuilder::createImportedDeclaration(DIScope *Context, DINode *Decl,
|
||||
// types that have one.
|
||||
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration,
|
||||
Context, Decl, File, Line, Name, Elements,
|
||||
AllImportedModules);
|
||||
getImportTrackingVector(Context));
|
||||
}
|
||||
|
||||
DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory,
|
||||
|
@ -1383,9 +1383,11 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
|
||||
auto *Node = dyn_cast<MDTuple>(RawNode);
|
||||
CheckDI(Node, "invalid retained nodes list", &N, RawNode);
|
||||
for (Metadata *Op : Node->operands()) {
|
||||
CheckDI(Op && (isa<DILocalVariable>(Op) || isa<DILabel>(Op)),
|
||||
"invalid retained nodes, expected DILocalVariable or DILabel", &N,
|
||||
Node, Op);
|
||||
CheckDI(Op && (isa<DILocalVariable>(Op) || isa<DILabel>(Op) ||
|
||||
isa<DIImportedEntity>(Op)),
|
||||
"invalid retained nodes, expected DILocalVariable, DILabel or "
|
||||
"DIImportedEntity",
|
||||
&N, Node, Op);
|
||||
}
|
||||
}
|
||||
CheckDI(!hasConflictingReferenceFlags(N.getFlags()),
|
||||
|
@ -1211,39 +1211,7 @@ void IRLinker::prepareCompileUnitsForImport() {
|
||||
// size inefficient.
|
||||
CU->replaceGlobalVariables(nullptr);
|
||||
|
||||
// Imported entities only need to be mapped in if they have local
|
||||
// scope, as those might correspond to an imported entity inside a
|
||||
// function being imported (any locally scoped imported entities that
|
||||
// don't end up referenced by an imported function will not be emitted
|
||||
// into the object). Imported entities not in a local scope
|
||||
// (e.g. on the namespace) only need to be emitted by the originating
|
||||
// module. Create a list of the locally scoped imported entities, and
|
||||
// replace the source CUs imported entity list with the new list, so
|
||||
// only those are mapped in.
|
||||
// FIXME: Locally-scoped imported entities could be moved to the
|
||||
// functions they are local to instead of listing them on the CU, and
|
||||
// we would naturally only link in those needed by function importing.
|
||||
SmallVector<TrackingMDNodeRef, 4> AllImportedModules;
|
||||
bool ReplaceImportedEntities = false;
|
||||
for (auto *IE : CU->getImportedEntities()) {
|
||||
DIScope *Scope = IE->getScope();
|
||||
assert(Scope && "Invalid Scope encoding!");
|
||||
if (isa<DILocalScope>(Scope))
|
||||
AllImportedModules.emplace_back(IE);
|
||||
else
|
||||
ReplaceImportedEntities = true;
|
||||
}
|
||||
if (ReplaceImportedEntities) {
|
||||
if (!AllImportedModules.empty())
|
||||
CU->replaceImportedEntities(MDTuple::get(
|
||||
CU->getContext(),
|
||||
SmallVector<Metadata *, 16>(AllImportedModules.begin(),
|
||||
AllImportedModules.end())));
|
||||
else
|
||||
// If there were no local scope imported entities, we can map
|
||||
// the whole list to nullptr.
|
||||
CU->replaceImportedEntities(nullptr);
|
||||
}
|
||||
CU->replaceImportedEntities(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,11 @@
|
||||
; RUN: llvm-dis -o - %s.bc | FileCheck %s
|
||||
|
||||
;Test whether DIImportedEntity are generated correctly.
|
||||
; CHECK: distinct !DICompileUnit(language: DW_LANG_Fortran90
|
||||
; CHECK-SAME: imports: [[IMPORTS:![0-9]+]]
|
||||
; CHECK: [[SP:![0-9]+]] = distinct !DISubprogram(name: "use_renamed"
|
||||
; CHECK-SAME: retainedNodes: [[IMPORTS:![0-9]+]]
|
||||
; CHECK: [[IMPORTS]] = !{[[IMPORT1:![0-9]+]], [[IMPORT2:![0-9]+]]}
|
||||
; CHECK: [[IMPORT1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: {{![0-9]+}}, entity: {{![0-9]+}}, file: {{![0-9]+}}, line: {{[0-9]+}})
|
||||
; CHECK: [[IMPORT2]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "var4", scope: {{![0-9]+}}, entity: {{![0-9]+}}, file: {{![0-9]+}}, line: {{[0-9]+}})
|
||||
; CHECK: [[IMPORT1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[SP]], entity: {{![0-9]+}}, file: {{![0-9]+}}, line: {{[0-9]+}})
|
||||
; CHECK: [[IMPORT2]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "var4", scope: [[SP]], entity: {{![0-9]+}}, file: {{![0-9]+}}, line: {{[0-9]+}})
|
||||
|
||||
; ModuleID = 'DIImportedEntity_backward.bc'
|
||||
source_filename = "/tmp/usemodulealias.ll"
|
||||
@ -58,7 +58,7 @@ declare void @fort_init(...)
|
||||
!1 = distinct !DIGlobalVariable(name: "var1", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
|
||||
!2 = !DIModule(scope: !4, name: "mymod", file: !3, line: 1)
|
||||
!3 = !DIFile(filename: "DIImportedEntity_backward.f90", directory: "/tmp")
|
||||
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang usemodulealias.f90 -g -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !12, nameTableKind: None)
|
||||
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang usemodulealias.f90 -g -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !5, nameTableKind: None)
|
||||
!5 = !{}
|
||||
!6 = !{!0, !7, !10}
|
||||
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_plus_uconst, 4))
|
||||
@ -68,7 +68,7 @@ declare void @fort_init(...)
|
||||
!11 = distinct !DIGlobalVariable(name: "var3", scope: !2, file: !3, line: 4, type: !9, isLocal: false, isDefinition: true)
|
||||
!12 = !{!13, !19}
|
||||
!13 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !14, entity: !2, file: !3, line: 10)
|
||||
!14 = distinct !DISubprogram(name: "use_renamed", scope: !15, file: !3, line: 10, type: !18, scopeLine: 10, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4)
|
||||
!14 = distinct !DISubprogram(name: "use_renamed", scope: !15, file: !3, line: 10, type: !18, scopeLine: 10, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4, retainedNodes: !12)
|
||||
!15 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 7, type: !16, scopeLine: 7, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4)
|
||||
!16 = !DISubroutineType(cc: DW_CC_program, types: !17)
|
||||
!17 = !{null}
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: llvm-as -o - %s | llvm-dis -o - | FileCheck %s
|
||||
; CHECK: DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !11, file: !3, line: 2)
|
||||
; CHECK: DIModule(scope: !2, name: "external_module", isDecl: true)
|
||||
; CHECK: DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: ![[MOD:[0-9]+]], file: !3, line: 2)
|
||||
; CHECK: ![[MOD]] = !DIModule(scope: !2, name: "external_module", isDecl: true)
|
||||
|
||||
; ModuleID = 'em.f90'
|
||||
source_filename = "em.f90"
|
||||
|
118
llvm/test/Bitcode/upgrade-cu-locals.ll
Normal file
118
llvm/test/Bitcode/upgrade-cu-locals.ll
Normal file
@ -0,0 +1,118 @@
|
||||
; Test moving of local imports from DICompileUnit's 'imports' to DISubprogram's 'retainedNodes'
|
||||
;
|
||||
; RUN: llvm-dis -o - %s.bc | FileCheck %s
|
||||
|
||||
%"struct.ns::t1" = type { i8 }
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
|
||||
|
||||
declare dso_local void @_Z3pinv() local_unnamed_addr
|
||||
|
||||
define dso_local i32 @main() local_unnamed_addr !dbg !23 {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata ptr undef, metadata !39, metadata !DIExpression()), !dbg !40
|
||||
call void @_Z3pinv(), !dbg !42
|
||||
ret i32 0, !dbg !43
|
||||
}
|
||||
|
||||
define dso_local i32 @main2() local_unnamed_addr !dbg !29 {
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
||||
|
||||
!llvm.dbg.cu = !{!0, !16}
|
||||
!llvm.ident = !{!33, !33}
|
||||
!llvm.module.flags = !{!34, !35, !36, !37, !38}
|
||||
|
||||
; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, imports: !2,
|
||||
; CHECK: !2 = !{!3}
|
||||
; CHECK: !3 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !4,
|
||||
; CHECK: !4 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t4"
|
||||
|
||||
; CHECK: !5 = !{}
|
||||
; CHECK: !6 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !7, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, imports: !5, nameTableKind: GNU)
|
||||
|
||||
; CHECK: !14 = distinct !DISubprogram(name: "main", scope: !7, file: !7, line: 2, type: !15, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !18)
|
||||
; CHECK: !18 = !{!19}
|
||||
; CHECK: !19 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !20, entity: !23,
|
||||
; CHECK: !20 = !DILexicalBlock(scope: !21, file: !7, line: 7, column: 35)
|
||||
; CHECK: !21 = !DILexicalBlock(scope: !22, file: !7, line: 7, column: 35)
|
||||
; CHECK: !22 = !DILexicalBlock(scope: !14, file: !7, line: 7, column: 35)
|
||||
; CHECK: !23 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t5", scope: !20,
|
||||
|
||||
; CHECK: !25 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 3, type: !26, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !28)
|
||||
; CHECK: !28 = !{!29, !32, !34}
|
||||
; CHECK: !29 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !25, entity: !30,
|
||||
; CHECK: !30 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1",
|
||||
; CHECK: !32 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !25, entity: !33,
|
||||
; CHECK: !33 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2",
|
||||
; CHECK: !34 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !25, entity: !35,
|
||||
; CHECK: !35 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t3",
|
||||
|
||||
; CHECK: !40 = distinct !DISubprogram(name: "main2", scope: !7, file: !7, line: 10, type: !15, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !6, retainedNodes: !41)
|
||||
; CHECK: !41 = !{!42, !44}
|
||||
; CHECK: !42 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !40, entity: !43,
|
||||
; CHECK: !43 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t6"
|
||||
; CHECK: !44 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !40, entity: !45,
|
||||
; CHECK: !45 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t7",
|
||||
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, imports: !2, nameTableKind: GNU)
|
||||
!1 = !DIFile(filename: "a.cpp", directory: "/")
|
||||
!2 = !{!3, !10, !12, !14}
|
||||
|
||||
; Move t1 to DISubprogram f1
|
||||
!3 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !8, file: !1, line: 3)
|
||||
!4 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !7)
|
||||
!5 = !DISubroutineType(types: !6)
|
||||
!6 = !{null}
|
||||
!7 = !{}
|
||||
!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", scope: !9, file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTSN2ns2t1E")
|
||||
!9 = !DINamespace(name: "ns", scope: null)
|
||||
|
||||
; Move t2 to DISubprogram f1
|
||||
!10 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !11, file: !1, line: 3)
|
||||
!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", scope: !9, file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTSN2ns2t2E")
|
||||
|
||||
; Move t3 to DISubprogram f1
|
||||
!12 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !13, file: !1, line: 3)
|
||||
!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t3", scope: !9, file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTSN2ns2t3E")
|
||||
|
||||
; Leave t4 in CU
|
||||
!14 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !15, file: !1, line: 3)
|
||||
!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t4", scope: !0, file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTSN2ns2t4E")
|
||||
!16 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !17, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, imports: !18, nameTableKind: GNU)
|
||||
!17 = !DIFile(filename: "b.cpp", directory: "/")
|
||||
!18 = !{!19, !28, !31}
|
||||
|
||||
; Move t5 to DISubprogram main
|
||||
!19 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !20, entity: !27, file: !1, line: 3)
|
||||
!20 = !DILexicalBlock(scope: !21, file: !17, line: 7, column: 35)
|
||||
!21 = !DILexicalBlock(scope: !22, file: !17, line: 7, column: 35)
|
||||
!22 = !DILexicalBlock(scope: !23, file: !17, line: 7, column: 35)
|
||||
!23 = distinct !DISubprogram(name: "main", scope: !17, file: !17, line: 2, type: !24, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !16, retainedNodes: !7)
|
||||
!24 = !DISubroutineType(types: !25)
|
||||
!25 = !{!26}
|
||||
!26 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!27 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t5", scope: !20, file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTSN2ns2t5E")
|
||||
|
||||
; Move t6 to DISubprogram main2
|
||||
!28 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !29, entity: !30, file: !17, line: 3)
|
||||
!29 = distinct !DISubprogram(name: "main2", scope: !17, file: !17, line: 10, type: !24, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !16, retainedNodes: !7)
|
||||
!30 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t6", scope: !29, file: !17, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTSN2ns2t6E")
|
||||
|
||||
; Move t7 to DISubprogram main2
|
||||
!31 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !29, entity: !32, file: !17, line: 3)
|
||||
!32 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t7", scope: !29, file: !17, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTSN2ns2t7E")
|
||||
!33 = !{!"clang version 14.0.0"}
|
||||
!34 = !{i32 7, !"Dwarf Version", i32 4}
|
||||
!35 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!36 = !{i32 1, !"wchar_size", i32 4}
|
||||
!37 = !{i32 7, !"uwtable", i32 1}
|
||||
!38 = !{i32 7, !"frame-pointer", i32 2}
|
||||
!39 = !DILocalVariable(name: "v1", scope: !4, file: !1, line: 3, type: !8)
|
||||
!40 = !DILocation(line: 3, column: 37, scope: !4, inlinedAt: !41)
|
||||
!41 = distinct !DILocation(line: 3, column: 3, scope: !23)
|
||||
!42 = !DILocation(line: 3, column: 41, scope: !4, inlinedAt: !41)
|
||||
!43 = !DILocation(line: 4, column: 1, scope: !23)
|
BIN
llvm/test/Bitcode/upgrade-cu-locals.ll.bc
Normal file
BIN
llvm/test/Bitcode/upgrade-cu-locals.ll.bc
Normal file
Binary file not shown.
@ -21,12 +21,12 @@ attributes #1 = { nounwind readnone speculatable }
|
||||
!llvm.dbg.cu = !{!1}
|
||||
|
||||
!0 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!1 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !2, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, retainedTypes: !3, globals: !3, imports: !4)
|
||||
!1 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !2, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, retainedTypes: !3, globals: !3)
|
||||
!2 = !DIFile(filename: "input", directory: "/")
|
||||
!3 = !{}
|
||||
!4 = !{!5}
|
||||
!5 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !6, entity: !9, file: !2, line: 18)
|
||||
!6 = distinct !DISubprogram(name: "p", scope: !1, file: !2, line: 18, type: !7, isLocal: false, isDefinition: true, scopeLine: 18, isOptimized: false, unit: !1)
|
||||
!6 = distinct !DISubprogram(name: "p", scope: !1, file: !2, line: 18, type: !7, isLocal: false, isDefinition: true, scopeLine: 18, isOptimized: false, unit: !1, retainedNodes: !4)
|
||||
!7 = !DISubroutineType(cc: DW_CC_program, types: !8)
|
||||
!8 = !{null}
|
||||
!9 = !DIModule(scope: !1, name: "mod")
|
||||
|
72
llvm/test/DebugInfo/Generic/import-inlined-declaration.ll
Normal file
72
llvm/test/DebugInfo/Generic/import-inlined-declaration.ll
Normal file
@ -0,0 +1,72 @@
|
||||
; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck --implicit-check-not "{{DW_TAG|NULL}}" %s
|
||||
|
||||
; namespace ns {
|
||||
; inline __attribute__((always_inline))
|
||||
; void foo() { int a = 4; }
|
||||
; }
|
||||
;
|
||||
; void goo() {
|
||||
; using ns::foo;
|
||||
; foo();
|
||||
; }
|
||||
|
||||
; Ensure that imported declarations reference the correct subprograms even if
|
||||
; those subprograms are inlined.
|
||||
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_TAG_namespace
|
||||
; CHECK: DW_AT_name ("ns")
|
||||
; CHECK: [[FOO:0x.*]]: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("foo")
|
||||
; CHECK: DW_TAG_variable
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_base_type
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("goo")
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: DW_AT_abstract_origin ([[FOO]]
|
||||
; CHECK: DW_TAG_variable
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_imported_declaration
|
||||
; CHECK: DW_AT_import ([[FOO]])
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
|
||||
; Function Attrs: mustprogress noinline optnone uwtable
|
||||
define dso_local void @_Z3goov() !dbg !4 {
|
||||
entry:
|
||||
%a.i = alloca i32, align 4
|
||||
call void @llvm.dbg.declare(metadata i32* %a.i, metadata !16, metadata !DIExpression()), !dbg !18
|
||||
store i32 4, i32* %a.i, align 4, !dbg !18
|
||||
ret void, !dbg !20
|
||||
}
|
||||
|
||||
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!10, !11, !12, !13, !14}
|
||||
!llvm.ident = !{!15}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
|
||||
!1 = !DIFile(filename: "imported-inlined-declaration.cpp", directory: "")
|
||||
!2 = !{!3}
|
||||
!3 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !8, file: !1, line: 7)
|
||||
!4 = distinct !DISubprogram(name: "goo", linkageName: "_Z3goov", scope: !1, file: !1, line: 6, type: !5, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
|
||||
!5 = !DISubroutineType(types: !6)
|
||||
!6 = !{null}
|
||||
!7 = !{}
|
||||
!8 = distinct !DISubprogram(name: "foo", linkageName: "_ZN2ns3fooEv", scope: !9, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !7)
|
||||
!9 = !DINamespace(name: "ns", scope: null)
|
||||
!10 = !{i32 7, !"Dwarf Version", i32 4}
|
||||
!11 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!12 = !{i32 1, !"wchar_size", i32 4}
|
||||
!13 = !{i32 7, !"uwtable", i32 1}
|
||||
!14 = !{i32 7, !"frame-pointer", i32 2}
|
||||
!15 = !{!"clang version 14.0.0"}
|
||||
!16 = !DILocalVariable(name: "a", scope: !8, file: !1, line: 3, type: !17)
|
||||
!17 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!18 = !DILocation(line: 3, column: 18, scope: !8, inlinedAt: !19)
|
||||
!19 = distinct !DILocation(line: 8, column: 2, scope: !4)
|
||||
!20 = !DILocation(line: 9, column: 1, scope: !4)
|
@ -13,21 +13,17 @@
|
||||
; Ensure that top level imported declarations don't produce an extra degenerate
|
||||
; concrete subprogram definition.
|
||||
|
||||
; FIXME: imported entities should only be emitted to the abstract origin if one is present
|
||||
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("f1")
|
||||
; CHECK: DW_TAG_imported_declaration
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_namespace
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("f2")
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: DW_TAG_imported_declaration
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_namespace
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
|
||||
@ -44,12 +40,12 @@ declare void @_ZN2ns1fEv()
|
||||
!llvm.module.flags = !{!10, !11, !12}
|
||||
!llvm.ident = !{!13}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 (trunk 309061) (llvm/trunk 309076)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, imports: !3)
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 (trunk 309061) (llvm/trunk 309076)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
|
||||
!1 = !DIFile(filename: "imported-name-inlined.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
|
||||
!2 = !{}
|
||||
!3 = !{!4}
|
||||
!4 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !5, entity: !8, file: !1, line: 5)
|
||||
!5 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 4, type: !6, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
|
||||
!5 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 4, type: !6, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !3)
|
||||
!6 = !DISubroutineType(types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DISubprogram(name: "f", linkageName: "_ZN2ns1fEv", scope: !9, file: !1, line: 2, type: !6, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: false)
|
||||
|
@ -33,6 +33,10 @@
|
||||
; CHECK: DW_TAG_formal_parameter
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: [[FUNC_FWD:0x[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("func_fwd")
|
||||
; CHECK-NOT: DW_AT_declaration
|
||||
|
||||
; CHECK: [[BAZ:0x[0-9a-f]*]]:{{.*}}DW_TAG_typedef
|
||||
; CHECK: DW_AT_name ("baz")
|
||||
|
||||
@ -43,10 +47,6 @@
|
||||
; CHECK: [[FUNC_DECL:0x[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("func_decl")
|
||||
; CHECK: DW_AT_declaration
|
||||
|
||||
; CHECK: [[FUNC_FWD:0x[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("func_fwd")
|
||||
; CHECK-NOT: DW_AT_declaration
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: DW_TAG_imported_module
|
||||
@ -63,6 +63,12 @@
|
||||
; CHECK: DW_AT_MIPS_linkage_name
|
||||
; CHECK: DW_AT_name ("func")
|
||||
; CHECK: DW_TAG_formal_parameter
|
||||
; CHECK: DW_TAG_lexical_block
|
||||
; CHECK: DW_TAG_imported_module
|
||||
; CHECK: DW_AT_decl_file ([[F2]])
|
||||
; CHECK: DW_AT_decl_line (23)
|
||||
; CHECK: DW_AT_import {{.*}}
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_imported_module
|
||||
; CHECK: DW_AT_decl_file ([[F2:.*]])
|
||||
; CHECK: DW_AT_decl_line (26)
|
||||
@ -113,12 +119,6 @@
|
||||
; CHECK: DW_AT_decl_file ([[F2]])
|
||||
; CHECK: DW_AT_decl_line (37)
|
||||
; CHECK: DW_AT_import ([[FUNC_FWD]])
|
||||
; CHECK: DW_TAG_lexical_block
|
||||
; CHECK: DW_TAG_imported_module
|
||||
; CHECK: DW_AT_decl_file ([[F2]])
|
||||
; CHECK: DW_AT_decl_line (23)
|
||||
; CHECK: DW_AT_import {{.*}}
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
@ -293,7 +293,7 @@ attributes #1 = { nounwind readnone }
|
||||
!18 = !DIFile(filename: "foo.cpp", directory: "/tmp")
|
||||
!19 = !DISubroutineType(types: !20)
|
||||
!20 = !{null}
|
||||
!21 = distinct !DISubprogram(name: "func", linkageName: "_Z4funcb", line: 21, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 21, file: !5, scope: !18, type: !22, retainedNodes: !2)
|
||||
!21 = distinct !DISubprogram(name: "func", linkageName: "_Z4funcb", line: 21, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 21, file: !5, scope: !18, type: !22, retainedNodes: !77)
|
||||
!22 = !DISubroutineType(types: !23)
|
||||
!23 = !{!13, !24}
|
||||
!24 = !DIBasicType(tag: DW_TAG_base_type, name: "bool", size: 8, align: 8, encoding: DW_ATE_boolean)
|
||||
@ -305,7 +305,7 @@ attributes #1 = { nounwind readnone }
|
||||
!30 = !{!131, !132}
|
||||
!31 = !DIGlobalVariable(name: "i", linkageName: "_ZN1A1B1iE", line: 20, isLocal: false, isDefinition: true, scope: !6, file: !18, type: !13)
|
||||
!32 = !DIGlobalVariable(name: "var_fwd", linkageName: "_ZN1A1B7var_fwdE", line: 44, isLocal: false, isDefinition: true, scope: !6, file: !18, type: !13)
|
||||
!33 = !{!34, !35, !36, !37, !40, !41, !42, !43, !44, !45, !47, !48, !49, !51, !54, !55, !56}
|
||||
!33 = !{!34, !35, !36, !56}
|
||||
!34 = !DIImportedEntity(tag: DW_TAG_imported_module, file: !5, line: 15, scope: !7, entity: !6)
|
||||
!35 = !DIImportedEntity(tag: DW_TAG_imported_module, file: !5, line: 18, scope: !0, entity: !7)
|
||||
!36 = !DIImportedEntity(tag: DW_TAG_imported_declaration, file: !5, line: 19, name: "E", scope: !0, entity: !7)
|
||||
@ -348,5 +348,6 @@ attributes #1 = { nounwind readnone }
|
||||
!73 = !DILocation(line: 47, column: 21, scope: !26)
|
||||
!74 = !DILocation(line: 0, scope: !75)
|
||||
!75 = !DILexicalBlockFile(discriminator: 0, file: !5, scope: !27)
|
||||
!77 = !{!37, !40, !41, !42, !43, !44, !45, !47, !48, !49, !51, !54, !55}
|
||||
!131 = !DIGlobalVariableExpression(var: !31, expr: !DIExpression())
|
||||
!132 = !DIGlobalVariableExpression(var: !32, expr: !DIExpression())
|
||||
|
75
llvm/test/DebugInfo/Generic/split-dwarf-local-import.ll
Normal file
75
llvm/test/DebugInfo/Generic/split-dwarf-local-import.ll
Normal file
@ -0,0 +1,75 @@
|
||||
; REQUIRES: x86-registered-target
|
||||
; RUN: %llc_dwarf -O1 -filetype=obj -split-dwarf-file=%t.dwo < %s | llvm-dwarfdump -debug-info - | FileCheck %s --implicit-check-not "{{DW_TAG|NULL}}"
|
||||
|
||||
; CHECK-LABEL: debug_info contents
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_AT_GNU_dwo_name
|
||||
; CHECK: DW_AT_GNU_dwo_id
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK-LABEL: debug_info.dwo contents
|
||||
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_TAG_imported_declaration
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_namespace
|
||||
; CHECK: DW_TAG_structure_type
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_base_type
|
||||
; CHECK: NULL
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
%"struct.ns::t1" = type { i8 }
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
declare dso_local void @_Z3pinv() local_unnamed_addr
|
||||
|
||||
define dso_local i32 @main() local_unnamed_addr !dbg !18 {
|
||||
entry:
|
||||
call void @llvm.dbg.declare(metadata %"struct.ns::t1"* undef, metadata !22, metadata !DIExpression()), !dbg !23
|
||||
call void @_Z3pinv(), !dbg !25
|
||||
ret i32 0, !dbg !26
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0, !10}
|
||||
!llvm.ident = !{!12, !12}
|
||||
!llvm.module.flags = !{!13, !14, !15, !16, !17}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: true, nameTableKind: GNU)
|
||||
!1 = !DIFile(filename: "a.cpp", directory: "/")
|
||||
!2 = !{!3}
|
||||
!3 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !8, file: !1, line: 3)
|
||||
!4 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
|
||||
!5 = !DISubroutineType(types: !6)
|
||||
!6 = !{null}
|
||||
!7 = !{}
|
||||
!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", scope: !9, file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "_ZTSN2ns2t1E")
|
||||
!9 = !DINamespace(name: "ns", scope: null)
|
||||
!10 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !11, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: true, nameTableKind: GNU)
|
||||
!11 = !DIFile(filename: "b.cpp", directory: "/")
|
||||
!12 = !{!"clang version 14.0.0"}
|
||||
!13 = !{i32 7, !"Dwarf Version", i32 4}
|
||||
!14 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!15 = !{i32 1, !"wchar_size", i32 4}
|
||||
!16 = !{i32 7, !"uwtable", i32 1}
|
||||
!17 = !{i32 7, !"frame-pointer", i32 2}
|
||||
!18 = distinct !DISubprogram(name: "main", scope: !11, file: !11, line: 2, type: !19, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !10, retainedNodes: !7)
|
||||
!19 = !DISubroutineType(types: !20)
|
||||
!20 = !{!21}
|
||||
!21 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!22 = !DILocalVariable(name: "v1", scope: !4, file: !1, line: 3, type: !8)
|
||||
!23 = !DILocation(line: 3, column: 37, scope: !4, inlinedAt: !24)
|
||||
!24 = distinct !DILocation(line: 3, column: 3, scope: !18)
|
||||
!25 = !DILocation(line: 3, column: 41, scope: !4, inlinedAt: !24)
|
||||
!26 = !DILocation(line: 4, column: 1, scope: !18)
|
44
llvm/test/DebugInfo/Generic/split-dwarf-local-import2.ll
Normal file
44
llvm/test/DebugInfo/Generic/split-dwarf-local-import2.ll
Normal file
@ -0,0 +1,44 @@
|
||||
; REQUIRES: x86-registered-target
|
||||
; RUN: %llc_dwarf -split-dwarf-file=%t.dwo < %s | FileCheck %s
|
||||
|
||||
; Ensure function-local DW_TAG_imported_declaration get skipped if its parent subprogram was not emitted.
|
||||
; CHECK-NOT: DW_TAG_imported_declaration
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @f1() !dbg !13 {
|
||||
lbl:
|
||||
ret void, !dbg !16
|
||||
}
|
||||
|
||||
define void @f2() !dbg !22 {
|
||||
lbl:
|
||||
ret void, !dbg !23
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0, !2, !10}
|
||||
!llvm.module.flags = !{!12}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, emissionKind: FullDebug)
|
||||
!1 = !DIFile(filename: "a.cc", directory: "")
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, emissionKind: FullDebug)
|
||||
!3 = !DIFile(filename: "b.cc", directory: "")
|
||||
!4 = !{!5}
|
||||
!5 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !6, entity: !7)
|
||||
!6 = !DISubprogram(scope: null, spFlags: DISPFlagOptimized, retainedNodes: !4)
|
||||
!7 = !DINamespace(scope: !2)
|
||||
!8 = !DISubroutineType(types: !9)
|
||||
!9 = !{}
|
||||
!10 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !11, emissionKind: FullDebug)
|
||||
!11 = !DIFile(filename: "c.cc", directory: "")
|
||||
!12 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!13 = distinct !DISubprogram(scope: null, type: !8, spFlags: DISPFlagDefinition, unit: !0)
|
||||
!16 = !DILocation(line: 0, scope: !17, inlinedAt: !18)
|
||||
!17 = distinct !DISubprogram(scope: null, unit: !10)
|
||||
!18 = !DILocation(line: 0, scope: !21)
|
||||
!21 = !DILexicalBlockFile(scope: !13, discriminator: 0)
|
||||
!22 = distinct !DISubprogram(scope: null, type: !8, spFlags: DISPFlagDefinition, unit: !0)
|
||||
!23 = !DILocation(line: 0, scope: !24, inlinedAt: !25)
|
||||
!24 = distinct !DISubprogram(scope: null, unit: !2)
|
||||
!25 = !DILocation(line: 0, scope: !22)
|
70
llvm/test/DebugInfo/Generic/split-dwarf-local-import3.ll
Normal file
70
llvm/test/DebugInfo/Generic/split-dwarf-local-import3.ll
Normal file
@ -0,0 +1,70 @@
|
||||
; REQUIRES: x86_64-linux
|
||||
; RUN: %llc_dwarf -O1 -filetype=obj -split-dwarf-file=%t.dwo < %s \
|
||||
; RUN: | llvm-dwarfdump -debug-info - \
|
||||
; RUN: | FileCheck %s --implicit-check-not "{{DW_TAG|NULL}}"
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Ensure that the imported entity 'nn::A' gets emitted in 'foo()'s abstract tree
|
||||
; in the destination (where 'foo()' was inlined) compile unit.
|
||||
|
||||
; CHECK-LABEL: .debug_info contents
|
||||
; CHECK: DW_TAG_skeleton_unit
|
||||
; CHECK: DW_AT_dwo_name
|
||||
|
||||
; CHECK-LABEL: .debug_info.dwo contents:
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_AT_name ("test.cpp")
|
||||
; CHECK: DW_AT_dwo_name
|
||||
|
||||
; CHECK: [[ABSTRACT_FOO:0x[0-9a-f]+]]: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("foo")
|
||||
; CHECK: DW_TAG_imported_declaration
|
||||
; CHECK: DW_AT_import ([[A:0x[0-9a-f]+]])
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: DW_TAG_base_type
|
||||
; CHECK: DW_AT_name ("int")
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("main")
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: DW_AT_abstract_origin ([[ABSTRACT_FOO]] "_Z3foov")
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: DW_TAG_namespace
|
||||
; CHECK: DW_AT_name ("nn")
|
||||
; CHECK: [[A]]: DW_TAG_variable
|
||||
; CHECK: DW_AT_name ("A")
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
|
||||
define dso_local noundef i32 @main() local_unnamed_addr !dbg !20 {
|
||||
entry:
|
||||
ret i32 42, !dbg !21
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0, !2}
|
||||
!llvm.module.flags = !{!13, !14}
|
||||
!llvm.ident = !{!19, !19}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 15.0.0", isOptimized: true, runtimeVersion: 0, splitDebugFilename: "test.dwo", emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: GNU)
|
||||
!1 = !DIFile(filename: "test.cpp", directory: "/", checksumkind: CSK_MD5, checksum: "e7c2808ee27614e496499d55e4b37962")
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 15.0.0", isOptimized: true, runtimeVersion: 0, splitDebugFilename: "cu1.dwo", emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: GNU)
|
||||
!3 = !DIFile(filename: "cu1.cpp", directory: "/", checksumkind: CSK_MD5, checksum: "c0b84240ef5682b87083b33cf9038171")
|
||||
!4 = !{!5}
|
||||
!5 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !6, entity: !11, file: !3, line: 5)
|
||||
!6 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !3, file: !3, line: 5, type: !7, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4)
|
||||
!7 = !DISubroutineType(types: !8)
|
||||
!8 = !{!9}
|
||||
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!10 = !{}
|
||||
!11 = distinct !DIGlobalVariable(name: "A", linkageName: "_ZN2nn1AE", scope: !12, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
|
||||
!12 = !DINamespace(name: "nn", scope: null)
|
||||
!13 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
!14 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!19 = !{!"clang version 15.0.0"}
|
||||
!20 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 3, type: !7, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
|
||||
!21 = !DILocation(line: 4, column: 3, scope: !6, inlinedAt: !22)
|
||||
!22 = !DILocation(line: 4, column: 3, scope: !20)
|
@ -38,7 +38,7 @@ define void @invalid_subprogram_declaration() !dbg !9 { ret void }
|
||||
define void @invalid_retained_nodes_list() !dbg !10 { ret void }
|
||||
!10 = distinct !DISubprogram(retainedNodes: !0)
|
||||
|
||||
; CHECK: invalid retained nodes, expected DILocalVariable or DILabel
|
||||
; CHECK: invalid retained nodes, expected DILocalVariable, DILabel or DIImportedEntity
|
||||
define void @invalid_retained_nodes_expected() !dbg !11 { ret void }
|
||||
!11 = distinct !DISubprogram(retainedNodes: !{!0})
|
||||
|
||||
|
@ -73,13 +73,13 @@ attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
|
||||
!3 = !DIFile(filename: "em.f90", directory: "tests")
|
||||
!4 = !DISubroutineType(types: !5)
|
||||
!5 = !{null}
|
||||
!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2165", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, imports: !9, splitDebugInlining: false, nameTableKind: None)
|
||||
!6 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "Intel(R) Fortran 21.0-2165", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !7, globals: !8, splitDebugInlining: false, nameTableKind: None)
|
||||
!7 = !{}
|
||||
!8 = !{!0}
|
||||
!9 = !{!10}
|
||||
!9 = !{}
|
||||
!10 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !2, entity: !11, file: !3, line: 2)
|
||||
!11 = !DIModule(scope: !2, name: "external_module", isDecl: true)
|
||||
!12 = !{!13}
|
||||
!12 = !{!10, !13}
|
||||
!13 = !DILocalVariable(name: "x", scope: !2, file: !3, line: 5, type: !14)
|
||||
!14 = !DIBasicType(name: "REAL*4", size: 32, encoding: DW_ATE_float)
|
||||
!15 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
|
@ -81,7 +81,7 @@ declare void @fort_init(...)
|
||||
!1 = distinct !DIGlobalVariable(name: "var1", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
|
||||
!2 = !DIModule(scope: !4, name: "mymod", file: !3, line: 1)
|
||||
!3 = !DIFile(filename: "DIImportedEntity_elements.f90", directory: "/tmp")
|
||||
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang usemodulealias.f90 -g -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !12, nameTableKind: None)
|
||||
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang usemodulealias.f90 -g -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, nameTableKind: None)
|
||||
!5 = !{}
|
||||
!6 = !{!0, !7, !10}
|
||||
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_plus_uconst, 4))
|
||||
@ -91,7 +91,7 @@ declare void @fort_init(...)
|
||||
!11 = distinct !DIGlobalVariable(name: "var3", scope: !2, file: !3, line: 4, type: !9, isLocal: false, isDefinition: true)
|
||||
!12 = !{!13}
|
||||
!13 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !14, entity: !2, file: !3, line: 10, elements: !19)
|
||||
!14 = distinct !DISubprogram(name: "use_renamed", scope: !15, file: !3, line: 10, type: !18, scopeLine: 10, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4)
|
||||
!14 = distinct !DISubprogram(name: "use_renamed", scope: !15, file: !3, line: 10, type: !18, scopeLine: 10, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4, retainedNodes: !12)
|
||||
!15 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 7, type: !16, scopeLine: 7, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4)
|
||||
!16 = !DISubroutineType(cc: DW_CC_program, types: !17)
|
||||
!17 = !{null}
|
||||
|
@ -97,7 +97,7 @@ attributes #1 = { "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp
|
||||
!llvm.module.flags = !{!22, !23}
|
||||
!llvm.ident = !{!24}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: false, splitDebugFilename: "fission-inline.dwo", emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !3, globals: !2, imports: !18)
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: false, splitDebugFilename: "fission-inline.dwo", emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !3, globals: !2)
|
||||
!1 = !DIFile(filename: "fission-inline.cpp", directory: "/tmp/dbginfo")
|
||||
!2 = !{}
|
||||
!3 = !{!4}
|
||||
@ -106,7 +106,7 @@ attributes #1 = { "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp
|
||||
!6 = !DISubprogram(name: "f3", linkageName: "_ZN3foo2f3Ez", line: 4, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 4, file: !1, scope: !4, type: !7)
|
||||
!7 = !DISubroutineType(types: !8)
|
||||
!8 = !{null, null}
|
||||
!10 = distinct !DISubprogram(name: "f3", linkageName: "_ZN3foo2f3Ez", line: 15, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 15, file: !1, scope: !4, type: !7, declaration: !6, retainedNodes: !2)
|
||||
!10 = distinct !DISubprogram(name: "f3", linkageName: "_ZN3foo2f3Ez", line: 15, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 15, file: !1, scope: !4, type: !7, declaration: !6, retainedNodes: !18)
|
||||
!11 = distinct !DISubprogram(name: "f2<int>", linkageName: "_ZN3foo2f2IiEEvv", line: 10, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 10, file: !1, scope: !4, type: !12, templateParams: !14, declaration: !17, retainedNodes: !2)
|
||||
!12 = !DISubroutineType(types: !13)
|
||||
!13 = !{null}
|
||||
|
@ -16,12 +16,12 @@ entry:
|
||||
!llvm.module.flags = !{!9, !10, !11}
|
||||
!llvm.ident = !{!12}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 (trunk 349508) (llvm/trunk 349520)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, imports: !3, nameTableKind: None)
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 (trunk 349508) (llvm/trunk 349520)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
|
||||
!1 = !DIFile(filename: "test.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch")
|
||||
!2 = !{}
|
||||
!3 = !{!4}
|
||||
!4 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !8, file: !1, line: 2)
|
||||
!5 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 2, type: !6, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
|
||||
!5 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 2, type: !6, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !3)
|
||||
!6 = !DISubroutineType(types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DINamespace(name: "ns1", scope: null)
|
||||
|
@ -53,7 +53,7 @@ attributes #1 = { "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp
|
||||
!llvm.module.flags = !{!22, !23}
|
||||
!llvm.ident = !{!24}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: false, splitDebugFilename: "fission-inline.dwo", emissionKind: FullDebug, splitDebugInlining: false, file: !1, enums: !2, retainedTypes: !3, globals: !2, imports: !18)
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 ", isOptimized: false, splitDebugFilename: "fission-inline.dwo", emissionKind: FullDebug, splitDebugInlining: false, file: !1, enums: !2, retainedTypes: !3, globals: !2)
|
||||
!1 = !DIFile(filename: "fission-inline.cpp", directory: "")
|
||||
!2 = !{}
|
||||
!3 = !{!4}
|
||||
@ -62,7 +62,7 @@ attributes #1 = { "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp
|
||||
!6 = !DISubprogram(name: "f3", linkageName: "_ZN3foo2f3Ez", line: 4, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 4, file: !1, scope: !4, type: !7)
|
||||
!7 = !DISubroutineType(types: !8)
|
||||
!8 = !{null, null}
|
||||
!10 = distinct !DISubprogram(name: "f3", linkageName: "_ZN3foo2f3Ez", line: 15, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 15, file: !1, scope: !4, type: !7, declaration: !6, retainedNodes: !2)
|
||||
!10 = distinct !DISubprogram(name: "f3", linkageName: "_ZN3foo2f3Ez", line: 15, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 15, file: !1, scope: !4, type: !7, declaration: !6, retainedNodes: !18)
|
||||
!11 = distinct !DISubprogram(name: "f2<int>", linkageName: "_ZN3foo2f2IiEEvv", line: 10, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 10, file: !1, scope: !4, type: !12, templateParams: !14, declaration: !17, retainedNodes: !2)
|
||||
!12 = !DISubroutineType(types: !13)
|
||||
!13 = !{null}
|
||||
|
@ -119,10 +119,10 @@ attributes #2 = { nounwind }
|
||||
!llvm.module.flags = !{!15, !16}
|
||||
!llvm.ident = !{!17}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 (trunk 264349)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, imports: !10)
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 (trunk 264349)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2)
|
||||
!1 = !DIFile(filename: "test.cpp", directory: "/")
|
||||
!2 = !{}
|
||||
!4 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
|
||||
!4 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !10)
|
||||
!5 = !DISubroutineType(types: !6)
|
||||
!6 = !{!7}
|
||||
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
|
@ -41,7 +41,7 @@ source_filename = "namelist2.ll"
|
||||
!1 = distinct !DIGlobalVariable(name: "aa", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
|
||||
!2 = !DIModule(scope: !4, name: "mm", file: !3, line: 1)
|
||||
!3 = !DIFile(filename: "namelist2.f90", directory: "/dir")
|
||||
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang -g namelist2.f90 -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !14, nameTableKind: None)
|
||||
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang -g namelist2.f90 -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, nameTableKind: None)
|
||||
!5 = !{}
|
||||
!6 = !{!0, !7, !10}
|
||||
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_plus_uconst, 4))
|
||||
@ -53,7 +53,7 @@ source_filename = "namelist2.ll"
|
||||
!13 = !{!1, !8}
|
||||
!14 = !{!15}
|
||||
!15 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !16, entity: !2, file: !3, line: 6)
|
||||
!16 = distinct !DISubprogram(name: "test", scope: !4, file: !3, line: 6, type: !17, scopeLine: 6, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition, unit: !4)
|
||||
!16 = distinct !DISubprogram(name: "test", scope: !4, file: !3, line: 6, type: !17, scopeLine: 6, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition, unit: !4, retainedNodes: !14)
|
||||
!17 = !DISubroutineType(types: !18)
|
||||
!18 = !{null}
|
||||
!19 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
|
@ -6,15 +6,15 @@
|
||||
!llvm.dbg.cu = !{!0, !5}
|
||||
!llvm.module.flags = !{!3, !4}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM", isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM", isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2)
|
||||
!1 = !DIFile(filename: "<stdin>", directory: "/")
|
||||
!2 = !{}
|
||||
!3 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!4 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!5 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, imports: !6)
|
||||
!5 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
!6 = !{!7}
|
||||
!7 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !8, entity: !8, file: !1, line: 3)
|
||||
!8 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !5, retainedNodes: !2)
|
||||
!8 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !5, retainedNodes: !6)
|
||||
!9 = !DISubroutineType(types: !10)
|
||||
!10 = !{null}
|
||||
!11 = !DINamespace(name: "ns", scope: null)
|
||||
|
@ -2,12 +2,11 @@
|
||||
; RUN: llvm-as %p/Inputs/pr26037.ll -o %t2.bc
|
||||
; RUN: llvm-link -S -only-needed %t2.bc %t.bc | FileCheck %s
|
||||
|
||||
; CHECK: !DIImportedEntity({{.*}}, scope: ![[B:[0-9]+]], entity: ![[A:[0-9]+]]
|
||||
; CHECK: ![[B]] = distinct !DISubprogram(name: "b"
|
||||
; CHECK: ![[CU_MAIN:[0-9]+]] = distinct !DICompileUnit(
|
||||
; CHECK: ![[CU:[0-9]+]] = distinct !DICompileUnit(
|
||||
; CHECK: !DIImportedEntity({{.*}}, scope: ![[CU]], entity: ![[A:[0-9]+]]
|
||||
; CHECK: ![[A]] = distinct !DISubprogram(name: "a"
|
||||
; CHECK: !DIImportedEntity({{.*}}, scope: ![[LBC:[0-9]+]], entity: ![[LBD:[0-9]+]]
|
||||
; CHECK: ![[LBC]] = distinct !DILexicalBlock(scope: ![[C:[0-9]+]]
|
||||
; CHECK: ![[C]] = distinct !DISubprogram(name: "c"
|
||||
; CHECK: !DIImportedEntity({{.*}}, scope: ![[CU]], entity: ![[LBD:[0-9]+]]
|
||||
; CHECK: ![[LBD]] = distinct !DILexicalBlock(scope: ![[D:[0-9]+]]
|
||||
; CHECK: ![[D]] = distinct !DISubprogram(name: "d"
|
||||
|
||||
@ -16,16 +15,6 @@ entry:
|
||||
ret void, !dbg !14
|
||||
}
|
||||
|
||||
define void @_ZN1A1bEv() #0 !dbg !8 {
|
||||
entry:
|
||||
ret void, !dbg !15
|
||||
}
|
||||
|
||||
define void @_ZN1A1cEv() #0 !dbg !18 {
|
||||
entry:
|
||||
ret void, !dbg !21
|
||||
}
|
||||
|
||||
define void @_ZN1A1dEv() #0 !dbg !20 {
|
||||
entry:
|
||||
ret void, !dbg !22
|
||||
@ -42,18 +31,13 @@ entry:
|
||||
!5 = !DINamespace(name: "A", scope: null)
|
||||
!6 = !DISubroutineType(types: !7)
|
||||
!7 = !{null}
|
||||
!8 = distinct !DISubprogram(name: "b", linkageName: "_ZN1A1bEv", scope: !5, file: !1, line: 8, type: !6, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
|
||||
!9 = !{!10, !16}
|
||||
!10 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !8, entity: !4, file: !1, line: 8)
|
||||
!10 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !4, file: !1, line: 8)
|
||||
!11 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!12 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!13 = !{!"clang version 3.8.0 (trunk 256934) (llvm/trunk 256936)"}
|
||||
!14 = !DILocation(line: 7, column: 12, scope: !4)
|
||||
!15 = !DILocation(line: 8, column: 24, scope: !8)
|
||||
!16 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !17, entity: !19, file: !1, line: 8)
|
||||
!17 = distinct !DILexicalBlock(scope: !18, file: !1, line: 9, column: 8)
|
||||
!18 = distinct !DISubprogram(name: "c", linkageName: "_ZN1A1cEv", scope: !5, file: !1, line: 9, type: !6, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
|
||||
!16 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !0, entity: !19, file: !1, line: 8)
|
||||
!19 = distinct !DILexicalBlock(scope: !20, file: !1, line: 10, column: 8)
|
||||
!20 = distinct !DISubprogram(name: "d", linkageName: "_ZN1A1dEv", scope: !5, file: !1, line: 10, type: !6, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
|
||||
!21 = !DILocation(line: 9, column: 8, scope: !18)
|
||||
!22 = !DILocation(line: 10, column: 8, scope: !20)
|
||||
|
@ -5,15 +5,13 @@
|
||||
; RUN: opt -module-summary %p/Inputs/debuginfo-cu-import.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
|
||||
|
||||
; Don't import enums, macros, retainedTypes or globals lists.
|
||||
; Only import local scope imported entities.
|
||||
; Don't import enums, macros, retainedTypes, globals or imports lists.
|
||||
; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t.index.bc -o - | llvm-dis -o - | FileCheck %s
|
||||
; CHECK-NOT: DICompileUnit{{.*}} enums:
|
||||
; CHECK-NOT: DICompileUnit{{.*}} macros:
|
||||
; CHECK-NOT: DICompileUnit{{.*}} retainedTypes:
|
||||
; CHECK-NOT: DICompileUnit{{.*}} globals:
|
||||
; CHECK: DICompileUnit{{.*}} imports: ![[IMP:[0-9]+]]
|
||||
; CHECK: ![[IMP]] = !{!{{[0-9]+}}}
|
||||
; CHECK-NOT: DICompileUnit{{.*}} imports:
|
||||
|
||||
; ModuleID = 'debuginfo-cu-import.c'
|
||||
source_filename = "debuginfo-cu-import.c"
|
||||
@ -50,14 +48,14 @@ entry:
|
||||
!8 = !{!9}
|
||||
!9 = !DIGlobalVariableExpression(var: !10, expr: !DIExpression())
|
||||
!10 = !DIGlobalVariable(name: "version", scope: !4, file: !1, line: 2, type: !7, isLocal: false, isDefinition: true)
|
||||
!11 = !{!12, !16}
|
||||
!11 = !{!12}
|
||||
!12 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !13, file: !1, line: 8)
|
||||
!13 = distinct !DISubprogram(name: "a", linkageName: "_ZN1A1aEv", scope: !4, file: !1, line: 7, type: !14, isLocal: false, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !5)
|
||||
!14 = !DISubroutineType(types: !15)
|
||||
!15 = !{null}
|
||||
!16 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !17, entity: !19, file: !1, line: 8)
|
||||
!17 = distinct !DILexicalBlock(scope: !18, file: !1, line: 9, column: 8)
|
||||
!18 = distinct !DISubprogram(name: "c", linkageName: "_ZN1A1cEv", scope: !4, file: !1, line: 9, type: !14, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !5)
|
||||
!18 = distinct !DISubprogram(name: "c", linkageName: "_ZN1A1cEv", scope: !4, file: !1, line: 9, type: !14, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !33)
|
||||
!19 = distinct !DILexicalBlock(scope: !20, file: !1, line: 10, column: 8)
|
||||
!20 = distinct !DISubprogram(name: "d", linkageName: "_ZN1A1dEv", scope: !4, file: !1, line: 10, type: !14, isLocal: false, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !5)
|
||||
!21 = !{!22}
|
||||
@ -72,4 +70,4 @@ entry:
|
||||
!30 = !DILocation(line: 7, column: 12, scope: !13)
|
||||
!31 = distinct !DISubprogram(name: "b", linkageName: "_ZN1A1bEv", scope: !4, file: !1, line: 8, type: !14, isLocal: true, isDefinition: true, scopeLine: 8, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !5)
|
||||
!32 = !DILocation(line: 8, column: 24, scope: !31)
|
||||
|
||||
!33 = !{!16}
|
||||
|
Loading…
x
Reference in New Issue
Block a user