forked from OSchip/llvm-project
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:
parent
4caa7f2a9c
commit
b105564015
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() + "::";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue