clang  10.0.0svn
Context.cpp
Go to the documentation of this file.
1 //===--- Context.cpp - Context for the constexpr 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 #include "Context.h"
10 #include "ByteCodeEmitter.h"
11 #include "ByteCodeExprGen.h"
12 #include "ByteCodeStmtGen.h"
13 #include "EvalEmitter.h"
14 #include "Interp.h"
15 #include "InterpFrame.h"
16 #include "InterpStack.h"
17 #include "PrimType.h"
18 #include "Program.h"
19 #include "clang/AST/Expr.h"
20 
21 using namespace clang;
22 using namespace clang::interp;
23 
25  : Ctx(Ctx), ForceInterp(getLangOpts().ForceNewConstInterp),
26  P(new Program(*this)) {}
27 
29 
31  const FunctionDecl *FD) {
32  Function *Func = P->getFunction(FD);
33  if (!Func) {
34  if (auto R = ByteCodeStmtGen<ByteCodeEmitter>(*this, *P).compileFunc(FD)) {
35  Func = *R;
36  } else if (ForceInterp) {
37  handleAllErrors(R.takeError(), [&Parent](ByteCodeGenError &Err) {
38  Parent.FFDiag(Err.getLoc(), diag::err_experimental_clang_interp_failed);
39  });
40  return InterpResult::Fail;
41  } else {
42  consumeError(R.takeError());
43  return InterpResult::Bail;
44  }
45  }
46 
47  if (!Func->isConstexpr())
48  return InterpResult::Fail;
49 
50  APValue Dummy;
51  return Run(Parent, Func, Dummy);
52 }
53 
55  APValue &Result) {
56  ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
57  return Check(Parent, C.interpretExpr(E));
58 }
59 
61  APValue &Result) {
62  ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result);
63  return Check(Parent, C.interpretDecl(VD));
64 }
65 
66 const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); }
67 
69  if (T->isReferenceType() || T->isPointerType()) {
70  return PT_Ptr;
71  }
72 
73  if (T->isBooleanType())
74  return PT_Bool;
75 
77  switch (Ctx.getIntWidth(T)) {
78  case 64:
79  return PT_Sint64;
80  case 32:
81  return PT_Sint32;
82  case 16:
83  return PT_Sint16;
84  case 8:
85  return PT_Sint8;
86  default:
87  return {};
88  }
89  }
90 
92  switch (Ctx.getIntWidth(T)) {
93  case 64:
94  return PT_Uint64;
95  case 32:
96  return PT_Uint32;
97  case 16:
98  return PT_Uint16;
99  case 8:
100  return PT_Uint8;
101  default:
102  return {};
103  }
104  }
105 
106  if (T->isNullPtrType())
107  return PT_Ptr;
108 
109  if (auto *AT = dyn_cast<AtomicType>(T))
110  return classify(AT->getValueType());
111 
112  return {};
113 }
114 
115 unsigned Context::getCharBit() const {
116  return Ctx.getTargetInfo().getCharWidth();
117 }
118 
119 InterpResult Context::Run(State &Parent, Function *Func, APValue &Result) {
120  InterpResult Flag;
121  {
122  InterpState State(Parent, *P, Stk, *this);
123  State.Current = new InterpFrame(State, Func, nullptr, {}, {});
124  if (Interpret(State, Result)) {
125  Flag = InterpResult::Success;
126  } else {
127  Flag = InterpResult::Fail;
128  }
129  }
130 
131  if (Flag != InterpResult::Success)
132  Stk.clear();
133  return Flag;
134 }
135 
136 InterpResult Context::Check(State &Parent, llvm::Expected<bool> &&R) {
137  if (R) {
139  } else if (ForceInterp) {
140  handleAllErrors(R.takeError(), [&Parent](ByteCodeGenError &Err) {
141  Parent.FFDiag(Err.getLoc(), diag::err_experimental_clang_interp_failed);
142  });
143  return InterpResult::Fail;
144  } else {
145  consumeError(R.takeError());
146  return InterpResult::Bail;
147  }
148 }
void clear()
Clears the stack without calling any destructors.
Definition: InterpStack.cpp:20
Represents a function declaration or definition.
Definition: Decl.h:1784
Context(ASTContext &Ctx)
Initialises the constexpr VM.
Definition: Context.cpp:24
A (possibly-)qualified type.
Definition: Type.h:643
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
Definition: Type.cpp:1987
InterpFrame * Current
The current frame.
Definition: InterpState.h:104
Frame storing local variables.
Definition: InterpFrame.h:29
StringRef P
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:706
unsigned getCharWidth() const
Definition: TargetInfo.h:382
Represents a variable declaration or definition.
Definition: Decl.h:827
llvm::Optional< PrimType > classify(QualType T)
Classifies an expression.
Definition: Context.cpp:68
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
LineState State
Compilation context for statements.
bool Interpret(InterpState &S, APValue &Result)
Interpreter entry point.
Definition: Interp.cpp:401
bool isReferenceType() const
Definition: Type.h:6403
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:49
unsigned getCharBit() const
Returns CHAR_BIT.
Definition: Context.cpp:115
NodeId Parent
Definition: ASTDiff.cpp:191
Interpreter encountered an unimplemented feature, AST fallback.
This represents one expression.
Definition: Expr.h:108
bool isNullPtrType() const
Definition: Type.h:6675
OptionalDiagnostic FFDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Definition: State.cpp:20
The program contains and links the bytecode for all functions.
Definition: Program.h:43
InterpResult isPotentialConstantExpr(State &Parent, const FunctionDecl *FnDecl)
Checks if a function is a potential constant expression.
Definition: Context.cpp:30
Bytecode function.
Definition: Function.h:59
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
Definition: Type.cpp:1947
~Context()
Cleans up the constexpr VM.
Definition: Context.cpp:28
InterpResult evaluateAsRValue(State &Parent, const Expr *E, APValue &Result)
Evaluates a toplevel expression as an rvalue.
Definition: Context.cpp:54
Dataflow Directional Tag Classes.
bool isBooleanType() const
Definition: Type.h:6767
Interpreter context.
Definition: InterpState.h:34
unsigned getIntWidth(QualType T) const
Error thrown by the compiler.
InterpResult
Wrapper around interpreter termination results.
Definition: Context.h:38
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
Definition: APValue.h:115
bool isConstexpr() const
Checks if the function is valid to call in constexpr.
Definition: Function.h:103
Compilation context for expressions.
Interface for the VM to interact with the AST walker&#39;s context.
Definition: State.h:55
const LangOptions & getLangOpts() const
Returns the language options.
Definition: Context.cpp:66
Interpreter successfully computed a value.
bool isPointerType() const
Definition: Type.h:6391
InterpResult evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result)
Evaluates a toplevel initializer.
Definition: Context.cpp:60
Interpreter encountered an error and quit.
const LangOptions & getLangOpts() const
Definition: ASTContext.h:723