14cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===//
24cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//
34cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
44cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//
54cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
64cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
74cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//
84cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
94cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//
104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//  This file implements parsing for C++ class inline methods.
114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//
124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
14500d3297d2a21edeac4d46cbcbe21bc2352c2a28Chris Lattner#include "clang/Parse/ParseDiagnostic.h"
154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis#include "clang/Parse/Parser.h"
1619510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/DeclSpec.h"
1719510856727e0e14a3696b2a72c35163bff2a71fJohn McCall#include "clang/Sema/Scope.h"
188387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet#include "clang/AST/DeclTemplate.h"
199257664568bf375b7790131a84d9a4fa30a5b7e3John McCall#include "RAIIObjectsForParser.h"
204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisusing namespace clang;
214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
22d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// ParseCXXInlineMethodDef - We parsed and verified that the specified
234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// Declarator is a well formed C++ inline method definition. Now lex its body
244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// and store its tokens for parsing after the C++ class is complete.
255f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik VerbruggenDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
265f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                      AttributeList *AccessAttrs,
275f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                      ParsingDeclarator &D,
2845fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                      const ParsedTemplateInfo &TemplateInfo,
2945fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                      const VirtSpecifiers& VS,
3045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                      FunctionDefinitionKind DefinitionKind,
3145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                      ExprResult& Init) {
32075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara  assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
33e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt  assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try) ||
34e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt          Tok.is(tok::equal)) &&
35e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt         "Current token not a '{', ':', '=', or 'try'!");
364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
375354e77e60e82828c7c2361f5c688c2667ab59ccBenjamin Kramer  MultiTemplateParamsArg TemplateParams(
384cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt          TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0,
394cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt          TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
404cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt
41d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *FnD;
4245fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor  D.setFunctionDefinitionKind(DefinitionKind);
4367d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  if (D.getDeclSpec().isFriendSpecified())
442c712f50cd56eaf3662989b556e9c6b1e8fcd11aKaelyn Uhrain    FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D,
453fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                          TemplateParams);
46147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor  else {
4723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
483fe198bf0d6118c7b080c17c3bb28d7c84e458b9Benjamin Kramer                                           TemplateParams, 0,
49ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith                                           VS, ICIS_NoInit);
50147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    if (FnD) {
515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs,
525f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                       false, true);
53147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      bool TypeSpecContainsAuto
54147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
55a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      if (Init.isUsable())
56147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        Actions.AddInitializerToDecl(FnD, Init.get(), false,
57147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor                                     TypeSpecContainsAuto);
58147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      else
59147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        Actions.ActOnUninitializedDecl(FnD, TypeSpecContainsAuto);
60147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    }
614867347e82648d3baf09524b98b09c297a5a198fNico Weber  }
624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
6374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  HandleMemberFunctionDeclDelays(D, FnD);
64d33133cdc1af466f9c276249b2621be03867888bEli Friedman
65eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  D.complete(FnD);
66eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
67e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt  if (Tok.is(tok::equal)) {
68e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    ConsumeToken();
69e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
70c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith    if (!FnD) {
71c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith      SkipUntil(tok::semi);
72c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith      return 0;
73c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith    }
74c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith
75e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    bool Delete = false;
76e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    SourceLocation KWLoc;
77e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    if (Tok.is(tok::kw_delete)) {
784e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      Diag(Tok, getLangOpts().CPlusPlus0x ?
797fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::warn_cxx98_compat_deleted_function :
80d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smith           diag::ext_deleted_function);
81e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
82e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      KWLoc = ConsumeToken();
83e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      Actions.SetDeclDeleted(FnD, KWLoc);
84e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      Delete = true;
85e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else if (Tok.is(tok::kw_default)) {
864e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      Diag(Tok, getLangOpts().CPlusPlus0x ?
877fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::warn_cxx98_compat_defaulted_function :
88d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smith           diag::ext_defaulted_function);
89e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
90e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      KWLoc = ConsumeToken();
91e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      Actions.SetDeclDefaulted(FnD, KWLoc);
92e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else {
93e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      llvm_unreachable("function definition after = not 'delete' or 'default'");
94e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
95e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
96e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    if (Tok.is(tok::comma)) {
97e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
98e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        << Delete;
99e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      SkipUntil(tok::semi);
100e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else {
101e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
102e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt                       Delete ? "delete" : "default", tok::semi);
103e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
104e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
105e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    return FnD;
106e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt  }
107e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
1088387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet  // In delayed template parsing mode, if we are within a class template
1098387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet  // or if we are about to parse function member template then consume
1108387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet  // the tokens and store them for parsing at the end of the translation unit.
1114e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().DelayedTemplateParsing &&
1120963017dcbc32176c79a251c3ab23bc35ac784e5Douglas Gregor      DefinitionKind == FDK_Definition &&
1138387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      ((Actions.CurContext->isDependentContext() ||
1148387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet        TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) &&
1159d38dbc9a16017fff3e34b7876a6590413a7d56bFrancois Pichet        !Actions.IsInsideALocalClassWithinATemplateFunction())) {
1168387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1178387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet    if (FnD) {
118e1fca502e7f1349e9b4520a4ca9a02413bcf2b14Francois Pichet      LateParsedTemplatedFunction *LPT = new LateParsedTemplatedFunction(FnD);
1198387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1208387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      FunctionDecl *FD = 0;
1218387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(FnD))
1228387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet        FD = FunTmpl->getTemplatedDecl();
1238387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      else
1248387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet        FD = cast<FunctionDecl>(FnD);
12581542fd91bd5e7e65ebae3eaad117bdaeaf7d737Chandler Carruth      Actions.CheckForFunctionRedefinition(FD);
1268387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1278387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      LateParsedTemplateMap[FD] = LPT;
1288387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      Actions.MarkAsLateParsedTemplate(FD);
1298387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      LexTemplateFunctionForLateParsing(LPT->Toks);
1308387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet    } else {
1318387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      CachedTokens Toks;
1328387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      LexTemplateFunctionForLateParsing(Toks);
1338387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet    }
1348387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1358387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet    return FnD;
1368387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet  }
1378387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Consume the tokens and store them for later parsing.
1394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
140d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  LexedMethod* LM = new LexedMethod(this, FnD);
141d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  getCurrentClass().LateParsedDeclarations.push_back(LM);
142d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  LM->TemplateScope = getCurScope()->isTemplateParamScope();
143d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  CachedTokens &Toks = LM->Toks;
1444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
145d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  tok::TokenKind kind = Tok.getKind();
146a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // Consume everything up to (and including) the left brace of the
147a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // function body.
148a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  if (ConsumeAndStoreFunctionPrologue(Toks)) {
149a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl    // We didn't find the left-brace we expected after the
150e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    // constructor initializer; we already printed an error, and it's likely
151e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    // impossible to recover, so don't try to parse this method later.
152e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    // If we stopped at a semicolon, consume it to avoid an extra warning.
153e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman     if (Tok.is(tok::semi))
154e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      ConsumeToken();
155e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    delete getCurrentClass().LateParsedDeclarations.back();
156e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    getCurrentClass().LateParsedDeclarations.pop_back();
157e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    return FnD;
1587ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } else {
159a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl    // Consume everything up to (and including) the matching right brace.
160a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
1617ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
1624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
163d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  // If we're in a function-try-block, we need to store all the catch blocks.
164d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  if (kind == tok::kw_try) {
165d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl    while (Tok.is(tok::kw_catch)) {
16614b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
16714b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
168d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl    }
169d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  }
170d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
17187f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor
17287f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor  if (!FnD) {
17387f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor    // If semantic analysis could not build a function declaration,
17487f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor    // just throw away the late-parsed declaration.
17587f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor    delete getCurrentClass().LateParsedDeclarations.back();
17687f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor    getCurrentClass().LateParsedDeclarations.pop_back();
17787f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor  }
17887f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor
1794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  return FnD;
1804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
1814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1827a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXNonStaticMemberInitializer - We parsed and verified that the
1837a614d8380297fcd2bc23986241905d97222948cRichard Smith/// specified Declarator is a well formed C++ non-static data member
1847a614d8380297fcd2bc23986241905d97222948cRichard Smith/// declaration. Now lex its initializer and store its tokens for parsing
1857a614d8380297fcd2bc23986241905d97222948cRichard Smith/// after the class is complete.
1867a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) {
1877a614d8380297fcd2bc23986241905d97222948cRichard Smith  assert((Tok.is(tok::l_brace) || Tok.is(tok::equal)) &&
1887a614d8380297fcd2bc23986241905d97222948cRichard Smith         "Current token not a '{' or '='!");
1897a614d8380297fcd2bc23986241905d97222948cRichard Smith
1907a614d8380297fcd2bc23986241905d97222948cRichard Smith  LateParsedMemberInitializer *MI =
1917a614d8380297fcd2bc23986241905d97222948cRichard Smith    new LateParsedMemberInitializer(this, VarD);
1927a614d8380297fcd2bc23986241905d97222948cRichard Smith  getCurrentClass().LateParsedDeclarations.push_back(MI);
1937a614d8380297fcd2bc23986241905d97222948cRichard Smith  CachedTokens &Toks = MI->Toks;
1947a614d8380297fcd2bc23986241905d97222948cRichard Smith
1957a614d8380297fcd2bc23986241905d97222948cRichard Smith  tok::TokenKind kind = Tok.getKind();
1967a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (kind == tok::equal) {
1977a614d8380297fcd2bc23986241905d97222948cRichard Smith    Toks.push_back(Tok);
198d78ef5b941ce2937228b010e8443f92025f9d683Douglas Gregor    ConsumeToken();
1997a614d8380297fcd2bc23986241905d97222948cRichard Smith  }
2007a614d8380297fcd2bc23986241905d97222948cRichard Smith
2017a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (kind == tok::l_brace) {
2027a614d8380297fcd2bc23986241905d97222948cRichard Smith    // Begin by storing the '{' token.
2037a614d8380297fcd2bc23986241905d97222948cRichard Smith    Toks.push_back(Tok);
2047a614d8380297fcd2bc23986241905d97222948cRichard Smith    ConsumeBrace();
2057a614d8380297fcd2bc23986241905d97222948cRichard Smith
2067a614d8380297fcd2bc23986241905d97222948cRichard Smith    // Consume everything up to (and including) the matching right brace.
2077a614d8380297fcd2bc23986241905d97222948cRichard Smith    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/true);
2087a614d8380297fcd2bc23986241905d97222948cRichard Smith  } else {
2097a614d8380297fcd2bc23986241905d97222948cRichard Smith    // Consume everything up to (but excluding) the comma or semicolon.
2107a614d8380297fcd2bc23986241905d97222948cRichard Smith    ConsumeAndStoreUntil(tok::comma, Toks, /*StopAtSemi=*/true,
2117a614d8380297fcd2bc23986241905d97222948cRichard Smith                         /*ConsumeFinalToken=*/false);
2127a614d8380297fcd2bc23986241905d97222948cRichard Smith  }
2137a614d8380297fcd2bc23986241905d97222948cRichard Smith
2147a614d8380297fcd2bc23986241905d97222948cRichard Smith  // Store an artificial EOF token to ensure that we don't run off the end of
2157a614d8380297fcd2bc23986241905d97222948cRichard Smith  // the initializer when we come to parse it.
2167a614d8380297fcd2bc23986241905d97222948cRichard Smith  Token Eof;
2177a614d8380297fcd2bc23986241905d97222948cRichard Smith  Eof.startToken();
2187a614d8380297fcd2bc23986241905d97222948cRichard Smith  Eof.setKind(tok::eof);
2197a614d8380297fcd2bc23986241905d97222948cRichard Smith  Eof.setLocation(Tok.getLocation());
2207a614d8380297fcd2bc23986241905d97222948cRichard Smith  Toks.push_back(Eof);
2217a614d8380297fcd2bc23986241905d97222948cRichard Smith}
2227a614d8380297fcd2bc23986241905d97222948cRichard Smith
223d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedDeclaration::~LateParsedDeclaration() {}
224d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}
2257a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {}
226d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}
227d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
228d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)
229d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  : Self(P), Class(C) {}
230d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
231d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedClass::~LateParsedClass() {
232d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->DeallocateParsedClasses(Class);
233d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
234d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
235d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedClass::ParseLexedMethodDeclarations() {
236d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->ParseLexedMethodDeclarations(*Class);
237d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
238d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
2397a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::LateParsedClass::ParseLexedMemberInitializers() {
2407a614d8380297fcd2bc23986241905d97222948cRichard Smith  Self->ParseLexedMemberInitializers(*Class);
2417a614d8380297fcd2bc23986241905d97222948cRichard Smith}
2427a614d8380297fcd2bc23986241905d97222948cRichard Smith
243d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedClass::ParseLexedMethodDefs() {
244d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->ParseLexedMethodDefs(*Class);
245d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
246d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
247d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {
248d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->ParseLexedMethodDeclaration(*this);
249d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
250d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
251d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LexedMethod::ParseLexedMethodDefs() {
252d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->ParseLexedMethodDef(*this);
253d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
254d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
2557a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {
2567a614d8380297fcd2bc23986241905d97222948cRichard Smith  Self->ParseLexedMemberInitializer(*this);
2577a614d8380297fcd2bc23986241905d97222948cRichard Smith}
2587a614d8380297fcd2bc23986241905d97222948cRichard Smith
25972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// ParseLexedMethodDeclarations - We finished parsing the member
26072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// specification of a top (non-nested) C++ class. Now go over the
26172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// stack of method declarations with some parts for which parsing was
26272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// delayed (such as default arguments) and parse them.
2636569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
2646569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
265d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
2666569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (HasTemplateScope)
26723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
2686569d68745c8213709740337d2be52b031384f58Douglas Gregor
2697a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall  // The current scope is still active if we're the top-level class.
2707a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall  // Otherwise we'll need to push and enter a new scope.
2716569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool HasClassScope = !Class.TopLevelClass;
2724cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
2734cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt                        HasClassScope);
2747a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall  if (HasClassScope)
27523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
2766569d68745c8213709740337d2be52b031384f58Douglas Gregor
277d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
278d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations();
279d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  }
28072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
281d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (HasClassScope)
282d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
283d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
2847fd3a6456a88cdd225b92ae1606144f24c7f51d4Argyrios Kyrtzidis
285d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
286d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // If this is a member template, introduce the template parameter scope.
287d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
288d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (LM.TemplateScope)
289d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method);
290d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
291d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Start the delayed C++ method declaration
292d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
293d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
294d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Introduce the parameters into scope and parse their default
295d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // arguments.
296d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope PrototypeScope(this,
297d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                            Scope::FunctionPrototypeScope|Scope::DeclScope);
298d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
299d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Introduce the parameter into scope.
300ccc1b5eebc6ca8a904c58c0468b9a71483b7c7cfDouglas Gregor    Actions.ActOnDelayedCXXMethodParameter(getCurScope(),
301ccc1b5eebc6ca8a904c58c0468b9a71483b7c7cfDouglas Gregor                                           LM.DefaultArgs[I].Param);
302d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
303d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
304d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Save the current token position.
305d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      SourceLocation origLoc = Tok.getLocation();
306d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
307d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Parse the default argument from its saved token stream.
308d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      Toks->push_back(Tok); // So that the current token doesn't get lost
309d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
310d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
311d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Consume the previously-pushed token.
312d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      ConsumeAnyToken();
313d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
314d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Consume the '='.
315d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      assert(Tok.is(tok::equal) && "Default argument not starting with '='");
316d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      SourceLocation EqualLoc = ConsumeToken();
317d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
318d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // The argument isn't actually potentially evaluated unless it is
319d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // used.
320d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      EnterExpressionEvaluationContext Eval(Actions,
321ccc1b5eebc6ca8a904c58c0468b9a71483b7c7cfDouglas Gregor                                            Sema::PotentiallyEvaluatedIfUsed,
322ccc1b5eebc6ca8a904c58c0468b9a71483b7c7cfDouglas Gregor                                            LM.DefaultArgs[I].Param);
323d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
32484407ba82a10235962901ce269b7b3276d17f01dSebastian Redl      ExprResult DefArgResult;
325ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl      if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
326ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl        Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
32784407ba82a10235962901ce269b7b3276d17f01dSebastian Redl        DefArgResult = ParseBraceInitializer();
328ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl      } else
32984407ba82a10235962901ce269b7b3276d17f01dSebastian Redl        DefArgResult = ParseAssignmentExpression();
330d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      if (DefArgResult.isInvalid())
331d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
332d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      else {
333d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        if (Tok.is(tok::cxx_defaultarg_end))
334d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor          ConsumeToken();
335d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        else
336d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor          Diag(Tok.getLocation(), diag::err_default_arg_unparsed);
337d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
338d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                                          DefArgResult.take());
339d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      }
34072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
341d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
342d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                                                         Tok.getLocation()) &&
343d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor             "ParseAssignmentExpression went over the default arg tokens!");
344d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // There could be leftover tokens (e.g. because of an error).
345d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Skip through until we reach the original token position.
346d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
34772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor        ConsumeAnyToken();
34872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
349d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      delete Toks;
350d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      LM.DefaultArgs[I].Toks = 0;
35172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    }
35272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  }
353a058fd4f0a944174295f77169b438510dad389f8Richard Smith
354d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  PrototypeScope.Exit();
3556569d68745c8213709740337d2be52b031384f58Douglas Gregor
356d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Finish the delayed C++ method declaration.
357d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
35872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor}
35972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
3604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseLexedMethodDefs - We finished parsing the member specification of a top
3614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// (non-nested) C++ class. Now go over the stack of lexed methods that were
3624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// collected during its parsing and parse them all.
3636569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::ParseLexedMethodDefs(ParsingClass &Class) {
3646569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
365d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
3666569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (HasTemplateScope)
36723c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
3686569d68745c8213709740337d2be52b031384f58Douglas Gregor
3696569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool HasClassScope = !Class.TopLevelClass;
3706569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
3716569d68745c8213709740337d2be52b031384f58Douglas Gregor                        HasClassScope);
3726569d68745c8213709740337d2be52b031384f58Douglas Gregor
373d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
374d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Class.LateParsedDeclarations[i]->ParseLexedMethodDefs();
375d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  }
376d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
3774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
378d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::ParseLexedMethodDef(LexedMethod &LM) {
379d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // If this is a member template, introduce the template parameter scope.
380d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
381d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (LM.TemplateScope)
382d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Actions.ActOnReenterTemplateScope(getCurScope(), LM.D);
383d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
384d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Save the current token position.
385d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  SourceLocation origLoc = Tok.getLocation();
386d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
387d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  assert(!LM.Toks.empty() && "Empty body!");
388d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Append the current token at the end of the new token stream so that it
389d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // doesn't get lost.
390d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  LM.Toks.push_back(Tok);
391d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
392d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
393d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Consume the previously pushed token.
394d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ConsumeAnyToken();
395d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
396d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor         && "Inline method not starting with '{', ':' or 'try'");
397d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
398d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Parse the method body. Function body parsing code is similar enough
399d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // to be re-used for method bodies as well.
400d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
401d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
402d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
403d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Tok.is(tok::kw_try)) {
404c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor    ParseFunctionTryBlock(LM.D, FnScope);
405d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
406d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                                                         Tok.getLocation()) &&
407d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor           "ParseFunctionTryBlock went over the cached tokens!");
408d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // There could be leftover tokens (e.g. because of an error).
409d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Skip through until we reach the original token position.
410d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
411d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      ConsumeAnyToken();
412d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    return;
413d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  }
414d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Tok.is(tok::colon)) {
415d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    ParseConstructorInitializer(LM.D);
4164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
417d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Error recovery.
418d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    if (!Tok.is(tok::l_brace)) {
419c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor      FnScope.Exit();
420d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      Actions.ActOnFinishFunctionBody(LM.D, 0);
42110904527359605a76561a49769a2199351a072d8Matt Beaumont-Gay      while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
42210904527359605a76561a49769a2199351a072d8Matt Beaumont-Gay        ConsumeAnyToken();
423d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      return;
424d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    }
425d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  } else
426d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Actions.ActOnDefaultCtorInitializers(LM.D);
427d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
428c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  ParseFunctionStatementBody(LM.D, FnScope);
429d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
430d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Tok.getLocation() != origLoc) {
431d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Due to parsing error, we either went over the cached tokens or
432d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // there are still cached tokens left. If it's the latter case skip the
433d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // leftover tokens.
434d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Since this is an uncommon situation that should be avoided, use the
435d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // expensive isBeforeInTranslationUnit call.
436d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
437d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                                                        origLoc))
4388f9359f5ae1227f3b489d1d261225d8180b64ed3Argyrios Kyrtzidis      while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
4397558cd00a5ac620990174f3cba86aea4bd9a000aArgyrios Kyrtzidis        ConsumeAnyToken();
4407a614d8380297fcd2bc23986241905d97222948cRichard Smith  }
4417a614d8380297fcd2bc23986241905d97222948cRichard Smith}
4427a614d8380297fcd2bc23986241905d97222948cRichard Smith
4437a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseLexedMemberInitializers - We finished parsing the member specification
4447a614d8380297fcd2bc23986241905d97222948cRichard Smith/// of a top (non-nested) C++ class. Now go over the stack of lexed data member
4457a614d8380297fcd2bc23986241905d97222948cRichard Smith/// initializers that were collected during its parsing and parse them all.
4467a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::ParseLexedMemberInitializers(ParsingClass &Class) {
4477a614d8380297fcd2bc23986241905d97222948cRichard Smith  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
4487a614d8380297fcd2bc23986241905d97222948cRichard Smith  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
4497a614d8380297fcd2bc23986241905d97222948cRichard Smith                                HasTemplateScope);
4507a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (HasTemplateScope)
4517a614d8380297fcd2bc23986241905d97222948cRichard Smith    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
4527a614d8380297fcd2bc23986241905d97222948cRichard Smith
453cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor  // Set or update the scope flags.
4547a614d8380297fcd2bc23986241905d97222948cRichard Smith  bool AlreadyHasClassScope = Class.TopLevelClass;
455cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor  unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
4567a614d8380297fcd2bc23986241905d97222948cRichard Smith  ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
4577a614d8380297fcd2bc23986241905d97222948cRichard Smith  ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
4587558cd00a5ac620990174f3cba86aea4bd9a000aArgyrios Kyrtzidis
4597a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (!AlreadyHasClassScope)
4607a614d8380297fcd2bc23986241905d97222948cRichard Smith    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
4617a614d8380297fcd2bc23986241905d97222948cRichard Smith                                                Class.TagOrTemplate);
4627a614d8380297fcd2bc23986241905d97222948cRichard Smith
463268efba18e171d47e847ccdf313498905c32acfaBenjamin Kramer  if (!Class.LateParsedDeclarations.empty()) {
464cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    // C++11 [expr.prim.general]p4:
465cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    //   Otherwise, if a member-declarator declares a non-static data member
466cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    //  (9.2) of a class X, the expression this is a prvalue of type "pointer
467cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    //  to X" within the optional brace-or-equal-initializer. It shall not
468cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    //  appear elsewhere in the member-declarator.
469cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
470cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor                                     /*TypeQuals=*/(unsigned)0);
471cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor
472cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
473cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor      Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers();
474cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    }
4754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
476cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor
4777a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (!AlreadyHasClassScope)
4787a614d8380297fcd2bc23986241905d97222948cRichard Smith    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
4797a614d8380297fcd2bc23986241905d97222948cRichard Smith                                                 Class.TagOrTemplate);
4807a614d8380297fcd2bc23986241905d97222948cRichard Smith
4817a614d8380297fcd2bc23986241905d97222948cRichard Smith  Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate);
4827a614d8380297fcd2bc23986241905d97222948cRichard Smith}
4837a614d8380297fcd2bc23986241905d97222948cRichard Smith
4847a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
4851991b7139a92d73420336690a870f049e88cfad6Richard Smith  if (!MI.Field || MI.Field->isInvalidDecl())
4867a614d8380297fcd2bc23986241905d97222948cRichard Smith    return;
4877a614d8380297fcd2bc23986241905d97222948cRichard Smith
4887a614d8380297fcd2bc23986241905d97222948cRichard Smith  // Append the current token at the end of the new token stream so that it
4897a614d8380297fcd2bc23986241905d97222948cRichard Smith  // doesn't get lost.
4907a614d8380297fcd2bc23986241905d97222948cRichard Smith  MI.Toks.push_back(Tok);
4917a614d8380297fcd2bc23986241905d97222948cRichard Smith  PP.EnterTokenStream(MI.Toks.data(), MI.Toks.size(), true, false);
4927a614d8380297fcd2bc23986241905d97222948cRichard Smith
4937a614d8380297fcd2bc23986241905d97222948cRichard Smith  // Consume the previously pushed token.
4947a614d8380297fcd2bc23986241905d97222948cRichard Smith  ConsumeAnyToken();
4957a614d8380297fcd2bc23986241905d97222948cRichard Smith
4967a614d8380297fcd2bc23986241905d97222948cRichard Smith  SourceLocation EqualLoc;
497ca5233044ef679840d1ad1c46a36b16e2ee8a6e1Richard Smith
498552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor  ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false,
499552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor                                              EqualLoc);
5007a614d8380297fcd2bc23986241905d97222948cRichard Smith
5017a614d8380297fcd2bc23986241905d97222948cRichard Smith  Actions.ActOnCXXInClassMemberInitializer(MI.Field, EqualLoc, Init.release());
5027a614d8380297fcd2bc23986241905d97222948cRichard Smith
5037a614d8380297fcd2bc23986241905d97222948cRichard Smith  // The next token should be our artificial terminating EOF token.
5047a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (Tok.isNot(tok::eof)) {
5057a614d8380297fcd2bc23986241905d97222948cRichard Smith    SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
5067a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (!EndLoc.isValid())
5077a614d8380297fcd2bc23986241905d97222948cRichard Smith      EndLoc = Tok.getLocation();
5087a614d8380297fcd2bc23986241905d97222948cRichard Smith    // No fixit; we can't recover as if there were a semicolon here.
5097a614d8380297fcd2bc23986241905d97222948cRichard Smith    Diag(EndLoc, diag::err_expected_semi_decl_list);
5107a614d8380297fcd2bc23986241905d97222948cRichard Smith
5117a614d8380297fcd2bc23986241905d97222948cRichard Smith    // Consume tokens until we hit the artificial EOF.
5127a614d8380297fcd2bc23986241905d97222948cRichard Smith    while (Tok.isNot(tok::eof))
5137a614d8380297fcd2bc23986241905d97222948cRichard Smith      ConsumeAnyToken();
5147a614d8380297fcd2bc23986241905d97222948cRichard Smith  }
5157a614d8380297fcd2bc23986241905d97222948cRichard Smith  ConsumeAnyToken();
5164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
5174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
5184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ConsumeAndStoreUntil - Consume and store the token at the passed token
51972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// container until the token 'T' is reached (which gets
5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// consumed/stored too, if ConsumeFinalToken).
52114b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis/// If StopAtSemi is true, then we will stop early at a ';' character.
52272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// Returns true if token 'T1' or 'T2' was found.
5234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// NOTE: This is a specialized version of Parser::SkipUntil.
52472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregorbool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
52572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor                                  CachedTokens &Toks,
52614b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis                                  bool StopAtSemi, bool ConsumeFinalToken) {
5274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // We always want this function to consume at least one token if the first
5284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // token isn't T and if not at EOF.
5294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  bool isFirstTokenConsumed = true;
5304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
5314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we found one of the tokens, stop and return true.
53272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    if (Tok.is(T1) || Tok.is(T2)) {
53372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor      if (ConsumeFinalToken) {
53472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor        Toks.push_back(Tok);
53572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor        ConsumeAnyToken();
53672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor      }
5374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      return true;
5384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
5394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
5404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    switch (Tok.getKind()) {
5414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::eof:
5424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Ran out of tokens.
5434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      return false;
5444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
5454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::l_paren:
5464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Recursively consume properly-nested parens.
5474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
5484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeParen();
54914b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
5504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
5514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::l_square:
5524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Recursively consume properly-nested square brackets.
5534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
5544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeBracket();
55514b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false);
5564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
5574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::l_brace:
5584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Recursively consume properly-nested braces.
5594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
5604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeBrace();
56114b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
5624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
5634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
5644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Okay, we found a ']' or '}' or ')', which we think should be balanced.
5654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Since the user wasn't looking for this token (if they were, it would
5664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // already be handled), this isn't balanced.  If there is a LHS token at a
5674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // higher level, we will assume that this matches the unbalanced token
5684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // and return it.  Otherwise, this is a spurious RHS token, which we skip.
5694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::r_paren:
5704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      if (ParenCount && !isFirstTokenConsumed)
5714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        return false;  // Matches something.
5724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
5734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeParen();
5744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
5754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::r_square:
5764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      if (BracketCount && !isFirstTokenConsumed)
5774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        return false;  // Matches something.
5784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
5794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeBracket();
5804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
5814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::r_brace:
5824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      if (BraceCount && !isFirstTokenConsumed)
5834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        return false;  // Matches something.
5844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
5854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeBrace();
5864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
5874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
5887d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    case tok::code_completion:
5897d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      Toks.push_back(Tok);
5907d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      ConsumeCodeCompletionToken();
5917d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      break;
5927d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis
5934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::string_literal:
5944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::wide_string_literal:
5955cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    case tok::utf8_string_literal:
5965cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    case tok::utf16_string_literal:
5975cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    case tok::utf32_string_literal:
5984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
5994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeStringToken();
6004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
60114b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis    case tok::semi:
60214b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      if (StopAtSemi)
60314b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis        return false;
60414b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      // FALL THROUGH.
6054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    default:
6064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // consume this token.
6074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
6094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
6104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
6114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    isFirstTokenConsumed = false;
6124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
6134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
6146df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
6156df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl/// \brief Consume tokens and store them in the passed token container until
6166df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl/// we've passed the try keyword and constructor initializers and have consumed
617a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl/// the opening brace of the function body. The opening brace will be consumed
618a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl/// if and only if there was no error.
6196df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl///
620a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl/// \return True on error.
621a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redlbool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
6226df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl  if (Tok.is(tok::kw_try)) {
6236df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    Toks.push_back(Tok);
6246df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    ConsumeToken();
6256df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl  }
626e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman  bool ReadInitializer = false;
6276df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl  if (Tok.is(tok::colon)) {
6286df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    // Initializers can contain braces too.
6296df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    Toks.push_back(Tok);
6306df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    ConsumeToken();
6316df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
6326df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    while (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
6336df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      if (Tok.is(tok::eof) || Tok.is(tok::semi))
634e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        return Diag(Tok.getLocation(), diag::err_expected_lbrace);
6356df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
6366df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      // Grab the identifier.
6376df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks,
6386df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl                                /*StopAtSemi=*/true,
6396df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl                                /*ConsumeFinalToken=*/false))
640e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        return Diag(Tok.getLocation(), diag::err_expected_lparen);
6416df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
6426df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      tok::TokenKind kind = Tok.getKind();
6436df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      Toks.push_back(Tok);
644e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      bool IsLParen = (kind == tok::l_paren);
645e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      SourceLocation LOpen = Tok.getLocation();
646e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman
647e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      if (IsLParen) {
6486df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl        ConsumeParen();
649e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      } else {
6506df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl        assert(kind == tok::l_brace && "Must be left paren or brace here.");
6516df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl        ConsumeBrace();
652a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl        // In C++03, this has to be the start of the function body, which
653e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        // means the initializer is malformed; we'll diagnose it later.
6544e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie        if (!getLangOpts().CPlusPlus0x)
655a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl          return false;
6566df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      }
6576df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
6586df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      // Grab the initializer
659e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      if (!ConsumeAndStoreUntil(IsLParen ? tok::r_paren : tok::r_brace,
660e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman                                Toks, /*StopAtSemi=*/true)) {
661e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        Diag(Tok, IsLParen ? diag::err_expected_rparen :
662e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman                             diag::err_expected_rbrace);
663e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        Diag(LOpen, diag::note_matching) << (IsLParen ? "(" : "{");
6646df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl        return true;
665e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      }
666e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman
667e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      // Grab pack ellipsis, if present
668e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      if (Tok.is(tok::ellipsis)) {
669e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        Toks.push_back(Tok);
670e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        ConsumeToken();
671e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      }
672a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl
673a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl      // Grab the separating comma, if any.
674a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl      if (Tok.is(tok::comma)) {
675a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl        Toks.push_back(Tok);
676a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl        ConsumeToken();
677e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      } else if (Tok.isNot(tok::l_brace)) {
678e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        ReadInitializer = true;
679e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        break;
680a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl      }
6816df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    }
6826df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl  }
6836df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
684a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // Grab any remaining garbage to be diagnosed later. We stop when we reach a
685a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // brace: an opening one is the function body, while a closing one probably
686a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // means we've reached the end of the class.
687e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman  ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,
688e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman                       /*StopAtSemi=*/true,
689e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman                       /*ConsumeFinalToken=*/false);
690e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman  if (Tok.isNot(tok::l_brace)) {
691e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    if (ReadInitializer)
692e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      return Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
693e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    return Diag(Tok.getLocation(), diag::err_expected_lbrace);
694e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman  }
695a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl
696a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  Toks.push_back(Tok);
697a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  ConsumeBrace();
698a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  return false;
6996df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl}
700