Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/CodeGen/CGCall.h
Line
Count
Source (jump to first uncovered line)
1
//===----- CGCall.h - Encapsulate calling convention 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
10
// definition used to handle ABI compliancy.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H
15
#define LLVM_CLANG_LIB_CODEGEN_CGCALL_H
16
17
#include "CGValue.h"
18
#include "EHScopeStack.h"
19
#include "clang/AST/CanonicalType.h"
20
#include "clang/AST/GlobalDecl.h"
21
#include "clang/AST/Type.h"
22
#include "llvm/IR/Value.h"
23
24
// FIXME: Restructure so we don't have to expose so much stuff.
25
#include "ABIInfo.h"
26
27
namespace llvm {
28
class AttributeList;
29
class Function;
30
class Type;
31
class Value;
32
}
33
34
namespace clang {
35
  class ASTContext;
36
  class Decl;
37
  class FunctionDecl;
38
  class ObjCMethodDecl;
39
  class VarDecl;
40
41
namespace CodeGen {
42
43
/// Abstract information about a function or function prototype.
44
class CGCalleeInfo {
45
  /// The function prototype of the callee.
46
  const FunctionProtoType *CalleeProtoTy;
47
  /// The function declaration of the callee.
48
  GlobalDecl CalleeDecl;
49
50
public:
51
3.07k
  explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl() {}
52
  CGCalleeInfo(const FunctionProtoType *calleeProtoTy, GlobalDecl calleeDecl)
53
4.79k
      : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
54
  CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
55
287
      : CalleeProtoTy(calleeProtoTy), CalleeDecl() {}
56
  CGCalleeInfo(GlobalDecl calleeDecl)
57
1.38M
      : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}
58
59
1.36M
  const FunctionProtoType *getCalleeFunctionProtoType() const {
60
1.36M
    return CalleeProtoTy;
61
1.36M
  }
62
3.25M
  const GlobalDecl getCalleeDecl() const { return CalleeDecl; }
63
  };
64
65
  /// All available information about a concrete callee.
66
  class CGCallee {
67
    enum class SpecialKind : uintptr_t {
68
      Invalid,
69
      Builtin,
70
      PseudoDestructor,
71
      Virtual,
72
73
      Last = Virtual
74
    };
75
76
    struct BuiltinInfoStorage {
77
      const FunctionDecl *Decl;
78
      unsigned ID;
79
    };
80
    struct PseudoDestructorInfoStorage {
81
      const CXXPseudoDestructorExpr *Expr;
82
    };
83
    struct VirtualInfoStorage {
84
      const CallExpr *CE;
85
      GlobalDecl MD;
86
      Address Addr;
87
      llvm::FunctionType *FTy;
88
    };
89
90
    SpecialKind KindOrFunctionPointer;
91
    union {
92
      CGCalleeInfo AbstractInfo;
93
      BuiltinInfoStorage BuiltinInfo;
94
      PseudoDestructorInfoStorage PseudoDestructorInfo;
95
      VirtualInfoStorage VirtualInfo;
96
    };
97
98
162k
    explicit CGCallee(SpecialKind kind) : KindOrFunctionPointer(kind) {}
99
100
    CGCallee(const FunctionDecl *builtinDecl, unsigned builtinID)
101
0
        : KindOrFunctionPointer(SpecialKind::Builtin) {
102
0
      BuiltinInfo.Decl = builtinDecl;
103
0
      BuiltinInfo.ID = builtinID;
104
0
    }
105
106
  public:
107
279k
    CGCallee() : KindOrFunctionPointer(SpecialKind::Invalid) {}
108
109
    /// Construct a callee.  Call this constructor directly when this
110
    /// isn't a direct call.
111
    CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr)
112
904k
        : KindOrFunctionPointer(SpecialKind(uintptr_t(functionPtr))) {
113
904k
      AbstractInfo = abstractInfo;
114
904k
      assert(functionPtr && "configuring callee without function pointer");
115
904k
      assert(functionPtr->getType()->isPointerTy());
116
904k
      assert(functionPtr->getType()->getPointerElementType()->isFunctionTy());
117
904k
    }
118
119
    static CGCallee forBuiltin(unsigned builtinID,
120
151k
                               const FunctionDecl *builtinDecl) {
121
151k
      CGCallee result(SpecialKind::Builtin);
122
151k
      result.BuiltinInfo.Decl = builtinDecl;
123
151k
      result.BuiltinInfo.ID = builtinID;
124
151k
      return result;
125
151k
    }
126
127
475
    static CGCallee forPseudoDestructor(const CXXPseudoDestructorExpr *E) {
128
475
      CGCallee result(SpecialKind::PseudoDestructor);
129
475
      result.PseudoDestructorInfo.Expr = E;
130
475
      return result;
131
475
    }
132
133
    static CGCallee forDirect(llvm::Constant *functionPtr,
134
886k
                        const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
135
886k
      return CGCallee(abstractInfo, functionPtr);
136
886k
    }
137
138
    static CGCallee
139
    forDirect(llvm::FunctionCallee functionPtr,
140
2.56k
              const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
141
2.56k
      return CGCallee(abstractInfo, functionPtr.getCallee());
142
2.56k
    }
143
144
    static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr,
145
10.6k
                               llvm::FunctionType *FTy) {
146
10.6k
      CGCallee result(SpecialKind::Virtual);
147
10.6k
      result.VirtualInfo.CE = CE;
148
10.6k
      result.VirtualInfo.MD = MD;
149
10.6k
      result.VirtualInfo.Addr = Addr;
150
10.6k
      result.VirtualInfo.FTy = FTy;
151
10.6k
      return result;
152
10.6k
    }
