aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGDebugInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp129
1 files changed, 66 insertions, 63 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 5f50b1cc..994bdbd 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -366,7 +366,7 @@ llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context,
if (const auto *RDecl = dyn_cast<RecordDecl>(Context))
if (!RDecl->isDependentType())
- return getOrCreateType(CGM.getContext().getTypeDeclType(RDecl),
+ return getOrCreateType(CGM.getContext().getCanonicalTagType(RDecl),
TheCU->getFile());
return Default;
}
@@ -1285,7 +1285,7 @@ static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM,
static SmallString<256> getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM,
llvm::DICompileUnit *TheCU) {
SmallString<256> Identifier;
- const TagDecl *TD = Ty->getDecl();
+ const TagDecl *TD = Ty->getOriginalDecl()->getDefinitionOrSelf();
if (!needsTypeIdentifier(TD, CGM, TheCU))
return Identifier;
@@ -1321,8 +1321,8 @@ static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD) {
llvm::DICompositeType *
CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,
llvm::DIScope *Ctx) {
- const RecordDecl *RD = Ty->getDecl();
- if (llvm::DIType *T = getTypeOrNull(CGM.getContext().getRecordType(RD)))
+ const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
return cast<llvm::DICompositeType>(T);
llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());
const unsigned Line =
@@ -2015,6 +2015,8 @@ void CGDebugInfo::CollectRecordNestedType(
const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
QualType Ty = CGM.getContext().getTypeDeclType(TD);
// Injected class names are not considered nested records.
+ // FIXME: Is this supposed to be testing for injected class name declarations
+ // instead?
if (isa<InjectedClassNameType>(Ty))
return;
SourceLocation Loc = TD->getLocation();
@@ -2356,7 +2358,9 @@ void CGDebugInfo::CollectCXXBasesAux(
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
for (const auto &BI : Bases) {
const auto *Base =
- cast<CXXRecordDecl>(BI.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ BI.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinition();
if (!SeenTypes.insert(Base).second)
continue;
auto *BaseTy = getOrCreateType(BI.getType(), Unit);
@@ -2825,12 +2829,12 @@ void CGDebugInfo::addHeapAllocSiteMetadata(llvm::CallBase *CI,
void CGDebugInfo::completeType(const EnumDecl *ED) {
if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
return;
- QualType Ty = CGM.getContext().getEnumType(ED);
+ CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
void *TyPtr = Ty.getAsOpaquePtr();
auto I = TypeCache.find(TyPtr);
if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
return;
- llvm::DIType *Res = CreateTypeDefinition(Ty->castAs<EnumType>());
+ llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
assert(!Res->isForwardDecl());
TypeCache[TyPtr].reset(Res);
}
@@ -2874,7 +2878,7 @@ static bool isDefinedInClangModule(const RecordDecl *RD) {
if (!Explicit && CXXDecl->getEnclosingNamespaceContext())
return false;
// This is a template, check the origin of the first member.
- if (CXXDecl->field_begin() == CXXDecl->field_end())
+ if (CXXDecl->fields().empty())
return TemplateKind == TSK_ExplicitInstantiationDeclaration;
if (!CXXDecl->field_begin()->isFromASTFile())
return false;
@@ -2900,7 +2904,7 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) {
void CGDebugInfo::completeClass(const RecordDecl *RD) {
if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
return;
- QualType Ty = CGM.getContext().getRecordType(RD);
+ CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
void *TyPtr = Ty.getAsOpaquePtr();
auto I = TypeCache.find(TyPtr);
if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
@@ -2909,7 +2913,7 @@ void CGDebugInfo::completeClass(const RecordDecl *RD) {
// We want the canonical definition of the structure to not
// be the typedef. Since that would lead to circular typedef
// metadata.
- auto [Res, PrefRes] = CreateTypeDefinition(Ty->castAs<RecordType>());
+ auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
assert(!Res->isForwardDecl());
TypeCache[TyPtr].reset(Res);
}
@@ -3013,14 +3017,14 @@ void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
if (shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD, CGM.getLangOpts()))
return;
- QualType Ty = CGM.getContext().getRecordType(RD);
+ CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
llvm::DIType *T = getTypeOrNull(Ty);
if (T && T->isForwardDecl())
completeClassData(RD);
}
llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) {
- RecordDecl *RD = Ty->getDecl();
+ RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(QualType(Ty, 0)));
if (T || shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD,
CGM.getLangOpts())) {
@@ -3048,7 +3052,7 @@ llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD,
std::pair<llvm::DIType *, llvm::DIType *>
CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
- RecordDecl *RD = Ty->getDecl();
+ RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
// Get overall information about the record type for the debug info.
llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());
@@ -3070,7 +3074,7 @@ CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
// Push the struct on region stack.
LexicalBlockStack.emplace_back(&*FwdDecl);
- RegionMap[Ty->getDecl()].reset(FwdDecl);
+ RegionMap[RD].reset(FwdDecl);
// Convert all the elements.
SmallVector<llvm::Metadata *, 16> EltTys;
@@ -3092,7 +3096,7 @@ CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
LexicalBlockStack.pop_back();
- RegionMap.erase(Ty->getDecl());
+ RegionMap.erase(RD);
llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
DBuilder.replaceArrays(FwdDecl, Elements);
@@ -3101,7 +3105,7 @@ CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
FwdDecl =
llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
- RegionMap[Ty->getDecl()].reset(FwdDecl);
+ RegionMap[RD].reset(FwdDecl);
if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
if (auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
@@ -3651,8 +3655,9 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty,
}
}
- llvm::DIType *ClassType = getOrCreateType(
- QualType(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0), U);
+ CanQualType T =
+ CGM.getContext().getCanonicalTagType(Ty->getMostRecentCXXRecordDecl());
+ llvm::DIType *ClassType = getOrCreateType(T, U);
if (Ty->isMemberDataPointerType())
return DBuilder.createMemberPointerType(
getOrCreateType(Ty->getPointeeType(), U), ClassType, Size, /*Align=*/0,
@@ -3687,17 +3692,21 @@ llvm::DIType *CGDebugInfo::CreateType(const HLSLInlineSpirvType *Ty,
return nullptr;
}
-llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
- const EnumDecl *ED = Ty->getDecl();
+static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU,
+ const EnumType *Ty) {
+ const EnumDecl *ED = Ty->getOriginalDecl()->getDefinitionOrSelf();
uint64_t Size = 0;
uint32_t Align = 0;
- if (!ED->getTypeForDecl()->isIncompleteType()) {
- Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());
+ if (ED->isComplete()) {
+ Size = CGM.getContext().getTypeSize(QualType(Ty, 0));
Align = getDeclAlignIfRequired(ED, CGM.getContext());
}
+ return std::make_tuple(ED, Size, Align, getTypeIdentifier(Ty, CGM, TheCU));
+}
- SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
+llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
+ auto [ED, Size, Align, Identifier] = getEnumInfo(CGM, TheCU, Ty);
bool isImportedFromModule =
DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
@@ -3732,15 +3741,7 @@ llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
}
llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {
- const EnumDecl *ED = Ty->getDecl();
- uint64_t Size = 0;
- uint32_t Align = 0;
- if (!ED->getTypeForDecl()->isIncompleteType()) {
- Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());
- Align = getDeclAlignIfRequired(ED, CGM.getContext());
- }
-
- SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
+ auto [ED, Size, Align, Identifier] = getEnumInfo(CGM, TheCU, Ty);
SmallVector<llvm::Metadata *, 16> Enumerators;
ED = ED->getDefinition();
@@ -3815,6 +3816,11 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
switch (T->getTypeClass()) {
default:
return C.getQualifiedType(T.getTypePtr(), Quals);
+ case Type::Enum:
+ case Type::Record:
+ case Type::InjectedClassName:
+ return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
+ Quals);
case Type::TemplateSpecialization: {
const auto *Spec = cast<TemplateSpecializationType>(T);
if (Spec->isTypeAlias())
@@ -3843,11 +3849,8 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
case Type::CountAttributed:
T = cast<CountAttributedType>(T)->desugar();
break;
- case Type::Elaborated:
- T = cast<ElaboratedType>(T)->getNamedType();
- break;
case Type::Using:
- T = cast<UsingType>(T)->getUnderlyingType();
+ T = cast<UsingType>(T)->desugar();
break;
case Type::Paren:
T = cast<ParenType>(T)->getInnerType();
@@ -3906,7 +3909,8 @@ void CGDebugInfo::completeUnusedClass(const CXXRecordDecl &D) {
completeClassData(&D);
// In case this type has no member function definitions being emitted, ensure
// it is retained
- RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr());
+ RetainedTypes.push_back(
+ CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
}
llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) {
@@ -4051,7 +4055,6 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
case Type::Adjusted:
case Type::Decayed:
case Type::DeducedTemplateSpecialization:
- case Type::Elaborated:
case Type::Using:
case Type::Paren:
case Type::MacroQualified:
@@ -4094,7 +4097,7 @@ CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty) {
// TODO: Currently used for context chains when limiting debug info.
llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
- RecordDecl *RD = Ty->getDecl();
+ RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
// Get overall information about the record type for the debug info.
StringRef RDName = getClassName(RD);
@@ -4111,7 +4114,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
// If we ended up creating the type during the context chain construction,
// just return that.
auto *T = cast_or_null<llvm::DICompositeType>(
- getTypeOrNull(CGM.getContext().getRecordType(RD)));
+ getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
if (T && (!T->isForwardDecl() || !RD->getDefinition()))
return T;
@@ -4181,7 +4184,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
break;
}
- RegionMap[Ty->getDecl()].reset(RealDecl);
+ RegionMap[RD].reset(RealDecl);
TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
if (const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
@@ -4205,8 +4208,8 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD,
else
break;
}
- ContainingType = getOrCreateType(QualType(PBase->getTypeForDecl(), 0),
- getOrCreateFile(RD->getLocation()));
+ CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
+ ContainingType = getOrCreateType(T, getOrCreateFile(RD->getLocation()));
} else if (RD->isDynamicClass())
ContainingType = RealDecl;
@@ -4412,9 +4415,10 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
// we would otherwise do to get a type for a pointee. (forward declarations in
// limited debug info, full definitions (if the type definition is available)
// in unlimited debug info)
- if (const auto *TD = dyn_cast<TypeDecl>(D))
- return getOrCreateType(CGM.getContext().getTypeDeclType(TD),
- getOrCreateFile(TD->getLocation()));
+ if (const auto *TD = dyn_cast<TypeDecl>(D)) {
+ QualType Ty = CGM.getContext().getTypeDeclType(TD);
+ return getOrCreateType(Ty, getOrCreateFile(TD->getLocation()));
+ }
auto I = DeclCache.find(D->getCanonicalDecl());
if (I != DeclCache.end()) {
@@ -5076,7 +5080,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
} else if (const auto *RT = dyn_cast<RecordType>(VD->getType())) {
// If VD is an anonymous union then Storage represents value for
// all union fields.
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isUnion() && RD->isAnonymousStructOrUnion()) {
// GDB has trouble finding local variables in anonymous unions, so we emit
// artificial local variables for each of the members.
@@ -5536,7 +5540,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
cast_or_null<CXXMethodDecl>(blockDecl->getNonClosureContext()))
type = Method->getThisType();
else if (auto *RDecl = dyn_cast<CXXRecordDecl>(blockDecl->getParent()))
- type = QualType(RDecl->getTypeForDecl(), 0);
+ type = CGM.getContext().getCanonicalTagType(RDecl);
else
llvm_unreachable("unexpected block declcontext");
@@ -5626,8 +5630,9 @@ llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
// Ignore unnamed fields, but recurse into anonymous records.
if (FieldName.empty()) {
if (const auto *RT = dyn_cast<RecordType>(Field->getType()))
- GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
- Var, DContext);
+ GVE =
+ CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(),
+ Unit, LineNo, LinkageName, Var, DContext);
continue;
}
// Use VarDecl's Tag, Scope and Line number.
@@ -5646,7 +5651,7 @@ static bool ReferencesAnonymousEntity(RecordType *RT) {
// But so long as it's not one of those, it doesn't matter if some sub-type
// of the record (a template parameter) can't be reconstituted - because the
// un-reconstitutable type itself will carry its own name.
- const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+ const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
if (!RD)
return false;
if (!RD->getIdentifier())
@@ -5705,15 +5710,15 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> {
}
return true;
}
- bool TraverseEnumType(EnumType *ET) {
+ bool TraverseEnumType(EnumType *ET, bool = false) {
// Unnamed enums can't be reconstituted due to a lack of column info we
// produce in the DWARF, so we can't get Clang's full name back.
- if (const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
+ if (const auto *ED = dyn_cast<EnumDecl>(ET->getOriginalDecl())) {
if (!ED->getIdentifier()) {
Reconstitutable = false;
return false;
}
- if (!ED->isExternallyVisible()) {
+ if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
Reconstitutable = false;
return false;
}
@@ -5726,7 +5731,7 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> {
Reconstitutable &= !FT->getNoReturnAttr();
return Reconstitutable;
}
- bool VisitRecordType(RecordType *RT) {
+ bool VisitRecordType(RecordType *RT, bool = false) {
if (ReferencesAnonymousEntity(RT)) {
Reconstitutable = false;
return false;
@@ -5909,7 +5914,8 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
// variable for each member of the anonymous union so that it's possible
// to find the name of any field in the union.
if (T->isUnionType() && DeclName.empty()) {
- const RecordDecl *RD = T->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ T->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
assert(RD->isAnonymousStructOrUnion() &&
"unnamed non-anonymous struct or union?");
GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
@@ -5956,8 +5962,6 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
if (const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
- assert(isa<EnumType>(ED->getTypeForDecl()) && "Enum without EnumType?");
-
if (CGM.getCodeGenOpts().EmitCodeView) {
// If CodeView, emit enums as global variables, unless they are defined
// inside a class. We do this because MSVC doesn't emit S_CONSTANTs for
@@ -5969,10 +5973,9 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
// If not CodeView, emit DW_TAG_enumeration_type if necessary. For
// example: for "enum { ZERO };", a DW_TAG_enumeration_type is created the
// first time `ZERO` is referenced in a function.
- llvm::DIType *EDTy =
- getOrCreateType(QualType(ED->getTypeForDecl(), 0), Unit);
- assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
- (void)EDTy;
+ CanQualType T = CGM.getContext().getCanonicalTagType(ED);
+ [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
+ assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
return;
}
}
@@ -5991,7 +5994,7 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
// FIXME: This is probably unnecessary, since Ty should reference RD
// through its scope.
RetainedTypes.push_back(
- CGM.getContext().getRecordType(RD).getAsOpaquePtr());
+ CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
return;
}