DebugInfo: Gut DIType and subclasses

Continuing PR23080, gut `DIType` and its various subclasses, leaving
behind thin wrappers around the pointer types in the new debug info
hierarchy.

llvm-svn: 235064
This commit is contained in:
Duncan P. N. Exon Smith 2015-04-16 01:01:28 +00:00
parent 4caa7f2a9c
commit b105564015
10 changed files with 182 additions and 241 deletions

View File

@ -237,126 +237,74 @@ template <> DIType DIRef<DIType>::resolve(const DITypeIdentifierMap &Map) const;
DIScopeRef DIScope::getContext() const { return get()->getScope(); }
/// \brief This is a wrapper for a type.
///
/// FIXME: Types should be factored much better so that CV qualifiers and
/// others do not require a huge and empty descriptor full of zeros.
class DIType : public DIScope {
class DIType {
MDType *N;
public:
DIType() = default;
DIType(const MDType *N) : DIScope(N) {}
DIType(const MDType *N = nullptr) : N(const_cast<MDType *>(N)) {}
MDType *get() const { return cast_or_null<MDType>(DIDescriptor::get()); }
operator MDType *() const { return get(); }
MDType *operator->() const { return get(); }
MDType &operator*() const { return *get(); }
DIScopeRef getContext() const { return get()->getScope(); }
StringRef getName() const { return get()->getName(); }
unsigned getLineNumber() const { return get()->getLine(); }
uint64_t getSizeInBits() const { return get()->getSizeInBits(); }
uint64_t getAlignInBits() const { return get()->getAlignInBits(); }
// FIXME: Offset is only used for DW_TAG_member nodes. Making every type
// carry this is just plain insane.
uint64_t getOffsetInBits() const { return get()->getOffsetInBits(); }
unsigned getFlags() const { return get()->getFlags(); }
bool isPrivate() const { return get()->isPrivate(); }
bool isProtected() const { return get()->isProtected(); }
bool isPublic() const { return get()->isPublic(); }
bool isForwardDecl() const { return get()->isForwardDecl(); }
bool isAppleBlockExtension() const { return get()->isAppleBlockExtension(); }
bool isBlockByrefStruct() const { return get()->isBlockByrefStruct(); }
bool isVirtual() const { return get()->isVirtual(); }
bool isArtificial() const { return get()->isArtificial(); }
bool isObjectPointer() const { return get()->isObjectPointer(); }
bool isObjcClassComplete() const { return get()->isObjcClassComplete(); }
bool isVector() const { return get()->isVector(); }
bool isStaticMember() const { return get()->isStaticMember(); }
bool isLValueReference() const { return get()->isLValueReference(); }
bool isRValueReference() const { return get()->isRValueReference(); }
operator DIDescriptor() const { return N; }
operator DIScope() const { return N; }
operator MDType *() const { return N; }
MDType *operator->() const { return N; }
MDType &operator*() const { return *N; }
};
/// \brief A basic type, like 'int' or 'float'.
class DIBasicType : public DIType {
class DIBasicType {
MDBasicType *N;
public:
DIBasicType() = default;
DIBasicType(const MDBasicType *N) : DIType(N) {}
DIBasicType(const MDBasicType *N = nullptr)
: N(const_cast<MDBasicType *>(N)) {}
MDBasicType *get() const {
return cast_or_null<MDBasicType>(DIDescriptor::get());
}
operator MDBasicType *() const { return get(); }
MDBasicType *operator->() const { return get(); }
MDBasicType &operator*() const { return *get(); }
unsigned getEncoding() const { return get()->getEncoding(); }
operator DIDescriptor() const { return N; }
operator DIType() const { return N; }
operator MDBasicType *() const { return N; }
MDBasicType *operator->() const { return N; }
MDBasicType &operator*() const { return *N; }
};
/// \brief A simple derived type
///
/// Like a const qualified type, a typedef, a pointer or reference, et cetera.
/// Or, a data member of a class/struct/union.
class DIDerivedType : public DIType {
class DIDerivedType {
MDDerivedTypeBase *N;
public:
DIDerivedType() = default;
DIDerivedType(const MDDerivedTypeBase *N) : DIType(N) {}
DIDerivedType(const MDDerivedTypeBase *N = nullptr)
: N(const_cast<MDDerivedTypeBase *>(N)) {}
MDDerivedTypeBase *get() const {
return cast_or_null<MDDerivedTypeBase>(DIDescriptor::get());
}
operator MDDerivedTypeBase *() const { return get(); }
MDDerivedTypeBase *operator->() const { return get(); }
MDDerivedTypeBase &operator*() const { return *get(); }
DITypeRef getTypeDerivedFrom() const { return get()->getBaseType(); }
operator DIDescriptor() const { return N; }
operator DIType() const { return N; }
operator MDDerivedTypeBase *() const { return N; }
MDDerivedTypeBase *operator->() const { return N; }
MDDerivedTypeBase &operator*() const { return *N; }
};
/// \brief Types that refer to multiple other types.
///
/// This descriptor holds a type that can refer to multiple other types, like a
/// function or struct.
///
/// DICompositeType is derived from DIDerivedType because some
/// composite types (such as enums) can be derived from basic types
// FIXME: Make this derive from DIType directly & just store the
// base type in a single DIType field.
class DICompositeType : public DIDerivedType {
friend class DIBuilder;
class DICompositeType {
MDCompositeTypeBase *N;
public:
DICompositeType() = default;
DICompositeType(const MDCompositeTypeBase *N) : DIDerivedType(N) {}
DICompositeType(const MDCompositeTypeBase *N = nullptr)
: N(const_cast<MDCompositeTypeBase *>(N)) {}
MDCompositeTypeBase *get() const {
return cast_or_null<MDCompositeTypeBase>(DIDescriptor::get());
}
operator MDCompositeTypeBase *() const { return get(); }
MDCompositeTypeBase *operator->() const { return get(); }
MDCompositeTypeBase &operator*() const { return *get(); }
DIArray getElements() const { return get()->getElements(); }
unsigned getRunTimeLang() const { return get()->getRuntimeLang(); }
DITypeRef getContainingType() const { return get()->getVTableHolder(); }
DIArray getTemplateParams() const { return get()->getTemplateParams(); }
MDString *getIdentifier() const { return get()->getRawIdentifier(); }
operator DIDescriptor() const { return N; }
operator DIType() const { return N; }
operator MDCompositeTypeBase *() const { return N; }
MDCompositeTypeBase *operator->() const { return N; }
MDCompositeTypeBase &operator*() const { return *N; }
};
class DISubroutineType : public DICompositeType {
class DISubroutineType {
MDSubroutineType *N;
public:
DISubroutineType() = default;
DISubroutineType(const MDSubroutineType *N) : DICompositeType(N) {}
DISubroutineType(const MDSubroutineType *N = nullptr)
: N(const_cast<MDSubroutineType *>(N)) {}
MDSubroutineType *get() const {
return cast_or_null<MDSubroutineType>(DIDescriptor::get());
}
operator MDSubroutineType *() const { return get(); }
MDSubroutineType *operator->() const { return get(); }
MDSubroutineType &operator*() const { return *get(); }
MDTypeRefArray getTypeArray() const { return get()->getTypeArray(); }
operator DIDescriptor() const { return N; }
operator DIType() const { return N; }
operator DICompositeType() const { return N; }
operator MDSubroutineType *() const { return N; }
MDSubroutineType *operator->() const { return N; }
MDSubroutineType &operator*() const { return *N; }
};
class DIFile {

View File

@ -594,7 +594,7 @@ public:
}
};
/// \brief Basic type.
/// \brief Basic type, like 'int' or 'float'.
///
/// TODO: Split out DW_TAG_unspecified_type.
/// TODO: Drop unused accessors.

View File

@ -98,27 +98,27 @@ void ModuleDebugInfoPrinter::print(raw_ostream &O, const Module *M) const {
O << '\n';
}
for (DIType T : Finder.types()) {
for (const MDType *T : Finder.types()) {
O << "Type:";
if (!T.getName().empty())
O << ' ' << T.getName();
printFile(O, T.getFilename(), T.getDirectory(), T.getLineNumber());
if (DIBasicType BT = dyn_cast<MDBasicType>(T)) {
if (!T->getName().empty())
O << ' ' << T->getName();
printFile(O, T->getFilename(), T->getDirectory(), T->getLine());
if (auto *BT = dyn_cast<MDBasicType>(T)) {
O << " ";
if (const char *Encoding =
dwarf::AttributeEncodingString(BT.getEncoding()))
dwarf::AttributeEncodingString(BT->getEncoding()))
O << Encoding;
else
O << "unknown-encoding(" << BT.getEncoding() << ')';
O << "unknown-encoding(" << BT->getEncoding() << ')';
} else {
O << ' ';
if (const char *Tag = dwarf::TagString(T.getTag()))
if (const char *Tag = dwarf::TagString(T->getTag()))
O << Tag;
else
O << "unknown-tag(" << T.getTag() << ")";
O << "unknown-tag(" << T->getTag() << ")";
}
if (DICompositeType CT = dyn_cast<MDCompositeType>(T)) {
if (auto *S = CT.getIdentifier())
if (auto *CT = dyn_cast<MDCompositeType>(T)) {
if (auto *S = CT->getRawIdentifier())
O << " (identifier: '" << S->getString() << "')";
}
O << '\n';

View File

@ -114,9 +114,9 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) {
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");
if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
DeclContext = resolve(SDMDecl->getScope());
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);
@ -720,7 +720,7 @@ void DwarfCompileUnit::addGlobalType(DIType Ty, const DIE &Die,
DIScope Context) {
if (includeMinimalInlineScopes())
return;
std::string FullName = getParentContextString(Context) + Ty.getName().str();
std::string FullName = getParentContextString(Context) + Ty->getName().str();
GlobalTypes[FullName] = &Die;
}

View File

@ -141,7 +141,7 @@ bool DbgVariable::isBlockByrefVariable() const {
}
DIType DbgVariable::getType() const {
DIType Ty = Var->getType().resolve(DD->getTypeIdentifierMap());
MDType *Ty = Var->getType().resolve(DD->getTypeIdentifierMap());
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
// addresses instead.
if (Ty->isBlockByrefStruct()) {
@ -169,17 +169,17 @@ DIType DbgVariable::getType() const {
have a DW_AT_location that tells the debugger how to unwind through
the pointers and __Block_byref_x_VarName struct to find the actual
value of the variable. The function addBlockByrefType does this. */
DIType subType = Ty;
uint16_t tag = Ty.getTag();
MDType *subType = Ty;
uint16_t tag = Ty->getTag();
if (tag == dwarf::DW_TAG_pointer_type)
subType = resolve(DITypeRef(cast<MDDerivedType>(Ty)->getBaseType()));
DIArray Elements(cast<MDCompositeTypeBase>(subType)->getElements());
auto Elements = cast<MDCompositeTypeBase>(subType)->getElements();
for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
DIDerivedType DT = cast<MDDerivedTypeBase>(Elements[i]);
if (getName() == DT.getName())
return (resolve(DT.getTypeDerivedFrom()));
auto *DT = cast<MDDerivedTypeBase>(Elements[i]);
if (getName() == DT->getName())
return resolve(DITypeRef(DT->getBaseType()));
}
}
return Ty;
@ -306,8 +306,8 @@ bool DwarfDebug::isSubprogramContext(const MDNode *Context) {
return false;
if (isa<MDSubprogram>(Context))
return true;
if (DIType T = dyn_cast<MDType>(Context))
return isSubprogramContext(resolve(T.getContext()));
if (auto *T = dyn_cast<MDType>(Context))
return isSubprogramContext(resolve(T->getScope()));
return false;
}
@ -461,13 +461,13 @@ void DwarfDebug::beginModule() {
for (DIType Ty : CUNode->getEnumTypes()) {
// The enum types array by design contains pointers to
// MDNodes rather than DIRefs. Unique them here.
DIType UniqueTy = cast<MDType>(resolve(Ty.getRef()));
DIType UniqueTy = cast<MDType>(resolve(Ty->getRef()));
CU.getOrCreateTypeDIE(UniqueTy);
}
for (DIType Ty : CUNode->getRetainedTypes()) {
// The retained types array by design contains pointers to
// MDNodes rather than DIRefs. Unique them here.
DIType UniqueTy = cast<MDType>(resolve(Ty.getRef()));
DIType UniqueTy = cast<MDType>(resolve(Ty->getRef()));
CU.getOrCreateTypeDIE(UniqueTy);
}
// Emit imported_modules last so that the relevant context is already

View File

@ -148,7 +148,7 @@ public:
bool isArtificial() const {
if (Var->isArtificial())
return true;
if (getType().isArtificial())
if (getType()->isArtificial())
return true;
return false;
}
@ -156,7 +156,7 @@ public:
bool isObjectPointer() const {
if (Var->isObjectPointer())
return true;
if (getType().isObjectPointer())
if (getType()->isObjectPointer())
return true;
return false;
}

View File

@ -424,7 +424,7 @@ void DwarfUnit::addSourceLine(DIE &Die, DISubprogram SP) {
void DwarfUnit::addSourceLine(DIE &Die, DIType Ty) {
assert(Ty);
addSourceLine(Die, Ty.getLineNumber(), Ty.getFilename(), Ty.getDirectory());
addSourceLine(Die, Ty->getLine(), Ty->getFilename(), Ty->getDirectory());
}
/// addSourceLine - Add location information to specified debug information
@ -521,28 +521,26 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
const MachineLocation &Location) {
DIType Ty = DV.getType();
DIType TmpTy = Ty;
uint16_t Tag = Ty.getTag();
uint16_t Tag = Ty->getTag();
bool isPointer = false;
StringRef varName = DV.getName();
if (Tag == dwarf::DW_TAG_pointer_type) {
DIDerivedType DTy = cast<MDDerivedType>(Ty);
TmpTy = resolve(DTy.getTypeDerivedFrom());
TmpTy = resolve(DTy->getBaseType());
isPointer = true;
}
DICompositeType blockStruct = cast<MDCompositeTypeBase>(TmpTy);
// Find the __forwarding field and the variable field in the __Block_byref
// struct.
DIArray Fields = blockStruct.getElements();
DIArray Fields = cast<MDCompositeTypeBase>(TmpTy)->getElements();
DIDerivedType varField;
DIDerivedType forwardingField;
for (unsigned i = 0, N = Fields.size(); i < N; ++i) {
DIDerivedType DT = cast<MDDerivedTypeBase>(Fields[i]);
StringRef fieldName = DT.getName();
StringRef fieldName = DT->getName();
if (fieldName == "__forwarding")
forwardingField = DT;
else if (fieldName == varName)
@ -550,8 +548,8 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
}
// Get the offsets for the forwarding field and the variable field.
unsigned forwardingFieldOffset = forwardingField.getOffsetInBits() >> 3;
unsigned varFieldOffset = varField.getOffsetInBits() >> 2;
unsigned forwardingFieldOffset = forwardingField->getOffsetInBits() >> 3;
unsigned varFieldOffset = varField->getOffsetInBits() >> 2;
// Decode the original location, and use that as the start of the byref
// variable's location.
@ -598,7 +596,7 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
/// Return true if type encoding is unsigned.
static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) {
if (DIDerivedType DTy = dyn_cast<MDDerivedTypeBase>(Ty)) {
dwarf::Tag T = (dwarf::Tag)Ty.getTag();
dwarf::Tag T = (dwarf::Tag)Ty->getTag();
// Encode pointer constants as unsigned bytes. This is used at least for
// null pointer constant emission.
// (Pieces of) aggregate types that get hacked apart by SROA may also be
@ -619,55 +617,55 @@ static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) {
T == dwarf::DW_TAG_volatile_type ||
T == dwarf::DW_TAG_restrict_type ||
T == dwarf::DW_TAG_enumeration_type);
if (DITypeRef Deriv = DTy.getTypeDerivedFrom())
if (DITypeRef Deriv = DTy->getBaseType())
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);
assert(DTy->getTag() == dwarf::DW_TAG_enumeration_type);
return false;
}
DIBasicType BTy = cast<MDBasicType>(Ty);
unsigned Encoding = BTy.getEncoding();
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_float ||
Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
(Ty.getTag() == dwarf::DW_TAG_unspecified_type &&
Ty.getName() == "decltype(nullptr)")) &&
Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
Encoding == dwarf::DW_ATE_boolean ||
(Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
Ty->getName() == "decltype(nullptr)")) &&
"Unsupported encoding");
return (Encoding == dwarf::DW_ATE_unsigned ||
Encoding == dwarf::DW_ATE_unsigned_char ||
Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
Ty.getTag() == dwarf::DW_TAG_unspecified_type);
return Encoding == dwarf::DW_ATE_unsigned ||
Encoding == dwarf::DW_ATE_unsigned_char ||
Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
Ty->getTag() == dwarf::DW_TAG_unspecified_type;
}
/// If this type is derived from a base type then return base type size.
static uint64_t getBaseTypeSize(DwarfDebug *DD, DIDerivedType Ty) {
unsigned Tag = Ty.getTag();
unsigned Tag = Ty->getTag();
if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
Tag != dwarf::DW_TAG_restrict_type)
return Ty.getSizeInBits();
return Ty->getSizeInBits();
DIType BaseType = DD->resolve(Ty.getTypeDerivedFrom());
auto *BaseType = DD->resolve(Ty->getBaseType());
assert(BaseType && "Unexpected invalid base type");
// If this is a derived type, go ahead and get the base type, unless it's a
// reference then it's just the size of the field. Pointer types have no need
// of this since they're a different type of qualification on the type.
if (BaseType.getTag() == dwarf::DW_TAG_reference_type ||
BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type)
return Ty.getSizeInBits();
if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
return Ty->getSizeInBits();
if (auto *DT = dyn_cast<MDDerivedTypeBase>(BaseType))
return getBaseTypeSize(DD, DT);
return BaseType.getSizeInBits();
return BaseType->getSizeInBits();
}
/// addConstantFPValue - Add constant value entry in variable DIE.
@ -788,14 +786,14 @@ DIE *DwarfUnit::getOrCreateContextDIE(DIScope Context) {
}
DIE *DwarfUnit::createTypeDIE(DICompositeType Ty) {
DIScope Context = resolve(Ty.getContext());
DIScope Context = resolve(Ty->getScope());
DIE *ContextDIE = getOrCreateContextDIE(Context);
if (DIE *TyDIE = getDIE(Ty))
return TyDIE;
// Create new type.
DIE &TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty);
constructTypeDIE(TyDIE, Ty);
@ -809,18 +807,18 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
if (!TyNode)
return nullptr;
DIType Ty = cast<MDType>(TyNode);
assert(Ty == resolve(Ty.getRef()) &&
auto *Ty = cast<MDType>(TyNode);
assert(Ty == resolve(Ty->getRef()) &&
"type was not uniqued, possible ODR violation.");
// DW_TAG_restrict_type is not supported in DWARF2
if (Ty.getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2)
if (Ty->getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2)
return getOrCreateTypeDIE(
resolve(DITypeRef(cast<MDDerivedType>(Ty)->getBaseType())));
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE.
DIScope Context = resolve(Ty.getContext());
DIScope Context = resolve(Ty->getScope());
DIE *ContextDIE = getOrCreateContextDIE(Context);
assert(ContextDIE);
@ -828,15 +826,15 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
return TyDIE;
// Create new type.
DIE &TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty);
updateAcceleratorTables(Context, Ty, TyDIE);
if (auto *BT = dyn_cast<MDBasicType>(Ty))
constructTypeDIE(TyDIE, BT);
else if (DICompositeType CTy = dyn_cast<MDCompositeTypeBase>(Ty)) {
if (GenerateDwarfTypeUnits && !Ty.isForwardDecl())
if (MDString *TypeId = CTy.getIdentifier()) {
if (GenerateDwarfTypeUnits && !Ty->isForwardDecl())
if (MDString *TypeId = CTy->getRawIdentifier()) {
DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy);
// Skip updating the accelerator tables since this is not the full type.
return &TyDIE;
@ -851,15 +849,15 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
void DwarfUnit::updateAcceleratorTables(DIScope Context, DIType Ty,
const DIE &TyDIE) {
if (!Ty.getName().empty() && !Ty.isForwardDecl()) {
if (!Ty->getName().empty() && !Ty->isForwardDecl()) {
bool IsImplementation = 0;
if (DICompositeType CT = dyn_cast<MDCompositeTypeBase>(Ty)) {
if (auto *CT = dyn_cast<MDCompositeTypeBase>(Ty)) {
// A runtime language of 0 actually means C/C++ and that any
// non-negative value is some version of Objective-C/C++.
IsImplementation = (CT.getRunTimeLang() == 0) || CT.isObjcClassComplete();
IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();
}
unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0;
DD->addAccelType(Ty.getName(), TyDIE, Flags);
DD->addAccelType(Ty->getName(), TyDIE, Flags);
if (!Context || isa<MDCompileUnit>(Context) || isa<MDFile>(Context) ||
isa<MDNamespace>(Context))
@ -933,31 +931,31 @@ std::string DwarfUnit::getParentContextString(DIScope Context) const {
/// constructTypeDIE - Construct basic type die from DIBasicType.
void DwarfUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
// Get core information.
StringRef Name = BTy.getName();
StringRef Name = BTy->getName();
// Add name if not anonymous or intermediate type.
if (!Name.empty())
addString(Buffer, dwarf::DW_AT_name, Name);
// An unspecified type only has a name attribute.
if (BTy.getTag() == dwarf::DW_TAG_unspecified_type)
if (BTy->getTag() == dwarf::DW_TAG_unspecified_type)
return;
addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
BTy.getEncoding());
BTy->getEncoding());
uint64_t Size = BTy.getSizeInBits() >> 3;
uint64_t Size = BTy->getSizeInBits() >> 3;
addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
}
/// constructTypeDIE - Construct derived type die from DIDerivedType.
void DwarfUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
// Get core information.
StringRef Name = DTy.getName();
uint64_t Size = DTy.getSizeInBits() >> 3;
StringRef Name = DTy->getName();
uint64_t Size = DTy->getSizeInBits() >> 3;
uint16_t Tag = Buffer.getTag();
// Map to main type, void will not have a type.
DIType FromTy = resolve(DTy.getTypeDerivedFrom());
DIType FromTy = resolve(DTy->getBaseType());
if (FromTy)
addType(Buffer, FromTy);
@ -975,7 +973,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
Buffer, dwarf::DW_AT_containing_type,
*getOrCreateTypeDIE(resolve(cast<MDDerivedType>(DTy)->getClassType())));
// Add source line info if available and TyDesc is not a forward declaration.
if (!DTy.isForwardDecl())
if (!DTy->isForwardDecl())
addSourceLine(Buffer, DTy);
}
@ -989,7 +987,7 @@ void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeArray Args) {
} else {
DIE &Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);
addType(Arg, Ty);
if (Ty.isArtificial())
if (Ty->isArtificial())
addFlag(Arg, dwarf::DW_AT_artificial);
}
}
@ -998,9 +996,9 @@ void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeArray Args) {
/// constructTypeDIE - Construct type DIE from DICompositeType.
void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// Add name if not anonymous or intermediate type.
StringRef Name = CTy.getName();
StringRef Name = CTy->getName();
uint64_t Size = CTy.getSizeInBits() >> 3;
uint64_t Size = CTy->getSizeInBits() >> 3;
uint16_t Tag = Buffer.getTag();
switch (Tag) {
@ -1031,17 +1029,17 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
Language == dwarf::DW_LANG_ObjC))
addFlag(Buffer, dwarf::DW_AT_prototyped);
if (CTy.isLValueReference())
if (CTy->isLValueReference())
addFlag(Buffer, dwarf::DW_AT_reference);
if (CTy.isRValueReference())
if (CTy->isRValueReference())
addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
} break;
case dwarf::DW_TAG_structure_type:
case dwarf::DW_TAG_union_type:
case dwarf::DW_TAG_class_type: {
// Add elements to structure type.
DIArray Elements = CTy.getElements();
DIArray Elements = CTy->getElements();
for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
DIDescriptor Element = Elements[i];
if (!Element)
@ -1049,11 +1047,10 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
if (auto *SP = dyn_cast<MDSubprogram>(Element))
getOrCreateSubprogramDIE(SP);
else if (DIDerivedType DDTy = dyn_cast<MDDerivedTypeBase>(Element)) {
if (DDTy.getTag() == dwarf::DW_TAG_friend) {
if (DDTy->getTag() == dwarf::DW_TAG_friend) {
DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);
addType(ElemDie, resolve(DDTy.getTypeDerivedFrom()),
dwarf::DW_AT_friend);
} else if (DDTy.isStaticMember()) {
addType(ElemDie, resolve(DDTy->getBaseType()), dwarf::DW_AT_friend);
} else if (DDTy->isStaticMember()) {
getOrCreateStaticMemberDIE(DDTy);
} else {
constructMemberDIE(Buffer, DDTy);
@ -1083,24 +1080,24 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
}
}
if (CTy.isAppleBlockExtension())
if (CTy->isAppleBlockExtension())
addFlag(Buffer, dwarf::DW_AT_APPLE_block);
// This is outside the DWARF spec, but GDB expects a DW_AT_containing_type
// inside C++ composite types to point to the base class with the vtable.
if (DICompositeType ContainingType =
dyn_cast_or_null<MDCompositeType>(resolve(CTy.getContainingType())))
dyn_cast_or_null<MDCompositeType>(resolve(CTy->getVTableHolder())))
addDIEEntry(Buffer, dwarf::DW_AT_containing_type,
*getOrCreateTypeDIE(ContainingType));
if (CTy.isObjcClassComplete())
if (CTy->isObjcClassComplete())
addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
// Add template parameters to a class, structure or union types.
// FIXME: The support isn't in the metadata for this yet.
if (Tag == dwarf::DW_TAG_class_type ||
Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
addTemplateParams(Buffer, CTy.getTemplateParams());
addTemplateParams(Buffer, CTy->getTemplateParams());
break;
}
@ -1119,20 +1116,20 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// TODO: Do we care about size for enum forward declarations?
if (Size)
addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
else if (!CTy.isForwardDecl())
else if (!CTy->isForwardDecl())
// Add zero size if it is not a forward declaration.
addUInt(Buffer, dwarf::DW_AT_byte_size, None, 0);
// If we're a forward decl, say so.
if (CTy.isForwardDecl())
if (CTy->isForwardDecl())
addFlag(Buffer, dwarf::DW_AT_declaration);
// Add source line info if available.
if (!CTy.isForwardDecl())
if (!CTy->isForwardDecl())
addSourceLine(Buffer, CTy);
// No harm in adding the runtime language to the declaration.
unsigned RLang = CTy.getRunTimeLang();
unsigned RLang = CTy->getRuntimeLang();
if (RLang)
addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
RLang);
@ -1297,10 +1294,10 @@ void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie,
addFlag(SPDie, dwarf::DW_AT_prototyped);
DISubroutineType SPTy = SP->getType();
assert(SPTy.getTag() == dwarf::DW_TAG_subroutine_type &&
assert(SPTy->getTag() == dwarf::DW_TAG_subroutine_type &&
"the type of a subprogram should be a subroutine");
auto Args = SPTy.getTypeArray();
auto 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.size())
@ -1394,11 +1391,11 @@ DIE *DwarfUnit::getIndexTyDie() {
/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) {
if (CTy.isVector())
if (CTy->isVector())
addFlag(Buffer, dwarf::DW_AT_GNU_vector);
// Emit the element type.
addType(Buffer, resolve(CTy.getTypeDerivedFrom()));
addType(Buffer, resolve(CTy->getBaseType()));
// Get an anonymous type for index type.
// FIXME: This type should be passed down from the front end
@ -1406,7 +1403,7 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) {
DIE *IdxTy = getIndexTyDie();
// Add subranges to array type.
DIArray Elements = CTy.getElements();
DIArray Elements = CTy->getElements();
for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
DIDescriptor Element = Elements[i];
if (Element.getTag() == dwarf::DW_TAG_subrange_type)
@ -1416,7 +1413,7 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) {
/// constructEnumTypeDIE - Construct an enum type DIE from DICompositeType.
void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy) {
DIArray Elements = CTy.getElements();
DIArray Elements = CTy->getElements();
// Add enumerators to enumeration type.
for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
@ -1430,7 +1427,7 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy) {
Value);
}
}
DIType DTy = resolve(CTy.getTypeDerivedFrom());
DIType DTy = resolve(CTy->getBaseType());
if (DTy) {
addType(Buffer, DTy);
addFlag(Buffer, dwarf::DW_AT_enum_class);

View File

@ -487,7 +487,7 @@ DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits,
auto *R =
MDCompositeType::get(VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0,
nullptr, MDTypeRef::get(Ty), Size, AlignInBits, 0,
DIType::FlagVector, Subscripts, 0, nullptr);
DebugNode::FlagVector, Subscripts, 0, nullptr);
trackIfUnresolved(R);
return R;
}
@ -501,27 +501,25 @@ static DIType createTypeWithFlags(LLVMContext &Context, DIType Ty,
DIType DIBuilder::createArtificialType(DIType Ty) {
// FIXME: Restrict this to the nodes where it's valid.
if (Ty.isArtificial())
if (Ty->isArtificial())
return Ty;
return createTypeWithFlags(VMContext, Ty, DIType::FlagArtificial);
return createTypeWithFlags(VMContext, Ty, DebugNode::FlagArtificial);
}
DIType DIBuilder::createObjectPointerType(DIType Ty) {
// FIXME: Restrict this to the nodes where it's valid.
if (Ty.isObjectPointer())
if (Ty->isObjectPointer())
return Ty;
unsigned Flags = DIType::FlagObjectPointer | DIType::FlagArtificial;
unsigned Flags = DebugNode::FlagObjectPointer | DebugNode::FlagArtificial;
return createTypeWithFlags(VMContext, Ty, Flags);
}
void DIBuilder::retainType(DIType T) {
assert(T.get() && "Expected non-null type");
assert(T && "Expected non-null type");
AllRetainTypes.emplace_back(T);
}
DIBasicType DIBuilder::createUnspecifiedParameter() {
return DIBasicType();
}
DIBasicType DIBuilder::createUnspecifiedParameter() { return nullptr; }
DICompositeType
DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope,
@ -579,9 +577,9 @@ DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {
static void checkGlobalVariableScope(DIDescriptor Context) {
#ifndef NDEBUG
if (DICompositeType CT =
if (auto *CT =
dyn_cast_or_null<MDCompositeType>(getNonCompileUnitScope(Context)))
assert(!CT.getIdentifier() &&
assert(CT->getIdentifier().empty() &&
"Context of a global variable should not be a type with identifier");
#endif
}
@ -675,11 +673,11 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name,
unsigned ScopeLine, unsigned Flags,
bool isOptimized, Function *Fn,
MDNode *TParams, MDNode *Decl) {
assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type &&
assert(Ty->getTag() == dwarf::DW_TAG_subroutine_type &&
"function types should be subroutines");
auto *Node = MDSubprogram::get(
VMContext, MDScopeRef::get(DIScope(getNonCompileUnitScope(Context))),
Name, LinkageName, File, LineNo, cast_or_null<MDSubroutineType>(Ty.get()),
Name, LinkageName, File, LineNo, cast_or_null<MDSubroutineType>(Ty),
isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized,
Fn, cast_or_null<MDTuple>(TParams), cast_or_null<MDSubprogram>(Decl),
MDTuple::getTemporary(VMContext, None).release());
@ -701,11 +699,10 @@ DIBuilder::createTempFunctionFwdDecl(DIDescriptor Context, StringRef Name,
return MDSubprogram::getTemporary(
VMContext,
MDScopeRef::get(DIScope(getNonCompileUnitScope(Context))), Name,
LinkageName, File, LineNo,
cast_or_null<MDSubroutineType>(Ty.get()), isLocalToUnit,
isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized, Fn,
cast_or_null<MDTuple>(TParams), cast_or_null<MDSubprogram>(Decl),
nullptr)
LinkageName, File, LineNo, cast_or_null<MDSubroutineType>(Ty),
isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, Flags,
isOptimized, Fn, cast_or_null<MDTuple>(TParams),
cast_or_null<MDSubprogram>(Decl), nullptr)
.release();
}
@ -717,7 +714,7 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name,
DIType VTableHolder, unsigned Flags,
bool isOptimized, Function *Fn,
MDNode *TParam) {
assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type &&
assert(Ty->getTag() == dwarf::DW_TAG_subroutine_type &&
"function types should be subroutines");
assert(getNonCompileUnitScope(Context) &&
"Methods should have both a Context and a context that isn't "
@ -725,9 +722,9 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name,
// FIXME: Do we want to use different scope/lines?
auto *SP = MDSubprogram::get(
VMContext, MDScopeRef::get(cast<MDScope>(Context)), Name, LinkageName, F,
LineNo, cast_or_null<MDSubroutineType>(Ty.get()), isLocalToUnit,
isDefinition, LineNo, MDTypeRef::get(VTableHolder), VK, VIndex, Flags,
isOptimized, Fn, cast_or_null<MDTuple>(TParam), nullptr, nullptr);
LineNo, cast_or_null<MDSubroutineType>(Ty), isLocalToUnit, isDefinition,
LineNo, MDTypeRef::get(VTableHolder), VK, VIndex, Flags, isOptimized, Fn,
cast_or_null<MDTuple>(TParam), nullptr, nullptr);
if (isDefinition)
AllSubprograms.push_back(SP);

View File

@ -67,8 +67,7 @@ DICompositeType llvm::getDICompositeType(DIType T) {
// not generate identifier for types, so using an empty map to resolve
// DerivedFrom should be fine.
DITypeIdentifierMap EmptyMap;
return getDICompositeType(
DIDerivedType(D).getTypeDerivedFrom().resolve(EmptyMap));
return getDICompositeType(D->getBaseType().resolve(EmptyMap));
}
return nullptr;
@ -83,15 +82,15 @@ llvm::generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes) {
for (unsigned Ti = 0, Te = Retain.size(); Ti != Te; ++Ti) {
if (!isa<MDCompositeType>(Retain[Ti]))
continue;
DICompositeType Ty = cast<MDCompositeType>(Retain[Ti]);
if (MDString *TypeId = Ty.getIdentifier()) {
auto *Ty = cast<MDCompositeType>(Retain[Ti]);
if (MDString *TypeId = Ty->getRawIdentifier()) {
// Definition has priority over declaration.
// Try to insert (TypeId, Ty) to Map.
std::pair<DITypeIdentifierMap::iterator, bool> P =
Map.insert(std::make_pair(TypeId, Ty));
// If TypeId already exists in Map and this is a definition, replace
// whatever we had (declaration or definition) with the definition.
if (!P.second && !Ty.isForwardDecl())
if (!P.second && !Ty->isForwardDecl())
P.first->second = Ty;
}
}
@ -164,22 +163,22 @@ void DebugInfoFinder::processLocation(const Module &M, DILocation Loc) {
void DebugInfoFinder::processType(DIType DT) {
if (!addType(DT))
return;
processScope(DT.getContext().resolve(TypeIdentifierMap));
if (DICompositeType DCT = dyn_cast<MDCompositeTypeBase>(DT)) {
processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap));
if (DISubroutineType ST = dyn_cast<MDSubroutineType>(DCT)) {
processScope(DT->getScope().resolve(TypeIdentifierMap));
if (auto *DCT = dyn_cast<MDCompositeTypeBase>(DT)) {
processType(DCT->getBaseType().resolve(TypeIdentifierMap));
if (auto *ST = dyn_cast<MDSubroutineType>(DCT)) {
for (MDTypeRef Ref : ST->getTypeArray())
processType(Ref.resolve(TypeIdentifierMap));
return;
}
for (Metadata *D : DCT->getElements()) {
if (DIType T = dyn_cast<MDType>(D))
if (auto *T = dyn_cast<MDType>(D))
processType(T);
else if (DISubprogram SP = dyn_cast<MDSubprogram>(D))
processSubprogram(SP);
}
} else if (DIDerivedType DDT = dyn_cast<MDDerivedTypeBase>(DT)) {
processType(DDT.getTypeDerivedFrom().resolve(TypeIdentifierMap));
} else if (auto *DDT = dyn_cast<MDDerivedTypeBase>(DT)) {
processType(DDT->getBaseType().resolve(TypeIdentifierMap));
}
}

View File

@ -36,9 +36,9 @@ struct BreakpointPrinter : public ModulePass {
N = N + NS->getName().str() + "::";
}
} else if (DIType TY = dyn_cast<MDType>(Context)) {
if (!TY.getName().empty()) {
getContextName(TY.getContext().resolve(TypeIdentifierMap), N);
N = N + TY.getName().str() + "::";
if (!TY->getName().empty()) {
getContextName(TY->getScope().resolve(TypeIdentifierMap), N);
N = N + TY->getName().str() + "::";
}
}
}