153
154
614k
    bool isBuiltin() const {
155
614k
      return KindOrFunctionPointer == SpecialKind::Builtin;
156
614k
    }
157
151k
    const FunctionDecl *getBuiltinDecl() const {
158
151k
      assert(isBuiltin());
159
151k
      return BuiltinInfo.Decl;
160
151k
    }
161
151k
    unsigned getBuiltinID() const {
162
151k
      assert(isBuiltin());
163
151k
      return BuiltinInfo.ID;
164
151k
    }
165
166
462k
    bool isPseudoDestructor() const {
167
462k
      return KindOrFunctionPointer == SpecialKind::PseudoDestructor;
168
462k
    }
169
475
    const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const {
170
475
      assert(isPseudoDestructor());
171
475
      return PseudoDestructorInfo.Expr;
172
475
    }
173
174
0
    bool isOrdinary() const {
175
0
      return uintptr_t(KindOrFunctionPointer) > uintptr_t(SpecialKind::Last);
176
0
    }
177
2.32M
    CGCalleeInfo getAbstractInfo() const {
178
2.32M
      if (isVirtual())
179
21.2k
        return VirtualInfo.MD;
180
2.30M
      assert(isOrdinary());
181
2.30M
      return AbstractInfo;
182
2.30M
    }
183
914k
    llvm::Value *getFunctionPointer() const {
184
914k
      assert(isOrdinary());
185
914k
      return reinterpret_cast<llvm::Value*>(uintptr_t(KindOrFunctionPointer));
186
914k
    }
187
9.45k
    void setFunctionPointer(llvm::Value *functionPtr) {
188
9.45k
      assert(isOrdinary());
189
9.45k
      KindOrFunctionPointer = SpecialKind(uintptr_t(functionPtr));
190
9.45k
    }
191
192
3.23M
    bool isVirtual() const {
193
3.23M
      return KindOrFunctionPointer == SpecialKind::Virtual;
194
3.23M
    }
195
10.6k
    const CallExpr *getVirtualCallExpr() const {
196
10.6k
      assert(isVirtual());
197
10.6k
      return VirtualInfo.CE;
198
10.6k
    }
