xref: /freebsd/contrib/llvm-project/clang/lib/CIR/CodeGen/TargetInfo.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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