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