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