diff options
Diffstat (limited to 'clang/lib')
140 files changed, 1010 insertions, 836 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a8b41ba..e403b3e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -563,8 +563,7 @@ comments::FullComment *ASTContext::getCommentForDecl( // does not have one of its own. QualType QT = TD->getUnderlyingType(); if (const auto *TT = QT->getAs<TagType>()) - if (comments::FullComment *FC = - getCommentForDecl(TT->getOriginalDecl(), PP)) + if (comments::FullComment *FC = getCommentForDecl(TT->getDecl(), PP)) return cloneFullComment(FC, D); } else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) { @@ -2387,7 +2386,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { case Type::Record: case Type::Enum: { const auto *TT = cast<TagType>(T); - const TagDecl *TD = TT->getOriginalDecl()->getDefinitionOrSelf(); + const TagDecl *TD = TT->getDecl()->getDefinitionOrSelf(); if (TD->isInvalidDecl()) { Width = 8; @@ -2531,7 +2530,7 @@ unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const { unsigned UnadjustedAlign; if (const auto *RT = T->getAsCanonical<RecordType>()) { - const ASTRecordLayout &Layout = getASTRecordLayout(RT->getOriginalDecl()); + const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl()); UnadjustedAlign = toBits(Layout.getUnadjustedAlignment()); } else if (const auto *ObjCI = T->getAsCanonical<ObjCInterfaceType>()) { const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); @@ -3469,7 +3468,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx, llvm_unreachable("should never get here"); } case Type::Record: { - const RecordDecl *RD = T->castAsCanonical<RecordType>()->getOriginalDecl(); + const RecordDecl *RD = T->castAsCanonical<RecordType>()->getDecl(); const IdentifierInfo *II = RD->getIdentifier(); // In C++, an immediate typedef of an anonymous struct or union @@ -5377,7 +5376,7 @@ TagType *ASTContext::getTagTypeInternal(ElaboratedTypeKeyword Keyword, }(); assert(T->getKeyword() == Keyword); assert(T->getQualifier() == Qualifier); - assert(T->getOriginalDecl() == TD); + assert(T->getDecl() == TD); assert(T->isInjected() == IsInjected); assert(T->isTagOwned() == OwnsTag); assert((T->isCanonicalUnqualified() @@ -8271,7 +8270,7 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const { static const Type *getIntegerTypeForEnum(const EnumType *ET) { // Incomplete enum types are not treated as integer types. // FIXME: In C++, enum types are never integer types. - const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf(); + const EnumDecl *ED = ET->getDecl()->getDefinitionOrSelf(); if (ED->isComplete() && !ED->isScoped()) return ED->getIntegerType().getTypePtr(); return nullptr; @@ -9189,7 +9188,7 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S, S += llvm::utostr(Offset); if (const auto *ET = T->getAsCanonical<EnumType>()) - S += ObjCEncodingForEnumDecl(Ctx, ET->getOriginalDecl()); + S += ObjCEncodingForEnumDecl(Ctx, ET->getDecl()); else { const auto *BT = T->castAs<BuiltinType>(); S += getObjCEncodingForPrimitiveType(Ctx, BT); @@ -9246,7 +9245,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, if (const auto *BT = dyn_cast<BuiltinType>(CT)) S += getObjCEncodingForPrimitiveType(this, BT); else - S += ObjCEncodingForEnumDecl(this, cast<EnumType>(CT)->getOriginalDecl()); + S += ObjCEncodingForEnumDecl(this, cast<EnumType>(CT)->getDecl()); return; case Type::Complex: @@ -9314,7 +9313,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, return; } } else if (const auto *RTy = PointeeTy->getAsCanonical<RecordType>()) { - const IdentifierInfo *II = RTy->getOriginalDecl()->getIdentifier(); + const IdentifierInfo *II = RTy->getDecl()->getIdentifier(); // GCC binary compat: Need to convert "struct objc_class *" to "#". if (II == &Idents.get("objc_class")) { S += '#'; @@ -9386,7 +9385,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, return; case Type::Record: { - RecordDecl *RDecl = cast<RecordType>(CT)->getOriginalDecl(); + RecordDecl *RDecl = cast<RecordType>(CT)->getDecl(); S += RDecl->isUnion() ? '(' : '{'; // Anonymous structures print as '?' if (const IdentifierInfo *II = RDecl->getIdentifier()) { @@ -11290,7 +11289,7 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType, bool OfBlockPointer, bool Unqualified) { if (const RecordType *UT = T->getAsUnionType()) { - RecordDecl *UD = UT->getOriginalDecl()->getMostRecentDecl(); + RecordDecl *UD = UT->getDecl()->getMostRecentDecl(); if (UD->hasAttr<TransparentUnionAttr>()) { for (const auto *I : UD->fields()) { QualType ET = I->getType().getUnqualifiedType(); @@ -11560,7 +11559,7 @@ static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET, // Compatibility is based on the underlying type, not the promotion // type. QualType underlyingType = - ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + ET->getDecl()->getDefinitionOrSelf()->getIntegerType(); if (underlyingType.isNull()) return {}; if (Context.hasSameType(underlyingType, other)) @@ -11581,6 +11580,12 @@ QualType ASTContext::mergeTagDefinitions(QualType LHS, QualType RHS) { if (LangOpts.CPlusPlus || !LangOpts.C23) return {}; + // Nameless tags are comparable only within outer definitions. At the top + // level they are not comparable. + const TagDecl *LTagD = LHS->castAsTagDecl(), *RTagD = RHS->castAsTagDecl(); + if (!LTagD->getIdentifier() || !RTagD->getIdentifier()) + return {}; + // C23, on the other hand, requires the members to be "the same enough", so // we use a structural equivalence check. StructuralEquivalenceContext::NonEquivalentDeclSet NonEquivalentDecls; @@ -14154,11 +14159,10 @@ static QualType getCommonNonSugarTypeNode(const ASTContext &Ctx, const Type *X, case Type::Record: case Type::InjectedClassName: { const auto *TX = cast<TagType>(X), *TY = cast<TagType>(Y); - return Ctx.getTagType( - ::getCommonTypeKeyword(TX, TY, /*IsSame=*/false), - ::getCommonQualifier(Ctx, TX, TY, /*IsSame=*/false), - ::getCommonDeclChecked(TX->getOriginalDecl(), TY->getOriginalDecl()), - /*OwnedTag=*/false); + return Ctx.getTagType(::getCommonTypeKeyword(TX, TY, /*IsSame=*/false), + ::getCommonQualifier(Ctx, TX, TY, /*IsSame=*/false), + ::getCommonDeclChecked(TX->getDecl(), TY->getDecl()), + /*OwnedTag=*/false); } case Type::TemplateSpecialization: { const auto *TX = cast<TemplateSpecializationType>(X), diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index d7fd411..b8023cb 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -196,8 +196,7 @@ break; \ // Don't desugar through the primary typedef of an anonymous type. if (const TagType *UTT = Underlying->getAs<TagType>()) if (const TypedefType *QTT = dyn_cast<TypedefType>(QT)) - if (UTT->getOriginalDecl()->getTypedefNameForAnonDecl() == - QTT->getDecl()) + if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl()) break; // Record that we actually looked through an opaque type here. @@ -1147,14 +1146,11 @@ class TemplateDiff { if (const auto* SubstType = Ty->getAs<SubstTemplateTypeParmType>()) Ty = SubstType->getReplacementType(); - const RecordType *RT = Ty->getAs<RecordType>(); - + const auto *RT = Ty->getAs<RecordType>(); if (!RT) return nullptr; - const ClassTemplateSpecializationDecl *CTSD = - dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl()); - + const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); if (!CTSD) return nullptr; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index f43fa8c..bf51c3e 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1740,7 +1740,7 @@ ExpectedType ASTNodeImporter::VisitDeducedTemplateSpecializationType( } ExpectedType ASTNodeImporter::VisitTagType(const TagType *T) { - TagDecl *DeclForType = T->getOriginalDecl(); + TagDecl *DeclForType = T->getDecl(); Expected<TagDecl *> ToDeclOrErr = import(DeclForType); if (!ToDeclOrErr) return ToDeclOrErr.takeError(); @@ -2155,7 +2155,7 @@ Error ASTNodeImporter::ImportDeclParts( const Type *LeafT = getLeafPointeeType(P->getType().getCanonicalType().getTypePtr()); auto *RT = dyn_cast<RecordType>(LeafT); - if (RT && RT->getOriginalDecl() == D) { + if (RT && RT->getDecl() == D) { Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node) << D->getDeclKindName(); return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct); @@ -2408,8 +2408,8 @@ Error ASTNodeImporter::ImportFieldDeclDefinition(const FieldDecl *From, const RecordType *RecordTo = ToType->getAs<RecordType>(); if (RecordFrom && RecordTo) { - FromRecordDecl = RecordFrom->getOriginalDecl(); - ToRecordDecl = RecordTo->getOriginalDecl(); + FromRecordDecl = RecordFrom->getDecl(); + ToRecordDecl = RecordTo->getDecl(); } } @@ -3205,7 +3205,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { if (auto *Typedef = dyn_cast<TypedefNameDecl>(FoundDecl)) { if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>()) - FoundDecl = Tag->getOriginalDecl(); + FoundDecl = Tag->getDecl(); } if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) { @@ -3336,7 +3336,7 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { Decl *Found = FoundDecl; if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) { if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>()) - Found = Tag->getOriginalDecl(); + Found = Tag->getDecl(); } if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) { @@ -3757,12 +3757,11 @@ public: } std::optional<bool> VisitTagType(const TagType *T) { - if (auto *Spec = - dyn_cast<ClassTemplateSpecializationDecl>(T->getOriginalDecl())) + if (auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) for (const auto &Arg : Spec->getTemplateArgs().asArray()) if (checkTemplateArgument(Arg)) return true; - return isAncestorDeclContextOf(ParentDC, T->getOriginalDecl()); + return isAncestorDeclContextOf(ParentDC, T->getDecl()); } std::optional<bool> VisitPointerType(const PointerType *T) { diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp index 1557346..da64c92 100644 --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -878,10 +878,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, // Treat the enumeration as its underlying type and use the builtin type // class comparison. if (T1->getTypeClass() == Type::Enum) { - T1 = cast<EnumType>(T1)->getOriginalDecl()->getIntegerType(); + T1 = cast<EnumType>(T1)->getDecl()->getIntegerType(); assert(T2->isBuiltinType() && !T1.isNull()); // Sanity check } else if (T2->getTypeClass() == Type::Enum) { - T2 = cast<EnumType>(T2)->getOriginalDecl()->getIntegerType(); + T2 = cast<EnumType>(T2)->getDecl()->getIntegerType(); assert(T1->isBuiltinType() && !T2.isNull()); // Sanity check } TC = Type::Builtin; @@ -1300,8 +1300,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, if (!IsStructurallyEquivalent(Context, TT1->getQualifier(), TT2->getQualifier())) return false; - if (!IsStructurallyEquivalent(Context, TT1->getOriginalDecl(), - TT2->getOriginalDecl())) + if (!IsStructurallyEquivalent(Context, TT1->getDecl(), TT2->getDecl())) return false; break; } @@ -1531,8 +1530,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, // types if (Field1->isAnonymousStructOrUnion() && Field2->isAnonymousStructOrUnion()) { - RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getOriginalDecl(); - RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getOriginalDecl(); + RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl(); + RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl(); return IsStructurallyEquivalent(Context, D1, D2); } @@ -1763,19 +1762,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, // another anonymous structure or union, respectively, if their members // fulfill the preceding requirements. ... Otherwise, the structure, union, // or enumerated types are incompatible. - - // Note: "the same tag" refers to the identifier for the structure; two - // structures without names are not compatible within a TU. In C23, if either - // declaration has no name, they're not equivalent. However, the paragraph - // after the bulleted list goes on to talk about compatibility of anonymous - // structure and union members, so this prohibition only applies to top-level - // declarations; if either declaration is not a member, they cannot be - // compatible. - if (Context.LangOpts.C23 && (!D1->getIdentifier() || !D2->getIdentifier()) && - (!D1->getDeclContext()->isRecord() || !D2->getDeclContext()->isRecord())) - return false; - - // Otherwise, check the names for equivalence. if (!NameIsStructurallyEquivalent(*D1, *D2)) return false; @@ -2600,7 +2586,7 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) { // struct { ... } A; QualType FieldType = F->getType(); if (const auto *RecType = dyn_cast<RecordType>(FieldType)) { - const RecordDecl *RecDecl = RecType->getOriginalDecl(); + const RecordDecl *RecDecl = RecType->getDecl(); if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) { if (Context.hasSameType(FieldType, AnonTy)) break; diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index c71fd22..74cae03 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -4660,7 +4660,7 @@ const RecordType *Compiler<Emitter>::getRecordTy(QualType Ty) { template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) { if (const auto *RecordTy = getRecordTy(Ty)) - return getRecord(RecordTy->getOriginalDecl()->getDefinitionOrSelf()); + return getRecord(RecordTy->getDecl()->getDefinitionOrSelf()); return nullptr; } diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 2d3cb6a..b69f360 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2790,6 +2790,34 @@ static bool interp__builtin_blend(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_ia32_pshufb(InterpState &S, CodePtr OpPC, + const CallExpr *Call) { + assert(Call->getNumArgs() == 2 && "masked forms handled via select*"); + const Pointer &Control = S.Stk.pop<Pointer>(); + const Pointer &Src = S.Stk.pop<Pointer>(); + const Pointer &Dst = S.Stk.peek<Pointer>(); + + unsigned NumElems = Dst.getNumElems(); + assert(NumElems == Control.getNumElems()); + assert(NumElems == Dst.getNumElems()); + + for (unsigned Idx = 0; Idx != NumElems; ++Idx) { + uint8_t Ctlb = static_cast<uint8_t>(Control.elem<int8_t>(Idx)); + + if (Ctlb & 0x80) { + Dst.elem<int8_t>(Idx) = 0; + } else { + unsigned LaneBase = (Idx / 16) * 16; + unsigned SrcOffset = Ctlb & 0x0F; + unsigned SrcIdx = LaneBase + SrcOffset; + + Dst.elem<int8_t>(Idx) = Src.elem<int8_t>(SrcIdx); + } + } + Dst.initializeAllElements(); + return true; +} + static bool interp__builtin_ia32_pshuf(InterpState &S, CodePtr OpPC, const CallExpr *Call, bool IsShufHW) { assert(Call->getNumArgs() == 2 && "masked forms handled via select*"); @@ -3943,6 +3971,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, case X86::BI__builtin_ia32_selectpd_512: return interp__builtin_select(S, OpPC, Call); + case X86::BI__builtin_ia32_pshufb128: + case X86::BI__builtin_ia32_pshufb256: + case X86::BI__builtin_ia32_pshufb512: + return interp__builtin_ia32_pshufb(S, OpPC, Call); + case X86::BI__builtin_ia32_pshuflw: case X86::BI__builtin_ia32_pshuflw256: case X86::BI__builtin_ia32_pshuflw512: diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h index a13244b..e2e4d5c 100644 --- a/clang/lib/AST/ByteCode/InterpState.h +++ b/clang/lib/AST/ByteCode/InterpState.h @@ -114,7 +114,7 @@ public: Alloc = std::make_unique<DynamicAllocator>(); } - return *Alloc.get(); + return *Alloc; } /// Diagnose any dynamic allocations that haven't been freed yet. diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 663134c..e417bdf 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -751,7 +751,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx, assert(Record && "Missing record descriptor"); bool Ok = true; - if (RT->getOriginalDecl()->isUnion()) { + if (RT->getDecl()->isUnion()) { const FieldDecl *ActiveField = nullptr; APValue Value; for (const auto &F : Record->fields()) { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 69cbf6e..f048076 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2989,10 +2989,7 @@ bool ParmVarDecl::isDestroyedInCallee() const { // FIXME: isParamDestroyedInCallee() should probably imply // isDestructedType() const auto *RT = getType()->getAsCanonical<RecordType>(); - if (RT && - RT->getOriginalDecl() - ->getDefinitionOrSelf() - ->isParamDestroyedInCallee() && + if (RT && RT->getDecl()->getDefinitionOrSelf()->isParamDestroyedInCallee() && getType().isDestructedType()) return true; @@ -3507,7 +3504,7 @@ bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation( while (const auto *TD = T->getAs<TypedefType>()) T = TD->getDecl()->getUnderlyingType(); const IdentifierInfo *II = - T->castAsCanonical<EnumType>()->getOriginalDecl()->getIdentifier(); + T->castAsCanonical<EnumType>()->getDecl()->getIdentifier(); if (II && II->isStr("__hot_cold_t")) Consume(); } @@ -4709,7 +4706,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const { return false; if (const auto *Record = getType()->getAsCanonical<RecordType>()) - return Record->getOriginalDecl()->isAnonymousStructOrUnion(); + return Record->getDecl()->isAnonymousStructOrUnion(); return false; } @@ -4769,7 +4766,7 @@ bool FieldDecl::isZeroSize(const ASTContext &Ctx) const { const auto *RT = getType()->getAsCanonical<RecordType>(); if (!RT) return false; - const RecordDecl *RD = RT->getOriginalDecl()->getDefinition(); + const RecordDecl *RD = RT->getDecl()->getDefinition(); if (!RD) { assert(isInvalidDecl() && "valid field has incomplete type"); return false; @@ -5194,7 +5191,7 @@ bool RecordDecl::isOrContainsUnion() const { if (const RecordDecl *Def = getDefinition()) { for (const FieldDecl *FD : Def->fields()) { const RecordType *RT = FD->getType()->getAsCanonical<RecordType>(); - if (RT && RT->getOriginalDecl()->isOrContainsUnion()) + if (RT && RT->getDecl()->isOrContainsUnion()) return true; } } @@ -5692,14 +5689,14 @@ void TypedefNameDecl::anchor() {} TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const { if (auto *TT = getTypeSourceInfo()->getType()->getAs<TagType>()) { - auto *OwningTypedef = TT->getOriginalDecl()->getTypedefNameForAnonDecl(); + auto *OwningTypedef = TT->getDecl()->getTypedefNameForAnonDecl(); auto *ThisTypedef = this; if (AnyRedecl && OwningTypedef) { OwningTypedef = OwningTypedef->getCanonicalDecl(); ThisTypedef = ThisTypedef->getCanonicalDecl(); } if (OwningTypedef == ThisTypedef) - return TT->getOriginalDecl()->getDefinitionOrSelf(); + return TT->getDecl()->getDefinitionOrSelf(); } return nullptr; @@ -5708,7 +5705,7 @@ TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const { bool TypedefNameDecl::isTransparentTagSlow() const { auto determineIsTransparent = [&]() { if (auto *TT = getUnderlyingType()->getAs<TagType>()) { - if (auto *TD = TT->getOriginalDecl()) { + if (auto *TD = TT->getDecl()) { if (TD->getName() != getName()) return false; SourceLocation TTLoc = getLocation(); diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index b244f0a..30c6d3e 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -77,8 +77,11 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, *PrefixPtr = ID.getRawValue(); // We leave the upper 16 bits to store the module IDs. 48 bits should be - // sufficient to store a declaration ID. - assert(*PrefixPtr < llvm::maskTrailingOnes<uint64_t>(48)); + // sufficient to store a declaration ID. See the comments in setOwningModuleID + // for details. + assert((*PrefixPtr < llvm::maskTrailingOnes<uint64_t>(48)) && + "Current Implementation limits the number of module files to not " + "exceed 2^16. Contact Clang Developers to remove the limitation."); return Result; } @@ -122,6 +125,25 @@ unsigned Decl::getOwningModuleID() const { void Decl::setOwningModuleID(unsigned ID) { assert(isFromASTFile() && "Only works on a deserialized declaration"); + // Currently, we use 64 bits to store the GlobalDeclID and the module ID + // to save the space. See `Decl::operator new` for details. To make it, + // we split the higher 32 bits to 2 16bits for the module file index of + // GlobalDeclID and the module ID. This introduces a limitation that the + // number of modules can't exceed 2^16. (The number of module files should be + // less than the number of modules). + // + // It is counter-intuitive to store both the module file index and the + // module ID as it seems redundant. However, this is not true. + // The module ID may be different from the module file where it is serialized + // from for implicit template instantiations. See + // https://github.com/llvm/llvm-project/issues/101939 + // + // If we reach the limitation, we have to remove the limitation by asking + // every deserialized declaration to pay for yet another 32 bits, or we have + // to review the above issue to decide what we should do for it. + assert((ID < llvm::maskTrailingOnes<unsigned>(16)) && + "Current Implementation limits the number of modules to not exceed " + "2^16. Contact Clang Developers to remove the limitation."); uint64_t *IDAddress = (uint64_t *)this - 1; *IDAddress &= llvm::maskTrailingOnes<uint64_t>(48); *IDAddress |= (uint64_t)ID << 48; diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 43264f8..24e4f18 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2314,7 +2314,7 @@ bool CXXRecordDecl::mayBeAbstract() const { for (const auto &B : bases()) { const auto *BaseDecl = cast<CXXRecordDecl>( - B.getType()->castAsCanonical<RecordType>()->getOriginalDecl()); + B.getType()->castAsCanonical<RecordType>()->getDecl()); if (BaseDecl->isAbstract()) return true; } diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index 7f3dcca..47ae613 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -485,7 +485,7 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { QualType BaseType = GetBaseType(CurDeclType); if (const auto *TT = dyn_cast_or_null<TagType>(BaseType); TT && TT->isTagOwned()) { - if (TT->getOriginalDecl() == Decls[0]) { + if (TT->getDecl() == Decls[0]) { Decls.push_back(*D); continue; } diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp index 55f5a99..9a89a66 100644 --- a/clang/lib/AST/DeclarationName.cpp +++ b/clang/lib/AST/DeclarationName.cpp @@ -116,12 +116,12 @@ static void printCXXConstructorDestructorName(QualType ClassType, Policy.SuppressScope = true; if (const RecordType *ClassRec = ClassType->getAsCanonical<RecordType>()) { - ClassRec->getOriginalDecl()->printName(OS, Policy); + ClassRec->getDecl()->printName(OS, Policy); return; } if (Policy.SuppressTemplateArgsInCXXConstructors) { if (auto *InjTy = ClassType->getAsCanonical<InjectedClassNameType>()) { - InjTy->getOriginalDecl()->printName(OS, Policy); + InjTy->getDecl()->printName(OS, Policy); return; } } @@ -185,7 +185,7 @@ void DeclarationName::print(raw_ostream &OS, OS << "operator "; QualType Type = getCXXNameType(); if (const RecordType *Rec = Type->getAs<RecordType>()) { - OS << *Rec->getOriginalDecl(); + OS << *Rec->getDecl(); return; } // We know we're printing C++ here, ensure we print 'bool' properly. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 597cbd8..340bb4b 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -4126,9 +4126,7 @@ Expr::isNullPointerConstant(ASTContext &Ctx, if (const RecordType *UT = getType()->getAsUnionType()) if (!Ctx.getLangOpts().CPlusPlus11 && UT && - UT->getOriginalDecl() - ->getMostRecentDecl() - ->hasAttr<TransparentUnionAttr>()) + UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){ const Expr *InitExpr = CLE->getInitializer(); if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr)) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 51c0382..a07eb22 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -4074,8 +4074,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, } // Next subobject is a class, struct or union field. - RecordDecl *RD = - ObjType->castAsCanonical<RecordType>()->getOriginalDecl(); + RecordDecl *RD = ObjType->castAsCanonical<RecordType>()->getDecl(); if (RD->isUnion()) { const FieldDecl *UnionField = O->getUnionField(); if (!UnionField || @@ -7810,7 +7809,7 @@ class BufferToAPValueConverter { std::optional<APValue> visit(const EnumType *Ty, CharUnits Offset) { QualType RepresentationType = - Ty->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(); + Ty->getDecl()->getDefinitionOrSelf()->getIntegerType(); assert(!RepresentationType.isNull() && "enum forward decl should be caught by Sema"); const auto *AsBuiltin = @@ -8607,7 +8606,7 @@ public: const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); if (!FD) return Error(E); assert(!FD->getType()->isReferenceType() && "prvalue reference?"); - assert(BaseTy->castAsCanonical<RecordType>()->getOriginalDecl() == + assert(BaseTy->castAsCanonical<RecordType>()->getDecl() == FD->getParent()->getCanonicalDecl() && "record / field mismatch"); @@ -8836,7 +8835,7 @@ public: const ValueDecl *MD = E->getMemberDecl(); if (const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) { - assert(BaseTy->castAsCanonical<RecordType>()->getOriginalDecl() == + assert(BaseTy->castAsCanonical<RecordType>()->getDecl() == FD->getParent()->getCanonicalDecl() && "record / field mismatch"); (void)BaseTy; @@ -11619,6 +11618,44 @@ static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result, return true; } +static bool evalPshufbBuiltin(EvalInfo &Info, const CallExpr *Call, + APValue &Out) { + APValue SrcVec, ControlVec; + if (!EvaluateAsRValue(Info, Call->getArg(0), SrcVec)) + return false; + if (!EvaluateAsRValue(Info, Call->getArg(1), ControlVec)) + return false; + + const auto *VT = Call->getType()->getAs<VectorType>(); + if (!VT) + return false; + + QualType ElemT = VT->getElementType(); + unsigned NumElts = VT->getNumElements(); + + SmallVector<APValue, 64> ResultElements; + ResultElements.reserve(NumElts); + + for (unsigned Idx = 0; Idx != NumElts; ++Idx) { + APValue CtlVal = ControlVec.getVectorElt(Idx); + APSInt CtlByte = CtlVal.getInt(); + uint8_t Ctl = static_cast<uint8_t>(CtlByte.getZExtValue()); + + if (Ctl & 0x80) { + APValue Zero(Info.Ctx.MakeIntValue(0, ElemT)); + ResultElements.push_back(Zero); + } else { + unsigned LaneBase = (Idx / 16) * 16; + unsigned SrcOffset = Ctl & 0x0F; + unsigned SrcIdx = LaneBase + SrcOffset; + + ResultElements.push_back(SrcVec.getVectorElt(SrcIdx)); + } + } + Out = APValue(ResultElements.data(), ResultElements.size()); + return true; +} + static bool evalPshufBuiltin(EvalInfo &Info, const CallExpr *Call, bool IsShufHW, APValue &Out) { APValue Vec; @@ -12241,6 +12278,15 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { return Success(APValue(ResultElements.data(), ResultElements.size()), E); } + case X86::BI__builtin_ia32_pshufb128: + case X86::BI__builtin_ia32_pshufb256: + case X86::BI__builtin_ia32_pshufb512: { + APValue R; + if (!evalPshufbBuiltin(Info, E, R)) + return false; + return Success(R, E); + } + case X86::BI__builtin_ia32_pshuflw: case X86::BI__builtin_ia32_pshuflw256: case X86::BI__builtin_ia32_pshuflw512: { diff --git a/clang/lib/AST/InheritViz.cpp b/clang/lib/AST/InheritViz.cpp index 3c4a5a8..c5f4c2b 100644 --- a/clang/lib/AST/InheritViz.cpp +++ b/clang/lib/AST/InheritViz.cpp @@ -89,8 +89,8 @@ void InheritanceHierarchyWriter::WriteNode(QualType Type, bool FromVirtual) { Out << " \"];\n"; // Display the base classes. - const auto *Decl = cast<CXXRecordDecl>( - Type->castAsCanonical<RecordType>()->getOriginalDecl()); + const auto *Decl = + cast<CXXRecordDecl>(Type->castAsCanonical<RecordType>()->getDecl()); for (const auto &Base : Decl->bases()) { QualType CanonBaseType = Context.getCanonicalType(Base.getType()); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 844db79..5572e0a 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2491,7 +2491,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, case Type::Enum: case Type::Record: mangleSourceNameWithAbiTags( - cast<TagType>(Ty)->getOriginalDecl()->getDefinitionOrSelf()); + cast<TagType>(Ty)->getDecl()->getDefinitionOrSelf()); break; case Type::TemplateSpecialization: { @@ -2556,9 +2556,8 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty, } case Type::InjectedClassName: - mangleSourceNameWithAbiTags(cast<InjectedClassNameType>(Ty) - ->getOriginalDecl() - ->getDefinitionOrSelf()); + mangleSourceNameWithAbiTags( + cast<InjectedClassNameType>(Ty)->getDecl()->getDefinitionOrSelf()); break; case Type::DependentName: @@ -3795,7 +3794,7 @@ void CXXNameMangler::mangleType(const RecordType *T) { mangleType(static_cast<const TagType*>(T)); } void CXXNameMangler::mangleType(const TagType *T) { - mangleName(T->getOriginalDecl()->getDefinitionOrSelf()); + mangleName(T->getDecl()->getDefinitionOrSelf()); } // <type> ::= <array-type> @@ -4430,8 +4429,8 @@ void CXXNameMangler::mangleType(const InjectedClassNameType *T) { // Mangle injected class name types as if the user had written the // specialization out fully. It may not actually be possible to see // this mangling, though. - mangleType(T->getOriginalDecl()->getCanonicalTemplateSpecializationType( - getASTContext())); + mangleType( + T->getDecl()->getCanonicalTemplateSpecializationType(getASTContext())); } void CXXNameMangler::mangleType(const TemplateSpecializationType *T) { @@ -4692,7 +4691,7 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T, void CXXNameMangler::mangleMemberExprBase(const Expr *Base, bool IsArrow) { // Ignore member expressions involving anonymous unions. while (const auto *RT = Base->getType()->getAsCanonical<RecordType>()) { - if (!RT->getOriginalDecl()->isAnonymousStructOrUnion()) + if (!RT->getDecl()->isAnonymousStructOrUnion()) break; const auto *ME = dyn_cast<MemberExpr>(Base); if (!ME) @@ -7010,8 +7009,7 @@ bool CXXNameMangler::isSpecializedAs(QualType S, llvm::StringRef Name, if (!RT) return false; - const ClassTemplateSpecializationDecl *SD = - dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl()); + const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); if (!SD || !SD->getIdentifier()->isStr(Name)) return false; diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 0ef6328..9f4dba9 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -396,7 +396,7 @@ llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) { for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) { const CXXBaseSpecifier *Base = *I; const auto *RD = cast<CXXRecordDecl>( - Base->getType()->castAsCanonical<RecordType>()->getOriginalDecl()); + Base->getType()->castAsCanonical<RecordType>()->getDecl()); llvm::json::Object Val{{"name", RD->getName()}}; if (Base->isVirtual()) @@ -764,7 +764,7 @@ void JSONNodeDumper::VisitTagType(const TagType *TT) { Qualifier.print(OS, PrintPolicy, /*ResolveTemplateArguments=*/true); JOS.attribute("qualifier", Str); } - JOS.attribute("decl", createBareDeclRef(TT->getOriginalDecl())); + JOS.attribute("decl", createBareDeclRef(TT->getDecl())); if (TT->isTagOwned()) JOS.attribute("isTagOwned", true); } @@ -816,7 +816,7 @@ void JSONNodeDumper::VisitTemplateSpecializationType( void JSONNodeDumper::VisitInjectedClassNameType( const InjectedClassNameType *ICNT) { - JOS.attribute("decl", createBareDeclRef(ICNT->getOriginalDecl())); + JOS.attribute("decl", createBareDeclRef(ICNT->getDecl())); } void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *OIT) { diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 8cbc72b..f1baf9f 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -3248,11 +3248,11 @@ void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) { } void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers, SourceRange) { - mangleType(cast<TagType>(T)->getOriginalDecl()); + mangleType(cast<TagType>(T)->getDecl()); } void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers, SourceRange) { - mangleType(cast<TagType>(T)->getOriginalDecl()); + mangleType(cast<TagType>(T)->getDecl()); } void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) { // MSVC chooses the tag kind of the definition if it exists, otherwise it diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 6842038..46a4e25 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -913,7 +913,7 @@ public: return false; if (TypedefT->getDecl()->getIdentifier() != - TagT->getOriginalDecl()->getIdentifier()) + TagT->getDecl()->getIdentifier()) return false; ID.AddInteger(TagT->getTypeClass()); @@ -1059,7 +1059,7 @@ public: } void VisitInjectedClassNameType(const InjectedClassNameType *T) { - AddDecl(T->getOriginalDecl()->getDefinitionOrSelf()); + AddDecl(T->getDecl()->getDefinitionOrSelf()); VisitType(T); } @@ -1164,7 +1164,7 @@ public: AddNestedNameSpecifier(ElaboratedOverride ? ElaboratedOverride->getQualifier() : T->getQualifier()); - AddDecl(T->getOriginalDecl()->getDefinitionOrSelf()); + AddDecl(T->getDecl()->getDefinitionOrSelf()); VisitType(T); } diff --git a/clang/lib/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp index acc011c..7138dff 100644 --- a/clang/lib/AST/ParentMapContext.cpp +++ b/clang/lib/AST/ParentMapContext.cpp @@ -20,36 +20,6 @@ using namespace clang; -ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {} - -ParentMapContext::~ParentMapContext() = default; - -void ParentMapContext::clear() { Parents.reset(); } - -const Expr *ParentMapContext::traverseIgnored(const Expr *E) const { - return traverseIgnored(const_cast<Expr *>(E)); -} - -Expr *ParentMapContext::traverseIgnored(Expr *E) const { - if (!E) - return nullptr; - - switch (Traversal) { - case TK_AsIs: - return E; - case TK_IgnoreUnlessSpelledInSource: - return E->IgnoreUnlessSpelledInSource(); - } - llvm_unreachable("Invalid Traversal type!"); -} - -DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const { - if (const auto *E = N.get<Expr>()) { - return DynTypedNode::create(*traverseIgnored(E)); - } - return N; -} - template <typename T, typename... U> static std::tuple<bool, DynTypedNodeList, const T *, const U *...> matchParents(const DynTypedNodeList &NodeList, @@ -334,6 +304,36 @@ matchParents(const DynTypedNodeList &NodeList, return MatchParents<T, U...>::match(NodeList, ParentMap); } +ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {} + +ParentMapContext::~ParentMapContext() = default; + +void ParentMapContext::clear() { Parents.reset(); } + +const Expr *ParentMapContext::traverseIgnored(const Expr *E) const { + return traverseIgnored(const_cast<Expr *>(E)); +} + +Expr *ParentMapContext::traverseIgnored(Expr *E) const { + if (!E) + return nullptr; + + switch (Traversal) { + case TK_AsIs: + return E; + case TK_IgnoreUnlessSpelledInSource: + return E->IgnoreUnlessSpelledInSource(); + } + llvm_unreachable("Invalid Traversal type!"); +} + +DynTypedNode ParentMapContext::traverseIgnored(const DynTypedNode &N) const { + if (const auto *E = N.get<Expr>()) { + return DynTypedNode::create(*traverseIgnored(E)); + } + return N; +} + /// Template specializations to abstract away from pointers and TypeLocs. /// @{ template <typename T> static DynTypedNode createDynTypedNode(const T &Node) { diff --git a/clang/lib/AST/QualTypeNames.cpp b/clang/lib/AST/QualTypeNames.cpp index a2f9309..1918416 100644 --- a/clang/lib/AST/QualTypeNames.cpp +++ b/clang/lib/AST/QualTypeNames.cpp @@ -125,7 +125,7 @@ static const Type *getFullyQualifiedTemplateType(const ASTContext &Ctx, // which can point to a template instantiation with no sugar in any of // its template argument, however we still need to fully qualify them. - const auto *TD = TSTRecord->getOriginalDecl(); + const auto *TD = TSTRecord->getDecl(); const auto *TSTDecl = dyn_cast<ClassTemplateSpecializationDecl>(TD); if (!TSTDecl) return Ctx.getTagType(Keyword, Qualifier, TD, /*OwnsTag=*/false) @@ -232,7 +232,7 @@ static NestedNameSpecifier getFullyQualifiedNestedNameSpecifier( // Find decl context. const TypeDecl *TD; if (const TagType *TagDeclType = Type->getAs<TagType>()) - TD = TagDeclType->getOriginalDecl(); + TD = TagDeclType->getDecl(); else if (const auto *D = dyn_cast<TypedefType>(Type)) TD = D->getDecl(); else @@ -316,7 +316,7 @@ createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Type *TypePtr, if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) { Decl = TDT->getDecl(); } else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) { - Decl = TagDeclType->getOriginalDecl(); + Decl = TagDeclType->getDecl(); } else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) { Decl = TST->getTemplateName().getAsTemplateDecl(); } else { diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 00b938b..ac18d4d 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2009,7 +2009,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, } else if (const BuiltinType *BTy = BaseTy->getAs<BuiltinType>()) { performBuiltinTypeAlignmentUpgrade(BTy); } else if (const RecordType *RT = BaseTy->getAsCanonical<RecordType>()) { - const RecordDecl *RD = RT->getOriginalDecl(); + const RecordDecl *RD = RT->getDecl(); const ASTRecordLayout &FieldRecord = Context.getASTRecordLayout(RD); PreferredAlign = FieldRecord.getPreferredAlignment(); } @@ -2710,7 +2710,7 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( if (const auto *RT = FD->getType() ->getBaseElementTypeUnsafe() ->getAsCanonical<RecordType>()) { - auto const &Layout = Context.getASTRecordLayout(RT->getOriginalDecl()); + auto const &Layout = Context.getASTRecordLayout(RT->getDecl()); EndsWithZeroSizedObject = Layout.endsWithZeroSizedObject(); FieldRequiredAlignment = std::max(FieldRequiredAlignment, Layout.getRequiredAlignment()); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index cf5e914..41aebdb 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1401,7 +1401,7 @@ static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { OS << " -> "; const auto *RD = cast<CXXRecordDecl>( - Base->getType()->castAsCanonical<RecordType>()->getOriginalDecl()); + Base->getType()->castAsCanonical<RecordType>()->getDecl()); if (Base->isVirtual()) OS << "virtual "; @@ -2180,7 +2180,7 @@ void TextNodeDumper::VisitTagType(const TagType *T) { K != ElaboratedTypeKeyword::None) OS << ' ' << TypeWithKeyword::getKeywordName(K); dumpNestedNameSpecifier(T->getQualifier()); - dumpDeclRef(T->getOriginalDecl()); + dumpDeclRef(T->getDecl()); } void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { @@ -2232,7 +2232,7 @@ void TextNodeDumper::VisitTemplateSpecializationType( void TextNodeDumper::VisitInjectedClassNameType( const InjectedClassNameType *T) { - dumpDeclRef(T->getOriginalDecl()); + dumpDeclRef(T->getDecl()); } void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) { diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index ee7a68e..4548af1 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -114,7 +114,7 @@ const IdentifierInfo *QualType::getBaseTypeIdentifier() const { if (ty->isPointerOrReferenceType()) return ty->getPointeeType().getBaseTypeIdentifier(); if (const auto *TT = ty->getAs<TagType>()) - ND = TT->getOriginalDecl(); + ND = TT->getDecl(); else if (ty->getTypeClass() == Type::Typedef) ND = ty->castAs<TypedefType>()->getDecl(); else if (ty->isArrayType()) @@ -671,13 +671,13 @@ const Type *Type::getUnqualifiedDesugaredType() const { bool Type::isClassType() const { if (const auto *RT = getAsCanonical<RecordType>()) - return RT->getOriginalDecl()->isClass(); + return RT->getDecl()->isClass(); return false; } bool Type::isStructureType() const { if (const auto *RT = getAsCanonical<RecordType>()) - return RT->getOriginalDecl()->isStruct(); + return RT->getDecl()->isStruct(); return false; } @@ -685,7 +685,7 @@ bool Type::isStructureTypeWithFlexibleArrayMember() const { const auto *RT = getAsCanonical<RecordType>(); if (!RT) return false; - const auto *Decl = RT->getOriginalDecl(); + const auto *Decl = RT->getDecl(); if (!Decl->isStruct()) return false; return Decl->getDefinitionOrSelf()->hasFlexibleArrayMember(); @@ -699,13 +699,13 @@ bool Type::isObjCBoxableRecordType() const { bool Type::isInterfaceType() const { if (const auto *RT = getAsCanonical<RecordType>()) - return RT->getOriginalDecl()->isInterface(); + return RT->getDecl()->isInterface(); return false; } bool Type::isStructureOrClassType() const { if (const auto *RT = getAsCanonical<RecordType>()) - return RT->getOriginalDecl()->isStructureOrClass(); + return RT->getDecl()->isStructureOrClass(); return false; } @@ -717,7 +717,7 @@ bool Type::isVoidPointerType() const { bool Type::isUnionType() const { if (const auto *RT = getAsCanonical<RecordType>()) - return RT->getOriginalDecl()->isUnion(); + return RT->getDecl()->isUnion(); return false; } @@ -734,7 +734,7 @@ bool Type::isComplexIntegerType() const { bool Type::isScopedEnumeralType() const { if (const auto *ET = getAsCanonical<EnumType>()) - return ET->getOriginalDecl()->isScoped(); + return ET->getDecl()->isScoped(); return false; } @@ -768,13 +768,13 @@ QualType Type::getPointeeType() const { const RecordType *Type::getAsStructureType() const { // If this is directly a structure type, return it. if (const auto *RT = dyn_cast<RecordType>(this)) { - if (RT->getOriginalDecl()->isStruct()) + if (RT->getDecl()->isStruct()) return RT; } // If the canonical form of this type isn't the right kind, reject it. if (const auto *RT = dyn_cast<RecordType>(CanonicalType)) { - if (!RT->getOriginalDecl()->isStruct()) + if (!RT->getDecl()->isStruct()) return nullptr; // If this is a typedef for a structure type, strip the typedef off without @@ -787,13 +787,13 @@ const RecordType *Type::getAsStructureType() const { const RecordType *Type::getAsUnionType() const { // If this is directly a union type, return it. if (const auto *RT = dyn_cast<RecordType>(this)) { - if (RT->getOriginalDecl()->isUnion()) + if (RT->getDecl()->isUnion()) return RT; } // If the canonical form of this type isn't the right kind, reject it. if (const auto *RT = dyn_cast<RecordType>(CanonicalType)) { - if (!RT->getOriginalDecl()->isUnion()) + if (!RT->getDecl()->isUnion()) return nullptr; // If this is a typedef for a union type, strip the typedef off without @@ -2107,7 +2107,7 @@ bool Type::isIntegralType(const ASTContext &Ctx) const { // Complete enum types are integral in C. if (!Ctx.getLangOpts().CPlusPlus) if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) - return IsEnumDeclComplete(ET->getOriginalDecl()); + return IsEnumDeclComplete(ET->getDecl()); return isBitIntType(); } @@ -2124,7 +2124,7 @@ bool Type::isIntegralOrUnscopedEnumerationType() const { bool Type::isUnscopedEnumerationType() const { if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) - return !ET->getOriginalDecl()->isScoped(); + return !ET->getDecl()->isScoped(); return false; } @@ -2328,7 +2328,7 @@ bool Type::isRealType() const { return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::Ibm128; if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) { - const auto *ED = ET->getOriginalDecl(); + const auto *ED = ET->getDecl(); return !ED->isScoped() && ED->getDefinitionOrSelf()->isComplete(); } return isBitIntType(); @@ -2345,7 +2345,7 @@ bool Type::isArithmeticType() const { // C++0x: Enumerations are not arithmetic types. For now, just return // false for scoped enumerations since that will disable any // unwanted implicit conversions. - const auto *ED = ET->getOriginalDecl(); + const auto *ED = ET->getDecl(); return !ED->isScoped() && ED->getDefinitionOrSelf()->isComplete(); } return isa<ComplexType>(CanonicalType) || isBitIntType(); @@ -2410,8 +2410,7 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const { /// includes union types. bool Type::isAggregateType() const { if (const auto *Record = dyn_cast<RecordType>(CanonicalType)) { - if (const auto *ClassDecl = - dyn_cast<CXXRecordDecl>(Record->getOriginalDecl())) + if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(Record->getDecl())) return ClassDecl->isAggregate(); return true; @@ -2746,8 +2745,8 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const { return true; case Type::Record: - if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>( - cast<RecordType>(CanonicalType)->getOriginalDecl())) + if (const auto *ClassDecl = + dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl())) return ClassDecl->isPOD(); // C struct/union is POD. @@ -3179,7 +3178,7 @@ bool Type::isNothrowT() const { bool Type::isAlignValT() const { if (const auto *ET = getAsCanonical<EnumType>()) { - const auto *ED = ET->getOriginalDecl(); + const auto *ED = ET->getDecl(); IdentifierInfo *II = ED->getIdentifier(); if (II && II->isStr("align_val_t") && ED->isInStdNamespace()) return true; @@ -3189,7 +3188,7 @@ bool Type::isAlignValT() const { bool Type::isStdByteType() const { if (const auto *ET = getAsCanonical<EnumType>()) { - const auto *ED = ET->getOriginalDecl(); + const auto *ED = ET->getDecl(); IdentifierInfo *II = ED->getIdentifier(); if (II && II->isStr("byte") && ED->isInStdNamespace()) return true; @@ -4321,7 +4320,7 @@ bool RecordType::hasConstFields() const { while (RecordTypeList.size() > NextToCheckIndex) { for (FieldDecl *FD : RecordTypeList[NextToCheckIndex] - ->getOriginalDecl() + ->getDecl() ->getDefinitionOrSelf() ->fields()) { QualType FieldTy = FD->getType(); @@ -4815,8 +4814,7 @@ static CachedProperties computeCachedProperties(const Type *T) { case Type::Record: case Type::Enum: { - const TagDecl *Tag = - cast<TagType>(T)->getOriginalDecl()->getDefinitionOrSelf(); + const auto *Tag = cast<TagType>(T)->getDecl()->getDefinitionOrSelf(); // C++ [basic.link]p8: // - it is a class or enumeration type that is named (or has a name @@ -4926,7 +4924,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) { case Type::Record: case Type::Enum: return getDeclLinkageAndVisibility( - cast<TagType>(T)->getOriginalDecl()->getDefinitionOrSelf()); + cast<TagType>(T)->getDecl()->getDefinitionOrSelf()); case Type::Complex: return computeTypeLinkageInfo(cast<ComplexType>(T)->getElementType()); @@ -5129,7 +5127,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { llvm_unreachable("unknown builtin type"); case Type::Record: { - const RecordDecl *RD = cast<RecordType>(type)->getOriginalDecl(); + const auto *RD = cast<RecordType>(type)->getDecl(); // For template specializations, look only at primary template attributes. // This is a consistent regardless of whether the instantiation is known. if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) @@ -5327,7 +5325,7 @@ bool Type::isCARCBridgableType() const { /// Check if the specified type is the CUDA device builtin surface type. bool Type::isCUDADeviceBuiltinSurfaceType() const { if (const auto *RT = getAsCanonical<RecordType>()) - return RT->getOriginalDecl() + return RT->getDecl() ->getMostRecentDecl() ->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>(); return false; @@ -5336,7 +5334,7 @@ bool Type::isCUDADeviceBuiltinSurfaceType() const { /// Check if the specified type is the CUDA device builtin texture type. bool Type::isCUDADeviceBuiltinTextureType() const { if (const auto *RT = getAsCanonical<RecordType>()) - return RT->getOriginalDecl() + return RT->getDecl() ->getMostRecentDecl() ->hasAttr<CUDADeviceBuiltinTextureTypeAttr>(); return false; diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index e952e82..f54ccf0 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -303,8 +303,7 @@ bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) { } bool TagTypeLoc::isDefinition() const { - return getTypePtr()->isTagOwned() && - getOriginalDecl()->isCompleteDefinition(); + return getTypePtr()->isTagOwned() && getDecl()->isCompleteDefinition(); } // Reimplemented to account for GNU/C++ extension diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 66a1b68..2da7789 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1421,7 +1421,7 @@ void TypePrinter::printDeducedTemplateSpecializationBefore( } else { // Should only get here for canonical types. const auto *CD = cast<ClassTemplateSpecializationDecl>( - cast<RecordType>(T->getDeducedType())->getOriginalDecl()); + cast<RecordType>(T->getDeducedType())->getDecl()); DeducedTD = CD->getSpecializedTemplate(); Args = CD->getTemplateArgs().asArray(); } @@ -1565,7 +1565,7 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS, } void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) { - TagDecl *D = T->getOriginalDecl(); + TagDecl *D = T->getDecl(); if (Policy.IncludeTagDefinition && T->isTagOwned()) { D->print(OS, Policy, Indentation); @@ -1669,11 +1669,11 @@ void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) { void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) { // Print the preferred name if we have one for this type. if (Policy.UsePreferredNames) { - for (const auto *PNA : T->getOriginalDecl() + for (const auto *PNA : T->getDecl() ->getMostRecentDecl() ->specific_attrs<PreferredNameAttr>()) { if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(), - T->getOriginalDecl())) + T->getDecl())) continue; // Find the outermost typedef or alias template. QualType T = PNA->getTypedefType(); @@ -1700,11 +1700,11 @@ void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {} void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T, raw_ostream &OS) { - const ASTContext &Ctx = T->getOriginalDecl()->getASTContext(); + const ASTContext &Ctx = T->getDecl()->getASTContext(); IncludeStrongLifetimeRAII Strong(Policy); T->getTemplateName(Ctx).print(OS, Policy); if (Policy.PrintInjectedClassNameWithArguments) { - auto *Decl = T->getOriginalDecl(); + auto *Decl = T->getDecl(); // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written // arguments. if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) { diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index 6cec526..3ded3a5 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -312,13 +312,12 @@ ComputeReturnAdjustmentBaseOffset(ASTContext &Context, return BaseOffset(); } - const CXXRecordDecl *DerivedRD = - cast<CXXRecordDecl>( - cast<RecordType>(CanDerivedReturnType)->getOriginalDecl()) + const auto *DerivedRD = + cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl()) ->getDefinitionOrSelf(); - const CXXRecordDecl *BaseRD = cast<CXXRecordDecl>( - cast<RecordType>(CanBaseReturnType)->getOriginalDecl()); + const auto *BaseRD = + cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl()); return ComputeBaseOffset(Context, BaseRD, DerivedRD); } diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index a56fdb1..77750cf 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -2032,9 +2032,7 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D, assert(inserted.second && "Are we visiting the same expression again?"); if (isa<CXXConstructExpr>(Exp)) Self = Placeholder; - if (TagT->getOriginalDecl() - ->getMostRecentDecl() - ->hasAttr<ScopedLockableAttr>()) + if (TagT->getDecl()->getMostRecentDecl()->hasAttr<ScopedLockableAttr>()) Scp = CapabilityExpr(Placeholder, Exp->getType(), /*Neg=*/false); } diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp index f034514..641a3db 100644 --- a/clang/lib/Basic/LangOptions.cpp +++ b/clang/lib/Basic/LangOptions.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/LangOptions.h" +#include "clang/Basic/LangStandard.h" #include "llvm/Support/Path.h" using namespace clang; @@ -243,3 +244,46 @@ LLVM_DUMP_METHOD void FPOptionsOverride::dump() { #include "clang/Basic/FPOptions.def" llvm::errs() << "\n"; } + +std::optional<uint32_t> LangOptions::getCPlusPlusLangStd() const { + if (!CPlusPlus) + return std::nullopt; + + LangStandard::Kind Std; + if (CPlusPlus26) + Std = LangStandard::lang_cxx26; + else if (CPlusPlus23) + Std = LangStandard::lang_cxx23; + else if (CPlusPlus20) + Std = LangStandard::lang_cxx20; + else if (CPlusPlus17) + Std = LangStandard::lang_cxx17; + else if (CPlusPlus14) + Std = LangStandard::lang_cxx14; + else if (CPlusPlus11) + Std = LangStandard::lang_cxx11; + else + Std = LangStandard::lang_cxx98; + + return LangStandard::getLangStandardForKind(Std).getVersion(); +} + +std::optional<uint32_t> LangOptions::getCLangStd() const { + LangStandard::Kind Std; + if (C2y) + Std = LangStandard::lang_c2y; + else if (C23) + Std = LangStandard::lang_c23; + else if (C17) + Std = LangStandard::lang_c17; + else if (C11) + Std = LangStandard::lang_c11; + else if (C99) + Std = LangStandard::lang_c99; + else if (!GNUMode && Digraphs) + Std = LangStandard::lang_c94; + else + return std::nullopt; + + return LangStandard::getLangStandardForKind(Std).getVersion(); +} diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp index c49d095..01c524b 100644 --- a/clang/lib/Basic/LangStandards.cpp +++ b/clang/lib/Basic/LangStandards.cpp @@ -46,16 +46,18 @@ StringRef clang::languageToString(Language L) { llvm_unreachable("unhandled language kind"); } -#define LANGSTANDARD(id, name, lang, desc, features) \ - static const LangStandard Lang_##id = {name, desc, features, Language::lang}; +#define LANGSTANDARD(id, name, lang, desc, features, version) \ + static const LangStandard Lang_##id = {name, desc, features, Language::lang, \ + version}; #include "clang/Basic/LangStandards.def" const LangStandard &LangStandard::getLangStandardForKind(Kind K) { switch (K) { case lang_unspecified: llvm::report_fatal_error("getLangStandardForKind() on unspecified kind"); -#define LANGSTANDARD(id, name, lang, desc, features) \ - case lang_##id: return Lang_##id; +#define LANGSTANDARD(id, name, lang, desc, features, version) \ + case lang_##id: \ + return Lang_##id; #include "clang/Basic/LangStandards.def" } llvm_unreachable("Invalid language kind!"); @@ -63,7 +65,8 @@ const LangStandard &LangStandard::getLangStandardForKind(Kind K) { LangStandard::Kind LangStandard::getLangKind(StringRef Name) { return llvm::StringSwitch<Kind>(Name) -#define LANGSTANDARD(id, name, lang, desc, features) .Case(name, lang_##id) +#define LANGSTANDARD(id, name, lang, desc, features, version) \ + .Case(name, lang_##id) #define LANGSTANDARD_ALIAS(id, alias) .Case(alias, lang_##id) #include "clang/Basic/LangStandards.def" .Default(lang_unspecified); diff --git a/clang/lib/Basic/Targets/AVR.cpp b/clang/lib/Basic/Targets/AVR.cpp index bbe7b01..2673669 100644 --- a/clang/lib/Basic/Targets/AVR.cpp +++ b/clang/lib/Basic/Targets/AVR.cpp @@ -420,23 +420,23 @@ static MCUInfo AVRMcus[] = { static bool ArchHasELPM(StringRef Arch) { return llvm::StringSwitch<bool>(Arch) - .Cases("31", "51", "6", true) - .Cases("102", "104", "105", "106", "107", true) - .Default(false); + .Cases({"31", "51", "6"}, true) + .Cases({"102", "104", "105", "106", "107"}, true) + .Default(false); } static bool ArchHasELPMX(StringRef Arch) { return llvm::StringSwitch<bool>(Arch) - .Cases("51", "6", true) - .Cases("102", "104", "105", "106", "107", true) - .Default(false); + .Cases({"51", "6"}, true) + .Cases({"102", "104", "105", "106", "107"}, true) + .Default(false); } static bool ArchHasMOVW(StringRef Arch) { return llvm::StringSwitch<bool>(Arch) - .Cases("25", "35", "4", "5", "51", "6", true) - .Cases("102", "103", "104", "105", "106", "107", true) - .Default(false); + .Cases({"25", "35", "4", "5", "51", "6"}, true) + .Cases({"102", "103", "104", "105", "106", "107"}, true) + .Default(false); } static bool ArchHasLPMX(StringRef Arch) { @@ -445,16 +445,16 @@ static bool ArchHasLPMX(StringRef Arch) { static bool ArchHasMUL(StringRef Arch) { return llvm::StringSwitch<bool>(Arch) - .Cases("4", "5", "51", "6", true) - .Cases("102", "103", "104", "105", "106", "107", true) - .Default(false); + .Cases({"4", "5", "51", "6"}, true) + .Cases({"102", "103", "104", "105", "106", "107"}, true) + .Default(false); } static bool ArchHasJMPCALL(StringRef Arch) { return llvm::StringSwitch<bool>(Arch) - .Cases("3", "31", "35", "5", "51", "6", true) - .Cases("102", "103", "104", "105", "106", "107", true) - .Default(false); + .Cases({"3", "31", "35", "5", "51", "6"}, true) + .Cases({"102", "103", "104", "105", "106", "107"}, true) + .Default(false); } static bool ArchHas3BytePC(StringRef Arch) { diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index bd13c9e..a21a593 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -64,8 +64,11 @@ public: NoAsmVariants = true; PlatformMinVersion = Triple.getOSVersion(); PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); + // TODO: We need to align vectors on the element size generally, but for now + // we hard code this for 3-element 32- and 64-bit vectors as a workaround. + // See https://github.com/llvm/llvm-project/issues/123968 resetDataLayout("e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:" - "32-f64:64-n8:16:32:64"); + "32-f64:64-n8:16:32:64-v48:16:16-v96:32:32-v192:64:64"); TheCXXABI.set(TargetCXXABI::GenericItanium); } bool useFP16ConversionIntrinsics() const override { return false; } diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 187815c..ef4973c 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -625,6 +625,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_ArrowlakeS: case CK_Lunarlake: case CK_Pantherlake: + case CK_Wildcatlake: case CK_Sierraforest: case CK_Grandridge: case CK_Graniterapids: @@ -1613,6 +1614,7 @@ std::optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const { case CK_ArrowlakeS: case CK_Lunarlake: case CK_Pantherlake: + case CK_Wildcatlake: case CK_Sierraforest: case CK_Grandridge: case CK_Graniterapids: diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index a6f10e6..84acc74 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -519,6 +519,14 @@ public: return createGlobal(module, loc, uniqueName, type, isConstant, linkage); } + cir::StackSaveOp createStackSave(mlir::Location loc, mlir::Type ty) { + return cir::StackSaveOp::create(*this, loc, ty); + } + + cir::StackRestoreOp createStackRestore(mlir::Location loc, mlir::Value v) { + return cir::StackRestoreOp::create(*this, loc, v); + } + mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType, Address dstAddr, mlir::Type storageType, mlir::Value src, const CIRGenBitFieldInfo &info, diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index dd357ce..89f4926 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -478,8 +478,7 @@ void CIRGenFunction::getVTablePointers(BaseSubobject base, for (const auto &nextBase : rd->bases()) { const auto *baseDecl = - cast<CXXRecordDecl>( - nextBase.getType()->castAs<RecordType>()->getOriginalDecl()) + cast<CXXRecordDecl>(nextBase.getType()->castAs<RecordType>()->getDecl()) ->getDefinitionOrSelf(); // Ignore classes without a vtable. @@ -1025,7 +1024,7 @@ void CIRGenFunction::enterDtorCleanups(const CXXDestructorDecl *dd, // Anonymous union members do not have their destructors called. const RecordType *rt = type->getAsUnionType(); - if (rt && rt->getOriginalDecl()->isAnonymousStructOrUnion()) + if (rt && rt->getDecl()->isAnonymousStructOrUnion()) continue; CleanupKind cleanupKind = getCleanupKind(dtorKind); diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 039d290..4a19d91 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -44,38 +44,70 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d, // If the type is variably-modified, emit all the VLA sizes for it. if (ty->isVariablyModifiedType()) - cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: variably modified type"); + emitVariablyModifiedType(ty); assert(!cir::MissingFeatures::openMP()); Address address = Address::invalid(); - if (!ty->isConstantSizeType()) - cgm.errorNYI(d.getSourceRange(), "emitAutoVarDecl: non-constant size type"); - - // A normal fixed sized variable becomes an alloca in the entry block, - // unless: - // - it's an NRVO variable. - // - we are compiling OpenMP and it's an OpenMP local variable. - if (nrvo) { - // The named return value optimization: allocate this variable in the - // return slot, so that we can elide the copy when returning this - // variable (C++0x [class.copy]p34). - address = returnValue; - - if (const RecordDecl *rd = ty->getAsRecordDecl()) { - if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd); - (cxxrd && !cxxrd->hasTrivialDestructor()) || - rd->isNonTrivialToPrimitiveDestroy()) - cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: set NRVO flag"); + if (ty->isConstantSizeType()) { + // A normal fixed sized variable becomes an alloca in the entry block, + // unless: + // - it's an NRVO variable. + // - we are compiling OpenMP and it's an OpenMP local variable. + if (nrvo) { + // The named return value optimization: allocate this variable in the + // return slot, so that we can elide the copy when returning this + // variable (C++0x [class.copy]p34). + address = returnValue; + + if (const RecordDecl *rd = ty->getAsRecordDecl()) { + if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd); + (cxxrd && !cxxrd->hasTrivialDestructor()) || + rd->isNonTrivialToPrimitiveDestroy()) + cgm.errorNYI(d.getSourceRange(), "emitAutoVarAlloca: set NRVO flag"); + } + } else { + // A normal fixed sized variable becomes an alloca in the entry block, + mlir::Type allocaTy = convertTypeForMem(ty); + // Create the temp alloca and declare variable using it. + address = createTempAlloca(allocaTy, alignment, loc, d.getName(), + /*arraySize=*/nullptr, /*alloca=*/nullptr, ip); + declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()), + alignment); } } else { - // A normal fixed sized variable becomes an alloca in the entry block, - mlir::Type allocaTy = convertTypeForMem(ty); - // Create the temp alloca and declare variable using it. - address = createTempAlloca(allocaTy, alignment, loc, d.getName(), - /*arraySize=*/nullptr, /*alloca=*/nullptr, ip); - declare(address.getPointer(), &d, ty, getLoc(d.getSourceRange()), - alignment); + // Non-constant size type + assert(!cir::MissingFeatures::openMP()); + if (!didCallStackSave) { + // Save the stack. + cir::PointerType defaultTy = AllocaInt8PtrTy; + CharUnits align = CharUnits::fromQuantity( + cgm.getDataLayout().getAlignment(defaultTy, false)); + Address stack = createTempAlloca(defaultTy, align, loc, "saved_stack"); + + mlir::Value v = builder.createStackSave(loc, defaultTy); + assert(v.getType() == AllocaInt8PtrTy); + builder.createStore(loc, v, stack); + + didCallStackSave = true; + + // Push a cleanup block and restore the stack there. + // FIXME: in general circumstances, this should be an EH cleanup. + pushStackRestore(NormalCleanup, stack); + } + + VlaSizePair vlaSize = getVLASize(ty); + mlir::Type memTy = convertTypeForMem(vlaSize.type); + + // Allocate memory for the array. + address = + createTempAlloca(memTy, alignment, loc, d.getName(), vlaSize.numElts, + /*alloca=*/nullptr, builder.saveInsertionPoint()); + + // If we have debug info enabled, properly describe the VLA dimensions for + // this type by registering the vla size expression for each of the + // dimensions. + assert(!cir::MissingFeatures::generateDebugInfo()); } emission.addr = address; @@ -696,6 +728,16 @@ struct DestroyObject final : EHScopeStack::Cleanup { cgf.emitDestroy(addr, type, destroyer); } }; + +struct CallStackRestore final : EHScopeStack::Cleanup { + Address stack; + CallStackRestore(Address stack) : stack(stack) {} + void emit(CIRGenFunction &cgf) override { + mlir::Location loc = stack.getPointer().getLoc(); + mlir::Value v = cgf.getBuilder().createLoad(loc, stack); + cgf.getBuilder().createStackRestore(loc, v); + } +}; } // namespace void CIRGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr, @@ -805,6 +847,10 @@ CIRGenFunction::getDestroyer(QualType::DestructionKind kind) { llvm_unreachable("Unknown DestructionKind"); } +void CIRGenFunction::pushStackRestore(CleanupKind kind, Address spMem) { + ehStack.pushCleanup<CallStackRestore>(kind, spMem); +} + /// Enter a destroy cleanup for the given local variable. void CIRGenFunction::emitAutoVarTypeCleanup( const CIRGenFunction::AutoVarEmission &emission, diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index f416571..4897c29 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -2068,7 +2068,7 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty, mlir::OpBuilder::InsertionGuard guard(builder); builder.restoreInsertionPoint(ip); addr = builder.createAlloca(loc, /*addr type*/ localVarPtrTy, - /*var type*/ ty, name, alignIntAttr); + /*var type*/ ty, name, alignIntAttr, arraySize); assert(!cir::MissingFeatures::astVarDeclInterface()); } return addr; diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 89e9ec4..81e5fe2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -614,7 +614,7 @@ bool ConstRecordBuilder::applyZeroInitPadding(const ASTRecordLayout &layout, bool ConstRecordBuilder::build(InitListExpr *ile, bool allowOverwrite) { RecordDecl *rd = ile->getType() ->castAs<clang::RecordType>() - ->getOriginalDecl() + ->getDecl() ->getDefinitionOrSelf(); const ASTRecordLayout &layout = cgm.getASTContext().getASTRecordLayout(rd); @@ -817,9 +817,8 @@ bool ConstRecordBuilder::build(const APValue &val, const RecordDecl *rd, mlir::Attribute ConstRecordBuilder::finalize(QualType type) { type = type.getNonReferenceType(); - RecordDecl *rd = type->castAs<clang::RecordType>() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + RecordDecl *rd = + type->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf(); mlir::Type valTy = cgm.convertType(type); return builder.build(valTy, rd->hasFlexibleArrayMember()); } @@ -842,9 +841,8 @@ mlir::Attribute ConstRecordBuilder::buildRecord(ConstantEmitter &emitter, ConstantAggregateBuilder constant(emitter.cgm); ConstRecordBuilder builder(emitter, constant, CharUnits::Zero()); - const RecordDecl *rd = valTy->castAs<clang::RecordType>() - ->getOriginalDecl() - ->getDefinitionOrSelf(); + const RecordDecl *rd = + valTy->castAs<clang::RecordType>()->getDecl()->getDefinitionOrSelf(); const CXXRecordDecl *cd = dyn_cast<CXXRecordDecl>(rd); if (!builder.build(val, rd, false, cd, CharUnits::Zero())) return nullptr; diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index 01a43a99..ba36cbe 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -410,6 +410,8 @@ void CIRGenFunction::startFunction(GlobalDecl gd, QualType returnType, curFn = fn; const Decl *d = gd.getDecl(); + + didCallStackSave = false; curCodeDecl = d; const auto *fd = dyn_cast_or_null<FunctionDecl>(d); curFuncDecl = d->getNonClosureContext(); @@ -1006,6 +1008,41 @@ mlir::Value CIRGenFunction::emitAlignmentAssumption( offsetValue); } +CIRGenFunction::VlaSizePair CIRGenFunction::getVLASize(QualType type) { + const VariableArrayType *vla = + cgm.getASTContext().getAsVariableArrayType(type); + assert(vla && "type was not a variable array type!"); + return getVLASize(vla); +} + +CIRGenFunction::VlaSizePair +CIRGenFunction::getVLASize(const VariableArrayType *type) { + // The number of elements so far; always size_t. + mlir::Value numElements; + + QualType elementType; + do { + elementType = type->getElementType(); + mlir::Value vlaSize = vlaSizeMap[type->getSizeExpr()]; + assert(vlaSize && "no size for VLA!"); + assert(vlaSize.getType() == SizeTy); + + if (!numElements) { + numElements = vlaSize; + } else { + // It's undefined behavior if this wraps around, so mark it that way. + // FIXME: Teach -fsanitize=undefined to trap this. + + numElements = + builder.createMul(numElements.getLoc(), numElements, vlaSize, + cir::OverflowBehavior::NoUnsignedWrap); + } + } while ((type = getContext().getAsVariableArrayType(elementType))); + + assert(numElements && "Undefined elements number"); + return {numElements, elementType}; +} + // TODO(cir): Most of this function can be shared between CIRGen // and traditional LLVM codegen void CIRGenFunction::emitVariablyModifiedType(QualType type) { @@ -1086,7 +1123,26 @@ void CIRGenFunction::emitVariablyModifiedType(QualType type) { break; case Type::VariableArray: { - cgm.errorNYI("CIRGenFunction::emitVariablyModifiedType VLA"); + // Losing element qualification here is fine. + const VariableArrayType *vat = cast<clang::VariableArrayType>(ty); + + // Unknown size indication requires no size computation. + // Otherwise, evaluate and record it. + if (const Expr *sizeExpr = vat->getSizeExpr()) { + // It's possible that we might have emitted this already, + // e.g. with a typedef and a pointer to it. + mlir::Value &entry = vlaSizeMap[sizeExpr]; + if (!entry) { + mlir::Value size = emitScalarExpr(sizeExpr); + assert(!cir::MissingFeatures::sanitizers()); + + // Always zexting here would be wrong if it weren't + // undefined behavior to have a negative bound. + // FIXME: What about when size's type is larger than size_t? + entry = builder.createIntCast(size, SizeTy); + } + } + type = vat->getElementType(); break; } diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index d71de2f..0d64c31 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -149,6 +149,10 @@ public: using SymTableTy = llvm::ScopedHashTable<const clang::Decl *, mlir::Value>; SymTableTy symbolTable; + /// Whether a cir.stacksave operation has been added. Used to avoid + /// inserting cir.stacksave for multiple VLAs in the same scope. + bool didCallStackSave = false; + /// Whether or not a Microsoft-style asm block has been processed within /// this fuction. These can potentially set the return value. bool sawAsmBlock = false; @@ -188,6 +192,14 @@ public: llvm::DenseMap<const OpaqueValueExpr *, LValue> opaqueLValues; llvm::DenseMap<const OpaqueValueExpr *, RValue> opaqueRValues; + // This keeps track of the associated size for each VLA type. + // We track this by the size expression rather than the type itself because + // in certain situations, like a const qualifier applied to an VLA typedef, + // multiple VLA types can share the same size expression. + // FIXME: Maybe this could be a stack of maps that is pushed/popped as we + // enter/leave scopes. + llvm::DenseMap<const Expr *, mlir::Value> vlaSizeMap; + public: /// A non-RAII class containing all the information about a bound /// opaque value. OpaqueValueMapping, below, is a RAII wrapper for @@ -436,6 +448,20 @@ public: } }; + struct VlaSizePair { + mlir::Value numElts; + QualType type; + + VlaSizePair(mlir::Value num, QualType ty) : numElts(num), type(ty) {} + }; + + /// Returns an MLIR::Value+QualType pair that corresponds to the size, + /// in non-variably-sized elements, of a variable length array type, + /// plus that largest non-variably-sized element type. Assumes that + /// the type has already been emitted with emitVariablyModifiedType. + VlaSizePair getVLASize(const VariableArrayType *type); + VlaSizePair getVLASize(QualType type); + void finishFunction(SourceLocation endLoc); /// Determine whether the given initializer is trivial in the sense @@ -583,6 +609,8 @@ public: return needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup; } + void pushStackRestore(CleanupKind kind, Address spMem); + /// Set the address of a local variable. void setAddrOfLocalVar(const clang::VarDecl *vd, Address addr) { assert(!localDeclMap.count(vd) && "Decl already exists in LocalDeclMap!"); @@ -854,6 +882,7 @@ public: protected: bool performCleanup; + bool oldDidCallStackSave; private: RunCleanupsScope(const RunCleanupsScope &) = delete; @@ -867,6 +896,8 @@ public: explicit RunCleanupsScope(CIRGenFunction &cgf) : performCleanup(true), cgf(cgf) { cleanupStackDepth = cgf.ehStack.stable_begin(); + oldDidCallStackSave = cgf.didCallStackSave; + cgf.didCallStackSave = false; oldCleanupStackDepth = cgf.currentCleanupStackDepth; cgf.currentCleanupStackDepth = cleanupStackDepth; } @@ -883,6 +914,7 @@ public: assert(performCleanup && "Already forced cleanup"); { mlir::OpBuilder::InsertionGuard guard(cgf.getBuilder()); + cgf.didCallStackSave = oldDidCallStackSave; cgf.popCleanupBlocks(cleanupStackDepth); performCleanup = false; cgf.currentCleanupStackDepth = oldCleanupStackDepth; diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index d30c975..1b85a53 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -744,8 +744,8 @@ static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) { return false; if (const auto *recordTy = dyn_cast<RecordType>(ty)) { - const CXXRecordDecl *rd = - cast<CXXRecordDecl>(recordTy->getOriginalDecl())->getDefinitionOrSelf(); + const auto *rd = + cast<CXXRecordDecl>(recordTy->getDecl())->getDefinitionOrSelf(); if (!rd->hasDefinition()) return false; @@ -859,9 +859,7 @@ static bool canUseSingleInheritance(const CXXRecordDecl *rd) { /// IsIncompleteClassType - Returns whether the given record type is incomplete. static bool isIncompleteClassType(const RecordType *recordTy) { - return !recordTy->getOriginalDecl() - ->getDefinitionOrSelf() - ->isCompleteDefinition(); + return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition(); } /// Returns whether the given type contains an @@ -939,8 +937,7 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) { case Type::Atomic: // FIXME: GCC treats block pointers as fundamental types?! case Type::BlockPointer: - cgm.errorNYI("VTableClassNameForType: __fundamental_type_info"); - break; + return "_ZTVN10__cxxabiv123__fundamental_type_infoE"; case Type::ConstantArray: case Type::IncompleteArray: case Type::VariableArray: @@ -957,9 +954,8 @@ const char *vTableClassNameForType(const CIRGenModule &cgm, const Type *ty) { break; case Type::Record: { - const CXXRecordDecl *rd = - cast<CXXRecordDecl>(cast<RecordType>(ty)->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *rd = cast<CXXRecordDecl>(cast<RecordType>(ty)->getDecl()) + ->getDefinitionOrSelf(); if (!rd->hasDefinition() || !rd->getNumBases()) { return classTypeInfo; @@ -1031,8 +1027,8 @@ static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, return cir::GlobalLinkageKind::LinkOnceODRLinkage; if (const RecordType *record = dyn_cast<RecordType>(ty)) { - const CXXRecordDecl *rd = - cast<CXXRecordDecl>(record->getOriginalDecl())->getDefinitionOrSelf(); + const auto *rd = + cast<CXXRecordDecl>(record->getDecl())->getDefinitionOrSelf(); if (rd->hasAttr<WeakAttr>()) return cir::GlobalLinkageKind::WeakODRLinkage; @@ -1382,9 +1378,8 @@ mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo( break; case Type::Record: { - const auto *rd = - cast<CXXRecordDecl>(cast<RecordType>(ty)->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *rd = cast<CXXRecordDecl>(cast<RecordType>(ty)->getDecl()) + ->getDefinitionOrSelf(); if (!rd->hasDefinition() || !rd->getNumBases()) { // We don't need to emit any fields. break; @@ -1651,8 +1646,7 @@ void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf, // Lowering pass to skip passing the trivial function. // if (const RecordType *recordTy = clangThrowType->getAs<RecordType>()) { - CXXRecordDecl *rec = - cast<CXXRecordDecl>(recordTy->getOriginalDecl()->getDefinition()); + auto *rec = cast<CXXRecordDecl>(recordTy->getDecl()->getDefinition()); assert(!cir::MissingFeatures::isTrivialCtorOrDtor()); if (!rec->hasTrivialDestructor()) { cgm.errorNYI("emitThrow: non-trivial destructor"); diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 82b1051..57c7a44 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -88,6 +88,8 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, FP80Ty = cir::FP80Type::get(&getMLIRContext()); FP128Ty = cir::FP128Type::get(&getMLIRContext()); + AllocaInt8PtrTy = cir::PointerType::get(UInt8Ty, cirAllocaAddressSpace); + PointerAlignInBytes = astContext .toCharUnitsFromBits( diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp index cfd48a2..5ba64dd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp @@ -536,7 +536,7 @@ mlir::LogicalResult CIRGenFunction::emitLabel(const clang::LabelDecl &d) { mlir::Block *currBlock = builder.getBlock(); mlir::Block *labelBlock = currBlock; - if (!currBlock->empty()) { + if (!currBlock->empty() || currBlock->isEntryBlock()) { { mlir::OpBuilder::InsertionGuard guard(builder); labelBlock = builder.createBlock(builder.getBlock()->getParent()); diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h index 273ec7f..b5612d9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h +++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h @@ -65,6 +65,9 @@ struct CIRGenTypeCache { cir::PointerType VoidPtrTy; cir::PointerType UInt8PtrTy; + /// void* in alloca address space + cir::PointerType AllocaInt8PtrTy; + /// The size and alignment of a pointer into the generic address space. union { unsigned char PointerAlignInBytes; diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 2ab1ea0c..d1b91d0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -159,7 +159,7 @@ isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt, for (const clang::CXXBaseSpecifier &i : crd->bases()) if (!isSafeToConvert(i.getType() ->castAs<RecordType>() - ->getOriginalDecl() + ->getDecl() ->getDefinitionOrSelf(), cgt, alreadyChecked)) return false; @@ -279,8 +279,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { // Process record types before the type cache lookup. if (const auto *recordType = dyn_cast<RecordType>(type)) - return convertRecordDeclType( - recordType->getOriginalDecl()->getDefinitionOrSelf()); + return convertRecordDeclType(recordType->getDecl()->getDefinitionOrSelf()); // Has the type already been processed? TypeCacheTy::iterator tci = typeCache.find(ty); @@ -421,6 +420,16 @@ mlir::Type CIRGenTypes::convertType(QualType type) { break; } + case Type::VariableArray: { + const VariableArrayType *a = cast<VariableArrayType>(ty); + if (a->getIndexTypeCVRQualifiers() != 0) + cgm.errorNYI(SourceLocation(), "non trivial array types", type); + // VLAs resolve to the innermost element type; this matches + // the return of alloca, and there isn't any obviously better choice. + resultType = convertTypeForMem(a->getElementType()); + break; + } + case Type::IncompleteArray: { const IncompleteArrayType *arrTy = cast<IncompleteArrayType>(ty); if (arrTy->getIndexTypeCVRQualifiers() != 0) diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 3abba3d..e61b65f 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1793,12 +1793,20 @@ CIRToLLVMGlobalOpLowering::getComdatAttr(cir::GlobalOp &op, if (!comdatOp) { builder.setInsertionPointToStart(module.getBody()); comdatOp = - builder.create<mlir::LLVM::ComdatOp>(module.getLoc(), comdatName); + mlir::LLVM::ComdatOp::create(builder, module.getLoc(), comdatName); + } + + if (auto comdatSelector = comdatOp.lookupSymbol<mlir::LLVM::ComdatSelectorOp>( + op.getSymName())) { + return mlir::SymbolRefAttr::get( + builder.getContext(), comdatName, + mlir::FlatSymbolRefAttr::get(comdatSelector.getSymNameAttr())); } builder.setInsertionPointToStart(&comdatOp.getBody().back()); - auto selectorOp = builder.create<mlir::LLVM::ComdatSelectorOp>( - comdatOp.getLoc(), op.getSymName(), mlir::LLVM::comdat::Comdat::Any); + auto selectorOp = mlir::LLVM::ComdatSelectorOp::create( + builder, comdatOp.getLoc(), op.getSymName(), + mlir::LLVM::comdat::Comdat::Any); return mlir::SymbolRefAttr::get( builder.getContext(), comdatName, mlir::FlatSymbolRefAttr::get(selectorOp.getSymNameAttr())); diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 13c837a..1e3ac2e 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -105,7 +105,7 @@ llvm::Type *CodeGen::getVAListElementType(CodeGenFunction &CGF) { CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) return CXXABI.getRecordArgABI(CXXRD); if (!RD->canPassInRegisters()) @@ -136,7 +136,7 @@ bool CodeGen::classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) { if (const RecordType *UT = Ty->getAsUnionType()) { - const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf(); if (UD->hasAttr<TransparentUnionAttr>()) { assert(!UD->field_empty() && "sema created an empty transparent union"); return UD->field_begin()->getType(); @@ -274,7 +274,7 @@ bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD, // according to the Itanium ABI. The exception applies only to records, // not arrays of records, so we must also check whether we stripped off an // array type above. - if (isa<CXXRecordDecl>(RT->getOriginalDecl()) && + if (isa<CXXRecordDecl>(RT->getDecl()) && (WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr<NoUniqueAddressAttr>()))) return false; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index f8e8086..6020684 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1200,7 +1200,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( } } - if (shouldEmitUnifiedLTOModueFlag()) + if (shouldEmitUnifiedLTOModueFlag() && + !TheModule->getModuleFlag("UnifiedLTO")) TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1)); } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index df28641..741fa44 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1896,7 +1896,7 @@ bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context, // complex destructor or a non-trivially copyable type. if (const RecordType *RT = ReturnType.getCanonicalType()->getAsCanonical<RecordType>()) { - if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) + if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) return ClassDecl->hasTrivialDestructor(); } return ReturnType.isTriviallyCopyableType(Context); @@ -3853,7 +3853,7 @@ static void setUsedBits(CodeGenModule &CGM, const RecordType *RTy, int Offset, SmallVectorImpl<uint64_t> &Bits) { ASTContext &Context = CGM.getContext(); int CharWidth = Context.getCharWidth(); - const RecordDecl *RD = RTy->getOriginalDecl()->getDefinition(); + const RecordDecl *RD = RTy->getDecl()->getDefinition(); const ASTRecordLayout &ASTLayout = Context.getASTRecordLayout(RD); const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(RD); diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index f31f0a2..f782b0c 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2026,7 +2026,7 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, // Anonymous union members do not have their destructors called. const RecordType *RT = type->getAsUnionType(); - if (RT && RT->getOriginalDecl()->isAnonymousStructOrUnion()) + if (RT && RT->getDecl()->isAnonymousStructOrUnion()) continue; CleanupKind cleanupKind = getCleanupKind(dtorKind); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 9fe9a13..85c70de 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1290,7 +1290,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->getOriginalDecl()->getDefinitionOrSelf(); + const TagDecl *TD = Ty->getDecl()->getDefinitionOrSelf(); if (!needsTypeIdentifier(TD, CGM, TheCU)) return Identifier; @@ -1326,7 +1326,7 @@ static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD) { llvm::DICompositeType * CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty, llvm::DIScope *Ctx) { - const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf(); if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0))) return cast<llvm::DICompositeType>(T); llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation()); @@ -2402,7 +2402,7 @@ void CGDebugInfo::CollectCXXBasesAux( for (const auto &BI : Bases) { const auto *Base = cast<CXXRecordDecl>( - BI.getType()->castAsCanonical<RecordType>()->getOriginalDecl()) + BI.getType()->castAsCanonical<RecordType>()->getDecl()) ->getDefinition(); if (!SeenTypes.insert(Base).second) continue; @@ -3077,7 +3077,7 @@ void CGDebugInfo::completeRequiredType(const RecordDecl *RD) { } llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) { - RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf(); llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(QualType(Ty, 0))); if (T || shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD, CGM.getLangOpts())) { @@ -3105,7 +3105,7 @@ llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD, std::pair<llvm::DIType *, llvm::DIType *> CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) { - RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf(); // Get overall information about the record type for the debug info. llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation()); @@ -3748,7 +3748,7 @@ llvm::DIType *CGDebugInfo::CreateType(const HLSLInlineSpirvType *Ty, static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU, const EnumType *Ty) { - const EnumDecl *ED = Ty->getOriginalDecl()->getDefinitionOrSelf(); + const EnumDecl *ED = Ty->getDecl()->getDefinitionOrSelf(); uint64_t Size = 0; uint32_t Align = 0; @@ -4151,7 +4151,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->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *RD = Ty->getDecl()->getDefinitionOrSelf(); // Get overall information about the record type for the debug info. StringRef RDName = getClassName(RD); @@ -4238,8 +4238,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) { break; } - if (auto *CTSD = - dyn_cast<ClassTemplateSpecializationDecl>(Ty->getOriginalDecl())) { + if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Ty->getDecl())) { CXXRecordDecl *TemplateDecl = CTSD->getSpecializedTemplate()->getTemplatedDecl(); RegionMap[TemplateDecl].reset(RealDecl); @@ -5141,7 +5140,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->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->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. @@ -5691,9 +5690,8 @@ 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->getOriginalDecl()->getDefinitionOrSelf(), - Unit, LineNo, LinkageName, Var, DContext); + GVE = CollectAnonRecordDecls(RT->getDecl()->getDefinitionOrSelf(), Unit, + LineNo, LinkageName, Var, DContext); continue; } // Use VarDecl's Tag, Scope and Line number. @@ -5712,7 +5710,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->getOriginalDecl()); + const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); if (!RD) return false; if (!RD->getIdentifier()) @@ -5774,7 +5772,7 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> { 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->getOriginalDecl())) { + if (const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) { if (!ED->getIdentifier()) { Reconstitutable = false; return false; diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index e8255b0..8439ec7 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2011,7 +2011,7 @@ static bool isConstantEmittableObjectType(QualType type) { // Otherwise, all object types satisfy this except C++ classes with // mutable subobjects or non-trivial copy/destroy behavior. if (const auto *RT = dyn_cast<RecordType>(type)) - if (const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) { + if (const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) { RD = RD->getDefinitionOrSelf(); if (RD->hasMutableFields() || !RD->isTrivial()) return false; @@ -4564,7 +4564,7 @@ static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase) { const auto *PointeeT = PtrT->getPointeeType() ->getUnqualifiedDesugaredType(); if (const auto *RecT = dyn_cast<RecordType>(PointeeT)) - return RecT->getOriginalDecl() + return RecT->getDecl() ->getMostRecentDecl() ->hasAttr<BPFPreserveAccessIndexAttr>(); return false; @@ -7008,7 +7008,7 @@ void CodeGenFunction::FlattenAccessAndTypeLValue( WorkList.emplace_back(LVal, CAT->getElementType(), IdxListCopy); } } else if (const auto *RT = dyn_cast<RecordType>(T)) { - const RecordDecl *Record = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *Record = RT->getDecl()->getDefinitionOrSelf(); assert(!Record->isUnion() && "Union types not supported in flat cast."); const CXXRecordDecl *CXXD = dyn_cast<CXXRecordDecl>(Record); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 07b9aeb..eee397f 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -2080,7 +2080,7 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { // referencee. InitListExprs for unions and arrays can't have references. if (const RecordType *RT = E->getType()->getAsCanonical<RecordType>()) { if (!RT->isUnionType()) { - RecordDecl *SD = RT->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *SD = RT->getDecl()->getDefinitionOrSelf(); CharUnits NumNonZeroBytes = CharUnits::Zero(); unsigned ILEElement = 0; @@ -2133,7 +2133,7 @@ static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, if (const RecordType *RT = CGF.getContext() .getBaseElementType(E->getType()) ->getAsCanonical<RecordType>()) { - const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getOriginalDecl()); + const auto *RD = cast<CXXRecordDecl>(RT->getDecl()); if (RD->hasUserDeclaredConstructor()) return; } diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 31ac266..14d8db3 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1236,8 +1236,8 @@ void CodeGenFunction::EmitNewArrayInitializer( if (auto *ILE = dyn_cast<InitListExpr>(Init)) { if (const RecordType *RType = ILE->getType()->getAsCanonical<RecordType>()) { - if (RType->getOriginalDecl()->isStruct()) { - const RecordDecl *RD = RType->getOriginalDecl()->getDefinitionOrSelf(); + if (RType->getDecl()->isStruct()) { + const RecordDecl *RD = RType->getDecl()->getDefinitionOrSelf(); unsigned NumElements = 0; if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) NumElements = CXXRD->getNumBases(); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 715160d..714192d 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -3583,7 +3583,7 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) { } const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout( - CurrentType->castAsCanonical<RecordType>()->getOriginalDecl()); + CurrentType->castAsCanonical<RecordType>()->getDecl()); // Save the element type. CurrentType = ON.getBase()->getType(); diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index 2d70e4c..0a383c8 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -464,8 +464,7 @@ template <class Derived> struct GenFuncBase { if (WrongType) { std::string FuncName = std::string(F->getName()); - SourceLocation Loc = - QT->castAs<RecordType>()->getOriginalDecl()->getLocation(); + SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation(); CGM.Error(Loc, "special function " + FuncName + " for non-trivial C struct has incorrect type"); return nullptr; diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index dbcce9b..c571821a 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2495,7 +2495,7 @@ void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT, CharUnits BytePos, bool &HasUnion, bool ByrefLayout) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); SmallVector<const FieldDecl *, 16> Fields(RD->fields()); llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); const llvm::StructLayout *RecLayout = @@ -5184,7 +5184,7 @@ CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, } void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); // If this is a union, remember that we had one, because it might mess // up the ordering of layout entries. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 8d019d4..c5eb14e 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2348,7 +2348,7 @@ static QualType GeneralizeTransparentUnion(QualType Ty) { const RecordType *UT = Ty->getAsUnionType(); if (!UT) return Ty; - const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf(); if (!UD->hasAttr<TransparentUnionAttr>()) return Ty; for (const auto *it : UD->fields()) { @@ -4230,7 +4230,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { static bool HasNonDllImportDtor(QualType T) { if (const auto *RT = T->getBaseElementTypeUnsafe()->getAsCanonical<RecordType>()) - if (auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) { + if (auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) { RD = RD->getDefinitionOrSelf(); if (RD->getDestructor() && !RD->getDestructor()->hasAttr<DLLImportAttr>()) return true; diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index f8c7d64..4e29d8a 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -310,7 +310,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { // This also covers anonymous structs and unions, which have a different // compatibility rule, but it doesn't matter because you can never have a // pointer to an anonymous struct or union. - if (!RT->getOriginalDecl()->getDeclName()) + if (!RT->getDecl()->getDeclName()) return getAnyPtr(PtrDepth); // For non-builtin types use the mangled name of the canonical type. @@ -332,7 +332,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { // Enum types are distinct types. In C++ they have "underlying types", // however they aren't related for TBAA. if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) { - const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf(); + const EnumDecl *ED = ETy->getDecl()->getDefinitionOrSelf(); if (!Features.CPlusPlus) return getTypeInfo(ED->getIntegerType()); @@ -433,7 +433,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag)); return true; } - const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition(); + const RecordDecl *RD = TTy->getDecl()->getDefinition(); if (RD->hasFlexibleArrayMember()) return false; @@ -514,7 +514,7 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) { llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) { if (auto *TTy = dyn_cast<RecordType>(Ty)) { - const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition(); + const RecordDecl *RD = TTy->getDecl()->getDefinition(); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); using TBAAStructField = llvm::MDBuilder::TBAAStructField; SmallVector<TBAAStructField, 4> Fields; diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 3ffe999..ea31195 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -373,8 +373,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { } // RecordTypes are cached and processed specially. - if (const RecordType *RT = dyn_cast<RecordType>(Ty)) - return ConvertRecordDeclType(RT->getOriginalDecl()->getDefinitionOrSelf()); + if (const auto *RT = dyn_cast<RecordType>(Ty)) + return ConvertRecordDeclType(RT->getDecl()->getDefinitionOrSelf()); llvm::Type *CachedType = nullptr; auto TCI = TypeCache.find(Ty); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 7dc2eaf..9e195a9 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3816,7 +3816,7 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { const CXXRecordDecl *RD = - cast<CXXRecordDecl>(RecordTy->getOriginalDecl())->getDefinitionOrSelf(); + cast<CXXRecordDecl>(RecordTy->getDecl())->getDefinitionOrSelf(); if (!RD->hasDefinition()) return false; @@ -3850,9 +3850,7 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, /// IsIncompleteClassType - Returns whether the given record type is incomplete. static bool IsIncompleteClassType(const RecordType *RecordTy) { - return !RecordTy->getOriginalDecl() - ->getDefinitionOrSelf() - ->isCompleteDefinition(); + return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition(); } /// ContainsIncompleteClassType - Returns whether the given type contains an @@ -3985,9 +3983,8 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty, break; case Type::Record: { - const CXXRecordDecl *RD = - cast<CXXRecordDecl>(cast<RecordType>(Ty)->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *RD = cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl()) + ->getDefinitionOrSelf(); if (!RD->hasDefinition() || !RD->getNumBases()) { VTableName = ClassTypeInfo; @@ -4109,8 +4106,8 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, return llvm::GlobalValue::LinkOnceODRLinkage; if (const RecordType *Record = dyn_cast<RecordType>(Ty)) { - const CXXRecordDecl *RD = - cast<CXXRecordDecl>(Record->getOriginalDecl())->getDefinitionOrSelf(); + const auto *RD = + cast<CXXRecordDecl>(Record->getDecl())->getDefinitionOrSelf(); if (RD->hasAttr<WeakAttr>()) return llvm::GlobalValue::WeakODRLinkage; if (CGM.getTriple().isWindowsItaniumEnvironment()) @@ -4273,9 +4270,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( break; case Type::Record: { - const CXXRecordDecl *RD = - cast<CXXRecordDecl>(cast<RecordType>(Ty)->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *RD = cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl()) + ->getDefinitionOrSelf(); if (!RD->hasDefinition() || !RD->getNumBases()) { // We don't need to emit any fields. break; @@ -4322,8 +4318,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo( if (CGM.getTarget().hasPS4DLLImportExport() && GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) { if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { - const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getOriginalDecl()) - ->getDefinitionOrSelf(); + const auto *RD = + cast<CXXRecordDecl>(RecordTy->getDecl())->getDefinitionOrSelf(); if (RD->hasAttr<DLLExportAttr>() || CXXRecordNonInlineHasAttr<DLLExportAttr>(RD)) GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass; diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp index 4d894fd..20965430 100644 --- a/clang/lib/CodeGen/SwiftCallingConv.cpp +++ b/clang/lib/CodeGen/SwiftCallingConv.cpp @@ -66,7 +66,7 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) { // Record types. if (auto recType = type->getAsCanonical<RecordType>()) { - addTypedData(recType->getOriginalDecl(), begin); + addTypedData(recType->getDecl(), begin); // Array types. } else if (type->isArrayType()) { @@ -814,7 +814,7 @@ static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, bool forReturn) { unsigned IndirectAS = CGM.getDataLayout().getAllocaAddrSpace(); if (auto recordType = dyn_cast<RecordType>(type)) { - auto record = recordType->getOriginalDecl(); + auto record = recordType->getDecl(); auto &layout = CGM.getContext().getASTRecordLayout(record); if (mustPassRecordIndirectly(CGM, record)) @@ -822,8 +822,7 @@ static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, /*AddrSpace=*/IndirectAS, /*byval=*/false); SwiftAggLowering lowering(CGM); - lowering.addTypedData(recordType->getOriginalDecl(), CharUnits::Zero(), - layout); + lowering.addTypedData(recordType->getDecl(), CharUnits::Zero(), layout); lowering.finish(); return classifyExpandedType(lowering, forReturn, layout.getAlignment(), diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index d7deece..bb41a14 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -743,7 +743,7 @@ bool AArch64ABIInfo::passAsPureScalableType( return false; // Pure scalable types are never unions and never contain unions. - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); if (RD->isUnion()) return false; diff --git a/clang/lib/CodeGen/Targets/ARC.cpp b/clang/lib/CodeGen/Targets/ARC.cpp index 6727587..6c9444d 100644 --- a/clang/lib/CodeGen/Targets/ARC.cpp +++ b/clang/lib/CodeGen/Targets/ARC.cpp @@ -112,8 +112,7 @@ ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty, if (isAggregateTypeForABI(Ty)) { // Structures with flexible arrays are always indirect. - if (RT && - RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) + if (RT && RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return getIndirectByValue(Ty); // Ignore empty structs/unions. diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp index c84c9f2..4d05217 100644 --- a/clang/lib/CodeGen/Targets/ARM.cpp +++ b/clang/lib/CodeGen/Targets/ARM.cpp @@ -516,7 +516,7 @@ static bool isIntegerLikeType(QualType Ty, ASTContext &Context, if (!RT) return false; // Ignore records with flexible arrays. - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return false; diff --git a/clang/lib/CodeGen/Targets/Lanai.cpp b/clang/lib/CodeGen/Targets/Lanai.cpp index e76431a..871a135 100644 --- a/clang/lib/CodeGen/Targets/Lanai.cpp +++ b/clang/lib/CodeGen/Targets/Lanai.cpp @@ -102,8 +102,7 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty, if (isAggregateTypeForABI(Ty)) { // Structures with flexible arrays are always indirect. - if (RT && - RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) + if (RT && RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return getIndirectResult(Ty, /*ByVal=*/true, State); // Ignore empty structs/unions. diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp index 1f344d6..878723d 100644 --- a/clang/lib/CodeGen/Targets/LoongArch.cpp +++ b/clang/lib/CodeGen/Targets/LoongArch.cpp @@ -150,7 +150,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( // Non-zero-length arrays of empty records make the struct ineligible to be // passed via FARs in C++. if (const auto *RTy = EltTy->getAsCanonical<RecordType>()) { - if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getOriginalDecl()) && + if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) && isEmptyRecord(getContext(), EltTy, true, true)) return false; } @@ -169,7 +169,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( // copy constructor are not eligible for the FP calling convention. if (getRecordArgABI(Ty, CGT.getCXXABI())) return false; - const RecordDecl *RD = RTy->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RTy->getDecl()->getDefinitionOrSelf(); if (isEmptyRecord(getContext(), Ty, true, true) && (!RD->isUnion() || !isa<CXXRecordDecl>(RD))) return true; diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp index f26ab97..22fdcd9 100644 --- a/clang/lib/CodeGen/Targets/Mips.cpp +++ b/clang/lib/CodeGen/Targets/Mips.cpp @@ -161,7 +161,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const { return llvm::StructType::get(getVMContext(), ArgList); } - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); assert(!(TySize % 8) && "Size of structure must be multiple of 8."); @@ -265,7 +265,7 @@ MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const { SmallVector<llvm::Type*, 8> RTList; if (RT && RT->isStructureOrClassType()) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); unsigned FieldCnt = Layout.getFieldCount(); diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 0d0941e..d134589 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -234,7 +234,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, // Non-zero-length arrays of empty records make the struct ineligible for // the FP calling convention in C++. if (const auto *RTy = EltTy->getAsCanonical<RecordType>()) { - if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getOriginalDecl()) && + if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) && isEmptyRecord(getContext(), EltTy, true, true)) return false; } @@ -256,7 +256,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, return false; if (isEmptyRecord(getContext(), Ty, true, true)) return true; - const RecordDecl *RD = RTy->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RTy->getDecl()->getDefinitionOrSelf(); // Unions aren't eligible unless they're empty (which is caught above). if (RD->isUnion()) return false; diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index fb78948..8daf8eb 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -795,8 +795,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State, if (isAggregateTypeForABI(Ty)) { // Structures with flexible arrays are always indirect. // FIXME: This should not be byval! - if (RT && - RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) + if (RT && RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return getIndirectResult(Ty, true, State); // Ignore empty structs/unions on non-Windows. @@ -831,7 +830,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State, unsigned AlignInBits = 0; if (RT) { const ASTRecordLayout &Layout = - getContext().getASTRecordLayout(RT->getOriginalDecl()); + getContext().getASTRecordLayout(RT->getDecl()); AlignInBits = getContext().toBits(Layout.getRequiredAlignment()); } else if (TI.isAlignRequired()) { AlignInBits = TI.Align; @@ -2042,7 +2041,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, if (getRecordArgABI(RT, getCXXABI())) return; - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); // Assume variable sized types are passed in memory. if (RD->hasFlexibleArrayMember()) @@ -2851,9 +2850,8 @@ ABIArgInfo X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt, unsigned &NeededSSE, unsigned &MaxVectorWidth) const { - auto *RD = cast<RecordType>(Ty.getCanonicalType()) - ->getOriginalDecl() - ->getDefinitionOrSelf(); + auto *RD = + cast<RecordType>(Ty.getCanonicalType())->getDecl()->getDefinitionOrSelf(); if (RD->hasFlexibleArrayMember()) return getIndirectReturnResult(Ty); @@ -3313,7 +3311,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs, RAA == CGCXXABI::RAA_DirectInMemory); } - if (RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) + if (RT->getDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember()) return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(), /*ByVal=*/false); } diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp index ab01154..f9726ec 100644 --- a/clang/lib/CodeGen/Targets/XCore.cpp +++ b/clang/lib/CodeGen/Targets/XCore.cpp @@ -380,7 +380,7 @@ static bool appendRecordType(SmallStringEnc &Enc, const RecordType *RT, // We collect all encoded fields and order as necessary. bool IsRecursive = false; - const RecordDecl *RD = RT->getOriginalDecl()->getDefinition(); + const RecordDecl *RD = RT->getDecl()->getDefinition(); if (RD && !RD->field_empty()) { // An incomplete TypeString stub is placed in the cache for this RecordType // so that recursive calls to this RecordType will use it whilst building a @@ -429,7 +429,7 @@ static bool appendEnumType(SmallStringEnc &Enc, const EnumType *ET, Enc += "){"; // We collect all encoded enumerations and order them alphanumerically. - if (const EnumDecl *ED = ET->getOriginalDecl()->getDefinition()) { + if (const EnumDecl *ED = ET->getDecl()->getDefinition()) { SmallVector<FieldEncoding, 16> FE; for (auto I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E; ++I) { diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp index 880e9e3..715429b 100644 --- a/clang/lib/Driver/Job.cpp +++ b/clang/lib/Driver/Job.cpp @@ -57,24 +57,25 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, SkipNum = 2; // These flags are all of the form -Flag <Arg> and are treated as two // arguments. Therefore, we need to skip the flag and the next argument. - bool ShouldSkip = llvm::StringSwitch<bool>(Flag) - .Cases("-MF", "-MT", "-MQ", "-serialize-diagnostic-file", true) - .Cases("-o", "-dependency-file", true) - .Cases("-fdebug-compilation-dir", "-diagnostic-log-file", true) - .Cases("-dwarf-debug-flags", "-ivfsoverlay", true) - .Default(false); + bool ShouldSkip = + llvm::StringSwitch<bool>(Flag) + .Cases({"-MF", "-MT", "-MQ", "-serialize-diagnostic-file"}, true) + .Cases({"-o", "-dependency-file"}, true) + .Cases({"-fdebug-compilation-dir", "-diagnostic-log-file"}, true) + .Cases({"-dwarf-debug-flags", "-ivfsoverlay"}, true) + .Default(false); if (ShouldSkip) return true; // Some include flags shouldn't be skipped if we have a crash VFS IsInclude = llvm::StringSwitch<bool>(Flag) - .Cases("-include", "-header-include-file", true) - .Cases("-idirafter", "-internal-isystem", "-iwithprefix", true) - .Cases("-internal-externc-isystem", "-iprefix", true) - .Cases("-iwithprefixbefore", "-isystem", "-iquote", true) - .Cases("-isysroot", "-I", "-F", "-resource-dir", true) - .Cases("-internal-iframework", "-iframework", "-include-pch", true) + .Cases({"-include", "-header-include-file"}, true) + .Cases({"-idirafter", "-internal-isystem", "-iwithprefix"}, true) + .Cases({"-internal-externc-isystem", "-iprefix"}, true) + .Cases({"-iwithprefixbefore", "-isystem", "-iquote"}, true) + .Cases({"-isysroot", "-I", "-F", "-resource-dir"}, true) + .Cases({"-internal-iframework", "-iframework", "-include-pch"}, true) .Default(false); if (IsInclude) return !HaveCrashVFS; @@ -83,9 +84,9 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, // These flags are all of the form -Flag and have no second argument. ShouldSkip = llvm::StringSwitch<bool>(Flag) - .Cases("-M", "-MM", "-MG", "-MP", "-MD", true) - .Case("-MMD", true) - .Default(false); + .Cases({"-M", "-MM", "-MG", "-MP", "-MD"}, true) + .Case("-MMD", true) + .Default(false); // Match found. SkipNum = 1; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index bf75573..f4bdfa5 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -9214,8 +9214,9 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_nogpulibc)) { forAllAssociatedToolChains(C, JA, getToolChain(), [&](const ToolChain &TC) { // The device C library is only available for NVPTX and AMDGPU targets - // currently. - if (!TC.getTriple().isNVPTX() && !TC.getTriple().isAMDGPU()) + // and we only link it by default for OpenMP currently. + if ((!TC.getTriple().isNVPTX() && !TC.getTriple().isAMDGPU()) || + !JA.isHostOffloading(Action::OFK_OpenMP)) return; bool HasLibC = TC.getStdlibIncludePath().has_value(); if (HasLibC) { diff --git a/clang/lib/Driver/XRayArgs.cpp b/clang/lib/Driver/XRayArgs.cpp index ceed7cb..0325296 100644 --- a/clang/lib/Driver/XRayArgs.cpp +++ b/clang/lib/Driver/XRayArgs.cpp @@ -105,8 +105,9 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { for (const auto &P : BundleParts) { // TODO: Automate the generation of the string case table. auto Valid = llvm::StringSwitch<bool>(P) - .Cases("none", "all", "function", "function-entry", - "function-exit", "custom", true) + .Cases({"none", "all", "function", "function-entry", + "function-exit", "custom"}, + true) .Default(false); if (!Valid) { diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 541af6d..e5eda46 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -422,7 +422,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( Fragments.append(getFragmentsForNNS(TagTy->getQualifier(), Context, After)); - const TagDecl *Decl = TagTy->getOriginalDecl(); + const TagDecl *Decl = TagTy->getDecl(); // Anonymous decl, skip this fragment. if (Decl->getName().empty()) return Fragments.append("{ ... }", diff --git a/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp b/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp index 5adbbc6..41e4e0c 100644 --- a/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp +++ b/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp @@ -26,7 +26,7 @@ TypedefUnderlyingTypeResolver::getUnderlyingTypeDecl(QualType Type) const { if (TypedefTy) TypeDecl = TypedefTy->getDecl(); if (const TagType *TagTy = Type->getAs<TagType>()) { - TypeDecl = TagTy->getOriginalDecl(); + TypeDecl = TagTy->getDecl(); } else if (const ObjCInterfaceType *ObjCITy = Type->getAs<ObjCInterfaceType>()) { TypeDecl = ObjCITy->getDecl(); diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 54f366f..7348a3a 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -289,17 +289,20 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, SmallVector<WhitespaceManager::Change, 16> &Changes) { int Shift = 0; - // ScopeStack keeps track of the current scope depth. It contains indices of - // the first token on each scope. + // ScopeStack keeps track of the current scope depth. It contains the levels + // of at most 2 scopes. The first one is the one that the matched token is + // in. The second one is the one that should not be moved by this procedure. // The "Matches" indices should only have tokens from the outer-most scope. // However, we do need to pay special attention to one class of tokens - // that are not in the outer-most scope, and that is function parameters - // which are split across multiple lines, as illustrated by this example: + // that are not in the outer-most scope, and that is the continuations of an + // unwrapped line whose positions are derived from a token to the right of the + // aligned token, as illustrated by this example: // double a(int x); // int b(int y, // double z); // In the above example, we need to take special care to ensure that - // 'double z' is indented along with it's owning function 'b'. + // 'double z' is indented along with its owning function 'b', because its + // position is derived from the '(' token to the right of the 'b' token. // The same holds for calling a function: // double a = foo(x); // int b = bar(foo(y), @@ -309,32 +312,28 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, // auto s = "Hello" // "World"; // Special handling is required for 'nested' ternary operators. - SmallVector<unsigned, 16> ScopeStack; + SmallVector<std::tuple<unsigned, unsigned, unsigned>, 2> ScopeStack; for (unsigned i = Start; i != End; ++i) { auto &CurrentChange = Changes[i]; if (!Matches.empty() && Matches[0] < i) Matches.consume_front(); assert(Matches.empty() || Matches[0] >= i); - if (!ScopeStack.empty() && - CurrentChange.indentAndNestingLevel() < - Changes[ScopeStack.back()].indentAndNestingLevel()) { + while (!ScopeStack.empty() && + CurrentChange.indentAndNestingLevel() < ScopeStack.back()) { ScopeStack.pop_back(); } - // Compare current token to previous non-comment token to ensure whether - // it is in a deeper scope or not. - unsigned PreviousNonComment = i - 1; - while (PreviousNonComment > Start && - Changes[PreviousNonComment].Tok->is(tok::comment)) { - --PreviousNonComment; - } - if (i != Start && CurrentChange.indentAndNestingLevel() > - Changes[PreviousNonComment].indentAndNestingLevel()) { - ScopeStack.push_back(i); + // Keep track of the level that should not move with the aligned token. + if (ScopeStack.size() == 1u && CurrentChange.NewlinesBefore != 0u && + CurrentChange.indentAndNestingLevel() > ScopeStack[0] && + !CurrentChange.IsAligned) { + ScopeStack.push_back(CurrentChange.indentAndNestingLevel()); } - bool InsideNestedScope = !ScopeStack.empty(); + bool InsideNestedScope = + !ScopeStack.empty() && + CurrentChange.indentAndNestingLevel() > ScopeStack[0]; bool ContinuedStringLiteral = i > Start && CurrentChange.Tok->is(tok::string_literal) && Changes[i - 1].Tok->is(tok::string_literal); @@ -349,103 +348,20 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End, if (!Matches.empty() && Matches[0] == i) { Shift = Column - (RightJustify ? CurrentChange.TokenLength : 0) - CurrentChange.StartOfTokenColumn; + ScopeStack = {CurrentChange.indentAndNestingLevel()}; CurrentChange.Spaces += Shift; } if (Shift == 0) continue; - // This is for function parameters that are split across multiple lines, - // as mentioned in the ScopeStack comment. - if (InsideNestedScope && CurrentChange.NewlinesBefore > 0) { - unsigned ScopeStart = ScopeStack.back(); - auto ShouldShiftBeAdded = [&] { - // Function declaration - if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName)) - return true; - - // Lambda. - if (Changes[ScopeStart - 1].Tok->is(TT_LambdaLBrace)) - return false; - - // Continued function declaration - if (ScopeStart > Start + 1 && - Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) { - return true; - } - - // Continued (template) function call. - if (ScopeStart > Start + 1 && - Changes[ScopeStart - 2].Tok->isOneOf(tok::identifier, - TT_TemplateCloser) && - Changes[ScopeStart - 1].Tok->is(tok::l_paren) && - Changes[ScopeStart].Tok->isNot(TT_LambdaLSquare)) { - if (CurrentChange.Tok->MatchingParen && - CurrentChange.Tok->MatchingParen->is(TT_LambdaLBrace)) { - return false; - } - if (Changes[ScopeStart].NewlinesBefore > 0) - return false; - if (CurrentChange.Tok->is(tok::l_brace) && - CurrentChange.Tok->is(BK_BracedInit)) { - return true; - } - return Style.BinPackArguments; - } - - // Ternary operator - if (CurrentChange.Tok->is(TT_ConditionalExpr)) - return true; - - // Period Initializer .XXX = 1. - if (CurrentChange.Tok->is(TT_DesignatedInitializerPeriod)) - return true; - - // Continued ternary operator - if (CurrentChange.Tok->Previous && - CurrentChange.Tok->Previous->is(TT_ConditionalExpr)) { - return true; - } - - // Continued direct-list-initialization using braced list. - if (ScopeStart > Start + 1 && - Changes[ScopeStart - 2].Tok->is(tok::identifier) && - Changes[ScopeStart - 1].Tok->is(tok::l_brace) && - CurrentChange.Tok->is(tok::l_brace) && - CurrentChange.Tok->is(BK_BracedInit)) { - return true; - } - - // Continued braced list. - if (ScopeStart > Start + 1 && - Changes[ScopeStart - 2].Tok->isNot(tok::identifier) && - Changes[ScopeStart - 1].Tok->is(tok::l_brace) && - CurrentChange.Tok->isNot(tok::r_brace)) { - for (unsigned OuterScopeStart : llvm::reverse(ScopeStack)) { - // Lambda. - if (OuterScopeStart > Start && - Changes[OuterScopeStart - 1].Tok->is(TT_LambdaLBrace)) { - return false; - } - } - if (Changes[ScopeStart].NewlinesBefore > 0) - return false; - return true; - } - - // Continued template parameter. - if (Changes[ScopeStart - 1].Tok->is(TT_TemplateOpener)) - return true; - - return false; - }; - - if (ShouldShiftBeAdded()) - CurrentChange.Spaces += Shift; - } - - if (ContinuedStringLiteral) + // This is for lines that are split across multiple lines, as mentioned in + // the ScopeStack comment. The stack size being 1 means that the token is + // not in a scope that should not move. + if (ScopeStack.size() == 1u && CurrentChange.NewlinesBefore > 0 && + (ContinuedStringLiteral || InsideNestedScope)) { CurrentChange.Spaces += Shift; + } // We should not remove required spaces unless we break the line before. assert(Shift > 0 || Changes[i].NewlinesBefore > 0 || diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 292adce..5bd15f5 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -4012,13 +4012,13 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, auto Diag = Diags.Report(diag::note_drv_use_standard); Diag << Std.getName() << Std.getDescription(); unsigned NumAliases = 0; -#define LANGSTANDARD(id, name, lang, desc, features) +#define LANGSTANDARD(id, name, lang, desc, features, version) #define LANGSTANDARD_ALIAS(id, alias) \ if (KindValue == LangStandard::lang_##id) ++NumAliases; #define LANGSTANDARD_ALIAS_DEPR(id, alias) #include "clang/Basic/LangStandards.def" Diag << NumAliases; -#define LANGSTANDARD(id, name, lang, desc, features) +#define LANGSTANDARD(id, name, lang, desc, features, version) #define LANGSTANDARD_ALIAS(id, alias) \ if (KindValue == LangStandard::lang_##id) Diag << alias; #define LANGSTANDARD_ALIAS_DEPR(id, alias) diff --git a/clang/lib/Frontend/FrontendOptions.cpp b/clang/lib/Frontend/FrontendOptions.cpp index 32ed995..fb178b6 100644 --- a/clang/lib/Frontend/FrontendOptions.cpp +++ b/clang/lib/Frontend/FrontendOptions.cpp @@ -14,25 +14,26 @@ using namespace clang; InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) { return llvm::StringSwitch<InputKind>(Extension) - .Cases("ast", "pcm", InputKind(Language::Unknown, InputKind::Precompiled)) + .Cases({"ast", "pcm"}, + InputKind(Language::Unknown, InputKind::Precompiled)) .Case("c", Language::C) - .Cases("S", "s", Language::Asm) + .Cases({"S", "s"}, Language::Asm) .Case("i", InputKind(Language::C).getPreprocessed()) .Case("ii", InputKind(Language::CXX).getPreprocessed()) .Case("cui", InputKind(Language::CUDA).getPreprocessed()) .Case("m", Language::ObjC) .Case("mi", InputKind(Language::ObjC).getPreprocessed()) - .Cases("mm", "M", Language::ObjCXX) + .Cases({"mm", "M"}, Language::ObjCXX) .Case("mii", InputKind(Language::ObjCXX).getPreprocessed()) - .Cases("C", "cc", "cp", Language::CXX) - .Cases("cpp", "CPP", "c++", "cxx", "hpp", "hxx", Language::CXX) + .Cases({"C", "cc", "cp"}, Language::CXX) + .Cases({"cpp", "CPP", "c++", "cxx", "hpp", "hxx"}, Language::CXX) .Case("cppm", Language::CXX) - .Cases("iim", "iih", InputKind(Language::CXX).getPreprocessed()) + .Cases({"iim", "iih"}, InputKind(Language::CXX).getPreprocessed()) .Case("cl", Language::OpenCL) .Case("clcpp", Language::OpenCLCXX) - .Cases("cu", "cuh", Language::CUDA) + .Cases({"cu", "cuh"}, Language::CUDA) .Case("hip", Language::HIP) - .Cases("ll", "bc", Language::LLVM_IR) + .Cases({"ll", "bc"}, Language::LLVM_IR) .Case("hlsl", Language::HLSL) .Case("cir", Language::CIR) .Default(Language::Unknown); diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index b899fb9..baad6317 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -459,43 +459,12 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, // value is, are implementation-defined. // (Removed in C++20.) if (!LangOpts.CPlusPlus) { - if (LangOpts.C2y) - Builder.defineMacro("__STDC_VERSION__", "202400L"); - else if (LangOpts.C23) - Builder.defineMacro("__STDC_VERSION__", "202311L"); - else if (LangOpts.C17) - Builder.defineMacro("__STDC_VERSION__", "201710L"); - else if (LangOpts.C11) - Builder.defineMacro("__STDC_VERSION__", "201112L"); - else if (LangOpts.C99) - Builder.defineMacro("__STDC_VERSION__", "199901L"); - else if (!LangOpts.GNUMode && LangOpts.Digraphs) - Builder.defineMacro("__STDC_VERSION__", "199409L"); + if (std::optional<uint32_t> Lang = LangOpts.getCLangStd()) + Builder.defineMacro("__STDC_VERSION__", Twine(*Lang) + "L"); } else { // -- __cplusplus - if (LangOpts.CPlusPlus26) - // FIXME: Use correct value for C++26. - Builder.defineMacro("__cplusplus", "202400L"); - else if (LangOpts.CPlusPlus23) - Builder.defineMacro("__cplusplus", "202302L"); - // [C++20] The integer literal 202002L. - else if (LangOpts.CPlusPlus20) - Builder.defineMacro("__cplusplus", "202002L"); - // [C++17] The integer literal 201703L. - else if (LangOpts.CPlusPlus17) - Builder.defineMacro("__cplusplus", "201703L"); - // [C++14] The name __cplusplus is defined to the value 201402L when - // compiling a C++ translation unit. - else if (LangOpts.CPlusPlus14) - Builder.defineMacro("__cplusplus", "201402L"); - // [C++11] The name __cplusplus is defined to the value 201103L when - // compiling a C++ translation unit. - else if (LangOpts.CPlusPlus11) - Builder.defineMacro("__cplusplus", "201103L"); - // [C++03] The name __cplusplus is defined to the value 199711L when - // compiling a C++ translation unit. - else - Builder.defineMacro("__cplusplus", "199711L"); + Builder.defineMacro("__cplusplus", + Twine(*LangOpts.getCPlusPlusLangStd()) + "L"); // -- __STDCPP_DEFAULT_NEW_ALIGNMENT__ // [C++17] An integer literal of type std::size_t whose value is the diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 42f2d65..dee29fe 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -852,7 +852,7 @@ RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); if (!IvarT->getAs<TypedefType>() && IvarT->isRecordType()) { - RecordDecl *RD = IvarT->castAsCanonical<RecordType>()->getOriginalDecl(); + RecordDecl *RD = IvarT->castAsCanonical<RecordType>()->getDecl(); RD = RD->getDefinition(); if (RD && !RD->getDeclName().getAsIdentifierInfo()) { // decltype(((Foo_IMPL*)0)->bar) * @@ -7453,8 +7453,7 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { IvarT = GetGroupRecordTypeForObjCIvarBitfield(D); if (!IvarT->getAs<TypedefType>() && IvarT->isRecordType()) { - RecordDecl *RD = - IvarT->castAsCanonical<RecordType>()->getOriginalDecl(); + RecordDecl *RD = IvarT->castAsCanonical<RecordType>()->getDecl(); RD = RD->getDefinition(); if (RD && !RD->getDeclName().getAsIdentifierInfo()) { // decltype(((Foo_IMPL*)0)->bar) * diff --git a/clang/lib/Headers/avx2intrin.h b/clang/lib/Headers/avx2intrin.h index e150aa6..fa7f4c2 100644 --- a/clang/lib/Headers/avx2intrin.h +++ b/clang/lib/Headers/avx2intrin.h @@ -1852,9 +1852,8 @@ _mm256_sad_epu8(__m256i __a, __m256i __b) /// control byte specify the index (within the same 128-bit half) of \a __a /// to copy to the result byte. /// \returns A 256-bit integer vector containing the result. -static __inline__ __m256i __DEFAULT_FN_ATTRS256 -_mm256_shuffle_epi8(__m256i __a, __m256i __b) -{ +static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR +_mm256_shuffle_epi8(__m256i __a, __m256i __b) { return (__m256i)__builtin_ia32_pshufb256((__v32qi)__a, (__v32qi)__b); } diff --git a/clang/lib/Headers/avx512bwintrin.h b/clang/lib/Headers/avx512bwintrin.h index 473fe94..23b2d29 100644 --- a/clang/lib/Headers/avx512bwintrin.h +++ b/clang/lib/Headers/avx512bwintrin.h @@ -866,23 +866,20 @@ _mm512_mask_min_epu16(__m512i __W, __mmask32 __M, __m512i __A, __m512i __B) { (__v32hi)__W); } -static __inline__ __m512i __DEFAULT_FN_ATTRS512 -_mm512_shuffle_epi8(__m512i __A, __m512i __B) -{ +static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR +_mm512_shuffle_epi8(__m512i __A, __m512i __B) { return (__m512i)__builtin_ia32_pshufb512((__v64qi)__A,(__v64qi)__B); } -static __inline__ __m512i __DEFAULT_FN_ATTRS512 -_mm512_mask_shuffle_epi8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) -{ +static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR +_mm512_mask_shuffle_epi8(__m512i __W, __mmask64 __U, __m512i __A, __m512i __B) { return (__m512i)__builtin_ia32_selectb_512((__mmask64)__U, (__v64qi)_mm512_shuffle_epi8(__A, __B), (__v64qi)__W); } -static __inline__ __m512i __DEFAULT_FN_ATTRS512 -_mm512_maskz_shuffle_epi8(__mmask64 __U, __m512i __A, __m512i __B) -{ +static __inline__ __m512i __DEFAULT_FN_ATTRS512_CONSTEXPR +_mm512_maskz_shuffle_epi8(__mmask64 __U, __m512i __A, __m512i __B) { return (__m512i)__builtin_ia32_selectb_512((__mmask64)__U, (__v64qi)_mm512_shuffle_epi8(__A, __B), (__v64qi)_mm512_setzero_si512()); diff --git a/clang/lib/Headers/avx512cdintrin.h b/clang/lib/Headers/avx512cdintrin.h index 8899298..b161440 100644 --- a/clang/lib/Headers/avx512cdintrin.h +++ b/clang/lib/Headers/avx512cdintrin.h @@ -109,17 +109,14 @@ _mm512_maskz_lzcnt_epi64(__mmask8 __U, __m512i __A) { (__v8di)_mm512_setzero_si512()); } -static __inline__ __m512i __DEFAULT_FN_ATTRS -_mm512_broadcastmb_epi64 (__mmask8 __A) -{ +static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR +_mm512_broadcastmb_epi64(__mmask8 __A) { return (__m512i) _mm512_set1_epi64((long long) __A); } -static __inline__ __m512i __DEFAULT_FN_ATTRS -_mm512_broadcastmw_epi32 (__mmask16 __A) -{ - return (__m512i) _mm512_set1_epi32((int) __A); - +static __inline__ __m512i __DEFAULT_FN_ATTRS_CONSTEXPR +_mm512_broadcastmw_epi32(__mmask16 __A) { + return (__m512i)_mm512_set1_epi32((int)__A); } #undef __DEFAULT_FN_ATTRS diff --git a/clang/lib/Headers/avx512vlbwintrin.h b/clang/lib/Headers/avx512vlbwintrin.h index 81e4cbb9..639fb60 100644 --- a/clang/lib/Headers/avx512vlbwintrin.h +++ b/clang/lib/Headers/avx512vlbwintrin.h @@ -1067,33 +1067,29 @@ _mm256_mask_min_epu16(__m256i __W, __mmask16 __M, __m256i __A, __m256i __B) { (__v16hi)__W); } -static __inline__ __m128i __DEFAULT_FN_ATTRS128 -_mm_mask_shuffle_epi8(__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) -{ +static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR +_mm_mask_shuffle_epi8(__m128i __W, __mmask16 __U, __m128i __A, __m128i __B) { return (__m128i)__builtin_ia32_selectb_128((__mmask16)__U, (__v16qi)_mm_shuffle_epi8(__A, __B), (__v16qi)__W); } -static __inline__ __m128i __DEFAULT_FN_ATTRS128 -_mm_maskz_shuffle_epi8(__mmask16 __U, __m128i __A, __m128i __B) -{ +static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR +_mm_maskz_shuffle_epi8(__mmask16 __U, __m128i __A, __m128i __B) { return (__m128i)__builtin_ia32_selectb_128((__mmask16)__U, (__v16qi)_mm_shuffle_epi8(__A, __B), (__v16qi)_mm_setzero_si128()); } -static __inline__ __m256i __DEFAULT_FN_ATTRS256 -_mm256_mask_shuffle_epi8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) -{ +static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR +_mm256_mask_shuffle_epi8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B) { return (__m256i)__builtin_ia32_selectb_256((__mmask32)__U, (__v32qi)_mm256_shuffle_epi8(__A, __B), (__v32qi)__W); } -static __inline__ __m256i __DEFAULT_FN_ATTRS256 -_mm256_maskz_shuffle_epi8(__mmask32 __U, __m256i __A, __m256i __B) -{ +static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR +_mm256_maskz_shuffle_epi8(__mmask32 __U, __m256i __A, __m256i __B) { return (__m256i)__builtin_ia32_selectb_256((__mmask32)__U, (__v32qi)_mm256_shuffle_epi8(__A, __B), (__v32qi)_mm256_setzero_si256()); diff --git a/clang/lib/Headers/avx512vlcdintrin.h b/clang/lib/Headers/avx512vlcdintrin.h index 30c9f90..cb98e7c 100644 --- a/clang/lib/Headers/avx512vlcdintrin.h +++ b/clang/lib/Headers/avx512vlcdintrin.h @@ -29,31 +29,26 @@ #define __DEFAULT_FN_ATTRS128_CONSTEXPR __DEFAULT_FN_ATTRS128 #endif -static __inline__ __m128i __DEFAULT_FN_ATTRS128 -_mm_broadcastmb_epi64 (__mmask8 __A) -{ +static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR +_mm_broadcastmb_epi64(__mmask8 __A) { return (__m128i) _mm_set1_epi64x((long long) __A); } -static __inline__ __m256i __DEFAULT_FN_ATTRS256 -_mm256_broadcastmb_epi64 (__mmask8 __A) -{ +static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR +_mm256_broadcastmb_epi64(__mmask8 __A) { return (__m256i) _mm256_set1_epi64x((long long)__A); } -static __inline__ __m128i __DEFAULT_FN_ATTRS128 -_mm_broadcastmw_epi32 (__mmask16 __A) -{ +static __inline__ __m128i __DEFAULT_FN_ATTRS128_CONSTEXPR +_mm_broadcastmw_epi32(__mmask16 __A) { return (__m128i) _mm_set1_epi32((int)__A); } -static __inline__ __m256i __DEFAULT_FN_ATTRS256 -_mm256_broadcastmw_epi32 (__mmask16 __A) -{ +static __inline__ __m256i __DEFAULT_FN_ATTRS256_CONSTEXPR +_mm256_broadcastmw_epi32(__mmask16 __A) { return (__m256i) _mm256_set1_epi32((int)__A); } - static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_conflict_epi64 (__m128i __A) { diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h index f902ca1..ad28f06 100644 --- a/clang/lib/Headers/ptrauth.h +++ b/clang/lib/Headers/ptrauth.h @@ -241,6 +241,18 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; #define ptrauth_type_discriminator(__type) \ __builtin_ptrauth_type_discriminator(__type) +/* Compute the constant discriminator used by Clang to sign pointers with the + given C function pointer type. + + A call to this function is an integer constant expression. */ +#if __has_feature(ptrauth_function_pointer_type_discrimination) +#define ptrauth_function_pointer_type_discriminator(__type) \ + __builtin_ptrauth_type_discriminator(__type) +#else +#define ptrauth_function_pointer_type_discriminator(__type) \ + ((ptrauth_extra_data_t)0) +#endif + /* Compute a signature for the given pair of pointer-sized values. The order of the arguments is significant. @@ -372,6 +384,8 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; }) #define ptrauth_type_discriminator(__type) ((ptrauth_extra_data_t)0) +#define ptrauth_function_pointer_type_discriminator(__type) \ + ((ptrauth_extra_data_t)0) #define ptrauth_sign_generic_data(__value, __data) \ ({ \ diff --git a/clang/lib/Headers/tmmintrin.h b/clang/lib/Headers/tmmintrin.h index 9d007c8..ee96caa 100644 --- a/clang/lib/Headers/tmmintrin.h +++ b/clang/lib/Headers/tmmintrin.h @@ -590,10 +590,9 @@ _mm_mulhrs_pi16(__m64 __a, __m64 __b) /// Bits [6:4] Reserved. \n /// Bits [3:0] select the source byte to be copied. /// \returns A 128-bit integer vector containing the copied or cleared values. -static __inline__ __m128i __DEFAULT_FN_ATTRS -_mm_shuffle_epi8(__m128i __a, __m128i __b) -{ - return (__m128i)__builtin_ia32_pshufb128((__v16qi)__a, (__v16qi)__b); +static __inline__ __m128i __DEFAULT_FN_ATTRS_CONSTEXPR +_mm_shuffle_epi8(__m128i __a, __m128i __b) { + return (__m128i)__builtin_ia32_pshufb128((__v16qi)__a, (__v16qi)__b); } /// Copies the 8-bit integers from a 64-bit integer vector to the @@ -615,13 +614,12 @@ _mm_shuffle_epi8(__m128i __a, __m128i __b) /// destination. \n /// Bits [2:0] select the source byte to be copied. /// \returns A 64-bit integer vector containing the copied or cleared values. -static __inline__ __m64 __DEFAULT_FN_ATTRS -_mm_shuffle_pi8(__m64 __a, __m64 __b) -{ - return __trunc64(__builtin_ia32_pshufb128( - (__v16qi)__builtin_shufflevector( - (__v2si)(__a), __extension__ (__v2si){}, 0, 1, 0, 1), - (__v16qi)__anyext128(__b))); +static __inline__ __m64 __DEFAULT_FN_ATTRS_CONSTEXPR +_mm_shuffle_pi8(__m64 __a, __m64 __b) { + return __trunc64(__builtin_ia32_pshufb128( + (__v16qi)__builtin_shufflevector((__v2si)(__a), __extension__(__v2si){}, + 0, 1, 0, 1), + (__v16qi)__zext128(__b))); } /// For each 8-bit integer in the first source operand, perform one of diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp index 74c6c11..3c1e038 100644 --- a/clang/lib/Index/IndexTypeSourceInfo.cpp +++ b/clang/lib/Index/IndexTypeSourceInfo.cpp @@ -117,7 +117,7 @@ public: } bool VisitTagTypeLoc(TagTypeLoc TL) { - TagDecl *D = TL.getOriginalDecl(); + TagDecl *D = TL.getDecl(); if (!IndexCtx.shouldIndexFunctionLocalSymbols() && D->getParentFunctionOrMethod()) return true; diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index c78d66f..08835ea 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -911,11 +911,10 @@ void USRGenerator::VisitType(QualType T) { } if (const TagType *TT = T->getAs<TagType>()) { if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TT)) { - T = ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType( - Ctx); + T = ICNT->getDecl()->getCanonicalTemplateSpecializationType(Ctx); } else { Out << '$'; - VisitTagDecl(TT->getOriginalDecl()); + VisitTagDecl(TT->getDecl()); return; } } diff --git a/clang/lib/InstallAPI/HeaderFile.cpp b/clang/lib/InstallAPI/HeaderFile.cpp index 0b7041e..d736a0a 100644 --- a/clang/lib/InstallAPI/HeaderFile.cpp +++ b/clang/lib/InstallAPI/HeaderFile.cpp @@ -38,7 +38,7 @@ std::optional<std::string> createIncludeHeaderName(const StringRef FullPath) { bool isHeaderFile(StringRef Path) { return StringSwitch<bool>(sys::path::extension(Path)) - .Cases(".h", ".H", ".hh", ".hpp", ".hxx", true) + .Cases({".h", ".H", ".hh", ".hpp", ".hxx"}, true) .Default(false); } diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp index f12e040..53fbc36 100644 --- a/clang/lib/InstallAPI/Visitor.cpp +++ b/clang/lib/InstallAPI/Visitor.cpp @@ -543,8 +543,8 @@ void InstallAPIVisitor::emitVTableSymbols(const CXXRecordDecl *D, } for (const auto &It : D->bases()) { - const CXXRecordDecl *Base = cast<CXXRecordDecl>( - It.getType()->castAs<RecordType>()->getOriginalDecl()); + const auto *Base = + cast<CXXRecordDecl>(It.getType()->castAs<RecordType>()->getDecl()); const auto BaseAccess = getAccessForDecl(Base); if (!BaseAccess) continue; diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp index a55b7f5..0ed02f3 100644 --- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp +++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp @@ -66,10 +66,10 @@ static std::string QualTypeToString(ASTContext &Ctx, QualType QT) { const QualType NonRefTy = QT.getNonReferenceType(); if (const auto *TTy = llvm::dyn_cast<TagType>(NonRefTy)) - return DeclTypeToString(NonRefTy, TTy->getOriginalDecl()); + return DeclTypeToString(NonRefTy, TTy->getDecl()); if (const auto *TRy = dyn_cast<RecordType>(NonRefTy)) - return DeclTypeToString(NonRefTy, TRy->getOriginalDecl()); + return DeclTypeToString(NonRefTy, TRy->getDecl()); const QualType Canon = NonRefTy.getCanonicalType(); diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 5c6ecdb..6a5e5d4 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -248,50 +248,67 @@ static bool warnByDefaultOnWrongCase(StringRef Include) { // The standard C/C++ and Posix headers return llvm::StringSwitch<bool>(LowerInclude) - // C library headers - .Cases("assert.h", "complex.h", "ctype.h", "errno.h", "fenv.h", true) - .Cases("float.h", "inttypes.h", "iso646.h", "limits.h", "locale.h", true) - .Cases("math.h", "setjmp.h", "signal.h", "stdalign.h", "stdarg.h", true) - .Cases("stdatomic.h", "stdbool.h", "stdckdint.h", "stdcountof.h", true) - .Cases("stddef.h", "stdint.h", "stdio.h", "stdlib.h", "stdnoreturn.h", true) - .Cases("string.h", "tgmath.h", "threads.h", "time.h", "uchar.h", true) - .Cases("wchar.h", "wctype.h", true) - - // C++ headers for C library facilities - .Cases("cassert", "ccomplex", "cctype", "cerrno", "cfenv", true) - .Cases("cfloat", "cinttypes", "ciso646", "climits", "clocale", true) - .Cases("cmath", "csetjmp", "csignal", "cstdalign", "cstdarg", true) - .Cases("cstdbool", "cstddef", "cstdint", "cstdio", "cstdlib", true) - .Cases("cstring", "ctgmath", "ctime", "cuchar", "cwchar", true) - .Case("cwctype", true) - - // C++ library headers - .Cases("algorithm", "fstream", "list", "regex", "thread", true) - .Cases("array", "functional", "locale", "scoped_allocator", "tuple", true) - .Cases("atomic", "future", "map", "set", "type_traits", true) - .Cases("bitset", "initializer_list", "memory", "shared_mutex", "typeindex", true) - .Cases("chrono", "iomanip", "mutex", "sstream", "typeinfo", true) - .Cases("codecvt", "ios", "new", "stack", "unordered_map", true) - .Cases("complex", "iosfwd", "numeric", "stdexcept", "unordered_set", true) - .Cases("condition_variable", "iostream", "ostream", "streambuf", "utility", true) - .Cases("deque", "istream", "queue", "string", "valarray", true) - .Cases("exception", "iterator", "random", "strstream", "vector", true) - .Cases("forward_list", "limits", "ratio", "system_error", true) - - // POSIX headers (which aren't also C headers) - .Cases("aio.h", "arpa/inet.h", "cpio.h", "dirent.h", "dlfcn.h", true) - .Cases("fcntl.h", "fmtmsg.h", "fnmatch.h", "ftw.h", "glob.h", true) - .Cases("grp.h", "iconv.h", "langinfo.h", "libgen.h", "monetary.h", true) - .Cases("mqueue.h", "ndbm.h", "net/if.h", "netdb.h", "netinet/in.h", true) - .Cases("netinet/tcp.h", "nl_types.h", "poll.h", "pthread.h", "pwd.h", true) - .Cases("regex.h", "sched.h", "search.h", "semaphore.h", "spawn.h", true) - .Cases("strings.h", "stropts.h", "sys/ipc.h", "sys/mman.h", "sys/msg.h", true) - .Cases("sys/resource.h", "sys/select.h", "sys/sem.h", "sys/shm.h", "sys/socket.h", true) - .Cases("sys/stat.h", "sys/statvfs.h", "sys/time.h", "sys/times.h", "sys/types.h", true) - .Cases("sys/uio.h", "sys/un.h", "sys/utsname.h", "sys/wait.h", "syslog.h", true) - .Cases("tar.h", "termios.h", "trace.h", "ulimit.h", true) - .Cases("unistd.h", "utime.h", "utmpx.h", "wordexp.h", true) - .Default(false); + // C library headers + .Cases({"assert.h", "complex.h", "ctype.h", "errno.h", "fenv.h"}, true) + .Cases({"float.h", "inttypes.h", "iso646.h", "limits.h", "locale.h"}, + true) + .Cases({"math.h", "setjmp.h", "signal.h", "stdalign.h", "stdarg.h"}, true) + .Cases({"stdatomic.h", "stdbool.h", "stdckdint.h", "stdcountof.h"}, true) + .Cases({"stddef.h", "stdint.h", "stdio.h", "stdlib.h", "stdnoreturn.h"}, + true) + .Cases({"string.h", "tgmath.h", "threads.h", "time.h", "uchar.h"}, true) + .Cases({"wchar.h", "wctype.h"}, true) + + // C++ headers for C library facilities + .Cases({"cassert", "ccomplex", "cctype", "cerrno", "cfenv"}, true) + .Cases({"cfloat", "cinttypes", "ciso646", "climits", "clocale"}, true) + .Cases({"cmath", "csetjmp", "csignal", "cstdalign", "cstdarg"}, true) + .Cases({"cstdbool", "cstddef", "cstdint", "cstdio", "cstdlib"}, true) + .Cases({"cstring", "ctgmath", "ctime", "cuchar", "cwchar"}, true) + .Case("cwctype", true) + + // C++ library headers + .Cases({"algorithm", "fstream", "list", "regex", "thread"}, true) + .Cases({"array", "functional", "locale", "scoped_allocator", "tuple"}, + true) + .Cases({"atomic", "future", "map", "set", "type_traits"}, true) + .Cases( + {"bitset", "initializer_list", "memory", "shared_mutex", "typeindex"}, + true) + .Cases({"chrono", "iomanip", "mutex", "sstream", "typeinfo"}, true) + .Cases({"codecvt", "ios", "new", "stack", "unordered_map"}, true) + .Cases({"complex", "iosfwd", "numeric", "stdexcept", "unordered_set"}, + true) + .Cases( + {"condition_variable", "iostream", "ostream", "streambuf", "utility"}, + true) + .Cases({"deque", "istream", "queue", "string", "valarray"}, true) + .Cases({"exception", "iterator", "random", "strstream", "vector"}, true) + .Cases({"forward_list", "limits", "ratio", "system_error"}, true) + + // POSIX headers (which aren't also C headers) + .Cases({"aio.h", "arpa/inet.h", "cpio.h", "dirent.h", "dlfcn.h"}, true) + .Cases({"fcntl.h", "fmtmsg.h", "fnmatch.h", "ftw.h", "glob.h"}, true) + .Cases({"grp.h", "iconv.h", "langinfo.h", "libgen.h", "monetary.h"}, true) + .Cases({"mqueue.h", "ndbm.h", "net/if.h", "netdb.h", "netinet/in.h"}, + true) + .Cases({"netinet/tcp.h", "nl_types.h", "poll.h", "pthread.h", "pwd.h"}, + true) + .Cases({"regex.h", "sched.h", "search.h", "semaphore.h", "spawn.h"}, true) + .Cases({"strings.h", "stropts.h", "sys/ipc.h", "sys/mman.h", "sys/msg.h"}, + true) + .Cases({"sys/resource.h", "sys/select.h", "sys/sem.h", "sys/shm.h", + "sys/socket.h"}, + true) + .Cases({"sys/stat.h", "sys/statvfs.h", "sys/time.h", "sys/times.h", + "sys/types.h"}, + true) + .Cases( + {"sys/uio.h", "sys/un.h", "sys/utsname.h", "sys/wait.h", "syslog.h"}, + true) + .Cases({"tar.h", "termios.h", "trace.h", "ulimit.h"}, true) + .Cases({"unistd.h", "utime.h", "utmpx.h", "wordexp.h"}, true) + .Default(false); } /// Find a similar string in `Candidates`. @@ -3648,14 +3665,14 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) { std::pair<tok::TokenKind, SourceLocation> Matches) { Diag(CurTok, diag::err_expected) << Expected; Diag(Matches.second, diag::note_matching) << Matches.first; - if (CurTok.isNot(tok::eod)) + if (CurTok.isNot(EndTokenKind)) DiscardUntilEndOfDirective(CurTok); }; auto ExpectOrDiagAndSkipToEOD = [&](tok::TokenKind Kind) { if (CurTok.isNot(Kind)) { Diag(CurTok, diag::err_expected) << Kind; - if (CurTok.isNot(tok::eod)) + if (CurTok.isNot(EndTokenKind)) DiscardUntilEndOfDirective(CurTok); return false; } @@ -3746,7 +3763,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) { if (Result.isNegative()) { Diag(CurTok, diag::err_requires_positive_value) << toString(Result, 10) << /*positive*/ 0; - if (CurTok.isNot(tok::eod)) + if (CurTok.isNot(EndTokenKind)) DiscardUntilEndOfDirective(CurTok); return std::nullopt; } @@ -3889,7 +3906,7 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) { } if (!ForHasEmbed) { Diag(ParamStartLoc, diag::err_pp_unknown_parameter) << 1 << Parameter; - if (CurTok.isNot(tok::eod)) + if (CurTok.isNot(EndTokenKind)) DiscardUntilEndOfDirective(CurTok); return std::nullopt; } diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index dec1956..dd80ae5 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1262,16 +1262,11 @@ EmbedResult Preprocessor::EvaluateHasEmbed(Token &Tok, IdentifierInfo *II) { std::optional<LexEmbedParametersResult> Params = this->LexEmbedParameters(Tok, /*ForHasEmbed=*/true); - assert((Params || Tok.is(tok::eod)) && - "expected success or to be at the end of the directive"); if (!Params) return EmbedResult::Invalid; - if (Params->UnrecognizedParams > 0) - return EmbedResult::NotFound; - - if (!Tok.is(tok::r_paren)) { + if (Tok.isNot(tok::r_paren)) { Diag(this->getLocForEndOfToken(FilenameLoc), diag::err_pp_expected_after) << II << tok::r_paren; Diag(LParenLoc, diag::note_matching) << tok::l_paren; @@ -1280,6 +1275,9 @@ EmbedResult Preprocessor::EvaluateHasEmbed(Token &Tok, IdentifierInfo *II) { return EmbedResult::Invalid; } + if (Params->UnrecognizedParams > 0) + return EmbedResult::NotFound; + SmallString<128> FilenameBuffer; StringRef Filename = this->getSpelling(FilenameTok, FilenameBuffer); if (Filename.empty()) diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index bbff627..ec01faf 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1272,7 +1272,7 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, // tokens and store them for late parsing at the end of the translation unit. if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) && TemplateInfo.Kind == ParsedTemplateKind::Template && - Actions.canDelayFunctionBody(D)) { + LateParsedAttrs->empty() && Actions.canDelayFunctionBody(D)) { MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams); ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | @@ -1301,10 +1301,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, } return DP; } - else if (CurParsedObjCImpl && - !TemplateInfo.TemplateParams && - (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) || - Tok.is(tok::colon)) && + if (CurParsedObjCImpl && !TemplateInfo.TemplateParams && + (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) || Tok.is(tok::colon)) && Actions.CurContext->isTranslationUnit()) { ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope); @@ -1420,7 +1418,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, // Late attributes are parsed in the same scope as the function body. if (LateParsedAttrs) - ParseLexedAttributeList(*LateParsedAttrs, Res, false, true); + ParseLexedAttributeList(*LateParsedAttrs, Res, /*EnterScope=*/false, + /*OnDefinition=*/true); if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) && trySkippingFunctionBody()) { diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index db14349..e797400 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -361,11 +361,11 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) { if (!Callee->getIdentifier()) return false; return llvm::StringSwitch<bool>(Callee->getName()) - .Cases("begin", "rbegin", "cbegin", "crbegin", true) - .Cases("end", "rend", "cend", "crend", true) - .Cases("c_str", "data", "get", true) + .Cases({"begin", "rbegin", "cbegin", "crbegin"}, true) + .Cases({"end", "rend", "cend", "crend"}, true) + .Cases({"c_str", "data", "get"}, true) // Map and set types. - .Cases("find", "equal_range", "lower_bound", "upper_bound", true) + .Cases({"find", "equal_range", "lower_bound", "upper_bound"}, true) .Default(false); } if (Callee->getReturnType()->isReferenceType()) { @@ -377,7 +377,7 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) { OO == OverloadedOperatorKind::OO_Star; } return llvm::StringSwitch<bool>(Callee->getName()) - .Cases("front", "back", "at", "top", "value", true) + .Cases({"front", "back", "at", "top", "value"}, true) .Default(false); } return false; @@ -394,14 +394,14 @@ static bool shouldTrackFirstArgument(const FunctionDecl *FD) { if (FD->getReturnType()->isPointerType() || isRecordWithAttr<PointerAttr>(FD->getReturnType())) { return llvm::StringSwitch<bool>(FD->getName()) - .Cases("begin", "rbegin", "cbegin", "crbegin", true) - .Cases("end", "rend", "cend", "crend", true) + .Cases({"begin", "rbegin", "cbegin", "crbegin"}, true) + .Cases({"end", "rend", "cend", "crend"}, true) .Case("data", true) .Default(false); } if (FD->getReturnType()->isReferenceType()) { return llvm::StringSwitch<bool>(FD->getName()) - .Cases("get", "any_cast", true) + .Cases({"get", "any_cast"}, true) .Default(false); } return false; diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp index f8d61d9..b09e168 100644 --- a/clang/lib/Sema/SemaAvailability.cpp +++ b/clang/lib/Sema/SemaAvailability.cpp @@ -102,7 +102,7 @@ Sema::ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message, break; for (const Type *T = TD->getUnderlyingType().getTypePtr(); /**/; /**/) { if (auto *TT = dyn_cast<TagType>(T)) { - D = TT->getOriginalDecl()->getDefinitionOrSelf(); + D = TT->getDecl()->getDefinitionOrSelf(); } else if (isa<SubstTemplateTypeParmType>(T)) { // A Subst* node represents a use through a template. // Any uses of the underlying declaration happened through it's template @@ -1019,7 +1019,7 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) { return true; if (const auto *TT = dyn_cast<TagType>(TyPtr)) { - TagDecl *TD = TT->getOriginalDecl()->getDefinitionOrSelf(); + TagDecl *TD = TT->getDecl()->getDefinitionOrSelf(); DiagnoseDeclAvailability(TD, Range); } else if (const auto *TD = dyn_cast<TypedefType>(TyPtr)) { diff --git a/clang/lib/Sema/SemaBPF.cpp b/clang/lib/Sema/SemaBPF.cpp index be890ab..a9761764 100644 --- a/clang/lib/Sema/SemaBPF.cpp +++ b/clang/lib/Sema/SemaBPF.cpp @@ -57,7 +57,7 @@ static bool isValidPreserveTypeInfoArg(Expr *Arg) { // Record type or Enum type. if (const auto *RT = ArgType->getAsCanonical<TagType>()) - if (!RT->getOriginalDecl()->getDeclName().isEmpty()) + if (!RT->getDecl()->getDeclName().isEmpty()) return true; return false; diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 97ba1a51..c52fc5b 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -31,8 +31,7 @@ static CXXRecordDecl *getCurrentInstantiationOf(QualType T, const TagType *TagTy = dyn_cast<TagType>(T->getCanonicalTypeInternal()); if (!isa_and_present<RecordType, InjectedClassNameType>(TagTy)) return nullptr; - auto *RD = - cast<CXXRecordDecl>(TagTy->getOriginalDecl())->getDefinitionOrSelf(); + auto *RD = cast<CXXRecordDecl>(TagTy->getDecl())->getDefinitionOrSelf(); if (isa<InjectedClassNameType>(TagTy) || RD->isCurrentInstantiation(CurContext)) return RD; @@ -121,7 +120,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS, } } else if (const auto *RecordT = dyn_cast<RecordType>(NNSType)) { // The nested name specifier refers to a member of a class template. - return RecordT->getOriginalDecl()->getDefinitionOrSelf(); + return RecordT->getDecl()->getDefinitionOrSelf(); } } diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index d986e3b..ddf17d8 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -962,7 +962,7 @@ void CastOperation::CheckDynamicCast() { } // C++ 5.2.7p6: Otherwise, v shall be [polymorphic]. - const RecordDecl *SrcDecl = SrcRecord->getOriginalDecl()->getDefinition(); + const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition(); assert(SrcDecl && "Definition missing"); if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) { Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic) @@ -1453,7 +1453,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, // converted to an integral type. [...] A value of a scoped enumeration type // can also be explicitly converted to a floating-point type [...]. if (const EnumType *Enum = dyn_cast<EnumType>(SrcType)) { - if (Enum->getOriginalDecl()->isScoped()) { + if (Enum->getDecl()->isScoped()) { if (DestType->isBooleanType()) { Kind = CK_IntegralToBoolean; return TC_Success; @@ -3105,7 +3105,7 @@ void CastOperation::CheckCStyleCast() { } // GCC's cast to union extension. - if (RecordDecl *RD = DestRecordTy->getOriginalDecl(); RD->isUnion()) { + if (RecordDecl *RD = DestRecordTy->getDecl(); RD->isUnion()) { if (CastExpr::getTargetFieldForToUnionCast(RD->getDefinitionOrSelf(), SrcType)) { Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 063db05..4f409ca 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3580,9 +3580,8 @@ static bool CheckNonNullExpr(Sema &S, const Expr *Expr) { // As a special case, transparent unions initialized with zero are // considered null for the purposes of the nonnull attribute. if (const RecordType *UT = Expr->getType()->getAsUnionType(); - UT && UT->getOriginalDecl() - ->getMostRecentDecl() - ->hasAttr<TransparentUnionAttr>()) { + UT && + UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) { if (const auto *CLE = dyn_cast<CompoundLiteralExpr>(Expr)) if (const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer())) Expr = ILE->getInit(0); @@ -12879,8 +12878,8 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, if (const EnumType *SourceEnum = Source->getAsCanonical<EnumType>()) if (const EnumType *TargetEnum = Target->getAsCanonical<EnumType>()) - if (SourceEnum->getOriginalDecl()->hasNameForLinkage() && - TargetEnum->getOriginalDecl()->hasNameForLinkage() && + if (SourceEnum->getDecl()->hasNameForLinkage() && + TargetEnum->getDecl()->hasNameForLinkage() && SourceEnum != TargetEnum) { if (SourceMgr.isInSystemMacro(CC)) return; diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 5dd4949..0514d10 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2070,7 +2070,7 @@ static const char *GetCompletionTypeString(QualType T, ASTContext &Context, // Anonymous tag types are constant strings. if (const TagType *TagT = dyn_cast<TagType>(T)) - if (TagDecl *Tag = TagT->getOriginalDecl()) + if (TagDecl *Tag = TagT->getDecl()) if (!Tag->hasNameForLinkage()) { switch (Tag->getTagKind()) { case TagTypeKind::Struct: diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 229e91e..c0aba83 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -640,10 +640,9 @@ static void checkNoThrow(Sema &S, const Stmt *E, QualType::DestructionKind::DK_cxx_destructor) { const auto *T = cast<RecordType>(ReturnType.getCanonicalType().getTypePtr()); - checkDeclNoexcept(cast<CXXRecordDecl>(T->getOriginalDecl()) - ->getDefinition() - ->getDestructor(), - /*IsDtor=*/true); + checkDeclNoexcept( + cast<CXXRecordDecl>(T->getDecl())->getDefinition()->getDestructor(), + /*IsDtor=*/true); } } else for (const auto *Child : E->children()) { diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 3107876..e6f8748 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1255,7 +1255,7 @@ bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) { // The nonnull attribute, and other similar attributes, can be applied to a // transparent union that contains a pointer type. if (const RecordType *UT = T->getAsUnionType()) { - RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf(); if (UD->hasAttr<TransparentUnionAttr>()) { for (const auto *I : UD->fields()) { QualType QT = I->getType(); @@ -3629,18 +3629,20 @@ static FormatAttrKind getFormatAttrKind(StringRef Format) { // Check for formats that get handled specially. .Case("NSString", NSStringFormat) .Case("CFString", CFStringFormat) - .Cases("gnu_strftime", "strftime", StrftimeFormat) + .Cases({"gnu_strftime", "strftime"}, StrftimeFormat) // Otherwise, check for supported formats. - .Cases("gnu_scanf", "scanf", "gnu_printf", "printf", "printf0", - "gnu_strfmon", "strfmon", SupportedFormat) - .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat) - .Cases("kprintf", "syslog", SupportedFormat) // OpenBSD. - .Case("freebsd_kprintf", SupportedFormat) // FreeBSD. + .Cases({"gnu_scanf", "scanf", "gnu_printf", "printf", "printf0", + "gnu_strfmon", "strfmon"}, + SupportedFormat) + .Cases({"cmn_err", "vcmn_err", "zcmn_err"}, SupportedFormat) + .Cases({"kprintf", "syslog"}, SupportedFormat) // OpenBSD. + .Case("freebsd_kprintf", SupportedFormat) // FreeBSD. .Case("os_trace", SupportedFormat) .Case("os_log", SupportedFormat) - .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat) + .Cases({"gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag"}, + IgnoredFormat) .Default(InvalidFormat); } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 215431c..d41ab12 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5630,7 +5630,7 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl<const void*> &IdealInits) { if (const RecordType *RT = Field->getType()->getAsCanonical<RecordType>()) { - const RecordDecl *RD = RT->getOriginalDecl(); + const RecordDecl *RD = RT->getDecl(); if (RD->isAnonymousStructOrUnion()) { for (auto *Field : RD->getDefinitionOrSelf()->fields()) PopulateKeysForFields(Field, IdealInits); @@ -7630,9 +7630,8 @@ static bool defaultedSpecialMemberIsConstexpr( continue; QualType BaseType = S.Context.getBaseElementType(F->getType()); if (const RecordType *RecordTy = BaseType->getAsCanonical<RecordType>()) { - CXXRecordDecl *FieldRecDecl = - cast<CXXRecordDecl>(RecordTy->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *FieldRecDecl = + cast<CXXRecordDecl>(RecordTy->getDecl())->getDefinitionOrSelf(); if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM, BaseType.getCVRQualifiers(), ConstArg && !F->isMutable())) @@ -10645,7 +10644,7 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) { if (const auto *RT = FT->getBaseElementTypeUnsafe()->getAsCanonical<RecordType>()) if (!RT->isDependentType() && - !cast<CXXRecordDecl>(RT->getOriginalDecl()->getDefinitionOrSelf()) + !cast<CXXRecordDecl>(RT->getDecl()->getDefinitionOrSelf()) ->canPassInRegisters()) { PrintDiagAndRemoveAttr(5); return; diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 98eb5af..3df9f9c 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -3232,10 +3232,8 @@ static bool tryMatchRecordTypes(ASTContext &Context, assert(lt && rt && lt != rt); if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false; - RecordDecl *left = - cast<RecordType>(lt)->getOriginalDecl()->getDefinitionOrSelf(); - RecordDecl *right = - cast<RecordType>(rt)->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *left = cast<RecordType>(lt)->getDecl()->getDefinitionOrSelf(); + RecordDecl *right = cast<RecordType>(rt)->getDecl()->getDefinitionOrSelf(); // Require union-hood to match. if (left->isUnion() != right->isUnion()) return false; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 01abc1f..3e0e9bb 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1535,12 +1535,8 @@ void Sema::checkEnumArithmeticConversions(Expr *LHS, Expr *RHS, // are ill-formed. if (getLangOpts().CPlusPlus26) DiagID = diag::warn_conv_mixed_enum_types_cxx26; - else if (!L->castAsCanonical<EnumType>() - ->getOriginalDecl() - ->hasNameForLinkage() || - !R->castAsCanonical<EnumType>() - ->getOriginalDecl() - ->hasNameForLinkage()) { + else if (!L->castAsCanonical<EnumType>()->getDecl()->hasNameForLinkage() || + !R->castAsCanonical<EnumType>()->getDecl()->hasNameForLinkage()) { // If either enumeration type is unnamed, it's less likely that the // user cares about this, but this situation is still deprecated in // C++2a. Use a different warning group. @@ -7095,7 +7091,7 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, for (unsigned i = 0, e = Args.size(); i != e; i++) { if (const auto *RT = dyn_cast<RecordType>(Args[i]->getType().getCanonicalType())) { - if (RT->getOriginalDecl()->isOrContainsUnion()) + if (RT->getDecl()->isOrContainsUnion()) Diag(Args[i]->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 0 << i; } @@ -9748,7 +9744,7 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, if (!UT) return AssignConvertType::Incompatible; - RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf(); if (!UD->hasAttr<TransparentUnionAttr>()) return AssignConvertType::Incompatible; @@ -10844,7 +10840,7 @@ static void diagnoseScopedEnums(Sema &S, const SourceLocation Loc, auto DiagnosticHelper = [&S](const Expr *expr, const QualType type) { SourceLocation BeginLoc = expr->getBeginLoc(); QualType IntType = type->castAs<EnumType>() - ->getOriginalDecl() + ->getDecl() ->getDefinitionOrSelf() ->getIntegerType(); std::string InsertionString = "static_cast<" + IntType.getAsString() + ">("; @@ -11533,7 +11529,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, static bool isScopedEnumerationType(QualType T) { if (const EnumType *ET = T->getAsCanonical<EnumType>()) - return ET->getOriginalDecl()->isScoped(); + return ET->getDecl()->isScoped(); return false; } @@ -13839,7 +13835,7 @@ static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD, while (RecordTypeList.size() > NextToCheckIndex) { bool IsNested = NextToCheckIndex > 0; for (const FieldDecl *Field : RecordTypeList[NextToCheckIndex] - ->getOriginalDecl() + ->getDecl() ->getDefinitionOrSelf() ->fields()) { // First, check every field for constness. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 0fe242dce..fe1f89b 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1988,7 +1988,7 @@ static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc, DeclarationName deleteName = S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete); LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName); - S.LookupQualifiedName(ops, record->getOriginalDecl()->getDefinitionOrSelf()); + S.LookupQualifiedName(ops, record->getDecl()->getDefinitionOrSelf()); // We're just doing this for information. ops.suppressDiagnostics(); @@ -6667,8 +6667,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { // That should be enough to guarantee that this type is complete, if we're // not processing a decltype expression. - CXXRecordDecl *RD = - cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf(); + auto *RD = cast<CXXRecordDecl>(RT->getDecl())->getDefinitionOrSelf(); if (RD->isInvalidDecl() || RD->isDependentContext()) return E; diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 331f6e5..4daf0170 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -3846,8 +3846,7 @@ static inline T *getObjCBridgeAttr(const TypedefType *TD) { if (QT->isPointerType()) { QT = QT->getPointeeType(); if (const RecordType *RT = QT->getAsCanonical<RecordType>()) { - for (auto *Redecl : - RT->getOriginalDecl()->getMostRecentDecl()->redecls()) { + for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) { if (auto *attr = Redecl->getAttr<T>()) return attr; } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 72b2ac9..f347066 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -782,7 +782,7 @@ bool SemaHLSL::isSemanticValid(FunctionDecl *FD, DeclaratorDecl *D) { if (!RT) return false; - const RecordDecl *RD = RT->getOriginalDecl(); + const RecordDecl *RD = RT->getDecl(); for (FieldDecl *Field : RD->fields()) { if (!isSemanticValid(FD, Field)) return false; @@ -1986,7 +1986,7 @@ SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) { // requirements and adds them to Bindings void SemaHLSL::collectResourceBindingsOnUserRecordDecl(const VarDecl *VD, const RecordType *RT) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); for (FieldDecl *FD : RD->fields()) { const Type *Ty = FD->getType()->getUnqualifiedDesugaredType(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 543db46..f7974eb 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -775,7 +775,7 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (Init >= NumInits || !ILE->getInit(Init)) { if (const RecordType *RType = ILE->getType()->getAsCanonical<RecordType>()) - if (!RType->getOriginalDecl()->isUnion()) + if (!RType->getDecl()->isUnion()) assert((Init < NumInits || VerifyOnly) && "This ILE should have been expanded"); @@ -9186,9 +9186,8 @@ bool InitializationSequence::Diagnose(Sema &S, diag::note_member_declared_at); if (const auto *Record = Entity.getType()->getAs<RecordType>()) - S.Diag(Record->getOriginalDecl()->getLocation(), - diag::note_previous_decl) - << S.Context.getCanonicalTagType(Record->getOriginalDecl()); + S.Diag(Record->getDecl()->getLocation(), diag::note_previous_decl) + << S.Context.getCanonicalTagType(Record->getDecl()); } break; } @@ -9974,8 +9973,8 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( // Cases where template arguments in the RHS of the alias are not // dependent. e.g. // using AliasFoo = Foo<bool>; - if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>( - RT->getOriginalDecl())) + if (const auto *CTSD = + llvm::dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) Template = CTSD->getSpecializedTemplate(); } } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 25728de..5915d6e 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2727,9 +2727,7 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, IsDependent = !DC && ObjectType->isDependentType(); assert(((!DC && ObjectType->isDependentType()) || !ObjectType->isIncompleteType() || !ObjectType->getAs<TagType>() || - ObjectType->castAs<TagType>() - ->getOriginalDecl() - ->isEntityBeingDefined()) && + ObjectType->castAs<TagType>()->getDecl()->isEntityBeingDefined()) && "Caller should have completed object type"); } else if (SS && SS->isNotEmpty()) { // This nested-name-specifier occurs after another nested-name-specifier, @@ -3191,9 +3189,8 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { // namespaces of its associated classes. case Type::Record: { // FIXME: This should use the original decl. - CXXRecordDecl *Class = - cast<CXXRecordDecl>(cast<RecordType>(T)->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *Class = cast<CXXRecordDecl>(cast<RecordType>(T)->getDecl()) + ->getDefinitionOrSelf(); addAssociatedClassesAndNamespaces(Result, Class); break; } @@ -4606,7 +4603,7 @@ static void getNestedNameSpecifierIdentifiers( case Type::InjectedClassName: { auto *TT = cast<TagType>(T); getNestedNameSpecifierIdentifiers(TT->getQualifier(), Identifiers); - Identifiers.push_back(TT->getOriginalDecl()->getIdentifier()); + Identifiers.push_back(TT->getDecl()->getIdentifier()); return; } case Type::Typedef: { diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp index 4f9470a..7aaa56e 100644 --- a/clang/lib/Sema/SemaObjC.cpp +++ b/clang/lib/Sema/SemaObjC.cpp @@ -1407,7 +1407,7 @@ SemaObjC::ObjCSubscriptKind SemaObjC::CheckSubscriptingKind(Expr *FromE) { int NoIntegrals = 0, NoObjCIdPointers = 0; SmallVector<CXXConversionDecl *, 4> ConversionDecls; - for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getOriginalDecl()) + for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getDecl()) ->getDefinitionOrSelf() ->getVisibleConversionFunctions()) { if (CXXConversionDecl *Conversion = @@ -1511,7 +1511,7 @@ bool SemaObjC::isCFStringType(QualType T) { if (!RT) return false; - const RecordDecl *RD = RT->getOriginalDecl(); + const RecordDecl *RD = RT->getDecl(); if (RD->getTagKind() != TagTypeKind::Struct) return false; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 8339bb1..7da09e8 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -2594,7 +2594,7 @@ IsTransparentUnionStandardConversion(Sema &S, Expr* From, if (!UT) return false; // The field to initialize within the transparent union. - const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf(); if (!UD->hasAttr<TransparentUnionAttr>()) return false; // It's compatible if the expression matches any of the fields. @@ -3973,7 +3973,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, if (!S.isCompleteType(From->getExprLoc(), ToType)) { // We're not going to find any constructors. } else if (auto *ToRecordDecl = - dyn_cast<CXXRecordDecl>(ToRecordType->getOriginalDecl())) { + dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) { ToRecordDecl = ToRecordDecl->getDefinitionOrSelf(); Expr **Args = &From; @@ -4048,7 +4048,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, } else if (const RecordType *FromRecordType = From->getType()->getAsCanonical<RecordType>()) { if (auto *FromRecordDecl = - dyn_cast<CXXRecordDecl>(FromRecordType->getOriginalDecl())) { + dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) { FromRecordDecl = FromRecordDecl->getDefinitionOrSelf(); // Add all of the conversion functions as candidates. const auto &Conversions = FromRecordDecl->getVisibleConversionFunctions(); @@ -6840,7 +6840,7 @@ ExprResult Sema::PerformContextualImplicitConversion( UnresolvedSet<4> ViableConversions; // These are *potentially* viable in C++1y. UnresolvedSet<4> ExplicitConversions; - const auto &Conversions = cast<CXXRecordDecl>(RecordTy->getOriginalDecl()) + const auto &Conversions = cast<CXXRecordDecl>(RecordTy->getDecl()) ->getDefinitionOrSelf() ->getVisibleConversionFunctions(); @@ -10194,9 +10194,7 @@ public: if (S.getLangOpts().CPlusPlus11) { for (QualType EnumTy : CandidateTypes[ArgIdx].enumeration_types()) { - if (!EnumTy->castAsCanonical<EnumType>() - ->getOriginalDecl() - ->isScoped()) + if (!EnumTy->castAsCanonical<EnumType>()->getDecl()->isScoped()) continue; if (!AddedTypes.insert(S.Context.getCanonicalType(EnumTy)).second) diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index b981c35..67f3856 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -221,8 +221,8 @@ static SourceLocation SourceLocationForUserDeclaredType(QualType QT) { SourceLocation Loc; const Type *T = QT->getUnqualifiedDesugaredType(); if (const TagType *TT = dyn_cast<TagType>(T)) - Loc = TT->getOriginalDecl()->getLocation(); - else if (const ObjCInterfaceType *ObjCIT = dyn_cast<ObjCInterfaceType>(T)) + Loc = TT->getDecl()->getLocation(); + else if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(T)) Loc = ObjCIT->getDecl()->getLocation(); return Loc; } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ae0bb616..f398963 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1277,11 +1277,11 @@ static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond, return; // Ignore anonymous enums. - if (!CondEnumType->getOriginalDecl()->getIdentifier() && - !CondEnumType->getOriginalDecl()->getTypedefNameForAnonDecl()) + if (!CondEnumType->getDecl()->getIdentifier() && + !CondEnumType->getDecl()->getTypedefNameForAnonDecl()) return; - if (!CaseEnumType->getOriginalDecl()->getIdentifier() && - !CaseEnumType->getOriginalDecl()->getTypedefNameForAnonDecl()) + if (!CaseEnumType->getDecl()->getIdentifier() && + !CaseEnumType->getDecl()->getTypedefNameForAnonDecl()) return; if (S.Context.hasSameUnqualifiedType(CondType, CaseType)) @@ -3760,7 +3760,7 @@ private: Sema &S; }; bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) { - auto *R = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()); + auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl()); if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() || R->isDependentType()) return true; @@ -3979,7 +3979,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, << RetValExp->getSourceRange(); if (FD->hasAttr<CmseNSEntryAttr>() && RetValExp) { if (const auto *RT = dyn_cast<RecordType>(FnRetType.getCanonicalType())) { - if (RT->getOriginalDecl()->isOrContainsUnion()) + if (RT->getDecl()->isOrContainsUnion()) Diag(RetValExp->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 1; } } diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 0438af7..f957bdf 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -908,7 +908,7 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member, LookupResult FieldResult(*this, &Context.Idents.get(NextMember), SourceLocation(), LookupMemberName); - RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); if (!LookupQualifiedName(FieldResult, RD)) return true; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3a6ff99..2cc6593 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -408,9 +408,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, Scope *S, CXXScopeSpec &SS, IsDependent = !LookupCtx && ObjectType->isDependentType(); assert((IsDependent || !ObjectType->isIncompleteType() || !ObjectType->getAs<TagType>() || - ObjectType->castAs<TagType>() - ->getOriginalDecl() - ->isEntityBeingDefined()) && + ObjectType->castAs<TagType>()->getDecl()->isEntityBeingDefined()) && "Caller should have completed object type"); // Template names cannot appear inside an Objective-C class or object type @@ -1819,7 +1817,7 @@ public: } bool VisitTagType(const TagType *T) override { - return TraverseDecl(T->getOriginalDecl()); + return TraverseDecl(T->getDecl()); } bool TraverseDecl(const Decl *D) override { @@ -2790,7 +2788,7 @@ struct DependencyChecker : DynamicRecursiveASTVisitor { // An InjectedClassNameType will never have a dependent template name, // so no need to traverse it. return TraverseTemplateArguments( - T->getTemplateArgs(T->getOriginalDecl()->getASTContext())); + T->getTemplateArgs(T->getDecl()->getASTContext())); } }; } // end anonymous namespace @@ -2914,7 +2912,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier( if (const EnumType *EnumT = T->getAsCanonical<EnumType>()) { // FIXME: Forward-declared enums require a TSK_ExplicitSpecialization // check here. - EnumDecl *Enum = EnumT->getOriginalDecl(); + EnumDecl *Enum = EnumT->getDecl(); // Get to the parent type. if (TypeDecl *Parent = dyn_cast<TypeDecl>(Enum->getParent())) @@ -3352,7 +3350,7 @@ static QualType builtinCommonTypeImpl(Sema &S, ElaboratedTypeKeyword Keyword, } static bool isInVkNamespace(const RecordType *RT) { - DeclContext *DC = RT->getOriginalDecl()->getDeclContext(); + DeclContext *DC = RT->getDecl()->getDeclContext(); if (!DC) return false; @@ -3369,9 +3367,8 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef, if (auto *RT = OperandArg->getAsCanonical<RecordType>()) { bool Literal = false; SourceLocation LiteralLoc; - if (isInVkNamespace(RT) && RT->getOriginalDecl()->getName() == "Literal") { - auto SpecDecl = - dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl()); + if (isInVkNamespace(RT) && RT->getDecl()->getName() == "Literal") { + auto SpecDecl = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); assert(SpecDecl); const TemplateArgumentList &LiteralArgs = SpecDecl->getTemplateArgs(); @@ -3382,9 +3379,8 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef, } if (RT && isInVkNamespace(RT) && - RT->getOriginalDecl()->getName() == "integral_constant") { - auto SpecDecl = - dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl()); + RT->getDecl()->getName() == "integral_constant") { + auto SpecDecl = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()); assert(SpecDecl); const TemplateArgumentList &ConstantArgs = SpecDecl->getTemplateArgs(); @@ -4110,7 +4106,7 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, // Check the tag kind if (const RecordType *RT = Result->getAs<RecordType>()) { - RecordDecl *D = RT->getOriginalDecl(); + RecordDecl *D = RT->getDecl(); IdentifierInfo *Id = D->getIdentifier(); assert(Id && "templated class must have an identifier"); @@ -6383,11 +6379,11 @@ bool UnnamedLocalNoLinkageFinder::VisitDeducedTemplateSpecializationType( } bool UnnamedLocalNoLinkageFinder::VisitRecordType(const RecordType* T) { - return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf()); + return VisitTagDecl(T->getDecl()->getDefinitionOrSelf()); } bool UnnamedLocalNoLinkageFinder::VisitEnumType(const EnumType* T) { - return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf()); + return VisitTagDecl(T->getDecl()->getDefinitionOrSelf()); } bool UnnamedLocalNoLinkageFinder::VisitTemplateTypeParmType( @@ -6412,7 +6408,7 @@ bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType( bool UnnamedLocalNoLinkageFinder::VisitInjectedClassNameType( const InjectedClassNameType* T) { - return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf()); + return VisitTagDecl(T->getDecl()->getDefinitionOrSelf()); } bool UnnamedLocalNoLinkageFinder::VisitDependentNameType( diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 3baa977..6964242 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5577,7 +5577,7 @@ static TemplateDeductionResult CheckDeductionConsistency( bool IsDeductionGuide = isa<CXXDeductionGuideDecl>(FTD->getTemplatedDecl()); if (IsDeductionGuide) { if (auto *Injected = P->getAsCanonical<InjectedClassNameType>()) - P = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType( + P = Injected->getDecl()->getCanonicalTemplateSpecializationType( S.Context); } QualType InstP = S.SubstType(P.getCanonicalType(), MLTAL, FTD->getLocation(), @@ -5598,10 +5598,10 @@ static TemplateDeductionResult CheckDeductionConsistency( auto T2 = S.Context.getUnqualifiedArrayType(A.getNonReferenceType()); if (IsDeductionGuide) { if (auto *Injected = T1->getAsCanonical<InjectedClassNameType>()) - T1 = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType( + T1 = Injected->getDecl()->getCanonicalTemplateSpecializationType( S.Context); if (auto *Injected = T2->getAsCanonical<InjectedClassNameType>()) - T2 = Injected->getOriginalDecl()->getCanonicalTemplateSpecializationType( + T2 = Injected->getDecl()->getCanonicalTemplateSpecializationType( S.Context); } if (!S.Context.hasSameType(T1, T2)) @@ -6973,7 +6973,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, case Type::InjectedClassName: T = cast<InjectedClassNameType>(T) - ->getOriginalDecl() + ->getDecl() ->getCanonicalTemplateSpecializationType(Ctx); [[fallthrough]]; diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 8ba23aa..ad50600 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -996,7 +996,7 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) { // dependent. e.g. // using AliasFoo = Foo<bool>; if (const auto *CTSD = - dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl())) { + dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) { Template = CTSD->getSpecializedTemplate(); AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray(); } @@ -1054,12 +1054,11 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef, // such that T can be deduced as U. auto RType = F->getTemplatedDecl()->getReturnType(); // The (trailing) return type of the deduction guide. - const TemplateSpecializationType *FReturnType = - RType->getAs<TemplateSpecializationType>(); + const auto *FReturnType = RType->getAs<TemplateSpecializationType>(); if (const auto *ICNT = RType->getAsCanonical<InjectedClassNameType>()) // implicitly-generated deduction guide. FReturnType = cast<TemplateSpecializationType>( - ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType( + ICNT->getDecl()->getCanonicalTemplateSpecializationType( SemaRef.Context)); assert(FReturnType && "expected to see a return type"); // Deduce template arguments of the deduction guide f from the RHS of diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 7b05e4c..bec2820 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1681,7 +1681,7 @@ namespace { ICNT && SemaRef.CodeSynthesisContexts.back().Kind == Sema::CodeSynthesisContext::BuildingDeductionGuides) { Type = inherited::TransformType( - ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType( + ICNT->getDecl()->getCanonicalTemplateSpecializationType( SemaRef.Context)); TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc()); } @@ -2105,7 +2105,7 @@ TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D, return cast_or_null<NamedDecl>(TransformDecl(Loc, D)); if (const TagType *Tag = T->getAs<TagType>()) - return Tag->getOriginalDecl(); + return Tag->getDecl(); // The resulting type is not a tag; complain. getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 73fd33a..468bc1d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1522,9 +1522,9 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D, // If the old typedef was the name for linkage purposes of an anonymous // tag decl, re-establish that relationship for the new typedef. if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) { - TagDecl *oldTag = oldTagType->getOriginalDecl(); + TagDecl *oldTag = oldTagType->getDecl(); if (oldTag->getTypedefNameForAnonDecl() == D && !Invalid) { - TagDecl *newTag = DI->getType()->castAs<TagType>()->getOriginalDecl(); + TagDecl *newTag = DI->getType()->castAs<TagType>()->getDecl(); assert(!newTag->hasNameForLinkage()); newTag->setTypedefNameForAnonDecl(Typedef); } @@ -5791,7 +5791,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, QualType TransformRecordType(TypeLocBuilder &TLB, RecordTypeLoc TL) { const RecordType *T = TL.getTypePtr(); RecordDecl *Record = cast_or_null<RecordDecl>( - getDerived().TransformDecl(TL.getNameLoc(), T->getOriginalDecl())); + getDerived().TransformDecl(TL.getNameLoc(), T->getDecl())); if (Record != OldDecl) return Base::TransformRecordType(TLB, TL); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index a9e7c34..638904d 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1238,8 +1238,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { Result = S.GetTypeFromParser(DS.getRepAsType()); assert(!Result.isNull() && "Didn't get a type for typeof?"); if (!Result->isDependentType()) - if (const TagType *TT = Result->getAs<TagType>()) - S.DiagnoseUseOfDecl(TT->getOriginalDecl(), DS.getTypeSpecTypeLoc()); + if (const auto *TT = Result->getAs<TagType>()) + S.DiagnoseUseOfDecl(TT->getDecl(), DS.getTypeSpecTypeLoc()); // TypeQuals handled by caller. Result = Context.getTypeOfType( Result, DS.getTypeSpecType() == DeclSpec::TST_typeof_unqualType @@ -9699,7 +9699,7 @@ QualType Sema::BuildTypeofExprType(Expr *E, TypeOfKind Kind) { if (!E->isTypeDependent()) { QualType T = E->getType(); if (const TagType *TT = T->getAs<TagType>()) - DiagnoseUseOfDecl(TT->getOriginalDecl(), E->getExprLoc()); + DiagnoseUseOfDecl(TT->getDecl(), E->getExprLoc()); } return Context.getTypeOfExprType(E, Kind); } @@ -9865,7 +9865,7 @@ QualType Sema::BuildPackIndexingType(QualType Pattern, Expr *IndexExpr, static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType, SourceLocation Loc) { assert(BaseType->isEnumeralType()); - EnumDecl *ED = BaseType->castAs<EnumType>()->getOriginalDecl(); + EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl(); S.DiagnoseUseOfDecl(ED, Loc); diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index 3e34675..3887796 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -1076,8 +1076,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, if (T.isPODType(C) || T->isObjCLifetimeType()) return true; if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) { - if (RD->hasTrivialDefaultConstructor() && - !RD->hasNonTrivialDefaultConstructor()) + if (RD->hasTrivialDefaultConstructor()) return true; bool FoundConstructor = false; @@ -1165,14 +1164,26 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, const CXXDestructorDecl *Dtor = RD->getDestructor(); if (UnqualT->isAggregateType() && (!Dtor || !Dtor->isUserProvided())) return true; - if (RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted())) { - for (CXXConstructorDecl *Ctr : RD->ctors()) { - if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted()) - continue; - if (Ctr->isTrivial()) - return true; - } + bool HasTrivialNonDeletedDtr = + RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted()); + if (!HasTrivialNonDeletedDtr) + return false; + for (CXXConstructorDecl *Ctr : RD->ctors()) { + if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted()) + continue; + if (Ctr->isTrivial()) + return true; } + if (RD->needsImplicitDefaultConstructor() && + RD->hasTrivialDefaultConstructor() && + !RD->hasNonTrivialDefaultConstructor()) + return true; + if (RD->needsImplicitCopyConstructor() && RD->hasTrivialCopyConstructor() && + !RD->defaultedCopyConstructorIsDeleted()) + return true; + if (RD->needsImplicitMoveConstructor() && RD->hasTrivialMoveConstructor() && + !RD->defaultedMoveConstructorIsDeleted()) + return true; return false; } case UTT_IsIntangibleType: @@ -1613,9 +1624,9 @@ bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, // Unions are never base classes, and never have base classes. // It doesn't matter if they are complete or not. See PR#41843 - if (lhsRecord && lhsRecord->getOriginalDecl()->isUnion()) + if (lhsRecord && lhsRecord->getDecl()->isUnion()) return false; - if (rhsRecord && rhsRecord->getOriginalDecl()->isUnion()) + if (rhsRecord && rhsRecord->getDecl()->isUnion()) return false; if (lhsRecord == rhsRecord) @@ -1629,8 +1640,8 @@ bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, diag::err_incomplete_type_used_in_type_trait_expr)) return false; - return cast<CXXRecordDecl>(rhsRecord->getOriginalDecl()) - ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getOriginalDecl())); + return cast<CXXRecordDecl>(rhsRecord->getDecl()) + ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl())); } static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, @@ -1670,9 +1681,8 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, diag::err_incomplete_type)) return false; - return cast<CXXRecordDecl>(DerivedRecord->getOriginalDecl()) - ->isVirtuallyDerivedFrom( - cast<CXXRecordDecl>(BaseRecord->getOriginalDecl())); + return cast<CXXRecordDecl>(DerivedRecord->getDecl()) + ->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl())); } case BTT_IsSame: return Self.Context.hasSameType(LhsT, RhsT); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 04a5e4b..86896ab 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7160,13 +7160,13 @@ QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB, } auto *TD = cast_or_null<TagDecl>( - getDerived().TransformDecl(TL.getNameLoc(), T->getOriginalDecl())); + getDerived().TransformDecl(TL.getNameLoc(), T->getDecl())); if (!TD) return QualType(); QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() || - TD != T->getOriginalDecl()) { + TD != T->getDecl()) { if (T->isCanonicalUnqualified()) Result = getDerived().RebuildCanonicalTagType(TD); else diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 32f7a0e..8b3fd41 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5504,7 +5504,7 @@ void ASTReader::InitializeContext() { Error("Invalid FILE type in AST file"); return; } - Context.setFILEDecl(Tag->getOriginalDecl()); + Context.setFILEDecl(Tag->getDecl()); } } } @@ -5525,7 +5525,7 @@ void ASTReader::InitializeContext() { Error("Invalid jmp_buf type in AST file"); return; } - Context.setjmp_bufDecl(Tag->getOriginalDecl()); + Context.setjmp_bufDecl(Tag->getDecl()); } } } @@ -5543,7 +5543,7 @@ void ASTReader::InitializeContext() { else { const TagType *Tag = Sigjmp_bufType->getAs<TagType>(); assert(Tag && "Invalid sigjmp_buf type in AST file"); - Context.setsigjmp_bufDecl(Tag->getOriginalDecl()); + Context.setsigjmp_bufDecl(Tag->getDecl()); } } } @@ -5578,7 +5578,7 @@ void ASTReader::InitializeContext() { else { const TagType *Tag = Ucontext_tType->getAs<TagType>(); assert(Tag && "Invalid ucontext_t type in AST file"); - Context.setucontext_tDecl(Tag->getOriginalDecl()); + Context.setucontext_tDecl(Tag->getDecl()); } } } diff --git a/clang/lib/Serialization/TemplateArgumentHasher.cpp b/clang/lib/Serialization/TemplateArgumentHasher.cpp index 3e8ffea..353e8a2 100644 --- a/clang/lib/Serialization/TemplateArgumentHasher.cpp +++ b/clang/lib/Serialization/TemplateArgumentHasher.cpp @@ -358,7 +358,7 @@ public: AddQualType(T->getReplacementType()); } - void VisitTagType(const TagType *T) { AddDecl(T->getOriginalDecl()); } + void VisitTagType(const TagType *T) { AddDecl(T->getDecl()); } void VisitRecordType(const RecordType *T) { VisitTagType(T); } void VisitEnumType(const EnumType *T) { VisitTagType(T); } diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp index b304350..7cc146e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -246,7 +246,7 @@ public: bool Find(const TypedValueRegion *R) { QualType T = R->getValueType(); if (const RecordType *RT = T->getAsStructureType()) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinition(); + const RecordDecl *RD = RT->getDecl()->getDefinition(); assert(RD && "Referred record has no definition"); for (const auto *I : RD->fields()) { if (I->isUnnamedBitField()) diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index 17af1ae..5e75c1c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -154,15 +154,15 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { .Case("mkstemp", &WalkAST::checkCall_mkstemp) .Case("mkdtemp", &WalkAST::checkCall_mkstemp) .Case("mkstemps", &WalkAST::checkCall_mkstemp) - .Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy) - .Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat) - .Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf", - "vscanf", "vwscanf", "vfscanf", "vfwscanf", + .Cases({"strcpy", "__strcpy_chk"}, &WalkAST::checkCall_strcpy) + .Cases({"strcat", "__strcat_chk"}, &WalkAST::checkCall_strcat) + .Cases({"sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf", + "vscanf", "vwscanf", "vfscanf", "vfwscanf"}, &WalkAST::checkDeprecatedOrUnsafeBufferHandling) - .Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf", - "snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove", + .Cases({"sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf", + "snprintf", "vswprintf", "vsnprintf", "memcpy", "memmove"}, &WalkAST::checkDeprecatedOrUnsafeBufferHandling) - .Cases("strncpy", "strncat", "memset", "fprintf", + .Cases({"strncpy", "strncat", "memset", "fprintf"}, &WalkAST::checkDeprecatedOrUnsafeBufferHandling) .Case("drand48", &WalkAST::checkCall_rand) .Case("erand48", &WalkAST::checkCall_rand) @@ -766,12 +766,14 @@ void WalkAST::checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE, int ArgIndex = llvm::StringSwitch<int>(Name) - .Cases("scanf", "wscanf", "vscanf", "vwscanf", 0) - .Cases("fscanf", "fwscanf", "vfscanf", "vfwscanf", "sscanf", - "swscanf", "vsscanf", "vswscanf", 1) - .Cases("sprintf", "vsprintf", "fprintf", 1) - .Cases("swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy", - "memmove", "memset", "strncpy", "strncat", DEPR_ONLY) + .Cases({"scanf", "wscanf", "vscanf", "vwscanf"}, 0) + .Cases({"fscanf", "fwscanf", "vfscanf", "vfwscanf", "sscanf", + "swscanf", "vsscanf", "vswscanf"}, + 1) + .Cases({"sprintf", "vsprintf", "fprintf"}, 1) + .Cases({"swprintf", "snprintf", "vswprintf", "vsnprintf", "memcpy", + "memmove", "memset", "strncpy", "strncat"}, + DEPR_ONLY) .Default(UNKNOWN_CALL); assert(ArgIndex != UNKNOWN_CALL && "Unsupported function"); diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp index b1a7cd7..bc67391 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp @@ -148,9 +148,8 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call, QualType T = ArgE->getType(); const RecordType *UT = T->getAsUnionType(); - if (!UT || !UT->getOriginalDecl() - ->getMostRecentDecl() - ->hasAttr<TransparentUnionAttr>()) + if (!UT || + !UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) continue; auto CSV = DV->getAs<nonloc::CompoundVal>(); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index 319aaca..e45673d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -26,6 +26,7 @@ bool tryToFindPtrOrigin( const Expr *E, bool StopAtFirstRefCountedObj, std::function<bool(const clang::CXXRecordDecl *)> isSafePtr, std::function<bool(const clang::QualType)> isSafePtrType, + std::function<bool(const clang::Decl *)> isSafeGlobalDecl, std::function<bool(const clang::Expr *, bool)> callback) { while (E) { if (auto *DRE = dyn_cast<DeclRefExpr>(E)) { @@ -34,6 +35,8 @@ bool tryToFindPtrOrigin( auto IsImmortal = safeGetName(VD) == "NSApp"; if (VD->hasGlobalStorage() && (IsImmortal || QT.isConstQualified())) return callback(E, true); + if (VD->hasGlobalStorage() && isSafeGlobalDecl(VD)) + return callback(E, true); } } if (auto *tempExpr = dyn_cast<MaterializeTemporaryExpr>(E)) { @@ -71,9 +74,11 @@ bool tryToFindPtrOrigin( } if (auto *Expr = dyn_cast<ConditionalOperator>(E)) { return tryToFindPtrOrigin(Expr->getTrueExpr(), StopAtFirstRefCountedObj, - isSafePtr, isSafePtrType, callback) && + isSafePtr, isSafePtrType, isSafeGlobalDecl, + callback) && tryToFindPtrOrigin(Expr->getFalseExpr(), StopAtFirstRefCountedObj, - isSafePtr, isSafePtrType, callback); + isSafePtr, isSafePtrType, isSafeGlobalDecl, + callback); } if (auto *cast = dyn_cast<CastExpr>(E)) { if (StopAtFirstRefCountedObj) { @@ -177,7 +182,7 @@ bool tryToFindPtrOrigin( if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(RetType)) { if (auto *SubstType = Subst->desugar().getTypePtr()) { if (auto *RD = dyn_cast<RecordType>(SubstType)) { - if (auto *CXX = dyn_cast<CXXRecordDecl>(RD->getOriginalDecl())) + if (auto *CXX = dyn_cast<CXXRecordDecl>(RD->getDecl())) if (isSafePtr(CXX)) return callback(E, true); } diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h index 3a009d6..9fff456 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h @@ -56,6 +56,7 @@ bool tryToFindPtrOrigin( const clang::Expr *E, bool StopAtFirstRefCountedObj, std::function<bool(const clang::CXXRecordDecl *)> isSafePtr, std::function<bool(const clang::QualType)> isSafePtrType, + std::function<bool(const clang::Decl *)> isSafeGlobalDecl, std::function<bool(const clang::Expr *, bool)> callback); /// For \p E referring to a ref-countable/-counted pointer/reference we return diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index e5c74bb..b41e450 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -255,7 +255,7 @@ void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) { return; } - for (auto *Redecl : RT->getOriginalDecl()->getMostRecentDecl()->redecls()) { + for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) { if (Redecl->getAttr<ObjCBridgeAttr>() || Redecl->getAttr<ObjCBridgeMutableAttr>()) { CFPointees.insert(RT); @@ -296,7 +296,7 @@ std::optional<bool> isUnretained(const QualType T, bool IsARCEnabled) { auto *Record = PointeeType->getAsStructureType(); if (!Record) return false; - auto *Decl = Record->getOriginalDecl(); + auto *Decl = Record->getDecl(); if (!Decl) return false; auto TypeName = Decl->getName(); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp index 9585ceb..791e709 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp @@ -29,12 +29,12 @@ namespace { class RawPtrRefCallArgsChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> { BugType Bug; - mutable BugReporter *BR; TrivialFunctionAnalysis TFA; EnsureFunctionAnalysis EFA; protected: + mutable BugReporter *BR; mutable std::optional<RetainTypeChecker> RTC; public: @@ -46,6 +46,7 @@ public: virtual bool isSafePtr(const CXXRecordDecl *Record) const = 0; virtual bool isSafePtrType(const QualType type) const = 0; virtual bool isSafeExpr(const Expr *) const { return false; } + virtual bool isSafeDecl(const Decl *) const { return false; } virtual const char *ptrKind() const = 0; void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, @@ -214,6 +215,7 @@ public: Arg, /*StopAtFirstRefCountedObj=*/true, [&](const clang::CXXRecordDecl *Record) { return isSafePtr(Record); }, [&](const clang::QualType T) { return isSafePtrType(T); }, + [&](const clang::Decl *D) { return isSafeDecl(D); }, [&](const clang::Expr *ArgOrigin, bool IsSafe) { if (IsSafe) return true; @@ -479,6 +481,11 @@ public: isa<ObjCMessageExpr>(E); } + bool isSafeDecl(const Decl *D) const final { + // Treat NS/CF globals in system header as immortal. + return BR->getSourceManager().isInSystemHeader(D->getLocation()); + } + const char *ptrKind() const final { return "unretained"; } }; diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp index dd9701f..c13df479 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp @@ -166,10 +166,10 @@ bool isGuardedScopeEmbeddedInGuardianScope(const VarDecl *Guarded, class RawPtrRefLocalVarsChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> { BugType Bug; - mutable BugReporter *BR; EnsureFunctionAnalysis EFA; protected: + mutable BugReporter *BR; mutable std::optional<RetainTypeChecker> RTC; public: @@ -180,6 +180,7 @@ public: virtual bool isSafePtr(const CXXRecordDecl *) const = 0; virtual bool isSafePtrType(const QualType) const = 0; virtual bool isSafeExpr(const Expr *) const { return false; } + virtual bool isSafeDecl(const Decl *) const { return false; } virtual const char *ptrKind() const = 0; void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, @@ -288,6 +289,7 @@ public: return isSafePtr(Record); }, [&](const clang::QualType Type) { return isSafePtrType(Type); }, + [&](const clang::Decl *D) { return isSafeDecl(D); }, [&](const clang::Expr *InitArgOrigin, bool IsSafe) { if (!InitArgOrigin || IsSafe) return true; @@ -443,6 +445,10 @@ public: return ento::cocoa::isCocoaObjectRef(E->getType()) && isa<ObjCMessageExpr>(E); } + bool isSafeDecl(const Decl *D) const final { + // Treat NS/CF globals in system header as immortal. + return BR->getSourceManager().isInSystemHeader(D->getLocation()); + } const char *ptrKind() const final { return "unretained"; } }; diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp index 6f3a280..c6421f8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp @@ -121,13 +121,13 @@ public: return true; } } else if (auto *RD = dyn_cast<RecordType>(PointeeType)) { - if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl)) + if (declaresSameEntity(RD->getDecl(), ClassDecl)) return true; } else if (auto *ST = dyn_cast<SubstTemplateTypeParmType>(PointeeType)) { auto Type = ST->getReplacementType(); if (auto *RD = dyn_cast<RecordType>(Type)) { - if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl)) + if (declaresSameEntity(RD->getDecl(), ClassDecl)) return true; } } diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 06ba015..62460cc 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -89,7 +89,7 @@ static bool isCallback(QualType T) { T = T->getPointeeType(); if (const RecordType *RT = T->getAsStructureType()) { - const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf(); + const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf(); for (const auto *I : RD->fields()) { QualType FieldT = I->getType(); if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType()) @@ -391,9 +391,8 @@ bool CallEvent::isVariadic(const Decl *D) { static bool isTransparentUnion(QualType T) { const RecordType *UT = T->getAsUnionType(); - return UT && UT->getOriginalDecl() - ->getMostRecentDecl() - ->hasAttr<TransparentUnionAttr>(); + return UT && + UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>(); } // In some cases, symbolic cases should be transformed before we associate diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index af0ef52..2838533 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2457,7 +2457,7 @@ NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B, SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B, const TypedValueRegion *R) { const RecordDecl *RD = - R->getValueType()->castAsCanonical<RecordType>()->getOriginalDecl(); + R->getValueType()->castAsCanonical<RecordType>()->getDecl(); if (!RD->getDefinition()) return UnknownVal(); |