diff options
Diffstat (limited to 'gnu/llvm/tools/clang/lib/CodeGen/CGCall.h')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/CodeGen/CGCall.h | 118 |
1 files changed, 99 insertions, 19 deletions
diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGCall.h b/gnu/llvm/tools/clang/lib/CodeGen/CGCall.h index 7e10407fc31..99a36e4e12f 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGCall.h +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGCall.h @@ -18,6 +18,7 @@ #include "CGValue.h" #include "EHScopeStack.h" #include "clang/AST/CanonicalType.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/Type.h" #include "llvm/IR/Value.h" @@ -42,9 +43,9 @@ namespace CodeGen { /// Abstract information about a function or function prototype. class CGCalleeInfo { - /// \brief The function prototype of the callee. + /// The function prototype of the callee. const FunctionProtoType *CalleeProtoTy; - /// \brief The function declaration of the callee. + /// The function declaration of the callee. const Decl *CalleeDecl; public: @@ -68,8 +69,9 @@ public: Invalid, Builtin, PseudoDestructor, + Virtual, - Last = PseudoDestructor + Last = Virtual }; struct BuiltinInfoStorage { @@ -79,12 +81,19 @@ public: struct PseudoDestructorInfoStorage { const CXXPseudoDestructorExpr *Expr; }; + struct VirtualInfoStorage { + const CallExpr *CE; + GlobalDecl MD; + Address Addr; + llvm::FunctionType *FTy; + }; SpecialKind KindOrFunctionPointer; union { CGCalleeInfo AbstractInfo; BuiltinInfoStorage BuiltinInfo; PseudoDestructorInfoStorage PseudoDestructorInfo; + VirtualInfoStorage VirtualInfo; }; explicit CGCallee(SpecialKind kind) : KindOrFunctionPointer(kind) {} @@ -127,6 +136,16 @@ public: return CGCallee(abstractInfo, functionPtr); } + static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, + llvm::FunctionType *FTy) { + CGCallee result(SpecialKind::Virtual); + result.VirtualInfo.CE = CE; + result.VirtualInfo.MD = MD; + result.VirtualInfo.Addr = Addr; + result.VirtualInfo.FTy = FTy; + return result; + } + bool isBuiltin() const { return KindOrFunctionPointer == SpecialKind::Builtin; } @@ -150,7 +169,9 @@ public: bool isOrdinary() const { return uintptr_t(KindOrFunctionPointer) > uintptr_t(SpecialKind::Last); } - const CGCalleeInfo &getAbstractInfo() const { + CGCalleeInfo getAbstractInfo() const { + if (isVirtual()) + return VirtualInfo.MD.getDecl(); assert(isOrdinary()); return AbstractInfo; } @@ -158,29 +179,86 @@ public: assert(isOrdinary()); return reinterpret_cast<llvm::Value*>(uintptr_t(KindOrFunctionPointer)); } - llvm::FunctionType *getFunctionType() const { - return cast<llvm::FunctionType>( - getFunctionPointer()->getType()->getPointerElementType()); - } void setFunctionPointer(llvm::Value *functionPtr) { assert(isOrdinary()); KindOrFunctionPointer = SpecialKind(uintptr_t(functionPtr)); } + + bool isVirtual() const { + return KindOrFunctionPointer == SpecialKind::Virtual; + } + const CallExpr *getVirtualCallExpr() const { + assert(isVirtual()); + return VirtualInfo.CE; + } + GlobalDecl getVirtualMethodDecl() const { + assert(isVirtual()); + return VirtualInfo.MD; + } + Address getThisAddress() const { + assert(isVirtual()); + return VirtualInfo.Addr; + } + + llvm::FunctionType *getFunctionType() const { + if (isVirtual()) + return VirtualInfo.FTy; + return cast<llvm::FunctionType>( + getFunctionPointer()->getType()->getPointerElementType()); + } + + /// If this is a delayed callee computation of some sort, prepare + /// a concrete callee. + CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const; }; struct CallArg { - RValue RV; + private: + union { + RValue RV; + LValue LV; /// The argument is semantically a load from this l-value. + }; + bool HasLV; + + /// A data-flow flag to make sure getRValue and/or copyInto are not + /// called twice for duplicated IR emission. + mutable bool IsUsed; + + public: QualType Ty; - bool NeedsCopy; - CallArg(RValue rv, QualType ty, bool needscopy) - : RV(rv), Ty(ty), NeedsCopy(needscopy) - { } + CallArg(RValue rv, QualType ty) + : RV(rv), HasLV(false), IsUsed(false), Ty(ty) {} + CallArg(LValue lv, QualType ty) + : LV(lv), HasLV(true), IsUsed(false), Ty(ty) {} + bool hasLValue() const { return HasLV; } + QualType getType() const { return Ty; } + + /// \returns an independent RValue. If the CallArg contains an LValue, + /// a temporary copy is returned. + RValue getRValue(CodeGenFunction &CGF) const; + + LValue getKnownLValue() const { + assert(HasLV && !IsUsed); + return LV; + } + RValue getKnownRValue() const { + assert(!HasLV && !IsUsed); + return RV; + } + void setRValue(RValue _RV) { + assert(!HasLV); + RV = _RV; + } + + bool isAggregate() const { return HasLV || RV.isAggregate(); } + + void copyInto(CodeGenFunction &CGF, Address A) const; }; /// CallArgList - Type for representing both the value and type of /// arguments in a call. class CallArgList : - public SmallVector<CallArg, 16> { + public SmallVector<CallArg, 8> { public: CallArgList() : StackBase(nullptr) {} @@ -204,8 +282,10 @@ public: llvm::Instruction *IsActiveIP; }; - void add(RValue rvalue, QualType type, bool needscopy = false) { - push_back(CallArg(rvalue, type, needscopy)); + void add(RValue rvalue, QualType type) { push_back(CallArg(rvalue, type)); } + + void addUncopiedAggregate(LValue LV, QualType type) { + push_back(CallArg(LV, type)); } /// Add all the arguments from another CallArgList to this one. After doing @@ -254,7 +334,7 @@ public: llvm::Instruction *getStackBase() const { return StackBase; } void freeArgumentMemory(CodeGenFunction &CGF) const; - /// \brief Returns if we're using an inalloca struct to pass arguments in + /// Returns if we're using an inalloca struct to pass arguments in /// memory. bool isUsingInAlloca() const { return StackBase; } @@ -276,7 +356,7 @@ public: class FunctionArgList : public SmallVector<const VarDecl*, 16> { }; - /// ReturnValueSlot - Contains the address where the return value of a + /// ReturnValueSlot - Contains the address where the return value of a /// function can be stored, and whether the address is volatile or not. class ReturnValueSlot { llvm::PointerIntPair<llvm::Value *, 2, unsigned int> Value; @@ -301,7 +381,7 @@ public: Address getValue() const { return Address(Value.getPointer(), Alignment); } bool isUnused() const { return Value.getInt() & IS_UNUSED; } }; - + } // end namespace CodeGen } // end namespace clang |
