• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
ParseCXXInlineMethodDef(AccessSpecifier AS,AttributeList * AccessAttrs,ParsingDeclarator & D,const ParsedTemplateInfo & TemplateInfo,const VirtSpecifiers & VS,FunctionDefinitionKind DefinitionKind,ExprResult & Init)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.
ParseCXXNonStaticMemberInitializer(Decl * VarD)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 
~LateParsedDeclaration()223 Parser::LateParsedDeclaration::~LateParsedDeclaration() {}
ParseLexedMethodDeclarations()224 void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}
ParseLexedMemberInitializers()225 void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {}
ParseLexedMethodDefs()226 void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}
227 
LateParsedClass(Parser * P,ParsingClass * C)228 Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)
229   : Self(P), Class(C) {}
230 
~LateParsedClass()231 Parser::LateParsedClass::~LateParsedClass() {
232   Self->DeallocateParsedClasses(Class);
233 }
234 
ParseLexedMethodDeclarations()235 void Parser::LateParsedClass::ParseLexedMethodDeclarations() {
236   Self->ParseLexedMethodDeclarations(*Class);
237 }
238 
ParseLexedMemberInitializers()239 void Parser::LateParsedClass::ParseLexedMemberInitializers() {
240   Self->ParseLexedMemberInitializers(*Class);
241 }
242 
ParseLexedMethodDefs()243 void Parser::LateParsedClass::ParseLexedMethodDefs() {
244   Self->ParseLexedMethodDefs(*Class);
245 }
246 
ParseLexedMethodDeclarations()247 void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {
248   Self->ParseLexedMethodDeclaration(*this);
249 }
250 
ParseLexedMethodDefs()251 void Parser::LexedMethod::ParseLexedMethodDefs() {
252   Self->ParseLexedMethodDef(*this);
253 }
254 
ParseLexedMemberInitializers()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.
ParseLexedMethodDeclarations(ParsingClass & Class)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 
ParseLexedMethodDeclaration(LateParsedMethodDeclaration & LM)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.
ParseLexedMethodDefs(ParsingClass & Class)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 
ParseLexedMethodDef(LexedMethod & LM)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.
ParseLexedMemberInitializers(ParsingClass & Class)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 
ParseLexedMemberInitializer(LateParsedMemberInitializer & MI)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.
ConsumeAndStoreUntil(tok::TokenKind T1,tok::TokenKind T2,CachedTokens & Toks,bool StopAtSemi,bool ConsumeFinalToken)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.
ConsumeAndStoreFunctionPrologue(CachedTokens & Toks)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