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");
71 return Kind == AArch64ABIKind::Win64
73 : isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF, Slot)
74 : EmitAAPCSVAArg(VAListAddr, Ty, CGF,
Kind, Slot);
86 raw_ostream &Out)
const override;
88 raw_ostream &Out)
const override;
97 unsigned NumElts)
const override;
104 SwiftInfo = std::make_unique<AArch64SwiftABIInfo>(CGT);
108 return "mov\tfp, fp\t\t// marker for objc_retainAutoreleaseReturnValue";
125 if (
const auto *TA = FD->
getAttr<TargetAttr>()) {
128 if (!
Attr.BranchProtection.empty()) {
131 Attr.CPU, BPI, Error);
132 assert(
Error.empty());
135 auto *
Fn = cast<llvm::Function>(GV);
140 llvm::Type *Ty)
const override {
142 auto *ST = dyn_cast<llvm::StructType>(Ty);
143 if (ST && ST->getNumElements() == 1) {
144 auto *AT = dyn_cast<llvm::ArrayType>(ST->getElementType(0));
145 if (AT && AT->getNumElements() == 8 &&
146 AT->getElementType()->isIntegerTy(64))
159 QualType ReturnType)
const override;
176class WindowsAArch64TargetCodeGenInfo :
public AArch64TargetCodeGenInfo {
179 : AArch64TargetCodeGenInfo(CGT, K) {}
181 void setTargetAttributes(
const Decl *
D, llvm::GlobalValue *GV,
184 void getDependentLibraryOption(llvm::StringRef Lib,
186 Opt =
"/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);
189 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef
Value,
191 Opt =
"/FAILIFMISMATCH:\"" + Name.str() +
"=" +
Value.str() +
"\"";
195void WindowsAArch64TargetCodeGenInfo::setTargetAttributes(
197 AArch64TargetCodeGenInfo::setTargetAttributes(
D, GV, CGM);
198 if (GV->isDeclaration())
200 addStackProbeTargetAttributes(
D, GV, CGM);
208 if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
209 assert(VT->getElementType()->isBuiltinType() &&
"expected builtin type!");
211 BuiltinType::UChar &&
212 "unexpected builtin type for SVE predicate!");
214 llvm::Type::getInt1Ty(getVMContext()), 16));
217 if (VT->getVectorKind() == VectorKind::SveFixedLengthData) {
218 assert(VT->getElementType()->isBuiltinType() &&
"expected builtin type!");
220 const auto *BT = VT->getElementType()->castAs<
BuiltinType>();
221 llvm::ScalableVectorType *ResType =
nullptr;
222 switch (BT->getKind()) {
224 llvm_unreachable(
"unexpected builtin type for SVE vector!");
225 case BuiltinType::SChar:
226 case BuiltinType::UChar:
227 ResType = llvm::ScalableVectorType::get(
228 llvm::Type::getInt8Ty(getVMContext()), 16);
230 case BuiltinType::Short:
231 case BuiltinType::UShort:
232 ResType = llvm::ScalableVectorType::get(
233 llvm::Type::getInt16Ty(getVMContext()), 8);
235 case BuiltinType::Int:
236 case BuiltinType::UInt:
237 ResType = llvm::ScalableVectorType::get(
238 llvm::Type::getInt32Ty(getVMContext()), 4);
240 case BuiltinType::Long:
241 case BuiltinType::ULong:
242 ResType = llvm::ScalableVectorType::get(
243 llvm::Type::getInt64Ty(getVMContext()), 2);
245 case BuiltinType::Half:
246 ResType = llvm::ScalableVectorType::get(
247 llvm::Type::getHalfTy(getVMContext()), 8);
249 case BuiltinType::Float:
250 ResType = llvm::ScalableVectorType::get(
251 llvm::Type::getFloatTy(getVMContext()), 4);
253 case BuiltinType::Double:
254 ResType = llvm::ScalableVectorType::get(
255 llvm::Type::getDoubleTy(getVMContext()), 2);
257 case BuiltinType::BFloat16:
258 ResType = llvm::ScalableVectorType::get(
259 llvm::Type::getBFloatTy(getVMContext()), 8);
267 if ((isAndroid() || isOHOSFamily()) && (Size <= 16)) {
268 llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext());
272 llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext());
277 llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 2);
282 llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 4);
285 return getNaturalAlignIndirect(Ty,
false);
289AArch64ABIInfo::classifyArgumentType(
QualType Ty,
bool IsVariadic,
290 unsigned CallingConvention)
const {
294 if (isIllegalVectorType(Ty))
295 return coerceIllegalVector(Ty);
300 Ty = EnumTy->getDecl()->getIntegerType();
303 if (EIT->getNumBits() > 128)
304 return getNaturalAlignIndirect(Ty,
false);
306 return (isPromotableIntegerTypeForABI(Ty) && isDarwinPCS()
314 return getNaturalAlignIndirect(Ty, RAA ==
322 if (IsEmpty || Size == 0) {
323 if (!getContext().getLangOpts().
CPlusPlus || isDarwinPCS())
328 if (IsEmpty && Size == 0)
336 bool IsWin64 =
Kind == AArch64ABIKind::Win64 ||
337 CallingConvention == llvm::CallingConv::Win64;
338 bool IsWinVariadic = IsWin64 && IsVariadic;
341 if (!IsWinVariadic && isHomogeneousAggregate(Ty,
Base, Members)) {
342 if (Kind != AArch64ABIKind::AAPCS)
344 llvm::ArrayType::get(CGT.ConvertType(
QualType(
Base, 0)), Members));
349 getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
350 Align = (Align >= 16) ? 16 : 8;
352 llvm::ArrayType::get(CGT.ConvertType(
QualType(
Base, 0)), Members), 0,
353 nullptr,
true, Align);
360 if (getTarget().isRenderScriptTarget()) {
364 if (Kind == AArch64ABIKind::AAPCS) {
365 Alignment = getContext().getTypeUnadjustedAlign(Ty);
366 Alignment = Alignment < 128 ? 64 : 128;
369 std::max(getContext().getTypeAlign(Ty),
370 (
unsigned)getTarget().getPointerWidth(LangAS::Default));
372 Size = llvm::alignTo(Size, Alignment);
376 llvm::Type *BaseTy = llvm::Type::getIntNTy(getVMContext(), Alignment);
378 Size == Alignment ? BaseTy
379 : llvm::ArrayType::get(BaseTy, Size / Alignment));
382 return getNaturalAlignIndirect(Ty,
false);
386 bool IsVariadic)
const {
391 if (VT->getVectorKind() == VectorKind::SveFixedLengthData ||
392 VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)
393 return coerceIllegalVector(RetTy);
397 if (RetTy->
isVectorType() && getContext().getTypeSize(RetTy) > 128)
398 return getNaturalAlignIndirect(RetTy);
403 RetTy = EnumTy->getDecl()->getIntegerType();
406 if (EIT->getNumBits() > 128)
407 return getNaturalAlignIndirect(RetTy);
409 return (isPromotableIntegerTypeForABI(RetTy) && isDarwinPCS()
420 if (isHomogeneousAggregate(RetTy,
Base, Members) &&
421 !(getTarget().getTriple().getArch() == llvm::Triple::aarch64_32 &&
430 if (getTarget().isRenderScriptTarget()) {
434 if (Size <= 64 && getDataLayout().isLittleEndian()) {
442 llvm::IntegerType::get(getVMContext(), Size));
445 unsigned Alignment = getContext().getTypeAlign(RetTy);
446 Size = llvm::alignTo(Size, 64);
450 if (Alignment < 128 && Size == 128) {
451 llvm::Type *BaseTy = llvm::Type::getInt64Ty(getVMContext());
457 return getNaturalAlignIndirect(RetTy);
461bool AArch64ABIInfo::isIllegalVectorType(
QualType Ty)
const {
466 if (VT->getVectorKind() == VectorKind::SveFixedLengthData ||
467 VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)
471 unsigned NumElements = VT->getNumElements();
474 if (!llvm::isPowerOf2_32(NumElements))
479 llvm::Triple Triple = getTarget().getTriple();
480 if (Triple.getArch() == llvm::Triple::aarch64_32 &&
481 Triple.isOSBinFormatMachO())
484 return Size != 64 && (
Size != 128 || NumElements == 1);
489bool AArch64SwiftABIInfo::isLegalVectorType(
CharUnits VectorSize,
491 unsigned NumElts)
const {
492 if (!llvm::isPowerOf2_32(NumElts))
500bool AArch64ABIInfo::isHomogeneousAggregateBaseType(
QualType Ty)
const {
503 if (Kind == AArch64ABIKind::AAPCSSoft)
511 if (BT->isFloatingPoint())
514 unsigned VecSize = getContext().getTypeSize(VT);
515 if (VecSize == 64 || VecSize == 128)
521bool AArch64ABIInfo::isHomogeneousAggregateSmallEnough(
const Type *
Base,
522 uint64_t Members)
const {
526bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
549 BaseTy = llvm::PointerType::getUnqual(BaseTy);
553 unsigned NumRegs = 1;
554 if (llvm::ArrayType *ArrTy = dyn_cast<llvm::ArrayType>(BaseTy)) {
555 BaseTy = ArrTy->getElementType();
556 NumRegs = ArrTy->getNumElements();
558 bool IsFPR =
Kind != AArch64ABIKind::AAPCSSoft &&
559 (BaseTy->isFloatingPointTy() || BaseTy->isVectorTy());
577 CharUnits TySize = getContext().getTypeSizeInChars(Ty);
578 CharUnits TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty);
581 llvm::Value *reg_offs =
nullptr;
583 int RegSize = IsIndirect ? 8 : TySize.
getQuantity();
589 RegSize = llvm::alignTo(RegSize, 8);
595 RegSize = 16 * NumRegs;
606 llvm::Value *UsingStack =
nullptr;
607 UsingStack = CGF.
Builder.CreateICmpSGE(
608 reg_offs, llvm::ConstantInt::get(CGF.
Int32Ty, 0));
610 CGF.
Builder.CreateCondBr(UsingStack, OnStackBlock, MaybeRegBlock);
619 if (!IsFPR && !IsIndirect && TyAlign.
getQuantity() > 8) {
622 reg_offs = CGF.
Builder.CreateAdd(
623 reg_offs, llvm::ConstantInt::get(CGF.
Int32Ty, Align - 1),
625 reg_offs = CGF.
Builder.CreateAnd(
626 reg_offs, llvm::ConstantInt::get(CGF.
Int32Ty, -Align),
634 llvm::Value *NewOffset =
nullptr;
635 NewOffset = CGF.
Builder.CreateAdd(
636 reg_offs, llvm::ConstantInt::get(CGF.
Int32Ty, RegSize),
"new_reg_offs");
641 llvm::Value *InRegs =
nullptr;
642 InRegs = CGF.
Builder.CreateICmpSLE(
643 NewOffset, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
"inreg");
645 CGF.
Builder.CreateCondBr(InRegs, InRegBlock, OnStackBlock);
655 llvm::Value *reg_top =
nullptr;
667 MemTy = llvm::PointerType::getUnqual(MemTy);
672 bool IsHFA = isHomogeneousAggregate(Ty,
Base, NumMembers);
673 if (IsHFA && NumMembers > 1) {
678 assert(!IsIndirect &&
"Homogeneous aggregates should be passed directly");
679 auto BaseTyInfo = getContext().getTypeInfoInChars(
QualType(
Base, 0));
681 llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers);
683 std::max(TyAlign, BaseTyInfo.Align));
688 BaseTyInfo.Width.getQuantity() < 16)
689 Offset = 16 - BaseTyInfo.Width.getQuantity();
691 for (
unsigned i = 0; i < NumMembers; ++i) {
708 CharUnits SlotSize = BaseAddr.getAlignment();
741 StackSize = StackSlotSize;
743 StackSize = TySize.
alignTo(StackSlotSize);
747 CGF.
Int8Ty, OnStackPtr, StackSizeC,
"new_stack");
753 TySize < StackSlotSize) {
754 CharUnits Offset = StackSlotSize - TySize;
768 OnStackBlock,
"vaargs.addr");
793 uint64_t PointerSize = getTarget().getPointerWidth(LangAS::Default) / 8;
802 auto TyInfo = getContext().getTypeInfoInChars(Ty);
806 bool IsIndirect =
false;
807 if (TyInfo.Width.getQuantity() > 16) {
810 IsIndirect = !isHomogeneousAggregate(Ty,
Base, Members);
819 bool IsIndirect =
false;
841 const StringRef ABIName,
845 const Type *HABase =
nullptr;
846 uint64_t HAMembers = 0;
849 Diags.
Report(loc, diag::err_target_unsupported_type_for_abi)
850 <<
D->getDeclName() << Ty << ABIName;
857void AArch64TargetCodeGenInfo::checkFunctionABI(
859 const AArch64ABIInfo &
ABIInfo = getABIInfo<AArch64ABIInfo>();
873void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming(
876 if (!Caller || !Callee || !
Callee->hasAttr<AlwaysInlineAttr>())
879 bool CallerIsStreaming =
881 bool CalleeIsStreaming =
886 if (!CalleeIsStreamingCompatible &&
887 (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible))
889 CallLoc, CalleeIsStreaming
890 ? diag::err_function_always_inline_attribute_mismatch
891 : diag::warn_function_always_inline_attribute_mismatch)
893 if (
auto *NewAttr =
Callee->getAttr<ArmNewAttr>())
894 if (NewAttr->isNewZA())
895 CGM.
getDiags().
Report(CallLoc, diag::err_function_always_inline_new_za)
902void AArch64TargetCodeGenInfo::checkFunctionCallABISoftFloat(
906 const AArch64ABIInfo &
ABIInfo = getABIInfo<AArch64ABIInfo>();
913 Callee ? Callee : Caller, CallLoc);
915 for (
const CallArg &Arg : Args)
917 Callee ? Callee : Caller, CallLoc);
920void AArch64TargetCodeGenInfo::checkFunctionCallABI(
CodeGenModule &CGM,
926 checkFunctionCallABIStreaming(CGM, CallLoc, Caller, Callee);
927 checkFunctionCallABISoftFloat(CGM, CallLoc, Caller, Callee, Args, ReturnType);
930void AArch64ABIInfo::appendAttributeMangling(TargetClonesAttr *
Attr,
932 raw_ostream &Out)
const {
933 appendAttributeMangling(
Attr->getFeatureStr(Index), Out);
936void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr,
937 raw_ostream &Out)
const {
938 if (AttrStr ==
"default") {
945 AttrStr.split(Features,
"+");
946 for (
auto &Feat : Features)
949 llvm::sort(Features, [](
const StringRef LHS,
const StringRef RHS) {
950 return LHS.compare(RHS) < 0;
953 llvm::SmallDenseSet<StringRef, 8> UniqueFeats;
954 for (
auto &Feat : Features)
955 if (
auto Ext = llvm::AArch64::parseFMVExtension(Feat))
956 if (UniqueFeats.insert(Ext->Name).second)
957 Out <<
'M' << Ext->Name;
960std::unique_ptr<TargetCodeGenInfo>
963 return std::make_unique<AArch64TargetCodeGenInfo>(CGM.
getTypes(), Kind);
966std::unique_ptr<TargetCodeGenInfo>
969 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, SourceLocation loc)
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
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 RValue EmitMSVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) const
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 RValue EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) const =0
EmitVAArg - Emit the target dependent code to load a value of.
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)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
const CGFunctionInfo * CurFnInfo
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
This class organizes the cross-function state that is used while generating LLVM code.
DiagnosticsEngine & getDiags() const
const LangOptions & getLangOpts() 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.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
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...
static void setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI, llvm::Function &F)
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)
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, 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.
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 * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * Int32Ty
Contains information gathered from parsing the contents of TargetAttr.