10#include "TargetInfo.h"
13#include "llvm/TargetParser/AArch64TargetParser.h"
24class AArch64ABIInfo :
public ABIInfo {
39 unsigned CallingConvention)
const;
43 uint64_t Members)
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);
85 raw_ostream &Out)
const override;
87 raw_ostream &Out)
const override;
96 unsigned NumElts)
const override;
103 SwiftInfo = std::make_unique<AArch64SwiftABIInfo>(CGT);
107 return "mov\tfp, fp\t\t// marker for objc_retainAutoreleaseReturnValue";
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);
140 if (BPI.
SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
141 Fn->addFnAttr(
"sign-return-address-key",
142 BPI.
SignKey == LangOptions::SignReturnAddressKeyKind::AKey
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;
192class 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() +
"\"";
211void WindowsAArch64TargetCodeGenInfo::setTargetAttributes(
213 AArch64TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
214 if (GV->isDeclaration())
216 addStackProbeTargetAttributes(D, GV, CGM);
224 if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
225 assert(VT->getElementType()->isBuiltinType() &&
"expected builtin type!");
227 BuiltinType::UChar &&
228 "unexpected builtin type for SVE predicate!");
230 llvm::Type::getInt1Ty(getVMContext()), 16));
233 if (VT->getVectorKind() == VectorKind::SveFixedLengthData) {
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);
265 case BuiltinType::Float:
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);
305AArch64ABIInfo::classifyArgumentType(
QualType Ty,
bool IsVariadic,
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)
352 bool IsWin64 =
Kind == AArch64ABIKind::Win64 ||
353 CallingConvention == llvm::CallingConv::Win64;
354 bool IsWinVariadic = IsWin64 && IsVariadic;
357 if (!IsWinVariadic && isHomogeneousAggregate(Ty,
Base, Members)) {
358 if (Kind != AArch64ABIKind::AAPCS)
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()) {
380 if (Kind == AArch64ABIKind::AAPCS) {
381 Alignment = getContext().getTypeUnadjustedAlign(Ty);
382 Alignment = Alignment < 128 ? 64 : 128;
385 std::max(getContext().getTypeAlign(Ty),
386 (
unsigned)getTarget().getPointerWidth(LangAS::Default));
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 {
407 if (VT->getVectorKind() == VectorKind::SveFixedLengthData ||
408 VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)
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);
477bool AArch64ABIInfo::isIllegalVectorType(
QualType Ty)
const {
482 if (VT->getVectorKind() == VectorKind::SveFixedLengthData ||
483 VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)
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);
505bool AArch64SwiftABIInfo::isLegalVectorType(
CharUnits VectorSize,
507 unsigned NumElts)
const {
508 if (!llvm::isPowerOf2_32(NumElts))
516bool AArch64ABIInfo::isHomogeneousAggregateBaseType(
QualType Ty)
const {
519 if (Kind == AArch64ABIKind::AAPCSSoft)
527 if (BT->isFloatingPoint())
530 unsigned VecSize = getContext().getTypeSize(VT);
531 if (VecSize == 64 || VecSize == 128)
537bool AArch64ABIInfo::isHomogeneousAggregateSmallEnough(
const Type *
Base,
538 uint64_t Members)
const {
542bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
559 uint64_t PointerSize = getTarget().getPointerWidth(LangAS::Default) / 8;
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();
579 bool IsFPR =
Kind != AArch64ABIKind::AAPCSSoft &&
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();
757 OnStackPtr = CGF.
Builder.CreateAdd(
758 OnStackPtr, llvm::ConstantInt::get(CGF.
Int64Ty, Align - 1),
760 OnStackPtr = CGF.
Builder.CreateAnd(
761 OnStackPtr, llvm::ConstantInt::get(CGF.
Int64Ty, -Align),
773 StackSize = StackSlotSize;
775 StackSize = TySize.
alignTo(StackSlotSize);
779 CGF.
Int8Ty, OnStackPtr, StackSizeC,
"new_stack");
785 TySize < StackSlotSize) {
786 CharUnits Offset = StackSlotSize - TySize;
800 OnStackBlock,
"vaargs.addr");
817 uint64_t PointerSize = getTarget().getPointerWidth(LangAS::Default) / 8;
827 auto TyInfo = getContext().getTypeInfoInChars(Ty);
831 bool IsIndirect =
false;
832 if (TyInfo.Width.getQuantity() > 16) {
835 IsIndirect = !isHomogeneousAggregate(Ty,
Base, Members);
839 TyInfo, SlotSize,
true);
844 bool IsIndirect =
false;
866 const StringRef ABIName,
869 const Type *HABase =
nullptr;
870 uint64_t HAMembers = 0;
881void AArch64TargetCodeGenInfo::checkFunctionABI(
883 const AArch64ABIInfo &
ABIInfo = getABIInfo<AArch64ABIInfo>();
896void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming(
899 if (!Caller || !Callee || !
Callee->hasAttr<AlwaysInlineAttr>())
902 bool CallerIsStreaming =
904 bool CalleeIsStreaming =
909 if (!CalleeIsStreamingCompatible &&
910 (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible))
912 diag::err_function_always_inline_attribute_mismatch)
914 if (
auto *NewAttr =
Callee->getAttr<ArmNewAttr>())
915 if (NewAttr->isNewZA())
916 CGM.
getDiags().
Report(CallLoc, diag::err_function_always_inline_new_za)
923void AArch64TargetCodeGenInfo::checkFunctionCallABISoftFloat(
927 const AArch64ABIInfo &
ABIInfo = getABIInfo<AArch64ABIInfo>();
936 for (
const CallArg &Arg : Args)
941void AArch64TargetCodeGenInfo::checkFunctionCallABI(
CodeGenModule &CGM,
947 checkFunctionCallABIStreaming(CGM, CallLoc, Caller, Callee);
948 checkFunctionCallABISoftFloat(CGM, CallLoc, Caller, Callee, Args, ReturnType);
951void AArch64ABIInfo::appendAttributeMangling(TargetClonesAttr *
Attr,
953 raw_ostream &Out)
const {
954 appendAttributeMangling(
Attr->getFeatureStr(Index), Out);
957void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr,
958 raw_ostream &Out)
const {
959 if (AttrStr ==
"default") {
966 AttrStr.split(Features,
"+");
967 for (
auto &Feat : Features)
970 llvm::sort(Features, [](
const StringRef LHS,
const StringRef RHS) {
971 return LHS.compare(RHS) < 0;
974 llvm::SmallDenseSet<StringRef, 8> UniqueFeats;
975 for (
auto &Feat : Features)
976 if (
auto Ext = llvm::AArch64::parseArchExtension(Feat))
977 if (UniqueFeats.insert(Ext->Name).second)
978 Out <<
'M' << Ext->Name;
981std::unique_ptr<TargetCodeGenInfo>
984 return std::make_unique<AArch64TargetCodeGenInfo>(CGM.
getTypes(), Kind);
987std::unique_ptr<TargetCodeGenInfo>
990 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)
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.
virtual bool allowBFloatArgsAndRet() const
virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty) const
Emit the target dependent code to load a value of.
bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const
isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous aggregate.
CodeGen::CGCXXABI & getCXXABI() const
ASTContext & getContext() const
virtual bool isHomogeneousAggregateBaseType(QualType Ty) const
virtual void appendAttributeMangling(TargetAttr *Attr, raw_ostream &Out) const
virtual CodeGen::Address EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty) const =0
EmitVAArg - Emit the target dependent code to load a value of.
virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, uint64_t Members) const
const TargetInfo & getTarget() const
virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const =0
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.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = [n x T]* ... produce name = getelementptr inbounds addr, i64 0, i64 index where i64 is a...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, 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="")
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.
ABIArgInfo & getReturnInfo()
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
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::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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...
llvm::Type * ConvertTypeForMem(QualType T)
const TargetInfo & getTarget() const
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
ASTContext & getContext() const
llvm::Type * ConvertType(QualType T)
const CGFunctionInfo * CurFnInfo
This class organizes the cross-function state that is used while generating LLVM code.
DiagnosticsEngine & getDiags() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() 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...
virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, unsigned NumElts) const
Returns true if the given vector type is legal from Swift's calling convention perspective.
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
virtual bool doesReturnSlotInterfereWithArgs() const
doesReturnSlotInterfereWithArgs - Return true if the target uses an argument slot for an 'sret' type.
virtual StringRef getARCRetainAutoreleasedReturnValueMarker() const
Retrieve the address of a function to call immediately before calling objc_retainAutoreleasedReturnVa...
virtual void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, const FunctionDecl *Callee, const CallArgList &Args, QualType ReturnType) const
Any further codegen related checks that need to be done on a function call in a target specific manne...
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const
setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...
virtual void checkFunctionABI(CodeGenModule &CGM, const FunctionDecl *Decl) const
Any further codegen related checks that need to be done on a function signature in a target specific ...
virtual bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF, llvm::Type *Ty) const
Target hook to decide whether an inline asm operand can be passed by value.
virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const
Determines the DWARF register number for the stack pointer, for exception-handling purposes.
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
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 hasBFloat16Type() const
Determine whether the _BFloat16 type is supported on this target.
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 classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
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)
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
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
llvm::IntegerType * Int64Ty
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
bool BranchProtectionPAuthLR
bool BranchTargetEnforcement
const char * getSignReturnAddrStr() const