diff options
Diffstat (limited to 'clang/lib/AST/Interp/Function.h')
-rw-r--r-- | clang/lib/AST/Interp/Function.h | 74 |
1 files changed, 61 insertions, 13 deletions
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h index ac1dffea1160..5b2a77f1a12d 100644 --- a/clang/lib/AST/Interp/Function.h +++ b/clang/lib/AST/Interp/Function.h @@ -29,7 +29,7 @@ enum PrimType : uint32_t; /// Describes a scope block. /// /// The block gathers all the descriptors of the locals defined in this block. -class Scope { +class Scope final { public: /// Information about a local's storage. struct Local { @@ -43,7 +43,7 @@ public: Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {} - llvm::iterator_range<LocalVectorTy::iterator> locals() { + llvm::iterator_range<LocalVectorTy::const_iterator> locals() const { return llvm::make_range(Descriptors.begin(), Descriptors.end()); } @@ -56,23 +56,42 @@ private: /// /// Contains links to the bytecode of the function, as well as metadata /// describing all arguments and stack-local variables. -class Function { +/// +/// # Calling Convention +/// +/// When calling a function, all argument values must be on the stack. +/// +/// If the function has a This pointer (i.e. hasThisPointer() returns true, +/// the argument values need to be preceeded by a Pointer for the This object. +/// +/// If the function uses Return Value Optimization, the arguments (and +/// potentially the This pointer) need to be proceeded by a Pointer pointing +/// to the location to construct the returned value. +/// +/// After the function has been called, it will remove all arguments, +/// including RVO and This pointer, from the stack. +/// +class Function final { public: using ParamDescriptor = std::pair<PrimType, Descriptor *>; /// Returns the size of the function's local stack. unsigned getFrameSize() const { return FrameSize; } - /// Returns the size of the argument stackx + /// Returns the size of the argument stack. unsigned getArgSize() const { return ArgSize; } /// Returns a pointer to the start of the code. - CodePtr getCodeBegin() const; + CodePtr getCodeBegin() const { return Code.data(); } /// Returns a pointer to the end of the code. - CodePtr getCodeEnd() const; + CodePtr getCodeEnd() const { return Code.data() + Code.size(); } /// Returns the original FunctionDecl. const FunctionDecl *getDecl() const { return F; } + /// Returns the name of the function decl this code + /// was generated for. + const std::string getName() const { return F->getNameInfo().getAsString(); } + /// Returns the location. SourceLocation getLoc() const { return Loc; } @@ -80,21 +99,24 @@ public: ParamDescriptor getParamDescriptor(unsigned Offset) const; /// Checks if the first argument is a RVO pointer. - bool hasRVO() const { return ParamTypes.size() != Params.size(); } + bool hasRVO() const { return HasRVO; } /// Range over the scope blocks. - llvm::iterator_range<llvm::SmallVector<Scope, 2>::iterator> scopes() { + llvm::iterator_range<llvm::SmallVector<Scope, 2>::const_iterator> + scopes() const { return llvm::make_range(Scopes.begin(), Scopes.end()); } /// Range over argument types. - using arg_reverse_iterator = SmallVectorImpl<PrimType>::reverse_iterator; - llvm::iterator_range<arg_reverse_iterator> args_reverse() { - return llvm::make_range(ParamTypes.rbegin(), ParamTypes.rend()); + using arg_reverse_iterator = + SmallVectorImpl<PrimType>::const_reverse_iterator; + llvm::iterator_range<arg_reverse_iterator> args_reverse() const { + return llvm::reverse(ParamTypes); } /// Returns a specific scope. Scope &getScope(unsigned Idx) { return Scopes[Idx]; } + const Scope &getScope(unsigned Idx) const { return Scopes[Idx]; } /// Returns the source information at a given PC. SourceInfo getSource(CodePtr PC) const; @@ -108,11 +130,22 @@ public: /// Checks if the function is a constructor. bool isConstructor() const { return isa<CXXConstructorDecl>(F); } + /// Checks if the function is fully done compiling. + bool isFullyCompiled() const { return IsFullyCompiled; } + + bool hasThisPointer() const { return HasThisPointer; } + + // Checks if the funtion already has a body attached. + bool hasBody() const { return HasBody; } + + unsigned getNumParams() const { return ParamTypes.size(); } + private: /// Construct a function representing an actual function. Function(Program &P, const FunctionDecl *F, unsigned ArgSize, llvm::SmallVector<PrimType, 8> &&ParamTypes, - llvm::DenseMap<unsigned, ParamDescriptor> &&Params); + llvm::DenseMap<unsigned, ParamDescriptor> &&Params, + bool HasThisPointer, bool HasRVO); /// Sets the code of a function. void setCode(unsigned NewFrameSize, std::vector<char> &&NewCode, SourceMap &&NewSrcMap, @@ -122,8 +155,11 @@ private: SrcMap = std::move(NewSrcMap); Scopes = std::move(NewScopes); IsValid = true; + HasBody = true; } + void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; } + private: friend class Program; friend class ByteCodeEmitter; @@ -135,7 +171,7 @@ private: /// Declaration this function was compiled from. const FunctionDecl *F; /// Local area size: storage + metadata. - unsigned FrameSize; + unsigned FrameSize = 0; /// Size of the argument stack. unsigned ArgSize; /// Program code. @@ -150,6 +186,18 @@ private: llvm::DenseMap<unsigned, ParamDescriptor> Params; /// Flag to indicate if the function is valid. bool IsValid = false; + /// Flag to indicate if the function is done being + /// compiled to bytecode. + bool IsFullyCompiled = false; + /// Flag indicating if this function takes the this pointer + /// as the first implicit argument + bool HasThisPointer = false; + /// Whether this function has Return Value Optimization, i.e. + /// the return value is constructed in the caller's stack frame. + /// This is done for functions that return non-primive values. + bool HasRVO = false; + /// If we've already compiled the function's body. + bool HasBody = false; public: /// Dumps the disassembled bytecode to \c llvm::errs(). |