clang: lib/AST/ByteCode/State.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
15
16using namespace clang;
18
19State::~State() {}
20
22 unsigned ExtraNotes) {
23 return diag(Loc, DiagId, ExtraNotes, false);
24}
25
27 unsigned ExtraNotes) {
28 if (getEvalStatus().Diag)
29 return diag(E->getExprLoc(), DiagId, ExtraNotes, false);
30 setActiveDiagnostic(false);
32}
33
35 unsigned ExtraNotes) {
36 if (getEvalStatus().Diag)
37 return diag(SI.getLoc(), DiagId, ExtraNotes, false);
38 setActiveDiagnostic(false);
40}
41
43 unsigned ExtraNotes) {
44
45
46 if (!getEvalStatus().Diag || !getEvalStatus().Diag->empty()) {
47 setActiveDiagnostic(false);
49 }
50 return diag(Loc, DiagId, ExtraNotes, true);
51}
52
54 unsigned ExtraNotes) {
55 return CCEDiag(E->getExprLoc(), DiagId, ExtraNotes);
56}
57
59 unsigned ExtraNotes) {
60 return CCEDiag(SI.getLoc(), DiagId, ExtraNotes);
61}
62
64 if (!hasActiveDiagnostic())
67}
68
70 if (hasActiveDiagnostic()) {
71 getEvalStatus().Diag->insert(getEvalStatus().Diag->end(), Diags.begin(),
72 Diags.end());
73 }
74}
75
77 return getASTContext().getDiagnostics().Report(Loc, DiagId);
78}
79
80
83 getEvalStatus().Diag->push_back(std::make_pair(Loc, PD));
84 return getEvalStatus().Diag->back().second;
85}
86
88 unsigned ExtraNotes, bool IsCCEDiag) {
90 if (EvalStatus.Diag) {
91 if (hasPriorDiagnostic()) {
93 }
94
95 unsigned CallStackNotes = getCallStackDepth() - 1;
96 unsigned Limit =
97 getASTContext().getDiagnostics().getConstexprBacktraceLimit();
98 if (Limit)
99 CallStackNotes = std::min(CallStackNotes, Limit + 1);
100 if (checkingPotentialConstantExpression())
101 CallStackNotes = 0;
102
103 setActiveDiagnostic(true);
104 setFoldFailureDiagnostic(!IsCCEDiag);
105 EvalStatus.Diag->clear();
106 EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);
107 addDiag(Loc, DiagId);
108 if (!checkingPotentialConstantExpression()) {
109 addCallStack(Limit);
110 }
112 }
113 setActiveDiagnostic(false);
115}
116
118 return getASTContext().getLangOpts();
119}
120
121void State::addCallStack(unsigned Limit) {
122
123 unsigned ActiveCalls = getCallStackDepth() - 1;
124 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
125 if (Limit && Limit < ActiveCalls) {
126 SkipStart = Limit / 2 + Limit % 2;
127 SkipEnd = ActiveCalls - Limit / 2;
128 }
129
130
131 unsigned CallIdx = 0;
132 const Frame *Top = getCurrentFrame();
133 const Frame *Bottom = getBottomFrame();
134 for (const Frame *F = Top; F != Bottom; F = F->getCaller(), ++CallIdx) {
135 SourceRange CallRange = F->getCallRange();
136
137
138 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
139 if (CallIdx == SkipStart) {
140
141 addDiag(CallRange.getBegin(), diag::note_constexpr_calls_suppressed)
142 << unsigned(ActiveCalls - Limit);
143 }
144 continue;
145 }
146
147
148
149 if (const auto *CD =
150 dyn_cast_if_present(F->getCallee());
151 CD && CD->isInheritingConstructor()) {
152 addDiag(CallRange.getBegin(),
153 diag::note_constexpr_inherited_ctor_call_here)
154 << CD->getParent();
155 continue;
156 }
157
159 llvm::raw_svector_ostream Out(Buffer);
160 F->describe(Out);
161 if (!Buffer.empty())
162 addDiag(CallRange.getBegin(), diag::note_constexpr_call_here)
163 << Out.str() << CallRange;
164 }
165}
Defines the clang::ASTContext interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Implements a partial diagnostic which may not be emitted.
A little helper class used to produce diagnostics.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A partial diagnostic which we might know in advance that we are not going to emit.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Base class for stack frames, shared between VM and walker.
virtual Frame * getCaller() const =0
Returns a pointer to the caller frame.
Describes the statement/declaration an opcode was generated from.
SourceLocation getLoc() const
The JSON file list parser is used to communicate input to InstallAPI.
EvalStatus is a struct with detailed info about an evaluation in progress.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...