199
10.6k
    GlobalDecl getVirtualMethodDecl() const {
200
10.6k
      assert(isVirtual());
201
10.6k
      return VirtualInfo.MD;
202
10.6k
    }
203
10.6k
    Address getThisAddress() const {
204
10.6k
      assert(isVirtual());
205
10.6k
      return VirtualInfo.Addr;
206
10.6k
    }
207
10.6k
    llvm::FunctionType *getVirtualFunctionType() const {
208
10.6k
      assert(isVirtual());
209
10.6k
      return VirtualInfo.FTy;
210
10.6k
    }
211
212
    /// If this is a delayed callee computation of some sort, prepare
213
    /// a concrete callee.
214
    CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const;
215
  };
216
217
  struct CallArg {
218
  private:
219
    union {
220
      RValue RV;
221
      LValue LV; /// The argument is semantically a load from this l-value.
222
    };
223
    bool HasLV;
224
225
    /// A data-flow flag to make sure getRValue and/or copyInto are not
226
    /// called twice for duplicated IR emission.
227
    mutable bool IsUsed;
228
229
  public:
230
    QualType Ty;
231
    CallArg(RValue rv, QualType ty)
232
1.66M
        : RV(rv), HasLV(false), IsUsed(false), Ty(ty) {}
233
    CallArg(LValue lv, QualType ty)
234
915
        : LV(lv), HasLV(true), IsUsed(false), Ty(ty) {}
235
1.24M
    bool hasLValue() const { return HasLV; }
236
36
    QualType getType() const { return Ty; }
237
238
    /// \returns an independent RValue. If the CallArg contains an LValue,
239
    /// a temporary copy is returned.
240
    RValue getRValue(CodeGenFunction &CGF) const;
241
242
1.18k
    LValue getKnownLValue() const {
243
1.18k
      assert(HasLV && !IsUsed);
244
1.18k
      return LV;
245
1.18k
    }
246
2.86M
    RValue getKnownRValue() const {
247
2.86M
      assert(!HasLV && !IsUsed);
248
2.86M
      return RV;
249
2.86M
    }
250
15
    void setRValue(RValue _RV) {
251
15
      assert(!HasLV);
252
15
      RV = _RV;
253
15
    }
254
255
1.63M
    bool isAggregate() const { return HasLV || 
RV.isAggregate()1.63M
; }
256
257
    void copyInto(CodeGenFunction &CGF, Address A) const;
258
  };
259
260
  /// CallArgList - Type for representing both the value and type of
261
  /// arguments in a call.
262
  class CallArgList :
263
    public SmallVector<CallArg, 8> {
264
  public:
265
1.54M
    CallArgList() : StackBase(nullptr) {}
266
267
    struct Writeback {
268
      /// The original argument.  Note that the argument l-value
269
      /// is potentially null.
270
      LValue Source;
271
272
      /// The temporary alloca.
273
      Address Temporary;
274
275
      /// A value to "use" after the writeback, or null.
276
      llvm::Value *ToUse;
277
    };
278
279
    struct CallArgCleanup {
280
      EHScopeStack::stable_iterator Cleanup;
281
282
      /// The "is active" insertion point.  This instruction is temporary and
283
      /// will be removed after insertion.
284
      llvm::Instruction *IsActiveIP;
285
    };
286
287
1.66M
    void add(RValue rvalue, QualType type) { push_back(CallArg(rvalue, type)); }
288
289
915
    void addUncopiedAggregate(LValue LV, QualType type) {
290
915
      push_back(CallArg(LV, type));
291
915
    }
292
293
    /// Add all the arguments from another CallArgList to this one. After doing
294
    /// this, the old CallArgList retains its list of arguments, but must not
295
    /// be used to emit a call.
296
5.55k
    void addFrom(const CallArgList &other) {
297
5.55k
      insert(end(), other.begin(), other.end());
298
5.55k
      Writebacks.insert(Writebacks.end(),
299
5.55k
                        other.Writebacks.begin(), other.Writebacks.end());
300
5.55k
      CleanupsToDeactivate.insert(CleanupsToDeactivate.end(),
301
5.55k
                                  other.CleanupsToDeactivate.begin(),
302
5.55k
                                  other.CleanupsToDeactivate.end());
303
5.55k
      assert(!(StackBase && other.StackBase) && "can't merge stackbases");
304
5.55k
      if (!StackBase)
305
5.55k
        StackBase = other.StackBase;
306
5.55k
    }
307
308
    void addWriteback(LValue srcLV, Address temporary,
309
26
                      llvm::Value *toUse) {
310
26
      Writeback writeback = { srcLV, temporary, toUse };
311
26
      Writebacks.push_back(writeback);
312
26
    }
313
314
881k
    bool hasWritebacks() const { return !Writebacks.empty(); }
315
316
    typedef llvm::iterator_range<SmallVectorImpl<Writeback>::const_iterator>
317
      writeback_const_range;
318
319
26
    writeback_const_range writebacks() const {
320
26
      return writeback_const_range(Writebacks.begin(), Writebacks.end());
321
26
    }
322
323
    void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup,
324
171
                                   llvm::Instruction *IsActiveIP) {
325
171
      CallArgCleanup ArgCleanup;
326
171
      ArgCleanup.Cleanup = Cleanup;
327
171
      ArgCleanup.IsActiveIP = IsActiveIP;
328
171
      CleanupsToDeactivate.push_back(ArgCleanup);
329
171
    }
