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