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