#ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H
#define LLVM_CLANG_LIB_CODEGEN_CGCALL_H
#include "CGValue.h"
#include "EHScopeStack.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/IR/Value.h"
#include "ABIInfo.h"
namespace llvm {
class AttributeSet;
class Function;
class Type;
class Value;
}
namespace clang {
class ASTContext;
class Decl;
class FunctionDecl;
class ObjCMethodDecl;
class VarDecl;
namespace CodeGen {
typedef SmallVector<llvm::AttributeSet, 8> AttributeListType;
struct CallArg {
RValue RV;
QualType Ty;
bool NeedsCopy;
CallArg(RValue rv, QualType ty, bool needscopy)
: RV(rv), Ty(ty), NeedsCopy(needscopy)
{ }
};
class CallArgList :
public SmallVector<CallArg, 16> {
public:
CallArgList() : StackBase(nullptr) {}
struct Writeback {
LValue Source;
Address Temporary;
llvm::Value *ToUse;
};
struct CallArgCleanup {
EHScopeStack::stable_iterator Cleanup;
llvm::Instruction *IsActiveIP;
};
void add(RValue rvalue, QualType type, bool needscopy = false) {
push_back(CallArg(rvalue, type, needscopy));
}
void addFrom(const CallArgList &other) {
insert(end(), other.begin(), other.end());
Writebacks.insert(Writebacks.end(),
other.Writebacks.begin(), other.Writebacks.end());
}
void addWriteback(LValue srcLV, Address temporary,
llvm::Value *toUse) {
Writeback writeback = { srcLV, temporary, toUse };
Writebacks.push_back(writeback);
}
bool hasWritebacks() const { return !Writebacks.empty(); }
typedef llvm::iterator_range<SmallVectorImpl<Writeback>::const_iterator>
writeback_const_range;
writeback_const_range writebacks() const {
return writeback_const_range(Writebacks.begin(), Writebacks.end());
}
void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup,
llvm::Instruction *IsActiveIP) {
CallArgCleanup ArgCleanup;
ArgCleanup.Cleanup = Cleanup;
ArgCleanup.IsActiveIP = IsActiveIP;
CleanupsToDeactivate.push_back(ArgCleanup);
}
ArrayRef<CallArgCleanup> getCleanupsToDeactivate() const {
return CleanupsToDeactivate;
}
void allocateArgumentMemory(CodeGenFunction &CGF);
llvm::Instruction *getStackBase() const { return StackBase; }
void freeArgumentMemory(CodeGenFunction &CGF) const;
bool isUsingInAlloca() const { return StackBase; }
private:
SmallVector<Writeback, 1> Writebacks;
SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;
llvm::CallInst *StackBase;
EHScopeStack::stable_iterator StackCleanup;
};
class FunctionArgList : public SmallVector<const VarDecl*, 16> {
};
class ReturnValueSlot {
llvm::PointerIntPair<llvm::Value *, 2, unsigned int> Value;
CharUnits Alignment;
enum Flags {
IS_VOLATILE = 0x1,
IS_UNUSED = 0x2,
};
public:
ReturnValueSlot() {}
ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused = false)
: Value(Addr.isValid() ? Addr.getPointer() : nullptr,
(IsVolatile ? IS_VOLATILE : 0) | (IsUnused ? IS_UNUSED : 0)),
Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {}
bool isNull() const { return !getValue().isValid(); }
bool isVolatile() const { return Value.getInt() & IS_VOLATILE; }
Address getValue() const { return Address(Value.getPointer(), Alignment); }
bool isUnused() const { return Value.getInt() & IS_UNUSED; }
};
} }
#endif