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"
194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisusing namespace clang;
204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
21d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// ParseCXXInlineMethodDef - We parsed and verified that the specified
224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// Declarator is a well formed C++ inline method definition. Now lex its body
234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// and store its tokens for parsing after the C++ class is complete.
245f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik VerbruggenDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS,
255f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                      AttributeList *AccessAttrs,
265f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                      ParsingDeclarator &D,
2745fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                      const ParsedTemplateInfo &TemplateInfo,
2845fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                      const VirtSpecifiers& VS,
2945fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                      FunctionDefinitionKind DefinitionKind,
3045fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor                                      ExprResult& Init) {
31075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara  assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
32e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt  assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try) ||
33e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt          Tok.is(tok::equal)) &&
34e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt         "Current token not a '{', ':', '=', or 'try'!");
354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
36f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall  MultiTemplateParamsArg TemplateParams(Actions,
374cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt          TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0,
384cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt          TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
394cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt
40d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall  Decl *FnD;
4145fa560c72441069d9e4eb1e66efd87349caa552Douglas Gregor  D.setFunctionDefinitionKind(DefinitionKind);
4267d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall  if (D.getDeclSpec().isFriendSpecified())
432c712f50cd56eaf3662989b556e9c6b1e8fcd11aKaelyn Uhrain    FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D,
444cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt                                          move(TemplateParams));
45147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor  else {
4623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
4769a87357310260c4b2c5dce2cdcd10c3fd3a0a58Anders Carlsson                                           move(TemplateParams), 0,
48a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor                                           VS, /*HasDeferredInit=*/false);
49147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    if (FnD) {
505f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen      Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs,
515f1c822def3efffe1d8f7299fbbbc3b1cdd4833dErik Verbruggen                                       false, true);
52147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      bool TypeSpecContainsAuto
53147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
54a2b4e5d9292688bc67b583592918dbeecae31ea3Douglas Gregor      if (Init.isUsable())
55147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        Actions.AddInitializerToDecl(FnD, Init.get(), false,
56147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor                                     TypeSpecContainsAuto);
57147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor      else
58147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor        Actions.ActOnUninitializedDecl(FnD, TypeSpecContainsAuto);
59147545d698972cfd34ece30a5d55e8180784161eDouglas Gregor    }
604867347e82648d3baf09524b98b09c297a5a198fNico Weber  }
614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
6274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  HandleMemberFunctionDeclDelays(D, FnD);
63d33133cdc1af466f9c276249b2621be03867888bEli Friedman
64eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall  D.complete(FnD);
65eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall
66e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt  if (Tok.is(tok::equal)) {
67e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    ConsumeToken();
68e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
69c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith    if (!FnD) {
70c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith      SkipUntil(tok::semi);
71c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith      return 0;
72c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith    }
73c430ef4f92eedea7d3378f05a2b05982ed3713dcRichard Smith
74e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    bool Delete = false;
75e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    SourceLocation KWLoc;
76e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    if (Tok.is(tok::kw_delete)) {
774e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      Diag(Tok, getLangOpts().CPlusPlus0x ?
787fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::warn_cxx98_compat_deleted_function :
79d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smith           diag::ext_deleted_function);
80e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
81e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      KWLoc = ConsumeToken();
82e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      Actions.SetDeclDeleted(FnD, KWLoc);
83e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      Delete = true;
84e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else if (Tok.is(tok::kw_default)) {
854e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie      Diag(Tok, getLangOpts().CPlusPlus0x ?
867fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith           diag::warn_cxx98_compat_defaulted_function :
87d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smith           diag::ext_defaulted_function);
88e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
89e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      KWLoc = ConsumeToken();
90e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      Actions.SetDeclDefaulted(FnD, KWLoc);
91e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else {
92e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      llvm_unreachable("function definition after = not 'delete' or 'default'");
93e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
94e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
95e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    if (Tok.is(tok::comma)) {
96e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
97e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt        << Delete;
98e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      SkipUntil(tok::semi);
99e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    } else {
100e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt      ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
101e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt                       Delete ? "delete" : "default", tok::semi);
102e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    }
103e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
104e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt    return FnD;
105e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt  }
106e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt
1078387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet  // In delayed template parsing mode, if we are within a class template
1088387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet  // or if we are about to parse function member template then consume
1098387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet  // the tokens and store them for parsing at the end of the translation unit.
1104e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  if (getLangOpts().DelayedTemplateParsing &&
1118387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      ((Actions.CurContext->isDependentContext() ||
1128387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet        TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) &&
1139d38dbc9a16017fff3e34b7876a6590413a7d56bFrancois Pichet        !Actions.IsInsideALocalClassWithinATemplateFunction())) {
1148387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1158387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet    if (FnD) {
116e1fca502e7f1349e9b4520a4ca9a02413bcf2b14Francois Pichet      LateParsedTemplatedFunction *LPT = new LateParsedTemplatedFunction(FnD);
1178387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1188387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      FunctionDecl *FD = 0;
1198387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(FnD))
1208387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet        FD = FunTmpl->getTemplatedDecl();
1218387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      else
1228387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet        FD = cast<FunctionDecl>(FnD);
12381542fd91bd5e7e65ebae3eaad117bdaeaf7d737Chandler Carruth      Actions.CheckForFunctionRedefinition(FD);
1248387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1258387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      LateParsedTemplateMap[FD] = LPT;
1268387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      Actions.MarkAsLateParsedTemplate(FD);
1278387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      LexTemplateFunctionForLateParsing(LPT->Toks);
1288387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet    } else {
1298387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      CachedTokens Toks;
1308387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet      LexTemplateFunctionForLateParsing(Toks);
1318387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet    }
1328387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1338387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet    return FnD;
1348387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet  }
1358387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet
1364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // Consume the tokens and store them for later parsing.
1374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
138d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  LexedMethod* LM = new LexedMethod(this, FnD);
139d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  getCurrentClass().LateParsedDeclarations.push_back(LM);
140d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  LM->TemplateScope = getCurScope()->isTemplateParamScope();
141d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  CachedTokens &Toks = LM->Toks;
1424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
143d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  tok::TokenKind kind = Tok.getKind();
144a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // Consume everything up to (and including) the left brace of the
145a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // function body.
146a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  if (ConsumeAndStoreFunctionPrologue(Toks)) {
147a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl    // We didn't find the left-brace we expected after the
148e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    // constructor initializer; we already printed an error, and it's likely
149e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    // impossible to recover, so don't try to parse this method later.
150e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    // If we stopped at a semicolon, consume it to avoid an extra warning.
151e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman     if (Tok.is(tok::semi))
152e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      ConsumeToken();
153e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    delete getCurrentClass().LateParsedDeclarations.back();
154e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    getCurrentClass().LateParsedDeclarations.pop_back();
155e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    return FnD;
1567ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  } else {
157a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl    // Consume everything up to (and including) the matching right brace.
158a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
1597ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor  }
1604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
161d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  // If we're in a function-try-block, we need to store all the catch blocks.
162d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  if (kind == tok::kw_try) {
163d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl    while (Tok.is(tok::kw_catch)) {
16414b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
16514b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
166d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl    }
167d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl  }
168d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl
16987f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor
17087f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor  if (!FnD) {
17187f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor    // If semantic analysis could not build a function declaration,
17287f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor    // just throw away the late-parsed declaration.
17387f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor    delete getCurrentClass().LateParsedDeclarations.back();
17487f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor    getCurrentClass().LateParsedDeclarations.pop_back();
17587f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor  }
17687f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor
1774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  return FnD;
1784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
1794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
1807a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseCXXNonStaticMemberInitializer - We parsed and verified that the
1817a614d8380297fcd2bc23986241905d97222948cRichard Smith/// specified Declarator is a well formed C++ non-static data member
1827a614d8380297fcd2bc23986241905d97222948cRichard Smith/// declaration. Now lex its initializer and store its tokens for parsing
1837a614d8380297fcd2bc23986241905d97222948cRichard Smith/// after the class is complete.
1847a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) {
1857a614d8380297fcd2bc23986241905d97222948cRichard Smith  assert((Tok.is(tok::l_brace) || Tok.is(tok::equal)) &&
1867a614d8380297fcd2bc23986241905d97222948cRichard Smith         "Current token not a '{' or '='!");
1877a614d8380297fcd2bc23986241905d97222948cRichard Smith
1887a614d8380297fcd2bc23986241905d97222948cRichard Smith  LateParsedMemberInitializer *MI =
1897a614d8380297fcd2bc23986241905d97222948cRichard Smith    new LateParsedMemberInitializer(this, VarD);
1907a614d8380297fcd2bc23986241905d97222948cRichard Smith  getCurrentClass().LateParsedDeclarations.push_back(MI);
1917a614d8380297fcd2bc23986241905d97222948cRichard Smith  CachedTokens &Toks = MI->Toks;
1927a614d8380297fcd2bc23986241905d97222948cRichard Smith
1937a614d8380297fcd2bc23986241905d97222948cRichard Smith  tok::TokenKind kind = Tok.getKind();
1947a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (kind == tok::equal) {
1957a614d8380297fcd2bc23986241905d97222948cRichard Smith    Toks.push_back(Tok);
196d78ef5b941ce2937228b010e8443f92025f9d683Douglas Gregor    ConsumeToken();
1977a614d8380297fcd2bc23986241905d97222948cRichard Smith  }
1987a614d8380297fcd2bc23986241905d97222948cRichard Smith
1997a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (kind == tok::l_brace) {
2007a614d8380297fcd2bc23986241905d97222948cRichard Smith    // Begin by storing the '{' token.
2017a614d8380297fcd2bc23986241905d97222948cRichard Smith    Toks.push_back(Tok);
2027a614d8380297fcd2bc23986241905d97222948cRichard Smith    ConsumeBrace();
2037a614d8380297fcd2bc23986241905d97222948cRichard Smith
2047a614d8380297fcd2bc23986241905d97222948cRichard Smith    // Consume everything up to (and including) the matching right brace.
2057a614d8380297fcd2bc23986241905d97222948cRichard Smith    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/true);
2067a614d8380297fcd2bc23986241905d97222948cRichard Smith  } else {
2077a614d8380297fcd2bc23986241905d97222948cRichard Smith    // Consume everything up to (but excluding) the comma or semicolon.
2087a614d8380297fcd2bc23986241905d97222948cRichard Smith    ConsumeAndStoreUntil(tok::comma, Toks, /*StopAtSemi=*/true,
2097a614d8380297fcd2bc23986241905d97222948cRichard Smith                         /*ConsumeFinalToken=*/false);
2107a614d8380297fcd2bc23986241905d97222948cRichard Smith  }
2117a614d8380297fcd2bc23986241905d97222948cRichard Smith
2127a614d8380297fcd2bc23986241905d97222948cRichard Smith  // Store an artificial EOF token to ensure that we don't run off the end of
2137a614d8380297fcd2bc23986241905d97222948cRichard Smith  // the initializer when we come to parse it.
2147a614d8380297fcd2bc23986241905d97222948cRichard Smith  Token Eof;
2157a614d8380297fcd2bc23986241905d97222948cRichard Smith  Eof.startToken();
2167a614d8380297fcd2bc23986241905d97222948cRichard Smith  Eof.setKind(tok::eof);
2177a614d8380297fcd2bc23986241905d97222948cRichard Smith  Eof.setLocation(Tok.getLocation());
2187a614d8380297fcd2bc23986241905d97222948cRichard Smith  Toks.push_back(Eof);
2197a614d8380297fcd2bc23986241905d97222948cRichard Smith}
2207a614d8380297fcd2bc23986241905d97222948cRichard Smith
221d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedDeclaration::~LateParsedDeclaration() {}
222d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}
2237a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {}
224d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}
225d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
226d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)
227d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  : Self(P), Class(C) {}
228d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
229d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedClass::~LateParsedClass() {
230d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->DeallocateParsedClasses(Class);
231d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
232d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
233d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedClass::ParseLexedMethodDeclarations() {
234d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->ParseLexedMethodDeclarations(*Class);
235d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
236d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
2377a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::LateParsedClass::ParseLexedMemberInitializers() {
2387a614d8380297fcd2bc23986241905d97222948cRichard Smith  Self->ParseLexedMemberInitializers(*Class);
2397a614d8380297fcd2bc23986241905d97222948cRichard Smith}
2407a614d8380297fcd2bc23986241905d97222948cRichard Smith
241d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedClass::ParseLexedMethodDefs() {
242d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->ParseLexedMethodDefs(*Class);
243d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
244d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
245d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {
246d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->ParseLexedMethodDeclaration(*this);
247d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
248d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
249d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LexedMethod::ParseLexedMethodDefs() {
250d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Self->ParseLexedMethodDef(*this);
251d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
252d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
2537a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {
2547a614d8380297fcd2bc23986241905d97222948cRichard Smith  Self->ParseLexedMemberInitializer(*this);
2557a614d8380297fcd2bc23986241905d97222948cRichard Smith}
2567a614d8380297fcd2bc23986241905d97222948cRichard Smith
25772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// ParseLexedMethodDeclarations - We finished parsing the member
25872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// specification of a top (non-nested) C++ class. Now go over the
25972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// stack of method declarations with some parts for which parsing was
26072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// delayed (such as default arguments) and parse them.
2616569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
2626569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
263d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
2646569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (HasTemplateScope)
26523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
2666569d68745c8213709740337d2be52b031384f58Douglas Gregor
2677a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall  // The current scope is still active if we're the top-level class.
2687a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall  // Otherwise we'll need to push and enter a new scope.
2696569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool HasClassScope = !Class.TopLevelClass;
2704cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
2714cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt                        HasClassScope);
2727a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall  if (HasClassScope)
27323c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
2746569d68745c8213709740337d2be52b031384f58Douglas Gregor
275d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
276d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations();
277d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  }
27872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
279d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (HasClassScope)
280d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
281d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
2827fd3a6456a88cdd225b92ae1606144f24c7f51d4Argyrios Kyrtzidis
283d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
284d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // If this is a member template, introduce the template parameter scope.
285d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
286d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (LM.TemplateScope)
287d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method);
288d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
289d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Start the delayed C++ method declaration
290d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
291d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
292d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Introduce the parameters into scope and parse their default
293d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // arguments.
294d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope PrototypeScope(this,
295d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                            Scope::FunctionPrototypeScope|Scope::DeclScope);
296d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
297d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Introduce the parameter into scope.
298ccc1b5eebc6ca8a904c58c0468b9a71483b7c7cfDouglas Gregor    Actions.ActOnDelayedCXXMethodParameter(getCurScope(),
299ccc1b5eebc6ca8a904c58c0468b9a71483b7c7cfDouglas Gregor                                           LM.DefaultArgs[I].Param);
300d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
301d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
302d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Save the current token position.
303d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      SourceLocation origLoc = Tok.getLocation();
304d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
305d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Parse the default argument from its saved token stream.
306d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      Toks->push_back(Tok); // So that the current token doesn't get lost
307d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
308d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
309d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Consume the previously-pushed token.
310d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      ConsumeAnyToken();
311d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
312d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Consume the '='.
313d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      assert(Tok.is(tok::equal) && "Default argument not starting with '='");
314d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      SourceLocation EqualLoc = ConsumeToken();
315d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
316d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // The argument isn't actually potentially evaluated unless it is
317d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // used.
318d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      EnterExpressionEvaluationContext Eval(Actions,
319ccc1b5eebc6ca8a904c58c0468b9a71483b7c7cfDouglas Gregor                                            Sema::PotentiallyEvaluatedIfUsed,
320ccc1b5eebc6ca8a904c58c0468b9a71483b7c7cfDouglas Gregor                                            LM.DefaultArgs[I].Param);
321d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
32284407ba82a10235962901ce269b7b3276d17f01dSebastian Redl      ExprResult DefArgResult;
323ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl      if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
324ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl        Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
32584407ba82a10235962901ce269b7b3276d17f01dSebastian Redl        DefArgResult = ParseBraceInitializer();
326ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl      } else
32784407ba82a10235962901ce269b7b3276d17f01dSebastian Redl        DefArgResult = ParseAssignmentExpression();
328d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      if (DefArgResult.isInvalid())
329d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
330d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      else {
331d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        if (Tok.is(tok::cxx_defaultarg_end))
332d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor          ConsumeToken();
333d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        else
334d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor          Diag(Tok.getLocation(), diag::err_default_arg_unparsed);
335d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor        Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
336d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                                          DefArgResult.take());
337d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      }
33872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
339d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
340d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                                                         Tok.getLocation()) &&
341d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor             "ParseAssignmentExpression went over the default arg tokens!");
342d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // There could be leftover tokens (e.g. because of an error).
343d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      // Skip through until we reach the original token position.
344d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
34572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor        ConsumeAnyToken();
34672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
347d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      delete Toks;
348d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      LM.DefaultArgs[I].Toks = 0;
34972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    }
35072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor  }
35174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
35274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  // Parse a delayed exception-specification, if there is one.
35374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  if (CachedTokens *Toks = LM.ExceptionSpecTokens) {
35474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Save the current token position.
35574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    SourceLocation origLoc = Tok.getLocation();
35674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
35774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Parse the default argument from its saved token stream.
35874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    Toks->push_back(Tok); // So that the current token doesn't get lost
35974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false);
36074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
36174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Consume the previously-pushed token.
36274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    ConsumeAnyToken();
36374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
36474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // C++11 [expr.prim.general]p3:
36574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    //   If a declaration declares a member function or member function
36674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    //   template of a class X, the expression this is a prvalue of type
36774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
36874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    //   and the end of the function-definition, member-declarator, or
36974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    //   declarator.
37074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    CXXMethodDecl *Method;
37174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    if (FunctionTemplateDecl *FunTmpl
37274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor          = dyn_cast<FunctionTemplateDecl>(LM.Method))
37374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      Method = cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
37474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    else
37574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      Method = cast<CXXMethodDecl>(LM.Method);
37674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
37774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    Sema::CXXThisScopeRAII ThisScope(Actions, Method->getParent(),
37874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                     Method->getTypeQualifiers(),
37974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                     getLangOpts().CPlusPlus0x);
38074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
38174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Parse the exception-specification.
38274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    SourceRange SpecificationRange;
38374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    SmallVector<ParsedType, 4> DynamicExceptions;
38474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    SmallVector<SourceRange, 4> DynamicExceptionRanges;
38574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    ExprResult NoexceptExpr;
38674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    CachedTokens *ExceptionSpecTokens;
38774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
38874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    ExceptionSpecificationType EST
38974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange,
39074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                       DynamicExceptions,
39174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                       DynamicExceptionRanges, NoexceptExpr,
39274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                       ExceptionSpecTokens);
39374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
39474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Clean up the remaining tokens.
39574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    if (Tok.is(tok::cxx_exceptspec_end))
39674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      ConsumeToken();
39774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    else if (EST != EST_None)
39874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      Diag(Tok.getLocation(), diag::err_except_spec_unparsed);
39974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
40074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Attach the exception-specification to the method.
40174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    if (EST != EST_None)
40274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      Actions.actOnDelayedExceptionSpecification(LM.Method, EST,
40374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                                 SpecificationRange,
40474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                                 DynamicExceptions,
40574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                                 DynamicExceptionRanges,
40674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                                 NoexceptExpr.isUsable()?
40774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                                   NoexceptExpr.get() : 0);
40874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
40974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
41074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor                                                            Tok.getLocation()) &&
41174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor           "tryParseExceptionSpecification went over the exception tokens!");
41274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
41374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // There could be leftover tokens (e.g. because of an error).
41474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    // Skip through until we reach the original token position.
41574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
41674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      ConsumeAnyToken();
41774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
41874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    delete LM.ExceptionSpecTokens;
41974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    LM.ExceptionSpecTokens = 0;
42074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  }
42174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
422d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  PrototypeScope.Exit();
4236569d68745c8213709740337d2be52b031384f58Douglas Gregor
424d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Finish the delayed C++ method declaration.
425d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
42672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor}
42772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor
4284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseLexedMethodDefs - We finished parsing the member specification of a top
4294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// (non-nested) C++ class. Now go over the stack of lexed methods that were
4304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// collected during its parsing and parse them all.
4316569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::ParseLexedMethodDefs(ParsingClass &Class) {
4326569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
433d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
4346569d68745c8213709740337d2be52b031384f58Douglas Gregor  if (HasTemplateScope)
43523c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
4366569d68745c8213709740337d2be52b031384f58Douglas Gregor
4376569d68745c8213709740337d2be52b031384f58Douglas Gregor  bool HasClassScope = !Class.TopLevelClass;
4386569d68745c8213709740337d2be52b031384f58Douglas Gregor  ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
4396569d68745c8213709740337d2be52b031384f58Douglas Gregor                        HasClassScope);
4406569d68745c8213709740337d2be52b031384f58Douglas Gregor
441d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
442d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Class.LateParsedDeclarations[i]->ParseLexedMethodDefs();
443d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  }
444d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor}
4454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
446d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::ParseLexedMethodDef(LexedMethod &LM) {
447d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // If this is a member template, introduce the template parameter scope.
448d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
449d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (LM.TemplateScope)
450d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Actions.ActOnReenterTemplateScope(getCurScope(), LM.D);
451d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
452d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Save the current token position.
453d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  SourceLocation origLoc = Tok.getLocation();
454d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
455d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  assert(!LM.Toks.empty() && "Empty body!");
456d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Append the current token at the end of the new token stream so that it
457d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // doesn't get lost.
458d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  LM.Toks.push_back(Tok);
459d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
460d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
461d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Consume the previously pushed token.
462d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ConsumeAnyToken();
463d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
464d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor         && "Inline method not starting with '{', ':' or 'try'");
465d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
466d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // Parse the method body. Function body parsing code is similar enough
467d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  // to be re-used for method bodies as well.
468d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
469d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
470d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
471d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Tok.is(tok::kw_try)) {
472c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor    ParseFunctionTryBlock(LM.D, FnScope);
473d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
474d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                                                         Tok.getLocation()) &&
475d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor           "ParseFunctionTryBlock went over the cached tokens!");
476d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // There could be leftover tokens (e.g. because of an error).
477d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Skip through until we reach the original token position.
478d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
479d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      ConsumeAnyToken();
480d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    return;
481d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  }
482d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Tok.is(tok::colon)) {
483d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    ParseConstructorInitializer(LM.D);
4844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
485d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Error recovery.
486d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    if (!Tok.is(tok::l_brace)) {
487c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor      FnScope.Exit();
488d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      Actions.ActOnFinishFunctionBody(LM.D, 0);
48910904527359605a76561a49769a2199351a072d8Matt Beaumont-Gay      while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
49010904527359605a76561a49769a2199351a072d8Matt Beaumont-Gay        ConsumeAnyToken();
491d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor      return;
492d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    }
493d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  } else
494d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    Actions.ActOnDefaultCtorInitializers(LM.D);
495d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
496c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor  ParseFunctionStatementBody(LM.D, FnScope);
497d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor
498d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor  if (Tok.getLocation() != origLoc) {
499d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Due to parsing error, we either went over the cached tokens or
500d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // there are still cached tokens left. If it's the latter case skip the
501d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // leftover tokens.
502d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // Since this is an uncommon situation that should be avoided, use the
503d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    // expensive isBeforeInTranslationUnit call.
504d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor    if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
505d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor                                                        origLoc))
5068f9359f5ae1227f3b489d1d261225d8180b64ed3Argyrios Kyrtzidis      while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
5077558cd00a5ac620990174f3cba86aea4bd9a000aArgyrios Kyrtzidis        ConsumeAnyToken();
5087a614d8380297fcd2bc23986241905d97222948cRichard Smith  }
5097a614d8380297fcd2bc23986241905d97222948cRichard Smith}
5107a614d8380297fcd2bc23986241905d97222948cRichard Smith
5117a614d8380297fcd2bc23986241905d97222948cRichard Smith/// ParseLexedMemberInitializers - We finished parsing the member specification
5127a614d8380297fcd2bc23986241905d97222948cRichard Smith/// of a top (non-nested) C++ class. Now go over the stack of lexed data member
5137a614d8380297fcd2bc23986241905d97222948cRichard Smith/// initializers that were collected during its parsing and parse them all.
5147a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::ParseLexedMemberInitializers(ParsingClass &Class) {
5157a614d8380297fcd2bc23986241905d97222948cRichard Smith  bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
5167a614d8380297fcd2bc23986241905d97222948cRichard Smith  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
5177a614d8380297fcd2bc23986241905d97222948cRichard Smith                                HasTemplateScope);
5187a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (HasTemplateScope)
5197a614d8380297fcd2bc23986241905d97222948cRichard Smith    Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
5207a614d8380297fcd2bc23986241905d97222948cRichard Smith
521cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor  // Set or update the scope flags.
5227a614d8380297fcd2bc23986241905d97222948cRichard Smith  bool AlreadyHasClassScope = Class.TopLevelClass;
523cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor  unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;
5247a614d8380297fcd2bc23986241905d97222948cRichard Smith  ParseScope ClassScope(this, ScopeFlags, !AlreadyHasClassScope);
5257a614d8380297fcd2bc23986241905d97222948cRichard Smith  ParseScopeFlags ClassScopeFlags(this, ScopeFlags, AlreadyHasClassScope);
5267558cd00a5ac620990174f3cba86aea4bd9a000aArgyrios Kyrtzidis
5277a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (!AlreadyHasClassScope)
5287a614d8380297fcd2bc23986241905d97222948cRichard Smith    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
5297a614d8380297fcd2bc23986241905d97222948cRichard Smith                                                Class.TagOrTemplate);
5307a614d8380297fcd2bc23986241905d97222948cRichard Smith
531cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor  {
532cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    // C++11 [expr.prim.general]p4:
533cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    //   Otherwise, if a member-declarator declares a non-static data member
534cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    //  (9.2) of a class X, the expression this is a prvalue of type "pointer
535cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    //  to X" within the optional brace-or-equal-initializer. It shall not
536cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    //  appear elsewhere in the member-declarator.
537cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
538cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor                                     /*TypeQuals=*/(unsigned)0);
539cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor
540cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
541cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor      Class.LateParsedDeclarations[i]->ParseLexedMemberInitializers();
542cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor    }
5434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
544cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor
5457a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (!AlreadyHasClassScope)
5467a614d8380297fcd2bc23986241905d97222948cRichard Smith    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
5477a614d8380297fcd2bc23986241905d97222948cRichard Smith                                                 Class.TagOrTemplate);
5487a614d8380297fcd2bc23986241905d97222948cRichard Smith
5497a614d8380297fcd2bc23986241905d97222948cRichard Smith  Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate);
5507a614d8380297fcd2bc23986241905d97222948cRichard Smith}
5517a614d8380297fcd2bc23986241905d97222948cRichard Smith
5527a614d8380297fcd2bc23986241905d97222948cRichard Smithvoid Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
5531991b7139a92d73420336690a870f049e88cfad6Richard Smith  if (!MI.Field || MI.Field->isInvalidDecl())
5547a614d8380297fcd2bc23986241905d97222948cRichard Smith    return;
5557a614d8380297fcd2bc23986241905d97222948cRichard Smith
5567a614d8380297fcd2bc23986241905d97222948cRichard Smith  // Append the current token at the end of the new token stream so that it
5577a614d8380297fcd2bc23986241905d97222948cRichard Smith  // doesn't get lost.
5587a614d8380297fcd2bc23986241905d97222948cRichard Smith  MI.Toks.push_back(Tok);
5597a614d8380297fcd2bc23986241905d97222948cRichard Smith  PP.EnterTokenStream(MI.Toks.data(), MI.Toks.size(), true, false);
5607a614d8380297fcd2bc23986241905d97222948cRichard Smith
5617a614d8380297fcd2bc23986241905d97222948cRichard Smith  // Consume the previously pushed token.
5627a614d8380297fcd2bc23986241905d97222948cRichard Smith  ConsumeAnyToken();
5637a614d8380297fcd2bc23986241905d97222948cRichard Smith
5647a614d8380297fcd2bc23986241905d97222948cRichard Smith  SourceLocation EqualLoc;
565cefc3afac14d29de5aba7810cc8fe6c858949e9dDouglas Gregor
566552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor  ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false,
567552e29985a710f4ced62b39d70557501bd31ca9bDouglas Gregor                                              EqualLoc);
5687a614d8380297fcd2bc23986241905d97222948cRichard Smith
5697a614d8380297fcd2bc23986241905d97222948cRichard Smith  Actions.ActOnCXXInClassMemberInitializer(MI.Field, EqualLoc, Init.release());
5707a614d8380297fcd2bc23986241905d97222948cRichard Smith
5717a614d8380297fcd2bc23986241905d97222948cRichard Smith  // The next token should be our artificial terminating EOF token.
5727a614d8380297fcd2bc23986241905d97222948cRichard Smith  if (Tok.isNot(tok::eof)) {
5737a614d8380297fcd2bc23986241905d97222948cRichard Smith    SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
5747a614d8380297fcd2bc23986241905d97222948cRichard Smith    if (!EndLoc.isValid())
5757a614d8380297fcd2bc23986241905d97222948cRichard Smith      EndLoc = Tok.getLocation();
5767a614d8380297fcd2bc23986241905d97222948cRichard Smith    // No fixit; we can't recover as if there were a semicolon here.
5777a614d8380297fcd2bc23986241905d97222948cRichard Smith    Diag(EndLoc, diag::err_expected_semi_decl_list);
5787a614d8380297fcd2bc23986241905d97222948cRichard Smith
5797a614d8380297fcd2bc23986241905d97222948cRichard Smith    // Consume tokens until we hit the artificial EOF.
5807a614d8380297fcd2bc23986241905d97222948cRichard Smith    while (Tok.isNot(tok::eof))
5817a614d8380297fcd2bc23986241905d97222948cRichard Smith      ConsumeAnyToken();
5827a614d8380297fcd2bc23986241905d97222948cRichard Smith  }
5837a614d8380297fcd2bc23986241905d97222948cRichard Smith  ConsumeAnyToken();
5844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
5854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
5864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ConsumeAndStoreUntil - Consume and store the token at the passed token
58772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// container until the token 'T' is reached (which gets
5881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// consumed/stored too, if ConsumeFinalToken).
58914b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis/// If StopAtSemi is true, then we will stop early at a ';' character.
59072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// Returns true if token 'T1' or 'T2' was found.
5914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// NOTE: This is a specialized version of Parser::SkipUntil.
59272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregorbool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
59372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor                                  CachedTokens &Toks,
59414b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis                                  bool StopAtSemi, bool ConsumeFinalToken) {
5954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // We always want this function to consume at least one token if the first
5964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  // token isn't T and if not at EOF.
5974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  bool isFirstTokenConsumed = true;
5984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  while (1) {
5994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // If we found one of the tokens, stop and return true.
60072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor    if (Tok.is(T1) || Tok.is(T2)) {
60172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor      if (ConsumeFinalToken) {
60272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor        Toks.push_back(Tok);
60372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor        ConsumeAnyToken();
60472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor      }
6054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      return true;
6064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
6074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
6084cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    switch (Tok.getKind()) {
6094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::eof:
6104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Ran out of tokens.
6114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      return false;
6124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
6134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::l_paren:
6144cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Recursively consume properly-nested parens.
6154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeParen();
61714b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
6184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
6194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::l_square:
6204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Recursively consume properly-nested square brackets.
6214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeBracket();
62314b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false);
6244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
6254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::l_brace:
6264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // Recursively consume properly-nested braces.
6274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeBrace();
62914b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
6304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
6314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
6324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Okay, we found a ']' or '}' or ')', which we think should be balanced.
6334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // Since the user wasn't looking for this token (if they were, it would
6344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // already be handled), this isn't balanced.  If there is a LHS token at a
6354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // higher level, we will assume that this matches the unbalanced token
6364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    // and return it.  Otherwise, this is a spurious RHS token, which we skip.
6374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::r_paren:
6384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      if (ParenCount && !isFirstTokenConsumed)
6394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        return false;  // Matches something.
6404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeParen();
6424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
6434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::r_square:
6444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      if (BracketCount && !isFirstTokenConsumed)
6454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        return false;  // Matches something.
6464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeBracket();
6484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
6494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::r_brace:
6504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      if (BraceCount && !isFirstTokenConsumed)
6514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis        return false;  // Matches something.
6524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeBrace();
6544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
6554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis
6567d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis    case tok::code_completion:
6577d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      Toks.push_back(Tok);
6587d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      ConsumeCodeCompletionToken();
6597d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis      break;
6607d100872341f233c81e1d7b72b40457e62c36862Argyrios Kyrtzidis
6614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::string_literal:
6624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    case tok::wide_string_literal:
6635cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    case tok::utf8_string_literal:
6645cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    case tok::utf16_string_literal:
6655cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    case tok::utf32_string_literal:
6664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeStringToken();
6684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
66914b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis    case tok::semi:
67014b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      if (StopAtSemi)
67114b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis        return false;
67214b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis      // FALL THROUGH.
6734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    default:
6744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      // consume this token.
6754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      Toks.push_back(Tok);
6764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      ConsumeToken();
6774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis      break;
6784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    }
6794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis    isFirstTokenConsumed = false;
6804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis  }
6814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis}
6826df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
6836df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl/// \brief Consume tokens and store them in the passed token container until
6846df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl/// we've passed the try keyword and constructor initializers and have consumed
685a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl/// the opening brace of the function body. The opening brace will be consumed
686a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl/// if and only if there was no error.
6876df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl///
688a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl/// \return True on error.
689a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redlbool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
6906df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl  if (Tok.is(tok::kw_try)) {
6916df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    Toks.push_back(Tok);
6926df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    ConsumeToken();
6936df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl  }
694e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman  bool ReadInitializer = false;
6956df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl  if (Tok.is(tok::colon)) {
6966df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    // Initializers can contain braces too.
6976df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    Toks.push_back(Tok);
6986df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    ConsumeToken();
6996df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
7006df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    while (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
7016df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      if (Tok.is(tok::eof) || Tok.is(tok::semi))
702e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        return Diag(Tok.getLocation(), diag::err_expected_lbrace);
7036df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
7046df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      // Grab the identifier.
7056df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks,
7066df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl                                /*StopAtSemi=*/true,
7076df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl                                /*ConsumeFinalToken=*/false))
708e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        return Diag(Tok.getLocation(), diag::err_expected_lparen);
7096df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
7106df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      tok::TokenKind kind = Tok.getKind();
7116df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      Toks.push_back(Tok);
712e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      bool IsLParen = (kind == tok::l_paren);
713e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      SourceLocation LOpen = Tok.getLocation();
714e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman
715e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      if (IsLParen) {
7166df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl        ConsumeParen();
717e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      } else {
7186df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl        assert(kind == tok::l_brace && "Must be left paren or brace here.");
7196df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl        ConsumeBrace();
720a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl        // In C++03, this has to be the start of the function body, which
721e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        // means the initializer is malformed; we'll diagnose it later.
7224e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie        if (!getLangOpts().CPlusPlus0x)
723a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl          return false;
7246df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      }
7256df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
7266df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl      // Grab the initializer
727e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      if (!ConsumeAndStoreUntil(IsLParen ? tok::r_paren : tok::r_brace,
728e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman                                Toks, /*StopAtSemi=*/true)) {
729e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        Diag(Tok, IsLParen ? diag::err_expected_rparen :
730e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman                             diag::err_expected_rbrace);
731e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        Diag(LOpen, diag::note_matching) << (IsLParen ? "(" : "{");
7326df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl        return true;
733e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      }
734e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman
735e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      // Grab pack ellipsis, if present
736e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      if (Tok.is(tok::ellipsis)) {
737e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        Toks.push_back(Tok);
738e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        ConsumeToken();
739e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      }
740a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl
741a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl      // Grab the separating comma, if any.
742a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl      if (Tok.is(tok::comma)) {
743a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl        Toks.push_back(Tok);
744a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl        ConsumeToken();
745e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      } else if (Tok.isNot(tok::l_brace)) {
746e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        ReadInitializer = true;
747e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman        break;
748a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl      }
7496df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl    }
7506df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl  }
7516df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl
752a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // Grab any remaining garbage to be diagnosed later. We stop when we reach a
753a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // brace: an opening one is the function body, while a closing one probably
754a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  // means we've reached the end of the class.
755e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman  ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,
756e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman                       /*StopAtSemi=*/true,
757e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman                       /*ConsumeFinalToken=*/false);
758e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman  if (Tok.isNot(tok::l_brace)) {
759e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    if (ReadInitializer)
760e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman      return Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
761e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman    return Diag(Tok.getLocation(), diag::err_expected_lbrace);
762e9ee382c32a83e9807a2fe4cfd52b5a11169a4b8Eli Friedman  }
763a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl
764a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  Toks.push_back(Tok);
765a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  ConsumeBrace();
766a891a32d3762ee641a29c091d286f2a7432671a5Sebastian Redl  return false;
7676df6548e44a61c444bd85dccd0398cba047c79b1Sebastian Redl}
768