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