 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
78.1% |
232 / 297 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
93.9% |
279 / 297 |
| |
|
Line Coverage: |
85.1% |
291 / 342 |
| |
 |
|
 |
1 : //===--- PPExpressions.cpp - Preprocessor Expression Evaluation -----------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements the Preprocessor::EvaluateDirectiveExpression method,
11 : // which parses and evaluates integer constant expressions for #if directives.
12 : //
13 : //===----------------------------------------------------------------------===//
14 : //
15 : // FIXME: implement testing for #assert's.
16 : //
17 : //===----------------------------------------------------------------------===//
18 :
19 : #include "clang/Lex/Preprocessor.h"
20 : #include "clang/Lex/MacroInfo.h"
21 : #include "clang/Lex/LiteralSupport.h"
22 : #include "clang/Basic/TargetInfo.h"
23 : #include "clang/Lex/LexDiagnostic.h"
24 : #include "llvm/ADT/APSInt.h"
25 : using namespace clang;
26 :
27 : /// PPValue - Represents the value of a subexpression of a preprocessor
28 : /// conditional and the source range covered by it.
29 8459: class PPValue {
30 : SourceRange Range;
31 : public:
32 : llvm::APSInt Val;
33 :
34 : // Default ctor - Construct an 'invalid' PPValue.
35 8459: PPValue(unsigned BitWidth) : Val(BitWidth) {}
36 :
37 12197: unsigned getBitWidth() const { return Val.getBitWidth(); }
38 7630: bool isUnsigned() const { return Val.isUnsigned(); }
39 :
40 6121: const SourceRange &getRange() const { return Range; }
41 :
42 5367: void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }
43 3283: void setRange(SourceLocation B, SourceLocation E) {
44 3283: Range.setBegin(B); Range.setEnd(E);
45 3283: }
46 4073: void setBegin(SourceLocation L) { Range.setBegin(L); }
47 9346: void setEnd(SourceLocation L) { Range.setEnd(L); }
48 : };
49 :
50 : static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
51 : Token &PeekTok, bool ValueLive,
52 : Preprocessor &PP);
53 :
54 : /// DefinedTracker - This struct is used while parsing expressions to keep track
55 : /// of whether !defined(X) has been seen.
56 : ///
57 : /// With this simple scheme, we handle the basic forms:
58 : /// !defined(X) and !defined X
59 : /// but we also trivially handle (silly) stuff like:
60 : /// !!!defined(X) and +!defined(X) and !+!+!defined(X) and !(defined(X)).
61 : struct DefinedTracker {
62 : /// Each time a Value is evaluated, it returns information about whether the
63 : /// parsed value is of the form defined(X), !defined(X) or is something else.
64 : enum TrackerState {
65 : DefinedMacro, // defined(X)
66 : NotDefinedMacro, // !defined(X)
67 : Unknown // Something else.
68 : } State;
69 : /// TheMacro - When the state is DefinedMacro or NotDefinedMacro, this
70 : /// indicates the macro that was checked.
71 : IdentifierInfo *TheMacro;
72 : };
73 :
74 : /// EvaluateDefined - Process a 'defined(sym)' expression.
75 : static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
76 3088: bool ValueLive, Preprocessor &PP) {
77 : IdentifierInfo *II;
78 3088: Result.setBegin(PeekTok.getLocation());
79 :
80 : // Get the next token, don't expand it.
81 3088: PP.LexUnexpandedToken(PeekTok);
82 :
83 : // Two options, it can either be a pp-identifier or a (.
84 3088: SourceLocation LParenLoc;
156: branch 1 taken
2932: branch 2 taken
85 3088: if (PeekTok.is(tok::l_paren)) {
86 : // Found a paren, remember we saw it and skip it.
87 156: LParenLoc = PeekTok.getLocation();
88 156: PP.LexUnexpandedToken(PeekTok);
89 : }
90 :
91 : // If we don't have a pp-identifier now, this is an error.
0: branch 1 not taken
3088: branch 2 taken
92 3088: if ((II = PeekTok.getIdentifierInfo()) == 0) {
93 0: PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
94 0: return true;
95 : }
96 :
97 : // Otherwise, we got an identifier, is it defined to something?
98 3088: Result.Val = II->hasMacroDefinition();
99 3088: Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
100 :
101 : // If there is a macro, mark it used.
1227: branch 1 taken
1861: branch 2 taken
764: branch 3 taken
463: branch 4 taken
764: branch 5 taken
2324: branch 6 taken
102 3088: if (Result.Val != 0 && ValueLive) {
103 764: MacroInfo *Macro = PP.getMacroInfo(II);
104 764: Macro->setIsUsed(true);
105 : }
106 :
107 : // Consume identifier.
108 3088: Result.setEnd(PeekTok.getLocation());
109 3088: PP.LexNonComment(PeekTok);
110 :
111 : // If we are in parens, ensure we have a trailing ).
156: branch 1 taken
2932: branch 2 taken
112 3088: if (LParenLoc.isValid()) {
0: branch 1 not taken
156: branch 2 taken
113 156: if (PeekTok.isNot(tok::r_paren)) {
114 0: PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
115 0: PP.Diag(LParenLoc, diag::note_matching) << "(";
116 0: return true;
117 : }
118 : // Consume the ).
119 156: Result.setEnd(PeekTok.getLocation());
120 156: PP.LexNonComment(PeekTok);
121 : }
122 :
123 : // Success, remember that we saw defined(X).
124 3088: DT.State = DefinedTracker::DefinedMacro;
125 3088: DT.TheMacro = II;
126 3088: return false;
127 : }
128 :
129 : /// EvaluateValue - Evaluate the token PeekTok (and any others needed) and
130 : /// return the computed value in Result. Return true if there was an error
131 : /// parsing. This function also returns information about the form of the
132 : /// expression in DT. See above for information on what DT means.
133 : ///
134 : /// If ValueLive is false, then this value is being evaluated in a context where
135 : /// the result is not used. As such, avoid diagnostics that relate to
136 : /// evaluation.
137 : static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
138 12727: bool ValueLive, Preprocessor &PP) {
139 12727: DT.State = DefinedTracker::Unknown;
140 :
141 : // If this token's spelling is a pp-identifier, check to see if it is
142 : // 'defined' or if it is a macro. Note that we check here because many
143 : // keywords are pp-identifiers, so we can't check the kind.
3284: branch 1 taken
9443: branch 2 taken
144 12727: if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
145 : // Handle "defined X" and "defined(X)".
3088: branch 1 taken
196: branch 2 taken
146 3284: if (II->isStr("defined"))
147 3088: return(EvaluateDefined(Result, PeekTok, DT, ValueLive, PP));
148 :
149 : // If this identifier isn't 'defined' or one of the special
150 : // preprocessor keywords and it wasn't macro expanded, it turns
151 : // into a simple 0, unless it is the C++ keyword "true", in which case it
152 : // turns into "1".
37: branch 0 taken
159: branch 1 taken
153 196: if (ValueLive)
154 37: PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
155 196: Result.Val = II->getTokenID() == tok::kw_true;
156 196: Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
157 196: Result.setRange(PeekTok.getLocation());
158 196: PP.LexNonComment(PeekTok);
159 196: return false;
160 : }
161 :
3: branch 1 taken
1: branch 2 taken
5169: branch 3 taken
2: branch 4 taken
3283: branch 5 taken
0: branch 6 not taken
5: branch 7 taken
6: branch 8 taken
974: branch 9 taken
162 9443: switch (PeekTok.getKind()) {
163 : default: // Non-value token.
164 3: PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
165 3: return true;
166 : case tok::eom:
167 : case tok::r_paren:
168 : // If there is no expression, report and exit.
169 1: PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
170 1: return true;
171 : case tok::numeric_constant: {
172 5169: llvm::SmallString<64> IntegerBuffer;
173 5169: IntegerBuffer.resize(PeekTok.getLength());
174 5169: const char *ThisTokBegin = &IntegerBuffer[0];
175 5169: unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
176 : NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
177 5169: PeekTok.getLocation(), PP);
0: branch 0 not taken
5169: branch 1 taken
178 5169: if (Literal.hadError)
179 0: return true; // a diagnostic was already reported.
180 :
5169: branch 1 taken
0: branch 2 not taken
0: branch 3 not taken
5169: branch 4 taken
0: branch 5 not taken
5169: branch 6 taken
181 5169: if (Literal.isFloatingLiteral() || Literal.isImaginary) {
182 0: PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
183 0: return true;
184 : }
5169: branch 1 taken
0: branch 2 not taken
185 5169: assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
186 :
187 : // long long is a C99 feature.
1051: branch 1 taken
4118: branch 2 taken
867: branch 4 taken
184: branch 5 taken
1: branch 6 taken
866: branch 7 taken
1: branch 8 taken
5168: branch 9 taken
188 6220: if (!PP.getLangOptions().C99 && !PP.getLangOptions().CPlusPlus0x
189 : && Literal.isLongLong)
190 1: PP.Diag(PeekTok, diag::ext_longlong);
191 :
192 : // Parse the integer literal into Result.
0: branch 1 not taken
5169: branch 2 taken
193 5169: if (Literal.GetIntegerValue(Result.Val)) {
194 : // Overflow parsing integer literal.
0: branch 0 not taken
0: branch 1 not taken
195 0: if (ValueLive) PP.Diag(PeekTok, diag::warn_integer_too_large);
196 0: Result.Val.setIsUnsigned(true);
197 : } else {
198 : // Set the signedness of the result to match whether there was a U suffix
199 : // or not.
200 5169: Result.Val.setIsUnsigned(Literal.isUnsigned);
201 :
202 : // Detect overflow based on whether the value is signed. If signed
203 : // and if the value is too large, emit a warning "integer constant is so
204 : // large that it is unsigned" e.g. on 12345678901234567890 where intmax_t
205 : // is 64-bits.
5167: branch 0 taken
2: branch 1 taken
4: branch 3 taken
5163: branch 4 taken
4: branch 5 taken
5165: branch 6 taken
206 5169: if (!Literal.isUnsigned && Result.Val.isNegative()) {
207 : // Don't warn for a hex literal: 0x8000..0 shouldn't warn.
4: branch 0 taken
0: branch 1 not taken
0: branch 3 not taken
4: branch 4 taken
0: branch 5 not taken
4: branch 6 taken
208 4: if (ValueLive && Literal.getRadix() != 16)
209 0: PP.Diag(PeekTok, diag::warn_integer_too_large_for_signed);
210 4: Result.Val.setIsUnsigned(true);
211 : }
212 : }
213 :
214 : // Consume the token.
215 5169: Result.setRange(PeekTok.getLocation());
216 5169: PP.LexNonComment(PeekTok);
217 5169: return false;
218 : }
219 : case tok::char_constant: { // 'x'
220 2: llvm::SmallString<32> CharBuffer;
221 2: CharBuffer.resize(PeekTok.getLength());
222 2: const char *ThisTokBegin = &CharBuffer[0];
223 2: unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
224 : CharLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength,
225 2: PeekTok.getLocation(), PP);
0: branch 1 not taken
2: branch 2 taken
226 2: if (Literal.hadError())
227 0: return true; // A diagnostic was already emitted.
228 :
229 : // Character literals are always int or wchar_t, expand to intmax_t.
230 2: const TargetInfo &TI = PP.getTargetInfo();
231 : unsigned NumBits;
1: branch 1 taken
1: branch 2 taken
232 2: if (Literal.isMultiChar())
233 1: NumBits = TI.getIntWidth();
0: branch 1 not taken
1: branch 2 taken
234 1: else if (Literal.isWide())
235 0: NumBits = TI.getWCharWidth();
236 : else
237 1: NumBits = TI.getCharWidth();
238 :
239 : // Set the width.
240 2: llvm::APSInt Val(NumBits);
241 : // Set the value.
242 2: Val = Literal.getValue();
243 : // Set the signedness.
244 2: Val.setIsUnsigned(!PP.getLangOptions().CharIsSigned);
245 :
2: branch 2 taken
0: branch 3 not taken
246 2: if (Result.Val.getBitWidth() > Val.getBitWidth()) {
247 2: Result.Val = Val.extend(Result.Val.getBitWidth());
248 : } else {
249 : assert(Result.Val.getBitWidth() == Val.getBitWidth() &&
0: branch 2 not taken
0: branch 3 not taken
250 0: "intmax_t smaller than char/wchar_t?");
251 0: Result.Val = Val;
252 : }
253 :
254 : // Consume the token.
255 2: Result.setRange(PeekTok.getLocation());
256 2: PP.LexNonComment(PeekTok);
257 2: return false;
258 : }
259 : case tok::l_paren: {
260 3283: SourceLocation Start = PeekTok.getLocation();
261 3283: PP.LexNonComment(PeekTok); // Eat the (.
262 : // Parse the value and if there are any binary operators involved, parse
263 : // them.
0: branch 1 not taken
3283: branch 2 taken
264 3283: if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
265 :
266 : // If this is a silly value like (X), which doesn't need parens, check for
267 : // !(defined X).
2227: branch 1 taken
1056: branch 2 taken
268 3283: if (PeekTok.is(tok::r_paren)) {
269 : // Just use DT unmodified as our result.
270 : } else {
271 : // Otherwise, we have something like (x+y), and we consumed '(x'.
0: branch 1 not taken
2227: branch 2 taken
272 2227: if (EvaluateDirectiveSubExpr(Result, 1, PeekTok, ValueLive, PP))
273 0: return true;
274 :
0: branch 1 not taken
2227: branch 2 taken
275 2227: if (PeekTok.isNot(tok::r_paren)) {
276 : PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
277 0: << Result.getRange();
278 0: PP.Diag(Start, diag::note_matching) << "(";
279 0: return true;
280 : }
281 2227: DT.State = DefinedTracker::Unknown;
282 : }
283 3283: Result.setRange(Start, PeekTok.getLocation());
284 3283: PP.LexNonComment(PeekTok); // Eat the ).
285 3283: return false;
286 : }
287 : case tok::plus: {
288 0: SourceLocation Start = PeekTok.getLocation();
289 : // Unary plus doesn't modify the value.
290 0: PP.LexNonComment(PeekTok);
0: branch 1 not taken
0: branch 2 not taken
291 0: if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
292 0: Result.setBegin(Start);
293 0: return false;
294 : }
295 : case tok::minus: {
296 5: SourceLocation Loc = PeekTok.getLocation();
297 5: PP.LexNonComment(PeekTok);
0: branch 1 not taken
5: branch 2 taken
298 5: if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
299 5: Result.setBegin(Loc);
300 :
301 : // C99 6.5.3.3p3: The sign of the result matches the sign of the operand.
302 5: Result.Val = -Result.Val;
303 :
304 : // -MININT is the only thing that overflows. Unsigned never overflows.
4: branch 1 taken
1: branch 2 taken
0: branch 4 not taken
4: branch 5 taken
305 5: bool Overflow = !Result.isUnsigned() && Result.Val.isMinSignedValue();
306 :
307 : // If this operator is live and overflowed, report the issue.
0: branch 0 not taken
5: branch 1 taken
5: branch 2 taken
5: branch 3 taken
308 5: if (Overflow && ValueLive)
309 0: PP.Diag(Loc, diag::warn_pp_expr_overflow) << Result.getRange();
310 :
311 5: DT.State = DefinedTracker::Unknown;
312 5: return false;
313 : }
314 :
315 : case tok::tilde: {
316 6: SourceLocation Start = PeekTok.getLocation();
317 6: PP.LexNonComment(PeekTok);
0: branch 1 not taken
6: branch 2 taken
318 6: if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
319 6: Result.setBegin(Start);
320 :
321 : // C99 6.5.3.3p4: The sign of the result matches the sign of the operand.
322 6: Result.Val = ~Result.Val;
323 6: DT.State = DefinedTracker::Unknown;
324 6: return false;
325 : }
326 :
327 : case tok::exclaim: {
328 974: SourceLocation Start = PeekTok.getLocation();
329 974: PP.LexNonComment(PeekTok);
0: branch 1 not taken
974: branch 2 taken
330 974: if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true;
331 974: Result.setBegin(Start);
332 974: Result.Val = !Result.Val;
333 : // C99 6.5.3.3p5: The sign of the result is 'int', aka it is signed.
334 974: Result.Val.setIsUnsigned(false);
335 :
875: branch 0 taken
99: branch 1 taken
336 974: if (DT.State == DefinedTracker::DefinedMacro)
337 875: DT.State = DefinedTracker::NotDefinedMacro;
0: branch 0 not taken
99: branch 1 taken
338 99: else if (DT.State == DefinedTracker::NotDefinedMacro)
339 0: DT.State = DefinedTracker::DefinedMacro;
340 974: return false;
341 : }
342 :
343 : // FIXME: Handle #assert
344 : }
345 : }
346 :
347 :
348 :
349 : /// getPrecedence - Return the precedence of the specified binary operator
350 : /// token. This returns:
351 : /// ~0 - Invalid token.
352 : /// 14 -> 3 - various operators.
353 : /// 0 - 'eom' or ')'
354 13383: static unsigned getPrecedence(tok::TokenKind Kind) {
3: branch 0 taken
18: branch 1 taken
1744: branch 2 taken
1058: branch 3 taken
1353: branch 4 taken
407: branch 5 taken
12: branch 6 taken
10: branch 7 taken
10: branch 8 taken
1318: branch 9 taken
1124: branch 10 taken
1628: branch 11 taken
27: branch 12 taken
24: branch 13 taken
2861: branch 14 taken
1786: branch 15 taken
355 13383: switch (Kind) {
356 3: default: return ~0U;
357 : case tok::percent:
358 : case tok::slash:
359 18: case tok::star: return 14;
360 : case tok::plus:
361 1744: case tok::minus: return 13;
362 : case tok::lessless:
363 1058: case tok::greatergreater: return 12;
364 : case tok::lessequal:
365 : case tok::less:
366 : case tok::greaterequal:
367 1353: case tok::greater: return 11;
368 : case tok::exclaimequal:
369 407: case tok::equalequal: return 10;
370 12: case tok::amp: return 9;
371 10: case tok::caret: return 8;
372 10: case tok::pipe: return 7;
373 1318: case tok::ampamp: return 6;
374 1124: case tok::pipepipe: return 5;
375 1628: case tok::question: return 4;
376 27: case tok::comma: return 3;
377 24: case tok::colon: return 2;
378 2861: case tok::r_paren: return 0; // Lowest priority, end of expr.
379 1786: case tok::eom: return 0; // Lowest priority, end of macro.
380 : }
381 : }
382 :
383 :
384 : /// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is
385 : /// PeekTok, and whose precedence is PeekPrec. This returns the result in LHS.
386 : ///
387 : /// If ValueLive is false, then this value is being evaluated in a context where
388 : /// the result is not used. As such, avoid diagnostics that relate to
389 : /// evaluation, such as division by zero warnings.
390 : static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
391 : Token &PeekTok, bool ValueLive,
392 4753: Preprocessor &PP) {
393 4753: unsigned PeekPrec = getPrecedence(PeekTok.getKind());
394 : // If this token isn't valid, report the error.
3: branch 0 taken
4750: branch 1 taken
395 4753: if (PeekPrec == ~0U) {
396 : PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
397 3: << LHS.getRange();
398 3: return true;
399 : }
400 :
6086: branch 1 taken
2: branch 2 taken
6086: branch 4 taken
5: branch 5 taken
401 6088: while (1) {
402 : // If this token has a lower precedence than we are allowed to parse, return
403 : // it so that higher levels of the recursion can parse it.
4745: branch 0 taken
6091: branch 1 taken
404 10836: if (PeekPrec < MinPrec)
405 4745: return false;
406 :
407 6091: tok::TokenKind Operator = PeekTok.getKind();
408 :
409 : // If this is a short-circuiting operator, see if the RHS of the operator is
410 : // dead. Note that this cannot just clobber ValueLive. Consider
411 : // "0 && 1 ? 4 : 1 / 0", which is parsed as "(0 && 1) ? 4 : (1 / 0)". In
412 : // this example, the RHS of the && being dead does not make the rest of the
413 : // expr dead.
414 : bool RHSIsLive;
1286: branch 0 taken
4805: branch 1 taken
624: branch 3 taken
662: branch 4 taken
624: branch 5 taken
5467: branch 6 taken
415 6091: if (Operator == tok::ampamp && LHS.Val == 0)
416 624: RHSIsLive = false; // RHS of "0 && x" is dead.
1070: branch 0 taken
4397: branch 1 taken
585: branch 3 taken
485: branch 4 taken
585: branch 5 taken
4882: branch 6 taken
417 5467: else if (Operator == tok::pipepipe && LHS.Val != 0)
418 585: RHSIsLive = false; // RHS of "1 || x" is dead.
17: branch 0 taken
4865: branch 1 taken
5: branch 3 taken
12: branch 4 taken
5: branch 5 taken
4877: branch 6 taken
419 4882: else if (Operator == tok::question && LHS.Val == 0)
420 5: RHSIsLive = false; // RHS (x) of "0 ? x : y" is dead.
421 : else
422 4877: RHSIsLive = ValueLive;
423 :
424 : // Consume the operator, remembering the operator's location for reporting.
425 6091: SourceLocation OpLoc = PeekTok.getLocation();
426 6091: PP.LexNonComment(PeekTok);
427 :
428 6091: PPValue RHS(LHS.getBitWidth());
429 : // Parse the RHS of the operator.
430 : DefinedTracker DT;
3: branch 1 taken
6088: branch 2 taken
431 6096: if (EvaluateValue(RHS, PeekTok, DT, RHSIsLive, PP)) return true;
432 :
433 : // Remember the precedence of this operator and get the precedence of the
434 : // operator immediately to the right of the RHS.
435 6088: unsigned ThisPrec = PeekPrec;
436 6088: PeekPrec = getPrecedence(PeekTok.getKind());
437 :
438 : // If this token isn't valid, report the error.
0: branch 0 not taken
6088: branch 1 taken
439 6088: if (PeekPrec == ~0U) {
440 : PP.Diag(PeekTok.getLocation(), diag::err_pp_expr_bad_token_binop)
441 0: << RHS.getRange();
442 0: return true;
443 : }
444 :
445 : // Decide whether to include the next binop in this subexpression. For
446 : // example, when parsing x+y*z and looking at '*', we want to recursively
447 : // handle y*z as a single subexpression. We do this because the precedence
448 : // of * is higher than that of +. The only strange case we have to handle
449 : // here is for the ?: operator, where the precedence is actually lower than
450 : // the LHS of the '?'. The grammar rule is:
451 : //
452 : // conditional-expression ::=
453 : // logical-OR-expression ? expression : conditional-expression
454 : // where 'expression' is actually comma-expression.
455 : unsigned RHSPrec;
17: branch 0 taken
6071: branch 1 taken
456 6088: if (Operator == tok::question)
457 : // The RHS of "?" should be maximally consumed as an expression.
458 17: RHSPrec = getPrecedence(tok::comma);
459 : else // All others should munch while higher precedence.
460 6071: RHSPrec = ThisPrec+1;
461 :
899: branch 0 taken
5189: branch 1 taken
462 6088: if (PeekPrec >= RHSPrec) {
0: branch 1 not taken
899: branch 2 taken
463 899: if (EvaluateDirectiveSubExpr(RHS, RHSPrec, PeekTok, RHSIsLive, PP))
464 0: return true;
465 899: PeekPrec = getPrecedence(PeekTok.getKind());
466 : }
0: branch 0 not taken
6088: branch 1 taken
467 6088: assert(PeekPrec <= ThisPrec && "Recursion didn't work!");
468 :
469 : // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
470 : // either operand is unsigned.
471 6088: llvm::APSInt Res(LHS.getBitWidth());
3433: branch 0 taken
2655: branch 1 taken
472 6088: switch (Operator) {
473 : case tok::question: // No UAC for x and y in "x ? y : z".
474 : case tok::lessless: // Shift amount doesn't UAC with shift value.
475 : case tok::greatergreater: // Shift amount doesn't UAC with shift value.
476 : case tok::comma: // Comma operands are not subject to UACs.
477 : case tok::pipepipe: // Logical || does not do UACs.
478 : case tok::ampamp: // Logical && does not do UACs.
479 3433: break; // No UAC
480 : default:
481 2655: Res.setIsUnsigned(LHS.isUnsigned()|RHS.isUnsigned());
482 : // If this just promoted something from signed to unsigned, and if the
483 : // value was negative, warn about it.
2216: branch 0 taken
439: branch 1 taken
5: branch 3 taken
2211: branch 4 taken
5: branch 5 taken
2650: branch 6 taken
484 2655: if (ValueLive && Res.isUnsigned()) {
1: branch 1 taken
4: branch 2 taken
1: branch 4 taken
0: branch 5 not taken
1: branch 6 taken
4: branch 7 taken
485 5: if (!LHS.isUnsigned() && LHS.Val.isNegative())
486 : PP.Diag(OpLoc, diag::warn_pp_convert_lhs_to_positive)
487 : << LHS.Val.toString(10, true) + " to " +
488 : LHS.Val.toString(10, false)
489 1: << LHS.getRange() << RHS.getRange();
4: branch 1 taken
1: branch 2 taken
2: branch 4 taken
2: branch 5 taken
2: branch 6 taken
3: branch 7 taken
490 5: if (!RHS.isUnsigned() && RHS.Val.isNegative())
491 : PP.Diag(OpLoc, diag::warn_pp_convert_rhs_to_positive)
492 : << RHS.Val.toString(10, true) + " to " +
493 : RHS.Val.toString(10, false)
494 2: << LHS.getRange() << RHS.getRange();
495 : }
496 2655: LHS.Val.setIsUnsigned(Res.isUnsigned());
497 2655: RHS.Val.setIsUnsigned(Res.isUnsigned());
498 : }
499 :
500 : // FIXME: All of these should detect and report overflow??
501 6088: bool Overflow = false;
0: branch 0 not taken
0: branch 1 not taken
8: branch 2 taken
2: branch 3 taken
1057: branch 4 taken
1: branch 5 taken
1059: branch 6 taken
157: branch 7 taken
0: branch 8 not taken
74: branch 9 taken
856: branch 10 taken
89: branch 11 taken
12: branch 12 taken
366: branch 13 taken
12: branch 14 taken
10: branch 15 taken
10: branch 16 taken
1286: branch 17 taken
1070: branch 18 taken
2: branch 19 taken
17: branch 20 taken
0: branch 21 not taken
502 6088: switch (Operator) {
503 0: default: assert(0 && "Unknown operator token!");
504 : case tok::percent:
0: branch 1 not taken
0: branch 2 not taken
505 0: if (RHS.Val != 0)
506 0: Res = LHS.Val % RHS.Val;
0: branch 0 not taken
0: branch 1 not taken
507 0: else if (ValueLive) {
508 : PP.Diag(OpLoc, diag::err_pp_remainder_by_zero)
509 0: << LHS.getRange() << RHS.getRange();
510 0: return true;
511 : }
512 0: break;
513 : case tok::slash:
1: branch 1 taken
7: branch 2 taken
514 8: if (RHS.Val != 0) {
515 1: Res = LHS.Val / RHS.Val;
0: branch 1 not taken
1: branch 2 taken
516 1: if (LHS.Val.isSigned()) // MININT/-1 --> overflow.
0: branch 1 not taken
0: branch 2 not taken
0: branch 4 not taken
0: branch 5 not taken
517 0: Overflow = LHS.Val.isMinSignedValue() && RHS.Val.isAllOnesValue();
1: branch 0 taken
6: branch 1 taken
518 7: } else if (ValueLive) {
519 : PP.Diag(OpLoc, diag::err_pp_division_by_zero)
520 1: << LHS.getRange() << RHS.getRange();
521 1: return true;
522 : }
523 7: break;
524 :
525 : case tok::star:
526 2: Res = LHS.Val * RHS.Val;
1: branch 1 taken
1: branch 2 taken
1: branch 4 taken
0: branch 5 not taken
1: branch 7 taken
0: branch 8 not taken
1: branch 9 taken
1: branch 10 taken
527 2: if (Res.isSigned() && LHS.Val != 0 && RHS.Val != 0)
0: branch 2 not taken
1: branch 3 taken
0: branch 6 not taken
0: branch 7 not taken
0: branch 8 not taken
1: branch 9 taken
1: branch 11 taken
0: branch 12 not taken
528 1: Overflow = Res/RHS.Val != LHS.Val || Res/LHS.Val != RHS.Val;
529 2: break;
530 : case tok::lessless: {
531 : // Determine whether overflow is about to happen.
532 1057: unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
0: branch 1 not taken
1057: branch 2 taken
533 1057: if (ShAmt >= LHS.Val.getBitWidth())
534 0: Overflow = true, ShAmt = LHS.Val.getBitWidth()-1;
0: branch 1 not taken
1057: branch 2 taken
535 1057: else if (LHS.isUnsigned())
536 0: Overflow = false;
1057: branch 1 taken
0: branch 2 not taken
537 1057: else if (LHS.Val.isNonNegative()) // Don't allow sign change.
538 1057: Overflow = ShAmt >= LHS.Val.countLeadingZeros();
539 : else
540 0: Overflow = ShAmt >= LHS.Val.countLeadingOnes();
541 :
542 1057: Res = LHS.Val << ShAmt;
543 1057: break;
544 : }
545 : case tok::greatergreater: {
546 : // Determine whether overflow is about to happen.
547 1: unsigned ShAmt = static_cast<unsigned>(RHS.Val.getLimitedValue());
0: branch 1 not taken
1: branch 2 taken
548 1: if (ShAmt >= LHS.getBitWidth())
549 0: Overflow = true, ShAmt = LHS.getBitWidth()-1;
550 1: Res = LHS.Val >> ShAmt;
551 1: break;
552 : }
553 : case tok::plus:
554 1059: Res = LHS.Val + RHS.Val;
2: branch 1 taken
1057: branch 2 taken
555 1059: if (LHS.isUnsigned())
556 2: Overflow = false;
1057: branch 2 taken
0: branch 3 not taken
1: branch 6 taken
1056: branch 7 taken
1: branch 8 taken
1056: branch 9 taken
557 1057: else if (LHS.Val.isNonNegative() == RHS.Val.isNonNegative() &&
558 : Res.isNonNegative() != LHS.Val.isNonNegative())
559 1: Overflow = true; // Overflow for signed addition.
560 1059: break;
561 : case tok::minus:
562 157: Res = LHS.Val - RHS.Val;
1: branch 1 taken
156: branch 2 taken
563 157: if (LHS.isUnsigned())
564 1: Overflow = false;
1: branch 2 taken
155: branch 3 taken
1: branch 6 taken
0: branch 7 not taken
1: branch 8 taken
155: branch 9 taken
565 156: else if (LHS.Val.isNonNegative() != RHS.Val.isNonNegative() &&
566 : Res.isNonNegative() != LHS.Val.isNonNegative())
567 1: Overflow = true; // Overflow for signed subtraction.
568 157: break;
569 : case tok::lessequal:
570 0: Res = LHS.Val <= RHS.Val;
571 0: Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
572 0: break;
573 : case tok::less:
574 74: Res = LHS.Val < RHS.Val;
575 74: Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
576 74: break;
577 : case tok::greaterequal:
578 856: Res = LHS.Val >= RHS.Val;
579 856: Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
580 856: break;
581 : case tok::greater:
582 89: Res = LHS.Val > RHS.Val;
583 89: Res.setIsUnsigned(false); // C99 6.5.8p6, result is always int (signed)
584 89: break;
585 : case tok::exclaimequal:
586 12: Res = LHS.Val != RHS.Val;
587 12: Res.setIsUnsigned(false); // C99 6.5.9p3, result is always int (signed)
588 12: break;
589 : case tok::equalequal:
590 366: Res = LHS.Val == RHS.Val;
591 366: Res.setIsUnsigned(false); // C99 6.5.9p3, result is always int (signed)
592 366: break;
593 : case tok::amp:
594 12: Res = LHS.Val & RHS.Val;
595 12: break;
596 : case tok::caret:
597 10: Res = LHS.Val ^ RHS.Val;
598 10: break;
599 : case tok::pipe:
600 10: Res = LHS.Val | RHS.Val;
601 10: break;
602 : case tok::ampamp:
662: branch 1 taken
624: branch 2 taken
548: branch 4 taken
114: branch 5 taken
603 1286: Res = (LHS.Val != 0 && RHS.Val != 0);
604 1286: Res.setIsUnsigned(false); // C99 6.5.13p3, result is always int (signed)
605 1286: break;
606 : case tok::pipepipe:
485: branch 1 taken
585: branch 2 taken
132: branch 4 taken
353: branch 5 taken
607 1070: Res = (LHS.Val != 0 || RHS.Val != 0);
608 1070: Res.setIsUnsigned(false); // C99 6.5.14p3, result is always int (signed)
609 1070: break;
610 : case tok::comma:
611 : // Comma is invalid in pp expressions in c89/c++ mode, but is valid in C99
612 : // if not being evaluated.
1: branch 1 taken
1: branch 2 taken
0: branch 3 not taken
1: branch 4 taken
1: branch 5 taken
1: branch 6 taken
613 2: if (!PP.getLangOptions().C99 || ValueLive)
614 : PP.Diag(OpLoc, diag::ext_pp_comma_expr)
615 1: << LHS.getRange() << RHS.getRange();
616 2: Res = RHS.Val; // LHS = LHS,RHS -> RHS.
617 2: break;
618 : case tok::question: {
619 : // Parse the : part of the expression.
0: branch 1 not taken
17: branch 2 taken
620 17: if (PeekTok.isNot(tok::colon)) {
621 : PP.Diag(PeekTok.getLocation(), diag::err_expected_colon)
622 0: << LHS.getRange(), RHS.getRange();
623 0: PP.Diag(OpLoc, diag::note_matching) << "?";
624 0: return true;
625 : }
626 : // Consume the :.
627 17: PP.LexNonComment(PeekTok);
628 :
629 : // Evaluate the value after the :.
16: branch 0 taken
1: branch 1 taken
5: branch 3 taken
11: branch 4 taken
630 17: bool AfterColonLive = ValueLive && LHS.Val == 0;
631 17: PPValue AfterColonVal(LHS.getBitWidth());
632 : DefinedTracker DT;
0: branch 1 not taken
17: branch 2 taken
633 17: if (EvaluateValue(AfterColonVal, PeekTok, DT, AfterColonLive, PP))
634 0: return true;
635 :
636 : // Parse anything after the : with the same precedence as ?. We allow
637 : // things of equal precedence because ?: is right associative.
1: branch 1 taken
16: branch 2 taken
638 17: if (EvaluateDirectiveSubExpr(AfterColonVal, ThisPrec,
639 : PeekTok, AfterColonLive, PP))
640 1: return true;
641 :
642 : // Now that we have the condition, the LHS and the RHS of the :, evaluate.
12: branch 1 taken
4: branch 2 taken
643 16: Res = LHS.Val != 0 ? RHS.Val : AfterColonVal.Val;
644 16: RHS.setEnd(AfterColonVal.getRange().getEnd());
645 :
646 : // Usual arithmetic conversions (C99 6.3.1.8p1): result is unsigned if
647 : // either operand is unsigned.
648 16: Res.setIsUnsigned(RHS.isUnsigned() | AfterColonVal.isUnsigned());
649 :
650 : // Figure out the precedence of the token after the : part.
651 16: PeekPrec = getPrecedence(PeekTok.getKind());
1: branch 1 taken
16: branch 2 taken
652 17: break;
653 : }
654 : case tok::colon:
655 : // Don't allow :'s to float around without being part of ?: exprs.
656 : PP.Diag(OpLoc, diag::err_pp_colon_without_question)
657 0: << LHS.getRange() << RHS.getRange();
658 0: return true;
659 : }
660 :
661 : // If this operator is live and overflowed, report the issue.
3: branch 0 taken
6083: branch 1 taken
3: branch 2 taken
0: branch 3 not taken
662 6086: if (Overflow && ValueLive)
663 : PP.Diag(OpLoc, diag::warn_pp_expr_overflow)
664 3: << LHS.getRange() << RHS.getRange();
665 :
666 : // Put the result back into 'LHS' for our next iteration.
667 6086: LHS.Val = Res;
668 6086: LHS.setEnd(RHS.getRange().getEnd());
669 : }
670 :
671 : return false;
672 : }
673 :
674 : /// EvaluateDirectiveExpression - Evaluate an integer constant expression that
675 : /// may occur after a #if or #elif directive. If the expression is equivalent
676 : /// to "!defined(X)" return X in IfNDefMacro.
677 : bool Preprocessor::
678 2351: EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
679 : // Save the current state of 'DisableMacroExpansion' and reset it to false. If
680 : // 'DisableMacroExpansion' is true, then we must be in a macro argument list
681 : // in which case a directive is undefined behavior. We want macros to be able
682 : // to recursively expand in order to get more gcc-list behavior, so we force
683 : // DisableMacroExpansion to false and restore it when we're done parsing the
684 : // expression.
685 2351: bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
686 2351: DisableMacroExpansion = false;
687 :
688 : // Peek ahead one token.
689 2351: Token Tok;
690 2351: Lex(Tok);
691 :
692 : // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t.
693 2351: unsigned BitWidth = getTargetInfo().getIntMaxTWidth();
694 :
695 2351: PPValue ResVal(BitWidth);
696 : DefinedTracker DT;
1: branch 1 taken
2350: branch 2 taken
697 2351: if (EvaluateValue(ResVal, Tok, DT, true, *this)) {
698 : // Parse error, skip the rest of the macro line.
0: branch 1 not taken
1: branch 2 taken
699 1: if (Tok.isNot(tok::eom))
700 0: DiscardUntilEndOfDirective();
701 :
702 : // Restore 'DisableMacroExpansion'.
703 1: DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
704 1: return false;
705 : }
706 :
707 : // If we are at the end of the expression after just parsing a value, there
708 : // must be no (unparenthesized) binary operators involved, so we can exit
709 : // directly.
740: branch 1 taken
1610: branch 2 taken
710 2350: if (Tok.is(tok::eom)) {
711 : // If the expression we parsed was of the form !defined(macro), return the
712 : // macro in IfNDefMacro.
7: branch 0 taken
733: branch 1 taken
713 740: if (DT.State == DefinedTracker::NotDefinedMacro)
714 7: IfNDefMacro = DT.TheMacro;
715 :
716 : // Restore 'DisableMacroExpansion'.
717 740: DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
718 740: return ResVal.Val != 0;
719 : }
720 :
721 : // Otherwise, we must have a binary operator (e.g. "#if 1 < 2"), so parse the
722 : // operator and the stuff after it.
7: branch 2 taken
1603: branch 3 taken
723 1610: if (EvaluateDirectiveSubExpr(ResVal, getPrecedence(tok::question),
724 : Tok, true, *this)) {
725 : // Parse error, skip the rest of the macro line.
6: branch 1 taken
1: branch 2 taken
726 7: if (Tok.isNot(tok::eom))
727 6: DiscardUntilEndOfDirective();
728 :
729 : // Restore 'DisableMacroExpansion'.
730 7: DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
731 7: return false;
732 : }
733 :
734 : // If we aren't at the tok::eom token, something bad happened, like an extra
735 : // ')' token.
3: branch 1 taken
1600: branch 2 taken
736 1603: if (Tok.isNot(tok::eom)) {
737 3: Diag(Tok, diag::err_pp_expected_eol);
738 3: DiscardUntilEndOfDirective();
739 : }
740 :
741 : // Restore 'DisableMacroExpansion'.
742 1603: DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
743 1603: return ResVal.Val != 0;
744 : }
745 :
Generated: 2010-02-10 01:31 by zcov