ParseCXXInlineMethods.cpp revision ca8937111cccdbf7d17c349487a332d6c7c97f91
1//===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===// 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 parsing for C++ class inline methods. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/Parse/ParseDiagnostic.h" 15#include "clang/Parse/Parser.h" 16#include "clang/Sema/DeclSpec.h" 17#include "clang/Sema/Scope.h" 18#include "clang/AST/DeclTemplate.h" 19using namespace clang; 20 21/// ParseCXXInlineMethodDef - We parsed and verified that the specified 22/// Declarator is a well formed C++ inline method definition. Now lex its body 23/// and store its tokens for parsing after the C++ class is complete. 24Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, 25 AttributeList *AccessAttrs, 26 ParsingDeclarator &D, 27 const ParsedTemplateInfo &TemplateInfo, 28 const VirtSpecifiers& VS, 29 FunctionDefinitionKind DefinitionKind, 30 ExprResult& Init) { 31 assert(D.isFunctionDeclarator() && "This isn't a function declarator!"); 32 assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try) || 33 Tok.is(tok::equal)) && 34 "Current token not a '{', ':', '=', or 'try'!"); 35 36 MultiTemplateParamsArg TemplateParams(Actions, 37 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0, 38 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0); 39 40 Decl *FnD; 41 D.setFunctionDefinitionKind(DefinitionKind); 42 if (D.getDeclSpec().isFriendSpecified()) 43 FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, 44 move(TemplateParams)); 45 else { 46 FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D, 47 move(TemplateParams), 0, 48 VS, /*HasDeferredInit=*/false); 49 if (FnD) { 50 Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs, 51 false, true); 52 bool TypeSpecContainsAuto 53 = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto; 54 if (Init.isUsable()) 55 Actions.AddInitializerToDecl(FnD, Init.get(), false, 56 TypeSpecContainsAuto); 57 else 58 Actions.ActOnUninitializedDecl(FnD, TypeSpecContainsAuto); 59 } 60 } 61 62 HandleMemberFunctionDefaultArgs(D, FnD); 63 64 D.complete(FnD); 65 66 if (Tok.is(tok::equal)) { 67 ConsumeToken(); 68 69 if (!FnD) { 70 SkipUntil(tok::semi); 71 return 0; 72 } 73 74 bool Delete = false; 75 SourceLocation KWLoc; 76 if (Tok.is(tok::kw_delete)) { 77 Diag(Tok, getLangOpts().CPlusPlus0x ? 78 diag::warn_cxx98_compat_deleted_function : 79 diag::ext_deleted_function); 80 81 KWLoc = ConsumeToken(); 82 Actions.SetDeclDeleted(FnD, KWLoc); 83 Delete = true; 84 } else if (Tok.is(tok::kw_default)) { 85 Diag(Tok, getLangOpts().CPlusPlus0x ? 86 diag::warn_cxx98_compat_defaulted_function : 87 diag::ext_defaulted_function); 88 89 KWLoc = ConsumeToken(); 90 Actions.SetDeclDefaulted(FnD, KWLoc); 91 } else { 92 llvm_unreachable("function definition after = not 'delete' or 'default'"); 93 } 94 95 if (Tok.is(tok::comma)) { 96 Diag(KWLoc, diag::err_default_delete_in_multiple_declaration) 97 << Delete; 98 SkipUntil(tok::semi); 99 } else { 100 ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 101 Delete ? "delete" : "default", tok::semi); 102 } 103 104 return FnD; 105 } 106 107 // In delayed template parsing mode, if we are within a class template 108 // or if we are about to parse function member template then consume 109 // the tokens and store them for parsing at the end of the translation unit. 110 if (getLangOpts().DelayedTemplateParsing && 111 ((Actions.CurContext->isDependentContext() || 112 TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) && 113 !Actions.IsInsideALocalClassWithinATemplateFunction())) { 114 115 if (FnD) { 116 LateParsedTemplatedFunction *LPT = new LateParsedTemplatedFunction(FnD); 117 118 FunctionDecl *FD = 0; 119 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(FnD)) 120 FD = FunTmpl->getTemplatedDecl(); 121 else 122 FD = cast<FunctionDecl>(FnD); 123 Actions.CheckForFunctionRedefinition(FD); 124 125 LateParsedTemplateMap[FD] = LPT; 126 Actions.MarkAsLateParsedTemplate(FD); 127 LexTemplateFunctionForLateParsing(LPT->Toks); 128 } else { 129 CachedTokens Toks; 130 LexTemplateFunctionForLateParsing(Toks); 131 } 132 133 return FnD; 134 } 135 136 // Consume the tokens and store them for later parsing. 137 138 LexedMethod* LM = new LexedMethod(this, FnD); 139 getCurrentClass().LateParsedDeclarations.push_back(LM); 140 LM->TemplateScope = getCurScope()->isTemplateParamScope(); 141 CachedTokens &Toks = LM->Toks; 142 143 tok::TokenKind kind = Tok.getKind(); 144 // Consume everything up to (and including) the left brace of the 145 // function body. 146 if (ConsumeAndStoreFunctionPrologue(Toks)) { 147 // We didn't find the left-brace we expected after the 148 // constructor initializer; we already printed an error, and it's likely 149 // impossible to recover, so don't try to parse this method later. 150 // If we stopped at a semicolon, consume it to avoid an extra warning. 151 if (Tok.is(tok::semi)) 152 ConsumeToken(); 153 delete getCurrentClass().LateParsedDeclarations.back(); 154 getCurrentClass().LateParsedDeclarations.pop_back(); 155 return FnD; 156 } else { 157 // Consume everything up to (and including) the matching right brace. 158 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 159 } 160 161 // If we're in a function-try-block, we need to store all the catch blocks. 162 if (kind == tok::kw_try) { 163 while (Tok.is(tok::kw_catch)) { 164 ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false); 165 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 166 } 167 } 168 169 170 if (!FnD) { 171 // If semantic analysis could not build a function declaration, 172 // just throw away the late-parsed declaration. 173 delete getCurrentClass().LateParsedDeclarations.back(); 174 getCurrentClass().LateParsedDeclarations.pop_back(); 175 } 176 177 return FnD; 178} 179 180/// ParseCXXNonStaticMemberInitializer - We parsed and verified that the 181/// specified Declarator is a well formed C++ non-static data member 182/// declaration. Now lex its initializer and store its tokens for parsing 183/// after the class is complete. 184void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) { 185 assert((Tok.is(tok::l_brace) || Tok.is(tok::equal)) && 186 "Current token not a '{' or '='!"); 187 188 LateParsedMemberInitializer *MI = 189 new LateParsedMemberInitializer(this, VarD); 190 getCurrentClass().LateParsedDeclarations.push_back(MI); 191 CachedTokens &Toks = MI->Toks; 192 193 tok::TokenKind kind = Tok.getKind(); 194 if (kind == tok::equal) { 195 Toks.push_back(Tok); 196 ConsumeToken(); 197 } 198 199 if (kind == tok::l_brace) { 200 // Begin by storing the '{' token. 201 Toks.push_back(Tok); 202 ConsumeBrace(); 203 204 // Consume everything up to (and including) the matching right brace. 205 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/true); 206 } else { 207 // Consume everything up to (but excluding) the comma or semicolon. 208 ConsumeAndStoreUntil(tok::comma, Toks, /*StopAtSemi=*/true, 209 /*ConsumeFinalToken=*/false); 210 } 211 212 // Store an artificial EOF token to ensure that we don't run off the end of 213 // the initializer when we come to parse it. 214 Token Eof; 215 Eof.startToken(); 216 Eof.setKind(tok::eof); 217 Eof.setLocation(Tok.getLocation()); 218 Toks.push_back(Eof); 219} 220 221Parser::LateParsedDeclaration::~LateParsedDeclaration() {} 222void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {} 223void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {} 224void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {} 225 226Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C) 227 : Self(P), Class(C) {} 228 229Parser::LateParsedClass::~LateParsedClass() { 230 Self->DeallocateParsedClasses(Class); 231} 232 233void Parser::LateParsedClass::ParseLexedMethodDeclarations() { 234 Self->ParseLexedMethodDeclarations(*Class); 235} 236 237void Parser::LateParsedClass::ParseLexedMemberInitializers() { 238 Self->ParseLexedMemberInitializers(*Class); 239} 240 241void Parser::LateParsedClass::ParseLexedMethodDefs() { 242 Self->ParseLexedMethodDefs(*Class); 243} 244 245void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() { 246 Self->ParseLexedMethodDeclaration(*this); 247} 248 249void Parser::LexedMethod::ParseLexedMethodDefs() { 250 Self->ParseLexedMethodDef(*this); 251} 252 253void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() { 254 Self->ParseLexedMemberInitializer(*this); 255} 256 257/// ParseLexedMethodDeclarations - We finished parsing the member 258/// specification of a top (non-nested) C++ class. Now go over the 259/// stack of method declarations with some parts for which parsing was 260/// delayed (such as default arguments) and parse them. 261void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { 262 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 263 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); 264 if (HasTemplateScope) 265 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 266 267 // The current scope is still active if we're the top-level class. 268 // Otherwise we'll need to push and enter a new scope. 269 bool HasClassScope = !Class.TopLevelClass; 270 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 271 HasClassScope); 272 if (HasClassScope) 273 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); 274 275 for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { 276 Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations(); 277 } 278 279 if (HasClassScope) 280 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); 281} 282 283void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { 284 // If this is a member template, introduce the template parameter scope. 285 ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); 286 if (LM.TemplateScope) 287 Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method); 288 289 // Start the delayed C++ method declaration 290 Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method); 291 292 // Introduce the parameters into scope and parse their default 293 // arguments. 294 ParseScope PrototypeScope(this, 295 Scope::FunctionPrototypeScope|Scope::DeclScope); 296 for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { 297 // Introduce the parameter into scope. 298 Actions.ActOnDelayedCXXMethodParameter(getCurScope(), 299 LM.DefaultArgs[I].Param); 300 301 if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) { 302 // Save the current token position. 303 SourceLocation origLoc = Tok.getLocation(); 304 305 // Parse the default argument from its saved token stream. 306 Toks->push_back(Tok); // So that the current token doesn't get lost 307 PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false); 308 309 // Consume the previously-pushed token. 310 ConsumeAnyToken(); 311 312 // Consume the '='. 313 assert(Tok.is(tok::equal) && "Default argument not starting with '='"); 314 SourceLocation EqualLoc = ConsumeToken(); 315 316 // The argument isn't actually potentially evaluated unless it is 317 // used. 318 EnterExpressionEvaluationContext Eval(Actions, 319 Sema::PotentiallyEvaluatedIfUsed, 320 LM.DefaultArgs[I].Param); 321 322 ExprResult DefArgResult; 323 if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) { 324 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 325 DefArgResult = ParseBraceInitializer(); 326 } else 327 DefArgResult = ParseAssignmentExpression(); 328 if (DefArgResult.isInvalid()) 329 Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param); 330 else { 331 if (Tok.is(tok::cxx_defaultarg_end)) 332 ConsumeToken(); 333 else 334 Diag(Tok.getLocation(), diag::err_default_arg_unparsed); 335 Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc, 336 DefArgResult.take()); 337 } 338 339 assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, 340 Tok.getLocation()) && 341 "ParseAssignmentExpression went over the default arg tokens!"); 342 // There could be leftover tokens (e.g. because of an error). 343 // Skip through until we reach the original token position. 344 while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof)) 345 ConsumeAnyToken(); 346 347 delete Toks; 348 LM.DefaultArgs[I].Toks = 0; 349 } 350 } 351 PrototypeScope.Exit(); 352 353 // Finish the delayed C++ method declaration. 354 Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method); 355} 356 357/// ParseLexedMethodDefs - We finished parsing the member specification of a top 358/// (non-nested) C++ class. Now go over the stack of lexed methods that were 359/// collected during its parsing and parse them all. 360void Parser::ParseLexedMethodDefs(ParsingClass &Class) { 361 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 362 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); 363 if (HasTemplateScope) 364 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 365 366 bool HasClassScope = !Class.TopLevelClass; 367 ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 368 HasClassScope); 369 370 for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { 371 Class.LateParsedDeclarations[i]->ParseLexedMethodDefs(); 372 } 373} 374 375void Parser::ParseLexedMethodDef(LexedMethod &LM) { 376 // If this is a member template, introduce the template parameter scope. 377 ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); 378 if (LM.TemplateScope) 379 Actions.ActOnReenterTemplateScope(getCurScope(), LM.D); 380 381 // Save the current token position. 382 SourceLocation origLoc = Tok.getLocation(); 383 384 assert(!LM.Toks.empty() && "Empty body!"); 385 // Append the current token at the end of the new token stream so that it 386 // doesn't get lost. 387 LM.Toks.push_back(Tok); 388 PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false); 389 390 // Consume the previously pushed token. 391 ConsumeAnyToken(); 392 assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) 393 && "Inline method not starting with '{', ':' or 'try'"); 394 395 // Parse the method body. Function body parsing code is similar enough 396 // to be re-used for method bodies as well. 397 ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); 398 Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); 399 400 if (Tok.is(tok::kw_try)) { 401 ParseFunctionTryBlock(LM.D, FnScope); 402 assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, 403 Tok.getLocation()) && 404 "ParseFunctionTryBlock went over the cached tokens!"); 405 // There could be leftover tokens (e.g. because of an error). 406 // Skip through until we reach the original token position. 407 while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof)) 408 ConsumeAnyToken(); 409 return; 410 } 411 if (Tok.is(tok::colon)) { 412 ParseConstructorInitializer(LM.D); 413 414 // Error recovery. 415 if (!Tok.is(tok::l_brace)) { 416 FnScope.Exit(); 417 Actions.ActOnFinishFunctionBody(LM.D, 0); 418 while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof)) 419 ConsumeAnyToken(); 420 return; 421 } 422 } else 423 Actions.ActOnDefaultCtorInitializers(LM.D); 424 425 ParseFunctionStatementBody(LM.D, FnScope); 426 427 if (Tok.getLocation() != origLoc) { 428 // Due to parsing error, we either went over the cached tokens or 429 // there are still cached tokens left. If it's the latter case skip the 430 // leftover tokens. 431 // Since this is an uncommon situation that should be avoided, use the 432 // expensive isBeforeInTranslationUnit call. 433 if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), 434 origLoc)) 435 while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof)) 436 ConsumeAnyToken(); 437 } 438} 439 440/// ParseLexedMemberInitializers - We finished parsing the member specification 441/// of a top (non-nested) C++ class. Now go over the stack of lexed data member 442/// initializers that were collected during its parsing and parse them all. 443void Parser::ParseLexedMemberInitializers(ParsingClass &Class) { 444 bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 445 ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, 446 HasTemplateScope); 447 if (HasTemplateScope) 448 Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 449 450 // Set or update the scope flags to include Scope::ThisScope. 451 bool AlreadyHasClassScope = Class.TopLevelClass; 452 unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope|Scope::ThisScope; 453 ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope); 454 ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope); 455 456 if (!AlreadyHasClassScope) 457 Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), 458 Class.TagOrTemplate); 459 460 for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { 461 Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers(); 462 } 463 464 if (!AlreadyHasClassScope) 465 Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), 466 Class.TagOrTemplate); 467 468 Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate); 469} 470 471void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { 472 if (!MI.Field || MI.Field->isInvalidDecl()) 473 return; 474 475 // Append the current token at the end of the new token stream so that it 476 // doesn't get lost. 477 MI.Toks.push_back(Tok); 478 PP.EnterTokenStream(MI.Toks.data(), MI.Toks.size(), true, false); 479 480 // Consume the previously pushed token. 481 ConsumeAnyToken(); 482 483 SourceLocation EqualLoc; 484 ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false, 485 EqualLoc); 486 487 Actions.ActOnCXXInClassMemberInitializer(MI.Field, EqualLoc, Init.release()); 488 489 // The next token should be our artificial terminating EOF token. 490 if (Tok.isNot(tok::eof)) { 491 SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation); 492 if (!EndLoc.isValid()) 493 EndLoc = Tok.getLocation(); 494 // No fixit; we can't recover as if there were a semicolon here. 495 Diag(EndLoc, diag::err_expected_semi_decl_list); 496 497 // Consume tokens until we hit the artificial EOF. 498 while (Tok.isNot(tok::eof)) 499 ConsumeAnyToken(); 500 } 501 ConsumeAnyToken(); 502} 503 504/// ConsumeAndStoreUntil - Consume and store the token at the passed token 505/// container until the token 'T' is reached (which gets 506/// consumed/stored too, if ConsumeFinalToken). 507/// If StopAtSemi is true, then we will stop early at a ';' character. 508/// Returns true if token 'T1' or 'T2' was found. 509/// NOTE: This is a specialized version of Parser::SkipUntil. 510bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, 511 CachedTokens &Toks, 512 bool StopAtSemi, bool ConsumeFinalToken) { 513 // We always want this function to consume at least one token if the first 514 // token isn't T and if not at EOF. 515 bool isFirstTokenConsumed = true; 516 while (1) { 517 // If we found one of the tokens, stop and return true. 518 if (Tok.is(T1) || Tok.is(T2)) { 519 if (ConsumeFinalToken) { 520 Toks.push_back(Tok); 521 ConsumeAnyToken(); 522 } 523 return true; 524 } 525 526 switch (Tok.getKind()) { 527 case tok::eof: 528 // Ran out of tokens. 529 return false; 530 531 case tok::l_paren: 532 // Recursively consume properly-nested parens. 533 Toks.push_back(Tok); 534 ConsumeParen(); 535 ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); 536 break; 537 case tok::l_square: 538 // Recursively consume properly-nested square brackets. 539 Toks.push_back(Tok); 540 ConsumeBracket(); 541 ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false); 542 break; 543 case tok::l_brace: 544 // Recursively consume properly-nested braces. 545 Toks.push_back(Tok); 546 ConsumeBrace(); 547 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 548 break; 549 550 // Okay, we found a ']' or '}' or ')', which we think should be balanced. 551 // Since the user wasn't looking for this token (if they were, it would 552 // already be handled), this isn't balanced. If there is a LHS token at a 553 // higher level, we will assume that this matches the unbalanced token 554 // and return it. Otherwise, this is a spurious RHS token, which we skip. 555 case tok::r_paren: 556 if (ParenCount && !isFirstTokenConsumed) 557 return false; // Matches something. 558 Toks.push_back(Tok); 559 ConsumeParen(); 560 break; 561 case tok::r_square: 562 if (BracketCount && !isFirstTokenConsumed) 563 return false; // Matches something. 564 Toks.push_back(Tok); 565 ConsumeBracket(); 566 break; 567 case tok::r_brace: 568 if (BraceCount && !isFirstTokenConsumed) 569 return false; // Matches something. 570 Toks.push_back(Tok); 571 ConsumeBrace(); 572 break; 573 574 case tok::code_completion: 575 Toks.push_back(Tok); 576 ConsumeCodeCompletionToken(); 577 break; 578 579 case tok::string_literal: 580 case tok::wide_string_literal: 581 case tok::utf8_string_literal: 582 case tok::utf16_string_literal: 583 case tok::utf32_string_literal: 584 Toks.push_back(Tok); 585 ConsumeStringToken(); 586 break; 587 case tok::semi: 588 if (StopAtSemi) 589 return false; 590 // FALL THROUGH. 591 default: 592 // consume this token. 593 Toks.push_back(Tok); 594 ConsumeToken(); 595 break; 596 } 597 isFirstTokenConsumed = false; 598 } 599} 600 601/// \brief Consume tokens and store them in the passed token container until 602/// we've passed the try keyword and constructor initializers and have consumed 603/// the opening brace of the function body. The opening brace will be consumed 604/// if and only if there was no error. 605/// 606/// \return True on error. 607bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) { 608 if (Tok.is(tok::kw_try)) { 609 Toks.push_back(Tok); 610 ConsumeToken(); 611 } 612 bool ReadInitializer = false; 613 if (Tok.is(tok::colon)) { 614 // Initializers can contain braces too. 615 Toks.push_back(Tok); 616 ConsumeToken(); 617 618 while (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) { 619 if (Tok.is(tok::eof) || Tok.is(tok::semi)) 620 return Diag(Tok.getLocation(), diag::err_expected_lbrace); 621 622 // Grab the identifier. 623 if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks, 624 /*StopAtSemi=*/true, 625 /*ConsumeFinalToken=*/false)) 626 return Diag(Tok.getLocation(), diag::err_expected_lparen); 627 628 tok::TokenKind kind = Tok.getKind(); 629 Toks.push_back(Tok); 630 bool IsLParen = (kind == tok::l_paren); 631 SourceLocation LOpen = Tok.getLocation(); 632 633 if (IsLParen) { 634 ConsumeParen(); 635 } else { 636 assert(kind == tok::l_brace && "Must be left paren or brace here."); 637 ConsumeBrace(); 638 // In C++03, this has to be the start of the function body, which 639 // means the initializer is malformed; we'll diagnose it later. 640 if (!getLangOpts().CPlusPlus0x) 641 return false; 642 } 643 644 // Grab the initializer 645 if (!ConsumeAndStoreUntil(IsLParen ? tok::r_paren : tok::r_brace, 646 Toks, /*StopAtSemi=*/true)) { 647 Diag(Tok, IsLParen ? diag::err_expected_rparen : 648 diag::err_expected_rbrace); 649 Diag(LOpen, diag::note_matching) << (IsLParen ? "(" : "{"); 650 return true; 651 } 652 653 // Grab pack ellipsis, if present 654 if (Tok.is(tok::ellipsis)) { 655 Toks.push_back(Tok); 656 ConsumeToken(); 657 } 658 659 // Grab the separating comma, if any. 660 if (Tok.is(tok::comma)) { 661 Toks.push_back(Tok); 662 ConsumeToken(); 663 } else if (Tok.isNot(tok::l_brace)) { 664 ReadInitializer = true; 665 break; 666 } 667 } 668 } 669 670 // Grab any remaining garbage to be diagnosed later. We stop when we reach a 671 // brace: an opening one is the function body, while a closing one probably 672 // means we've reached the end of the class. 673 ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks, 674 /*StopAtSemi=*/true, 675 /*ConsumeFinalToken=*/false); 676 if (Tok.isNot(tok::l_brace)) { 677 if (ReadInitializer) 678 return Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma); 679 return Diag(Tok.getLocation(), diag::err_expected_lbrace); 680 } 681 682 Toks.push_back(Tok); 683 ConsumeBrace(); 684 return false; 685} 686