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 16bdd1243dSDimitry 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. 26bdd1243dSDimitry 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 47bdd1243dSDimitry Andric operator bool() const { return Ptr; } 48bdd1243dSDimitry 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() { 51bdd1243dSDimitry Andric assert(aligned(Ptr)); 52349cc55cSDimitry Andric using namespace llvm::support; 53349cc55cSDimitry Andric T Value = endian::read<T, endianness::native, 1>(Ptr); 54bdd1243dSDimitry Andric Ptr += align(sizeof(T)); 55a7dea167SDimitry Andric return Value; 56a7dea167SDimitry Andric } 57a7dea167SDimitry Andric 58a7dea167SDimitry Andric private: 59a7dea167SDimitry Andric friend class Function; 60*06c3fb27SDimitry Andric /// Constructor used by Function to generate pointers. 61*06c3fb27SDimitry Andric CodePtr(const std::byte *Ptr) : Ptr(Ptr) {} 62a7dea167SDimitry Andric /// Pointer into the code owned by a function. 63*06c3fb27SDimitry Andric const std::byte *Ptr; 64a7dea167SDimitry Andric }; 65a7dea167SDimitry Andric 66a7dea167SDimitry Andric /// Describes the statement/declaration an opcode was generated from. 67bdd1243dSDimitry Andric class SourceInfo final { 68a7dea167SDimitry Andric public: 69a7dea167SDimitry Andric SourceInfo() {} 70a7dea167SDimitry Andric SourceInfo(const Stmt *E) : Source(E) {} 71a7dea167SDimitry Andric SourceInfo(const Decl *D) : Source(D) {} 72a7dea167SDimitry Andric 73a7dea167SDimitry Andric SourceLocation getLoc() const; 74a7dea167SDimitry Andric 75a7dea167SDimitry Andric const Stmt *asStmt() const { return Source.dyn_cast<const Stmt *>(); } 76a7dea167SDimitry Andric const Decl *asDecl() const { return Source.dyn_cast<const Decl *>(); } 77a7dea167SDimitry Andric const Expr *asExpr() const; 78a7dea167SDimitry Andric 79a7dea167SDimitry Andric operator bool() const { return !Source.isNull(); } 80a7dea167SDimitry Andric 81a7dea167SDimitry Andric private: 82a7dea167SDimitry Andric llvm::PointerUnion<const Decl *, const Stmt *> Source; 83a7dea167SDimitry Andric }; 84a7dea167SDimitry Andric 85a7dea167SDimitry Andric using SourceMap = std::vector<std::pair<unsigned, SourceInfo>>; 86a7dea167SDimitry Andric 87a7dea167SDimitry Andric /// Interface for classes which map locations to sources. 88a7dea167SDimitry Andric class SourceMapper { 89a7dea167SDimitry Andric public: 90a7dea167SDimitry Andric virtual ~SourceMapper() {} 91a7dea167SDimitry Andric 92a7dea167SDimitry Andric /// Returns source information for a given PC in a function. 93bdd1243dSDimitry Andric virtual SourceInfo getSource(const Function *F, CodePtr PC) const = 0; 94a7dea167SDimitry Andric 95a7dea167SDimitry Andric /// Returns the expression if an opcode belongs to one, null otherwise. 96bdd1243dSDimitry Andric const Expr *getExpr(const Function *F, CodePtr PC) const; 97a7dea167SDimitry Andric /// Returns the location from which an opcode originates. 98bdd1243dSDimitry Andric SourceLocation getLocation(const Function *F, CodePtr PC) const; 99a7dea167SDimitry Andric }; 100a7dea167SDimitry Andric 101a7dea167SDimitry Andric } // namespace interp 102a7dea167SDimitry Andric } // namespace clang 103a7dea167SDimitry Andric 104a7dea167SDimitry Andric #endif 105