1a7dea167SDimitry Andric //===--- Source.h - Source location provider for the VM --------*- C++ -*-===// 2a7dea167SDimitry Andric // 3a7dea167SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a7dea167SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5a7dea167SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a7dea167SDimitry Andric // 7a7dea167SDimitry Andric //===----------------------------------------------------------------------===// 8a7dea167SDimitry Andric // 9a7dea167SDimitry Andric // Defines a program which organises and links multiple bytecode functions. 10a7dea167SDimitry Andric // 11a7dea167SDimitry Andric //===----------------------------------------------------------------------===// 12a7dea167SDimitry Andric 13a7dea167SDimitry Andric #ifndef LLVM_CLANG_AST_INTERP_SOURCE_H 14a7dea167SDimitry Andric #define LLVM_CLANG_AST_INTERP_SOURCE_H 15a7dea167SDimitry Andric 16*bdd1243dSDimitry Andric #include "PrimType.h" 17a7dea167SDimitry Andric #include "clang/AST/Decl.h" 18a7dea167SDimitry Andric #include "clang/AST/Stmt.h" 19a7dea167SDimitry Andric #include "llvm/Support/Endian.h" 20a7dea167SDimitry Andric 21a7dea167SDimitry Andric namespace clang { 22a7dea167SDimitry Andric namespace interp { 23a7dea167SDimitry Andric class Function; 24a7dea167SDimitry Andric 25a7dea167SDimitry Andric /// Pointer into the code segment. 26*bdd1243dSDimitry Andric class CodePtr final { 27a7dea167SDimitry Andric public: 28a7dea167SDimitry Andric CodePtr() : Ptr(nullptr) {} 29a7dea167SDimitry Andric 30a7dea167SDimitry Andric CodePtr &operator+=(int32_t Offset) { 31a7dea167SDimitry Andric Ptr += Offset; 32a7dea167SDimitry Andric return *this; 33a7dea167SDimitry Andric } 34a7dea167SDimitry Andric 35a7dea167SDimitry Andric int32_t operator-(const CodePtr &RHS) const { 36a7dea167SDimitry Andric assert(Ptr != nullptr && RHS.Ptr != nullptr && "Invalid code pointer"); 37a7dea167SDimitry Andric return Ptr - RHS.Ptr; 38a7dea167SDimitry Andric } 39a7dea167SDimitry Andric 40a7dea167SDimitry Andric CodePtr operator-(size_t RHS) const { 41a7dea167SDimitry Andric assert(Ptr != nullptr && "Invalid code pointer"); 42a7dea167SDimitry Andric return CodePtr(Ptr - RHS); 43a7dea167SDimitry Andric } 44a7dea167SDimitry Andric 45a7dea167SDimitry Andric bool operator!=(const CodePtr &RHS) const { return Ptr != RHS.Ptr; } 46a7dea167SDimitry Andric 47*bdd1243dSDimitry Andric operator bool() const { return Ptr; } 48*bdd1243dSDimitry Andric 49a7dea167SDimitry Andric /// Reads data and advances the pointer. 50349cc55cSDimitry Andric template <typename T> std::enable_if_t<!std::is_pointer<T>::value, T> read() { 51*bdd1243dSDimitry Andric assert(aligned(Ptr)); 52349cc55cSDimitry Andric using namespace llvm::support; 53349cc55cSDimitry Andric T Value = endian::read<T, endianness::native, 1>(Ptr); 54*bdd1243dSDimitry Andric Ptr += align(sizeof(T)); 55a7dea167SDimitry Andric return Value; 56a7dea167SDimitry Andric } 57a7dea167SDimitry Andric 58a7dea167SDimitry Andric private: 59a7dea167SDimitry Andric /// Constructor used by Function to generate pointers. 60a7dea167SDimitry Andric CodePtr(const char *Ptr) : Ptr(Ptr) {} 61a7dea167SDimitry Andric 62a7dea167SDimitry Andric private: 63a7dea167SDimitry Andric friend class Function; 64a7dea167SDimitry Andric 65a7dea167SDimitry Andric /// Pointer into the code owned by a function. 66a7dea167SDimitry Andric const char *Ptr; 67a7dea167SDimitry Andric }; 68a7dea167SDimitry Andric 69a7dea167SDimitry Andric /// Describes the statement/declaration an opcode was generated from. 70*bdd1243dSDimitry Andric class SourceInfo final { 71a7dea167SDimitry Andric public: 72a7dea167SDimitry Andric SourceInfo() {} 73a7dea167SDimitry Andric SourceInfo(const Stmt *E) : Source(E) {} 74a7dea167SDimitry Andric SourceInfo(const Decl *D) : Source(D) {} 75a7dea167SDimitry Andric 76a7dea167SDimitry Andric SourceLocation getLoc() const; 77a7dea167SDimitry Andric 78a7dea167SDimitry Andric const Stmt *asStmt() const { return Source.dyn_cast<const Stmt *>(); } 79a7dea167SDimitry Andric const Decl *asDecl() const { return Source.dyn_cast<const Decl *>(); } 80a7dea167SDimitry Andric const Expr *asExpr() const; 81a7dea167SDimitry Andric 82a7dea167SDimitry Andric operator bool() const { return !Source.isNull(); } 83a7dea167SDimitry Andric 84a7dea167SDimitry Andric private: 85a7dea167SDimitry Andric llvm::PointerUnion<const Decl *, const Stmt *> Source; 86a7dea167SDimitry Andric }; 87a7dea167SDimitry Andric 88a7dea167SDimitry Andric using SourceMap = std::vector<std::pair<unsigned, SourceInfo>>; 89a7dea167SDimitry Andric 90a7dea167SDimitry Andric /// Interface for classes which map locations to sources. 91a7dea167SDimitry Andric class SourceMapper { 92a7dea167SDimitry Andric public: 93a7dea167SDimitry Andric virtual ~SourceMapper() {} 94a7dea167SDimitry Andric 95a7dea167SDimitry Andric /// Returns source information for a given PC in a function. 96*bdd1243dSDimitry Andric virtual SourceInfo getSource(const Function *F, CodePtr PC) const = 0; 97a7dea167SDimitry Andric 98a7dea167SDimitry Andric /// Returns the expression if an opcode belongs to one, null otherwise. 99*bdd1243dSDimitry Andric const Expr *getExpr(const Function *F, CodePtr PC) const; 100a7dea167SDimitry Andric /// Returns the location from which an opcode originates. 101*bdd1243dSDimitry Andric SourceLocation getLocation(const Function *F, CodePtr PC) const; 102a7dea167SDimitry Andric }; 103a7dea167SDimitry Andric 104a7dea167SDimitry Andric } // namespace interp 105a7dea167SDimitry Andric } // namespace clang 106a7dea167SDimitry Andric 107a7dea167SDimitry Andric #endif 108