1 //===--- Function.h - Bytecode function for the VM --------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Defines the Function class which holds all bytecode function-specific data. 10 // 11 // The scope class which describes local variables is also defined here. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_AST_INTERP_FUNCTION_H 16 #define LLVM_CLANG_AST_INTERP_FUNCTION_H 17 18 #include "Pointer.h" 19 #include "Source.h" 20 #include "clang/AST/Decl.h" 21 #include "llvm/Support/raw_ostream.h" 22 23 namespace clang { 24 namespace interp { 25 class Program; 26 class ByteCodeEmitter; 27 enum PrimType : uint32_t; 28 29 /// Describes a scope block. 30 /// 31 /// The block gathers all the descriptors of the locals defined in this block. 32 class Scope { 33 public: 34 /// Information about a local's storage. 35 struct Local { 36 /// Offset of the local in frame. 37 unsigned Offset; 38 /// Descriptor of the local. 39 Descriptor *Desc; 40 }; 41 42 using LocalVectorTy = llvm::SmallVector<Local, 8>; 43 44 Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {} 45 46 llvm::iterator_range<LocalVectorTy::iterator> locals() { 47 return llvm::make_range(Descriptors.begin(), Descriptors.end()); 48 } 49 50 private: 51 /// Object descriptors in this block. 52 LocalVectorTy Descriptors; 53 }; 54 55 /// Bytecode function. 56 /// 57 /// Contains links to the bytecode of the function, as well as metadata 58 /// describing all arguments and stack-local variables. 59 class Function { 60 public: 61 using ParamDescriptor = std::pair<PrimType, Descriptor *>; 62 63 /// Returns the size of the function's local stack. 64 unsigned getFrameSize() const { return FrameSize; } 65 /// Returns the size of the argument stackx 66 unsigned getArgSize() const { return ArgSize; } 67 68 /// Returns a pointer to the start of the code. 69 CodePtr getCodeBegin() const; 70 /// Returns a pointer to the end of the code. 71 CodePtr getCodeEnd() const; 72 73 /// Returns the original FunctionDecl. 74 const FunctionDecl *getDecl() const { return F; } 75 76 /// Returns the lcoation. 77 SourceLocation getLoc() const { return Loc; } 78 79 /// Returns a parameter descriptor. 80 ParamDescriptor getParamDescriptor(unsigned Offset) const; 81 82 /// Checks if the first argument is a RVO pointer. 83 bool hasRVO() const { return ParamTypes.size() != Params.size(); } 84 85 /// Range over the scope blocks. 86 llvm::iterator_range<llvm::SmallVector<Scope, 2>::iterator> scopes() { 87 return llvm::make_range(Scopes.begin(), Scopes.end()); 88 } 89 90 /// Range over argument types. 91 using arg_reverse_iterator = SmallVectorImpl<PrimType>::reverse_iterator; 92 llvm::iterator_range<arg_reverse_iterator> args_reverse() { 93 return llvm::make_range(ParamTypes.rbegin(), ParamTypes.rend()); 94 } 95 96 /// Returns a specific scope. 97 Scope &getScope(unsigned Idx) { return Scopes[Idx]; } 98 99 /// Returns the source information at a given PC. 100 SourceInfo getSource(CodePtr PC) const; 101 102 /// Checks if the function is valid to call in constexpr. 103 bool isConstexpr() const { return IsValid; } 104 105 /// Checks if the function is virtual. 106 bool isVirtual() const; 107 108 /// Checks if the function is a constructor. 109 bool isConstructor() const { return isa<CXXConstructorDecl>(F); } 110 111 private: 112 /// Construct a function representing an actual function. 113 Function(Program &P, const FunctionDecl *F, unsigned ArgSize, 114 llvm::SmallVector<PrimType, 8> &&ParamTypes, 115 llvm::DenseMap<unsigned, ParamDescriptor> &&Params); 116 117 /// Sets the code of a function. 118 void setCode(unsigned NewFrameSize, std::vector<char> &&NewCode, SourceMap &&NewSrcMap, 119 llvm::SmallVector<Scope, 2> &&NewScopes) { 120 FrameSize = NewFrameSize; 121 Code = std::move(NewCode); 122 SrcMap = std::move(NewSrcMap); 123 Scopes = std::move(NewScopes); 124 IsValid = true; 125 } 126 127 private: 128 friend class Program; 129 friend class ByteCodeEmitter; 130 131 /// Program reference. 132 Program &P; 133 /// Location of the executed code. 134 SourceLocation Loc; 135 /// Declaration this function was compiled from. 136 const FunctionDecl *F; 137 /// Local area size: storage + metadata. 138 unsigned FrameSize; 139 /// Size of the argument stack. 140 unsigned ArgSize; 141 /// Program code. 142 std::vector<char> Code; 143 /// Opcode-to-expression mapping. 144 SourceMap SrcMap; 145 /// List of block descriptors. 146 llvm::SmallVector<Scope, 2> Scopes; 147 /// List of argument types. 148 llvm::SmallVector<PrimType, 8> ParamTypes; 149 /// Map from byte offset to parameter descriptor. 150 llvm::DenseMap<unsigned, ParamDescriptor> Params; 151 /// Flag to indicate if the function is valid. 152 bool IsValid = false; 153 154 public: 155 /// Dumps the disassembled bytecode to \c llvm::errs(). 156 void dump() const; 157 void dump(llvm::raw_ostream &OS) const; 158 }; 159 160 } // namespace interp 161 } // namespace clang 162 163 #endif 164