1*700637cbSDimitry Andric #include "TargetInfo.h" 2*700637cbSDimitry Andric #include "ABIInfo.h" 3*700637cbSDimitry Andric 4*700637cbSDimitry Andric using namespace clang; 5*700637cbSDimitry Andric using namespace clang::CIRGen; 6*700637cbSDimitry Andric isEmptyRecordForLayout(const ASTContext & context,QualType t)7*700637cbSDimitry Andricbool clang::CIRGen::isEmptyRecordForLayout(const ASTContext &context, 8*700637cbSDimitry Andric QualType t) { 9*700637cbSDimitry Andric const RecordType *rt = t->getAs<RecordType>(); 10*700637cbSDimitry Andric if (!rt) 11*700637cbSDimitry Andric return false; 12*700637cbSDimitry Andric 13*700637cbSDimitry Andric const RecordDecl *rd = rt->getDecl(); 14*700637cbSDimitry Andric 15*700637cbSDimitry Andric // If this is a C++ record, check the bases first. 16*700637cbSDimitry Andric if (const CXXRecordDecl *cxxrd = dyn_cast<CXXRecordDecl>(rd)) { 17*700637cbSDimitry Andric if (cxxrd->isDynamicClass()) 18*700637cbSDimitry Andric return false; 19*700637cbSDimitry Andric 20*700637cbSDimitry Andric for (const auto &I : cxxrd->bases()) 21*700637cbSDimitry Andric if (!isEmptyRecordForLayout(context, I.getType())) 22*700637cbSDimitry Andric return false; 23*700637cbSDimitry Andric } 24*700637cbSDimitry Andric 25*700637cbSDimitry Andric for (const auto *I : rd->fields()) 26*700637cbSDimitry Andric if (!isEmptyFieldForLayout(context, I)) 27*700637cbSDimitry Andric return false; 28*700637cbSDimitry Andric 29*700637cbSDimitry Andric return true; 30*700637cbSDimitry Andric } 31*700637cbSDimitry Andric isEmptyFieldForLayout(const ASTContext & context,const FieldDecl * fd)32*700637cbSDimitry Andricbool clang::CIRGen::isEmptyFieldForLayout(const ASTContext &context, 33*700637cbSDimitry Andric const FieldDecl *fd) { 34*700637cbSDimitry Andric if (fd->isZeroLengthBitField()) 35*700637cbSDimitry Andric return true; 36*700637cbSDimitry Andric 37*700637cbSDimitry Andric if (fd->isUnnamedBitField()) 38*700637cbSDimitry Andric return false; 39*700637cbSDimitry Andric 40*700637cbSDimitry Andric return isEmptyRecordForLayout(context, fd->getType()); 41*700637cbSDimitry Andric } 42*700637cbSDimitry Andric 43*700637cbSDimitry Andric namespace { 44*700637cbSDimitry Andric 45*700637cbSDimitry Andric class X8664ABIInfo : public ABIInfo { 46*700637cbSDimitry Andric public: X8664ABIInfo(CIRGenTypes & cgt)47*700637cbSDimitry Andric X8664ABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {} 48*700637cbSDimitry Andric }; 49*700637cbSDimitry Andric 50*700637cbSDimitry Andric class X8664TargetCIRGenInfo : public TargetCIRGenInfo { 51*700637cbSDimitry Andric public: X8664TargetCIRGenInfo(CIRGenTypes & cgt)52*700637cbSDimitry Andric X8664TargetCIRGenInfo(CIRGenTypes &cgt) 53*700637cbSDimitry Andric : TargetCIRGenInfo(std::make_unique<X8664ABIInfo>(cgt)) {} 54*700637cbSDimitry Andric }; 55*700637cbSDimitry Andric 56*700637cbSDimitry Andric } // namespace 57*700637cbSDimitry Andric 58*700637cbSDimitry Andric std::unique_ptr<TargetCIRGenInfo> createX8664TargetCIRGenInfo(CIRGenTypes & cgt)59*700637cbSDimitry Andricclang::CIRGen::createX8664TargetCIRGenInfo(CIRGenTypes &cgt) { 60*700637cbSDimitry Andric return std::make_unique<X8664TargetCIRGenInfo>(cgt); 61*700637cbSDimitry Andric } 62*700637cbSDimitry Andric 63*700637cbSDimitry Andric ABIInfo::~ABIInfo() noexcept = default; 64*700637cbSDimitry Andric isNoProtoCallVariadic(const FunctionNoProtoType * fnType) const65*700637cbSDimitry Andricbool TargetCIRGenInfo::isNoProtoCallVariadic( 66*700637cbSDimitry Andric const FunctionNoProtoType *fnType) const { 67*700637cbSDimitry Andric // The following conventions are known to require this to be false: 68*700637cbSDimitry Andric // x86_stdcall 69*700637cbSDimitry Andric // MIPS 70*700637cbSDimitry Andric // For everything else, we just prefer false unless we opt out. 71*700637cbSDimitry Andric return false; 72*700637cbSDimitry Andric } 73