330
331
905k
    ArrayRef<CallArgCleanup> getCleanupsToDeactivate() const {
332
905k
      return CleanupsToDeactivate;
333
905k
    }
334
335
    void allocateArgumentMemory(CodeGenFunction &CGF);
336
67
    llvm::Instruction *getStackBase() const { return StackBase; }
337
    void freeArgumentMemory(CodeGenFunction &CGF) const;
338
339
    /// Returns if we're using an inalloca struct to pass arguments in
340
    /// memory.
341
327
    bool isUsingInAlloca() const { return StackBase; }
342
343
  private:
344
    SmallVector<Writeback, 1> Writebacks;
345
346
    /// Deactivate these cleanups immediately before making the call.  This
347
    /// is used to cleanup objects that are owned by the callee once the call
348
    /// occurs.
349
    SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;
350
351
    /// The stacksave call.  It dominates all of the argument evaluation.
352
    llvm::CallInst *StackBase;
353
  };
354
355
  /// FunctionArgList - Type for representing both the decl and type
356
  /// of parameters to a function. The decl must be either a
357
  /// ParmVarDecl or ImplicitParamDecl.
358
  class FunctionArgList : public SmallVector<const VarDecl*, 16> {
359
  };
360
361
  /// ReturnValueSlot - Contains the address where the return value of a
362
  /// function can be stored, and whether the address is volatile or not.
363
  class ReturnValueSlot {
364
    llvm::PointerIntPair<llvm::Value *, 2, unsigned int> Value;
365
    CharUnits Alignment;
366
367
    // Return value slot flags
368
    enum Flags {
369
      IS_VOLATILE = 0x1,
370
      IS_UNUSED = 0x2,
371
    };
372
373
  public:
374
1.04M
    ReturnValueSlot() {}
375
    ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused = false)
376
      : Value(Addr.isValid() ? Addr.getPointer() : nullptr,
377
              (IsVolatile ? IS_VOLATILE : 0) | (IsUnused ? IS_UNUSED : 0)),
378
19.5k
        Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {}
379
380
8.45k
    bool isNull() const { return !getValue().isValid(); }
381
382
12.1k
    bool isVolatile() const { return Value.getInt() & IS_VOLATILE; }
383
27.8k
    Address getValue() const { return Address(Value.getPointer(), Alignment); }
384
1.68k
    bool isUnused() const { return Value.getInt() & IS_UNUSED; }
385
  };
386
387
}  // end namespace CodeGen
388
}  // end namespace clang
389
390
#endif