Coverage Report

Created: 2023-05-31 04:38

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/Interp/EvalEmitter.h
Line
Count
Source (jump to first uncovered line)
1
//===--- EvalEmitter.h - Instruction emitter 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 the instruction emitters.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_CLANG_AST_INTERP_EVALEMITTER_H
14
#define LLVM_CLANG_AST_INTERP_EVALEMITTER_H
15
16
#include "ByteCodeGenError.h"
17
#include "Context.h"
18
#include "InterpStack.h"
19
#include "InterpState.h"
20
#include "PrimType.h"
21
#include "Program.h"
22
#include "Source.h"
23
#include "llvm/Support/Error.h"
24
25
namespace clang {
26
namespace interp {
27
class Context;
28
class Function;
29
class InterpState;
30
class Program;
31
class SourceInfo;
32
enum Opcode : uint32_t;
33
34
/// An emitter which evaluates opcodes as they are emitted.
35
class EvalEmitter : public SourceMapper {
36
public:
37
  using LabelTy = uint32_t;
38
  using AddrTy = uintptr_t;
39
  using Local = Scope::Local;
40
41
  llvm::Expected<bool> interpretExpr(const Expr *E);
42
  llvm::Expected<bool> interpretDecl(const VarDecl *VD);
43
44
protected:
45
  EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk,
46
              APValue &Result);
47
48
4.76k
  virtual ~EvalEmitter() {}
49
50
  /// Define a label.
51
  void emitLabel(LabelTy Label);
52
  /// Create a label.
53
  LabelTy getLabel();
54
55
  /// Methods implemented by the compiler.
56
  virtual bool visitExpr(const Expr *E) = 0;
57
  virtual bool visitDecl(const VarDecl *VD) = 0;
58
59
0
  bool bail(const Stmt *S) { return bail(S->getBeginLoc()); }
60
8
  bool bail(const Decl *D) { return bail(D->getBeginLoc()); }
61
  bool bail(const SourceLocation &Loc);
62
63
  /// Emits jumps.
64
  bool jumpTrue(const LabelTy &Label);
65
  bool jumpFalse(const LabelTy &Label);
66
  bool jump(const LabelTy &Label);
67
  bool fallthrough(const LabelTy &Label);
68
69
  /// Callback for registering a local.
70
  Local createLocal(Descriptor *D);
71
72
  /// Returns the source location of the current opcode.
73
343
  SourceInfo getSource(const Function *F, CodePtr PC) const override {
74
343
    return (F && 
F->hasBody()77
) ?
F->getSource(PC)77
:
CurrentSource266
;
75
343
  }
76
77
  /// Parameter indices.
78
  llvm::DenseMap<const ParmVarDecl *, unsigned> Params;
79
  /// Local descriptors.
80
  llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
81
82
private:
83
  /// Current compilation context.
84
  Context &Ctx;
85
  /// Current program.
86
  Program &P;
87
  /// Callee evaluation state.
88
  InterpState S;
89
  /// Location to write the result to.
90
  APValue &Result;
91
92
  /// Temporaries which require storage.
93
  llvm::DenseMap<unsigned, std::unique_ptr<char[]>> Locals;
94
95
90
  Block *getLocal(unsigned Index) const {
96
90
    auto It = Locals.find(Index);
97
90
    assert(It != Locals.end() && "Missing local variable");
98
90
    return reinterpret_cast<Block *>(It->second.get());
99
90
  }
100
101
  // The emitter always tracks the current instruction and sets OpPC to a token
102
  // value which is mapped to the location of the opcode being evaluated.
103
  CodePtr OpPC;
104
  /// Location of a failure.
105
  std::optional<SourceLocation> BailLocation;
106
  /// Location of the current instruction.
107
  SourceInfo CurrentSource;
108
109
  /// Next label ID to generate - first label is 1.
110
  LabelTy NextLabel = 1;
111
  /// Label being executed - 0 is the entry label.
112
  LabelTy CurrentLabel = 0;
113
  /// Active block which should be executed.
114
  LabelTy ActiveLabel = 0;
115
116
  /// Since expressions can only jump forward, predicated execution is
117
  /// used to deal with if-else statements.
118
18.2k
  bool isActive() const { return CurrentLabel == ActiveLabel; }
119
120
protected:
121
#define GET_EVAL_PROTO
122
#include "Opcodes.inc"
123
#undef GET_EVAL_PROTO
124
};
125
126
} // namespace interp
127
} // namespace clang
128
129
#endif