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