llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Oliver Hunt (ojhunt) <details> <summary>Changes</summary> --- Patch is 245.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/94056.diff 53 Files Affected: - (modified) clang/include/clang/AST/ASTContext.h (+13) - (modified) clang/include/clang/AST/GlobalDecl.h (+4) - (modified) clang/include/clang/AST/Mangle.h (+5-6) - (modified) clang/include/clang/AST/VTableBuilder.h (+29) - (modified) clang/include/clang/Basic/Attr.td (+29) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+31) - (modified) clang/include/clang/Basic/PointerAuthOptions.h (+25) - (modified) clang/include/clang/Basic/Thunk.h (+10-3) - (modified) clang/include/clang/CodeGen/CodeGenABITypes.h (+4) - (modified) clang/include/clang/CodeGen/ConstantInitBuilder.h (+15-1) - (modified) clang/include/clang/InstallAPI/Visitor.h (+2-2) - (modified) clang/include/clang/Sema/Sema.h (+4) - (modified) clang/lib/AST/ASTContext.cpp (+86) - (modified) clang/lib/AST/ItaniumMangle.cpp (+70-7) - (modified) clang/lib/AST/Mangle.cpp (+17-6) - (modified) clang/lib/AST/MicrosoftMangle.cpp (+16-7) - (modified) clang/lib/AST/VTableBuilder.cpp (+101-6) - (modified) clang/lib/CodeGen/CGCXX.cpp (+10-1) - (modified) clang/lib/CodeGen/CGCXXABI.h (+8-6) - (modified) clang/lib/CodeGen/CGClass.cpp (+30-1) - (modified) clang/lib/CodeGen/CGExpr.cpp (+5-2) - (modified) clang/lib/CodeGen/CGExprConstant.cpp (+76-1) - (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+239) - (modified) clang/lib/CodeGen/CGVTT.cpp (+5) - (modified) clang/lib/CodeGen/CGVTables.cpp (+38-10) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+27) - (modified) clang/lib/CodeGen/CodeGenFunction.h (+18-2) - (modified) clang/lib/CodeGen/CodeGenModule.h (+19) - (modified) clang/lib/CodeGen/ConstantEmitter.h (+3) - (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+53-19) - (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+7-2) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+12) - (modified) clang/lib/Headers/ptrauth.h (+14) - (modified) clang/lib/InstallAPI/Visitor.cpp (+7-6) - (modified) clang/lib/Parse/ParseDecl.cpp (+29-1) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+116) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+46) - (modified) clang/lib/Sema/SemaExpr.cpp (+33) - (added) clang/test/CodeGen/ptrauth-ubsan-vptr.cpp (+30) - (modified) clang/test/CodeGenCXX/catch-undef-behavior.cpp (+4-3) - (added) clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call-2.cpp (+105) - (added) clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call.cpp (+42) - (added) clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-virtual-dtor-call.cpp (+50) - (added) clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp (+652) - (added) clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp (+10) - (added) clang/test/CodeGenCXX/ptrauth-thunks.cpp (+28) - (added) clang/test/CodeGenCXX/ptrauth-virtual-function.cpp (+581) - (added) clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp (+309) - (modified) clang/test/CodeGenCXX/ubsan-vtable-checks.cpp (+46-2) - (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test (+1) - (added) clang/test/SemaCXX/ptrauth-incomplete-virtual-member-function-return-arg-type.cpp (+50) - (added) clang/test/SemaCXX/vtable_pointer_authentication_attribute.cpp (+225) - (modified) clang/utils/TableGen/ClangAttrEmitter.cpp (+27) ``````````diff diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index a1d1d1c51cd41..e601face9c2b6 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -37,6 +37,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/TypeSize.h" #include <optional> @@ -1261,6 +1262,10 @@ class ASTContext : public RefCountedBase<ASTContext> { /// space. QualType removeAddrSpaceQualType(QualType T) const; + /// Return the "other" type-specific discriminator for the given type. + uint16_t + getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *record); + /// Apply Objective-C protocol qualifiers to the given type. /// \param allowOnPointerType specifies if we can apply protocol /// qualifiers on ObjCObjectPointerType. It can be set to true when @@ -3418,12 +3423,20 @@ OPT_LIST(V) /// Whether a C++ static variable or CUDA/HIP kernel should be externalized. bool shouldExternalize(const Decl *D) const; + /// Resolve the root record to be used to derive the vtable pointer + /// authentication policy for the specified record. + const CXXRecordDecl *baseForVTableAuthentication(const CXXRecordDecl *); + bool useAbbreviatedThunkName(GlobalDecl virtualMethodDecl, + StringRef mangledName); + StringRef getCUIDHash() const; private: /// All OMPTraitInfo objects live in this collection, one per /// `pragma omp [begin] declare variant` directive. SmallVector<std::unique_ptr<OMPTraitInfo>, 4> OMPTraitInfoVector; + + llvm::DenseMap<GlobalDecl, llvm::StringSet<>> thunksToBeAbbreviated; }; /// Insertion operator for diagnostics. diff --git a/clang/include/clang/AST/GlobalDecl.h b/clang/include/clang/AST/GlobalDecl.h index 88abba28c991d..386693cabb1fb 100644 --- a/clang/include/clang/AST/GlobalDecl.h +++ b/clang/include/clang/AST/GlobalDecl.h @@ -145,6 +145,10 @@ class GlobalDecl { LHS.MultiVersionIndex == RHS.MultiVersionIndex; } + bool operator!=(const GlobalDecl &Other) const { + return !(*this == Other); + } + void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } explicit operator bool() const { return getAsOpaquePtr(); } diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h index e586b0cec43df..d83d56cf42c72 100644 --- a/clang/include/clang/AST/Mangle.h +++ b/clang/include/clang/AST/Mangle.h @@ -130,15 +130,15 @@ class MangleContext { // FIXME: consider replacing raw_ostream & with something like SmallString &. void mangleName(GlobalDecl GD, raw_ostream &); virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0; - virtual void mangleThunk(const CXXMethodDecl *MD, - const ThunkInfo &Thunk, - raw_ostream &) = 0; + virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, + bool elideOverrideInfo, raw_ostream &) = 0; virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, - const ThisAdjustment &ThisAdjustment, - raw_ostream &) = 0; + const ThunkInfo &Thunk, + bool elideOverrideInfo, raw_ostream &) = 0; virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &) = 0; + virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers = false) = 0; @@ -192,7 +192,6 @@ class ItaniumMangleContext : public MangleContext { bool IsAux = false) : MangleContext(C, D, MK_Itanium, IsAux) {} - virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0; virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, const CXXRecordDecl *Type, diff --git a/clang/include/clang/AST/VTableBuilder.h b/clang/include/clang/AST/VTableBuilder.h index fbf6c041a1ec1..a5de41dbc22f1 100644 --- a/clang/include/clang/AST/VTableBuilder.h +++ b/clang/include/clang/AST/VTableBuilder.h @@ -361,6 +361,10 @@ class VTableContextBase { }; class ItaniumVTableContext : public VTableContextBase { +public: + typedef llvm::DenseMap<const CXXMethodDecl *, const CXXMethodDecl *> + OriginalMethodMapTy; + private: /// Contains the index (relative to the vtable address point) @@ -384,6 +388,10 @@ class ItaniumVTableContext : public VTableContextBase { VirtualBaseClassOffsetOffsetsMapTy; VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets; + /// Map from a virtual method to the nearest method in the primary base class + /// chain that it overrides. + OriginalMethodMapTy OriginalMethodMap; + void computeVTableRelatedInformation(const CXXRecordDecl *RD) override; public: @@ -425,6 +433,27 @@ class ItaniumVTableContext : public VTableContextBase { CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase); + /// Return the method that added the v-table slot that will be used to call + /// the given method. + /// + /// In the Itanium ABI, where overrides always cause methods to be added to + /// the primary v-table if they're not already there, this will be the first + /// declaration in the primary base class chain for which the return type + /// adjustment is trivial. + GlobalDecl findOriginalMethod(GlobalDecl GD); + + const CXXMethodDecl *findOriginalMethodInMap(const CXXMethodDecl *MD) const; + + void setOriginalMethod(const CXXMethodDecl *Key, const CXXMethodDecl *Val) { + OriginalMethodMap[Key] = Val; + } + + /// This method is reserved for the implementation and shouldn't be used + /// directly. + const OriginalMethodMapTy &getOriginalMethodMap() { + return OriginalMethodMap; + } + static bool classof(const VTableContextBase *VT) { return !VT->isMicrosoft(); } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index ef9df1e9d8b4a..191afdc147f40 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -680,6 +680,10 @@ class Attr { bit PragmaAttributeSupport; // Set to true if this attribute accepts parameter pack expansion expressions. bit AcceptsExprPack = 0; + // To support multiple enum parameters to an attribute without breaking + // our existing general parsing we need to have a separate flag that + // opts an attribute into strict parsing of attribute parameters + bit StrictEnumParameters = 0; // Lists language options, one of which is required to be true for the // attribute to be applicable. If empty, no language options are required. list<LangOpt> LangOpts = []; @@ -4546,6 +4550,31 @@ def NoRandomizeLayout : InheritableAttr { } def : MutualExclusions<[RandomizeLayout, NoRandomizeLayout]>; +def VTablePointerAuthentication : InheritableAttr { + let Spellings = [Clang<"ptrauth_vtable_pointer">]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [Undocumented]; + let StrictEnumParameters = 1; + let Args = [EnumArgument<"Key", "VPtrAuthKeyType", /*is_string=*/ true, + ["default_key", "no_authentication", "process_dependent", + "process_independent"], + ["DefaultKey", "NoKey", "ProcessDependent", + "ProcessIndependent"]>, + EnumArgument<"AddressDiscrimination", "AddressDiscriminationMode", + /*is_string=*/ true, + ["default_address_discrimination", "no_address_discrimination", + "address_discrimination"], + ["DefaultAddressDiscrimination", "NoAddressDiscrimination", + "AddressDiscrimination"]>, + EnumArgument<"ExtraDiscrimination", "ExtraDiscrimination", + /*is_string=*/ true, + ["default_extra_discrimination", "no_extra_discrimination", + "type_discrimination", "custom_discrimination"], + ["DefaultExtraDiscrimination", "NoExtraDiscrimination", + "TypeDiscrimination", "CustomDiscrimination"]>, + IntArgument<"CustomDiscriminationValue", 1>]; +} + def FunctionReturnThunks : InheritableAttr, TargetSpecificAttr<TargetAnyX86> { let Spellings = [GCC<"function_return">]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 753e775ce0968..88b8fd344648b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -938,6 +938,13 @@ def warn_ptrauth_auth_null_pointer : def err_ptrauth_string_not_literal : Error< "argument must be a string literal%select{| of char type}0">; +def note_ptrauth_virtual_function_pointer_incomplete_arg_ret : + Note<"cannot take an address of a virtual member function if its return or " + "argument types are incomplete">; +def note_ptrauth_virtual_function_incomplete_arg_ret_type : + Note<"%0 is incomplete">; + + /// main() // static main() is not an error in C, just in C++. def warn_static_main : Warning<"'main' should not be declared static">, @@ -12175,6 +12182,30 @@ def warn_cuda_maxclusterrank_sm_90 : Warning< "maxclusterrank requires sm_90 or higher, CUDA arch provided: %0, ignoring " "%1 attribute">, InGroup<IgnoredAttributes>; +// VTable pointer authentication errors +def err_non_polymorphic_vtable_pointer_auth : Error< + "cannot set vtable pointer authentication on monomorphic type %0">; +def err_incomplete_type_vtable_pointer_auth : Error< + "cannot set vtable pointer authentication on an incomplete type %0">; +def err_non_top_level_vtable_pointer_auth : Error< + "cannot set vtable pointer authentication on %0 which is a subclass of polymorphic type %1">; +def err_duplicated_vtable_pointer_auth : Error< + "multiple vtable pointer authentication policies on %0">; +def err_invalid_authentication_key : Error< + "invalid authentication key %0">; +def err_invalid_address_discrimination : Error< + "invalid address discrimination mode %0">; +def err_invalid_extra_discrimination : Error< + "invalid extra discrimination selection %0">; +def err_invalid_custom_discrimination : Error< + "invalid custom discrimination">; +def err_missing_custom_discrimination : Error< + "missing custom discrimination">; +def err_no_default_vtable_pointer_auth : Error< + "cannot specify a default vtable pointer authentication " + "%select{key|address discrimination mode|discriminator}0 with no default set" +>; + def err_bit_int_bad_size : Error<"%select{signed|unsigned}0 _BitInt must " "have a bit size of at least %select{2|1}0">; def err_bit_int_max_size : Error<"%select{signed|unsigned}0 _BitInt of bit " diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h index 32b179e3f9460..d4d794a6fabe0 100644 --- a/clang/include/clang/Basic/PointerAuthOptions.h +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -49,6 +49,12 @@ class PointerAuthSchema { /// No additional discrimination. None, + /// Include a hash of the entity's type. + Type, + + /// Include a hash of the entity's identity. + Decl, + /// Discriminate using a constant value. Constant, }; @@ -152,6 +158,25 @@ class PointerAuthSchema { struct PointerAuthOptions { /// The ABI for C function pointers. PointerAuthSchema FunctionPointers; + + /// The ABI for C++ virtual table pointers (the pointer to the table + /// itself) as installed in an actual class instance. + PointerAuthSchema CXXVTablePointers; + + /// TypeInfo has external ABI requirements and is emitted without + /// actually having parsed the libcxx definition, so we can't simply + /// perform a look up. The settings for this should match the exact + /// specification in type_info.h + PointerAuthSchema CXXTypeInfoVTablePointer; + + /// The ABI for C++ virtual table pointers as installed in a VTT. + PointerAuthSchema CXXVTTVTablePointers; + + /// The ABI for most C++ virtual function pointers, i.e. v-table entries. + PointerAuthSchema CXXVirtualFunctionPointers; + + /// The ABI for variadic C++ virtual function pointers. + PointerAuthSchema CXXVirtualVariadicFunctionPointers; }; } // end namespace clang diff --git a/clang/include/clang/Basic/Thunk.h b/clang/include/clang/Basic/Thunk.h index 0247e279408f0..4dccebf687585 100644 --- a/clang/include/clang/Basic/Thunk.h +++ b/clang/include/clang/Basic/Thunk.h @@ -162,20 +162,27 @@ struct ThunkInfo { /// Holds a pointer to the overridden method this thunk is for, /// if needed by the ABI to distinguish different thunks with equal - /// adjustments. Otherwise, null. + /// adjustments. + /// In the Itanium ABI, this field can hold the method that created the + /// vtable entry for this thunk. + /// Otherwise, null. /// CAUTION: In the unlikely event you need to sort ThunkInfos, consider using /// an ABI-specific comparator. const CXXMethodDecl *Method; + const Type *ThisType { nullptr }; ThunkInfo() : Method(nullptr) {} ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return, + const Type *thisType, const CXXMethodDecl *Method = nullptr) - : This(This), Return(Return), Method(Method) {} + : This(This), Return(Return), Method(Method), + ThisType(thisType) {} friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) { return LHS.This == RHS.This && LHS.Return == RHS.Return && - LHS.Method == RHS.Method; + LHS.Method == RHS.Method && + LHS.ThisType == RHS.ThisType; } bool isEmpty() const { diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h index 8c62d8597ecbe..0d0c152c6fea0 100644 --- a/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -42,6 +42,7 @@ class CXXConstructorDecl; class CXXDestructorDecl; class CXXRecordDecl; class CXXMethodDecl; +class GlobalDecl; class ObjCMethodDecl; class ObjCProtocolDecl; @@ -104,6 +105,9 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T); unsigned getLLVMFieldNumber(CodeGenModule &CGM, const RecordDecl *RD, const FieldDecl *FD); +/// Return a declaration discriminator for the given global decl. +uint16_t getPointerAuthDeclDiscriminator(CodeGenModule &CGM, GlobalDecl GD); + /// Return a signed constant pointer. llvm::Constant *getConstantSignedPointer(CodeGenModule &CGM, llvm::Constant *pointer, diff --git a/clang/include/clang/CodeGen/ConstantInitBuilder.h b/clang/include/clang/CodeGen/ConstantInitBuilder.h index 498acfd380131..f6d8e15ff2131 100644 --- a/clang/include/clang/CodeGen/ConstantInitBuilder.h +++ b/clang/include/clang/CodeGen/ConstantInitBuilder.h @@ -25,8 +25,11 @@ #include <vector> namespace clang { -namespace CodeGen { +class GlobalDecl; +class PointerAuthSchema; +class QualType; +namespace CodeGen { class CodeGenModule; /// A convenience builder class for complex constant initializers, @@ -199,6 +202,17 @@ class ConstantAggregateBuilderBase { add(llvm::ConstantInt::get(intTy, value, isSigned)); } + /// Add a signed pointer using the given pointer authentication schema. + void addSignedPointer(llvm::Constant *pointer, + const PointerAuthSchema &schema, GlobalDecl calleeDecl, + QualType calleeType); + + /// Add a signed pointer using the given pointer authentication schema. + void addSignedPointer(llvm::Constant *pointer, + unsigned key, + bool useAddressDiscrimination, + llvm::Constant *otherDiscriminator); + /// Add a null pointer of a specific type. void addNullPointer(llvm::PointerType *ptrTy) { add(llvm::ConstantPointerNull::get(ptrTy)); diff --git a/clang/include/clang/InstallAPI/Visitor.h b/clang/include/clang/InstallAPI/Visitor.h index 9ac948ded3e33..3680ee566ca87 100644 --- a/clang/include/clang/InstallAPI/Visitor.h +++ b/clang/include/clang/InstallAPI/Visitor.h @@ -60,8 +60,8 @@ class InstallAPIVisitor final : public ASTConsumer, std::string getMangledName(const NamedDecl *D) const; std::string getBackendMangledName(llvm::Twine Name) const; std::string getMangledCXXVTableName(const CXXRecordDecl *D) const; - std::string getMangledCXXThunk(const GlobalDecl &D, - const ThunkInfo &Thunk) const; + std::string getMangledCXXThunk(const GlobalDecl &D, const ThunkInfo &Thunk, + bool ElideOverrideInfo) const; std::string getMangledCXXRTTI(const CXXRecordDecl *D) const; std::string getMangledCXXRTTIName(const CXXRecordDecl *D) const; std::string getMangledCtorDtor(const CXXMethodDecl *D, int Type) const; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ec083f7cc09b7..dd65662e77860 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4401,6 +4401,10 @@ class Sema final : public SemaBase { /// conditions that are needed for the attribute to have an effect. void checkIllFormedTrivialABIStruct(CXXRecordDecl &RD); + /// Check that VTable Pointer authentication is only being set on the first + /// first instantiation of the vtable + void checkIncorrectVTablePointerAuthenticationAttribute(CXXRecordDecl &RD); + void ActOnFinishCXXMemberSpecification(Scope *S, SourceLocation RLoc, Decl *TagDecl, SourceLocation LBrac, SourceLocation RBrac, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a2398fef623ea..2e230ce556459 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -86,6 +86,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/SipHash.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" #include <algorithm> @@ -3088,6 +3089,17 @@ QualType ASTContext::removeAddrSpaceQualType(QualType T) const { return QualType(TypeNode, Quals.getFastQualifiers()); } +uint16_t ASTContext::getPointerAuthVTablePointerDiscriminator( + const CXXRecordDecl *record) { + assert(record->isPolymorphic() && + "Attempted to get vtable pointer discriminator on a monomorphic type"); + std::unique_ptr<MangleContext> MC(createMangleContext()); + SmallString<256> Str; + llvm::raw_svector_ostream Out(Str); + MC->mangleCXXVTable(record, Out); + return llvm::getPointerAuthStableSipHash16(Str.c_str()); +} + QualType ASTContext::getObjCGCQualType(QualType T, Qualifiers::GC GCAttr) const { QualType CanT = getCanonicalType(T); @@ -13812,3 +13824,77 @@ StringRef ASTContext::getCUIDHash() const { CUIDHash = llvm::utohexstr(llvm::MD5Hash(LangOpts.CUID), /*LowerCase=*/true); return CUIDHash; } + +const CXXRecordDecl * +ASTContext::baseForVTableAuthentication(const CXXRecordDecl *thisClass) { + assert(thisClass); + assert(thisClass->isPolymorphic()); + const CXXRecordDecl *primaryBase = thisClass; + while (1) { + assert(primaryBase); + assert(primaryBase->isPolymorphic()); + auto &layout = getASTRecordLayout(primaryBase); + auto base = layout.getPrimaryBase(); + if (!base || base == primaryBase || !base->isPolymorphic()) + break; + primaryBase = base; + } + return primaryBase; +} + +bool ASTContext::useAbbreviatedThunkName(GlobalDecl virtualMethodDecl, + StringRef mangledName) { + auto method = cast<CXXMethodDecl>(virtualMethodDe... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/94056 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits