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