Home | History | Annotate | Download | only in CodeGen
      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 LLVM_CLANG_LIB_CODEGEN_CGCALL_H
     16 #define LLVM_CLANG_LIB_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 
     28 namespace llvm {
     29   class AttributeSet;
     30   class Function;
     31   class Type;
     32   class Value;
     33 }
     34 
     35 namespace clang {
     36   class ASTContext;
     37   class Decl;
     38   class FunctionDecl;
     39   class ObjCMethodDecl;
     40   class VarDecl;
     41 
     42 namespace 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     CallArgList() : StackBase(nullptr) {}
     60 
     61     struct Writeback {
     62       /// The original argument.  Note that the argument l-value
     63       /// is potentially null.
     64       LValue Source;
     65 
     66       /// The temporary alloca.
     67       Address Temporary;
     68 
     69       /// A value to "use" after the writeback, or null.
     70       llvm::Value *ToUse;
     71     };
     72 
     73     struct CallArgCleanup {
     74       EHScopeStack::stable_iterator Cleanup;
     75 
     76       /// The "is active" insertion point.  This instruction is temporary and
     77       /// will be removed after insertion.
     78       llvm::Instruction *IsActiveIP;
     79     };
     80 
     81     void add(RValue rvalue, QualType type, bool needscopy = false) {
     82       push_back(CallArg(rvalue, type, needscopy));
     83     }
     84 
     85     void addFrom(const CallArgList &other) {
     86       insert(end(), other.begin(), other.end());
     87       Writebacks.insert(Writebacks.end(),
     88                         other.Writebacks.begin(), other.Writebacks.end());
     89     }
     90 
     91     void addWriteback(LValue srcLV, Address temporary,
     92                       llvm::Value *toUse) {
     93       Writeback writeback = { srcLV, temporary, toUse };
     94       Writebacks.push_back(writeback);
     95     }
     96 
     97     bool hasWritebacks() const { return !Writebacks.empty(); }
     98 
     99     typedef llvm::iterator_range<SmallVectorImpl<Writeback>::const_iterator>
    100       writeback_const_range;
    101 
    102     writeback_const_range writebacks() const {
    103       return writeback_const_range(Writebacks.begin(), Writebacks.end());
    104     }
    105 
    106     void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup,
    107                                    llvm::Instruction *IsActiveIP) {
    108       CallArgCleanup ArgCleanup;
    109       ArgCleanup.Cleanup = Cleanup;
    110       ArgCleanup.IsActiveIP = IsActiveIP;
    111       CleanupsToDeactivate.push_back(ArgCleanup);
    112     }
    113 
    114     ArrayRef<CallArgCleanup> getCleanupsToDeactivate() const {
    115       return CleanupsToDeactivate;
    116     }
    117 
    118     void allocateArgumentMemory(CodeGenFunction &CGF);
    119     llvm::Instruction *getStackBase() const { return StackBase; }
    120     void freeArgumentMemory(CodeGenFunction &CGF) const;
    121 
    122     /// \brief Returns if we're using an inalloca struct to pass arguments in
    123     /// memory.
    124     bool isUsingInAlloca() const { return StackBase; }
    125 
    126   private:
    127     SmallVector<Writeback, 1> Writebacks;
    128 
    129     /// Deactivate these cleanups immediately before making the call.  This
    130     /// is used to cleanup objects that are owned by the callee once the call
    131     /// occurs.
    132     SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;
    133 
    134     /// The stacksave call.  It dominates all of the argument evaluation.
    135     llvm::CallInst *StackBase;
    136 
    137     /// The iterator pointing to the stack restore cleanup.  We manually run and
    138     /// deactivate this cleanup after the call in the unexceptional case because
    139     /// it doesn't run in the normal order.
    140     EHScopeStack::stable_iterator StackCleanup;
    141   };
    142 
    143   /// FunctionArgList - Type for representing both the decl and type
    144   /// of parameters to a function. The decl must be either a
    145   /// ParmVarDecl or ImplicitParamDecl.
    146   class FunctionArgList : public SmallVector<const VarDecl*, 16> {
    147   };
    148 
    149   /// ReturnValueSlot - Contains the address where the return value of a
    150   /// function can be stored, and whether the address is volatile or not.
    151   class ReturnValueSlot {
    152     llvm::PointerIntPair<llvm::Value *, 2, unsigned int> Value;
    153     CharUnits Alignment;
    154 
    155     // Return value slot flags
    156     enum Flags {
    157       IS_VOLATILE = 0x1,
    158       IS_UNUSED = 0x2,
    159     };
    160 
    161   public:
    162     ReturnValueSlot() {}
    163     ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused = false)
    164       : Value(Addr.isValid() ? Addr.getPointer() : nullptr,
    165               (IsVolatile ? IS_VOLATILE : 0) | (IsUnused ? IS_UNUSED : 0)),
    166         Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {}
    167 
    168     bool isNull() const { return !getValue().isValid(); }
    169 
    170     bool isVolatile() const { return Value.getInt() & IS_VOLATILE; }
    171     Address getValue() const { return Address(Value.getPointer(), Alignment); }
    172     bool isUnused() const { return Value.getInt() & IS_UNUSED; }
    173   };
    174 
    175 }  // end namespace CodeGen
    176 }  // end namespace clang
    177 
    178 #endif
    179