X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfCompileUnit.cpp;h=bd63279f2fc9779c77944777d45f6e7a4ef0b2c3;hp=617df1b762f7a2c93e7d3ffca90ab22065909abe;hb=54a86b37ddf5425deb7fadde898437df9c6c770b;hpb=43ed8aefd3b11630f66d262db2fcb2cfbf2e09bf diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 617df1b762f..bd63279f2fc 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -105,28 +105,23 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) { DIScope GVContext = GV.getContext(); DIType GTy = DD->resolve(GV.getType()); - // If this is a static data member definition, some attributes belong - // to the declaration DIE. - DIE *VariableDIE = nullptr; - bool IsStaticMember = false; - DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration(); - if (SDMDecl.Verify()) { - assert(SDMDecl.isStaticMember() && "Expected static member decl"); - // We need the declaration DIE that is in the static member's class. - VariableDIE = getOrCreateStaticMemberDIE(SDMDecl); - IsStaticMember = true; - } + // Construct the context before querying for the existence of the DIE in + // case such construction creates the DIE. + DIE *ContextDIE = getOrCreateContextDIE(GVContext); - // If this is not a static data member definition, create the variable - // DIE and add the initial set of attributes to it. - if (!VariableDIE) { - // Construct the context before querying for the existence of the DIE in - // case such construction creates the DIE. - DIE *ContextDIE = getOrCreateContextDIE(GVContext); - - // Add to map. - VariableDIE = &createAndAddDIE(GV.getTag(), *ContextDIE, GV); + // Add to map. + DIE *VariableDIE = &createAndAddDIE(GV.getTag(), *ContextDIE, GV); + DIScope DeclContext; + if (DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration()) { + DeclContext = resolve(SDMDecl.getContext()); + assert(SDMDecl.isStaticMember() && "Expected static member decl"); + assert(GV.isDefinition()); + // We need the declaration DIE that is in the static member's class. + DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl); + addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE); + } else { + DeclContext = GV.getContext(); // Add name and type. addString(*VariableDIE, dwarf::DW_AT_name, GV.getDisplayName()); addType(*VariableDIE, GTy); @@ -139,9 +134,11 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) { addSourceLine(*VariableDIE, GV); } + if (!GV.isDefinition()) + addFlag(*VariableDIE, dwarf::DW_AT_declaration); + // Add location. bool addToAccelTable = false; - DIE *VariableSpecDIE = nullptr; bool isGlobalVariable = GV.getGlobal() != nullptr; if (isGlobalVariable) { addToAccelTable = true; @@ -172,41 +169,21 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) { DD->addArangeLabel(SymbolCU(this, Sym)); addOpAddress(*Loc, Sym); } - // A static member's declaration is already flagged as such. - if (!SDMDecl.Verify() && !GV.isDefinition()) - addFlag(*VariableDIE, dwarf::DW_AT_declaration); - // Do not create specification DIE if context is either compile unit - // or a subprogram. - if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() && - !GVContext.isFile() && !DD->isSubprogramContext(GVContext)) { - // Create specification DIE. - VariableSpecDIE = &createAndAddDIE(dwarf::DW_TAG_variable, UnitDie); - addDIEEntry(*VariableSpecDIE, dwarf::DW_AT_specification, *VariableDIE); - addBlock(*VariableSpecDIE, dwarf::DW_AT_location, Loc); - // A static member's declaration is already flagged as such. - if (!SDMDecl.Verify()) - addFlag(*VariableDIE, dwarf::DW_AT_declaration); - } else { - addBlock(*VariableDIE, dwarf::DW_AT_location, Loc); - } + + addBlock(*VariableDIE, dwarf::DW_AT_location, Loc); // Add the linkage name. StringRef LinkageName = GV.getLinkageName(); if (!LinkageName.empty()) // From DWARF4: DIEs to which DW_AT_linkage_name may apply include: // TAG_common_block, TAG_constant, TAG_entry_point, TAG_subprogram and // TAG_variable. - addString(IsStaticMember && VariableSpecDIE ? *VariableSpecDIE - : *VariableDIE, + addString(*VariableDIE, DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name : dwarf::DW_AT_MIPS_linkage_name, GlobalValue::getRealLinkageName(LinkageName)); } else if (const ConstantInt *CI = dyn_cast_or_null(GV.getConstant())) { - // AT_const_value was added when the static member was created. To avoid - // emitting AT_const_value multiple times, we only add AT_const_value when - // it is not a static member. - if (!IsStaticMember) - addConstantValue(*VariableDIE, CI, GTy); + addConstantValue(*VariableDIE, CI, GTy); } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV.getConstant())) { addToAccelTable = true; // GV is a merged global. @@ -223,19 +200,17 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) { addBlock(*VariableDIE, dwarf::DW_AT_location, Loc); } - DIE *ResultDIE = VariableSpecDIE ? VariableSpecDIE : VariableDIE; - if (addToAccelTable) { - DD->addAccelName(GV.getName(), *ResultDIE); + DD->addAccelName(GV.getName(), *VariableDIE); // If the linkage name is different than the name, go ahead and output // that as well into the name table. if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName()) - DD->addAccelName(GV.getLinkageName(), *ResultDIE); + DD->addAccelName(GV.getLinkageName(), *VariableDIE); } - addGlobalName(GV.getName(), *ResultDIE, GV.getContext()); - return ResultDIE; + addGlobalName(GV.getName(), *VariableDIE, DeclContext); + return VariableDIE; } void DwarfCompileUnit::addRange(RangeSpan Range) { @@ -555,7 +530,7 @@ DIE *DwarfCompileUnit::createScopeChildrenDIE( unsigned *ChildScopeCount) { DIE *ObjectPointer = nullptr; - for (DbgVariable *DV : DD->getScopeVariables().lookup(Scope)) + for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope)) Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer)); unsigned ChildCountWithoutScopes = Children.size(); @@ -581,31 +556,21 @@ void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) { DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); - // Collect arguments for current function. - DIE *ObjectPointer = nullptr; - for (DbgVariable *ArgDV : DD->getCurrentFnArguments()) - if (ArgDV) - ScopeDIE.addChild(constructVariableDIE(*ArgDV, *Scope, ObjectPointer)); - // If this is a variadic function, add an unspecified parameter. DITypeArray FnArgs = Sub.getType().getTypeArray(); + + // Collect lexical scope children first. + // ObjectPointer might be a local (non-argument) local variable if it's a + // block's synthetic this pointer. + if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, ScopeDIE)) + addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); + // If we have a single element of null, it is a function that returns void. // If we have more than one elements and the last one is null, it is a // variadic function. if (FnArgs.getNumElements() > 1 && !FnArgs.getElement(FnArgs.getNumElements() - 1)) ScopeDIE.addChild(make_unique(dwarf::DW_TAG_unspecified_parameters)); - - // Collect lexical scope children first. - // ObjectPointer might be a local (non-argument) local variable if it's a - // block's synthetic this pointer. - if (DIE *BlockObjPtr = createAndAddScopeChildren(Scope, ScopeDIE)) { - assert(!ObjectPointer && "multiple object pointers can't be described"); - ObjectPointer = BlockObjPtr; - } - - if (ObjectPointer) - addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer); } DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, @@ -621,8 +586,12 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope, return ObjectPointer; } -DIE & +void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { + DIE *&AbsDef = DD->getAbstractSPDies()[Scope->getScopeNode()]; + if (AbsDef) + return; + DISubprogram SP(Scope->getScopeNode()); DIE *ContextDIE; @@ -639,15 +608,81 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { // Passing null as the associated DIDescriptor because the abstract definition // shouldn't be found by lookup. - DIE &AbsDef = - createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, DIDescriptor()); - applySubprogramAttributesToDefinition(SP, AbsDef); + AbsDef = + &createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, DIDescriptor()); + applySubprogramAttributesToDefinition(SP, *AbsDef); if (getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly) - addUInt(AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); - if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, AbsDef)) - addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); - return AbsDef; + addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); + if (DIE *ObjectPointer = createAndAddScopeChildren(Scope, *AbsDef)) + addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer); +} + +std::unique_ptr +DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity &Module) { + assert(Module.Verify() && + "Use one of the MDNode * overloads to handle invalid metadata"); + std::unique_ptr IMDie = make_unique((dwarf::Tag)Module.getTag()); + insertDIE(Module, IMDie.get()); + DIE *EntityDie; + DIDescriptor Entity = resolve(Module.getEntity()); + if (Entity.isNameSpace()) + EntityDie = getOrCreateNameSpace(DINameSpace(Entity)); + else if (Entity.isSubprogram()) + EntityDie = getOrCreateSubprogramDIE(DISubprogram(Entity)); + else if (Entity.isType()) + EntityDie = getOrCreateTypeDIE(DIType(Entity)); + else + EntityDie = getDIE(Entity); + assert(EntityDie); + addSourceLine(*IMDie, Module.getLineNumber(), + Module.getContext().getFilename(), + Module.getContext().getDirectory()); + addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie); + StringRef Name = Module.getName(); + if (!Name.empty()) + addString(*IMDie, dwarf::DW_AT_name, Name); + + return IMDie; +} + +void DwarfCompileUnit::finishSubprogramDefinition(DISubprogram SP) { + DIE *D = getDIE(SP); + if (DIE *AbsSPDIE = DD->getAbstractSPDies().lookup(SP)) { + if (D) + // If this subprogram has an abstract definition, reference that + addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE); + } else { + if (!D && getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly) + // Lazily construct the subprogram if we didn't see either concrete or + // inlined versions during codegen. (except in -gmlt ^ where we want + // to omit these entirely) + D = getOrCreateSubprogramDIE(SP); + if (D) + // And attach the attributes + applySubprogramAttributesToDefinition(SP, *D); + } +} +void DwarfCompileUnit::collectDeadVariables(DISubprogram SP) { + assert(SP.isSubprogram() && "CU's subprogram list contains a non-subprogram"); + assert(SP.isDefinition() && + "CU's subprogram list contains a subprogram declaration"); + DIArray Variables = SP.getVariables(); + if (Variables.getNumElements() == 0) + return; + + DIE *SPDIE = DD->getAbstractSPDies().lookup(SP); + if (!SPDIE) + SPDIE = getDIE(SP); + assert(SPDIE); + for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { + DIVariable DV(Variables.getElement(vi)); + assert(DV.isVariable()); + DbgVariable NewVar(DV, DIExpression(nullptr), DD); + auto VariableDie = constructVariableDIE(NewVar); + applyVariableAttributes(NewVar, *VariableDie); + SPDIE->addChild(std::move(VariableDie)); + } } } // end llvm namespace