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().getClangABICompat() <=
357 LangOptions::ClangABI::Ver19)
364ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty,
bool isVariadic,
365 unsigned functionCallConv)
const {
375 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv,
false);
380 if (isIllegalVectorType(Ty))
381 return coerceIllegalVector(Ty);
386 Ty = ED->getIntegerType();
389 if (
const auto *EIT = Ty->
getAs<BitIntType>())
390 if (EIT->getNumBits() > 64)
391 return getNaturalAlignIndirect(
392 Ty, getDataLayout().getAllocaAddrSpace(),
395 return (isPromotableIntegerTypeForABI(Ty)
401 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
408 getContext().getTypeSize(Ty) == 0) {
409 if (shouldIgnoreEmptyArg(Ty))
420 if (isHomogeneousAggregate(Ty, Base, Members))
421 return classifyHomogeneousAggregate(Ty, Base, Members);
422 }
else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
428 if (isHomogeneousAggregate(Ty, Base, Members)) {
429 assert(Base && Members <= 4 &&
"unexpected homogeneous aggregate");
431 llvm::ArrayType::get(CGT.
ConvertType(QualType(Base, 0)), Members);
436 if (getABIKind() == ARMABIKind::AAPCS16_VFP &&
443 getDataLayout().getAllocaAddrSpace(),
false);
452 if (getABIKind() == ARMABIKind::AAPCS_VFP ||
453 getABIKind() == ARMABIKind::AAPCS) {
454 TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
455 ABIAlign = std::clamp(TyAlign, (uint64_t)4, (uint64_t)8);
457 TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity();
460 assert(getABIKind() != ARMABIKind::AAPCS16_VFP &&
"unexpected byval");
463 getDataLayout().getAllocaAddrSpace(),
464 true, TyAlign > ABIAlign);
473 ElemTy = llvm::Type::getInt32Ty(getVMContext());
474 SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;
476 ElemTy = llvm::Type::getInt64Ty(getVMContext());
477 SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
484 llvm::LLVMContext &VMContext) {
489 uint64_t Size = Context.getTypeSize(Ty);
516 if (!RT)
return false;
519 const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
527 bool HadField =
false;
530 i != e; ++i, ++idx) {
568ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
bool isVariadic,
569 unsigned functionCallConv)
const {
573 !isVariadic && isEffectivelyAAPCS_VFP(functionCallConv,
true);
578 if (
const VectorType *VT = RetTy->
getAs<VectorType>()) {
580 if (getContext().getTypeSize(RetTy) > 128)
581 return getNaturalAlignIndirect(RetTy,
582 getDataLayout().getAllocaAddrSpace());
585 if ((!getTarget().hasFastHalfType() &&
586 (VT->getElementType()->isFloat16Type() ||
587 VT->getElementType()->isHalfType())) ||
589 VT->getElementType()->isBFloat16Type()))
590 return coerceIllegalVector(RetTy);
596 RetTy = ED->getIntegerType();
598 if (
const auto *EIT = RetTy->
getAs<BitIntType>())
599 if (EIT->getNumBits() > 64)
600 return getNaturalAlignIndirect(
601 RetTy, getDataLayout().getAllocaAddrSpace(),
605 : ABIArgInfo::getDirect();
609 if (getABIKind() == ARMABIKind::APCS) {
619 getVMContext(), getContext().getTypeSize(RetTy)));
633 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
639 getContext().getTypeSize(RetTy) == 0)
646 if (isHomogeneousAggregate(RetTy, Base, Members))
647 return classifyHomogeneousAggregate(RetTy, Base, Members);
654 if (getDataLayout().isBigEndian())
664 }
else if (Size <= 128 && getABIKind() == ARMABIKind::AAPCS16_VFP) {
665 llvm::Type *Int32Ty = llvm::Type::getInt32Ty(getVMContext());
666 llvm::Type *CoerceTy =
667 llvm::ArrayType::get(Int32Ty, llvm::alignTo(Size, 32) / 32);
671 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
675bool ARMABIInfo::isIllegalVectorType(QualType Ty)
const {
676 if (
const VectorType *VT = Ty->
getAs<VectorType> ()) {
683 if ((!getTarget().hasFastHalfType() &&
684 (VT->getElementType()->isFloat16Type() ||
685 VT->getElementType()->isHalfType())) ||
687 VT->getElementType()->isBFloat16Type()))
695 unsigned NumElements = VT->getNumElements();
697 if (!llvm::isPowerOf2_32(NumElements) && NumElements != 3)
701 unsigned NumElements = VT->getNumElements();
704 if (!llvm::isPowerOf2_32(NumElements))
714bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty)
const {
715 if (
const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
716 uint64_t NElements = AT->getZExtSize();
719 return containsAnyFP16Vectors(AT->getElementType());
723 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
724 if (llvm::any_of(CXXRD->bases(), [
this](
const CXXBaseSpecifier &B) {
725 return containsAnyFP16Vectors(B.getType());
729 if (llvm::any_of(RD->fields(), [
this](FieldDecl *FD) {
730 return FD && containsAnyFP16Vectors(FD->getType());
736 if (
const VectorType *VT = Ty->
getAs<VectorType>())
737 return (VT->getElementType()->isFloat16Type() ||
738 VT->getElementType()->isBFloat16Type() ||
739 VT->getElementType()->isHalfType());
744bool ARMSwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
745 unsigned NumElts)
const {
746 if (!llvm::isPowerOf2_32(NumElts))
748 unsigned size = CGT.
getDataLayout().getTypeStoreSizeInBits(EltTy);
757bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty)
const {
760 if (
const BuiltinType *BT = Ty->
getAs<BuiltinType>()) {
761 if (BT->getKind() == BuiltinType::Float ||
762 BT->getKind() == BuiltinType::Double ||
763 BT->getKind() == BuiltinType::LongDouble)
765 }
else if (
const VectorType *VT = Ty->
getAs<VectorType>()) {
766 unsigned VecSize = getContext().getTypeSize(VT);
767 if (VecSize == 64 || VecSize == 128)
773bool ARMABIInfo::isHomogeneousAggregateSmallEnough(
const Type *Base,
774 uint64_t Members)
const {
778bool ARMABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
const {
787bool ARMABIInfo::isEffectivelyAAPCS_VFP(
unsigned callConvention,
788 bool acceptHalf)
const {
790 if (callConvention != llvm::CallingConv::C)
791 return (callConvention == llvm::CallingConv::ARM_AAPCS_VFP);
793 return (getABIKind() == ARMABIKind::AAPCS_VFP) ||
794 (acceptHalf && (getABIKind() == ARMABIKind::AAPCS16_VFP));
797RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
798 QualType Ty, AggValueSlot Slot)
const {
804 if ((IsEmpty || Size == 0) && shouldIgnoreEmptyArg(Ty))
807 CharUnits TySize = getContext().getTypeSizeInChars(Ty);
808 CharUnits TyAlignForABI = getContext().getTypeUnadjustedAlignInChars(Ty);
811 bool IsIndirect =
false;
820 getABIKind() == ARMABIKind::AAPCS16_VFP &&
821 !isHomogeneousAggregate(Ty, Base, Members)) {
828 }
else if (getABIKind() == ARMABIKind::AAPCS_VFP ||
829 getABIKind() == ARMABIKind::AAPCS) {
832 }
else if (getABIKind() == ARMABIKind::AAPCS16_VFP) {
840 TypeInfoChars TyInfo(TySize, TyAlignForABI, AlignRequirementKind::None);
845std::unique_ptr<TargetCodeGenInfo>
847 return std::make_unique<ARMTargetCodeGenInfo>(CGM.
getTypes(), Kind);
850std::unique_ptr<TargetCodeGenInfo>
852 return std::make_unique<WindowsARMTargetCodeGenInfo>(CGM.
getTypes(), K);
static bool isIntegerLikeType(QualType Ty, ASTContext &Context, llvm::LLVMContext &VMContext)
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
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - 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 getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=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
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.
The JSON file list parser is used to communicate input to InstallAPI.
@ Type
The name was classified as a type.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64