clang API Documentation
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 }