diff options
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 129 |
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; } |