ParseCXXInlineMethods.cpp 24 KB

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