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" 17*5f757f3fSDimitry Andric #include "clang/AST/DeclBase.h" 18a7dea167SDimitry Andric #include "clang/AST/Stmt.h" 19*5f757f3fSDimitry Andric #include "llvm/ADT/PointerUnion.h" 20a7dea167SDimitry Andric #include "llvm/Support/Endian.h" 21a7dea167SDimitry Andric 22a7dea167SDimitry Andric namespace clang { 23*5f757f3fSDimitry Andric class Expr; 24*5f757f3fSDimitry Andric class SourceLocation; 25*5f757f3fSDimitry Andric class SourceRange; 26a7dea167SDimitry Andric namespace interp { 27a7dea167SDimitry Andric class Function; 28a7dea167SDimitry Andric 29a7dea167SDimitry Andric /// Pointer into the code segment. 30bdd1243dSDimitry Andric class CodePtr final { 31a7dea167SDimitry Andric public: 32a7dea167SDimitry Andric CodePtr() : Ptr(nullptr) {} 33a7dea167SDimitry Andric 34a7dea167SDimitry Andric CodePtr &operator+=(int32_t Offset) { 35a7dea167SDimitry Andric Ptr += Offset; 36a7dea167SDimitry Andric return *this; 37a7dea167SDimitry Andric } 38a7dea167SDimitry Andric 39a7dea167SDimitry Andric int32_t operator-(const CodePtr &RHS) const { 40a7dea167SDimitry Andric assert(Ptr != nullptr && RHS.Ptr != nullptr && "Invalid code pointer"); 41a7dea167SDimitry Andric return Ptr - RHS.Ptr; 42a7dea167SDimitry Andric } 43a7dea167SDimitry Andric 44a7dea167SDimitry Andric CodePtr operator-(size_t RHS) const { 45a7dea167SDimitry Andric assert(Ptr != nullptr && "Invalid code pointer"); 46a7dea167SDimitry Andric return CodePtr(Ptr - RHS); 47a7dea167SDimitry Andric } 48a7dea167SDimitry Andric 49a7dea167SDimitry Andric bool operator!=(const CodePtr &RHS) const { return Ptr != RHS.Ptr; } 50*5f757f3fSDimitry Andric const std::byte *operator*() const { return Ptr; } 51a7dea167SDimitry Andric 52bdd1243dSDimitry Andric operator bool() const { return Ptr; } 53bdd1243dSDimitry Andric 54a7dea167SDimitry Andric /// Reads data and advances the pointer. 55349cc55cSDimitry Andric template <typename T> std::enable_if_t<!std::is_pointer<T>::value, T> read() { 56bdd1243dSDimitry Andric assert(aligned(Ptr)); 57349cc55cSDimitry Andric using namespace llvm::support; 58*5f757f3fSDimitry Andric T Value = endian::read<T, llvm::endianness::native>(Ptr); 59bdd1243dSDimitry Andric Ptr += align(sizeof(T)); 60a7dea167SDimitry Andric return Value; 61a7dea167SDimitry Andric } 62a7dea167SDimitry Andric 63a7dea167SDimitry Andric private: 64a7dea167SDimitry Andric friend class Function; 6506c3fb27SDimitry Andric /// Constructor used by Function to generate pointers. 6606c3fb27SDimitry Andric CodePtr(const std::byte *Ptr) : Ptr(Ptr) {} 67a7dea167SDimitry Andric /// Pointer into the code owned by a function. 6806c3fb27SDimitry Andric const std::byte *Ptr; 69a7dea167SDimitry Andric }; 70a7dea167SDimitry Andric 71a7dea167SDimitry Andric /// Describes the statement/declaration an opcode was generated from. 72bdd1243dSDimitry Andric class SourceInfo final { 73a7dea167SDimitry Andric public: 74a7dea167SDimitry Andric SourceInfo() {} 75a7dea167SDimitry Andric SourceInfo(const Stmt *E) : Source(E) {} 76a7dea167SDimitry Andric SourceInfo(const Decl *D) : Source(D) {} 77a7dea167SDimitry Andric 78a7dea167SDimitry Andric SourceLocation getLoc() const; 79*5f757f3fSDimitry Andric SourceRange getRange() const; 80a7dea167SDimitry Andric 81a7dea167SDimitry Andric const Stmt *asStmt() const { return Source.dyn_cast<const Stmt *>(); } 82a7dea167SDimitry Andric const Decl *asDecl() const { return Source.dyn_cast<const Decl *>(); } 83a7dea167SDimitry Andric const Expr *asExpr() const; 84a7dea167SDimitry Andric 85a7dea167SDimitry Andric operator bool() const { return !Source.isNull(); } 86a7dea167SDimitry Andric 87a7dea167SDimitry Andric private: 88a7dea167SDimitry Andric llvm::PointerUnion<const Decl *, const Stmt *> Source; 89a7dea167SDimitry Andric }; 90a7dea167SDimitry Andric 91a7dea167SDimitry Andric using SourceMap = std::vector<std::pair<unsigned, SourceInfo>>; 92a7dea167SDimitry Andric 93a7dea167SDimitry Andric /// Interface for classes which map locations to sources. 94a7dea167SDimitry Andric class SourceMapper { 95a7dea167SDimitry Andric public: 96a7dea167SDimitry Andric virtual ~SourceMapper() {} 97a7dea167SDimitry Andric 98a7dea167SDimitry Andric /// Returns source information for a given PC in a function. 99bdd1243dSDimitry Andric virtual SourceInfo getSource(const Function *F, CodePtr PC) const = 0; 100a7dea167SDimitry Andric 101a7dea167SDimitry Andric /// Returns the expression if an opcode belongs to one, null otherwise. 102bdd1243dSDimitry Andric const Expr *getExpr(const Function *F, CodePtr PC) const; 103a7dea167SDimitry Andric /// Returns the location from which an opcode originates. 104bdd1243dSDimitry Andric SourceLocation getLocation(const Function *F, CodePtr PC) const; 105*5f757f3fSDimitry Andric SourceRange getRange(const Function *F, CodePtr PC) const; 106a7dea167SDimitry Andric }; 107a7dea167SDimitry Andric 108a7dea167SDimitry Andric } // namespace interp 109a7dea167SDimitry Andric } // namespace clang 110a7dea167SDimitry Andric 111a7dea167SDimitry Andric #endif 112