1//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// These classes wrap the information about a call or function
11// definition used to handle ABI compliancy.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef CLANG_CODEGEN_CGCALL_H
16#define CLANG_CODEGEN_CGCALL_H
17
18#include "CGValue.h"
19#include "EHScopeStack.h"
20#include "clang/AST/CanonicalType.h"
21#include "clang/AST/Type.h"
22#include "llvm/ADT/FoldingSet.h"
23#include "llvm/IR/Value.h"
24
25// FIXME: Restructure so we don't have to expose so much stuff.
26#include "ABIInfo.h"
27
28namespace llvm {
29  class AttributeSet;
30  class Function;
31  class Type;
32  class Value;
33}
34
35namespace clang {
36  class ASTContext;
37  class Decl;
38  class FunctionDecl;
39  class ObjCMethodDecl;
40  class VarDecl;
41
42namespace CodeGen {
43  typedef SmallVector<llvm::AttributeSet, 8> AttributeListType;
44
45  struct CallArg {
46    RValue RV;
47    QualType Ty;
48    bool NeedsCopy;
49    CallArg(RValue rv, QualType ty, bool needscopy)
50    : RV(rv), Ty(ty), NeedsCopy(needscopy)
51    { }
52  };
53
54  /// CallArgList - Type for representing both the value and type of
55  /// arguments in a call.
56  class CallArgList :
57    public SmallVector<CallArg, 16> {
58  public:
59    struct Writeback {
60      /// The original argument.  Note that the argument l-value
61      /// is potentially null.
62      LValue Source;
63
64      /// The temporary alloca.
65      llvm::Value *Temporary;
66
67      /// A value to "use" after the writeback, or null.
68      llvm::Value *ToUse;
69    };
70
71    struct CallArgCleanup {
72      EHScopeStack::stable_iterator Cleanup;
73
74      /// The "is active" insertion point.  This instruction is temporary and
75      /// will be removed after insertion.
76      llvm::Instruction *IsActiveIP;
77    };
78
79    void add(RValue rvalue, QualType type, bool needscopy = false) {
80      push_back(CallArg(rvalue, type, needscopy));
81    }
82
83    void addFrom(const CallArgList &other) {
84      insert(end(), other.begin(), other.end());
85      Writebacks.insert(Writebacks.end(),
86                        other.Writebacks.begin(), other.Writebacks.end());
87    }
88
89    void addWriteback(LValue srcLV, llvm::Value *temporary,
90                      llvm::Value *toUse) {
91      Writeback writeback;
92      writeback.Source = srcLV;
93      writeback.Temporary = temporary;
94      writeback.ToUse = toUse;
95      Writebacks.push_back(writeback);
96    }
97
98    bool hasWritebacks() const { return !Writebacks.empty(); }
99
100    typedef SmallVectorImpl<Writeback>::const_iterator writeback_iterator;
101    writeback_iterator writeback_begin() const { return Writebacks.begin(); }
102    writeback_iterator writeback_end() const { return Writebacks.end(); }
103
104    void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup,
105                                   llvm::Instruction *IsActiveIP) {
106      CallArgCleanup ArgCleanup;
107      ArgCleanup.Cleanup = Cleanup;
108      ArgCleanup.IsActiveIP = IsActiveIP;
109      CleanupsToDeactivate.push_back(ArgCleanup);
110    }
111
112    ArrayRef<CallArgCleanup> getCleanupsToDeactivate() const {
113      return CleanupsToDeactivate;
114    }
115
116  private:
117    SmallVector<Writeback, 1> Writebacks;
118
119    /// Deactivate these cleanups immediately before making the call.  This
120    /// is used to cleanup objects that are owned by the callee once the call
121    /// occurs.
122    SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;
123  };
124
125  /// A class for recording the number of arguments that a function
126  /// signature requires.
127  class RequiredArgs {
128    /// The number of required arguments, or ~0 if the signature does
129    /// not permit optional arguments.
130    unsigned NumRequired;
131  public:
132    enum All_t { All };
133
134    RequiredArgs(All_t _) : NumRequired(~0U) {}
135    explicit RequiredArgs(unsigned n) : NumRequired(n) {
136      assert(n != ~0U);
137    }
138
139    /// Compute the arguments required by the given formal prototype,
140    /// given that there may be some additional, non-formal arguments
141    /// in play.
142    static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
143                                         unsigned additional) {
144      if (!prototype->isVariadic()) return All;
145      return RequiredArgs(prototype->getNumArgs() + additional);
146    }
147
148    static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
149      return forPrototypePlus(prototype, 0);
150    }
151
152    static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
153      return forPrototype(prototype.getTypePtr());
154    }
155
156    static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
157                                         unsigned additional) {
158      return forPrototypePlus(prototype.getTypePtr(), additional);
159    }
160
161    bool allowsOptionalArgs() const { return NumRequired != ~0U; }
162    unsigned getNumRequiredArgs() const {
163      assert(allowsOptionalArgs());
164      return NumRequired;
165    }
166
167    unsigned getOpaqueData() const { return NumRequired; }
168    static RequiredArgs getFromOpaqueData(unsigned value) {
169      if (value == ~0U) return All;
170      return RequiredArgs(value);
171    }
172  };
173
174  /// FunctionArgList - Type for representing both the decl and type
175  /// of parameters to a function. The decl must be either a
176  /// ParmVarDecl or ImplicitParamDecl.
177  class FunctionArgList : public SmallVector<const VarDecl*, 16> {
178  };
179
180  /// CGFunctionInfo - Class to encapsulate the information about a
181  /// function definition.
182  class CGFunctionInfo : public llvm::FoldingSetNode {
183    struct ArgInfo {
184      CanQualType type;
185      ABIArgInfo info;
186    };
187
188    /// The LLVM::CallingConv to use for this function (as specified by the
189    /// user).
190    unsigned CallingConvention : 8;
191
192    /// The LLVM::CallingConv to actually use for this function, which may
193    /// depend on the ABI.
194    unsigned EffectiveCallingConvention : 8;
195
196    /// The clang::CallingConv that this was originally created with.
197    unsigned ASTCallingConvention : 8;
198
199    /// Whether this function is noreturn.
200    unsigned NoReturn : 1;
201
202    /// Whether this function is returns-retained.
203    unsigned ReturnsRetained : 1;
204
205    /// How many arguments to pass inreg.
206    unsigned HasRegParm : 1;
207    unsigned RegParm : 4;
208
209    RequiredArgs Required;
210
211    unsigned NumArgs;
212    ArgInfo *getArgsBuffer() {
213      return reinterpret_cast<ArgInfo*>(this+1);
214    }
215    const ArgInfo *getArgsBuffer() const {
216      return reinterpret_cast<const ArgInfo*>(this + 1);
217    }
218
219    CGFunctionInfo() : Required(RequiredArgs::All) {}
220
221  public:
222    static CGFunctionInfo *create(unsigned llvmCC,
223                                  const FunctionType::ExtInfo &extInfo,
224                                  CanQualType resultType,
225                                  ArrayRef<CanQualType> argTypes,
226                                  RequiredArgs required);
227
228    typedef const ArgInfo *const_arg_iterator;
229    typedef ArgInfo *arg_iterator;
230
231    const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
232    const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
233    arg_iterator arg_begin() { return getArgsBuffer() + 1; }
234    arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
235
236    unsigned  arg_size() const { return NumArgs; }
237
238    bool isVariadic() const { return Required.allowsOptionalArgs(); }
239    RequiredArgs getRequiredArgs() const { return Required; }
240
241    bool isNoReturn() const { return NoReturn; }
242
243    /// In ARC, whether this function retains its return value.  This
244    /// is not always reliable for call sites.
245    bool isReturnsRetained() const { return ReturnsRetained; }
246
247    /// getASTCallingConvention() - Return the AST-specified calling
248    /// convention.
249    CallingConv getASTCallingConvention() const {
250      return CallingConv(ASTCallingConvention);
251    }
252
253    /// getCallingConvention - Return the user specified calling
254    /// convention, which has been translated into an LLVM CC.
255    unsigned getCallingConvention() const { return CallingConvention; }
256
257    /// getEffectiveCallingConvention - Return the actual calling convention to
258    /// use, which may depend on the ABI.
259    unsigned getEffectiveCallingConvention() const {
260      return EffectiveCallingConvention;
261    }
262    void setEffectiveCallingConvention(unsigned Value) {
263      EffectiveCallingConvention = Value;
264    }
265
266    bool getHasRegParm() const { return HasRegParm; }
267    unsigned getRegParm() const { return RegParm; }
268
269    FunctionType::ExtInfo getExtInfo() const {
270      return FunctionType::ExtInfo(isNoReturn(),
271                                   getHasRegParm(), getRegParm(),
272                                   getASTCallingConvention(),
273                                   isReturnsRetained());
274    }
275
276    CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
277
278    ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
279    const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
280
281    void Profile(llvm::FoldingSetNodeID &ID) {
282      ID.AddInteger(getASTCallingConvention());
283      ID.AddBoolean(NoReturn);
284      ID.AddBoolean(ReturnsRetained);
285      ID.AddBoolean(HasRegParm);
286      ID.AddInteger(RegParm);
287      ID.AddInteger(Required.getOpaqueData());
288      getReturnType().Profile(ID);
289      for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it)
290        it->type.Profile(ID);
291    }
292    static void Profile(llvm::FoldingSetNodeID &ID,
293                        const FunctionType::ExtInfo &info,
294                        RequiredArgs required,
295                        CanQualType resultType,
296                        ArrayRef<CanQualType> argTypes) {
297      ID.AddInteger(info.getCC());
298      ID.AddBoolean(info.getNoReturn());
299      ID.AddBoolean(info.getProducesResult());
300      ID.AddBoolean(info.getHasRegParm());
301      ID.AddInteger(info.getRegParm());
302      ID.AddInteger(required.getOpaqueData());
303      resultType.Profile(ID);
304      for (ArrayRef<CanQualType>::iterator
305             i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
306        i->Profile(ID);
307      }
308    }
309  };
310
311  /// ReturnValueSlot - Contains the address where the return value of a
312  /// function can be stored, and whether the address is volatile or not.
313  class ReturnValueSlot {
314    llvm::PointerIntPair<llvm::Value *, 1, bool> Value;
315
316  public:
317    ReturnValueSlot() {}
318    ReturnValueSlot(llvm::Value *Value, bool IsVolatile)
319      : Value(Value, IsVolatile) {}
320
321    bool isNull() const { return !getValue(); }
322
323    bool isVolatile() const { return Value.getInt(); }
324    llvm::Value *getValue() const { return Value.getPointer(); }
325  };
326
327}  // end namespace CodeGen
328}  // end namespace clang
329
330#endif
331