ParseCXXInlineMethods.cpp revision e4246a633b13197634225971b25df0cbdcec0c5d
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. 24eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCallDecl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, 254867347e82648d3baf09524b98b09c297a5a198fNico Weber const ParsedTemplateInfo &TemplateInfo, 266a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet const VirtSpecifiers& VS, ExprResult& Init) { 27075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara assert(D.isFunctionDeclarator() && "This isn't a function declarator!"); 28e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try) || 29e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt Tok.is(tok::equal)) && 30e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt "Current token not a '{', ':', '=', or 'try'!"); 314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 32f312b1ea179f1c44371f9ee0cd0bc006f612de11John McCall MultiTemplateParamsArg TemplateParams(Actions, 334cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0, 344cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0); 354cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt 36d226f65006733ed7f709c3174f22ce33391cb58fJohn McCall Decl *FnD; 3767d1a67f3db2f1aa69083c5c94164d6e0ee05b32John McCall if (D.getDeclSpec().isFriendSpecified()) 3837b372b76a3fafe77186d7e6079e5642e2017478Douglas Gregor // FIXME: Friend templates 3923c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, true, 404cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt move(TemplateParams)); 414867347e82648d3baf09524b98b09c297a5a198fNico Weber else { // FIXME: pass template information through 4223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D, 4369a87357310260c4b2c5dce2cdcd10c3fd3a0a58Anders Carlsson move(TemplateParams), 0, 446a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet VS, Init.release(), 456a24747beed797b2f1184c66ca45beb4db20eb08Francois Pichet /*IsDefinition*/true); 464867347e82648d3baf09524b98b09c297a5a198fNico Weber } 474cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 48d33133cdc1af466f9c276249b2621be03867888bEli Friedman HandleMemberFunctionDefaultArgs(D, FnD); 49d33133cdc1af466f9c276249b2621be03867888bEli Friedman 50eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall D.complete(FnD); 51eee1d5434ebfa955ffc3c493aecd68bb7b3f4838John McCall 52e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt if (Tok.is(tok::equal)) { 53e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt ConsumeToken(); 54e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 55e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt bool Delete = false; 56e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt SourceLocation KWLoc; 57e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt if (Tok.is(tok::kw_delete)) { 58e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt if (!getLang().CPlusPlus0x) 59e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt Diag(Tok, diag::warn_deleted_function_accepted_as_extension); 60e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 61e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt KWLoc = ConsumeToken(); 62e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt Actions.SetDeclDeleted(FnD, KWLoc); 63e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt Delete = true; 64e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else if (Tok.is(tok::kw_default)) { 65e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt if (!getLang().CPlusPlus0x) 66e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt Diag(Tok, diag::warn_defaulted_function_accepted_as_extension); 67e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 68e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt KWLoc = ConsumeToken(); 69e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt Actions.SetDeclDefaulted(FnD, KWLoc); 70e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else { 71e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt llvm_unreachable("function definition after = not 'delete' or 'default'"); 72e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 73e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 74e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt if (Tok.is(tok::comma)) { 75e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt Diag(KWLoc, diag::err_default_delete_in_multiple_declaration) 76e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt << Delete; 77e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt SkipUntil(tok::semi); 78e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } else { 79e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 80e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt Delete ? "delete" : "default", tok::semi); 81e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 82e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 83e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt return FnD; 84e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt } 85e4246a633b13197634225971b25df0cbdcec0c5dSean Hunt 868387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet // In delayed template parsing mode, if we are within a class template 878387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet // or if we are about to parse function member template then consume 888387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet // the tokens and store them for parsing at the end of the translation unit. 898387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet if (getLang().DelayedTemplateParsing && 908387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet ((Actions.CurContext->isDependentContext() || 918387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) && 928387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet !Actions.IsInsideALocalClassWithinATemplateFunction()) && 938387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet !D.getDeclSpec().isFriendSpecified()) { 948387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet 958387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet if (FnD) { 968387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet LateParsedTemplatedFunction *LPT = 978387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet new LateParsedTemplatedFunction(this, FnD); 988387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet 998387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet FunctionDecl *FD = 0; 1008387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(FnD)) 1018387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet FD = FunTmpl->getTemplatedDecl(); 1028387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet else 1038387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet FD = cast<FunctionDecl>(FnD); 10481542fd91bd5e7e65ebae3eaad117bdaeaf7d737Chandler Carruth Actions.CheckForFunctionRedefinition(FD); 1058387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet 1068387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet LateParsedTemplateMap[FD] = LPT; 1078387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet Actions.MarkAsLateParsedTemplate(FD); 1088387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet LexTemplateFunctionForLateParsing(LPT->Toks); 1098387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet } else { 1108387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet CachedTokens Toks; 1118387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet LexTemplateFunctionForLateParsing(Toks); 1128387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet } 1138387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet 1148387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet return FnD; 1158387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet } 1168387e2a41eef6fa17fb140a18c29b6eee9dd2b8aFrancois Pichet 1174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Consume the tokens and store them for later parsing. 1184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 119d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor LexedMethod* LM = new LexedMethod(this, FnD); 120d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor getCurrentClass().LateParsedDeclarations.push_back(LM); 121d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor LM->TemplateScope = getCurScope()->isTemplateParamScope(); 122d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor CachedTokens &Toks = LM->Toks; 1234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 124d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl tok::TokenKind kind = Tok.getKind(); 125d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl // We may have a constructor initializer or function-try-block here. 126d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl if (kind == tok::colon || kind == tok::kw_try) { 1277ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Consume everything up to (and including) the left brace. 12814b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis if (!ConsumeAndStoreUntil(tok::l_brace, Toks)) { 1293f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor // We didn't find the left-brace we expected after the 1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // constructor initializer. 1313f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor if (Tok.is(tok::semi)) { 1323f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor // We found a semicolon; complain, consume the semicolon, and 1333f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor // don't try to parse this method later. 1343f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor Diag(Tok.getLocation(), diag::err_expected_lbrace); 1353f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor ConsumeAnyToken(); 136d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor delete getCurrentClass().LateParsedDeclarations.back(); 137d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor getCurrentClass().LateParsedDeclarations.pop_back(); 1383f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor return FnD; 1393f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor } 1403f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor } 1413f08d181f620e6bf4971c436fc9878f98a02bbe3Douglas Gregor 1427ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } else { 1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Begin by storing the '{' token. 1447ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor Toks.push_back(Tok); 1457ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor ConsumeBrace(); 1467ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor } 1477ad8390f7992ab7f19b1460c5f0b9d96f165c4e9Douglas Gregor // Consume everything up to (and including) the matching right brace. 14814b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 1494cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 150d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl // If we're in a function-try-block, we need to store all the catch blocks. 151d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl if (kind == tok::kw_try) { 152d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl while (Tok.is(tok::kw_catch)) { 15314b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false); 15414b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 155d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl } 156d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl } 157d3a413d3b8eb39bcee5944bc545d9997c1abe492Sebastian Redl 15887f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor 15987f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor if (!FnD) { 16087f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor // If semantic analysis could not build a function declaration, 16187f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor // just throw away the late-parsed declaration. 16287f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor delete getCurrentClass().LateParsedDeclarations.back(); 16387f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor getCurrentClass().LateParsedDeclarations.pop_back(); 16487f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor } 16587f106462ce49a4a9b812b9de92aadd4e54567bdDouglas Gregor 1664cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return FnD; 1674cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 1684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 169d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedDeclaration::~LateParsedDeclaration() {} 170d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {} 171d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedDeclaration::ParseLexedMethodDefs() {} 172d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 173d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C) 174d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor : Self(P), Class(C) {} 175d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 176d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas GregorParser::LateParsedClass::~LateParsedClass() { 177d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Self->DeallocateParsedClasses(Class); 178d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor} 179d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 180d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedClass::ParseLexedMethodDeclarations() { 181d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Self->ParseLexedMethodDeclarations(*Class); 182d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor} 183d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 184d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedClass::ParseLexedMethodDefs() { 185d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Self->ParseLexedMethodDefs(*Class); 186d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor} 187d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 188d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() { 189d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Self->ParseLexedMethodDeclaration(*this); 190d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor} 191d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 192d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::LexedMethod::ParseLexedMethodDefs() { 193d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Self->ParseLexedMethodDef(*this); 194d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor} 195d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 19672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// ParseLexedMethodDeclarations - We finished parsing the member 19772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// specification of a top (non-nested) C++ class. Now go over the 19872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// stack of method declarations with some parts for which parsing was 19972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// delayed (such as default arguments) and parse them. 2006569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { 2016569d68745c8213709740337d2be52b031384f58Douglas Gregor bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 202d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); 2036569d68745c8213709740337d2be52b031384f58Douglas Gregor if (HasTemplateScope) 20423c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 2056569d68745c8213709740337d2be52b031384f58Douglas Gregor 2067a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall // The current scope is still active if we're the top-level class. 2077a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall // Otherwise we'll need to push and enter a new scope. 2086569d68745c8213709740337d2be52b031384f58Douglas Gregor bool HasClassScope = !Class.TopLevelClass; 2094cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 2104cd8494d9a2f99cbf38147bca80be18cdff83734Sean Hunt HasClassScope); 2117a1dc562d4ad59237ed9fe7e8cef56f9eaa7a26cJohn McCall if (HasClassScope) 21223c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); 2136569d68745c8213709740337d2be52b031384f58Douglas Gregor 214d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { 215d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations(); 216d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor } 21772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 218d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (HasClassScope) 219d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); 220d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor} 2217fd3a6456a88cdd225b92ae1606144f24c7f51d4Argyrios Kyrtzidis 222d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) { 223d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // If this is a member template, introduce the template parameter scope. 224d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); 225d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (LM.TemplateScope) 226d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method); 227d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 228d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Start the delayed C++ method declaration 229d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method); 230d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 231d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Introduce the parameters into scope and parse their default 232d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // arguments. 233d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ParseScope PrototypeScope(this, 234d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Scope::FunctionPrototypeScope|Scope::DeclScope); 235d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) { 236d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Introduce the parameter into scope. 237d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnDelayedCXXMethodParameter(getCurScope(), LM.DefaultArgs[I].Param); 238d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 239d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) { 240d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Save the current token position. 241d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor SourceLocation origLoc = Tok.getLocation(); 242d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 243d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Parse the default argument from its saved token stream. 244d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Toks->push_back(Tok); // So that the current token doesn't get lost 245d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor PP.EnterTokenStream(&Toks->front(), Toks->size(), true, false); 246d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 247d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Consume the previously-pushed token. 248d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ConsumeAnyToken(); 249d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 250d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Consume the '='. 251d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor assert(Tok.is(tok::equal) && "Default argument not starting with '='"); 252d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor SourceLocation EqualLoc = ConsumeToken(); 253d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 254d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // The argument isn't actually potentially evaluated unless it is 255d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // used. 256d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor EnterExpressionEvaluationContext Eval(Actions, 257d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Sema::PotentiallyEvaluatedIfUsed); 258d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 259d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ExprResult DefArgResult(ParseAssignmentExpression()); 260d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (DefArgResult.isInvalid()) 261d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param); 262d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor else { 263d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (Tok.is(tok::cxx_defaultarg_end)) 264d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ConsumeToken(); 265d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor else 266d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Diag(Tok.getLocation(), diag::err_default_arg_unparsed); 267d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc, 268d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor DefArgResult.take()); 269d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor } 27072b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 271d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, 272d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Tok.getLocation()) && 273d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor "ParseAssignmentExpression went over the default arg tokens!"); 274d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // There could be leftover tokens (e.g. because of an error). 275d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Skip through until we reach the original token position. 276d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof)) 27772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ConsumeAnyToken(); 27872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 279d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor delete Toks; 280d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor LM.DefaultArgs[I].Toks = 0; 28172b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 28272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 283d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor PrototypeScope.Exit(); 2846569d68745c8213709740337d2be52b031384f58Douglas Gregor 285d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Finish the delayed C++ method declaration. 286d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method); 28772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor} 28872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor 2894cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ParseLexedMethodDefs - We finished parsing the member specification of a top 2904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// (non-nested) C++ class. Now go over the stack of lexed methods that were 2914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// collected during its parsing and parse them all. 2926569d68745c8213709740337d2be52b031384f58Douglas Gregorvoid Parser::ParseLexedMethodDefs(ParsingClass &Class) { 2936569d68745c8213709740337d2be52b031384f58Douglas Gregor bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; 294d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope); 2956569d68745c8213709740337d2be52b031384f58Douglas Gregor if (HasTemplateScope) 29623c94dbb6631fecdb55ba401aa93722803d980c6Douglas Gregor Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); 2976569d68745c8213709740337d2be52b031384f58Douglas Gregor 2986569d68745c8213709740337d2be52b031384f58Douglas Gregor bool HasClassScope = !Class.TopLevelClass; 2996569d68745c8213709740337d2be52b031384f58Douglas Gregor ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope, 3006569d68745c8213709740337d2be52b031384f58Douglas Gregor HasClassScope); 3016569d68745c8213709740337d2be52b031384f58Douglas Gregor 302d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) { 303d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Class.LateParsedDeclarations[i]->ParseLexedMethodDefs(); 304d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor } 305d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor} 3064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 307d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregorvoid Parser::ParseLexedMethodDef(LexedMethod &LM) { 308d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // If this is a member template, introduce the template parameter scope. 309d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope); 310d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (LM.TemplateScope) 311d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnReenterTemplateScope(getCurScope(), LM.D); 312d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 313d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Save the current token position. 314d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor SourceLocation origLoc = Tok.getLocation(); 315d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 316d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor assert(!LM.Toks.empty() && "Empty body!"); 317d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Append the current token at the end of the new token stream so that it 318d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // doesn't get lost. 319d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor LM.Toks.push_back(Tok); 320d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false); 321d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 322d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Consume the previously pushed token. 323d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ConsumeAnyToken(); 324d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) 325d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor && "Inline method not starting with '{', ':' or 'try'"); 326d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 327d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Parse the method body. Function body parsing code is similar enough 328d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // to be re-used for method bodies as well. 329d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); 330d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); 331d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 332d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (Tok.is(tok::kw_try)) { 333c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor ParseFunctionTryBlock(LM.D, FnScope); 334d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, 335d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Tok.getLocation()) && 336d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor "ParseFunctionTryBlock went over the cached tokens!"); 337d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // There could be leftover tokens (e.g. because of an error). 338d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Skip through until we reach the original token position. 339d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof)) 340d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ConsumeAnyToken(); 341d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor return; 342d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor } 343d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (Tok.is(tok::colon)) { 344d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor ParseConstructorInitializer(LM.D); 3454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 346d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Error recovery. 347d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (!Tok.is(tok::l_brace)) { 348c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor FnScope.Exit(); 349d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnFinishFunctionBody(LM.D, 0); 350d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor return; 351d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor } 352d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor } else 353d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor Actions.ActOnDefaultCtorInitializers(LM.D); 354d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 355c9977d09a2de7f7d2245973413d4caf86c736640Douglas Gregor ParseFunctionStatementBody(LM.D, FnScope); 356d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor 357d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (Tok.getLocation() != origLoc) { 358d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Due to parsing error, we either went over the cached tokens or 359d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // there are still cached tokens left. If it's the latter case skip the 360d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // leftover tokens. 361d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // Since this is an uncommon situation that should be avoided, use the 362d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor // expensive isBeforeInTranslationUnit call. 363d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), 364d54eb4410330383f48d3cc22b2ad8d23f120836bDouglas Gregor origLoc)) 3658f9359f5ae1227f3b489d1d261225d8180b64ed3Argyrios Kyrtzidis while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof)) 3667558cd00a5ac620990174f3cba86aea4bd9a000aArgyrios Kyrtzidis ConsumeAnyToken(); 3677558cd00a5ac620990174f3cba86aea4bd9a000aArgyrios Kyrtzidis 3684cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 3694cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 3704cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3714cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// ConsumeAndStoreUntil - Consume and store the token at the passed token 37272b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// container until the token 'T' is reached (which gets 3731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// consumed/stored too, if ConsumeFinalToken). 37414b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis/// If StopAtSemi is true, then we will stop early at a ';' character. 37572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor/// Returns true if token 'T1' or 'T2' was found. 3764cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis/// NOTE: This is a specialized version of Parser::SkipUntil. 37772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregorbool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2, 37872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor CachedTokens &Toks, 37914b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis bool StopAtSemi, bool ConsumeFinalToken) { 3804cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // We always want this function to consume at least one token if the first 3814cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // token isn't T and if not at EOF. 3824cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis bool isFirstTokenConsumed = true; 3834cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis while (1) { 3844cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // If we found one of the tokens, stop and return true. 38572b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (Tok.is(T1) || Tok.is(T2)) { 38672b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor if (ConsumeFinalToken) { 38772b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor Toks.push_back(Tok); 38872b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor ConsumeAnyToken(); 38972b505b7904b3c9320a1312998800ba76e4f5841Douglas Gregor } 3904cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return true; 3914cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 3924cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3934cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis switch (Tok.getKind()) { 3944cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::eof: 3954cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Ran out of tokens. 3964cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return false; 3974cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 3984cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::l_paren: 3994cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Recursively consume properly-nested parens. 4004cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 4014cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeParen(); 40214b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false); 4034cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 4044cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::l_square: 4054cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Recursively consume properly-nested square brackets. 4064cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 4074cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeBracket(); 40814b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false); 4094cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 4104cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::l_brace: 4114cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Recursively consume properly-nested braces. 4124cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 4134cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeBrace(); 41414b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false); 4154cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 4164cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 4174cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Okay, we found a ']' or '}' or ')', which we think should be balanced. 4184cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // Since the user wasn't looking for this token (if they were, it would 4194cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // already be handled), this isn't balanced. If there is a LHS token at a 4204cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // higher level, we will assume that this matches the unbalanced token 4214cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // and return it. Otherwise, this is a spurious RHS token, which we skip. 4224cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::r_paren: 4234cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (ParenCount && !isFirstTokenConsumed) 4244cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return false; // Matches something. 4254cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 4264cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeParen(); 4274cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 4284cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::r_square: 4294cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (BracketCount && !isFirstTokenConsumed) 4304cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return false; // Matches something. 4314cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 4324cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeBracket(); 4334cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 4344cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::r_brace: 4354cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis if (BraceCount && !isFirstTokenConsumed) 4364cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis return false; // Matches something. 4374cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 4384cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeBrace(); 4394cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 4404cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis 4414cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::string_literal: 4424cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis case tok::wide_string_literal: 4434cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 4444cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeStringToken(); 4454cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 44614b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis case tok::semi: 44714b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis if (StopAtSemi) 44814b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis return false; 44914b91628961ab50cc6e724bbcd408fdee100662dArgyrios Kyrtzidis // FALL THROUGH. 4504cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis default: 4514cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis // consume this token. 4524cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis Toks.push_back(Tok); 4534cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis ConsumeToken(); 4544cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis break; 4554cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 4564cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis isFirstTokenConsumed = false; 4574cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis } 4584cc18a4d5222e04bd568b1e3e4d86127dbbcdf3fArgyrios Kyrtzidis} 459