// Find the __forwarding field and the variable field in the __Block_byref
// struct.
- DIArray Fields = blockStruct.getTypeArray();
+ DIArray Fields = blockStruct.getElements();
DIDerivedType varField;
DIDerivedType forwardingField;
I != E; ++I) {
DIScope Ctx = *I;
StringRef Name = Ctx.getName();
+ if (Name.empty() && Ctx.isNameSpace())
+ Name = "(anonymous namespace)";
if (!Name.empty()) {
CS += Name;
CS += "::";
}
/// constructSubprogramArguments - Construct function argument DIEs.
-void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DIArray Args) {
+void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeArray Args) {
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
- DIDescriptor Ty = Args.getElement(i);
+ DIType Ty = resolve(Args.getElement(i));
if (Ty.isUnspecifiedParameter()) {
assert(i == N-1 && "Unspecified parameter must be the last argument");
createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);
break;
case dwarf::DW_TAG_subroutine_type: {
// Add return type. A void return won't have a type.
- DIArray Elements = CTy.getTypeArray();
- DIType RTy(Elements.getElement(0));
+ DITypeArray Elements = DISubroutineType(CTy).getTypeArray();
+ DIType RTy(resolve(Elements.getElement(0)));
if (RTy)
addType(Buffer, RTy);
bool isPrototyped = true;
if (Elements.getNumElements() == 2 &&
- Elements.getElement(1).isUnspecifiedParameter())
+ resolve(Elements.getElement(1)).isUnspecifiedParameter())
isPrototyped = false;
constructSubprogramArguments(Buffer, Elements);
case dwarf::DW_TAG_union_type:
case dwarf::DW_TAG_class_type: {
// Add elements to structure type.
- DIArray Elements = CTy.getTypeArray();
+ DIArray Elements = CTy.getElements();
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
DIDescriptor Element = Elements.getElement(i);
if (Element.isSubprogram())
return NDie;
DIE &NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS);
- if (!NS.getName().empty()) {
+ StringRef Name = NS.getName();
+ if (!Name.empty())
addString(NDie, dwarf::DW_AT_name, NS.getName());
- DD->addAccelNamespace(NS.getName(), NDie);
- addGlobalName(NS.getName(), NDie, NS.getContext());
- } else
- DD->addAccelNamespace("(anonymous namespace)", NDie);
+ else
+ Name = "(anonymous namespace)";
+ DD->addAccelNamespace(Name, NDie);
+ addGlobalName(Name, NDie, NS.getContext());
addSourceLine(NDie, NS);
return &NDie;
}
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE (as is the case for member function
// declarations).
- DIScope Context = resolve(SP.getContext());
- DIE *ContextDIE = getOrCreateContextDIE(Context);
-
- // Unique declarations based on the ODR, where applicable.
- SP = DISubprogram(DD->resolve(SP.getRef()));
- assert(SP.Verify());
+ DIE *ContextDIE = getOrCreateContextDIE(resolve(SP.getContext()));
if (DIE *SPDie = getDIE(SP))
return SPDie;
- DISubprogram SPDecl = SP.getFunctionDeclaration();
- if (SPDecl.isSubprogram())
+ if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
// Add subprogram definitions to the CU die directly.
ContextDIE = &getUnitDie();
+ // Build the decl now to ensure it precedes the definition.
+ getOrCreateSubprogramDIE(SPDecl);
+ }
// DW_TAG_inlined_subroutine may refer to this DIE.
DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
+ // Stop here and fill this in later, depending on whether or not this
+ // subprogram turns out to have inlined instances or not.
+ if (SP.isDefinition())
+ return &SPDie;
+
+ applySubprogramAttributes(SP, SPDie);
+ return &SPDie;
+}
+
+void DwarfUnit::applySubprogramAttributesToDefinition(DISubprogram SP, DIE &SPDie) {
+ DISubprogram SPDecl = SP.getFunctionDeclaration();
+ DIScope Context = resolve(SPDecl ? SPDecl.getContext() : SP.getContext());
+ applySubprogramAttributes(SP, SPDie);
+ addGlobalName(SP.getName(), SPDie, Context);
+}
+
+void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie) {
DIE *DeclDie = nullptr;
- if (SPDecl.isSubprogram())
- DeclDie = getOrCreateSubprogramDIE(SPDecl);
+ StringRef DeclLinkageName;
+ if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
+ DeclDie = getDIE(SPDecl);
+ assert(DeclDie && "This DIE should've already been constructed when the "
+ "definition DIE was created in "
+ "getOrCreateSubprogramDIE");
+ DeclLinkageName = SPDecl.getLinkageName();
+ }
// Add function template parameters.
addTemplateParams(SPDie, SP.getTemplateParams());
- if (DeclDie)
- // Refer function declaration directly.
- addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
-
// Add the linkage name if we have one and it isn't in the Decl.
StringRef LinkageName = SP.getLinkageName();
- if (!LinkageName.empty()) {
- if (SPDecl.isSubprogram() && !SPDecl.getLinkageName().empty())
- assert(SPDecl.getLinkageName() == SP.getLinkageName() &&
- "decl has a linkage name and it is different");
- else
- addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
- GlobalValue::getRealLinkageName(LinkageName));
+ assert(((LinkageName.empty() || DeclLinkageName.empty()) ||
+ LinkageName == DeclLinkageName) &&
+ "decl has a linkage name and it is different");
+ if (!LinkageName.empty() && DeclLinkageName.empty())
+ addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
+ GlobalValue::getRealLinkageName(LinkageName));
+
+ if (DeclDie) {
+ // Refer to the function declaration where all the other attributes will be
+ // found.
+ addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
+ return;
}
- // If this DIE is going to refer declaration info using AT_specification
- // then there is no need to add other attributes.
- if (DeclDie)
- return &SPDie;
-
// Constructors and operators for anonymous aggregates do not have names.
if (!SP.getName().empty())
addString(SPDie, dwarf::DW_AT_name, SP.getName());
Language == dwarf::DW_LANG_ObjC))
addFlag(SPDie, dwarf::DW_AT_prototyped);
- DICompositeType SPTy = SP.getType();
+ DISubroutineType SPTy = SP.getType();
assert(SPTy.getTag() == dwarf::DW_TAG_subroutine_type &&
"the type of a subprogram should be a subroutine");
- DIArray Args = SPTy.getTypeArray();
+ DITypeArray Args = SPTy.getTypeArray();
// Add a return type. If this is a type like a C/C++ void type we don't add a
// return type.
- if (Args.getElement(0))
- addType(SPDie, DIType(Args.getElement(0)));
+ if (resolve(Args.getElement(0)))
+ addType(SPDie, DIType(resolve(Args.getElement(0))));
unsigned VK = SP.getVirtuality();
if (VK) {
if (SP.isExplicit())
addFlag(SPDie, dwarf::DW_AT_explicit);
+}
- return &SPDie;
+void DwarfUnit::applyVariableAttributes(const DbgVariable &Var,
+ DIE &VariableDie) {
+ StringRef Name = Var.getName();
+ if (!Name.empty())
+ addString(VariableDie, dwarf::DW_AT_name, Name);
+ addSourceLine(VariableDie, Var.getVariable());
+ addType(VariableDie, Var.getType());
+ if (Var.isArtificial())
+ addFlag(VariableDie, dwarf::DW_AT_artificial);
}
// Return const expression if value is a GEP to access merged global
DD->addAccelName(GV.getLinkageName(), AddrDIE);
}
- if (!GV.isLocalToUnit())
- addGlobalName(GV.getName(),
- VariableSpecDIE ? *VariableSpecDIE : *VariableDIE,
- GV.getContext());
+ addGlobalName(GV.getName(), VariableSpecDIE ? *VariableSpecDIE : *VariableDIE,
+ GV.getContext());
}
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
}
// Add subranges to array type.
- DIArray Elements = CTy.getTypeArray();
+ DIArray Elements = CTy.getElements();
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
DIDescriptor Element = Elements.getElement(i);
if (Element.getTag() == dwarf::DW_TAG_subrange_type)
/// constructEnumTypeDIE - Construct an enum type DIE from DICompositeType.
void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy) {
- DIArray Elements = CTy.getTypeArray();
+ DIArray Elements = CTy.getElements();
// Add enumerators to enumeration type.
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
std::unique_ptr<DIE> DwarfUnit::constructVariableDIE(DbgVariable &DV,
- AbstractOrInlined AbsIn) {
- auto D = constructVariableDIEImpl(DV, AbsIn);
+ bool Abstract) {
+ auto D = constructVariableDIEImpl(DV, Abstract);
DV.setDIE(*D);
return D;
}
-std::unique_ptr<DIE>
-DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV,
- AbstractOrInlined AbsIn) {
- StringRef Name = DV.getName();
-
+std::unique_ptr<DIE> DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV,
+ bool Abstract) {
// Define variable debug information entry.
auto VariableDie = make_unique<DIE>(DV.getTag());
- DbgVariable *AbsVar = DV.getAbstractVariable();
- DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : nullptr;
- if (AbsDIE)
- addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin, *AbsDIE);
- else {
- if (!Name.empty())
- addString(*VariableDie, dwarf::DW_AT_name, Name);
- addSourceLine(*VariableDie, DV.getVariable());
- addType(*VariableDie, DV.getType());
- }
- if (AbsIn != AOI_Inlined && DV.isArtificial())
- addFlag(*VariableDie, dwarf::DW_AT_artificial);
-
- if (AbsIn == AOI_Abstract)
+ if (Abstract) {
+ applyVariableAttributes(DV, *VariableDie);
return VariableDie;
+ }
// Add variable address.