Source.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. #ifndef LLVM_CLANG_AST_INTERP_SOURCE_H
  13. #define LLVM_CLANG_AST_INTERP_SOURCE_H
  14. #include "PrimType.h"
  15. #include "clang/AST/Decl.h"
  16. #include "clang/AST/Stmt.h"
  17. #include "llvm/Support/Endian.h"
  18. namespace clang {
  19. namespace interp {
  20. class Function;
  21. /// Pointer into the code segment.
  22. class CodePtr final {
  23. public:
  24. CodePtr() : Ptr(nullptr) {}
  25. CodePtr &operator+=(int32_t Offset) {
  26. Ptr += Offset;
  27. return *this;
  28. }
  29. int32_t operator-(const CodePtr &RHS) const {
  30. assert(Ptr != nullptr && RHS.Ptr != nullptr && "Invalid code pointer");
  31. return Ptr - RHS.Ptr;
  32. }
  33. CodePtr operator-(size_t RHS) const {
  34. assert(Ptr != nullptr && "Invalid code pointer");
  35. return CodePtr(Ptr - RHS);
  36. }
  37. bool operator!=(const CodePtr &RHS) const { return Ptr != RHS.Ptr; }
  38. operator bool() const { return Ptr; }
  39. /// Reads data and advances the pointer.
  40. template <typename T> std::enable_if_t<!std::is_pointer<T>::value, T> read() {
  41. assert(aligned(Ptr));
  42. using namespace llvm::support;
  43. T Value = endian::read<T, endianness::native, 1>(Ptr);
  44. Ptr += align(sizeof(T));
  45. return Value;
  46. }
  47. private:
  48. /// Constructor used by Function to generate pointers.
  49. CodePtr(const char *Ptr) : Ptr(Ptr) {}
  50. private:
  51. friend class Function;
  52. /// Pointer into the code owned by a function.
  53. const char *Ptr;
  54. };
  55. /// Describes the statement/declaration an opcode was generated from.
  56. class SourceInfo final {
  57. public:
  58. SourceInfo() {}
  59. SourceInfo(const Stmt *E) : Source(E) {}
  60. SourceInfo(const Decl *D) : Source(D) {}
  61. SourceLocation getLoc() const;
  62. const Stmt *asStmt() const { return Source.dyn_cast<const Stmt *>(); }
  63. const Decl *asDecl() const { return Source.dyn_cast<const Decl *>(); }
  64. const Expr *asExpr() const;
  65. operator bool() const { return !Source.isNull(); }
  66. private:
  67. llvm::PointerUnion<const Decl *, const Stmt *> Source;
  68. };
  69. using SourceMap = std::vector<std::pair<unsigned, SourceInfo>>;
  70. /// Interface for classes which map locations to sources.
  71. class SourceMapper {
  72. public:
  73. virtual ~SourceMapper() {}
  74. /// Returns source information for a given PC in a function.
  75. virtual SourceInfo getSource(const Function *F, CodePtr PC) const = 0;
  76. /// Returns the expression if an opcode belongs to one, null otherwise.
  77. const Expr *getExpr(const Function *F, CodePtr PC) const;
  78. /// Returns the location from which an opcode originates.
  79. SourceLocation getLocation(const Function *F, CodePtr PC) const;
  80. };
  81. } // namespace interp
  82. } // namespace clang
  83. #endif