 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
79.9% |
267 / 334 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
91.6% |
306 / 334 |
| |
|
Line Coverage: |
87.8% |
389 / 443 |
| |
 |
|
 |
1 : //===--- Parser.cpp - C Language Family Parser ----------------------------===//
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 Parser interfaces.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/Parse/Parser.h"
15 : #include "clang/Parse/ParseDiagnostic.h"
16 : #include "clang/Parse/DeclSpec.h"
17 : #include "clang/Parse/Scope.h"
18 : #include "clang/Parse/Template.h"
19 : #include "llvm/Support/raw_ostream.h"
20 : #include "RAIIObjectsForParser.h"
21 : #include "ParsePragma.h"
22 : using namespace clang;
23 :
24 : /// \brief A comment handler that passes comments found by the preprocessor
25 : /// to the parser action.
2251: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
26 2251: class ActionCommentHandler : public CommentHandler {
27 : Action &Actions;
28 :
29 : public:
30 2251: explicit ActionCommentHandler(Action &Actions) : Actions(Actions) { }
31 :
32 28241: virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) {
33 28241: Actions.ActOnComment(Comment);
34 28241: return false;
35 : }
36 : };
37 :
38 2251: Parser::Parser(Preprocessor &pp, Action &actions)
39 : : CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
40 : GreaterThanIsOperator(true), ColonIsSacred(false),
41 2251: TemplateParameterDepth(0) {
42 2251: Tok.setKind(tok::eof);
43 2251: CurScope = 0;
44 2251: NumCachedScopes = 0;
45 2251: ParenCount = BracketCount = BraceCount = 0;
46 2251: ObjCImpDecl = DeclPtrTy();
47 :
48 : // Add #pragma handlers. These are removed and destroyed in the
49 : // destructor.
50 : PackHandler.reset(new
51 2251: PragmaPackHandler(&PP.getIdentifierTable().get("pack"), actions));
52 2251: PP.AddPragmaHandler(0, PackHandler.get());
53 :
54 : UnusedHandler.reset(new
55 : PragmaUnusedHandler(&PP.getIdentifierTable().get("unused"), actions,
56 2251: *this));
57 2251: PP.AddPragmaHandler(0, UnusedHandler.get());
58 :
59 : WeakHandler.reset(new
60 2251: PragmaWeakHandler(&PP.getIdentifierTable().get("weak"), actions));
61 2251: PP.AddPragmaHandler(0, WeakHandler.get());
62 :
63 2251: CommentHandler.reset(new ActionCommentHandler(actions));
64 2251: PP.AddCommentHandler(CommentHandler.get());
65 2251: }
66 :
67 : /// If a crash happens while the parser is active, print out a line indicating
68 : /// what the current token is.
69 0: void PrettyStackTraceParserEntry::print(llvm::raw_ostream &OS) const {
70 0: const Token &Tok = P.getCurToken();
0: branch 1 not taken
0: branch 2 not taken
71 0: if (Tok.is(tok::eof)) {
72 0: OS << "<eof> parser at end of file\n";
73 0: return;
74 : }
75 :
0: branch 2 not taken
0: branch 3 not taken
76 0: if (Tok.getLocation().isInvalid()) {
77 0: OS << "<unknown> parser at unknown location\n";
78 0: return;
79 : }
80 :
81 0: const Preprocessor &PP = P.getPreprocessor();
82 0: Tok.getLocation().print(OS, PP.getSourceManager());
0: branch 1 not taken
0: branch 2 not taken
83 0: if (Tok.isAnnotation())
84 0: OS << ": at annotation token \n";
85 : else
86 0: OS << ": current parser token '" << PP.getSpelling(Tok) << "'\n";
87 : }
88 :
89 :
90 1162: DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
91 1162: return Diags.Report(FullSourceLoc(Loc, PP.getSourceManager()), DiagID);
92 : }
93 :
94 872: DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) {
95 872: return Diag(Tok.getLocation(), DiagID);
96 : }
97 :
98 : /// \brief Emits a diagnostic suggesting parentheses surrounding a
99 : /// given range.
100 : ///
101 : /// \param Loc The location where we'll emit the diagnostic.
102 : /// \param Loc The kind of diagnostic to emit.
103 : /// \param ParenRange Source range enclosing code that should be parenthesized.
104 : void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK,
105 3: SourceRange ParenRange) {
106 3: SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd());
3: branch 2 taken
0: branch 3 not taken
0: branch 5 not taken
3: branch 6 taken
0: branch 7 not taken
3: branch 8 taken
107 3: if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) {
108 : // We can't display the parentheses, so just dig the
109 : // warning/error and return.
110 0: Diag(Loc, DK);
111 0: return;
112 : }
113 :
114 : Diag(Loc, DK)
115 : << CodeModificationHint::CreateInsertion(ParenRange.getBegin(), "(")
116 3: << CodeModificationHint::CreateInsertion(EndLoc, ")");
117 : }
118 :
119 : /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
120 : /// this helper function matches and consumes the specified RHS token if
121 : /// present. If not present, it emits the specified diagnostic indicating
122 : /// that the parser failed to match the RHS of the token at LHSLoc. LHSName
123 : /// should be the name of the unmatched LHS token.
124 : SourceLocation Parser::MatchRHSPunctuation(tok::TokenKind RHSTok,
125 25062: SourceLocation LHSLoc) {
126 :
25038: branch 1 taken
24: branch 2 taken
127 25062: if (Tok.is(RHSTok))
128 25038: return ConsumeAnyToken();
129 :
130 24: SourceLocation R = Tok.getLocation();
131 24: const char *LHSName = "unknown";
132 24: diag::kind DID = diag::err_parse_error;
0: branch 0 not taken
13: branch 1 taken
10: branch 2 taken
1: branch 3 taken
0: branch 4 not taken
133 24: switch (RHSTok) {
134 0: default: break;
135 13: case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break;
136 10: case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break;
137 1: case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break;
138 0: case tok::greater: LHSName = "<"; DID = diag::err_expected_greater; break;
139 : }
140 24: Diag(Tok, DID);
141 24: Diag(LHSLoc, diag::note_matching) << LHSName;
142 24: SkipUntil(RHSTok);
143 24: return R;
144 : }
145 :
146 : /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
147 : /// input. If so, it is consumed and false is returned.
148 : ///
149 : /// If the input is malformed, this emits the specified diagnostic. Next, if
150 : /// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
151 : /// returned.
152 : bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
153 51168: const char *Msg, tok::TokenKind SkipToTok) {
51135: branch 1 taken
33: branch 2 taken
154 51168: if (Tok.is(ExpectedTok)) {
155 51135: ConsumeAnyToken();
156 51135: return false;
157 : }
158 :
159 33: const char *Spelling = 0;
160 33: SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
33: branch 1 taken
0: branch 2 not taken
33: branch 4 taken
0: branch 5 not taken
33: branch 6 taken
0: branch 7 not taken
161 33: if (EndLoc.isValid() &&
162 : (Spelling = tok::getTokenSimpleSpelling(ExpectedTok))) {
163 : // Show what code to insert to fix this problem.
164 : Diag(EndLoc, DiagID)
165 : << Msg
166 33: << CodeModificationHint::CreateInsertion(EndLoc, Spelling);
167 : } else
168 0: Diag(Tok, DiagID) << Msg;
169 :
9: branch 0 taken
24: branch 1 taken
170 33: if (SkipToTok != tok::unknown)
171 9: SkipUntil(SkipToTok);
172 33: return true;
173 : }
174 :
175 : //===----------------------------------------------------------------------===//
176 : // Error recovery.
177 : //===----------------------------------------------------------------------===//
178 :
179 : /// SkipUntil - Read tokens until we get to the specified token, then consume
180 : /// it (unless DontConsume is true). Because we cannot guarantee that the
181 : /// token will ever occur, this skips to the next token, or to some likely
182 : /// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
183 : /// character.
184 : ///
185 : /// If SkipUntil finds the specified token, it returns true, otherwise it
186 : /// returns false.
187 : bool Parser::SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
188 1772: bool StopAtSemi, bool DontConsume) {
189 : // We always want this function to skip at least one token if the first token
190 : // isn't T and if not at EOF.
191 1772: bool isFirstTokenSkipped = true;
192 1348: while (1) {
193 : // If we found one of the tokens, stop and return true.
3147: branch 0 taken
1618: branch 1 taken
194 4765: for (unsigned i = 0; i != NumToks; ++i) {
1502: branch 1 taken
1645: branch 2 taken
195 3147: if (Tok.is(Toks[i])) {
1279: branch 0 taken
223: branch 1 taken
196 1502: if (DontConsume) {
197 : // Noop, don't consume the token.
198 : } else {
199 1279: ConsumeAnyToken();
200 : }
201 1502: return true;
202 : }
203 : }
204 :
119: branch 1 taken
74: branch 2 taken
9: branch 3 taken
19: branch 4 taken
5: branch 5 taken
1: branch 6 taken
2: branch 7 taken
4: branch 8 taken
163: branch 9 taken
1222: branch 10 taken
205 1618: switch (Tok.getKind()) {
206 : case tok::eof:
207 : // Ran out of tokens.
208 119: return false;
209 :
210 : case tok::l_paren:
211 : // Recursively skip properly-nested parens.
212 74: ConsumeParen();
213 74: SkipUntil(tok::r_paren, false);
214 74: break;
215 : case tok::l_square:
216 : // Recursively skip properly-nested square brackets.
217 9: ConsumeBracket();
218 9: SkipUntil(tok::r_square, false);
219 9: break;
220 : case tok::l_brace:
221 : // Recursively skip properly-nested braces.
222 19: ConsumeBrace();
223 19: SkipUntil(tok::r_brace, false);
224 19: break;
225 :
226 : // Okay, we found a ']' or '}' or ')', which we think should be balanced.
227 : // Since the user wasn't looking for this token (if they were, it would
228 : // already be handled), this isn't balanced. If there is a LHS token at a
229 : // higher level, we will assume that this matches the unbalanced token
230 : // and return it. Otherwise, this is a spurious RHS token, which we skip.
231 : case tok::r_paren:
4: branch 0 taken
1: branch 1 taken
3: branch 2 taken
1: branch 3 taken
232 5: if (ParenCount && !isFirstTokenSkipped)
233 3: return false; // Matches something.
234 2: ConsumeParen();
235 2: break;
236 : case tok::r_square:
0: branch 0 not taken
1: branch 1 taken
1: branch 2 taken
1: branch 3 taken
237 1: if (BracketCount && !isFirstTokenSkipped)
238 0: return false; // Matches something.
239 1: ConsumeBracket();
240 1: break;
241 : case tok::r_brace:
2: branch 0 taken
0: branch 1 not taken
1: branch 2 taken
1: branch 3 taken
242 2: if (BraceCount && !isFirstTokenSkipped)
243 1: return false; // Matches something.
244 1: ConsumeBrace();
245 1: break;
246 :
247 : case tok::string_literal:
248 : case tok::wide_string_literal:
249 4: ConsumeStringToken();
250 4: break;
251 : case tok::semi:
147: branch 0 taken
16: branch 1 taken
252 163: if (StopAtSemi)
253 147: return false;
254 : // FALL THROUGH.
255 : default:
256 : // Skip this token.
257 1238: ConsumeToken();
258 : break;
259 : }
260 1348: isFirstTokenSkipped = false;
261 : }
262 : }
263 :
264 : //===----------------------------------------------------------------------===//
265 : // Scope manipulation
266 : //===----------------------------------------------------------------------===//
267 :
268 : /// EnterScope - Start a new scope.
269 35381: void Parser::EnterScope(unsigned ScopeFlags) {
28845: branch 0 taken
6536: branch 1 taken
270 35381: if (NumCachedScopes) {
271 28845: Scope *N = ScopeCache[--NumCachedScopes];
272 28845: N->Init(CurScope, ScopeFlags);
273 28845: CurScope = N;
274 : } else {
275 6536: CurScope = new Scope(CurScope, ScopeFlags);
276 : }
277 35381: }
278 :
279 : /// ExitScope - Pop a scope off the scope stack.
280 33145: void Parser::ExitScope() {
0: branch 0 not taken
33145: branch 1 taken
281 33145: assert(CurScope && "Scope imbalance!");
282 :
283 : // Inform the actions module that this scope is going away if there are any
284 : // decls in it.
23726: branch 1 taken
9419: branch 2 taken
285 33145: if (!CurScope->decl_empty())
286 23726: Actions.ActOnPopScope(Tok.getLocation(), CurScope);
287 :
288 33145: Scope *OldScope = CurScope;
289 33145: CurScope = OldScope->getParent();
290 :
0: branch 0 not taken
33145: branch 1 taken
291 33145: if (NumCachedScopes == ScopeCacheSize)
0: branch 0 not taken
0: branch 1 not taken
292 0: delete OldScope;
293 : else
294 33145: ScopeCache[NumCachedScopes++] = OldScope;
295 33145: }
296 :
297 :
298 :
299 :
300 : //===----------------------------------------------------------------------===//
301 : // C99 6.9: External Definitions.
302 : //===----------------------------------------------------------------------===//
303 :
304 2251: Parser::~Parser() {
305 : // If we still have scopes active, delete the scope tree.
2236: branch 0 taken
15: branch 1 taken
2236: branch 4 taken
2236: branch 5 taken
306 2251: delete CurScope;
307 :
308 : // Free the scope cache.
4300: branch 0 taken
2251: branch 1 taken
2251: branch 2 taken
2251: branch 3 taken
309 6551: for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
4300: branch 0 taken
0: branch 1 not taken
4300: branch 4 taken
4300: branch 5 taken
310 4300: delete ScopeCache[i];
311 :
312 : // Remove the pragma handlers we installed.
313 2251: PP.RemovePragmaHandler(0, PackHandler.get());
314 2251: PackHandler.reset();
315 2251: PP.RemovePragmaHandler(0, UnusedHandler.get());
316 2251: UnusedHandler.reset();
317 2251: PP.RemovePragmaHandler(0, WeakHandler.get());
318 2251: WeakHandler.reset();
319 2251: PP.RemoveCommentHandler(CommentHandler.get());
320 2251: }
321 :
322 : /// Initialize - Warm up the parser.
323 : ///
324 2251: void Parser::Initialize() {
325 : // Prime the lexer look-ahead.
326 2251: ConsumeToken();
327 :
328 : // Create the translation unit scope. Install it as the current scope.
0: branch 0 not taken
2251: branch 1 taken
329 2251: assert(CurScope == 0 && "A scope is already active?");
330 2251: EnterScope(Scope::DeclScope);
331 2251: Actions.ActOnTranslationUnitScope(Tok.getLocation(), CurScope);
332 :
5: branch 1 taken
2246: branch 2 taken
5: branch 4 taken
0: branch 5 not taken
5: branch 6 taken
2246: branch 7 taken
333 2251: if (Tok.is(tok::eof) &&
334 : !getLang().CPlusPlus) // Empty source file is an extension in C
335 5: Diag(Tok, diag::ext_empty_source_file);
336 :
337 : // Initialization for Objective-C context sensitive keywords recognition.
338 : // Referenced in Parser::ParseObjCTypeQualifierList.
642: branch 1 taken
1609: branch 2 taken
339 2251: if (getLang().ObjC1) {
340 642: ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in");
341 642: ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out");
342 642: ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout");
343 642: ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway");
344 642: ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy");
345 642: ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref");
346 : }
347 :
348 2251: Ident_super = &PP.getIdentifierTable().get("super");
349 :
6: branch 1 taken
2245: branch 2 taken
350 2251: if (getLang().AltiVec) {
351 6: Ident_vector = &PP.getIdentifierTable().get("vector");
352 6: Ident_pixel = &PP.getIdentifierTable().get("pixel");
353 : }
354 2251: }
355 :
356 : /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
357 : /// action tells us to. This returns true if the EOF was encountered.
358 30521: bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
359 30521: Result = DeclGroupPtrTy();
2251: branch 1 taken
28270: branch 2 taken
360 30521: if (Tok.is(tok::eof)) {
361 2251: Actions.ActOnEndOfTranslationUnit();
362 2251: return true;
363 : }
364 :
365 28270: CXX0XAttributeList Attr;
1260: branch 1 taken
27010: branch 2 taken
12: branch 4 taken
1248: branch 5 taken
12: branch 6 taken
28258: branch 7 taken
366 28270: if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
367 12: Attr = ParseCXX0XAttributes();
368 28270: Result = ParseExternalDeclaration(Attr);
369 28270: return false;
370 : }
371 :
372 : /// ParseTranslationUnit:
373 : /// translation-unit: [C99 6.9]
374 : /// external-declaration
375 : /// translation-unit external-declaration
376 15: void Parser::ParseTranslationUnit() {
377 15: Initialize();
378 :
379 15: DeclGroupPtrTy Res;
136: branch 1 taken
15: branch 2 taken
380 151: while (!ParseTopLevelDecl(Res))
381 : /*parse them all*/;
382 :
383 15: ExitScope();
0: branch 0 not taken
15: branch 1 taken
384 15: assert(CurScope == 0 && "Scope imbalance!");
385 15: }
386 :
387 : /// ParseExternalDeclaration:
388 : ///
389 : /// external-declaration: [C99 6.9], declaration: [C++ dcl.dcl]
390 : /// function-definition
391 : /// declaration
392 : /// [C++0x] empty-declaration
393 : /// [GNU] asm-definition
394 : /// [GNU] __extension__ external-declaration
395 : /// [OBJC] objc-class-definition
396 : /// [OBJC] objc-class-declaration
397 : /// [OBJC] objc-alias-declaration
398 : /// [OBJC] objc-protocol-definition
399 : /// [OBJC] objc-method-definition
400 : /// [OBJC] @end
401 : /// [C++] linkage-specification
402 : /// [GNU] asm-definition:
403 : /// simple-asm-expr ';'
404 : ///
405 : /// [C++0x] empty-declaration:
406 : /// ';'
407 : ///
408 : /// [C++0x/GNU] 'extern' 'template' declaration
409 30933: Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) {
410 30933: DeclPtrTy SingleDecl;
134: branch 1 taken
2: branch 2 taken
2: branch 3 taken
471: branch 4 taken
17: branch 5 taken
4381: branch 6 taken
924: branch 7 taken
2: branch 8 taken
8794: branch 9 taken
1835: branch 10 taken
14371: branch 11 taken
411 30933: switch (Tok.getKind()) {
412 : case tok::semi:
121: branch 1 taken
13: branch 2 taken
413 134: if (!getLang().CPlusPlus0x)
414 : Diag(Tok, diag::ext_top_level_semi)
415 121: << CodeModificationHint::CreateRemoval(Tok.getLocation());
416 :
417 134: ConsumeToken();
418 : // TODO: Invoke action for top-level semicolon.
419 134: return DeclGroupPtrTy();
420 : case tok::r_brace:
421 2: Diag(Tok, diag::err_expected_external_declaration);
422 2: ConsumeBrace();
423 2: return DeclGroupPtrTy();
424 : case tok::eof:
425 2: Diag(Tok, diag::err_expected_external_declaration);
426 2: return DeclGroupPtrTy();
427 : case tok::kw___extension__: {
428 : // __extension__ silences extension warnings in the subexpression.
429 471: ExtensionRAIIObject O(Diags); // Use RAII to do this.
430 471: ConsumeToken();
431 471: return ParseExternalDeclaration(Attr);
432 : }
433 : case tok::kw_asm: {
1: branch 0 taken
16: branch 1 taken
434 17: if (Attr.HasAttr)
435 : Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
436 1: << Attr.Range;
437 :
438 17: OwningExprResult Result(ParseSimpleAsm());
439 :
440 : ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
441 17: "top-level asm block");
442 :
1: branch 1 taken
16: branch 2 taken
443 17: if (Result.isInvalid())
444 2: return DeclGroupPtrTy();
445 16: SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result));
1: branch 1 taken
16: branch 2 taken
446 33: break;
447 : }
448 : case tok::at:
449 : // @ is not a legal token unless objc is enabled, no need to check for ObjC.
450 : /// FIXME: ParseObjCAtDirectives should return a DeclGroup for things like
451 : /// @class foo, bar;
452 4381: SingleDecl = ParseObjCAtDirectives();
453 4381: break;
454 : case tok::minus:
455 : case tok::plus:
0: branch 1 not taken
924: branch 2 taken
456 924: if (!getLang().ObjC1) {
457 0: Diag(Tok, diag::err_expected_external_declaration);
458 0: ConsumeToken();
459 0: return DeclGroupPtrTy();
460 : }
461 924: SingleDecl = ParseObjCMethodDefinition();
462 924: break;
463 : case tok::code_completion:
464 : Actions.CodeCompleteOrdinaryName(CurScope,
465 : ObjCImpDecl? Action::CCC_ObjCImplementation
0: branch 1 not taken
2: branch 2 taken
466 2: : Action::CCC_Namespace);
467 2: ConsumeToken();
468 2: return ParseExternalDeclaration(Attr);
469 : case tok::kw_using:
470 : case tok::kw_namespace:
471 : case tok::kw_typedef:
472 : case tok::kw_template:
473 : case tok::kw_export: // As in 'export template'
474 : case tok::kw_static_assert:
475 : // A function definition cannot start with a these keywords.
476 : {
477 8794: SourceLocation DeclEnd;
478 8794: return ParseDeclaration(Declarator::FileContext, DeclEnd, Attr);
479 : }
480 : case tok::kw_extern:
442: branch 1 taken
1393: branch 2 taken
18: branch 5 taken
424: branch 6 taken
18: branch 7 taken
1817: branch 8 taken
481 1835: if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) {
482 : // Extern templates
483 18: SourceLocation ExternLoc = ConsumeToken();
484 18: SourceLocation TemplateLoc = ConsumeToken();
485 18: SourceLocation DeclEnd;
486 : return Actions.ConvertDeclToDeclGroup(
487 18: ParseExplicitInstantiation(ExternLoc, TemplateLoc, DeclEnd));
488 : }
489 :
490 : // FIXME: Detect C++ linkage specifications here?
491 :
492 : // Fall through to handle other declarations or function definitions.
493 :
494 : default:
495 : // We can't tell whether this is a function-definition or declaration yet.
496 16188: return ParseDeclarationOrFunctionDefinition(Attr.AttrList);
497 : }
498 :
499 : // This routine returns a DeclGroup, if the thing we parsed only contains a
500 : // single decl, convert it now.
501 5321: return Actions.ConvertDeclToDeclGroup(SingleDecl);
502 : }
503 :
504 : /// \brief Determine whether the current token, if it occurs after a
505 : /// declarator, continues a declaration or declaration list.
506 10680: bool Parser::isDeclarationAfterDeclarator() {
507 : return Tok.is(tok::equal) || // int X()= -> not a function def
508 : Tok.is(tok::comma) || // int X(), -> not a function def
509 : Tok.is(tok::semi) || // int X(); -> not a function def
510 : Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def
511 : Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
512 : (getLang().CPlusPlus &&
10652: branch 1 taken
28: branch 2 taken
10645: branch 4 taken
7: branch 5 taken
8142: branch 7 taken
2503: branch 8 taken
8123: branch 10 taken
19: branch 11 taken
7214: branch 13 taken
909: branch 14 taken
2413: branch 16 taken
4801: branch 17 taken
0: branch 19 not taken
2413: branch 20 taken
513 10680: Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++]
514 : }
515 :
516 : /// \brief Determine whether the current token, if it occurs after a
517 : /// declarator, indicates the start of a function definition.
518 7212: bool Parser::isStartOfFunctionDefinition() {
7150: branch 1 taken
62: branch 2 taken
519 7212: if (Tok.is(tok::l_brace)) // int X() {}
520 7150: return true;
521 :
50: branch 1 taken
12: branch 2 taken
522 62: if (!getLang().CPlusPlus)
523 50: return isDeclarationSpecifier(); // int X(f) int f; {}
524 : return Tok.is(tok::colon) || // X() : Base() {} (used for ctors)
5: branch 1 taken
7: branch 2 taken
5: branch 4 taken
0: branch 5 not taken
525 12: Tok.is(tok::kw_try); // X() try { ... }
526 : }
527 :
528 : /// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
529 : /// a declaration. We can't tell which we have until we read up to the
530 : /// compound-statement in function-definition. TemplateParams, if
531 : /// non-NULL, provides the template parameters when we're parsing a
532 : /// C++ template-declaration.
533 : ///
534 : /// function-definition: [C99 6.9.1]
535 : /// decl-specs declarator declaration-list[opt] compound-statement
536 : /// [C90] function-definition: [C99 6.7.1] - implicit int result
537 : /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
538 : ///
539 : /// declaration: [C99 6.7]
540 : /// declaration-specifiers init-declarator-list[opt] ';'
541 : /// [!C99] init-declarator-list ';' [TODO: warn in c99 mode]
542 : /// [OMP] threadprivate-directive [TODO]
543 : ///
544 : Parser::DeclGroupPtrTy
545 : Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
546 : AttributeList *Attr,
547 16271: AccessSpecifier AS) {
548 : // Parse the common declaration-specifiers piece.
2: branch 0 taken
16269: branch 1 taken
549 16271: if (Attr)
550 2: DS.AddAttributes(Attr);
551 :
552 16271: ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
553 :
554 : // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
555 : // declaration-specifiers init-declarator-list[opt] ';'
2983: branch 1 taken
13288: branch 2 taken
556 16271: if (Tok.is(tok::semi)) {
557 2983: ConsumeToken();
558 2983: DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
559 2983: DS.complete(TheDecl);
560 2983: return Actions.ConvertDeclToDeclGroup(TheDecl);
561 : }
562 :
563 : // ObjC2 allows prefix attributes on class interfaces and protocols.
564 : // FIXME: This still needs better diagnostics. We should only accept
565 : // attributes here, no types, etc.
2833: branch 1 taken
10455: branch 2 taken
22: branch 4 taken
2811: branch 5 taken
22: branch 6 taken
13266: branch 7 taken
566 13288: if (getLang().ObjC2 && Tok.is(tok::at)) {
567 22: SourceLocation AtLoc = ConsumeToken(); // the "@"
7: branch 1 taken
15: branch 2 taken
2: branch 4 taken
5: branch 5 taken
2: branch 6 taken
20: branch 7 taken
568 22: if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
569 : !Tok.isObjCAtKeyword(tok::objc_protocol)) {
570 2: Diag(Tok, diag::err_objc_unexpected_attr);
571 2: SkipUntil(tok::semi); // FIXME: better skip?
572 2: return DeclGroupPtrTy();
573 : }
574 :
575 20: DS.abort();
576 :
577 20: const char *PrevSpec = 0;
578 : unsigned DiagID;
1: branch 1 taken
19: branch 2 taken
579 20: if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID))
580 1: Diag(AtLoc, DiagID) << PrevSpec;
581 :
582 20: DeclPtrTy TheDecl;
5: branch 1 taken
15: branch 2 taken
583 20: if (Tok.isObjCAtKeyword(tok::objc_protocol))
584 5: TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
585 : else
586 15: TheDecl = ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
587 20: return Actions.ConvertDeclToDeclGroup(TheDecl);
588 : }
589 :
590 : // If the declspec consisted only of 'extern' and we have a string
591 : // literal following it, this must be a C++ linkage specifier like
592 : // 'extern "C"'.
111: branch 1 taken
13155: branch 2 taken
111: branch 4 taken
0: branch 5 not taken
111: branch 7 taken
0: branch 8 not taken
111: branch 10 taken
0: branch 11 not taken
111: branch 12 taken
13155: branch 13 taken
593 13266: if (Tok.is(tok::string_literal) && getLang().CPlusPlus &&
594 : DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
595 : DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
596 111: DeclPtrTy TheDecl = ParseLinkage(DS, Declarator::FileContext);
597 111: return Actions.ConvertDeclToDeclGroup(TheDecl);
598 : }
599 :
600 13155: return ParseDeclGroup(DS, Declarator::FileContext, true);
601 : }
602 :
603 : Parser::DeclGroupPtrTy
604 : Parser::ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
605 16201: AccessSpecifier AS) {
606 16201: ParsingDeclSpec DS(*this);
607 16201: return ParseDeclarationOrFunctionDefinition(DS, Attr, AS);
608 : }
609 :
610 : /// ParseFunctionDefinition - We parsed and verified that the specified
611 : /// Declarator is well formed. If this is a K&R-style function, read the
612 : /// parameters declaration-list, then start the compound-statement.
613 : ///
614 : /// function-definition: [C99 6.9.1]
615 : /// decl-specs declarator declaration-list[opt] compound-statement
616 : /// [C90] function-definition: [C99 6.7.1] - implicit int result
617 : /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
618 : /// [C++] function-definition: [C++ 8.4]
619 : /// decl-specifier-seq[opt] declarator ctor-initializer[opt]
620 : /// function-body
621 : /// [C++] function-definition: [C++ 8.4]
622 : /// decl-specifier-seq[opt] declarator function-try-block
623 : ///
624 : Parser::DeclPtrTy Parser::ParseFunctionDefinition(ParsingDeclarator &D,
625 7210: const ParsedTemplateInfo &TemplateInfo) {
626 7210: const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0);
627 : assert(FnTypeInfo.Kind == DeclaratorChunk::Function &&
0: branch 0 not taken
7210: branch 1 taken
628 7210: "This isn't a function declarator!");
629 7210: const DeclaratorChunk::FunctionTypeInfo &FTI = FnTypeInfo.Fun;
630 :
631 : // If this is C90 and the declspecs were completely missing, fudge in an
632 : // implicit int. We do this here because this is the only place where
633 : // declaration-specifiers are completely optional in the grammar.
53: branch 1 taken
7157: branch 2 taken
1: branch 5 taken
52: branch 6 taken
1: branch 7 taken
7209: branch 8 taken
634 7210: if (getLang().ImplicitInt && D.getDeclSpec().isEmpty()) {
635 : const char *PrevSpec;
636 : unsigned DiagID;
637 : D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
638 : D.getIdentifierLoc(),
639 1: PrevSpec, DiagID);
640 1: D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin());
641 : }
642 :
643 : // If this declaration was formed with a K&R-style identifier list for the
644 : // arguments, parse declarations for all of the args next.
645 : // int foo(a,b) int a; float b; {}
1601: branch 0 taken
5609: branch 1 taken
53: branch 2 taken
1548: branch 3 taken
646 7210: if (!FTI.hasPrototype && FTI.NumArgs != 0)
647 53: ParseKNRParamDeclarations(D);
648 :
649 : // We should have either an opening brace or, in a C++ constructor,
650 : // we may have a colon.
12: branch 1 taken
7198: branch 2 taken
5: branch 4 taken
7: branch 5 taken
0: branch 7 not taken
5: branch 8 taken
0: branch 9 not taken
7210: branch 10 taken
651 7210: if (Tok.isNot(tok::l_brace) && Tok.isNot(tok::colon) &&
652 : Tok.isNot(tok::kw_try)) {
653 0: Diag(Tok, diag::err_expected_fn_body);
654 :
655 : // Skip over garbage, until we get to '{'. Don't eat the '{'.
656 0: SkipUntil(tok::l_brace, true, true);
657 :
658 : // If we didn't find the '{', bail out.
0: branch 1 not taken
0: branch 2 not taken
659 0: if (Tok.isNot(tok::l_brace))
660 0: return DeclPtrTy();
661 : }
662 :
663 : // Enter a scope for the function body.
664 7210: ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
665 :
666 : // Tell the actions module that we have entered a function definition with the
667 : // specified Declarator for the function.
668 : DeclPtrTy Res = TemplateInfo.TemplateParams?
669 : Actions.ActOnStartOfFunctionTemplateDef(CurScope,
670 : Action::MultiTemplateParamsArg(Actions,
671 : TemplateInfo.TemplateParams->data(),
672 : TemplateInfo.TemplateParams->size()),
673 : D)
297: branch 0 taken
6913: branch 1 taken
674 7210: : Actions.ActOnStartOfFunctionDef(CurScope, D);
675 :
676 : // Break out of the ParsingDeclarator context before we parse the body.
677 7210: D.complete(Res);
678 :
679 : // Break out of the ParsingDeclSpec context, too. This const_cast is
680 : // safe because we're always the sole owner.
681 7210: D.getMutableDeclSpec().abort();
682 :
5: branch 1 taken
7205: branch 2 taken
683 7210: if (Tok.is(tok::kw_try))
684 5: return ParseFunctionTryBlock(Res);
685 :
686 : // If we have a colon, then we're probably parsing a C++
687 : // ctor-initializer.
7: branch 1 taken
7198: branch 2 taken
688 7205: if (Tok.is(tok::colon))
689 7: ParseConstructorInitializer(Res);
690 : else
691 7198: Actions.ActOnDefaultCtorInitializers(Res);
692 :
693 7205: return ParseFunctionStatementBody(Res);
694 : }
695 :
696 : /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
697 : /// types for a function with a K&R-style identifier list for arguments.
698 53: void Parser::ParseKNRParamDeclarations(Declarator &D) {
699 : // We know that the top-level of this declarator is a function.
700 53: DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
701 :
702 : // Enter function-declaration scope, limiting any declarators to the
703 : // function prototype scope, including parameter declarators.
704 53: ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope|Scope::DeclScope);
705 :
706 : // Read all the argument declarations.
57: branch 2 taken
0: branch 3 not taken
57: branch 5 taken
53: branch 6 taken
707 220: while (isDeclarationSpecifier()) {
708 57: SourceLocation DSStart = Tok.getLocation();
709 :
710 : // Parse the common declaration-specifiers piece.
711 57: DeclSpec DS;
712 57: ParseDeclarationSpecifiers(DS);
713 :
714 : // C99 6.9.1p6: 'each declaration in the declaration list shall have at
715 : // least one declarator'.
716 : // NOTE: GCC just makes this an ext-warn. It's not clear what it does with
717 : // the declarations though. It's trivial to ignore them, really hard to do
718 : // anything else with them.
0: branch 1 not taken
57: branch 2 taken
719 57: if (Tok.is(tok::semi)) {
720 0: Diag(DSStart, diag::err_declaration_does_not_declare_param);
721 0: ConsumeToken();
722 0: continue;
723 : }
724 :
725 : // C99 6.9.1p6: Declarations shall contain no storage-class specifiers other
726 : // than register.
0: branch 1 not taken
57: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
57: branch 7 taken
727 57: if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified &&
728 : DS.getStorageClassSpec() != DeclSpec::SCS_register) {
729 : Diag(DS.getStorageClassSpecLoc(),
730 0: diag::err_invalid_storage_class_in_func_decl);
731 0: DS.ClearStorageClassSpecs();
732 : }
0: branch 1 not taken
57: branch 2 taken
733 57: if (DS.isThreadSpecified()) {
734 : Diag(DS.getThreadSpecLoc(),
735 0: diag::err_invalid_storage_class_in_func_decl);
736 0: DS.ClearStorageClassSpecs();
737 : }
738 :
739 : // Parse the first declarator attached to this declspec.
740 57: Declarator ParmDeclarator(DS, Declarator::KNRTypeListContext);
741 57: ParseDeclarator(ParmDeclarator);
742 :
743 : // Handle the full declarator list.
744 8: while (1) {
745 : Action::AttrTy *AttrList;
746 : // If attributes are present, parse them.
0: branch 1 not taken
65: branch 2 taken
747 65: if (Tok.is(tok::kw___attribute))
748 : // FIXME: attach attributes too.
749 0: AttrList = ParseGNUAttributes();
750 :
751 : // Ask the actions module to compute the type for this declarator.
752 : Action::DeclPtrTy Param =
753 65: Actions.ActOnParamDeclarator(CurScope, ParmDeclarator);
754 :
60: branch 1 taken
5: branch 2 taken
59: branch 4 taken
1: branch 5 taken
59: branch 6 taken
6: branch 7 taken
755 65: if (Param &&
756 : // A missing identifier has already been diagnosed.
757 : ParmDeclarator.getIdentifier()) {
758 :
759 : // Scan the argument list looking for the correct param to apply this
760 : // type.
761 88: for (unsigned i = 0; ; ++i) {
762 : // C99 6.9.1p6: those declarators shall declare only identifiers from
763 : // the identifier list.
0: branch 0 not taken
88: branch 1 taken
764 88: if (i == FTI.NumArgs) {
765 : Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param)
766 0: << ParmDeclarator.getIdentifier();
767 0: break;
768 : }
769 :
59: branch 1 taken
29: branch 2 taken
770 88: if (FTI.ArgInfo[i].Ident == ParmDeclarator.getIdentifier()) {
771 : // Reject redefinitions of parameters.
0: branch 1 not taken
59: branch 2 taken
772 59: if (FTI.ArgInfo[i].Param) {
773 : Diag(ParmDeclarator.getIdentifierLoc(),
774 : diag::err_param_redefinition)
775 0: << ParmDeclarator.getIdentifier();
776 : } else {
777 59: FTI.ArgInfo[i].Param = Param;
778 : }
779 59: break;
780 : }
781 : }
782 : }
783 :
784 : // If we don't have a comma, it is either the end of the list (a ';') or
785 : // an error, bail out.
8: branch 1 taken
57: branch 2 taken
786 65: if (Tok.isNot(tok::comma))
787 57: break;
788 :
789 : // Consume the comma.
790 8: ConsumeToken();
791 :
792 : // Parse the next declarator.
793 8: ParmDeclarator.clear();
794 8: ParseDeclarator(ParmDeclarator);
795 : }
796 :
57: branch 1 taken
0: branch 2 not taken
797 57: if (Tok.is(tok::semi)) {
798 57: ConsumeToken();
799 : } else {
800 0: Diag(Tok, diag::err_parse_error);
801 : // Skip to end of block or statement
802 0: SkipUntil(tok::semi, true);
0: branch 1 not taken
0: branch 2 not taken
803 0: if (Tok.is(tok::semi))
804 0: ConsumeToken();
805 : }
806 : }
807 :
808 : // The actions module must verify that all arguments were declared.
809 53: Actions.ActOnFinishKNRParamDeclarations(CurScope, D, Tok.getLocation());
810 53: }
811 :
812 :
813 : /// ParseAsmStringLiteral - This is just a normal string-literal, but is not
814 : /// allowed to be a wide string, and is not subject to character translation.
815 : ///
816 : /// [GNU] asm-string-literal:
817 : /// string-literal
818 : ///
819 292: Parser::OwningExprResult Parser::ParseAsmStringLiteral() {
1: branch 1 taken
291: branch 2 taken
820 292: if (!isTokenStringLiteral()) {
821 1: Diag(Tok, diag::err_expected_string_literal);
822 1: return ExprError();
823 : }
824 :
825 291: OwningExprResult Res(ParseStringLiteralExpression());
0: branch 1 not taken
291: branch 2 taken
826 291: if (Res.isInvalid()) return move(Res);
827 :
828 : // TODO: Diagnose: wide string literal in 'asm'
829 :
830 291: return move(Res);
831 : }
832 :
833 : /// ParseSimpleAsm
834 : ///
835 : /// [GNU] simple-asm-expr:
836 : /// 'asm' '(' asm-string-literal ')'
837 : ///
838 46: Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
46: branch 1 taken
0: branch 2 not taken
839 46: assert(Tok.is(tok::kw_asm) && "Not an asm!");
840 46: SourceLocation Loc = ConsumeToken();
841 :
1: branch 1 taken
45: branch 2 taken
842 46: if (Tok.is(tok::kw_volatile)) {
843 : // Remove from the end of 'asm' to the end of 'volatile'.
844 : SourceRange RemovalRange(PP.getLocForEndOfToken(Loc),
845 1: PP.getLocForEndOfToken(Tok.getLocation()));
846 :
847 : Diag(Tok, diag::warn_file_asm_volatile)
848 1: << CodeModificationHint::CreateRemoval(RemovalRange);
849 1: ConsumeToken();
850 : }
851 :
1: branch 1 taken
45: branch 2 taken
852 46: if (Tok.isNot(tok::l_paren)) {
853 1: Diag(Tok, diag::err_expected_lparen_after) << "asm";
854 1: return ExprError();
855 : }
856 :
857 45: Loc = ConsumeParen();
858 :
859 45: OwningExprResult Result(ParseAsmStringLiteral());
860 :
0: branch 1 not taken
45: branch 2 taken
861 45: if (Result.isInvalid()) {
862 0: SkipUntil(tok::r_paren, true, true);
0: branch 0 not taken
0: branch 1 not taken
863 0: if (EndLoc)
864 0: *EndLoc = Tok.getLocation();
865 0: ConsumeAnyToken();
866 : } else {
867 45: Loc = MatchRHSPunctuation(tok::r_paren, Loc);
29: branch 0 taken
16: branch 1 taken
868 45: if (EndLoc)
869 29: *EndLoc = Loc;
870 : }
871 :
872 45: return move(Result);
873 : }
874 :
875 : /// TryAnnotateTypeOrScopeToken - If the current token position is on a
876 : /// typename (possibly qualified in C++) or a C++ scope specifier not followed
877 : /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
878 : /// with a single annotation token representing the typename or C++ scope
879 : /// respectively.
880 : /// This simplifies handling of C++ scope specifiers and allows efficient
881 : /// backtracking without the need to re-parse and resolve nested-names and
882 : /// typenames.
883 : /// It will mainly be called when we expect to treat identifiers as typenames
884 : /// (if they are typenames). For example, in C we do not expect identifiers
885 : /// inside expressions to be treated as typenames so it will not be called
886 : /// for expressions in C.
887 : /// The benefit for C/ObjC is that a typename will be annotated and
888 : /// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
889 : /// will not be called twice, once to check whether we have a declaration
890 : /// specifier, and another one to get the actual type inside
891 : /// ParseDeclarationSpecifiers).
892 : ///
893 : /// This returns true if the token was annotated or an unrecoverable error
894 : /// occurs.
895 : ///
896 : /// Note that this routine emits an error if you call it with ::new or ::delete
897 : /// as the current tokens, so only call it in contexts where these are invalid.
898 21887: bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) {
899 : assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)
900 : || Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)) &&
348: branch 1 taken
21539: branch 2 taken
324: branch 4 taken
24: branch 5 taken
163: branch 7 taken
161: branch 8 taken
163: branch 10 taken
0: branch 11 not taken
901 21887: "Cannot be a type or scope token!");
902 :
161: branch 1 taken
21726: branch 2 taken
903 21887: if (Tok.is(tok::kw_typename)) {
904 : // Parse a C++ typename-specifier, e.g., "typename T::type".
905 : //
906 : // typename-specifier:
907 : // 'typename' '::' [opt] nested-name-specifier identifier
908 : // 'typename' '::' [opt] nested-name-specifier template [opt]
909 : // simple-template-id
910 161: SourceLocation TypenameLoc = ConsumeToken();
911 161: CXXScopeSpec SS;
912 : bool HadNestedNameSpecifier
913 161: = ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
1: branch 0 taken
160: branch 1 taken
914 161: if (!HadNestedNameSpecifier) {
915 1: Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
916 1: return false;
917 : }
918 :
919 160: TypeResult Ty;
135: branch 1 taken
25: branch 2 taken
920 160: if (Tok.is(tok::identifier)) {
921 : // FIXME: check whether the next token is '<', first!
922 : Ty = Actions.ActOnTypenameType(TypenameLoc, SS, *Tok.getIdentifierInfo(),
923 135: Tok.getLocation());
23: branch 1 taken
2: branch 2 taken
924 25: } else if (Tok.is(tok::annot_template_id)) {
925 : TemplateIdAnnotation *TemplateId
926 23: = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
0: branch 0 not taken
23: branch 1 taken
927 23: if (TemplateId->Kind == TNK_Function_template) {
928 : Diag(Tok, diag::err_typename_refers_to_non_type_template)
929 0: << Tok.getAnnotationRange();
930 0: return false;
931 : }
932 :
933 23: AnnotateTemplateIdTokenAsType(0);
934 : assert(Tok.is(tok::annot_typename) &&
23: branch 1 taken
0: branch 2 not taken
935 23: "AnnotateTemplateIdTokenAsType isn't working properly");
23: branch 1 taken
0: branch 2 not taken
936 23: if (Tok.getAnnotationValue())
937 : Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(),
938 23: Tok.getAnnotationValue());
939 : else
940 0: Ty = true;
941 : } else {
942 : Diag(Tok, diag::err_expected_type_name_after_typename)
943 2: << SS.getRange();
944 2: return false;
945 : }
946 :
947 158: SourceLocation EndLoc = Tok.getLastLoc();
948 158: Tok.setKind(tok::annot_typename);
3: branch 1 taken
155: branch 2 taken
949 158: Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get());
950 158: Tok.setAnnotationEndLoc(EndLoc);
951 158: Tok.setLocation(TypenameLoc);
952 158: PP.AnnotateCachedTokens(Tok);
953 158: return true;
954 : }
955 :
956 : // Remembers whether the token was originally a scope annotation.
957 21726: bool wasScopeAnnotation = Tok.is(tok::annot_cxxscope);
958 :
959 21726: CXXScopeSpec SS;
9765: branch 1 taken
11961: branch 2 taken
960 21726: if (getLang().CPlusPlus)
961 9765: ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext);
962 :
21039: branch 1 taken
687: branch 2 taken
963 21726: if (Tok.is(tok::identifier)) {
964 : // Determine whether the identifier is a type name.
11545: branch 0 taken
9494: branch 1 taken
965 21039: if (TypeTy *Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
966 21039: Tok.getLocation(), CurScope, &SS)) {
967 : // This is a typename. Replace the current token in-place with an
968 : // annotation type token.
969 11545: Tok.setKind(tok::annot_typename);
970 11545: Tok.setAnnotationValue(Ty);
971 11545: Tok.setAnnotationEndLoc(Tok.getLocation());
164: branch 1 taken
11381: branch 2 taken
972 11545: if (SS.isNotEmpty()) // it was a C++ qualified type name.
973 164: Tok.setLocation(SS.getBeginLoc());
974 :
975 : // In case the tokens were cached, have Preprocessor replace
976 : // them with the annotation token.
977 11545: PP.AnnotateCachedTokens(Tok);
978 11545: return true;
979 : }
980 :
4594: branch 1 taken
4900: branch 2 taken
981 9494: if (!getLang().CPlusPlus) {
982 : // If we're in C, we can't have :: tokens at all (the lexer won't return
983 : // them). If the identifier is not a type, then it can't be scope either,
984 : // just early exit.
985 4594: return false;
986 : }
987 :
988 : // If this is a template-id, annotate with a template-id or type token.
171: branch 2 taken
4729: branch 3 taken
989 4900: if (NextToken().is(tok::less)) {
990 171: TemplateTy Template;
991 171: UnqualifiedId TemplateName;
992 171: TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
0: branch 0 not taken
171: branch 1 taken
993 171: if (TemplateNameKind TNK
994 : = Actions.isTemplateName(CurScope, SS, TemplateName,
995 : /*ObjectType=*/0, EnteringContext,
996 171: Template)) {
997 : // Consume the identifier.
998 0: ConsumeToken();
0: branch 2 not taken
0: branch 3 not taken
999 0: if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName)) {
1000 : // If an unrecoverable error occurred, we need to return true here,
1001 : // because the token stream is in a damaged state. We may not return
1002 : // a valid identifier.
1003 0: return Tok.isNot(tok::identifier);
1004 : }
171: branch 1 taken
0: branch 2 not taken
1005 171: }
1006 : }
1007 :
1008 : // The current token, which is either an identifier or a
1009 : // template-id, is not part of the annotation. Fall through to
1010 : // push that token back into the stream and complete the C++ scope
1011 : // specifier annotation.
1012 : }
1013 :
610: branch 1 taken
4977: branch 2 taken
1014 5587: if (Tok.is(tok::annot_template_id)) {
1015 : TemplateIdAnnotation *TemplateId
1016 610: = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
479: branch 0 taken
131: branch 1 taken
1017 610: if (TemplateId->Kind == TNK_Type_template) {
1018 : // A template-id that refers to a type was parsed into a
1019 : // template-id annotation in a context where we weren't allowed
1020 : // to produce a type annotation token. Update the template-id
1021 : // annotation token to a type annotation token now.
1022 479: AnnotateTemplateIdTokenAsType(&SS);
1023 479: return true;
1024 : }
1025 : }
1026 :
4363: branch 1 taken
745: branch 2 taken
1027 5108: if (SS.isEmpty())
124: branch 1 taken
4239: branch 2 taken
119: branch 4 taken
5: branch 5 taken
1028 4363: return Tok.isNot(tok::identifier) && Tok.isNot(tok::coloncolon);
1029 :
1030 : // A C++ scope specifier that isn't followed by a typename.
1031 : // Push the current token back into the token stream (or revert it if it is
1032 : // cached) and use an annotation scope token for current token.
39: branch 1 taken
706: branch 2 taken
1033 745: if (PP.isBacktrackEnabled())
1034 39: PP.RevertCachedTokens(1);
1035 : else
1036 706: PP.EnterToken(Tok);
1037 745: Tok.setKind(tok::annot_cxxscope);
1038 745: Tok.setAnnotationValue(SS.getScopeRep());
1039 745: Tok.setAnnotationRange(SS.getRange());
1040 :
1041 : // In case the tokens were cached, have Preprocessor replace them
1042 : // with the annotation token. We don't need to do this if we've
1043 : // just reverted back to the state we were in before being called.
590: branch 0 taken
155: branch 1 taken
1044 745: if (!wasScopeAnnotation)
1045 590: PP.AnnotateCachedTokens(Tok);
1046 745: return true;
1047 : }
1048 :
1049 : /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
1050 : /// annotates C++ scope specifiers and template-ids. This returns
1051 : /// true if the token was annotated or there was an error that could not be
1052 : /// recovered from.
1053 : ///
1054 : /// Note that this routine emits an error if you call it with ::new or ::delete
1055 : /// as the current tokens, so only call it in contexts where these are invalid.
1056 17434: bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
1057 : assert(getLang().CPlusPlus &&
17434: branch 1 taken
0: branch 2 not taken
1058 17434: "Call sites of this function should be guarded by checking for C++");
1059 : assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
24: branch 1 taken
17410: branch 2 taken
24: branch 4 taken
0: branch 5 not taken
1060 17458: "Cannot be a type or scope token!");
1061 :
1062 17434: CXXScopeSpec SS;
16675: branch 1 taken
759: branch 2 taken
1063 17434: if (!ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext))
1064 : // If the token left behind is not an identifier, we either had an error or
1065 : // successfully turned it into an annotation token.
1066 16675: return Tok.isNot(tok::identifier);
1067 :
1068 : // Push the current token back into the token stream (or revert it if it is
1069 : // cached) and use an annotation scope token for current token.
50: branch 1 taken
709: branch 2 taken
1070 759: if (PP.isBacktrackEnabled())
1071 50: PP.RevertCachedTokens(1);
1072 : else
1073 709: PP.EnterToken(Tok);
1074 759: Tok.setKind(tok::annot_cxxscope);
1075 759: Tok.setAnnotationValue(SS.getScopeRep());
1076 759: Tok.setAnnotationRange(SS.getRange());
1077 :
1078 : // In case the tokens were cached, have Preprocessor replace them with the
1079 : // annotation token.
1080 759: PP.AnnotateCachedTokens(Tok);
1081 759: return true;
1082 : }
1083 :
1084 : // Anchor the Parser::FieldCallback vtable to this translation unit.
1085 : // We use a spurious method instead of the destructor because
1086 : // destroying FieldCallbacks can actually be slightly
1087 : // performance-sensitive.
1088 0: void Parser::FieldCallback::_anchor() {
1089 0: }
Generated: 2010-02-10 01:31 by zcov