10#include "TargetInfo.h"
21class ARMABIInfo :
public ABIInfo {
23 bool IsFloatABISoftFP;
26 ARMABIInfo(CodeGenTypes &CGT,
ARMABIKind Kind) : ABIInfo(CGT), Kind(Kind) {
33 switch (getTarget().
getTriple().getEnvironment()) {
34 case llvm::Triple::Android:
35 case llvm::Triple::EABI:
36 case llvm::Triple::EABIHF:
37 case llvm::Triple::GNUEABI:
38 case llvm::Triple::GNUEABIT64:
39 case llvm::Triple::GNUEABIHF:
40 case llvm::Triple::GNUEABIHFT64:
41 case llvm::Triple::MuslEABI:
42 case llvm::Triple::MuslEABIHF:
45 return getTarget().getTriple().isOHOSFamily();
49 bool isEABIHF()
const {
50 switch (getTarget().
getTriple().getEnvironment()) {
51 case llvm::Triple::EABIHF:
52 case llvm::Triple::GNUEABIHF:
53 case llvm::Triple::GNUEABIHFT64:
54 case llvm::Triple::MuslEABIHF:
63 bool allowBFloatArgsAndRet()
const override {
64 return !IsFloatABISoftFP && getTarget().hasBFloat16Type();
69 unsigned functionCallConv)
const;
71 unsigned functionCallConv)
const;
72 ABIArgInfo classifyHomogeneousAggregate(QualType Ty,
const Type *Base,
73 uint64_t Members)
const;
74 bool shouldIgnoreEmptyArg(QualType Ty)
const;
75 ABIArgInfo coerceIllegalVector(QualType Ty)
const;
76 bool isIllegalVectorType(QualType Ty)
const;
77 bool containsAnyFP16Vectors(QualType Ty)
const;
79 bool isHomogeneousAggregateBaseType(QualType Ty)
const override;
80 bool isHomogeneousAggregateSmallEnough(
const Type *Ty,
81 uint64_t Members)
const override;
82 bool isZeroLengthBitfieldPermittedInHomogeneousAggregate()
const override;
84 bool isEffectivelyAAPCS_VFP(
unsigned callConvention,
bool acceptHalf)
const;
86 void computeInfo(CGFunctionInfo &FI)
const override;
88 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
89 AggValueSlot Slot)
const override;
91 llvm::CallingConv::ID getLLVMDefaultCC()
const;
92 llvm::CallingConv::ID getABIDefaultCC()
const;
98 explicit ARMSwiftABIInfo(CodeGenTypes &CGT)
99 : SwiftABIInfo(CGT,
true) {}
102 unsigned NumElts)
const override;
107 ARMTargetCodeGenInfo(CodeGenTypes &CGT,
ARMABIKind K)
108 : TargetCodeGenInfo(std::make_unique<ARMABIInfo>(CGT, K)) {
109 SwiftInfo = std::make_unique<ARMSwiftABIInfo>(CGT);
112 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M)
const override {
116 StringRef getARCRetainAutoreleasedReturnValueMarker()
const override {
117 return "mov\tr7, r7\t\t// marker for objc_retainAutoreleaseReturnValue";
120 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
121 llvm::Value *Address)
const override {
122 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.
Int8Ty, 4);
129 unsigned getSizeOfUnwindException()
const override {
130 if (getABIInfo<ARMABIInfo>().isEABI())
135 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
136 CodeGen::CodeGenModule &CGM)
const override {
137 auto *
Fn = dyn_cast<llvm::Function>(GV);
140 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
142 if (FD && FD->hasAttr<TargetAttr>()) {
143 const auto *TA = FD->getAttr<TargetAttr>();
144 ParsedTargetAttr Attr =
146 if (!Attr.BranchProtection.empty()) {
147 TargetInfo::BranchProtectionInfo BPI{};
155 diag::warn_target_unsupported_branch_protection_attribute)
158 setBranchProtectionFnAttributes(BPI, (*Fn));
159 }
else if (CGM.
getLangOpts().BranchTargetEnforcement ||
167 diag::warn_target_unsupported_branch_protection_attribute)
172 TargetInfo::BranchProtectionInfo BPI(CGM.
getLangOpts());
173 setBranchProtectionFnAttributes(BPI, (*Fn));
176 if (!FD || !FD->hasAttr<ARMInterruptAttr>())
179 const ARMInterruptAttr *Attr = FD->getAttr<ARMInterruptAttr>();
181 switch (Attr->getInterrupt()) {
182 case ARMInterruptAttr::Generic:
Kind =
"";
break;
183 case ARMInterruptAttr::IRQ:
Kind =
"IRQ";
break;
184 case ARMInterruptAttr::FIQ:
Kind =
"FIQ";
break;
185 case ARMInterruptAttr::SWI:
Kind =
"SWI";
break;
186 case ARMInterruptAttr::ABORT:
Kind =
"ABORT";
break;
187 case ARMInterruptAttr::UNDEF:
Kind =
"UNDEF";
break;
190 Fn->addFnAttr(
"interrupt", Kind);
194 const ARMSaveFPAttr *SaveFPAttr = FD->getAttr<ARMSaveFPAttr>();
196 Fn->addFnAttr(
"save-fp");
198 ARMABIKind ABI = getABIInfo<ARMABIInfo>().getABIKind();
199 if (ABI == ARMABIKind::APCS)
205 llvm::AttrBuilder B(
Fn->getContext());
206 B.addStackAlignmentAttr(8);
211class WindowsARMTargetCodeGenInfo :
public ARMTargetCodeGenInfo {
213 WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT,
ARMABIKind K)
214 : ARMTargetCodeGenInfo(CGT, K) {}
216 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
217 CodeGen::CodeGenModule &CGM)
const override;
219 void getDependentLibraryOption(llvm::StringRef Lib,
220 llvm::SmallString<24> &Opt)
const override {
221 Opt =
"/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);
224 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef
Value,
225 llvm::SmallString<32> &Opt)
const override {
226 Opt =
"/FAILIFMISMATCH:\"" + Name.str() +
"=" +
Value.str() +
"\"";
230void WindowsARMTargetCodeGenInfo::setTargetAttributes(
232 ARMTargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
233 if (GV->isDeclaration())
235 addStackProbeTargetAttributes(D, GV, CGM);
239void ARMABIInfo::computeInfo(CGFunctionInfo &FI)
const {
253 llvm::CallingConv::ID cc = getRuntimeCC();
254 if (cc != llvm::CallingConv::C)
259llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC()
const {
261 if (isEABIHF() || getTarget().
getTriple().isWatchABI())
262 return llvm::CallingConv::ARM_AAPCS_VFP;
264 return llvm::CallingConv::ARM_AAPCS;
266 return llvm::CallingConv::ARM_APCS;
271llvm::CallingConv::ID ARMABIInfo::getABIDefaultCC()
const {
272 switch (getABIKind()) {
273 case ARMABIKind::APCS:
274 return llvm::CallingConv::ARM_APCS;
275 case ARMABIKind::AAPCS:
276 return llvm::CallingConv::ARM_AAPCS;
277 case ARMABIKind::AAPCS_VFP:
278 return llvm::CallingConv::ARM_AAPCS_VFP;
279 case ARMABIKind::AAPCS16_VFP:
280 return llvm::CallingConv::ARM_AAPCS_VFP;
282 llvm_unreachable(
"bad ABI kind");
285void ARMABIInfo::setCCs() {
286 assert(getRuntimeCC() == llvm::CallingConv::C);
290 llvm::CallingConv::ID abiCC = getABIDefaultCC();
291 if (abiCC != getLLVMDefaultCC())
295ABIArgInfo ARMABIInfo::coerceIllegalVector(QualType Ty)
const {
298 llvm::Type *ResType =
299 llvm::Type::getInt32Ty(getVMContext());
302 if (Size == 64 || Size == 128) {
303 auto *ResType = llvm::FixedVectorType::get(
304 llvm::Type::getInt32Ty(getVMContext()), Size / 32);
307 return getNaturalAlignIndirect(
308 Ty, getDataLayout().getAllocaAddrSpace(),
312ABIArgInfo ARMABIInfo::classifyHomogeneousAggregate(QualType Ty,
314 uint64_t Members)
const {
315 assert(Base &&
"Base class should be set for homogeneous aggregate");
317 if (
const VectorType *VT =
Base->getAs<VectorType>()) {
319 if (!getTarget().hasFastHalfType() && containsAnyFP16Vectors(Ty)) {
321 auto *NewVecTy = llvm::FixedVectorType::get(
322 llvm::Type::getInt32Ty(getVMContext()), Size / 32);
323 llvm::Type *Ty = llvm::ArrayType::get(NewVecTy, Members);
328 if (getABIKind() == ARMABIKind::AAPCS ||
329 getABIKind() == ARMABIKind::AAPCS_VFP) {
332 Align = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
333 unsigned BaseAlign = getContext().getTypeAlignInChars(Base).getQuantity();
334 Align = (Align > BaseAlign && Align >= 8) ? 8 : 0;
339bool ARMABIInfo::shouldIgnoreEmptyArg(QualType Ty)
const {
341 assert((
isEmptyRecord(getContext(), Ty,
true) || Size == 0) &&
345 if (!getContext().getLangOpts().
CPlusPlus ||
346 getABIKind() == ARMABIKind::AAPCS16_VFP)
356 if (getContext().getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver19))
363ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
bool isVariadic,
364 unsigned functionCallConv)
const {
374 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv,
false);
379 if (isIllegalVectorType(Ty))
380 return coerceIllegalVector(Ty);
385 Ty = ED->getIntegerType();
388 if (
const auto *EIT = Ty->
getAs<BitIntType>())
389 if (EIT->getNumBits() > 64)
390 return getNaturalAlignIndirect(
391 Ty, getDataLayout().getAllocaAddrSpace(),
394 return (isPromotableIntegerTypeForABI(Ty)
400 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
407 getContext().getTypeSize(Ty) == 0) {
408 if (shouldIgnoreEmptyArg(Ty))
419 if (isHomogeneousAggregate(Ty, Base, Members))
420 return classifyHomogeneousAggregate(Ty, Base, Members);
421 }
else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
427 if (isHomogeneousAggregate(Ty, Base, Members)) {
428 assert(Base && Members <= 4 &&
"unexpected homogeneous aggregate");
430 llvm::ArrayType::get(CGT.
ConvertType(QualType(Base, 0)), Members);
435 if (getABIKind() == ARMABIKind::AAPCS16_VFP &&
442 getDataLayout().getAllocaAddrSpace(),
false);
451 if (getABIKind() == ARMABIKind::AAPCS_VFP ||
452 getABIKind() == ARMABIKind::AAPCS) {
453 TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
454 ABIAlign = std::clamp(TyAlign, (uint64_t)4, (uint64_t)8);
456 TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity();
459 assert(getABIKind() != ARMABIKind::AAPCS16_VFP &&
"unexpected byval");
462 getDataLayout().getAllocaAddrSpace(),
463 true, TyAlign > ABIAlign);
472 ElemTy = llvm::Type::getInt32Ty(getVMContext());
473 SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;
475 ElemTy = llvm::Type::getInt64Ty(getVMContext());
476 SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
483 llvm::LLVMContext &VMContext) {
488 uint64_t Size = Context.getTypeSize(Ty);
515 if (!RT)
return false;
526 bool HadField =
false;
529 i != e; ++i, ++idx) {
567ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
bool isVariadic,
568 unsigned functionCallConv)
const {
572 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv,
true);
577 if (
const VectorType *VT = RetTy->
getAs<VectorType>()) {
579 if (getContext().getTypeSize(RetTy) > 128)
580 return getNaturalAlignIndirect(RetTy,
581 getDataLayout().getAllocaAddrSpace());
584 if ((!getTarget().hasFastHalfType() &&
585 (VT->getElementType()->isFloat16Type() ||
586 VT->getElementType()->isHalfType())) ||
588 VT->getElementType()->isBFloat16Type()))
589 return coerceIllegalVector(RetTy);
595 RetTy = ED->getIntegerType();
597 if (
const auto *EIT = RetTy->
getAs<BitIntType>())
598 if (EIT->getNumBits() > 64)
599 return getNaturalAlignIndirect(
600 RetTy, getDataLayout().getAllocaAddrSpace(),
604 : ABIArgInfo::getDirect();
608 if (getABIKind() == ARMABIKind::APCS) {
618 getVMContext(), getContext().getTypeSize(RetTy)));
632 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
638 getContext().getTypeSize(RetTy) == 0)
645 if (isHomogeneousAggregate(RetTy, Base, Members))
646 return classifyHomogeneousAggregate(RetTy, Base, Members);
653 if (getDataLayout().isBigEndian())
663 }
else if (Size <= 128 && getABIKind() == ARMABIKind::AAPCS16_VFP) {
664 llvm::Type *Int32Ty = llvm::Type::getInt32Ty(getVMContext());
665 llvm::Type *CoerceTy =
666 llvm::ArrayType::get(Int32Ty, llvm::alignTo(Size, 32) / 32);
670 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
674bool ARMABIInfo::isIllegalVectorType(QualType Ty)
const {
675 if (
const VectorType *VT = Ty->
getAs<VectorType> ()) {
682 if ((!getTarget().hasFastHalfType() &&
683 (VT->getElementType()->isFloat16Type() ||
684 VT->getElementType()->isHalfType())) ||
686 VT->getElementType()->isBFloat16Type()))
694 unsigned NumElements = VT->getNumElements();
696 if (!llvm::isPowerOf2_32(NumElements) && NumElements != 3)
700 unsigned NumElements = VT->getNumElements();
703 if (!llvm::isPowerOf2_32(NumElements))
713bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty)
const {
714 if (
const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
715 uint64_t NElements = AT->getZExtSize();
718 return containsAnyFP16Vectors(AT->getElementType());
722 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
723 if (llvm::any_of(CXXRD->bases(), [
this](
const CXXBaseSpecifier &B) {
724 return containsAnyFP16Vectors(B.getType());
728 if (llvm::any_of(RD->fields(), [
this](FieldDecl *FD) {
729 return FD && containsAnyFP16Vectors(FD->getType());
735 if (
const VectorType *VT = Ty->
getAs<VectorType>())
736 return (VT->getElementType()->isFloat16Type() ||
737 VT->getElementType()->isBFloat16Type() ||
738 VT->getElementType()->isHalfType());
743bool ARMSwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
744 unsigned NumElts)
const {
745 if (!llvm::isPowerOf2_32(NumElts))
747 unsigned size = CGT.
getDataLayout().getTypeStoreSizeInBits(EltTy);
756bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty)
const {
759 if (
const BuiltinType *BT = Ty->
getAs<BuiltinType>()) {
760 if (BT->getKind() == BuiltinType::Float ||
761 BT->getKind() == BuiltinType::Double ||
762 BT->getKind() == BuiltinType::LongDouble)
764 }
else if (
const VectorType *VT = Ty->
getAs<VectorType>()) {
765 unsigned VecSize = getContext().getTypeSize(VT);
766 if (VecSize == 64 || VecSize == 128)
772bool ARMABIInfo::isHomogeneousAggregateSmallEnough(
const Type *Base,
773 uint64_t Members)
const {
777bool ARMABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
const {
786bool ARMABIInfo::isEffectivelyAAPCS_VFP(
unsigned callConvention,
787 bool acceptHalf)
const {
789 if (callConvention != llvm::CallingConv::C)
790 return (callConvention == llvm::CallingConv::ARM_AAPCS_VFP);
792 return (getABIKind() == ARMABIKind::AAPCS_VFP) ||
793 (acceptHalf && (getABIKind() == ARMABIKind::AAPCS16_VFP));
796RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
797 QualType Ty, AggValueSlot Slot)
const {
803 if ((IsEmpty || Size == 0) && shouldIgnoreEmptyArg(Ty))
806 CharUnits TySize = getContext().getTypeSizeInChars(Ty);
807 CharUnits TyAlignForABI = getContext().getTypeUnadjustedAlignInChars(Ty);
810 bool IsIndirect =
false;
819 getABIKind() == ARMABIKind::AAPCS16_VFP &&
820 !isHomogeneousAggregate(Ty, Base, Members)) {
827 }
else if (getABIKind() == ARMABIKind::AAPCS_VFP ||
828 getABIKind() == ARMABIKind::AAPCS) {
831 }
else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
839 TypeInfoChars TyInfo(TySize, TyAlignForABI, AlignRequirementKind::None);
844std::unique_ptr<TargetCodeGenInfo>
846 return std::make_unique<ARMTargetCodeGenInfo>(CGM.
getTypes(), Kind);
849std::unique_ptr<TargetCodeGenInfo>
851 return std::make_unique<WindowsARMTargetCodeGenInfo>(CGM.
getTypes(), K);
static bool isIntegerLikeType(QualType Ty, ASTContext &Context, llvm::LLVMContext &VMContext)
static StringRef getTriple(const Command &Job)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
This class is used for builtin types like 'int'.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
std::string FloatABI
The ABI to use for passing floating point arguments.
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 *Padding=nullptr)
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
RecordArgABI
Specify how one should pass an argument of a record type.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
ABIArgInfo & getReturnInfo()
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
void setEffectiveCallingConvention(unsigned Value)
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
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CodeGenOptions & getCodeGenOpts() const
const llvm::DataLayout & getDataLayout() const
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 unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.
Complex values, per C99 6.2.5p11.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
bool hasSignReturnAddress() const
Check if return address signing is enabled.
A (possibly-)qualified type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
field_iterator field_end() const
specific_decl_iterator< FieldDecl > field_iterator
RecordDecl * getDefinitionOrSelf() const
field_iterator field_begin() const
TargetOptions & getTargetOpts() const
Retrieve the target options.
virtual bool isBranchProtectionSupportedArch(StringRef Arch) const
Determine if the Architecture in this TargetInfo supports branch protection.
virtual bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, const LangOptions &LO, StringRef &Err) const
Determine if this TargetInfo supports the given branch protection specification.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
std::string CPU
If given, the name of the target CPU to generate code for.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isAnyComplexType() const
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * getAs() const
Member-template getAs<specific 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?
std::unique_ptr< TargetCodeGenInfo > createARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind Kind)
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
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 ...
bool isAggregateTypeForABI(QualType T)
std::unique_ptr< TargetCodeGenInfo > createWindowsARMTargetCodeGenInfo(CodeGenModule &CGM, ARMABIKind K)
void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array, llvm::Value *Value, unsigned FirstIndex, unsigned LastIndex)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
Top level wrappers for InstallAPI frontend operations.
@ Type
The name was classified as a type.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64