1*700637cbSDimitry Andric //===---- TargetInfo.h - Encapsulate target details -------------*- C++ -*-===// 2*700637cbSDimitry Andric // 3*700637cbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*700637cbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*700637cbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*700637cbSDimitry Andric // 7*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 8*700637cbSDimitry Andric // 9*700637cbSDimitry Andric // These classes wrap the information about a call or function definition used 10*700637cbSDimitry Andric // to handle ABI compliancy. 11*700637cbSDimitry Andric // 12*700637cbSDimitry Andric //===----------------------------------------------------------------------===// 13*700637cbSDimitry Andric 14*700637cbSDimitry Andric #ifndef LLVM_CLANG_LIB_CIR_TARGETINFO_H 15*700637cbSDimitry Andric #define LLVM_CLANG_LIB_CIR_TARGETINFO_H 16*700637cbSDimitry Andric 17*700637cbSDimitry Andric #include "ABIInfo.h" 18*700637cbSDimitry Andric #include "CIRGenTypes.h" 19*700637cbSDimitry Andric 20*700637cbSDimitry Andric #include <memory> 21*700637cbSDimitry Andric #include <utility> 22*700637cbSDimitry Andric 23*700637cbSDimitry Andric namespace clang::CIRGen { 24*700637cbSDimitry Andric 25*700637cbSDimitry Andric /// isEmptyFieldForLayout - Return true if the field is "empty", that is, 26*700637cbSDimitry Andric /// either a zero-width bit-field or an isEmptyRecordForLayout. 27*700637cbSDimitry Andric bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd); 28*700637cbSDimitry Andric 29*700637cbSDimitry Andric /// isEmptyRecordForLayout - Return true if a structure contains only empty 30*700637cbSDimitry Andric /// base classes (per isEmptyRecordForLayout) and fields (per 31*700637cbSDimitry Andric /// isEmptyFieldForLayout). Note, C++ record fields are considered empty 32*700637cbSDimitry Andric /// if the [[no_unique_address]] attribute would have made them empty. 33*700637cbSDimitry Andric bool isEmptyRecordForLayout(const ASTContext &context, QualType t); 34*700637cbSDimitry Andric 35*700637cbSDimitry Andric class TargetCIRGenInfo { 36*700637cbSDimitry Andric std::unique_ptr<ABIInfo> info; 37*700637cbSDimitry Andric 38*700637cbSDimitry Andric public: TargetCIRGenInfo(std::unique_ptr<ABIInfo> info)39*700637cbSDimitry Andric TargetCIRGenInfo(std::unique_ptr<ABIInfo> info) : info(std::move(info)) {} 40*700637cbSDimitry Andric 41*700637cbSDimitry Andric virtual ~TargetCIRGenInfo() = default; 42*700637cbSDimitry Andric 43*700637cbSDimitry Andric /// Returns ABI info helper for the target. getABIInfo()44*700637cbSDimitry Andric const ABIInfo &getABIInfo() const { return *info; } 45*700637cbSDimitry Andric 46*700637cbSDimitry Andric /// Determine whether a call to an unprototyped functions under 47*700637cbSDimitry Andric /// the given calling convention should use the variadic 48*700637cbSDimitry Andric /// convention or the non-variadic convention. 49*700637cbSDimitry Andric /// 50*700637cbSDimitry Andric /// There's a good reason to make a platform's variadic calling 51*700637cbSDimitry Andric /// convention be different from its non-variadic calling 52*700637cbSDimitry Andric /// convention: the non-variadic arguments can be passed in 53*700637cbSDimitry Andric /// registers (better for performance), and the variadic arguments 54*700637cbSDimitry Andric /// can be passed on the stack (also better for performance). If 55*700637cbSDimitry Andric /// this is done, however, unprototyped functions *must* use the 56*700637cbSDimitry Andric /// non-variadic convention, because C99 states that a call 57*700637cbSDimitry Andric /// through an unprototyped function type must succeed if the 58*700637cbSDimitry Andric /// function was defined with a non-variadic prototype with 59*700637cbSDimitry Andric /// compatible parameters. Therefore, splitting the conventions 60*700637cbSDimitry Andric /// makes it impossible to call a variadic function through an 61*700637cbSDimitry Andric /// unprototyped type. Since function prototypes came out in the 62*700637cbSDimitry Andric /// late 1970s, this is probably an acceptable trade-off. 63*700637cbSDimitry Andric /// Nonetheless, not all platforms are willing to make it, and in 64*700637cbSDimitry Andric /// particularly x86-64 bends over backwards to make the 65*700637cbSDimitry Andric /// conventions compatible. 66*700637cbSDimitry Andric /// 67*700637cbSDimitry Andric /// The default is false. This is correct whenever: 68*700637cbSDimitry Andric /// - the conventions are exactly the same, because it does not 69*700637cbSDimitry Andric /// matter and the resulting IR will be somewhat prettier in 70*700637cbSDimitry Andric /// certain cases; or 71*700637cbSDimitry Andric /// - the conventions are substantively different in how they pass 72*700637cbSDimitry Andric /// arguments, because in this case using the variadic convention 73*700637cbSDimitry Andric /// will lead to C99 violations. 74*700637cbSDimitry Andric /// 75*700637cbSDimitry Andric /// However, some platforms make the conventions identical except 76*700637cbSDimitry Andric /// for passing additional out-of-band information to a variadic 77*700637cbSDimitry Andric /// function: for example, x86-64 passes the number of SSE 78*700637cbSDimitry Andric /// arguments in %al. On these platforms, it is desirable to 79*700637cbSDimitry Andric /// call unprototyped functions using the variadic convention so 80*700637cbSDimitry Andric /// that unprototyped calls to varargs functions still succeed. 81*700637cbSDimitry Andric /// 82*700637cbSDimitry Andric /// Relatedly, platforms which pass the fixed arguments to this: 83*700637cbSDimitry Andric /// A foo(B, C, D); 84*700637cbSDimitry Andric /// differently than they would pass them to this: 85*700637cbSDimitry Andric /// A foo(B, C, D, ...); 86*700637cbSDimitry Andric /// may need to adjust the debugger-support code in Sema to do the 87*700637cbSDimitry Andric /// right thing when calling a function with no know signature. 88*700637cbSDimitry Andric virtual bool isNoProtoCallVariadic(const FunctionNoProtoType *fnType) const; 89*700637cbSDimitry Andric }; 90*700637cbSDimitry Andric 91*700637cbSDimitry Andric std::unique_ptr<TargetCIRGenInfo> createX8664TargetCIRGenInfo(CIRGenTypes &cgt); 92*700637cbSDimitry Andric 93*700637cbSDimitry Andric } // namespace clang::CIRGen 94*700637cbSDimitry Andric 95*700637cbSDimitry Andric #endif // LLVM_CLANG_LIB_CIR_TARGETINFO_H 96