index 7797ff4273a69c2a31f083591e53449e2c62de9f..4bf0b1878473dacd2dca69599ec31031a76e4070 100644 (file)
static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) {
DIDerivedType DTy(Ty);
if (DTy.isDerivedType()) {
- if (DIType Deriv = DD->resolve(DTy.getTypeDerivedFrom()))
- return isUnsignedDIType(DD, Deriv);
+ dwarf::Tag T = (dwarf::Tag)Ty.getTag();
+ // Encode pointer constants as unsigned bytes. This is used at least for
+ // null pointer constant emission.
+ // FIXME: reference and rvalue_reference /probably/ shouldn't be allowed
+ // here, but accept them for now due to a bug in SROA producing bogus
+ // dbg.values.
+ if (T == dwarf::DW_TAG_pointer_type ||
+ T == dwarf::DW_TAG_ptr_to_member_type ||
+ T == dwarf::DW_TAG_reference_type ||
+ T == dwarf::DW_TAG_rvalue_reference_type)
+ return true;
+ assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
+ T == dwarf::DW_TAG_volatile_type ||
+ T == dwarf::DW_TAG_restrict_type ||
+ T == dwarf::DW_TAG_enumeration_type);
+ if (DITypeRef Deriv = DTy.getTypeDerivedFrom())
+ return isUnsignedDIType(DD, DD->resolve(Deriv));
// FIXME: Enums without a fixed underlying type have unknown signedness
// here, leading to incorrectly emitted constants.
assert(DTy.getTag() == dwarf::DW_TAG_enumeration_type);
DIBasicType BTy(Ty);
assert(BTy.isBasicType());
unsigned Encoding = BTy.getEncoding();
- assert(Encoding == dwarf::DW_ATE_unsigned ||
- Encoding == dwarf::DW_ATE_unsigned_char ||
- Encoding == dwarf::DW_ATE_signed ||
- Encoding == dwarf::DW_ATE_signed_char ||
- Encoding == dwarf::DW_ATE_boolean && "Unsupported encoding");
+ assert((Encoding == dwarf::DW_ATE_unsigned ||
+ Encoding == dwarf::DW_ATE_unsigned_char ||
+ Encoding == dwarf::DW_ATE_signed ||
+ Encoding == dwarf::DW_ATE_signed_char ||
+ Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean) &&
+ "Unsupported encoding");
return (Encoding == dwarf::DW_ATE_unsigned ||
Encoding == dwarf::DW_ATE_unsigned_char ||
- Encoding == dwarf::DW_ATE_boolean);
+ Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean);
}
/// If this type is derived from a base type then return base type size.
// 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 preceeds the definition.
+ getOrCreateSubprogramDIE(SPDecl);
+ }
// DW_TAG_inlined_subroutine may refer to this DIE.
DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
+ // Abort 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::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);
+ 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());
if (SP.isExplicit())
addFlag(SPDie, dwarf::DW_AT_explicit);
-
- return &SPDie;
}
// Return const expression if value is a GEP to access merged global
/// 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) {
+std::unique_ptr<DIE> DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV,
+ bool Abstract) {
StringRef Name = DV.getName();
// 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);
+ if (DbgVariable *AbsVar = DV.getAbstractVariable())
+ addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin, *AbsVar->getDIE());
else {
if (!Name.empty())
addString(*VariableDie, dwarf::DW_AT_name, Name);
addSourceLine(*VariableDie, DV.getVariable());
addType(*VariableDie, DV.getType());
+ if (DV.isArtificial())
+ addFlag(*VariableDie, dwarf::DW_AT_artificial);
}
- if (AbsIn != AOI_Inlined && DV.isArtificial())
- addFlag(*VariableDie, dwarf::DW_AT_artificial);
-
- if (AbsIn == AOI_Abstract)
+ if (Abstract)
return VariableDie;
// Add variable address.