ParseCXXInlineMethods.cpp revision 1eb4433ac451dc16f4133a88af2d002ac26c58ef
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" 164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis#include "clang/Parse/DeclSpec.h" 174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis#include "clang/Parse/Scope.h" 184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidisusing namespace clang; 194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 20d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl/// ParseCXXInlineMethodDef - We parsed and verified that the specified 214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// Declarator is a well formed C++ inline method definition. Now lex its body 224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// and store its tokens for parsing after the C++ class is complete. 23b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris LattnerParser::DeclPtrTy 2437b372b76a3fafe77186d7e6079e5642e2017478Douglas GregorParser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D, 2537b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor const ParsedTemplateInfo &TemplateInfo) { 264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function && 274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis "This isn't a function declarator!"); 28d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) && 29d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl "Current token not a '{', ':' or 'try'!"); 304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3137b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor Action::MultiTemplateParamsArg TemplateParams(Actions, 3237b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0, 3337b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); 3467d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall DeclPtrTy FnD; 3567d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall if (D.getDeclSpec().isFriendSpecified()) 3637b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor // FIXME: Friend templates 373f9a8a60614b763785d54ad08821745d03a4af70John McCall FnD = Actions.ActOnFriendDecl(CurScope, &D, /*IsDefinition*/ true); 3837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor else // FIXME: pass template information through 391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 4037b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor move(TemplateParams), 0, 0); 414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 42d33133cdc1af466f9c276249b2621be03867888bEli Friedman HandleMemberFunctionDefaultArgs(D, FnD); 43d33133cdc1af466f9c276249b2621be03867888bEli Friedman 444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the tokens and store them for later parsing. 454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 466569d68745c8213709740337d2be52b031384f58Douglas Gregor getCurrentClass().MethodDefs.push_back(LexedMethod(FnD)); 471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump getCurrentClass().MethodDefs.back().TemplateScope 48d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor = CurScope->isTemplateParamScope(); 496569d68745c8213709740337d2be52b031384f58Douglas Gregor CachedTokens &Toks = getCurrentClass().MethodDefs.back().Toks; 504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 51d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl tok::TokenKind kind = Tok.getKind(); 52d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl // We may have a constructor initializer or function-try-block here. 53d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl if (kind == tok::colon || kind == tok::kw_try) { 547ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Consume everything up to (and including) the left brace. 5572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (!ConsumeAndStoreUntil(tok::l_brace, tok::unknown, Toks, tok::semi)) { 563f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor // We didn't find the left-brace we expected after the 571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // constructor initializer. 583f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor if (Tok.is(tok::semi)) { 593f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor // We found a semicolon; complain, consume the semicolon, and 603f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor // don't try to parse this method later. 613f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor Diag(Tok.getLocation(), diag::err_expected_lbrace); 623f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor ConsumeAnyToken(); 636569d68745c8213709740337d2be52b031384f58Douglas Gregor getCurrentClass().MethodDefs.pop_back(); 643f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor return FnD; 653f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor } 663f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor } 673f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor 687ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } else { 691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Begin by storing the '{' token. 707ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor Toks.push_back(Tok); 717ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeBrace(); 727ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 737ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Consume everything up to (and including) the matching right brace. 7472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ConsumeAndStoreUntil(tok::r_brace, tok::unknown, Toks); 754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 76d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl // If we're in a function-try-block, we need to store all the catch blocks. 77d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl if (kind == tok::kw_try) { 78d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl while (Tok.is(tok::kw_catch)) { 79d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl ConsumeAndStoreUntil(tok::l_brace, tok::unknown, Toks); 80d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl ConsumeAndStoreUntil(tok::r_brace, tok::unknown, Toks); 81d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl } 82d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl } 83d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl 844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return FnD; 854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 8772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// ParseLexedMethodDeclarations - We finished parsing the member 8872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// specification of a top (non-nested) C++ class. Now go over the 8972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// stack of method declarations with some parts for which parsing was 9072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// delayed (such as default arguments) and parse them. 916569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { 926569d68745c8213709740337d2be52b031384f58Douglas Gregor bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 936569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); 946569d68745c8213709740337d2be52b031384f58Douglas Gregor if (HasTemplateScope) 956569d68745c8213709740337d2be52b031384f58Douglas Gregor Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate); 966569d68745c8213709740337d2be52b031384f58Douglas Gregor 976569d68745c8213709740337d2be52b031384f58Douglas Gregor bool HasClassScope = !Class.TopLevelClass; 986569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 996569d68745c8213709740337d2be52b031384f58Douglas Gregor HasClassScope); 1006569d68745c8213709740337d2be52b031384f58Douglas Gregor 1016569d68745c8213709740337d2be52b031384f58Douglas Gregor for (; !Class.MethodDecls.empty(); Class.MethodDecls.pop_front()) { 1026569d68745c8213709740337d2be52b031384f58Douglas Gregor LateParsedMethodDeclaration &LM = Class.MethodDecls.front(); 1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 104d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor // If this is a member template, introduce the template parameter scope. 105d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); 106d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor if (LM.TemplateScope) 107d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor Actions.ActOnReenterTemplateScope(CurScope, LM.Method); 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Start the delayed C++ method declaration 11072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor Actions.ActOnStartDelayedCXXMethodDeclaration(CurScope, LM.Method); 11172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 11272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Introduce the parameters into scope and parse their default 11372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // arguments. 1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ParseScope PrototypeScope(this, 1153218c4bb3b5d7250f12420de6db7ef3e3f805a75Douglas Gregor Scope::FunctionPrototypeScope|Scope::DeclScope); 11672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { 11772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Introduce the parameter into scope. 11872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor Actions.ActOnDelayedCXXMethodParameter(CurScope, LM.DefaultArgs[I].Param); 11972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 12072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) { 12172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Parse the default argument from its saved token stream. 12272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor Toks->push_back(Tok); // So that the current token doesn't get lost 12372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false); 12472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 12572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Consume the previously-pushed token. 12672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ConsumeAnyToken(); 12772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 12872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Consume the '='. 12972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor assert(Tok.is(tok::equal) && "Default argument not starting with '='"); 13072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor SourceLocation EqualLoc = ConsumeToken(); 13172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 13272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor OwningExprResult DefArgResult(ParseAssignmentExpression()); 13372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (DefArgResult.isInvalid()) 13472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param); 13572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor else 13672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc, 137f53597fb16142bdb4a66901f8c0b768db4f2a548Sebastian Redl move(DefArgResult)); 13872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor delete Toks; 13972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor LM.DefaultArgs[I].Toks = 0; 14072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 14172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 14272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor PrototypeScope.Exit(); 14372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 14472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor // Finish the delayed C++ method declaration. 14572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor Actions.ActOnFinishDelayedCXXMethodDeclaration(CurScope, LM.Method); 14672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 1476569d68745c8213709740337d2be52b031384f58Douglas Gregor 1486569d68745c8213709740337d2be52b031384f58Douglas Gregor for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I) 1496569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDeclarations(*Class.NestedClasses[I]); 15072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor} 15172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 1524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseLexedMethodDefs - We finished parsing the member specification of a top 1534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// (non-nested) C++ class. Now go over the stack of lexed methods that were 1544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// collected during its parsing and parse them all. 1556569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::ParseLexedMethodDefs(ParsingClass &Class) { 1566569d68745c8213709740337d2be52b031384f58Douglas Gregor bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 1576569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseScope TemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); 1586569d68745c8213709740337d2be52b031384f58Douglas Gregor if (HasTemplateScope) 1596569d68745c8213709740337d2be52b031384f58Douglas Gregor Actions.ActOnReenterTemplateScope(CurScope, Class.TagOrTemplate); 1606569d68745c8213709740337d2be52b031384f58Douglas Gregor 1616569d68745c8213709740337d2be52b031384f58Douglas Gregor bool HasClassScope = !Class.TopLevelClass; 1626569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 1636569d68745c8213709740337d2be52b031384f58Douglas Gregor HasClassScope); 1646569d68745c8213709740337d2be52b031384f58Douglas Gregor 1656569d68745c8213709740337d2be52b031384f58Douglas Gregor for (; !Class.MethodDefs.empty(); Class.MethodDefs.pop_front()) { 1666569d68745c8213709740337d2be52b031384f58Douglas Gregor LexedMethod &LM = Class.MethodDefs.front(); 1674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 168d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor // If this is a member template, introduce the template parameter scope. 169d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); 170d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor if (LM.TemplateScope) 171d83d04041f64a2c89123d227fa8003b482391279Douglas Gregor Actions.ActOnReenterTemplateScope(CurScope, LM.D); 1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis assert(!LM.Toks.empty() && "Empty body!"); 1744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Append the current token at the end of the new token stream so that it 1754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // doesn't get lost. 1764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis LM.Toks.push_back(Tok); 177efd5bdad3c2b746db46452c6b13bd3c462dd761dDouglas Gregor PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false); 1784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 1794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the previously pushed token. 1804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeAnyToken(); 181d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) 182d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl && "Inline method not starting with '{', ':' or 'try'"); 1834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 1844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Parse the method body. Function body parsing code is similar enough 1854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // to be re-used for method bodies as well. 1868935b8b49053122ddd3ab4cd59af0fe5eb9c23cfDouglas Gregor ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); 1874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Actions.ActOnStartOfFunctionDef(CurScope, LM.D); 1884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 189d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl if (Tok.is(tok::kw_try)) { 190d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl ParseFunctionTryBlock(LM.D); 191de1b60a9868f80f0872ed05d78df3b40a10ba5caSebastian Redl continue; 192d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl } 1937ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor if (Tok.is(tok::colon)) 1947ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ParseConstructorInitializer(LM.D); 1950849d38128536b0b33377d91bf02d005308319efFariborz Jahanian else 196393612e6c7727f1fee50039254d9f434364cc0b2Fariborz Jahanian Actions.ActOnDefaultCtorInitializers(LM.D); 197d01c915dda27bb0045687f0a08bbcab1dd40e652Fariborz Jahanian 19840e9bc84a2ab49fc33c2b1a95c6674ab2b820e9eChris Lattner // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'?? 19940e9bc84a2ab49fc33c2b1a95c6674ab2b820e9eChris Lattner ParseFunctionStatementBody(LM.D); 2004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 2016569d68745c8213709740337d2be52b031384f58Douglas Gregor 2026569d68745c8213709740337d2be52b031384f58Douglas Gregor for (unsigned I = 0, N = Class.NestedClasses.size(); I != N; ++I) 2036569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseLexedMethodDefs(*Class.NestedClasses[I]); 2044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 2054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ConsumeAndStoreUntil - Consume and store the token at the passed token 20772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// container until the token 'T' is reached (which gets 2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// consumed/stored too, if ConsumeFinalToken). 2093f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor/// If EarlyAbortIf is specified, then we will stop early if we find that 2103f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor/// token at the top level. 21172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// Returns true if token 'T1' or 'T2' was found. 2124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// NOTE: This is a specialized version of Parser::SkipUntil. 21372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregorbool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, 21472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor CachedTokens &Toks, 21572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor tok::TokenKind EarlyAbortIf, 21672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor bool ConsumeFinalToken) { 2174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We always want this function to consume at least one token if the first 2184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // token isn't T and if not at EOF. 2194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis bool isFirstTokenConsumed = true; 2204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 2214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we found one of the tokens, stop and return true. 22272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (Tok.is(T1) || Tok.is(T2)) { 22372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (ConsumeFinalToken) { 22472b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor Toks.push_back(Tok); 22572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ConsumeAnyToken(); 22672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 2274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return true; 2284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 2294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2303f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor // If we found the early-abort token, return. 2313f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor if (Tok.is(EarlyAbortIf)) 2323f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor return false; 2333f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor 2344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis switch (Tok.getKind()) { 2354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::eof: 2364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Ran out of tokens. 2374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return false; 2384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::l_paren: 2404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Recursively consume properly-nested parens. 2414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 2424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeParen(); 24372b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ConsumeAndStoreUntil(tok::r_paren, tok::unknown, Toks); 2444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 2454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::l_square: 2464cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Recursively consume properly-nested square brackets. 2474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 2484cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeBracket(); 24972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ConsumeAndStoreUntil(tok::r_square, tok::unknown, Toks); 2504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 2514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::l_brace: 2524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Recursively consume properly-nested braces. 2534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 2544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeBrace(); 25572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ConsumeAndStoreUntil(tok::r_brace, tok::unknown, Toks); 2564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 2574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Okay, we found a ']' or '}' or ')', which we think should be balanced. 2594cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Since the user wasn't looking for this token (if they were, it would 2604cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // already be handled), this isn't balanced. If there is a LHS token at a 2614cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // higher level, we will assume that this matches the unbalanced token 2624cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // and return it. Otherwise, this is a spurious RHS token, which we skip. 2634cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::r_paren: 2644cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (ParenCount && !isFirstTokenConsumed) 2654cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return false; // Matches something. 2664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 2674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeParen(); 2684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 2694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::r_square: 2704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (BracketCount && !isFirstTokenConsumed) 2714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return false; // Matches something. 2724cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 2734cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeBracket(); 2744cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 2754cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::r_brace: 2764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (BraceCount && !isFirstTokenConsumed) 2774cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return false; // Matches something. 2784cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 2794cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeBrace(); 2804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 2814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 2824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::string_literal: 2834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::wide_string_literal: 2844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 2854cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeStringToken(); 2864cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 2874cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis default: 2884cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // consume this token. 2894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 2904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 2914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 2924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 2934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis isFirstTokenConsumed = false; 2944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 2954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 296