forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			164 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--- Function.h - Bytecode function for the VM --------------*- C++ -*-===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // Defines the Function class which holds all bytecode function-specific data.
 | |
| //
 | |
| // The scope class which describes local variables is also defined here.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_CLANG_AST_INTERP_FUNCTION_H
 | |
| #define LLVM_CLANG_AST_INTERP_FUNCTION_H
 | |
| 
 | |
| #include "Pointer.h"
 | |
| #include "Source.h"
 | |
| #include "clang/AST/Decl.h"
 | |
| #include "llvm/Support/raw_ostream.h"
 | |
| 
 | |
| namespace clang {
 | |
| namespace interp {
 | |
| class Program;
 | |
| class ByteCodeEmitter;
 | |
| enum PrimType : uint32_t;
 | |
| 
 | |
| /// Describes a scope block.
 | |
| ///
 | |
| /// The block gathers all the descriptors of the locals defined in this block.
 | |
| class Scope {
 | |
| public:
 | |
|   /// Information about a local's storage.
 | |
|   struct Local {
 | |
|     /// Offset of the local in frame.
 | |
|     unsigned Offset;
 | |
|     /// Descriptor of the local.
 | |
|     Descriptor *Desc;
 | |
|   };
 | |
| 
 | |
|   using LocalVectorTy = llvm::SmallVector<Local, 8>;
 | |
| 
 | |
|   Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {}
 | |
| 
 | |
|   llvm::iterator_range<LocalVectorTy::iterator> locals() {
 | |
|     return llvm::make_range(Descriptors.begin(), Descriptors.end());
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   /// Object descriptors in this block.
 | |
|   LocalVectorTy Descriptors;
 | |
| };
 | |
| 
 | |
| /// Bytecode function.
 | |
| ///
 | |
| /// Contains links to the bytecode of the function, as well as metadata
 | |
| /// describing all arguments and stack-local variables.
 | |
| class Function {
 | |
| 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
 | |
|   unsigned getArgSize() const { return ArgSize; }
 | |
| 
 | |
|   /// Returns a pointer to the start of the code.
 | |
|   CodePtr getCodeBegin() const;
 | |
|   /// Returns a pointer to the end of the code.
 | |
|   CodePtr getCodeEnd() const;
 | |
| 
 | |
|   /// Returns the original FunctionDecl.
 | |
|   const FunctionDecl *getDecl() const { return F; }
 | |
| 
 | |
|   /// Returns the lcoation.
 | |
|   SourceLocation getLoc() const { return Loc; }
 | |
| 
 | |
|   /// Returns a parameter descriptor.
 | |
|   ParamDescriptor getParamDescriptor(unsigned Offset) const;
 | |
| 
 | |
|   /// Checks if the first argument is a RVO pointer.
 | |
|   bool hasRVO() const { return ParamTypes.size() != Params.size(); }
 | |
| 
 | |
|   /// Range over the scope blocks.
 | |
|   llvm::iterator_range<llvm::SmallVector<Scope, 2>::iterator> scopes() {
 | |
|     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());
 | |
|   }
 | |
| 
 | |
|   /// Returns a specific scope.
 | |
|   Scope &getScope(unsigned Idx) { return Scopes[Idx]; }
 | |
| 
 | |
|   /// Returns the source information at a given PC.
 | |
|   SourceInfo getSource(CodePtr PC) const;
 | |
| 
 | |
|   /// Checks if the function is valid to call in constexpr.
 | |
|   bool isConstexpr() const { return IsValid; }
 | |
| 
 | |
|   /// Checks if the function is virtual.
 | |
|   bool isVirtual() const;
 | |
| 
 | |
|   /// Checks if the function is a constructor.
 | |
|   bool isConstructor() const { return isa<CXXConstructorDecl>(F); }
 | |
| 
 | |
| 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);
 | |
| 
 | |
|   /// Sets the code of a function.
 | |
|   void setCode(unsigned NewFrameSize, std::vector<char> &&NewCode, SourceMap &&NewSrcMap,
 | |
|                llvm::SmallVector<Scope, 2> &&NewScopes) {
 | |
|     FrameSize = NewFrameSize;
 | |
|     Code = std::move(NewCode);
 | |
|     SrcMap = std::move(NewSrcMap);
 | |
|     Scopes = std::move(NewScopes);
 | |
|     IsValid = true;
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   friend class Program;
 | |
|   friend class ByteCodeEmitter;
 | |
| 
 | |
|   /// Program reference.
 | |
|   Program &P;
 | |
|   /// Location of the executed code.
 | |
|   SourceLocation Loc;
 | |
|   /// Declaration this function was compiled from.
 | |
|   const FunctionDecl *F;
 | |
|   /// Local area size: storage + metadata.
 | |
|   unsigned FrameSize;
 | |
|   /// Size of the argument stack.
 | |
|   unsigned ArgSize;
 | |
|   /// Program code.
 | |
|   std::vector<char> Code;
 | |
|   /// Opcode-to-expression mapping.
 | |
|   SourceMap SrcMap;
 | |
|   /// List of block descriptors.
 | |
|   llvm::SmallVector<Scope, 2> Scopes;
 | |
|   /// List of argument types.
 | |
|   llvm::SmallVector<PrimType, 8> ParamTypes;
 | |
|   /// Map from byte offset to parameter descriptor.
 | |
|   llvm::DenseMap<unsigned, ParamDescriptor> Params;
 | |
|   /// Flag to indicate if the function is valid.
 | |
|   bool IsValid = false;
 | |
| 
 | |
| public:
 | |
|   /// Dumps the disassembled bytecode to \c llvm::errs().
 | |
|   void dump() const;
 | |
|   void dump(llvm::raw_ostream &OS) const;
 | |
| };
 | |
| 
 | |
| } // namespace interp
 | |
| } // namespace clang
 | |
| 
 | |
| #endif
 |