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