clang API Documentation

ParseCXXInlineMethods.cpp
Go to the documentation of this file.
00001 //===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements parsing for C++ class inline methods.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/Parse/ParseDiagnostic.h"
00015 #include "clang/Parse/Parser.h"
00016 #include "clang/Sema/DeclSpec.h"
00017 #include "clang/Sema/Scope.h"
00018 #include "clang/AST/DeclTemplate.h"
00019 #include "RAIIObjectsForParser.h"
00020 using namespace clang;
00021 
00022 /// ParseCXXInlineMethodDef - We parsed and verified that the specified
00023 /// Declarator is a well formed C++ inline method definition. Now lex its body
00024 /// and store its tokens for parsing after the C++ class is complete.
00025 Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
00026                                       AttributeList *AccessAttrs,
00027                                       ParsingDeclarator &D,
00028                                       const ParsedTemplateInfo &TemplateInfo,
00029                                       const VirtSpecifiers& VS, 
00030                                       FunctionDefinitionKind DefinitionKind,
00031                                       ExprResult& Init) {
00032   assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
00033   assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try) ||
00034           Tok.is(tok::equal)) &&
00035          "Current token not a '{', ':', '=', or 'try'!");
00036 
00037   MultiTemplateParamsArg TemplateParams(Actions,
00038           TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0,
00039           TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
00040 
00041   Decl *FnD;
00042   D.setFunctionDefinitionKind(DefinitionKind);
00043   if (D.getDeclSpec().isFriendSpecified())
00044     FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D,
00045                                           move(TemplateParams));
00046   else {
00047     FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
00048                                            move(TemplateParams), 0, 
00049                                            VS, /*HasDeferredInit=*/false);
00050     if (FnD) {
00051       Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs,
00052                                        false, true);
00053       bool TypeSpecContainsAuto
00054         = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
00055       if (Init.isUsable())
00056         Actions.AddInitializerToDecl(FnD, Init.get(), false, 
00057                                      TypeSpecContainsAuto);
00058       else
00059         Actions.ActOnUninitializedDecl(FnD, TypeSpecContainsAuto);
00060     }
00061   }
00062 
00063   HandleMemberFunctionDeclDelays(D, FnD);
00064 
00065   D.complete(FnD);
00066 
00067   if (Tok.is(tok::equal)) {
00068     ConsumeToken();
00069 
00070     if (!FnD) {
00071       SkipUntil(tok::semi);
00072       return 0;
00073     }
00074 
00075     bool Delete = false;
00076     SourceLocation KWLoc;
00077     if (Tok.is(tok::kw_delete)) {
00078       Diag(Tok, getLangOpts().CPlusPlus0x ?
00079            diag::warn_cxx98_compat_deleted_function :
00080            diag::ext_deleted_function);
00081 
00082       KWLoc = ConsumeToken();
00083       Actions.SetDeclDeleted(FnD, KWLoc);
00084       Delete = true;
00085     } else if (Tok.is(tok::kw_default)) {
00086       Diag(Tok, getLangOpts().CPlusPlus0x ?
00087            diag::warn_cxx98_compat_defaulted_function :
00088            diag::ext_defaulted_function);
00089 
00090       KWLoc = ConsumeToken();
00091       Actions.SetDeclDefaulted(FnD, KWLoc);
00092     } else {
00093       llvm_unreachable("function definition after = not 'delete' or 'default'");
00094     }
00095 
00096     if (Tok.is(tok::comma)) {
00097       Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
00098         << Delete;
00099       SkipUntil(tok::semi);
00100     } else {
00101       ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
00102                        Delete ? "delete" : "default", tok::semi);
00103     }
00104 
00105     return FnD;
00106   }
00107 
00108   // In delayed template parsing mode, if we are within a class template
00109   // or if we are about to parse function member template then consume
00110   // the tokens and store them for parsing at the end of the translation unit.
00111   if (getLangOpts().DelayedTemplateParsing && 
00112       ((Actions.CurContext->isDependentContext() ||
00113         TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) && 
00114         !Actions.IsInsideALocalClassWithinATemplateFunction())) {
00115 
00116     if (FnD) {
00117       LateParsedTemplatedFunction *LPT = new LateParsedTemplatedFunction(FnD);
00118 
00119       FunctionDecl *FD = 0;
00120       if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(FnD))
00121         FD = FunTmpl->getTemplatedDecl();
00122       else
00123         FD = cast<FunctionDecl>(FnD);
00124       Actions.CheckForFunctionRedefinition(FD);
00125 
00126       LateParsedTemplateMap[FD] = LPT;
00127       Actions.MarkAsLateParsedTemplate(FD);
00128       LexTemplateFunctionForLateParsing(LPT->Toks);
00129     } else {
00130       CachedTokens Toks;
00131       LexTemplateFunctionForLateParsing(Toks);
00132     }
00133 
00134     return FnD;
00135   }
00136 
00137   // Consume the tokens and store them for later parsing.
00138 
00139   LexedMethod* LM = new LexedMethod(this, FnD);
00140   getCurrentClass().LateParsedDeclarations.push_back(LM);
00141   LM->TemplateScope = getCurScope()->isTemplateParamScope();
00142   CachedTokens &Toks = LM->Toks;
00143 
00144   tok::TokenKind kind = Tok.getKind();
00145   // Consume everything up to (and including) the left brace of the
00146   // function body.
00147   if (ConsumeAndStoreFunctionPrologue(Toks)) {
00148     // We didn't find the left-brace we expected after the
00149     // constructor initializer; we already printed an error, and it's likely
00150     // impossible to recover, so don't try to parse this method later.
00151     // If we stopped at a semicolon, consume it to avoid an extra warning.
00152      if (Tok.is(tok::semi))
00153       ConsumeToken();
00154     delete getCurrentClass().LateParsedDeclarations.back();
00155     getCurrentClass().LateParsedDeclarations.pop_back();
00156     return FnD;
00157   } else {
00158     // Consume everything up to (and including) the matching right brace.
00159     ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
00160   }
00161 
00162   // If we're in a function-try-block, we need to store all the catch blocks.
00163   if (kind == tok::kw_try) {
00164     while (Tok.is(tok::kw_catch)) {
00165       ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
00166       ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
00167     }
00168   }
00169 
00170 
00171   if (!FnD) {
00172     // If semantic analysis could not build a function declaration,
00173     // just throw away the late-parsed declaration.
00174     delete getCurrentClass().LateParsedDeclarations.back();
00175     getCurrentClass().LateParsedDeclarations.pop_back();
00176   }
00177 
00178   return FnD;
00179 }
00180 
00181 /// ParseCXXNonStaticMemberInitializer - We parsed and verified that the
00182 /// specified Declarator is a well formed C++ non-static data member
00183 /// declaration. Now lex its initializer and store its tokens for parsing
00184 /// after the class is complete.
00185 void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) {
00186   assert((Tok.is(tok::l_brace) || Tok.is(tok::equal)) &&
00187          "Current token not a '{' or '='!");
00188 
00189   LateParsedMemberInitializer *MI =
00190     new LateParsedMemberInitializer(this, VarD);
00191   getCurrentClass().LateParsedDeclarations.push_back(MI);
00192   CachedTokens &Toks = MI->Toks;
00193 
00194   tok::TokenKind kind = Tok.getKind();
00195   if (kind == tok::equal) {
00196     Toks.push_back(Tok);
00197     ConsumeToken();
00198   }
00199 
00200   if (kind == tok::l_brace) {
00201     // Begin by storing the '{' token.
00202     Toks.push_back(Tok);
00203     ConsumeBrace();
00204 
00205     // Consume everything up to (and including) the matching right brace.
00206     ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/true);
00207   } else {
00208     // Consume everything up to (but excluding) the comma or semicolon.
00209     ConsumeAndStoreUntil(tok::comma, Toks, /*StopAtSemi=*/true,
00210                          /*ConsumeFinalToken=*/false);
00211   }
00212 
00213   // Store an artificial EOF token to ensure that we don't run off the end of
00214   // the initializer when we come to parse it.
00215   Token Eof;
00216   Eof.startToken();
00217   Eof.setKind(tok::eof);
00218   Eof.setLocation(Tok.getLocation());
00219   Toks.push_back(Eof);
00220 }
00221 
00222 Parser::LateParsedDeclaration::~LateParsedDeclaration() {}
00223 void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}
00224 void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {}
00225 void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}
00226 
00227 Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)
00228   : Self(P), Class(C) {}
00229 
00230 Parser::LateParsedClass::~LateParsedClass() {
00231   Self->DeallocateParsedClasses(Class);
00232 }
00233 
00234 void Parser::LateParsedClass::ParseLexedMethodDeclarations() {
00235   Self->ParseLexedMethodDeclarations(*Class);
00236 }
00237 
00238 void Parser::LateParsedClass::ParseLexedMemberInitializers() {
00239   Self->ParseLexedMemberInitializers(*Class);
00240 }
00241 
00242 void Parser::LateParsedClass::ParseLexedMethodDefs() {
00243   Self->ParseLexedMethodDefs(*Class);
00244 }
00245 
00246 void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {
00247   Self->ParseLexedMethodDeclaration(*this);
00248 }
00249 
00250 void Parser::LexedMethod::ParseLexedMethodDefs() {
00251   Self->ParseLexedMethodDef(*this);
00252 }
00253 
00254 void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {
00255   Self->ParseLexedMemberInitializer(*this);
00256 }
00257 
00258 /// ParseLexedMethodDeclarations - We finished parsing the member
00259 /// specification of a top (non-nested) C++ class. Now go over the
00260 /// stack of method declarations with some parts for which parsing was
00261 /// delayed (such as default arguments) and parse them.
00262 void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
00263   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
00264   ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
00265   if (HasTemplateScope)
00266     Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
00267 
00268   // The current scope is still active if we're the top-level class.
00269   // Otherwise we'll need to push and enter a new scope.
00270   bool HasClassScope = !Class.TopLevelClass;
00271   ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
00272                         HasClassScope);
00273   if (HasClassScope)
00274     Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
00275 
00276   for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
00277     Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations();
00278   }
00279 
00280   if (HasClassScope)
00281     Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
00282 }
00283 
00284 void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
00285   // If this is a member template, introduce the template parameter scope.
00286   ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
00287   if (LM.TemplateScope)
00288     Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method);
00289 
00290   // Start the delayed C++ method declaration
00291   Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
00292 
00293   // Introduce the parameters into scope and parse their default
00294   // arguments.
00295   ParseScope PrototypeScope(this,
00296                             Scope::FunctionPrototypeScope|Scope::DeclScope);
00297   for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
00298     // Introduce the parameter into scope.
00299     Actions.ActOnDelayedCXXMethodParameter(getCurScope(), 
00300                                            LM.DefaultArgs[I].Param);
00301 
00302     if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
00303       // Save the current token position.
00304       SourceLocation origLoc = Tok.getLocation();
00305 
00306       // Parse the default argument from its saved token stream.
00307       Toks->push_back(Tok); // So that the current token doesn't get lost
00308       PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
00309 
00310       // Consume the previously-pushed token.
00311       ConsumeAnyToken();
00312 
00313       // Consume the '='.
00314       assert(Tok.is(tok::equal) && "Default argument not starting with '='");
00315       SourceLocation EqualLoc = ConsumeToken();
00316 
00317       // The argument isn't actually potentially evaluated unless it is
00318       // used.
00319       EnterExpressionEvaluationContext Eval(Actions,
00320                                             Sema::PotentiallyEvaluatedIfUsed,
00321                                             LM.DefaultArgs[I].Param);
00322 
00323       ExprResult DefArgResult;
00324       if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
00325         Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
00326         DefArgResult = ParseBraceInitializer();
00327       } else
00328         DefArgResult = ParseAssignmentExpression();
00329       if (DefArgResult.isInvalid())
00330         Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
00331       else {
00332         if (Tok.is(tok::cxx_defaultarg_end))
00333           ConsumeToken();
00334         else
00335           Diag(Tok.getLocation(), diag::err_default_arg_unparsed);
00336         Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
00337                                           DefArgResult.take());
00338       }
00339 
00340       assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
00341                                                          Tok.getLocation()) &&
00342              "ParseAssignmentExpression went over the default arg tokens!");
00343       // There could be leftover tokens (e.g. because of an error).
00344       // Skip through until we reach the original token position.
00345       while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
00346         ConsumeAnyToken();
00347 
00348       delete Toks;
00349       LM.DefaultArgs[I].Toks = 0;
00350     }
00351   }
00352 
00353   PrototypeScope.Exit();
00354 
00355   // Finish the delayed C++ method declaration.
00356   Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
00357 }
00358 
00359 /// ParseLexedMethodDefs - We finished parsing the member specification of a top
00360 /// (non-nested) C++ class. Now go over the stack of lexed methods that were
00361 /// collected during its parsing and parse them all.
00362 void Parser::ParseLexedMethodDefs(ParsingClass &Class) {
00363   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
00364   ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
00365   if (HasTemplateScope)
00366     Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
00367 
00368   bool HasClassScope = !Class.TopLevelClass;
00369   ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
00370                         HasClassScope);
00371 
00372   for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
00373     Class.LateParsedDeclarations[i]->ParseLexedMethodDefs();
00374   }
00375 }
00376 
00377 void Parser::ParseLexedMethodDef(LexedMethod &LM) {
00378   // If this is a member template, introduce the template parameter scope.
00379   ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
00380   if (LM.TemplateScope)
00381     Actions.ActOnReenterTemplateScope(getCurScope(), LM.D);
00382 
00383   // Save the current token position.
00384   SourceLocation origLoc = Tok.getLocation();
00385 
00386   assert(!LM.Toks.empty() && "Empty body!");
00387   // Append the current token at the end of the new token stream so that it
00388   // doesn't get lost.
00389   LM.Toks.push_back(Tok);
00390   PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
00391 
00392   // Consume the previously pushed token.
00393   ConsumeAnyToken();
00394   assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
00395          && "Inline method not starting with '{', ':' or 'try'");
00396 
00397   // Parse the method body. Function body parsing code is similar enough
00398   // to be re-used for method bodies as well.
00399   ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
00400   Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
00401 
00402   if (Tok.is(tok::kw_try)) {
00403     ParseFunctionTryBlock(LM.D, FnScope);
00404     assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
00405                                                          Tok.getLocation()) &&
00406            "ParseFunctionTryBlock went over the cached tokens!");
00407     // There could be leftover tokens (e.g. because of an error).
00408     // Skip through until we reach the original token position.
00409     while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
00410       ConsumeAnyToken();
00411     return;
00412   }
00413   if (Tok.is(tok::colon)) {
00414     ParseConstructorInitializer(LM.D);
00415 
00416     // Error recovery.
00417     if (!Tok.is(tok::l_brace)) {
00418       FnScope.Exit();
00419       Actions.ActOnFinishFunctionBody(LM.D, 0);
00420       while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
00421         ConsumeAnyToken();
00422       return;
00423     }
00424   } else
00425     Actions.ActOnDefaultCtorInitializers(LM.D);
00426 
00427   ParseFunctionStatementBody(LM.D, FnScope);
00428 
00429   if (Tok.getLocation() != origLoc) {
00430     // Due to parsing error, we either went over the cached tokens or
00431     // there are still cached tokens left. If it's the latter case skip the
00432     // leftover tokens.
00433     // Since this is an uncommon situation that should be avoided, use the
00434     // expensive isBeforeInTranslationUnit call.
00435     if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
00436                                                         origLoc))
00437       while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
00438         ConsumeAnyToken();
00439   }
00440 }
00441 
00442 /// ParseLexedMemberInitializers - We finished parsing the member specification
00443 /// of a top (non-nested) C++ class. Now go over the stack of lexed data member
00444 /// initializers that were collected during its parsing and parse them all.
00445 void Parser::ParseLexedMemberInitializers(ParsingClass &Class) {
00446   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
00447   ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
00448                                 HasTemplateScope);
00449   if (HasTemplateScope)
00450     Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
00451 
00452   // Set or update the scope flags.
00453   bool AlreadyHasClassScope = Class.TopLevelClass;
00454   unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
00455   ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
00456   ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
00457 
00458   if (!AlreadyHasClassScope)
00459     Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
00460                                                 Class.TagOrTemplate);
00461 
00462   if (!Class.LateParsedDeclarations.empty()) {
00463     // C++11 [expr.prim.general]p4:
00464     //   Otherwise, if a member-declarator declares a non-static data member 
00465     //  (9.2) of a class X, the expression this is a prvalue of type "pointer
00466     //  to X" within the optional brace-or-equal-initializer. It shall not 
00467     //  appear elsewhere in the member-declarator.
00468     Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
00469                                      /*TypeQuals=*/(unsigned)0);
00470 
00471     for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
00472       Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers();
00473     }
00474   }
00475   
00476   if (!AlreadyHasClassScope)
00477     Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
00478                                                  Class.TagOrTemplate);
00479 
00480   Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate);
00481 }
00482 
00483 void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
00484   if (!MI.Field || MI.Field->isInvalidDecl())
00485     return;
00486 
00487   // Append the current token at the end of the new token stream so that it
00488   // doesn't get lost.
00489   MI.Toks.push_back(Tok);
00490   PP.EnterTokenStream(MI.Toks.data(), MI.Toks.size(), true, false);
00491 
00492   // Consume the previously pushed token.
00493   ConsumeAnyToken();
00494 
00495   SourceLocation EqualLoc;
00496     
00497   ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false, 
00498                                               EqualLoc);
00499 
00500   Actions.ActOnCXXInClassMemberInitializer(MI.Field, EqualLoc, Init.release());
00501 
00502   // The next token should be our artificial terminating EOF token.
00503   if (Tok.isNot(tok::eof)) {
00504     SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
00505     if (!EndLoc.isValid())
00506       EndLoc = Tok.getLocation();
00507     // No fixit; we can't recover as if there were a semicolon here.
00508     Diag(EndLoc, diag::err_expected_semi_decl_list);
00509 
00510     // Consume tokens until we hit the artificial EOF.
00511     while (Tok.isNot(tok::eof))
00512       ConsumeAnyToken();
00513   }
00514   ConsumeAnyToken();
00515 }
00516 
00517 /// ConsumeAndStoreUntil - Consume and store the token at the passed token
00518 /// container until the token 'T' is reached (which gets
00519 /// consumed/stored too, if ConsumeFinalToken).
00520 /// If StopAtSemi is true, then we will stop early at a ';' character.
00521 /// Returns true if token 'T1' or 'T2' was found.
00522 /// NOTE: This is a specialized version of Parser::SkipUntil.
00523 bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
00524                                   CachedTokens &Toks,
00525                                   bool StopAtSemi, bool ConsumeFinalToken) {
00526   // We always want this function to consume at least one token if the first
00527   // token isn't T and if not at EOF.
00528   bool isFirstTokenConsumed = true;
00529   while (1) {
00530     // If we found one of the tokens, stop and return true.
00531     if (Tok.is(T1) || Tok.is(T2)) {
00532       if (ConsumeFinalToken) {
00533         Toks.push_back(Tok);
00534         ConsumeAnyToken();
00535       }
00536       return true;
00537     }
00538 
00539     switch (Tok.getKind()) {
00540     case tok::eof:
00541       // Ran out of tokens.
00542       return false;
00543 
00544     case tok::l_paren:
00545       // Recursively consume properly-nested parens.
00546       Toks.push_back(Tok);
00547       ConsumeParen();
00548       ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
00549       break;
00550     case tok::l_square:
00551       // Recursively consume properly-nested square brackets.
00552       Toks.push_back(Tok);
00553       ConsumeBracket();
00554       ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false);
00555       break;
00556     case tok::l_brace:
00557       // Recursively consume properly-nested braces.
00558       Toks.push_back(Tok);
00559       ConsumeBrace();
00560       ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
00561       break;
00562 
00563     // Okay, we found a ']' or '}' or ')', which we think should be balanced.
00564     // Since the user wasn't looking for this token (if they were, it would
00565     // already be handled), this isn't balanced.  If there is a LHS token at a
00566     // higher level, we will assume that this matches the unbalanced token
00567     // and return it.  Otherwise, this is a spurious RHS token, which we skip.
00568     case tok::r_paren:
00569       if (ParenCount && !isFirstTokenConsumed)
00570         return false;  // Matches something.
00571       Toks.push_back(Tok);
00572       ConsumeParen();
00573       break;
00574     case tok::r_square:
00575       if (BracketCount && !isFirstTokenConsumed)
00576         return false;  // Matches something.
00577       Toks.push_back(Tok);
00578       ConsumeBracket();
00579       break;
00580     case tok::r_brace:
00581       if (BraceCount && !isFirstTokenConsumed)
00582         return false;  // Matches something.
00583       Toks.push_back(Tok);
00584       ConsumeBrace();
00585       break;
00586 
00587     case tok::code_completion:
00588       Toks.push_back(Tok);
00589       ConsumeCodeCompletionToken();
00590       break;
00591 
00592     case tok::string_literal:
00593     case tok::wide_string_literal:
00594     case tok::utf8_string_literal:
00595     case tok::utf16_string_literal:
00596     case tok::utf32_string_literal:
00597       Toks.push_back(Tok);
00598       ConsumeStringToken();
00599       break;
00600     case tok::semi:
00601       if (StopAtSemi)
00602         return false;
00603       // FALL THROUGH.
00604     default:
00605       // consume this token.
00606       Toks.push_back(Tok);
00607       ConsumeToken();
00608       break;
00609     }
00610     isFirstTokenConsumed = false;
00611   }
00612 }
00613 
00614 /// \brief Consume tokens and store them in the passed token container until
00615 /// we've passed the try keyword and constructor initializers and have consumed
00616 /// the opening brace of the function body. The opening brace will be consumed
00617 /// if and only if there was no error.
00618 ///
00619 /// \return True on error. 
00620 bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
00621   if (Tok.is(tok::kw_try)) {
00622     Toks.push_back(Tok);
00623     ConsumeToken();
00624   }
00625   bool ReadInitializer = false;
00626   if (Tok.is(tok::colon)) {
00627     // Initializers can contain braces too.
00628     Toks.push_back(Tok);
00629     ConsumeToken();
00630 
00631     while (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
00632       if (Tok.is(tok::eof) || Tok.is(tok::semi))
00633         return Diag(Tok.getLocation(), diag::err_expected_lbrace);
00634 
00635       // Grab the identifier.
00636       if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks,
00637                                 /*StopAtSemi=*/true,
00638                                 /*ConsumeFinalToken=*/false))
00639         return Diag(Tok.getLocation(), diag::err_expected_lparen);
00640 
00641       tok::TokenKind kind = Tok.getKind();
00642       Toks.push_back(Tok);
00643       bool IsLParen = (kind == tok::l_paren);
00644       SourceLocation LOpen = Tok.getLocation();
00645 
00646       if (IsLParen) {
00647         ConsumeParen();
00648       } else {
00649         assert(kind == tok::l_brace && "Must be left paren or brace here.");
00650         ConsumeBrace();
00651         // In C++03, this has to be the start of the function body, which
00652         // means the initializer is malformed; we'll diagnose it later.
00653         if (!getLangOpts().CPlusPlus0x)
00654           return false;
00655       }
00656 
00657       // Grab the initializer
00658       if (!ConsumeAndStoreUntil(IsLParen ? tok::r_paren : tok::r_brace,
00659                                 Toks, /*StopAtSemi=*/true)) {
00660         Diag(Tok, IsLParen ? diag::err_expected_rparen :
00661                              diag::err_expected_rbrace);
00662         Diag(LOpen, diag::note_matching) << (IsLParen ? "(" : "{");
00663         return true;
00664       }
00665 
00666       // Grab pack ellipsis, if present
00667       if (Tok.is(tok::ellipsis)) {
00668         Toks.push_back(Tok);
00669         ConsumeToken();
00670       }
00671 
00672       // Grab the separating comma, if any.
00673       if (Tok.is(tok::comma)) {
00674         Toks.push_back(Tok);
00675         ConsumeToken();
00676       } else if (Tok.isNot(tok::l_brace)) {
00677         ReadInitializer = true;
00678         break;
00679       }
00680     }
00681   }
00682 
00683   // Grab any remaining garbage to be diagnosed later. We stop when we reach a
00684   // brace: an opening one is the function body, while a closing one probably
00685   // means we've reached the end of the class.
00686   ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,
00687                        /*StopAtSemi=*/true,
00688                        /*ConsumeFinalToken=*/false);
00689   if (Tok.isNot(tok::l_brace)) {
00690     if (ReadInitializer)
00691       return Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
00692     return Diag(Tok.getLocation(), diag::err_expected_lbrace);
00693   }
00694 
00695   Toks.push_back(Tok);
00696   ConsumeBrace();
00697   return false;
00698 }