10 #include "TargetInfo.h"
13 #include "llvm/TargetParser/AArch64TargetParser.h"
15 using namespace clang;
24 class AArch64ABIInfo :
public ABIInfo {
39 unsigned CallingConvention)
const;
41 bool isHomogeneousAggregateBaseType(
QualType Ty)
const override;
42 bool isHomogeneousAggregateSmallEnough(
const Type *Ty,
44 bool isZeroLengthBitfieldPermittedInHomogeneousAggregate()
const override;
46 bool isIllegalVectorType(
QualType Ty)
const;
67 if (isa<llvm::ScalableVectorType>(BaseTy))
68 llvm::report_fatal_error(
"Passing SVE types to variadic functions is "
69 "currently not supported");
72 : isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF)
73 : EmitAAPCSVAArg(VAListAddr, Ty, CGF,
Kind);
79 bool allowBFloatArgsAndRet()
const override {
80 return getTarget().hasBFloat16Type();
84 void appendAttributeMangling(TargetClonesAttr *
Attr,
unsigned Index,
85 raw_ostream &Out)
const override;
86 void appendAttributeMangling(StringRef AttrStr,
87 raw_ostream &Out)
const override;
96 unsigned NumElts)
const override;
103 SwiftInfo = std::make_unique<AArch64SwiftABIInfo>(CGT);
106 StringRef getARCRetainAutoreleasedReturnValueMarker()
const override {
107 return "mov\tfp, fp\t\t// marker for objc_retainAutoreleaseReturnValue";
114 bool doesReturnSlotInterfereWithArgs()
const override {
return false; }
116 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
118 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
122 const auto *TA = FD->
getAttr<TargetAttr>();
128 if (
Attr.BranchProtection.empty())
134 Attr.CPU, BPI, Error);
135 assert(
Error.empty());
137 auto *Fn = cast<llvm::Function>(GV);
141 Fn->addFnAttr(
"sign-return-address-key",
147 Fn->addFnAttr(
"branch-target-enforcement",
149 Fn->addFnAttr(
"branch-protection-pauth-lr",
151 Fn->addFnAttr(
"guarded-control-stack",
156 llvm::Type *Ty)
const override {
158 auto *ST = dyn_cast<llvm::StructType>(Ty);
159 if (ST && ST->getNumElements() == 1) {
160 auto *AT = dyn_cast<llvm::ArrayType>(ST->getElementType(0));
161 if (AT && AT->getNumElements() == 8 &&
162 AT->getElementType()->isIntegerTy(64))
175 QualType ReturnType)
const override;
192 class WindowsAArch64TargetCodeGenInfo :
public AArch64TargetCodeGenInfo {
195 : AArch64TargetCodeGenInfo(CGT, K) {}
197 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
200 void getDependentLibraryOption(llvm::StringRef Lib,
202 Opt =
"/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);
205 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef
Value,
207 Opt =
"/FAILIFMISMATCH:\"" + Name.str() +
"=" +
Value.str() +
"\"";
211 void WindowsAArch64TargetCodeGenInfo::setTargetAttributes(
213 AArch64TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
214 if (GV->isDeclaration())
216 addStackProbeTargetAttributes(D, GV, CGM);
225 assert(VT->getElementType()->isBuiltinType() &&
"expected builtin type!");
227 BuiltinType::UChar &&
228 "unexpected builtin type for SVE predicate!");
230 llvm::Type::getInt1Ty(getVMContext()), 16));
234 assert(VT->getElementType()->isBuiltinType() &&
"expected builtin type!");
236 const auto *BT = VT->getElementType()->castAs<
BuiltinType>();
237 llvm::ScalableVectorType *ResType =
nullptr;
238 switch (BT->getKind()) {
240 llvm_unreachable(
"unexpected builtin type for SVE vector!");
241 case BuiltinType::SChar:
242 case BuiltinType::UChar:
243 ResType = llvm::ScalableVectorType::get(
244 llvm::Type::getInt8Ty(getVMContext()), 16);
246 case BuiltinType::Short:
247 case BuiltinType::UShort:
248 ResType = llvm::ScalableVectorType::get(
249 llvm::Type::getInt16Ty(getVMContext()), 8);
251 case BuiltinType::Int:
252 case BuiltinType::UInt:
253 ResType = llvm::ScalableVectorType::get(
254 llvm::Type::getInt32Ty(getVMContext()), 4);
256 case BuiltinType::Long:
257 case BuiltinType::ULong:
258 ResType = llvm::ScalableVectorType::get(
259 llvm::Type::getInt64Ty(getVMContext()), 2);
261 case BuiltinType::Half:
262 ResType = llvm::ScalableVectorType::get(
263 llvm::Type::getHalfTy(getVMContext()), 8);
266 ResType = llvm::ScalableVectorType::get(
267 llvm::Type::getFloatTy(getVMContext()), 4);
269 case BuiltinType::Double:
270 ResType = llvm::ScalableVectorType::get(
271 llvm::Type::getDoubleTy(getVMContext()), 2);
273 case BuiltinType::BFloat16:
274 ResType = llvm::ScalableVectorType::get(
275 llvm::Type::getBFloatTy(getVMContext()), 8);
283 if ((isAndroid() || isOHOSFamily()) && (Size <= 16)) {
284 llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext());
288 llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext());
293 llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 2);
298 llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 4);
301 return getNaturalAlignIndirect(Ty,
false);
306 unsigned CallingConvention)
const {
310 if (isIllegalVectorType(Ty))
311 return coerceIllegalVector(Ty);
316 Ty = EnumTy->getDecl()->getIntegerType();
319 if (EIT->getNumBits() > 128)
320 return getNaturalAlignIndirect(Ty,
false);
322 return (isPromotableIntegerTypeForABI(Ty) && isDarwinPCS()
330 return getNaturalAlignIndirect(Ty, RAA ==
338 if (IsEmpty || Size == 0) {
339 if (!getContext().getLangOpts().
CPlusPlus || isDarwinPCS())
344 if (IsEmpty && Size == 0)
353 CallingConvention == llvm::CallingConv::Win64;
354 bool IsWinVariadic = IsWin64 && IsVariadic;
357 if (!IsWinVariadic && isHomogeneousAggregate(Ty,
Base, Members)) {
360 llvm::ArrayType::get(CGT.ConvertType(
QualType(
Base, 0)), Members));
365 getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
366 Align = (Align >= 16) ? 16 : 8;
368 llvm::ArrayType::get(CGT.ConvertType(
QualType(
Base, 0)), Members), 0,
369 nullptr,
true, Align);
376 if (getTarget().isRenderScriptTarget()) {
381 Alignment = getContext().getTypeUnadjustedAlign(Ty);
382 Alignment = Alignment < 128 ? 64 : 128;
385 std::max(getContext().getTypeAlign(Ty),
388 Size = llvm::alignTo(Size, Alignment);
392 llvm::Type *BaseTy = llvm::Type::getIntNTy(getVMContext(), Alignment);
394 Size == Alignment ? BaseTy
395 : llvm::ArrayType::get(BaseTy, Size / Alignment));
398 return getNaturalAlignIndirect(Ty,
false);
402 bool IsVariadic)
const {
409 return coerceIllegalVector(RetTy);
413 if (RetTy->
isVectorType() && getContext().getTypeSize(RetTy) > 128)
414 return getNaturalAlignIndirect(RetTy);
419 RetTy = EnumTy->getDecl()->getIntegerType();
422 if (EIT->getNumBits() > 128)
423 return getNaturalAlignIndirect(RetTy);
425 return (isPromotableIntegerTypeForABI(RetTy) && isDarwinPCS()
436 if (isHomogeneousAggregate(RetTy,
Base, Members) &&
437 !(getTarget().getTriple().getArch() == llvm::Triple::aarch64_32 &&
446 if (getTarget().isRenderScriptTarget()) {
450 if (Size <= 64 && getDataLayout().isLittleEndian()) {
458 llvm::IntegerType::get(getVMContext(), Size));
461 unsigned Alignment = getContext().getTypeAlign(RetTy);
462 Size = llvm::alignTo(Size, 64);
466 if (Alignment < 128 && Size == 128) {
467 llvm::Type *BaseTy = llvm::Type::getInt64Ty(getVMContext());
473 return getNaturalAlignIndirect(RetTy);
477 bool AArch64ABIInfo::isIllegalVectorType(
QualType Ty)
const {
487 unsigned NumElements = VT->getNumElements();
490 if (!llvm::isPowerOf2_32(NumElements))
495 llvm::Triple Triple = getTarget().getTriple();
496 if (Triple.getArch() == llvm::Triple::aarch64_32 &&
497 Triple.isOSBinFormatMachO())
500 return Size != 64 && (
Size != 128 || NumElements == 1);
507 unsigned NumElts)
const {
508 if (!llvm::isPowerOf2_32(NumElts))
516 bool AArch64ABIInfo::isHomogeneousAggregateBaseType(
QualType Ty)
const {
527 if (BT->isFloatingPoint())
530 unsigned VecSize = getContext().getTypeSize(VT);
531 if (VecSize == 64 || VecSize == 128)
537 bool AArch64ABIInfo::isHomogeneousAggregateSmallEnough(
const Type *
Base,
542 bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
570 BaseTy = llvm::PointerType::getUnqual(BaseTy);
574 unsigned NumRegs = 1;
575 if (llvm::ArrayType *ArrTy = dyn_cast<llvm::ArrayType>(BaseTy)) {
576 BaseTy = ArrTy->getElementType();
577 NumRegs = ArrTy->getNumElements();
580 (BaseTy->isFloatingPointTy() || BaseTy->isVectorTy());
598 CharUnits TySize = getContext().getTypeSizeInChars(Ty);
599 CharUnits TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty);
602 llvm::Value *reg_offs =
nullptr;
604 int RegSize = IsIndirect ? 8 : TySize.
getQuantity();
610 RegSize = llvm::alignTo(RegSize, 8);
616 RegSize = 16 * NumRegs;
627 llvm::Value *UsingStack =
nullptr;
628 UsingStack = CGF.
Builder.CreateICmpSGE(
629 reg_offs, llvm::ConstantInt::get(CGF.
Int32Ty, 0));
631 CGF.
Builder.CreateCondBr(UsingStack, OnStackBlock, MaybeRegBlock);
640 if (!IsFPR && !IsIndirect && TyAlign.
getQuantity() > 8) {
643 reg_offs = CGF.
Builder.CreateAdd(
644 reg_offs, llvm::ConstantInt::get(CGF.
Int32Ty, Align - 1),
646 reg_offs = CGF.
Builder.CreateAnd(
647 reg_offs, llvm::ConstantInt::get(CGF.
Int32Ty, -Align),
655 llvm::Value *NewOffset =
nullptr;
656 NewOffset = CGF.
Builder.CreateAdd(
657 reg_offs, llvm::ConstantInt::get(CGF.
Int32Ty, RegSize),
"new_reg_offs");
662 llvm::Value *InRegs =
nullptr;
663 InRegs = CGF.
Builder.CreateICmpSLE(
664 NewOffset, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
"inreg");
666 CGF.
Builder.CreateCondBr(InRegs, InRegBlock, OnStackBlock);
676 llvm::Value *reg_top =
nullptr;
688 MemTy = llvm::PointerType::getUnqual(MemTy);
693 bool IsHFA = isHomogeneousAggregate(Ty,
Base, NumMembers);
694 if (IsHFA && NumMembers > 1) {
699 assert(!IsIndirect &&
"Homogeneous aggregates should be passed directly");
700 auto BaseTyInfo = getContext().getTypeInfoInChars(
QualType(
Base, 0));
702 llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers);
704 std::max(TyAlign, BaseTyInfo.Align));
709 BaseTyInfo.Width.getQuantity() < 16)
710 Offset = 16 - BaseTyInfo.Width.getQuantity();
712 for (
unsigned i = 0; i < NumMembers; ++i) {
729 CharUnits SlotSize = BaseAddr.getAlignment();
762 StackSize = StackSlotSize;
764 StackSize = TySize.
alignTo(StackSlotSize);
768 CGF.
Int8Ty, OnStackPtr, StackSizeC,
"new_stack");
774 TySize < StackSlotSize) {
789 OnStackBlock,
"vaargs.addr");
816 auto TyInfo = getContext().getTypeInfoInChars(Ty);
820 bool IsIndirect =
false;
821 if (TyInfo.Width.getQuantity() > 16) {
824 IsIndirect = !isHomogeneousAggregate(Ty,
Base, Members);
828 TyInfo, SlotSize,
true);
833 bool IsIndirect =
false;
855 const StringRef ABIName,
858 const Type *HABase =
nullptr;
870 void AArch64TargetCodeGenInfo::checkFunctionABI(
872 const AArch64ABIInfo &
ABIInfo = getABIInfo<AArch64ABIInfo>();
885 void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming(
888 if (!Caller || !Callee || !
Callee->hasAttr<AlwaysInlineAttr>())
891 bool CallerIsStreaming =
893 bool CalleeIsStreaming =
898 if (!CalleeIsStreamingCompatible &&
899 (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible))
901 diag::err_function_always_inline_attribute_mismatch)
903 if (
auto *NewAttr =
Callee->getAttr<ArmNewAttr>())
904 if (NewAttr->isNewZA())
905 CGM.
getDiags().
Report(CallLoc, diag::err_function_always_inline_new_za)
912 void AArch64TargetCodeGenInfo::checkFunctionCallABISoftFloat(
916 const AArch64ABIInfo &
ABIInfo = getABIInfo<AArch64ABIInfo>();
925 for (
const CallArg &Arg : Args)
930 void AArch64TargetCodeGenInfo::checkFunctionCallABI(
CodeGenModule &CGM,
936 checkFunctionCallABIStreaming(CGM, CallLoc, Caller, Callee);
937 checkFunctionCallABISoftFloat(CGM, CallLoc, Caller, Callee, Args, ReturnType);
940 void AArch64ABIInfo::appendAttributeMangling(TargetClonesAttr *
Attr,
942 raw_ostream &Out)
const {
943 appendAttributeMangling(
Attr->getFeatureStr(Index), Out);
946 void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr,
947 raw_ostream &Out)
const {
948 if (AttrStr ==
"default") {
955 AttrStr.split(Features,
"+");
956 for (
auto &Feat : Features)
959 llvm::sort(Features, [](
const StringRef LHS,
const StringRef RHS) {
960 return LHS.compare(RHS) < 0;
963 llvm::SmallDenseSet<StringRef, 8> UniqueFeats;
964 for (
auto &Feat : Features)
965 if (
auto Ext = llvm::AArch64::parseArchExtension(Feat))
966 if (UniqueFeats.insert(Ext->Name).second)
967 Out <<
'M' << Ext->Name;
970 std::unique_ptr<TargetCodeGenInfo>
973 return std::make_unique<AArch64TargetCodeGenInfo>(CGM.
getTypes(),
Kind);
976 std::unique_ptr<TargetCodeGenInfo>
979 return std::make_unique<WindowsAArch64TargetCodeGenInfo>(CGM.
getTypes(), K);
static bool isStreamingCompatible(const FunctionDecl *F)
static void diagnoseIfNeedsFPReg(DiagnosticsEngine &Diags, const StringRef ABIName, const AArch64ABIInfo &ABIInfo, const QualType &Ty, const NamedDecl *D)
__DEVICE__ int max(int __a, int __b)
TypeInfoChars getTypeInfoInChars(const Type *T) const
const TargetInfo & getTargetInfo() const
Attr - This represents one attribute.
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIgnore()
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
llvm::Type * getCoerceToType() const
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const
isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous aggregate.
ASTContext & getContext() const
virtual void appendAttributeMangling(TargetAttr *Attr, raw_ostream &Out) const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = [n x T]* ...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::ConstantInt * getSize(CharUnits N)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
RecordArgABI
Specify how one should pass an argument of a record type.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
CGFunctionInfo - Class to encapsulate the information about a function definition.
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
ABIArgInfo & getReturnInfo()
CallArgList - Type for representing both the value and type of arguments in a call.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
ASTContext & getContext() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
const TargetInfo & getTarget() const
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
const CGFunctionInfo * CurFnInfo
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
const TargetInfo & getTarget() const
CodeGenTypes & getTypes()
const llvm::DataLayout & getDataLayout() const
DiagnosticsEngine & getDiags() const
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
Target specific hooks for defining how a type should be passed or returned from functions with one of...
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
virtual bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF, llvm::Type *Ty) const
Target hook to decide whether an inline asm operand can be passed by value.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Represents a function declaration or definition.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
Represents a prototype with parameter type info, e.g.
unsigned getAArch64SMEAttributes() const
Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...
@ SME_PStateSMCompatibleMask
@ None
No signing for any function.
@ AKey
Return address signing uses APIA key.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a parameter to a function.
A (possibly-)qualified type.
Encodes a location in the source.
Exposes information about the current target.
virtual StringRef getABI() const
Get the ABI currently in use.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
virtual bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, StringRef &Err) const
Determine if this TargetInfo supports the given branch protection specification.
The base class of the type hierarchy.
const T * castAs() const
Member-template castAs<specific type>.
bool isVectorType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector type.
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Is the given vector type "legal" for Swift's perspective on the current platform?
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
Address EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, const ABIArgInfo &AI)
Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
Address emitMergePHI(CodeGenFunction &CGF, Address Addr1, llvm::BasicBlock *Block1, Address Addr2, llvm::BasicBlock *Block2, const llvm::Twine &Name="")
ABIArgInfo coerceToIntArray(QualType Ty, ASTContext &Context, llvm::LLVMContext &LLVMContext)
llvm::Value * emitRoundPointerUpToAlignment(CodeGenFunction &CGF, llvm::Value *Ptr, CharUnits Align)
bool isAggregateTypeForABI(QualType T)
std::unique_ptr< TargetCodeGenInfo > createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
std::unique_ptr< TargetCodeGenInfo > createWindowsAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind K)
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
bool Load(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
@ SveFixedLengthData
is AArch64 SVE fixed-length data vector
@ SveFixedLengthPredicate
is AArch64 SVE fixed-length predicate vector
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
llvm::PointerType * Int8PtrTy
Contains information gathered from parsing the contents of TargetAttr.
LangOptions::SignReturnAddressScopeKind SignReturnAddr
LangOptions::SignReturnAddressKeyKind SignKey
const char * getSignReturnAddrStr() const
bool BranchProtectionPAuthLR
bool BranchTargetEnforcement