1353942Sdim//===--- Source.h - Source location provider for the VM --------*- C++ -*-===// 2353942Sdim// 3353942Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353942Sdim// See https://llvm.org/LICENSE.txt for license information. 5353942Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6353942Sdim// 7353942Sdim//===----------------------------------------------------------------------===// 8353942Sdim// 9353942Sdim// Defines a program which organises and links multiple bytecode functions. 10353942Sdim// 11353942Sdim//===----------------------------------------------------------------------===// 12353942Sdim 13353942Sdim#ifndef LLVM_CLANG_AST_INTERP_SOURCE_H 14353942Sdim#define LLVM_CLANG_AST_INTERP_SOURCE_H 15353942Sdim 16353942Sdim#include "clang/AST/Decl.h" 17353942Sdim#include "clang/AST/Stmt.h" 18353942Sdim#include "llvm/Support/Endian.h" 19353942Sdim 20353942Sdimnamespace clang { 21353942Sdimnamespace interp { 22353942Sdimclass Function; 23353942Sdim 24353942Sdim/// Pointer into the code segment. 25353942Sdimclass CodePtr { 26353942Sdimpublic: 27353942Sdim CodePtr() : Ptr(nullptr) {} 28353942Sdim 29353942Sdim CodePtr &operator+=(int32_t Offset) { 30353942Sdim Ptr += Offset; 31353942Sdim return *this; 32353942Sdim } 33353942Sdim 34353942Sdim int32_t operator-(const CodePtr &RHS) const { 35353942Sdim assert(Ptr != nullptr && RHS.Ptr != nullptr && "Invalid code pointer"); 36353942Sdim return Ptr - RHS.Ptr; 37353942Sdim } 38353942Sdim 39353942Sdim CodePtr operator-(size_t RHS) const { 40353942Sdim assert(Ptr != nullptr && "Invalid code pointer"); 41353942Sdim return CodePtr(Ptr - RHS); 42353942Sdim } 43353942Sdim 44353942Sdim bool operator!=(const CodePtr &RHS) const { return Ptr != RHS.Ptr; } 45353942Sdim 46353942Sdim /// Reads data and advances the pointer. 47353942Sdim template <typename T> T read() { 48353942Sdim T Value = ReadHelper<T>(Ptr); 49353942Sdim Ptr += sizeof(T); 50353942Sdim return Value; 51353942Sdim } 52353942Sdim 53353942Sdimprivate: 54353942Sdim /// Constructor used by Function to generate pointers. 55353942Sdim CodePtr(const char *Ptr) : Ptr(Ptr) {} 56353942Sdim 57353942Sdim /// Helper to decode a value or a pointer. 58353942Sdim template <typename T> 59353942Sdim static typename std::enable_if<!std::is_pointer<T>::value, T>::type 60353942Sdim ReadHelper(const char *Ptr) { 61353942Sdim using namespace llvm::support; 62353942Sdim return endian::read<T, endianness::native, 1>(Ptr); 63353942Sdim } 64353942Sdim 65353942Sdim template <typename T> 66353942Sdim static typename std::enable_if<std::is_pointer<T>::value, T>::type 67353942Sdim ReadHelper(const char *Ptr) { 68353942Sdim using namespace llvm::support; 69353942Sdim auto Punned = endian::read<uintptr_t, endianness::native, 1>(Ptr); 70353942Sdim return reinterpret_cast<T>(Punned); 71353942Sdim } 72353942Sdim 73353942Sdimprivate: 74353942Sdim friend class Function; 75353942Sdim 76353942Sdim /// Pointer into the code owned by a function. 77353942Sdim const char *Ptr; 78353942Sdim}; 79353942Sdim 80353942Sdim/// Describes the statement/declaration an opcode was generated from. 81353942Sdimclass SourceInfo { 82353942Sdimpublic: 83353942Sdim SourceInfo() {} 84353942Sdim SourceInfo(const Stmt *E) : Source(E) {} 85353942Sdim SourceInfo(const Decl *D) : Source(D) {} 86353942Sdim 87353942Sdim SourceLocation getLoc() const; 88353942Sdim 89353942Sdim const Stmt *asStmt() const { return Source.dyn_cast<const Stmt *>(); } 90353942Sdim const Decl *asDecl() const { return Source.dyn_cast<const Decl *>(); } 91353942Sdim const Expr *asExpr() const; 92353942Sdim 93353942Sdim operator bool() const { return !Source.isNull(); } 94353942Sdim 95353942Sdimprivate: 96353942Sdim llvm::PointerUnion<const Decl *, const Stmt *> Source; 97353942Sdim}; 98353942Sdim 99353942Sdimusing SourceMap = std::vector<std::pair<unsigned, SourceInfo>>; 100353942Sdim 101353942Sdim/// Interface for classes which map locations to sources. 102353942Sdimclass SourceMapper { 103353942Sdimpublic: 104353942Sdim virtual ~SourceMapper() {} 105353942Sdim 106353942Sdim /// Returns source information for a given PC in a function. 107353942Sdim virtual SourceInfo getSource(Function *F, CodePtr PC) const = 0; 108353942Sdim 109353942Sdim /// Returns the expression if an opcode belongs to one, null otherwise. 110353942Sdim const Expr *getExpr(Function *F, CodePtr PC) const; 111353942Sdim /// Returns the location from which an opcode originates. 112353942Sdim SourceLocation getLocation(Function *F, CodePtr PC) const; 113353942Sdim}; 114353942Sdim 115353942Sdim} // namespace interp 116353942Sdim} // namespace clang 117353942Sdim 118353942Sdim#endif 119