10b57cec5SDimitry Andric //===--- Parser.cpp - C Language Family Parser ----------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the Parser interfaces. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "clang/Parse/Parser.h" 140b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h" 150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 160b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 175ffd83dbSDimitry Andric #include "clang/Basic/FileManager.h" 180b57cec5SDimitry Andric #include "clang/Parse/ParseDiagnostic.h" 190b57cec5SDimitry Andric #include "clang/Parse/RAIIObjectsForParser.h" 200b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h" 210b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h" 220b57cec5SDimitry Andric #include "clang/Sema/Scope.h" 230b57cec5SDimitry Andric #include "llvm/Support/Path.h" 240b57cec5SDimitry Andric using namespace clang; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace { 280b57cec5SDimitry Andric /// A comment handler that passes comments found by the preprocessor 290b57cec5SDimitry Andric /// to the parser action. 300b57cec5SDimitry Andric class ActionCommentHandler : public CommentHandler { 310b57cec5SDimitry Andric Sema &S; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric public: 340b57cec5SDimitry Andric explicit ActionCommentHandler(Sema &S) : S(S) { } 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric bool HandleComment(Preprocessor &PP, SourceRange Comment) override { 370b57cec5SDimitry Andric S.ActOnComment(Comment); 380b57cec5SDimitry Andric return false; 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric }; 410b57cec5SDimitry Andric } // end anonymous namespace 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric IdentifierInfo *Parser::getSEHExceptKeyword() { 440b57cec5SDimitry Andric // __except is accepted as a (contextual) keyword 450b57cec5SDimitry Andric if (!Ident__except && (getLangOpts().MicrosoftExt || getLangOpts().Borland)) 460b57cec5SDimitry Andric Ident__except = PP.getIdentifierInfo("__except"); 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric return Ident__except; 490b57cec5SDimitry Andric } 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) 52fe6060f1SDimitry Andric : PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions), 53fe6060f1SDimitry Andric Diags(PP.getDiagnostics()), GreaterThanIsOperator(true), 54fe6060f1SDimitry Andric ColonIsSacred(false), InMessageExpression(false), 55fe6060f1SDimitry Andric TemplateParameterDepth(0), ParsingInObjCContainer(false) { 560b57cec5SDimitry Andric SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies; 570b57cec5SDimitry Andric Tok.startToken(); 580b57cec5SDimitry Andric Tok.setKind(tok::eof); 590b57cec5SDimitry Andric Actions.CurScope = nullptr; 600b57cec5SDimitry Andric NumCachedScopes = 0; 610b57cec5SDimitry Andric CurParsedObjCImpl = nullptr; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // Add #pragma handlers. These are removed and destroyed in the 640b57cec5SDimitry Andric // destructor. 650b57cec5SDimitry Andric initializePragmaHandlers(); 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric CommentSemaHandler.reset(new ActionCommentHandler(actions)); 680b57cec5SDimitry Andric PP.addCommentHandler(CommentSemaHandler.get()); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric PP.setCodeCompletionHandler(*this); 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) { 740b57cec5SDimitry Andric return Diags.Report(Loc, DiagID); 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) { 780b57cec5SDimitry Andric return Diag(Tok.getLocation(), DiagID); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// Emits a diagnostic suggesting parentheses surrounding a 820b57cec5SDimitry Andric /// given range. 830b57cec5SDimitry Andric /// 840b57cec5SDimitry Andric /// \param Loc The location where we'll emit the diagnostic. 850b57cec5SDimitry Andric /// \param DK The kind of diagnostic to emit. 860b57cec5SDimitry Andric /// \param ParenRange Source range enclosing code that should be parenthesized. 870b57cec5SDimitry Andric void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK, 880b57cec5SDimitry Andric SourceRange ParenRange) { 890b57cec5SDimitry Andric SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd()); 900b57cec5SDimitry Andric if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) { 910b57cec5SDimitry Andric // We can't display the parentheses, so just dig the 920b57cec5SDimitry Andric // warning/error and return. 930b57cec5SDimitry Andric Diag(Loc, DK); 940b57cec5SDimitry Andric return; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric Diag(Loc, DK) 980b57cec5SDimitry Andric << FixItHint::CreateInsertion(ParenRange.getBegin(), "(") 990b57cec5SDimitry Andric << FixItHint::CreateInsertion(EndLoc, ")"); 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok) { 1030b57cec5SDimitry Andric switch (ExpectedTok) { 1040b57cec5SDimitry Andric case tok::semi: 1050b57cec5SDimitry Andric return Tok.is(tok::colon) || Tok.is(tok::comma); // : or , for ; 1060b57cec5SDimitry Andric default: return false; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID, 1110b57cec5SDimitry Andric StringRef Msg) { 1120b57cec5SDimitry Andric if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) { 1130b57cec5SDimitry Andric ConsumeAnyToken(); 1140b57cec5SDimitry Andric return false; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // Detect common single-character typos and resume. 1180b57cec5SDimitry Andric if (IsCommonTypo(ExpectedTok, Tok)) { 1190b57cec5SDimitry Andric SourceLocation Loc = Tok.getLocation(); 1200b57cec5SDimitry Andric { 1210b57cec5SDimitry Andric DiagnosticBuilder DB = Diag(Loc, DiagID); 1220b57cec5SDimitry Andric DB << FixItHint::CreateReplacement( 1230b57cec5SDimitry Andric SourceRange(Loc), tok::getPunctuatorSpelling(ExpectedTok)); 1240b57cec5SDimitry Andric if (DiagID == diag::err_expected) 1250b57cec5SDimitry Andric DB << ExpectedTok; 1260b57cec5SDimitry Andric else if (DiagID == diag::err_expected_after) 1270b57cec5SDimitry Andric DB << Msg << ExpectedTok; 1280b57cec5SDimitry Andric else 1290b57cec5SDimitry Andric DB << Msg; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric // Pretend there wasn't a problem. 1330b57cec5SDimitry Andric ConsumeAnyToken(); 1340b57cec5SDimitry Andric return false; 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation); 1380b57cec5SDimitry Andric const char *Spelling = nullptr; 1390b57cec5SDimitry Andric if (EndLoc.isValid()) 1400b57cec5SDimitry Andric Spelling = tok::getPunctuatorSpelling(ExpectedTok); 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric DiagnosticBuilder DB = 1430b57cec5SDimitry Andric Spelling 1440b57cec5SDimitry Andric ? Diag(EndLoc, DiagID) << FixItHint::CreateInsertion(EndLoc, Spelling) 1450b57cec5SDimitry Andric : Diag(Tok, DiagID); 1460b57cec5SDimitry Andric if (DiagID == diag::err_expected) 1470b57cec5SDimitry Andric DB << ExpectedTok; 1480b57cec5SDimitry Andric else if (DiagID == diag::err_expected_after) 1490b57cec5SDimitry Andric DB << Msg << ExpectedTok; 1500b57cec5SDimitry Andric else 1510b57cec5SDimitry Andric DB << Msg; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric return true; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric bool Parser::ExpectAndConsumeSemi(unsigned DiagID) { 1570b57cec5SDimitry Andric if (TryConsumeToken(tok::semi)) 1580b57cec5SDimitry Andric return false; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 1610b57cec5SDimitry Andric handleUnexpectedCodeCompletionToken(); 1620b57cec5SDimitry Andric return false; 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) && 1660b57cec5SDimitry Andric NextToken().is(tok::semi)) { 1670b57cec5SDimitry Andric Diag(Tok, diag::err_extraneous_token_before_semi) 1680b57cec5SDimitry Andric << PP.getSpelling(Tok) 1690b57cec5SDimitry Andric << FixItHint::CreateRemoval(Tok.getLocation()); 1700b57cec5SDimitry Andric ConsumeAnyToken(); // The ')' or ']'. 1710b57cec5SDimitry Andric ConsumeToken(); // The ';'. 1720b57cec5SDimitry Andric return false; 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric return ExpectAndConsume(tok::semi, DiagID); 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 178a7dea167SDimitry Andric void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST TST) { 1790b57cec5SDimitry Andric if (!Tok.is(tok::semi)) return; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric bool HadMultipleSemis = false; 1820b57cec5SDimitry Andric SourceLocation StartLoc = Tok.getLocation(); 1830b57cec5SDimitry Andric SourceLocation EndLoc = Tok.getLocation(); 1840b57cec5SDimitry Andric ConsumeToken(); 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric while ((Tok.is(tok::semi) && !Tok.isAtStartOfLine())) { 1870b57cec5SDimitry Andric HadMultipleSemis = true; 1880b57cec5SDimitry Andric EndLoc = Tok.getLocation(); 1890b57cec5SDimitry Andric ConsumeToken(); 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric // C++11 allows extra semicolons at namespace scope, but not in any of the 1930b57cec5SDimitry Andric // other contexts. 1940b57cec5SDimitry Andric if (Kind == OutsideFunction && getLangOpts().CPlusPlus) { 1950b57cec5SDimitry Andric if (getLangOpts().CPlusPlus11) 1960b57cec5SDimitry Andric Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi) 1970b57cec5SDimitry Andric << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); 1980b57cec5SDimitry Andric else 1990b57cec5SDimitry Andric Diag(StartLoc, diag::ext_extra_semi_cxx11) 2000b57cec5SDimitry Andric << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); 2010b57cec5SDimitry Andric return; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis) 2050b57cec5SDimitry Andric Diag(StartLoc, diag::ext_extra_semi) 206a7dea167SDimitry Andric << Kind << DeclSpec::getSpecifierName(TST, 2070b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy()) 2080b57cec5SDimitry Andric << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); 2090b57cec5SDimitry Andric else 2100b57cec5SDimitry Andric // A single semicolon is valid after a member function definition. 2110b57cec5SDimitry Andric Diag(StartLoc, diag::warn_extra_semi_after_mem_fn_def) 2120b57cec5SDimitry Andric << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric bool Parser::expectIdentifier() { 2160b57cec5SDimitry Andric if (Tok.is(tok::identifier)) 2170b57cec5SDimitry Andric return false; 2180b57cec5SDimitry Andric if (const auto *II = Tok.getIdentifierInfo()) { 2190b57cec5SDimitry Andric if (II->isCPlusPlusKeyword(getLangOpts())) { 2200b57cec5SDimitry Andric Diag(Tok, diag::err_expected_token_instead_of_objcxx_keyword) 2210b57cec5SDimitry Andric << tok::identifier << Tok.getIdentifierInfo(); 2220b57cec5SDimitry Andric // Objective-C++: Recover by treating this keyword as a valid identifier. 2230b57cec5SDimitry Andric return false; 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::identifier; 2270b57cec5SDimitry Andric return true; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric 230e8d8bef9SDimitry Andric void Parser::checkCompoundToken(SourceLocation FirstTokLoc, 231e8d8bef9SDimitry Andric tok::TokenKind FirstTokKind, CompoundToken Op) { 232e8d8bef9SDimitry Andric if (FirstTokLoc.isInvalid()) 233e8d8bef9SDimitry Andric return; 234e8d8bef9SDimitry Andric SourceLocation SecondTokLoc = Tok.getLocation(); 235e8d8bef9SDimitry Andric 236e8d8bef9SDimitry Andric // If either token is in a macro, we expect both tokens to come from the same 237e8d8bef9SDimitry Andric // macro expansion. 238e8d8bef9SDimitry Andric if ((FirstTokLoc.isMacroID() || SecondTokLoc.isMacroID()) && 239e8d8bef9SDimitry Andric PP.getSourceManager().getFileID(FirstTokLoc) != 240e8d8bef9SDimitry Andric PP.getSourceManager().getFileID(SecondTokLoc)) { 241e8d8bef9SDimitry Andric Diag(FirstTokLoc, diag::warn_compound_token_split_by_macro) 242e8d8bef9SDimitry Andric << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind() 243e8d8bef9SDimitry Andric << static_cast<int>(Op) << SourceRange(FirstTokLoc); 244e8d8bef9SDimitry Andric Diag(SecondTokLoc, diag::note_compound_token_split_second_token_here) 245e8d8bef9SDimitry Andric << (FirstTokKind == Tok.getKind()) << Tok.getKind() 246e8d8bef9SDimitry Andric << SourceRange(SecondTokLoc); 247e8d8bef9SDimitry Andric return; 248e8d8bef9SDimitry Andric } 249e8d8bef9SDimitry Andric 250e8d8bef9SDimitry Andric // We expect the tokens to abut. 251e8d8bef9SDimitry Andric if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) { 252e8d8bef9SDimitry Andric SourceLocation SpaceLoc = PP.getLocForEndOfToken(FirstTokLoc); 253e8d8bef9SDimitry Andric if (SpaceLoc.isInvalid()) 254e8d8bef9SDimitry Andric SpaceLoc = FirstTokLoc; 255e8d8bef9SDimitry Andric Diag(SpaceLoc, diag::warn_compound_token_split_by_whitespace) 256e8d8bef9SDimitry Andric << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind() 257e8d8bef9SDimitry Andric << static_cast<int>(Op) << SourceRange(FirstTokLoc, SecondTokLoc); 258e8d8bef9SDimitry Andric return; 259e8d8bef9SDimitry Andric } 260e8d8bef9SDimitry Andric } 261e8d8bef9SDimitry Andric 2620b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2630b57cec5SDimitry Andric // Error recovery. 2640b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) { 2670b57cec5SDimitry Andric return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0; 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric /// SkipUntil - Read tokens until we get to the specified token, then consume 2710b57cec5SDimitry Andric /// it (unless no flag StopBeforeMatch). Because we cannot guarantee that the 2720b57cec5SDimitry Andric /// token will ever occur, this skips to the next token, or to some likely 2730b57cec5SDimitry Andric /// good stopping point. If StopAtSemi is true, skipping will stop at a ';' 2740b57cec5SDimitry Andric /// character. 2750b57cec5SDimitry Andric /// 2760b57cec5SDimitry Andric /// If SkipUntil finds the specified token, it returns true, otherwise it 2770b57cec5SDimitry Andric /// returns false. 2780b57cec5SDimitry Andric bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) { 2790b57cec5SDimitry Andric // We always want this function to skip at least one token if the first token 2800b57cec5SDimitry Andric // isn't T and if not at EOF. 2810b57cec5SDimitry Andric bool isFirstTokenSkipped = true; 28204eeddc0SDimitry Andric while (true) { 2830b57cec5SDimitry Andric // If we found one of the tokens, stop and return true. 2840b57cec5SDimitry Andric for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) { 2850b57cec5SDimitry Andric if (Tok.is(Toks[i])) { 2860b57cec5SDimitry Andric if (HasFlagsSet(Flags, StopBeforeMatch)) { 2870b57cec5SDimitry Andric // Noop, don't consume the token. 2880b57cec5SDimitry Andric } else { 2890b57cec5SDimitry Andric ConsumeAnyToken(); 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric return true; 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric // Important special case: The caller has given up and just wants us to 2960b57cec5SDimitry Andric // skip the rest of the file. Do this without recursing, since we can 2970b57cec5SDimitry Andric // get here precisely because the caller detected too much recursion. 2980b57cec5SDimitry Andric if (Toks.size() == 1 && Toks[0] == tok::eof && 2990b57cec5SDimitry Andric !HasFlagsSet(Flags, StopAtSemi) && 3000b57cec5SDimitry Andric !HasFlagsSet(Flags, StopAtCodeCompletion)) { 3010b57cec5SDimitry Andric while (Tok.isNot(tok::eof)) 3020b57cec5SDimitry Andric ConsumeAnyToken(); 3030b57cec5SDimitry Andric return true; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric switch (Tok.getKind()) { 3070b57cec5SDimitry Andric case tok::eof: 3080b57cec5SDimitry Andric // Ran out of tokens. 3090b57cec5SDimitry Andric return false; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric case tok::annot_pragma_openmp: 312fe6060f1SDimitry Andric case tok::annot_attr_openmp: 3130b57cec5SDimitry Andric case tok::annot_pragma_openmp_end: 3140b57cec5SDimitry Andric // Stop before an OpenMP pragma boundary. 315480093f4SDimitry Andric if (OpenMPDirectiveParsing) 316480093f4SDimitry Andric return false; 317480093f4SDimitry Andric ConsumeAnnotationToken(); 318480093f4SDimitry Andric break; 3190b57cec5SDimitry Andric case tok::annot_module_begin: 3200b57cec5SDimitry Andric case tok::annot_module_end: 3210b57cec5SDimitry Andric case tok::annot_module_include: 3220b57cec5SDimitry Andric // Stop before we change submodules. They generally indicate a "good" 3230b57cec5SDimitry Andric // place to pick up parsing again (except in the special case where 3240b57cec5SDimitry Andric // we're trying to skip to EOF). 3250b57cec5SDimitry Andric return false; 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric case tok::code_completion: 3280b57cec5SDimitry Andric if (!HasFlagsSet(Flags, StopAtCodeCompletion)) 3290b57cec5SDimitry Andric handleUnexpectedCodeCompletionToken(); 3300b57cec5SDimitry Andric return false; 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric case tok::l_paren: 3330b57cec5SDimitry Andric // Recursively skip properly-nested parens. 3340b57cec5SDimitry Andric ConsumeParen(); 3350b57cec5SDimitry Andric if (HasFlagsSet(Flags, StopAtCodeCompletion)) 3360b57cec5SDimitry Andric SkipUntil(tok::r_paren, StopAtCodeCompletion); 3370b57cec5SDimitry Andric else 3380b57cec5SDimitry Andric SkipUntil(tok::r_paren); 3390b57cec5SDimitry Andric break; 3400b57cec5SDimitry Andric case tok::l_square: 3410b57cec5SDimitry Andric // Recursively skip properly-nested square brackets. 3420b57cec5SDimitry Andric ConsumeBracket(); 3430b57cec5SDimitry Andric if (HasFlagsSet(Flags, StopAtCodeCompletion)) 3440b57cec5SDimitry Andric SkipUntil(tok::r_square, StopAtCodeCompletion); 3450b57cec5SDimitry Andric else 3460b57cec5SDimitry Andric SkipUntil(tok::r_square); 3470b57cec5SDimitry Andric break; 3480b57cec5SDimitry Andric case tok::l_brace: 3490b57cec5SDimitry Andric // Recursively skip properly-nested braces. 3500b57cec5SDimitry Andric ConsumeBrace(); 3510b57cec5SDimitry Andric if (HasFlagsSet(Flags, StopAtCodeCompletion)) 3520b57cec5SDimitry Andric SkipUntil(tok::r_brace, StopAtCodeCompletion); 3530b57cec5SDimitry Andric else 3540b57cec5SDimitry Andric SkipUntil(tok::r_brace); 3550b57cec5SDimitry Andric break; 3560b57cec5SDimitry Andric case tok::question: 3570b57cec5SDimitry Andric // Recursively skip ? ... : pairs; these function as brackets. But 3580b57cec5SDimitry Andric // still stop at a semicolon if requested. 3590b57cec5SDimitry Andric ConsumeToken(); 3600b57cec5SDimitry Andric SkipUntil(tok::colon, 3610b57cec5SDimitry Andric SkipUntilFlags(unsigned(Flags) & 3620b57cec5SDimitry Andric unsigned(StopAtCodeCompletion | StopAtSemi))); 3630b57cec5SDimitry Andric break; 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric // Okay, we found a ']' or '}' or ')', which we think should be balanced. 3660b57cec5SDimitry Andric // Since the user wasn't looking for this token (if they were, it would 3670b57cec5SDimitry Andric // already be handled), this isn't balanced. If there is a LHS token at a 3680b57cec5SDimitry Andric // higher level, we will assume that this matches the unbalanced token 3690b57cec5SDimitry Andric // and return it. Otherwise, this is a spurious RHS token, which we skip. 3700b57cec5SDimitry Andric case tok::r_paren: 3710b57cec5SDimitry Andric if (ParenCount && !isFirstTokenSkipped) 3720b57cec5SDimitry Andric return false; // Matches something. 3730b57cec5SDimitry Andric ConsumeParen(); 3740b57cec5SDimitry Andric break; 3750b57cec5SDimitry Andric case tok::r_square: 3760b57cec5SDimitry Andric if (BracketCount && !isFirstTokenSkipped) 3770b57cec5SDimitry Andric return false; // Matches something. 3780b57cec5SDimitry Andric ConsumeBracket(); 3790b57cec5SDimitry Andric break; 3800b57cec5SDimitry Andric case tok::r_brace: 3810b57cec5SDimitry Andric if (BraceCount && !isFirstTokenSkipped) 3820b57cec5SDimitry Andric return false; // Matches something. 3830b57cec5SDimitry Andric ConsumeBrace(); 3840b57cec5SDimitry Andric break; 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric case tok::semi: 3870b57cec5SDimitry Andric if (HasFlagsSet(Flags, StopAtSemi)) 3880b57cec5SDimitry Andric return false; 3890b57cec5SDimitry Andric LLVM_FALLTHROUGH; 3900b57cec5SDimitry Andric default: 3910b57cec5SDimitry Andric // Skip this token. 3920b57cec5SDimitry Andric ConsumeAnyToken(); 3930b57cec5SDimitry Andric break; 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric isFirstTokenSkipped = false; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric } 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4000b57cec5SDimitry Andric // Scope manipulation 4010b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric /// EnterScope - Start a new scope. 4040b57cec5SDimitry Andric void Parser::EnterScope(unsigned ScopeFlags) { 4050b57cec5SDimitry Andric if (NumCachedScopes) { 4060b57cec5SDimitry Andric Scope *N = ScopeCache[--NumCachedScopes]; 4070b57cec5SDimitry Andric N->Init(getCurScope(), ScopeFlags); 4080b57cec5SDimitry Andric Actions.CurScope = N; 4090b57cec5SDimitry Andric } else { 4100b57cec5SDimitry Andric Actions.CurScope = new Scope(getCurScope(), ScopeFlags, Diags); 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric /// ExitScope - Pop a scope off the scope stack. 4150b57cec5SDimitry Andric void Parser::ExitScope() { 4160b57cec5SDimitry Andric assert(getCurScope() && "Scope imbalance!"); 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric // Inform the actions module that this scope is going away if there are any 4190b57cec5SDimitry Andric // decls in it. 4200b57cec5SDimitry Andric Actions.ActOnPopScope(Tok.getLocation(), getCurScope()); 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric Scope *OldScope = getCurScope(); 4230b57cec5SDimitry Andric Actions.CurScope = OldScope->getParent(); 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric if (NumCachedScopes == ScopeCacheSize) 4260b57cec5SDimitry Andric delete OldScope; 4270b57cec5SDimitry Andric else 4280b57cec5SDimitry Andric ScopeCache[NumCachedScopes++] = OldScope; 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric /// Set the flags for the current scope to ScopeFlags. If ManageFlags is false, 4320b57cec5SDimitry Andric /// this object does nothing. 4330b57cec5SDimitry Andric Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags, 4340b57cec5SDimitry Andric bool ManageFlags) 4350b57cec5SDimitry Andric : CurScope(ManageFlags ? Self->getCurScope() : nullptr) { 4360b57cec5SDimitry Andric if (CurScope) { 4370b57cec5SDimitry Andric OldFlags = CurScope->getFlags(); 4380b57cec5SDimitry Andric CurScope->setFlags(ScopeFlags); 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric /// Restore the flags for the current scope to what they were before this 4430b57cec5SDimitry Andric /// object overrode them. 4440b57cec5SDimitry Andric Parser::ParseScopeFlags::~ParseScopeFlags() { 4450b57cec5SDimitry Andric if (CurScope) 4460b57cec5SDimitry Andric CurScope->setFlags(OldFlags); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4510b57cec5SDimitry Andric // C99 6.9: External Definitions. 4520b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric Parser::~Parser() { 4550b57cec5SDimitry Andric // If we still have scopes active, delete the scope tree. 4560b57cec5SDimitry Andric delete getCurScope(); 4570b57cec5SDimitry Andric Actions.CurScope = nullptr; 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric // Free the scope cache. 4600b57cec5SDimitry Andric for (unsigned i = 0, e = NumCachedScopes; i != e; ++i) 4610b57cec5SDimitry Andric delete ScopeCache[i]; 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric resetPragmaHandlers(); 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric PP.removeCommentHandler(CommentSemaHandler.get()); 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric PP.clearCodeCompletionHandler(); 4680b57cec5SDimitry Andric 4695ffd83dbSDimitry Andric DestroyTemplateIds(); 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric /// Initialize - Warm up the parser. 4730b57cec5SDimitry Andric /// 4740b57cec5SDimitry Andric void Parser::Initialize() { 4750b57cec5SDimitry Andric // Create the translation unit scope. Install it as the current scope. 4760b57cec5SDimitry Andric assert(getCurScope() == nullptr && "A scope is already active?"); 4770b57cec5SDimitry Andric EnterScope(Scope::DeclScope); 4780b57cec5SDimitry Andric Actions.ActOnTranslationUnitScope(getCurScope()); 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric // Initialization for Objective-C context sensitive keywords recognition. 4810b57cec5SDimitry Andric // Referenced in Parser::ParseObjCTypeQualifierList. 4820b57cec5SDimitry Andric if (getLangOpts().ObjC) { 4830b57cec5SDimitry Andric ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in"); 4840b57cec5SDimitry Andric ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out"); 4850b57cec5SDimitry Andric ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout"); 4860b57cec5SDimitry Andric ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway"); 4870b57cec5SDimitry Andric ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy"); 4880b57cec5SDimitry Andric ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref"); 4890b57cec5SDimitry Andric ObjCTypeQuals[objc_nonnull] = &PP.getIdentifierTable().get("nonnull"); 4900b57cec5SDimitry Andric ObjCTypeQuals[objc_nullable] = &PP.getIdentifierTable().get("nullable"); 4910b57cec5SDimitry Andric ObjCTypeQuals[objc_null_unspecified] 4920b57cec5SDimitry Andric = &PP.getIdentifierTable().get("null_unspecified"); 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric Ident_instancetype = nullptr; 4960b57cec5SDimitry Andric Ident_final = nullptr; 4970b57cec5SDimitry Andric Ident_sealed = nullptr; 498fe6060f1SDimitry Andric Ident_abstract = nullptr; 4990b57cec5SDimitry Andric Ident_override = nullptr; 5000b57cec5SDimitry Andric Ident_GNU_final = nullptr; 5010b57cec5SDimitry Andric Ident_import = nullptr; 5020b57cec5SDimitry Andric Ident_module = nullptr; 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric Ident_super = &PP.getIdentifierTable().get("super"); 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric Ident_vector = nullptr; 5070b57cec5SDimitry Andric Ident_bool = nullptr; 508fe6060f1SDimitry Andric Ident_Bool = nullptr; 5090b57cec5SDimitry Andric Ident_pixel = nullptr; 5100b57cec5SDimitry Andric if (getLangOpts().AltiVec || getLangOpts().ZVector) { 5110b57cec5SDimitry Andric Ident_vector = &PP.getIdentifierTable().get("vector"); 5120b57cec5SDimitry Andric Ident_bool = &PP.getIdentifierTable().get("bool"); 513fe6060f1SDimitry Andric Ident_Bool = &PP.getIdentifierTable().get("_Bool"); 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric if (getLangOpts().AltiVec) 5160b57cec5SDimitry Andric Ident_pixel = &PP.getIdentifierTable().get("pixel"); 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric Ident_introduced = nullptr; 5190b57cec5SDimitry Andric Ident_deprecated = nullptr; 5200b57cec5SDimitry Andric Ident_obsoleted = nullptr; 5210b57cec5SDimitry Andric Ident_unavailable = nullptr; 5220b57cec5SDimitry Andric Ident_strict = nullptr; 5230b57cec5SDimitry Andric Ident_replacement = nullptr; 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric Ident_language = Ident_defined_in = Ident_generated_declaration = nullptr; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric Ident__except = nullptr; 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric Ident__exception_code = Ident__exception_info = nullptr; 5300b57cec5SDimitry Andric Ident__abnormal_termination = Ident___exception_code = nullptr; 5310b57cec5SDimitry Andric Ident___exception_info = Ident___abnormal_termination = nullptr; 5320b57cec5SDimitry Andric Ident_GetExceptionCode = Ident_GetExceptionInfo = nullptr; 5330b57cec5SDimitry Andric Ident_AbnormalTermination = nullptr; 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric if(getLangOpts().Borland) { 5360b57cec5SDimitry Andric Ident__exception_info = PP.getIdentifierInfo("_exception_info"); 5370b57cec5SDimitry Andric Ident___exception_info = PP.getIdentifierInfo("__exception_info"); 5380b57cec5SDimitry Andric Ident_GetExceptionInfo = PP.getIdentifierInfo("GetExceptionInformation"); 5390b57cec5SDimitry Andric Ident__exception_code = PP.getIdentifierInfo("_exception_code"); 5400b57cec5SDimitry Andric Ident___exception_code = PP.getIdentifierInfo("__exception_code"); 5410b57cec5SDimitry Andric Ident_GetExceptionCode = PP.getIdentifierInfo("GetExceptionCode"); 5420b57cec5SDimitry Andric Ident__abnormal_termination = PP.getIdentifierInfo("_abnormal_termination"); 5430b57cec5SDimitry Andric Ident___abnormal_termination = PP.getIdentifierInfo("__abnormal_termination"); 5440b57cec5SDimitry Andric Ident_AbnormalTermination = PP.getIdentifierInfo("AbnormalTermination"); 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric PP.SetPoisonReason(Ident__exception_code,diag::err_seh___except_block); 5470b57cec5SDimitry Andric PP.SetPoisonReason(Ident___exception_code,diag::err_seh___except_block); 5480b57cec5SDimitry Andric PP.SetPoisonReason(Ident_GetExceptionCode,diag::err_seh___except_block); 5490b57cec5SDimitry Andric PP.SetPoisonReason(Ident__exception_info,diag::err_seh___except_filter); 5500b57cec5SDimitry Andric PP.SetPoisonReason(Ident___exception_info,diag::err_seh___except_filter); 5510b57cec5SDimitry Andric PP.SetPoisonReason(Ident_GetExceptionInfo,diag::err_seh___except_filter); 5520b57cec5SDimitry Andric PP.SetPoisonReason(Ident__abnormal_termination,diag::err_seh___finally_block); 5530b57cec5SDimitry Andric PP.SetPoisonReason(Ident___abnormal_termination,diag::err_seh___finally_block); 5540b57cec5SDimitry Andric PP.SetPoisonReason(Ident_AbnormalTermination,diag::err_seh___finally_block); 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric if (getLangOpts().CPlusPlusModules) { 5580b57cec5SDimitry Andric Ident_import = PP.getIdentifierInfo("import"); 5590b57cec5SDimitry Andric Ident_module = PP.getIdentifierInfo("module"); 5600b57cec5SDimitry Andric } 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric Actions.Initialize(); 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric // Prime the lexer look-ahead. 5650b57cec5SDimitry Andric ConsumeToken(); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric 5685ffd83dbSDimitry Andric void Parser::DestroyTemplateIds() { 5695ffd83dbSDimitry Andric for (TemplateIdAnnotation *Id : TemplateIds) 5705ffd83dbSDimitry Andric Id->Destroy(); 5715ffd83dbSDimitry Andric TemplateIds.clear(); 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric /// Parse the first top-level declaration in a translation unit. 5750b57cec5SDimitry Andric /// 5760b57cec5SDimitry Andric /// translation-unit: 5770b57cec5SDimitry Andric /// [C] external-declaration 5780b57cec5SDimitry Andric /// [C] translation-unit external-declaration 5790b57cec5SDimitry Andric /// [C++] top-level-declaration-seq[opt] 5800b57cec5SDimitry Andric /// [C++20] global-module-fragment[opt] module-declaration 5810b57cec5SDimitry Andric /// top-level-declaration-seq[opt] private-module-fragment[opt] 5820b57cec5SDimitry Andric /// 5830b57cec5SDimitry Andric /// Note that in C, it is an error if there is no first declaration. 58481ad6265SDimitry Andric bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result, 58581ad6265SDimitry Andric Sema::ModuleImportState &ImportState) { 5860b57cec5SDimitry Andric Actions.ActOnStartOfTranslationUnit(); 5870b57cec5SDimitry Andric 58881ad6265SDimitry Andric // For C++20 modules, a module decl must be the first in the TU. We also 58981ad6265SDimitry Andric // need to track module imports. 59081ad6265SDimitry Andric ImportState = Sema::ModuleImportState::FirstDecl; 59181ad6265SDimitry Andric bool NoTopLevelDecls = ParseTopLevelDecl(Result, ImportState); 59281ad6265SDimitry Andric 5930b57cec5SDimitry Andric // C11 6.9p1 says translation units must have at least one top-level 5940b57cec5SDimitry Andric // declaration. C++ doesn't have this restriction. We also don't want to 5950b57cec5SDimitry Andric // complain if we have a precompiled header, although technically if the PCH 5960b57cec5SDimitry Andric // is empty we should still emit the (pedantic) diagnostic. 597e8d8bef9SDimitry Andric // If the main file is a header, we're only pretending it's a TU; don't warn. 5980b57cec5SDimitry Andric if (NoTopLevelDecls && !Actions.getASTContext().getExternalSource() && 599e8d8bef9SDimitry Andric !getLangOpts().CPlusPlus && !getLangOpts().IsHeaderFile) 6000b57cec5SDimitry Andric Diag(diag::ext_empty_translation_unit); 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric return NoTopLevelDecls; 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric 6050b57cec5SDimitry Andric /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the 6060b57cec5SDimitry Andric /// action tells us to. This returns true if the EOF was encountered. 6070b57cec5SDimitry Andric /// 6080b57cec5SDimitry Andric /// top-level-declaration: 6090b57cec5SDimitry Andric /// declaration 6100b57cec5SDimitry Andric /// [C++20] module-import-declaration 61181ad6265SDimitry Andric bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, 61281ad6265SDimitry Andric Sema::ModuleImportState &ImportState) { 6135ffd83dbSDimitry Andric DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this); 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric // Skip over the EOF token, flagging end of previous input for incremental 6160b57cec5SDimitry Andric // processing 6170b57cec5SDimitry Andric if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof)) 6180b57cec5SDimitry Andric ConsumeToken(); 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric Result = nullptr; 6210b57cec5SDimitry Andric switch (Tok.getKind()) { 6220b57cec5SDimitry Andric case tok::annot_pragma_unused: 6230b57cec5SDimitry Andric HandlePragmaUnused(); 6240b57cec5SDimitry Andric return false; 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andric case tok::kw_export: 6270b57cec5SDimitry Andric switch (NextToken().getKind()) { 6280b57cec5SDimitry Andric case tok::kw_module: 6290b57cec5SDimitry Andric goto module_decl; 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric // Note: no need to handle kw_import here. We only form kw_import under 6320b57cec5SDimitry Andric // the Modules TS, and in that case 'export import' is parsed as an 6330b57cec5SDimitry Andric // export-declaration containing an import-declaration. 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric // Recognize context-sensitive C++20 'export module' and 'export import' 6360b57cec5SDimitry Andric // declarations. 6370b57cec5SDimitry Andric case tok::identifier: { 6380b57cec5SDimitry Andric IdentifierInfo *II = NextToken().getIdentifierInfo(); 6390b57cec5SDimitry Andric if ((II == Ident_module || II == Ident_import) && 6400b57cec5SDimitry Andric GetLookAheadToken(2).isNot(tok::coloncolon)) { 6410b57cec5SDimitry Andric if (II == Ident_module) 6420b57cec5SDimitry Andric goto module_decl; 6430b57cec5SDimitry Andric else 6440b57cec5SDimitry Andric goto import_decl; 6450b57cec5SDimitry Andric } 6460b57cec5SDimitry Andric break; 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric default: 6500b57cec5SDimitry Andric break; 6510b57cec5SDimitry Andric } 6520b57cec5SDimitry Andric break; 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric case tok::kw_module: 6550b57cec5SDimitry Andric module_decl: 65681ad6265SDimitry Andric Result = ParseModuleDecl(ImportState); 6570b57cec5SDimitry Andric return false; 6580b57cec5SDimitry Andric 65981ad6265SDimitry Andric case tok::kw_import: 6600b57cec5SDimitry Andric import_decl: { 66181ad6265SDimitry Andric Decl *ImportDecl = ParseModuleImport(SourceLocation(), ImportState); 6620b57cec5SDimitry Andric Result = Actions.ConvertDeclToDeclGroup(ImportDecl); 6630b57cec5SDimitry Andric return false; 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 666*753f127fSDimitry Andric case tok::annot_module_include: { 667*753f127fSDimitry Andric auto Loc = Tok.getLocation(); 668*753f127fSDimitry Andric Module *Mod = reinterpret_cast<Module *>(Tok.getAnnotationValue()); 669*753f127fSDimitry Andric // FIXME: We need a better way to disambiguate C++ clang modules and 670*753f127fSDimitry Andric // standard C++ modules. 671*753f127fSDimitry Andric if (!getLangOpts().CPlusPlusModules || !Mod->isHeaderUnit()) 672*753f127fSDimitry Andric Actions.ActOnModuleInclude(Loc, Mod); 673*753f127fSDimitry Andric else { 674*753f127fSDimitry Andric DeclResult Import = 675*753f127fSDimitry Andric Actions.ActOnModuleImport(Loc, SourceLocation(), Loc, Mod); 676*753f127fSDimitry Andric Decl *ImportDecl = Import.isInvalid() ? nullptr : Import.get(); 677*753f127fSDimitry Andric Result = Actions.ConvertDeclToDeclGroup(ImportDecl); 678*753f127fSDimitry Andric } 6790b57cec5SDimitry Andric ConsumeAnnotationToken(); 6800b57cec5SDimitry Andric return false; 681*753f127fSDimitry Andric } 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric case tok::annot_module_begin: 6840b57cec5SDimitry Andric Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>( 6850b57cec5SDimitry Andric Tok.getAnnotationValue())); 6860b57cec5SDimitry Andric ConsumeAnnotationToken(); 68781ad6265SDimitry Andric ImportState = Sema::ModuleImportState::NotACXX20Module; 6880b57cec5SDimitry Andric return false; 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric case tok::annot_module_end: 6910b57cec5SDimitry Andric Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>( 6920b57cec5SDimitry Andric Tok.getAnnotationValue())); 6930b57cec5SDimitry Andric ConsumeAnnotationToken(); 69481ad6265SDimitry Andric ImportState = Sema::ModuleImportState::NotACXX20Module; 6950b57cec5SDimitry Andric return false; 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric case tok::eof: 6985ffd83dbSDimitry Andric // Check whether -fmax-tokens= was reached. 6995ffd83dbSDimitry Andric if (PP.getMaxTokens() != 0 && PP.getTokenCount() > PP.getMaxTokens()) { 7005ffd83dbSDimitry Andric PP.Diag(Tok.getLocation(), diag::warn_max_tokens_total) 7015ffd83dbSDimitry Andric << PP.getTokenCount() << PP.getMaxTokens(); 7025ffd83dbSDimitry Andric SourceLocation OverrideLoc = PP.getMaxTokensOverrideLoc(); 7035ffd83dbSDimitry Andric if (OverrideLoc.isValid()) { 7045ffd83dbSDimitry Andric PP.Diag(OverrideLoc, diag::note_max_tokens_total_override); 7055ffd83dbSDimitry Andric } 7065ffd83dbSDimitry Andric } 7075ffd83dbSDimitry Andric 7080b57cec5SDimitry Andric // Late template parsing can begin. 7095ffd83dbSDimitry Andric Actions.SetLateTemplateParser(LateTemplateParserCallback, nullptr, this); 7100b57cec5SDimitry Andric if (!PP.isIncrementalProcessingEnabled()) 7110b57cec5SDimitry Andric Actions.ActOnEndOfTranslationUnit(); 7120b57cec5SDimitry Andric //else don't tell Sema that we ended parsing: more input might come. 7130b57cec5SDimitry Andric return true; 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric case tok::identifier: 7160b57cec5SDimitry Andric // C++2a [basic.link]p3: 7170b57cec5SDimitry Andric // A token sequence beginning with 'export[opt] module' or 7180b57cec5SDimitry Andric // 'export[opt] import' and not immediately followed by '::' 7190b57cec5SDimitry Andric // is never interpreted as the declaration of a top-level-declaration. 7200b57cec5SDimitry Andric if ((Tok.getIdentifierInfo() == Ident_module || 7210b57cec5SDimitry Andric Tok.getIdentifierInfo() == Ident_import) && 7220b57cec5SDimitry Andric NextToken().isNot(tok::coloncolon)) { 7230b57cec5SDimitry Andric if (Tok.getIdentifierInfo() == Ident_module) 7240b57cec5SDimitry Andric goto module_decl; 7250b57cec5SDimitry Andric else 7260b57cec5SDimitry Andric goto import_decl; 7270b57cec5SDimitry Andric } 7280b57cec5SDimitry Andric break; 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric default: 7310b57cec5SDimitry Andric break; 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 73481ad6265SDimitry Andric ParsedAttributes attrs(AttrFactory); 7350b57cec5SDimitry Andric MaybeParseCXX11Attributes(attrs); 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric Result = ParseExternalDeclaration(attrs); 73881ad6265SDimitry Andric // An empty Result might mean a line with ';' or some parsing error, ignore 73981ad6265SDimitry Andric // it. 74081ad6265SDimitry Andric if (Result) { 74181ad6265SDimitry Andric if (ImportState == Sema::ModuleImportState::FirstDecl) 74281ad6265SDimitry Andric // First decl was not modular. 74381ad6265SDimitry Andric ImportState = Sema::ModuleImportState::NotACXX20Module; 74481ad6265SDimitry Andric else if (ImportState == Sema::ModuleImportState::ImportAllowed) 74581ad6265SDimitry Andric // Non-imports disallow further imports. 74681ad6265SDimitry Andric ImportState = Sema::ModuleImportState::ImportFinished; 74781ad6265SDimitry Andric } 7480b57cec5SDimitry Andric return false; 7490b57cec5SDimitry Andric } 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric /// ParseExternalDeclaration: 7520b57cec5SDimitry Andric /// 75381ad6265SDimitry Andric /// The `Attrs` that are passed in are C++11 attributes and appertain to the 75481ad6265SDimitry Andric /// declaration. 75581ad6265SDimitry Andric /// 7560b57cec5SDimitry Andric /// external-declaration: [C99 6.9], declaration: [C++ dcl.dcl] 7570b57cec5SDimitry Andric /// function-definition 7580b57cec5SDimitry Andric /// declaration 7590b57cec5SDimitry Andric /// [GNU] asm-definition 7600b57cec5SDimitry Andric /// [GNU] __extension__ external-declaration 7610b57cec5SDimitry Andric /// [OBJC] objc-class-definition 7620b57cec5SDimitry Andric /// [OBJC] objc-class-declaration 7630b57cec5SDimitry Andric /// [OBJC] objc-alias-declaration 7640b57cec5SDimitry Andric /// [OBJC] objc-protocol-definition 7650b57cec5SDimitry Andric /// [OBJC] objc-method-definition 7660b57cec5SDimitry Andric /// [OBJC] @end 7670b57cec5SDimitry Andric /// [C++] linkage-specification 7680b57cec5SDimitry Andric /// [GNU] asm-definition: 7690b57cec5SDimitry Andric /// simple-asm-expr ';' 7700b57cec5SDimitry Andric /// [C++11] empty-declaration 7710b57cec5SDimitry Andric /// [C++11] attribute-declaration 7720b57cec5SDimitry Andric /// 7730b57cec5SDimitry Andric /// [C++11] empty-declaration: 7740b57cec5SDimitry Andric /// ';' 7750b57cec5SDimitry Andric /// 7760b57cec5SDimitry Andric /// [C++0x/GNU] 'extern' 'template' declaration 7770b57cec5SDimitry Andric /// 7780b57cec5SDimitry Andric /// [Modules-TS] module-import-declaration 7790b57cec5SDimitry Andric /// 78081ad6265SDimitry Andric Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributes &Attrs, 7810b57cec5SDimitry Andric ParsingDeclSpec *DS) { 7825ffd83dbSDimitry Andric DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this); 7830b57cec5SDimitry Andric ParenBraceBracketBalancer BalancerRAIIObj(*this); 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric if (PP.isCodeCompletionReached()) { 7860b57cec5SDimitry Andric cutOffParsing(); 7870b57cec5SDimitry Andric return nullptr; 7880b57cec5SDimitry Andric } 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric Decl *SingleDecl = nullptr; 7910b57cec5SDimitry Andric switch (Tok.getKind()) { 7920b57cec5SDimitry Andric case tok::annot_pragma_vis: 7930b57cec5SDimitry Andric HandlePragmaVisibility(); 7940b57cec5SDimitry Andric return nullptr; 7950b57cec5SDimitry Andric case tok::annot_pragma_pack: 7960b57cec5SDimitry Andric HandlePragmaPack(); 7970b57cec5SDimitry Andric return nullptr; 7980b57cec5SDimitry Andric case tok::annot_pragma_msstruct: 7990b57cec5SDimitry Andric HandlePragmaMSStruct(); 8000b57cec5SDimitry Andric return nullptr; 8010b57cec5SDimitry Andric case tok::annot_pragma_align: 8020b57cec5SDimitry Andric HandlePragmaAlign(); 8030b57cec5SDimitry Andric return nullptr; 8040b57cec5SDimitry Andric case tok::annot_pragma_weak: 8050b57cec5SDimitry Andric HandlePragmaWeak(); 8060b57cec5SDimitry Andric return nullptr; 8070b57cec5SDimitry Andric case tok::annot_pragma_weakalias: 8080b57cec5SDimitry Andric HandlePragmaWeakAlias(); 8090b57cec5SDimitry Andric return nullptr; 8100b57cec5SDimitry Andric case tok::annot_pragma_redefine_extname: 8110b57cec5SDimitry Andric HandlePragmaRedefineExtname(); 8120b57cec5SDimitry Andric return nullptr; 8130b57cec5SDimitry Andric case tok::annot_pragma_fp_contract: 8140b57cec5SDimitry Andric HandlePragmaFPContract(); 8150b57cec5SDimitry Andric return nullptr; 8160b57cec5SDimitry Andric case tok::annot_pragma_fenv_access: 817349cc55cSDimitry Andric case tok::annot_pragma_fenv_access_ms: 8180b57cec5SDimitry Andric HandlePragmaFEnvAccess(); 8190b57cec5SDimitry Andric return nullptr; 820e8d8bef9SDimitry Andric case tok::annot_pragma_fenv_round: 821e8d8bef9SDimitry Andric HandlePragmaFEnvRound(); 822e8d8bef9SDimitry Andric return nullptr; 8235ffd83dbSDimitry Andric case tok::annot_pragma_float_control: 8245ffd83dbSDimitry Andric HandlePragmaFloatControl(); 8255ffd83dbSDimitry Andric return nullptr; 8260b57cec5SDimitry Andric case tok::annot_pragma_fp: 8270b57cec5SDimitry Andric HandlePragmaFP(); 8280b57cec5SDimitry Andric break; 8290b57cec5SDimitry Andric case tok::annot_pragma_opencl_extension: 8300b57cec5SDimitry Andric HandlePragmaOpenCLExtension(); 8310b57cec5SDimitry Andric return nullptr; 832fe6060f1SDimitry Andric case tok::annot_attr_openmp: 8330b57cec5SDimitry Andric case tok::annot_pragma_openmp: { 8340b57cec5SDimitry Andric AccessSpecifier AS = AS_none; 83581ad6265SDimitry Andric return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs); 8360b57cec5SDimitry Andric } 8370b57cec5SDimitry Andric case tok::annot_pragma_ms_pointers_to_members: 8380b57cec5SDimitry Andric HandlePragmaMSPointersToMembers(); 8390b57cec5SDimitry Andric return nullptr; 8400b57cec5SDimitry Andric case tok::annot_pragma_ms_vtordisp: 8410b57cec5SDimitry Andric HandlePragmaMSVtorDisp(); 8420b57cec5SDimitry Andric return nullptr; 8430b57cec5SDimitry Andric case tok::annot_pragma_ms_pragma: 8440b57cec5SDimitry Andric HandlePragmaMSPragma(); 8450b57cec5SDimitry Andric return nullptr; 8460b57cec5SDimitry Andric case tok::annot_pragma_dump: 8470b57cec5SDimitry Andric HandlePragmaDump(); 8480b57cec5SDimitry Andric return nullptr; 8490b57cec5SDimitry Andric case tok::annot_pragma_attribute: 8500b57cec5SDimitry Andric HandlePragmaAttribute(); 8510b57cec5SDimitry Andric return nullptr; 8520b57cec5SDimitry Andric case tok::semi: 8530b57cec5SDimitry Andric // Either a C++11 empty-declaration or attribute-declaration. 8540b57cec5SDimitry Andric SingleDecl = 85581ad6265SDimitry Andric Actions.ActOnEmptyDeclaration(getCurScope(), Attrs, Tok.getLocation()); 8560b57cec5SDimitry Andric ConsumeExtraSemi(OutsideFunction); 8570b57cec5SDimitry Andric break; 8580b57cec5SDimitry Andric case tok::r_brace: 8590b57cec5SDimitry Andric Diag(Tok, diag::err_extraneous_closing_brace); 8600b57cec5SDimitry Andric ConsumeBrace(); 8610b57cec5SDimitry Andric return nullptr; 8620b57cec5SDimitry Andric case tok::eof: 8630b57cec5SDimitry Andric Diag(Tok, diag::err_expected_external_declaration); 8640b57cec5SDimitry Andric return nullptr; 8650b57cec5SDimitry Andric case tok::kw___extension__: { 8660b57cec5SDimitry Andric // __extension__ silences extension warnings in the subexpression. 8670b57cec5SDimitry Andric ExtensionRAIIObject O(Diags); // Use RAII to do this. 8680b57cec5SDimitry Andric ConsumeToken(); 86981ad6265SDimitry Andric return ParseExternalDeclaration(Attrs); 8700b57cec5SDimitry Andric } 8710b57cec5SDimitry Andric case tok::kw_asm: { 87281ad6265SDimitry Andric ProhibitAttributes(Attrs); 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andric SourceLocation StartLoc = Tok.getLocation(); 8750b57cec5SDimitry Andric SourceLocation EndLoc; 8760b57cec5SDimitry Andric 877480093f4SDimitry Andric ExprResult Result(ParseSimpleAsm(/*ForAsmLabel*/ false, &EndLoc)); 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric // Check if GNU-style InlineAsm is disabled. 8800b57cec5SDimitry Andric // Empty asm string is allowed because it will not introduce 8810b57cec5SDimitry Andric // any assembly code. 8820b57cec5SDimitry Andric if (!(getLangOpts().GNUAsm || Result.isInvalid())) { 8830b57cec5SDimitry Andric const auto *SL = cast<StringLiteral>(Result.get()); 8840b57cec5SDimitry Andric if (!SL->getString().trim().empty()) 8850b57cec5SDimitry Andric Diag(StartLoc, diag::err_gnu_inline_asm_disabled); 8860b57cec5SDimitry Andric } 8870b57cec5SDimitry Andric 8880b57cec5SDimitry Andric ExpectAndConsume(tok::semi, diag::err_expected_after, 8890b57cec5SDimitry Andric "top-level asm block"); 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric if (Result.isInvalid()) 8920b57cec5SDimitry Andric return nullptr; 8930b57cec5SDimitry Andric SingleDecl = Actions.ActOnFileScopeAsmDecl(Result.get(), StartLoc, EndLoc); 8940b57cec5SDimitry Andric break; 8950b57cec5SDimitry Andric } 8960b57cec5SDimitry Andric case tok::at: 89781ad6265SDimitry Andric return ParseObjCAtDirectives(Attrs); 8980b57cec5SDimitry Andric case tok::minus: 8990b57cec5SDimitry Andric case tok::plus: 9000b57cec5SDimitry Andric if (!getLangOpts().ObjC) { 9010b57cec5SDimitry Andric Diag(Tok, diag::err_expected_external_declaration); 9020b57cec5SDimitry Andric ConsumeToken(); 9030b57cec5SDimitry Andric return nullptr; 9040b57cec5SDimitry Andric } 9050b57cec5SDimitry Andric SingleDecl = ParseObjCMethodDefinition(); 9060b57cec5SDimitry Andric break; 9070b57cec5SDimitry Andric case tok::code_completion: 908fe6060f1SDimitry Andric cutOffParsing(); 9090b57cec5SDimitry Andric if (CurParsedObjCImpl) { 9100b57cec5SDimitry Andric // Code-complete Objective-C methods even without leading '-'/'+' prefix. 9110b57cec5SDimitry Andric Actions.CodeCompleteObjCMethodDecl(getCurScope(), 9120b57cec5SDimitry Andric /*IsInstanceMethod=*/None, 9130b57cec5SDimitry Andric /*ReturnType=*/nullptr); 9140b57cec5SDimitry Andric } 9150b57cec5SDimitry Andric Actions.CodeCompleteOrdinaryName( 9160b57cec5SDimitry Andric getCurScope(), 9170b57cec5SDimitry Andric CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace); 9180b57cec5SDimitry Andric return nullptr; 91981ad6265SDimitry Andric case tok::kw_import: { 92081ad6265SDimitry Andric Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module; 92181ad6265SDimitry Andric if (getLangOpts().CPlusPlusModules) { 92281ad6265SDimitry Andric llvm_unreachable("not expecting a c++20 import here"); 92381ad6265SDimitry Andric ProhibitAttributes(Attrs); 92481ad6265SDimitry Andric } 92581ad6265SDimitry Andric SingleDecl = ParseModuleImport(SourceLocation(), IS); 92681ad6265SDimitry Andric } break; 9270b57cec5SDimitry Andric case tok::kw_export: 9280b57cec5SDimitry Andric if (getLangOpts().CPlusPlusModules || getLangOpts().ModulesTS) { 92981ad6265SDimitry Andric ProhibitAttributes(Attrs); 9300b57cec5SDimitry Andric SingleDecl = ParseExportDeclaration(); 9310b57cec5SDimitry Andric break; 9320b57cec5SDimitry Andric } 9330b57cec5SDimitry Andric // This must be 'export template'. Parse it so we can diagnose our lack 9340b57cec5SDimitry Andric // of support. 9350b57cec5SDimitry Andric LLVM_FALLTHROUGH; 9360b57cec5SDimitry Andric case tok::kw_using: 9370b57cec5SDimitry Andric case tok::kw_namespace: 9380b57cec5SDimitry Andric case tok::kw_typedef: 9390b57cec5SDimitry Andric case tok::kw_template: 9400b57cec5SDimitry Andric case tok::kw_static_assert: 9410b57cec5SDimitry Andric case tok::kw__Static_assert: 9420b57cec5SDimitry Andric // A function definition cannot start with any of these keywords. 9430b57cec5SDimitry Andric { 9440b57cec5SDimitry Andric SourceLocation DeclEnd; 94581ad6265SDimitry Andric ParsedAttributes EmptyDeclSpecAttrs(AttrFactory); 94681ad6265SDimitry Andric return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs, 94781ad6265SDimitry Andric EmptyDeclSpecAttrs); 9480b57cec5SDimitry Andric } 9490b57cec5SDimitry Andric 9500b57cec5SDimitry Andric case tok::kw_static: 9510b57cec5SDimitry Andric // Parse (then ignore) 'static' prior to a template instantiation. This is 9520b57cec5SDimitry Andric // a GCC extension that we intentionally do not support. 9530b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) { 9540b57cec5SDimitry Andric Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) 9550b57cec5SDimitry Andric << 0; 9560b57cec5SDimitry Andric SourceLocation DeclEnd; 95781ad6265SDimitry Andric ParsedAttributes EmptyDeclSpecAttrs(AttrFactory); 95881ad6265SDimitry Andric return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs, 95981ad6265SDimitry Andric EmptyDeclSpecAttrs); 9600b57cec5SDimitry Andric } 9610b57cec5SDimitry Andric goto dont_know; 9620b57cec5SDimitry Andric 9630b57cec5SDimitry Andric case tok::kw_inline: 9640b57cec5SDimitry Andric if (getLangOpts().CPlusPlus) { 9650b57cec5SDimitry Andric tok::TokenKind NextKind = NextToken().getKind(); 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric // Inline namespaces. Allowed as an extension even in C++03. 9680b57cec5SDimitry Andric if (NextKind == tok::kw_namespace) { 9690b57cec5SDimitry Andric SourceLocation DeclEnd; 97081ad6265SDimitry Andric ParsedAttributes EmptyDeclSpecAttrs(AttrFactory); 97181ad6265SDimitry Andric return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs, 97281ad6265SDimitry Andric EmptyDeclSpecAttrs); 9730b57cec5SDimitry Andric } 9740b57cec5SDimitry Andric 9750b57cec5SDimitry Andric // Parse (then ignore) 'inline' prior to a template instantiation. This is 9760b57cec5SDimitry Andric // a GCC extension that we intentionally do not support. 9770b57cec5SDimitry Andric if (NextKind == tok::kw_template) { 9780b57cec5SDimitry Andric Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) 9790b57cec5SDimitry Andric << 1; 9800b57cec5SDimitry Andric SourceLocation DeclEnd; 98181ad6265SDimitry Andric ParsedAttributes EmptyDeclSpecAttrs(AttrFactory); 98281ad6265SDimitry Andric return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs, 98381ad6265SDimitry Andric EmptyDeclSpecAttrs); 9840b57cec5SDimitry Andric } 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric goto dont_know; 9870b57cec5SDimitry Andric 9880b57cec5SDimitry Andric case tok::kw_extern: 9890b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) { 9900b57cec5SDimitry Andric // Extern templates 9910b57cec5SDimitry Andric SourceLocation ExternLoc = ConsumeToken(); 9920b57cec5SDimitry Andric SourceLocation TemplateLoc = ConsumeToken(); 9930b57cec5SDimitry Andric Diag(ExternLoc, getLangOpts().CPlusPlus11 ? 9940b57cec5SDimitry Andric diag::warn_cxx98_compat_extern_template : 9950b57cec5SDimitry Andric diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc); 9960b57cec5SDimitry Andric SourceLocation DeclEnd; 997e8d8bef9SDimitry Andric return Actions.ConvertDeclToDeclGroup(ParseExplicitInstantiation( 99881ad6265SDimitry Andric DeclaratorContext::File, ExternLoc, TemplateLoc, DeclEnd, Attrs)); 9990b57cec5SDimitry Andric } 10000b57cec5SDimitry Andric goto dont_know; 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric case tok::kw___if_exists: 10030b57cec5SDimitry Andric case tok::kw___if_not_exists: 10040b57cec5SDimitry Andric ParseMicrosoftIfExistsExternalDeclaration(); 10050b57cec5SDimitry Andric return nullptr; 10060b57cec5SDimitry Andric 10070b57cec5SDimitry Andric case tok::kw_module: 10080b57cec5SDimitry Andric Diag(Tok, diag::err_unexpected_module_decl); 10090b57cec5SDimitry Andric SkipUntil(tok::semi); 10100b57cec5SDimitry Andric return nullptr; 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric default: 10130b57cec5SDimitry Andric dont_know: 10140b57cec5SDimitry Andric if (Tok.isEditorPlaceholder()) { 10150b57cec5SDimitry Andric ConsumeToken(); 10160b57cec5SDimitry Andric return nullptr; 10170b57cec5SDimitry Andric } 10180b57cec5SDimitry Andric // We can't tell whether this is a function-definition or declaration yet. 101981ad6265SDimitry Andric return ParseDeclarationOrFunctionDefinition(Attrs, DS); 10200b57cec5SDimitry Andric } 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric // This routine returns a DeclGroup, if the thing we parsed only contains a 10230b57cec5SDimitry Andric // single decl, convert it now. 10240b57cec5SDimitry Andric return Actions.ConvertDeclToDeclGroup(SingleDecl); 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric /// Determine whether the current token, if it occurs after a 10280b57cec5SDimitry Andric /// declarator, continues a declaration or declaration list. 10290b57cec5SDimitry Andric bool Parser::isDeclarationAfterDeclarator() { 10300b57cec5SDimitry Andric // Check for '= delete' or '= default' 10310b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) { 10320b57cec5SDimitry Andric const Token &KW = NextToken(); 10330b57cec5SDimitry Andric if (KW.is(tok::kw_default) || KW.is(tok::kw_delete)) 10340b57cec5SDimitry Andric return false; 10350b57cec5SDimitry Andric } 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric return Tok.is(tok::equal) || // int X()= -> not a function def 10380b57cec5SDimitry Andric Tok.is(tok::comma) || // int X(), -> not a function def 10390b57cec5SDimitry Andric Tok.is(tok::semi) || // int X(); -> not a function def 10400b57cec5SDimitry Andric Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def 10410b57cec5SDimitry Andric Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def 10420b57cec5SDimitry Andric (getLangOpts().CPlusPlus && 10430b57cec5SDimitry Andric Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++] 10440b57cec5SDimitry Andric } 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric /// Determine whether the current token, if it occurs after a 10470b57cec5SDimitry Andric /// declarator, indicates the start of a function definition. 10480b57cec5SDimitry Andric bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) { 10490b57cec5SDimitry Andric assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator"); 10500b57cec5SDimitry Andric if (Tok.is(tok::l_brace)) // int X() {} 10510b57cec5SDimitry Andric return true; 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric // Handle K&R C argument lists: int X(f) int f; {} 10540b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus && 10550b57cec5SDimitry Andric Declarator.getFunctionTypeInfo().isKNRPrototype()) 10560b57cec5SDimitry Andric return isDeclarationSpecifier(); 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) { 10590b57cec5SDimitry Andric const Token &KW = NextToken(); 10600b57cec5SDimitry Andric return KW.is(tok::kw_default) || KW.is(tok::kw_delete); 10610b57cec5SDimitry Andric } 10620b57cec5SDimitry Andric 10630b57cec5SDimitry Andric return Tok.is(tok::colon) || // X() : Base() {} (used for ctors) 10640b57cec5SDimitry Andric Tok.is(tok::kw_try); // X() try { ... } 10650b57cec5SDimitry Andric } 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric /// Parse either a function-definition or a declaration. We can't tell which 10680b57cec5SDimitry Andric /// we have until we read up to the compound-statement in function-definition. 10690b57cec5SDimitry Andric /// TemplateParams, if non-NULL, provides the template parameters when we're 10700b57cec5SDimitry Andric /// parsing a C++ template-declaration. 10710b57cec5SDimitry Andric /// 10720b57cec5SDimitry Andric /// function-definition: [C99 6.9.1] 10730b57cec5SDimitry Andric /// decl-specs declarator declaration-list[opt] compound-statement 10740b57cec5SDimitry Andric /// [C90] function-definition: [C99 6.7.1] - implicit int result 10750b57cec5SDimitry Andric /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement 10760b57cec5SDimitry Andric /// 10770b57cec5SDimitry Andric /// declaration: [C99 6.7] 10780b57cec5SDimitry Andric /// declaration-specifiers init-declarator-list[opt] ';' 10790b57cec5SDimitry Andric /// [!C99] init-declarator-list ';' [TODO: warn in c99 mode] 10800b57cec5SDimitry Andric /// [OMP] threadprivate-directive 10810b57cec5SDimitry Andric /// [OMP] allocate-directive [TODO] 10820b57cec5SDimitry Andric /// 108381ad6265SDimitry Andric Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal( 108481ad6265SDimitry Andric ParsedAttributes &Attrs, ParsingDeclSpec &DS, AccessSpecifier AS) { 10850b57cec5SDimitry Andric MaybeParseMicrosoftAttributes(DS.getAttributes()); 10860b57cec5SDimitry Andric // Parse the common declaration-specifiers piece. 10870b57cec5SDimitry Andric ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, 10880b57cec5SDimitry Andric DeclSpecContext::DSC_top_level); 10890b57cec5SDimitry Andric 10900b57cec5SDimitry Andric // If we had a free-standing type definition with a missing semicolon, we 10910b57cec5SDimitry Andric // may get this far before the problem becomes obvious. 10920b57cec5SDimitry Andric if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition( 10930b57cec5SDimitry Andric DS, AS, DeclSpecContext::DSC_top_level)) 10940b57cec5SDimitry Andric return nullptr; 10950b57cec5SDimitry Andric 10960b57cec5SDimitry Andric // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" 10970b57cec5SDimitry Andric // declaration-specifiers init-declarator-list[opt] ';' 10980b57cec5SDimitry Andric if (Tok.is(tok::semi)) { 10990b57cec5SDimitry Andric auto LengthOfTSTToken = [](DeclSpec::TST TKind) { 11000b57cec5SDimitry Andric assert(DeclSpec::isDeclRep(TKind)); 11010b57cec5SDimitry Andric switch(TKind) { 11020b57cec5SDimitry Andric case DeclSpec::TST_class: 11030b57cec5SDimitry Andric return 5; 11040b57cec5SDimitry Andric case DeclSpec::TST_struct: 11050b57cec5SDimitry Andric return 6; 11060b57cec5SDimitry Andric case DeclSpec::TST_union: 11070b57cec5SDimitry Andric return 5; 11080b57cec5SDimitry Andric case DeclSpec::TST_enum: 11090b57cec5SDimitry Andric return 4; 11100b57cec5SDimitry Andric case DeclSpec::TST_interface: 11110b57cec5SDimitry Andric return 9; 11120b57cec5SDimitry Andric default: 11130b57cec5SDimitry Andric llvm_unreachable("we only expect to get the length of the class/struct/union/enum"); 11140b57cec5SDimitry Andric } 11150b57cec5SDimitry Andric 11160b57cec5SDimitry Andric }; 11170b57cec5SDimitry Andric // Suggest correct location to fix '[[attrib]] struct' to 'struct [[attrib]]' 11180b57cec5SDimitry Andric SourceLocation CorrectLocationForAttributes = 11190b57cec5SDimitry Andric DeclSpec::isDeclRep(DS.getTypeSpecType()) 11200b57cec5SDimitry Andric ? DS.getTypeSpecTypeLoc().getLocWithOffset( 11210b57cec5SDimitry Andric LengthOfTSTToken(DS.getTypeSpecType())) 11220b57cec5SDimitry Andric : SourceLocation(); 112381ad6265SDimitry Andric ProhibitAttributes(Attrs, CorrectLocationForAttributes); 11240b57cec5SDimitry Andric ConsumeToken(); 11250b57cec5SDimitry Andric RecordDecl *AnonRecord = nullptr; 112681ad6265SDimitry Andric Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec( 112781ad6265SDimitry Andric getCurScope(), AS_none, DS, ParsedAttributesView::none(), AnonRecord); 11280b57cec5SDimitry Andric DS.complete(TheDecl); 11290b57cec5SDimitry Andric if (AnonRecord) { 11300b57cec5SDimitry Andric Decl* decls[] = {AnonRecord, TheDecl}; 11310b57cec5SDimitry Andric return Actions.BuildDeclaratorGroup(decls); 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric return Actions.ConvertDeclToDeclGroup(TheDecl); 11340b57cec5SDimitry Andric } 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric // ObjC2 allows prefix attributes on class interfaces and protocols. 11370b57cec5SDimitry Andric // FIXME: This still needs better diagnostics. We should only accept 11380b57cec5SDimitry Andric // attributes here, no types, etc. 11390b57cec5SDimitry Andric if (getLangOpts().ObjC && Tok.is(tok::at)) { 11400b57cec5SDimitry Andric SourceLocation AtLoc = ConsumeToken(); // the "@" 11410b57cec5SDimitry Andric if (!Tok.isObjCAtKeyword(tok::objc_interface) && 11420b57cec5SDimitry Andric !Tok.isObjCAtKeyword(tok::objc_protocol) && 11430b57cec5SDimitry Andric !Tok.isObjCAtKeyword(tok::objc_implementation)) { 11440b57cec5SDimitry Andric Diag(Tok, diag::err_objc_unexpected_attr); 11450b57cec5SDimitry Andric SkipUntil(tok::semi); 11460b57cec5SDimitry Andric return nullptr; 11470b57cec5SDimitry Andric } 11480b57cec5SDimitry Andric 11490b57cec5SDimitry Andric DS.abort(); 115081ad6265SDimitry Andric DS.takeAttributesFrom(Attrs); 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric const char *PrevSpec = nullptr; 11530b57cec5SDimitry Andric unsigned DiagID; 11540b57cec5SDimitry Andric if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID, 11550b57cec5SDimitry Andric Actions.getASTContext().getPrintingPolicy())) 11560b57cec5SDimitry Andric Diag(AtLoc, DiagID) << PrevSpec; 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric if (Tok.isObjCAtKeyword(tok::objc_protocol)) 11590b57cec5SDimitry Andric return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes()); 11600b57cec5SDimitry Andric 11610b57cec5SDimitry Andric if (Tok.isObjCAtKeyword(tok::objc_implementation)) 11620b57cec5SDimitry Andric return ParseObjCAtImplementationDeclaration(AtLoc, DS.getAttributes()); 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric return Actions.ConvertDeclToDeclGroup( 11650b57cec5SDimitry Andric ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes())); 11660b57cec5SDimitry Andric } 11670b57cec5SDimitry Andric 11680b57cec5SDimitry Andric // If the declspec consisted only of 'extern' and we have a string 11690b57cec5SDimitry Andric // literal following it, this must be a C++ linkage specifier like 11700b57cec5SDimitry Andric // 'extern "C"'. 11710b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && isTokenStringLiteral() && 11720b57cec5SDimitry Andric DS.getStorageClassSpec() == DeclSpec::SCS_extern && 11730b57cec5SDimitry Andric DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) { 117481ad6265SDimitry Andric ProhibitAttributes(Attrs); 1175e8d8bef9SDimitry Andric Decl *TheDecl = ParseLinkage(DS, DeclaratorContext::File); 11760b57cec5SDimitry Andric return Actions.ConvertDeclToDeclGroup(TheDecl); 11770b57cec5SDimitry Andric } 11780b57cec5SDimitry Andric 117981ad6265SDimitry Andric return ParseDeclGroup(DS, DeclaratorContext::File, Attrs); 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric 118281ad6265SDimitry Andric Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition( 118381ad6265SDimitry Andric ParsedAttributes &Attrs, ParsingDeclSpec *DS, AccessSpecifier AS) { 11840b57cec5SDimitry Andric if (DS) { 118581ad6265SDimitry Andric return ParseDeclOrFunctionDefInternal(Attrs, *DS, AS); 11860b57cec5SDimitry Andric } else { 11870b57cec5SDimitry Andric ParsingDeclSpec PDS(*this); 11880b57cec5SDimitry Andric // Must temporarily exit the objective-c container scope for 11890b57cec5SDimitry Andric // parsing c constructs and re-enter objc container scope 11900b57cec5SDimitry Andric // afterwards. 11910b57cec5SDimitry Andric ObjCDeclContextSwitch ObjCDC(*this); 11920b57cec5SDimitry Andric 119381ad6265SDimitry Andric return ParseDeclOrFunctionDefInternal(Attrs, PDS, AS); 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric } 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric /// ParseFunctionDefinition - We parsed and verified that the specified 11980b57cec5SDimitry Andric /// Declarator is well formed. If this is a K&R-style function, read the 11990b57cec5SDimitry Andric /// parameters declaration-list, then start the compound-statement. 12000b57cec5SDimitry Andric /// 12010b57cec5SDimitry Andric /// function-definition: [C99 6.9.1] 12020b57cec5SDimitry Andric /// decl-specs declarator declaration-list[opt] compound-statement 12030b57cec5SDimitry Andric /// [C90] function-definition: [C99 6.7.1] - implicit int result 12040b57cec5SDimitry Andric /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement 12050b57cec5SDimitry Andric /// [C++] function-definition: [C++ 8.4] 12060b57cec5SDimitry Andric /// decl-specifier-seq[opt] declarator ctor-initializer[opt] 12070b57cec5SDimitry Andric /// function-body 12080b57cec5SDimitry Andric /// [C++] function-definition: [C++ 8.4] 12090b57cec5SDimitry Andric /// decl-specifier-seq[opt] declarator function-try-block 12100b57cec5SDimitry Andric /// 12110b57cec5SDimitry Andric Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, 12120b57cec5SDimitry Andric const ParsedTemplateInfo &TemplateInfo, 12130b57cec5SDimitry Andric LateParsedAttrList *LateParsedAttrs) { 12140b57cec5SDimitry Andric // Poison SEH identifiers so they are flagged as illegal in function bodies. 12150b57cec5SDimitry Andric PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); 12160b57cec5SDimitry Andric const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); 121755e4f9d5SDimitry Andric TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); 12180b57cec5SDimitry Andric 121981ad6265SDimitry Andric // If this is C89 and the declspecs were completely missing, fudge in an 12200b57cec5SDimitry Andric // implicit int. We do this here because this is the only place where 12210b57cec5SDimitry Andric // declaration-specifiers are completely optional in the grammar. 122281ad6265SDimitry Andric if (getLangOpts().isImplicitIntRequired() && D.getDeclSpec().isEmpty()) { 122381ad6265SDimitry Andric Diag(D.getIdentifierLoc(), diag::warn_missing_type_specifier) 122481ad6265SDimitry Andric << D.getDeclSpec().getSourceRange(); 12250b57cec5SDimitry Andric const char *PrevSpec; 12260b57cec5SDimitry Andric unsigned DiagID; 12270b57cec5SDimitry Andric const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy(); 12280b57cec5SDimitry Andric D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int, 12290b57cec5SDimitry Andric D.getIdentifierLoc(), 12300b57cec5SDimitry Andric PrevSpec, DiagID, 12310b57cec5SDimitry Andric Policy); 12320b57cec5SDimitry Andric D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin()); 12330b57cec5SDimitry Andric } 12340b57cec5SDimitry Andric 12350b57cec5SDimitry Andric // If this declaration was formed with a K&R-style identifier list for the 12360b57cec5SDimitry Andric // arguments, parse declarations for all of the args next. 12370b57cec5SDimitry Andric // int foo(a,b) int a; float b; {} 12380b57cec5SDimitry Andric if (FTI.isKNRPrototype()) 12390b57cec5SDimitry Andric ParseKNRParamDeclarations(D); 12400b57cec5SDimitry Andric 12410b57cec5SDimitry Andric // We should have either an opening brace or, in a C++ constructor, 12420b57cec5SDimitry Andric // we may have a colon. 12430b57cec5SDimitry Andric if (Tok.isNot(tok::l_brace) && 12440b57cec5SDimitry Andric (!getLangOpts().CPlusPlus || 12450b57cec5SDimitry Andric (Tok.isNot(tok::colon) && Tok.isNot(tok::kw_try) && 12460b57cec5SDimitry Andric Tok.isNot(tok::equal)))) { 12470b57cec5SDimitry Andric Diag(Tok, diag::err_expected_fn_body); 12480b57cec5SDimitry Andric 12490b57cec5SDimitry Andric // Skip over garbage, until we get to '{'. Don't eat the '{'. 12500b57cec5SDimitry Andric SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch); 12510b57cec5SDimitry Andric 12520b57cec5SDimitry Andric // If we didn't find the '{', bail out. 12530b57cec5SDimitry Andric if (Tok.isNot(tok::l_brace)) 12540b57cec5SDimitry Andric return nullptr; 12550b57cec5SDimitry Andric } 12560b57cec5SDimitry Andric 12570b57cec5SDimitry Andric // Check to make sure that any normal attributes are allowed to be on 12580b57cec5SDimitry Andric // a definition. Late parsed attributes are checked at the end. 12590b57cec5SDimitry Andric if (Tok.isNot(tok::equal)) { 12600b57cec5SDimitry Andric for (const ParsedAttr &AL : D.getAttributes()) 1261fe6060f1SDimitry Andric if (AL.isKnownToGCC() && !AL.isStandardAttributeSyntax()) 1262a7dea167SDimitry Andric Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) << AL; 12630b57cec5SDimitry Andric } 12640b57cec5SDimitry Andric 12650b57cec5SDimitry Andric // In delayed template parsing mode, for function template we consume the 12660b57cec5SDimitry Andric // tokens and store them for late parsing at the end of the translation unit. 12670b57cec5SDimitry Andric if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) && 12680b57cec5SDimitry Andric TemplateInfo.Kind == ParsedTemplateInfo::Template && 12690b57cec5SDimitry Andric Actions.canDelayFunctionBody(D)) { 12700b57cec5SDimitry Andric MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams); 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andric ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | 12730b57cec5SDimitry Andric Scope::CompoundStmtScope); 12740b57cec5SDimitry Andric Scope *ParentScope = getCurScope()->getParent(); 12750b57cec5SDimitry Andric 1276e8d8bef9SDimitry Andric D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 12770b57cec5SDimitry Andric Decl *DP = Actions.HandleDeclarator(ParentScope, D, 12780b57cec5SDimitry Andric TemplateParameterLists); 12790b57cec5SDimitry Andric D.complete(DP); 12800b57cec5SDimitry Andric D.getMutableDeclSpec().abort(); 12810b57cec5SDimitry Andric 12820b57cec5SDimitry Andric if (SkipFunctionBodies && (!DP || Actions.canSkipFunctionBody(DP)) && 12830b57cec5SDimitry Andric trySkippingFunctionBody()) { 12840b57cec5SDimitry Andric BodyScope.Exit(); 12850b57cec5SDimitry Andric return Actions.ActOnSkippedFunctionBody(DP); 12860b57cec5SDimitry Andric } 12870b57cec5SDimitry Andric 12880b57cec5SDimitry Andric CachedTokens Toks; 12890b57cec5SDimitry Andric LexTemplateFunctionForLateParsing(Toks); 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric if (DP) { 12920b57cec5SDimitry Andric FunctionDecl *FnD = DP->getAsFunction(); 12930b57cec5SDimitry Andric Actions.CheckForFunctionRedefinition(FnD); 12940b57cec5SDimitry Andric Actions.MarkAsLateParsedTemplate(FnD, DP, Toks); 12950b57cec5SDimitry Andric } 12960b57cec5SDimitry Andric return DP; 12970b57cec5SDimitry Andric } 12980b57cec5SDimitry Andric else if (CurParsedObjCImpl && 12990b57cec5SDimitry Andric !TemplateInfo.TemplateParams && 13000b57cec5SDimitry Andric (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) || 13010b57cec5SDimitry Andric Tok.is(tok::colon)) && 13020b57cec5SDimitry Andric Actions.CurContext->isTranslationUnit()) { 13030b57cec5SDimitry Andric ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | 13040b57cec5SDimitry Andric Scope::CompoundStmtScope); 13050b57cec5SDimitry Andric Scope *ParentScope = getCurScope()->getParent(); 13060b57cec5SDimitry Andric 1307e8d8bef9SDimitry Andric D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition); 13080b57cec5SDimitry Andric Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D, 13090b57cec5SDimitry Andric MultiTemplateParamsArg()); 13100b57cec5SDimitry Andric D.complete(FuncDecl); 13110b57cec5SDimitry Andric D.getMutableDeclSpec().abort(); 13120b57cec5SDimitry Andric if (FuncDecl) { 13130b57cec5SDimitry Andric // Consume the tokens and store them for later parsing. 13140b57cec5SDimitry Andric StashAwayMethodOrFunctionBodyTokens(FuncDecl); 13150b57cec5SDimitry Andric CurParsedObjCImpl->HasCFunction = true; 13160b57cec5SDimitry Andric return FuncDecl; 13170b57cec5SDimitry Andric } 13180b57cec5SDimitry Andric // FIXME: Should we really fall through here? 13190b57cec5SDimitry Andric } 13200b57cec5SDimitry Andric 13210b57cec5SDimitry Andric // Enter a scope for the function body. 13220b57cec5SDimitry Andric ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | 13230b57cec5SDimitry Andric Scope::CompoundStmtScope); 13240b57cec5SDimitry Andric 132581ad6265SDimitry Andric // Parse function body eagerly if it is either '= delete;' or '= default;' as 132681ad6265SDimitry Andric // ActOnStartOfFunctionDef needs to know whether the function is deleted. 132781ad6265SDimitry Andric Sema::FnBodyKind BodyKind = Sema::FnBodyKind::Other; 132881ad6265SDimitry Andric SourceLocation KWLoc; 132981ad6265SDimitry Andric if (TryConsumeToken(tok::equal)) { 133081ad6265SDimitry Andric assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='"); 133181ad6265SDimitry Andric 133281ad6265SDimitry Andric if (TryConsumeToken(tok::kw_delete, KWLoc)) { 133381ad6265SDimitry Andric Diag(KWLoc, getLangOpts().CPlusPlus11 133481ad6265SDimitry Andric ? diag::warn_cxx98_compat_defaulted_deleted_function 133581ad6265SDimitry Andric : diag::ext_defaulted_deleted_function) 133681ad6265SDimitry Andric << 1 /* deleted */; 133781ad6265SDimitry Andric BodyKind = Sema::FnBodyKind::Delete; 133881ad6265SDimitry Andric } else if (TryConsumeToken(tok::kw_default, KWLoc)) { 133981ad6265SDimitry Andric Diag(KWLoc, getLangOpts().CPlusPlus11 134081ad6265SDimitry Andric ? diag::warn_cxx98_compat_defaulted_deleted_function 134181ad6265SDimitry Andric : diag::ext_defaulted_deleted_function) 134281ad6265SDimitry Andric << 0 /* defaulted */; 134381ad6265SDimitry Andric BodyKind = Sema::FnBodyKind::Default; 134481ad6265SDimitry Andric } else { 134581ad6265SDimitry Andric llvm_unreachable("function definition after = not 'delete' or 'default'"); 134681ad6265SDimitry Andric } 134781ad6265SDimitry Andric 134881ad6265SDimitry Andric if (Tok.is(tok::comma)) { 134981ad6265SDimitry Andric Diag(KWLoc, diag::err_default_delete_in_multiple_declaration) 135081ad6265SDimitry Andric << (BodyKind == Sema::FnBodyKind::Delete); 135181ad6265SDimitry Andric SkipUntil(tok::semi); 135281ad6265SDimitry Andric } else if (ExpectAndConsume(tok::semi, diag::err_expected_after, 135381ad6265SDimitry Andric BodyKind == Sema::FnBodyKind::Delete 135481ad6265SDimitry Andric ? "delete" 135581ad6265SDimitry Andric : "default")) { 135681ad6265SDimitry Andric SkipUntil(tok::semi); 135781ad6265SDimitry Andric } 135881ad6265SDimitry Andric } 135981ad6265SDimitry Andric 13600b57cec5SDimitry Andric // Tell the actions module that we have entered a function definition with the 13610b57cec5SDimitry Andric // specified Declarator for the function. 13620b57cec5SDimitry Andric Sema::SkipBodyInfo SkipBody; 13630b57cec5SDimitry Andric Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D, 13640b57cec5SDimitry Andric TemplateInfo.TemplateParams 13650b57cec5SDimitry Andric ? *TemplateInfo.TemplateParams 13660b57cec5SDimitry Andric : MultiTemplateParamsArg(), 136781ad6265SDimitry Andric &SkipBody, BodyKind); 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric if (SkipBody.ShouldSkip) { 137081ad6265SDimitry Andric // Do NOT enter SkipFunctionBody if we already consumed the tokens. 137181ad6265SDimitry Andric if (BodyKind == Sema::FnBodyKind::Other) 13720b57cec5SDimitry Andric SkipFunctionBody(); 137381ad6265SDimitry Andric 13740b57cec5SDimitry Andric return Res; 13750b57cec5SDimitry Andric } 13760b57cec5SDimitry Andric 13770b57cec5SDimitry Andric // Break out of the ParsingDeclarator context before we parse the body. 13780b57cec5SDimitry Andric D.complete(Res); 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric // Break out of the ParsingDeclSpec context, too. This const_cast is 13810b57cec5SDimitry Andric // safe because we're always the sole owner. 13820b57cec5SDimitry Andric D.getMutableDeclSpec().abort(); 13830b57cec5SDimitry Andric 138481ad6265SDimitry Andric if (BodyKind != Sema::FnBodyKind::Other) { 138581ad6265SDimitry Andric Actions.SetFunctionBodyKind(Res, KWLoc, BodyKind); 138681ad6265SDimitry Andric Stmt *GeneratedBody = Res ? Res->getBody() : nullptr; 138781ad6265SDimitry Andric Actions.ActOnFinishFunctionBody(Res, GeneratedBody, false); 138881ad6265SDimitry Andric return Res; 138981ad6265SDimitry Andric } 139081ad6265SDimitry Andric 139155e4f9d5SDimitry Andric // With abbreviated function templates - we need to explicitly add depth to 139255e4f9d5SDimitry Andric // account for the implicit template parameter list induced by the template. 139355e4f9d5SDimitry Andric if (auto *Template = dyn_cast_or_null<FunctionTemplateDecl>(Res)) 139455e4f9d5SDimitry Andric if (Template->isAbbreviated() && 139555e4f9d5SDimitry Andric Template->getTemplateParameters()->getParam(0)->isImplicit()) 139655e4f9d5SDimitry Andric // First template parameter is implicit - meaning no explicit template 139755e4f9d5SDimitry Andric // parameter list was specified. 139855e4f9d5SDimitry Andric CurTemplateDepthTracker.addDepth(1); 139955e4f9d5SDimitry Andric 14000b57cec5SDimitry Andric if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) && 14010b57cec5SDimitry Andric trySkippingFunctionBody()) { 14020b57cec5SDimitry Andric BodyScope.Exit(); 14030b57cec5SDimitry Andric Actions.ActOnSkippedFunctionBody(Res); 14040b57cec5SDimitry Andric return Actions.ActOnFinishFunctionBody(Res, nullptr, false); 14050b57cec5SDimitry Andric } 14060b57cec5SDimitry Andric 14070b57cec5SDimitry Andric if (Tok.is(tok::kw_try)) 14080b57cec5SDimitry Andric return ParseFunctionTryBlock(Res, BodyScope); 14090b57cec5SDimitry Andric 14100b57cec5SDimitry Andric // If we have a colon, then we're probably parsing a C++ 14110b57cec5SDimitry Andric // ctor-initializer. 14120b57cec5SDimitry Andric if (Tok.is(tok::colon)) { 14130b57cec5SDimitry Andric ParseConstructorInitializer(Res); 14140b57cec5SDimitry Andric 14150b57cec5SDimitry Andric // Recover from error. 14160b57cec5SDimitry Andric if (!Tok.is(tok::l_brace)) { 14170b57cec5SDimitry Andric BodyScope.Exit(); 14180b57cec5SDimitry Andric Actions.ActOnFinishFunctionBody(Res, nullptr); 14190b57cec5SDimitry Andric return Res; 14200b57cec5SDimitry Andric } 14210b57cec5SDimitry Andric } else 14220b57cec5SDimitry Andric Actions.ActOnDefaultCtorInitializers(Res); 14230b57cec5SDimitry Andric 14240b57cec5SDimitry Andric // Late attributes are parsed in the same scope as the function body. 14250b57cec5SDimitry Andric if (LateParsedAttrs) 14260b57cec5SDimitry Andric ParseLexedAttributeList(*LateParsedAttrs, Res, false, true); 14270b57cec5SDimitry Andric 14280b57cec5SDimitry Andric return ParseFunctionStatementBody(Res, BodyScope); 14290b57cec5SDimitry Andric } 14300b57cec5SDimitry Andric 14310b57cec5SDimitry Andric void Parser::SkipFunctionBody() { 14320b57cec5SDimitry Andric if (Tok.is(tok::equal)) { 14330b57cec5SDimitry Andric SkipUntil(tok::semi); 14340b57cec5SDimitry Andric return; 14350b57cec5SDimitry Andric } 14360b57cec5SDimitry Andric 14370b57cec5SDimitry Andric bool IsFunctionTryBlock = Tok.is(tok::kw_try); 14380b57cec5SDimitry Andric if (IsFunctionTryBlock) 14390b57cec5SDimitry Andric ConsumeToken(); 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andric CachedTokens Skipped; 14420b57cec5SDimitry Andric if (ConsumeAndStoreFunctionPrologue(Skipped)) 14430b57cec5SDimitry Andric SkipMalformedDecl(); 14440b57cec5SDimitry Andric else { 14450b57cec5SDimitry Andric SkipUntil(tok::r_brace); 14460b57cec5SDimitry Andric while (IsFunctionTryBlock && Tok.is(tok::kw_catch)) { 14470b57cec5SDimitry Andric SkipUntil(tok::l_brace); 14480b57cec5SDimitry Andric SkipUntil(tok::r_brace); 14490b57cec5SDimitry Andric } 14500b57cec5SDimitry Andric } 14510b57cec5SDimitry Andric } 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andric /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides 14540b57cec5SDimitry Andric /// types for a function with a K&R-style identifier list for arguments. 14550b57cec5SDimitry Andric void Parser::ParseKNRParamDeclarations(Declarator &D) { 14560b57cec5SDimitry Andric // We know that the top-level of this declarator is a function. 14570b57cec5SDimitry Andric DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); 14580b57cec5SDimitry Andric 14590b57cec5SDimitry Andric // Enter function-declaration scope, limiting any declarators to the 14600b57cec5SDimitry Andric // function prototype scope, including parameter declarators. 14610b57cec5SDimitry Andric ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | 14620b57cec5SDimitry Andric Scope::FunctionDeclarationScope | Scope::DeclScope); 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric // Read all the argument declarations. 14650b57cec5SDimitry Andric while (isDeclarationSpecifier()) { 14660b57cec5SDimitry Andric SourceLocation DSStart = Tok.getLocation(); 14670b57cec5SDimitry Andric 14680b57cec5SDimitry Andric // Parse the common declaration-specifiers piece. 14690b57cec5SDimitry Andric DeclSpec DS(AttrFactory); 14700b57cec5SDimitry Andric ParseDeclarationSpecifiers(DS); 14710b57cec5SDimitry Andric 14720b57cec5SDimitry Andric // C99 6.9.1p6: 'each declaration in the declaration list shall have at 14730b57cec5SDimitry Andric // least one declarator'. 14740b57cec5SDimitry Andric // NOTE: GCC just makes this an ext-warn. It's not clear what it does with 14750b57cec5SDimitry Andric // the declarations though. It's trivial to ignore them, really hard to do 14760b57cec5SDimitry Andric // anything else with them. 14770b57cec5SDimitry Andric if (TryConsumeToken(tok::semi)) { 14780b57cec5SDimitry Andric Diag(DSStart, diag::err_declaration_does_not_declare_param); 14790b57cec5SDimitry Andric continue; 14800b57cec5SDimitry Andric } 14810b57cec5SDimitry Andric 14820b57cec5SDimitry Andric // C99 6.9.1p6: Declarations shall contain no storage-class specifiers other 14830b57cec5SDimitry Andric // than register. 14840b57cec5SDimitry Andric if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified && 14850b57cec5SDimitry Andric DS.getStorageClassSpec() != DeclSpec::SCS_register) { 14860b57cec5SDimitry Andric Diag(DS.getStorageClassSpecLoc(), 14870b57cec5SDimitry Andric diag::err_invalid_storage_class_in_func_decl); 14880b57cec5SDimitry Andric DS.ClearStorageClassSpecs(); 14890b57cec5SDimitry Andric } 14900b57cec5SDimitry Andric if (DS.getThreadStorageClassSpec() != DeclSpec::TSCS_unspecified) { 14910b57cec5SDimitry Andric Diag(DS.getThreadStorageClassSpecLoc(), 14920b57cec5SDimitry Andric diag::err_invalid_storage_class_in_func_decl); 14930b57cec5SDimitry Andric DS.ClearStorageClassSpecs(); 14940b57cec5SDimitry Andric } 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andric // Parse the first declarator attached to this declspec. 149781ad6265SDimitry Andric Declarator ParmDeclarator(DS, ParsedAttributesView::none(), 149881ad6265SDimitry Andric DeclaratorContext::KNRTypeList); 14990b57cec5SDimitry Andric ParseDeclarator(ParmDeclarator); 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric // Handle the full declarator list. 150204eeddc0SDimitry Andric while (true) { 15030b57cec5SDimitry Andric // If attributes are present, parse them. 15040b57cec5SDimitry Andric MaybeParseGNUAttributes(ParmDeclarator); 15050b57cec5SDimitry Andric 15060b57cec5SDimitry Andric // Ask the actions module to compute the type for this declarator. 15070b57cec5SDimitry Andric Decl *Param = 15080b57cec5SDimitry Andric Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator); 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andric if (Param && 15110b57cec5SDimitry Andric // A missing identifier has already been diagnosed. 15120b57cec5SDimitry Andric ParmDeclarator.getIdentifier()) { 15130b57cec5SDimitry Andric 15140b57cec5SDimitry Andric // Scan the argument list looking for the correct param to apply this 15150b57cec5SDimitry Andric // type. 15160b57cec5SDimitry Andric for (unsigned i = 0; ; ++i) { 15170b57cec5SDimitry Andric // C99 6.9.1p6: those declarators shall declare only identifiers from 15180b57cec5SDimitry Andric // the identifier list. 15190b57cec5SDimitry Andric if (i == FTI.NumParams) { 15200b57cec5SDimitry Andric Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param) 15210b57cec5SDimitry Andric << ParmDeclarator.getIdentifier(); 15220b57cec5SDimitry Andric break; 15230b57cec5SDimitry Andric } 15240b57cec5SDimitry Andric 15250b57cec5SDimitry Andric if (FTI.Params[i].Ident == ParmDeclarator.getIdentifier()) { 15260b57cec5SDimitry Andric // Reject redefinitions of parameters. 15270b57cec5SDimitry Andric if (FTI.Params[i].Param) { 15280b57cec5SDimitry Andric Diag(ParmDeclarator.getIdentifierLoc(), 15290b57cec5SDimitry Andric diag::err_param_redefinition) 15300b57cec5SDimitry Andric << ParmDeclarator.getIdentifier(); 15310b57cec5SDimitry Andric } else { 15320b57cec5SDimitry Andric FTI.Params[i].Param = Param; 15330b57cec5SDimitry Andric } 15340b57cec5SDimitry Andric break; 15350b57cec5SDimitry Andric } 15360b57cec5SDimitry Andric } 15370b57cec5SDimitry Andric } 15380b57cec5SDimitry Andric 15390b57cec5SDimitry Andric // If we don't have a comma, it is either the end of the list (a ';') or 15400b57cec5SDimitry Andric // an error, bail out. 15410b57cec5SDimitry Andric if (Tok.isNot(tok::comma)) 15420b57cec5SDimitry Andric break; 15430b57cec5SDimitry Andric 15440b57cec5SDimitry Andric ParmDeclarator.clear(); 15450b57cec5SDimitry Andric 15460b57cec5SDimitry Andric // Consume the comma. 15470b57cec5SDimitry Andric ParmDeclarator.setCommaLoc(ConsumeToken()); 15480b57cec5SDimitry Andric 15490b57cec5SDimitry Andric // Parse the next declarator. 15500b57cec5SDimitry Andric ParseDeclarator(ParmDeclarator); 15510b57cec5SDimitry Andric } 15520b57cec5SDimitry Andric 15530b57cec5SDimitry Andric // Consume ';' and continue parsing. 15540b57cec5SDimitry Andric if (!ExpectAndConsumeSemi(diag::err_expected_semi_declaration)) 15550b57cec5SDimitry Andric continue; 15560b57cec5SDimitry Andric 15570b57cec5SDimitry Andric // Otherwise recover by skipping to next semi or mandatory function body. 15580b57cec5SDimitry Andric if (SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch)) 15590b57cec5SDimitry Andric break; 15600b57cec5SDimitry Andric TryConsumeToken(tok::semi); 15610b57cec5SDimitry Andric } 15620b57cec5SDimitry Andric 15630b57cec5SDimitry Andric // The actions module must verify that all arguments were declared. 15640b57cec5SDimitry Andric Actions.ActOnFinishKNRParamDeclarations(getCurScope(), D, Tok.getLocation()); 15650b57cec5SDimitry Andric } 15660b57cec5SDimitry Andric 15670b57cec5SDimitry Andric 15680b57cec5SDimitry Andric /// ParseAsmStringLiteral - This is just a normal string-literal, but is not 15690b57cec5SDimitry Andric /// allowed to be a wide string, and is not subject to character translation. 1570480093f4SDimitry Andric /// Unlike GCC, we also diagnose an empty string literal when parsing for an 1571480093f4SDimitry Andric /// asm label as opposed to an asm statement, because such a construct does not 1572480093f4SDimitry Andric /// behave well. 15730b57cec5SDimitry Andric /// 15740b57cec5SDimitry Andric /// [GNU] asm-string-literal: 15750b57cec5SDimitry Andric /// string-literal 15760b57cec5SDimitry Andric /// 1577480093f4SDimitry Andric ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) { 15780b57cec5SDimitry Andric if (!isTokenStringLiteral()) { 15790b57cec5SDimitry Andric Diag(Tok, diag::err_expected_string_literal) 15800b57cec5SDimitry Andric << /*Source='in...'*/0 << "'asm'"; 15810b57cec5SDimitry Andric return ExprError(); 15820b57cec5SDimitry Andric } 15830b57cec5SDimitry Andric 15840b57cec5SDimitry Andric ExprResult AsmString(ParseStringLiteralExpression()); 15850b57cec5SDimitry Andric if (!AsmString.isInvalid()) { 15860b57cec5SDimitry Andric const auto *SL = cast<StringLiteral>(AsmString.get()); 158781ad6265SDimitry Andric if (!SL->isOrdinary()) { 15880b57cec5SDimitry Andric Diag(Tok, diag::err_asm_operand_wide_string_literal) 15890b57cec5SDimitry Andric << SL->isWide() 15900b57cec5SDimitry Andric << SL->getSourceRange(); 15910b57cec5SDimitry Andric return ExprError(); 15920b57cec5SDimitry Andric } 1593480093f4SDimitry Andric if (ForAsmLabel && SL->getString().empty()) { 1594480093f4SDimitry Andric Diag(Tok, diag::err_asm_operand_wide_string_literal) 1595480093f4SDimitry Andric << 2 /* an empty */ << SL->getSourceRange(); 1596480093f4SDimitry Andric return ExprError(); 1597480093f4SDimitry Andric } 15980b57cec5SDimitry Andric } 15990b57cec5SDimitry Andric return AsmString; 16000b57cec5SDimitry Andric } 16010b57cec5SDimitry Andric 16020b57cec5SDimitry Andric /// ParseSimpleAsm 16030b57cec5SDimitry Andric /// 16040b57cec5SDimitry Andric /// [GNU] simple-asm-expr: 16050b57cec5SDimitry Andric /// 'asm' '(' asm-string-literal ')' 16060b57cec5SDimitry Andric /// 1607480093f4SDimitry Andric ExprResult Parser::ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc) { 16080b57cec5SDimitry Andric assert(Tok.is(tok::kw_asm) && "Not an asm!"); 16090b57cec5SDimitry Andric SourceLocation Loc = ConsumeToken(); 16100b57cec5SDimitry Andric 16115ffd83dbSDimitry Andric if (isGNUAsmQualifier(Tok)) { 16125ffd83dbSDimitry Andric // Remove from the end of 'asm' to the end of the asm qualifier. 16130b57cec5SDimitry Andric SourceRange RemovalRange(PP.getLocForEndOfToken(Loc), 16140b57cec5SDimitry Andric PP.getLocForEndOfToken(Tok.getLocation())); 16155ffd83dbSDimitry Andric Diag(Tok, diag::err_global_asm_qualifier_ignored) 16165ffd83dbSDimitry Andric << GNUAsmQualifiers::getQualifierName(getGNUAsmQualifier(Tok)) 16170b57cec5SDimitry Andric << FixItHint::CreateRemoval(RemovalRange); 16180b57cec5SDimitry Andric ConsumeToken(); 16190b57cec5SDimitry Andric } 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 16220b57cec5SDimitry Andric if (T.consumeOpen()) { 16230b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lparen_after) << "asm"; 16240b57cec5SDimitry Andric return ExprError(); 16250b57cec5SDimitry Andric } 16260b57cec5SDimitry Andric 1627480093f4SDimitry Andric ExprResult Result(ParseAsmStringLiteral(ForAsmLabel)); 16280b57cec5SDimitry Andric 16290b57cec5SDimitry Andric if (!Result.isInvalid()) { 16300b57cec5SDimitry Andric // Close the paren and get the location of the end bracket 16310b57cec5SDimitry Andric T.consumeClose(); 16320b57cec5SDimitry Andric if (EndLoc) 16330b57cec5SDimitry Andric *EndLoc = T.getCloseLocation(); 16340b57cec5SDimitry Andric } else if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) { 16350b57cec5SDimitry Andric if (EndLoc) 16360b57cec5SDimitry Andric *EndLoc = Tok.getLocation(); 16370b57cec5SDimitry Andric ConsumeParen(); 16380b57cec5SDimitry Andric } 16390b57cec5SDimitry Andric 16400b57cec5SDimitry Andric return Result; 16410b57cec5SDimitry Andric } 16420b57cec5SDimitry Andric 16430b57cec5SDimitry Andric /// Get the TemplateIdAnnotation from the token and put it in the 16440b57cec5SDimitry Andric /// cleanup pool so that it gets destroyed when parsing the current top level 16450b57cec5SDimitry Andric /// declaration is finished. 16460b57cec5SDimitry Andric TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) { 16470b57cec5SDimitry Andric assert(tok.is(tok::annot_template_id) && "Expected template-id token"); 16480b57cec5SDimitry Andric TemplateIdAnnotation * 16490b57cec5SDimitry Andric Id = static_cast<TemplateIdAnnotation *>(tok.getAnnotationValue()); 16500b57cec5SDimitry Andric return Id; 16510b57cec5SDimitry Andric } 16520b57cec5SDimitry Andric 16530b57cec5SDimitry Andric void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) { 16540b57cec5SDimitry Andric // Push the current token back into the token stream (or revert it if it is 16550b57cec5SDimitry Andric // cached) and use an annotation scope token for current token. 16560b57cec5SDimitry Andric if (PP.isBacktrackEnabled()) 16570b57cec5SDimitry Andric PP.RevertCachedTokens(1); 16580b57cec5SDimitry Andric else 16590b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject=*/true); 16600b57cec5SDimitry Andric Tok.setKind(tok::annot_cxxscope); 16610b57cec5SDimitry Andric Tok.setAnnotationValue(Actions.SaveNestedNameSpecifierAnnotation(SS)); 16620b57cec5SDimitry Andric Tok.setAnnotationRange(SS.getRange()); 16630b57cec5SDimitry Andric 16640b57cec5SDimitry Andric // In case the tokens were cached, have Preprocessor replace them 16650b57cec5SDimitry Andric // with the annotation token. We don't need to do this if we've 16660b57cec5SDimitry Andric // just reverted back to a prior state. 16670b57cec5SDimitry Andric if (IsNewAnnotation) 16680b57cec5SDimitry Andric PP.AnnotateCachedTokens(Tok); 16690b57cec5SDimitry Andric } 16700b57cec5SDimitry Andric 16710b57cec5SDimitry Andric /// Attempt to classify the name at the current token position. This may 16720b57cec5SDimitry Andric /// form a type, scope or primary expression annotation, or replace the token 16730b57cec5SDimitry Andric /// with a typo-corrected keyword. This is only appropriate when the current 16740b57cec5SDimitry Andric /// name must refer to an entity which has already been declared. 16750b57cec5SDimitry Andric /// 16760b57cec5SDimitry Andric /// \param CCC Indicates how to perform typo-correction for this name. If NULL, 16770b57cec5SDimitry Andric /// no typo correction will be performed. 16780b57cec5SDimitry Andric Parser::AnnotatedNameKind 1679a7dea167SDimitry Andric Parser::TryAnnotateName(CorrectionCandidateCallback *CCC) { 16800b57cec5SDimitry Andric assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope)); 16810b57cec5SDimitry Andric 16820b57cec5SDimitry Andric const bool EnteringContext = false; 16830b57cec5SDimitry Andric const bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope); 16840b57cec5SDimitry Andric 16850b57cec5SDimitry Andric CXXScopeSpec SS; 16860b57cec5SDimitry Andric if (getLangOpts().CPlusPlus && 16875ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 168804eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 16895ffd83dbSDimitry Andric EnteringContext)) 16900b57cec5SDimitry Andric return ANK_Error; 16910b57cec5SDimitry Andric 16920b57cec5SDimitry Andric if (Tok.isNot(tok::identifier) || SS.isInvalid()) { 16930b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation)) 16940b57cec5SDimitry Andric return ANK_Error; 16950b57cec5SDimitry Andric return ANK_Unresolved; 16960b57cec5SDimitry Andric } 16970b57cec5SDimitry Andric 16980b57cec5SDimitry Andric IdentifierInfo *Name = Tok.getIdentifierInfo(); 16990b57cec5SDimitry Andric SourceLocation NameLoc = Tok.getLocation(); 17000b57cec5SDimitry Andric 17010b57cec5SDimitry Andric // FIXME: Move the tentative declaration logic into ClassifyName so we can 17020b57cec5SDimitry Andric // typo-correct to tentatively-declared identifiers. 17030b57cec5SDimitry Andric if (isTentativelyDeclared(Name)) { 17040b57cec5SDimitry Andric // Identifier has been tentatively declared, and thus cannot be resolved as 17050b57cec5SDimitry Andric // an expression. Fall back to annotating it as a type. 17060b57cec5SDimitry Andric if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation)) 17070b57cec5SDimitry Andric return ANK_Error; 17080b57cec5SDimitry Andric return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl; 17090b57cec5SDimitry Andric } 17100b57cec5SDimitry Andric 17110b57cec5SDimitry Andric Token Next = NextToken(); 17120b57cec5SDimitry Andric 17130b57cec5SDimitry Andric // Look up and classify the identifier. We don't perform any typo-correction 17140b57cec5SDimitry Andric // after a scope specifier, because in general we can't recover from typos 17150b57cec5SDimitry Andric // there (eg, after correcting 'A::template B<X>::C' [sic], we would need to 17160b57cec5SDimitry Andric // jump back into scope specifier parsing). 1717a7dea167SDimitry Andric Sema::NameClassification Classification = Actions.ClassifyName( 1718a7dea167SDimitry Andric getCurScope(), SS, Name, NameLoc, Next, SS.isEmpty() ? CCC : nullptr); 17190b57cec5SDimitry Andric 17200b57cec5SDimitry Andric // If name lookup found nothing and we guessed that this was a template name, 17210b57cec5SDimitry Andric // double-check before committing to that interpretation. C++20 requires that 17220b57cec5SDimitry Andric // we interpret this as a template-id if it can be, but if it can't be, then 17230b57cec5SDimitry Andric // this is an error recovery case. 17240b57cec5SDimitry Andric if (Classification.getKind() == Sema::NC_UndeclaredTemplate && 17250b57cec5SDimitry Andric isTemplateArgumentList(1) == TPResult::False) { 17260b57cec5SDimitry Andric // It's not a template-id; re-classify without the '<' as a hint. 17270b57cec5SDimitry Andric Token FakeNext = Next; 17280b57cec5SDimitry Andric FakeNext.setKind(tok::unknown); 17290b57cec5SDimitry Andric Classification = 17300b57cec5SDimitry Andric Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, FakeNext, 1731a7dea167SDimitry Andric SS.isEmpty() ? CCC : nullptr); 17320b57cec5SDimitry Andric } 17330b57cec5SDimitry Andric 17340b57cec5SDimitry Andric switch (Classification.getKind()) { 17350b57cec5SDimitry Andric case Sema::NC_Error: 17360b57cec5SDimitry Andric return ANK_Error; 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric case Sema::NC_Keyword: 17390b57cec5SDimitry Andric // The identifier was typo-corrected to a keyword. 17400b57cec5SDimitry Andric Tok.setIdentifierInfo(Name); 17410b57cec5SDimitry Andric Tok.setKind(Name->getTokenID()); 17420b57cec5SDimitry Andric PP.TypoCorrectToken(Tok); 17430b57cec5SDimitry Andric if (SS.isNotEmpty()) 17440b57cec5SDimitry Andric AnnotateScopeToken(SS, !WasScopeAnnotation); 17450b57cec5SDimitry Andric // We've "annotated" this as a keyword. 17460b57cec5SDimitry Andric return ANK_Success; 17470b57cec5SDimitry Andric 17480b57cec5SDimitry Andric case Sema::NC_Unknown: 17490b57cec5SDimitry Andric // It's not something we know about. Leave it unannotated. 17500b57cec5SDimitry Andric break; 17510b57cec5SDimitry Andric 17520b57cec5SDimitry Andric case Sema::NC_Type: { 1753fe6060f1SDimitry Andric if (TryAltiVecVectorToken()) 1754fe6060f1SDimitry Andric // vector has been found as a type id when altivec is enabled but 1755fe6060f1SDimitry Andric // this is followed by a declaration specifier so this is really the 1756fe6060f1SDimitry Andric // altivec vector token. Leave it unannotated. 1757fe6060f1SDimitry Andric break; 17580b57cec5SDimitry Andric SourceLocation BeginLoc = NameLoc; 17590b57cec5SDimitry Andric if (SS.isNotEmpty()) 17600b57cec5SDimitry Andric BeginLoc = SS.getBeginLoc(); 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric /// An Objective-C object type followed by '<' is a specialization of 17630b57cec5SDimitry Andric /// a parameterized class type or a protocol-qualified type. 17640b57cec5SDimitry Andric ParsedType Ty = Classification.getType(); 17650b57cec5SDimitry Andric if (getLangOpts().ObjC && NextToken().is(tok::less) && 17660b57cec5SDimitry Andric (Ty.get()->isObjCObjectType() || 17670b57cec5SDimitry Andric Ty.get()->isObjCObjectPointerType())) { 17680b57cec5SDimitry Andric // Consume the name. 17690b57cec5SDimitry Andric SourceLocation IdentifierLoc = ConsumeToken(); 17700b57cec5SDimitry Andric SourceLocation NewEndLoc; 17710b57cec5SDimitry Andric TypeResult NewType 17720b57cec5SDimitry Andric = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty, 17730b57cec5SDimitry Andric /*consumeLastToken=*/false, 17740b57cec5SDimitry Andric NewEndLoc); 17750b57cec5SDimitry Andric if (NewType.isUsable()) 17760b57cec5SDimitry Andric Ty = NewType.get(); 17770b57cec5SDimitry Andric else if (Tok.is(tok::eof)) // Nothing to do here, bail out... 17780b57cec5SDimitry Andric return ANK_Error; 17790b57cec5SDimitry Andric } 17800b57cec5SDimitry Andric 17810b57cec5SDimitry Andric Tok.setKind(tok::annot_typename); 17820b57cec5SDimitry Andric setTypeAnnotation(Tok, Ty); 17830b57cec5SDimitry Andric Tok.setAnnotationEndLoc(Tok.getLocation()); 17840b57cec5SDimitry Andric Tok.setLocation(BeginLoc); 17850b57cec5SDimitry Andric PP.AnnotateCachedTokens(Tok); 17860b57cec5SDimitry Andric return ANK_Success; 17870b57cec5SDimitry Andric } 17880b57cec5SDimitry Andric 1789e8d8bef9SDimitry Andric case Sema::NC_OverloadSet: 1790e8d8bef9SDimitry Andric Tok.setKind(tok::annot_overload_set); 17910b57cec5SDimitry Andric setExprAnnotation(Tok, Classification.getExpression()); 17920b57cec5SDimitry Andric Tok.setAnnotationEndLoc(NameLoc); 17930b57cec5SDimitry Andric if (SS.isNotEmpty()) 17940b57cec5SDimitry Andric Tok.setLocation(SS.getBeginLoc()); 17950b57cec5SDimitry Andric PP.AnnotateCachedTokens(Tok); 17960b57cec5SDimitry Andric return ANK_Success; 17970b57cec5SDimitry Andric 1798a7dea167SDimitry Andric case Sema::NC_NonType: 1799fe6060f1SDimitry Andric if (TryAltiVecVectorToken()) 1800fe6060f1SDimitry Andric // vector has been found as a non-type id when altivec is enabled but 1801fe6060f1SDimitry Andric // this is followed by a declaration specifier so this is really the 1802fe6060f1SDimitry Andric // altivec vector token. Leave it unannotated. 1803fe6060f1SDimitry Andric break; 1804a7dea167SDimitry Andric Tok.setKind(tok::annot_non_type); 1805a7dea167SDimitry Andric setNonTypeAnnotation(Tok, Classification.getNonTypeDecl()); 1806a7dea167SDimitry Andric Tok.setLocation(NameLoc); 1807a7dea167SDimitry Andric Tok.setAnnotationEndLoc(NameLoc); 1808a7dea167SDimitry Andric PP.AnnotateCachedTokens(Tok); 1809a7dea167SDimitry Andric if (SS.isNotEmpty()) 1810a7dea167SDimitry Andric AnnotateScopeToken(SS, !WasScopeAnnotation); 1811a7dea167SDimitry Andric return ANK_Success; 1812a7dea167SDimitry Andric 1813a7dea167SDimitry Andric case Sema::NC_UndeclaredNonType: 1814a7dea167SDimitry Andric case Sema::NC_DependentNonType: 1815a7dea167SDimitry Andric Tok.setKind(Classification.getKind() == Sema::NC_UndeclaredNonType 1816a7dea167SDimitry Andric ? tok::annot_non_type_undeclared 1817a7dea167SDimitry Andric : tok::annot_non_type_dependent); 1818a7dea167SDimitry Andric setIdentifierAnnotation(Tok, Name); 1819a7dea167SDimitry Andric Tok.setLocation(NameLoc); 1820a7dea167SDimitry Andric Tok.setAnnotationEndLoc(NameLoc); 1821a7dea167SDimitry Andric PP.AnnotateCachedTokens(Tok); 1822a7dea167SDimitry Andric if (SS.isNotEmpty()) 1823a7dea167SDimitry Andric AnnotateScopeToken(SS, !WasScopeAnnotation); 1824a7dea167SDimitry Andric return ANK_Success; 1825a7dea167SDimitry Andric 18260b57cec5SDimitry Andric case Sema::NC_TypeTemplate: 18270b57cec5SDimitry Andric if (Next.isNot(tok::less)) { 18280b57cec5SDimitry Andric // This may be a type template being used as a template template argument. 18290b57cec5SDimitry Andric if (SS.isNotEmpty()) 18300b57cec5SDimitry Andric AnnotateScopeToken(SS, !WasScopeAnnotation); 18310b57cec5SDimitry Andric return ANK_TemplateName; 18320b57cec5SDimitry Andric } 18330b57cec5SDimitry Andric LLVM_FALLTHROUGH; 18340b57cec5SDimitry Andric case Sema::NC_VarTemplate: 18350b57cec5SDimitry Andric case Sema::NC_FunctionTemplate: 18360b57cec5SDimitry Andric case Sema::NC_UndeclaredTemplate: { 18370b57cec5SDimitry Andric // We have a type, variable or function template followed by '<'. 18380b57cec5SDimitry Andric ConsumeToken(); 18390b57cec5SDimitry Andric UnqualifiedId Id; 18400b57cec5SDimitry Andric Id.setIdentifier(Name, NameLoc); 18410b57cec5SDimitry Andric if (AnnotateTemplateIdToken( 18420b57cec5SDimitry Andric TemplateTy::make(Classification.getTemplateName()), 18430b57cec5SDimitry Andric Classification.getTemplateNameKind(), SS, SourceLocation(), Id)) 18440b57cec5SDimitry Andric return ANK_Error; 18450b57cec5SDimitry Andric return ANK_Success; 18460b57cec5SDimitry Andric } 184755e4f9d5SDimitry Andric case Sema::NC_Concept: { 184855e4f9d5SDimitry Andric UnqualifiedId Id; 184955e4f9d5SDimitry Andric Id.setIdentifier(Name, NameLoc); 185055e4f9d5SDimitry Andric if (Next.is(tok::less)) 185155e4f9d5SDimitry Andric // We have a concept name followed by '<'. Consume the identifier token so 185255e4f9d5SDimitry Andric // we reach the '<' and annotate it. 185355e4f9d5SDimitry Andric ConsumeToken(); 185455e4f9d5SDimitry Andric if (AnnotateTemplateIdToken( 185555e4f9d5SDimitry Andric TemplateTy::make(Classification.getTemplateName()), 185655e4f9d5SDimitry Andric Classification.getTemplateNameKind(), SS, SourceLocation(), Id, 185755e4f9d5SDimitry Andric /*AllowTypeAnnotation=*/false, /*TypeConstraint=*/true)) 185855e4f9d5SDimitry Andric return ANK_Error; 185955e4f9d5SDimitry Andric return ANK_Success; 186055e4f9d5SDimitry Andric } 18610b57cec5SDimitry Andric } 18620b57cec5SDimitry Andric 18630b57cec5SDimitry Andric // Unable to classify the name, but maybe we can annotate a scope specifier. 18640b57cec5SDimitry Andric if (SS.isNotEmpty()) 18650b57cec5SDimitry Andric AnnotateScopeToken(SS, !WasScopeAnnotation); 18660b57cec5SDimitry Andric return ANK_Unresolved; 18670b57cec5SDimitry Andric } 18680b57cec5SDimitry Andric 18690b57cec5SDimitry Andric bool Parser::TryKeywordIdentFallback(bool DisableKeyword) { 18700b57cec5SDimitry Andric assert(Tok.isNot(tok::identifier)); 18710b57cec5SDimitry Andric Diag(Tok, diag::ext_keyword_as_ident) 18720b57cec5SDimitry Andric << PP.getSpelling(Tok) 18730b57cec5SDimitry Andric << DisableKeyword; 18740b57cec5SDimitry Andric if (DisableKeyword) 18750b57cec5SDimitry Andric Tok.getIdentifierInfo()->revertTokenIDToIdentifier(); 18760b57cec5SDimitry Andric Tok.setKind(tok::identifier); 18770b57cec5SDimitry Andric return true; 18780b57cec5SDimitry Andric } 18790b57cec5SDimitry Andric 18800b57cec5SDimitry Andric /// TryAnnotateTypeOrScopeToken - If the current token position is on a 18810b57cec5SDimitry Andric /// typename (possibly qualified in C++) or a C++ scope specifier not followed 18820b57cec5SDimitry Andric /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens 18830b57cec5SDimitry Andric /// with a single annotation token representing the typename or C++ scope 18840b57cec5SDimitry Andric /// respectively. 18850b57cec5SDimitry Andric /// This simplifies handling of C++ scope specifiers and allows efficient 18860b57cec5SDimitry Andric /// backtracking without the need to re-parse and resolve nested-names and 18870b57cec5SDimitry Andric /// typenames. 18880b57cec5SDimitry Andric /// It will mainly be called when we expect to treat identifiers as typenames 18890b57cec5SDimitry Andric /// (if they are typenames). For example, in C we do not expect identifiers 18900b57cec5SDimitry Andric /// inside expressions to be treated as typenames so it will not be called 18910b57cec5SDimitry Andric /// for expressions in C. 18920b57cec5SDimitry Andric /// The benefit for C/ObjC is that a typename will be annotated and 18930b57cec5SDimitry Andric /// Actions.getTypeName will not be needed to be called again (e.g. getTypeName 18940b57cec5SDimitry Andric /// will not be called twice, once to check whether we have a declaration 18950b57cec5SDimitry Andric /// specifier, and another one to get the actual type inside 18960b57cec5SDimitry Andric /// ParseDeclarationSpecifiers). 18970b57cec5SDimitry Andric /// 18980b57cec5SDimitry Andric /// This returns true if an error occurred. 18990b57cec5SDimitry Andric /// 19000b57cec5SDimitry Andric /// Note that this routine emits an error if you call it with ::new or ::delete 19010b57cec5SDimitry Andric /// as the current tokens, so only call it in contexts where these are invalid. 19020b57cec5SDimitry Andric bool Parser::TryAnnotateTypeOrScopeToken() { 19030b57cec5SDimitry Andric assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || 19040b57cec5SDimitry Andric Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) || 19050b57cec5SDimitry Andric Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) || 19060b57cec5SDimitry Andric Tok.is(tok::kw___super)) && 19070b57cec5SDimitry Andric "Cannot be a type or scope token!"); 19080b57cec5SDimitry Andric 19090b57cec5SDimitry Andric if (Tok.is(tok::kw_typename)) { 19100b57cec5SDimitry Andric // MSVC lets you do stuff like: 19110b57cec5SDimitry Andric // typename typedef T_::D D; 19120b57cec5SDimitry Andric // 19130b57cec5SDimitry Andric // We will consume the typedef token here and put it back after we have 19140b57cec5SDimitry Andric // parsed the first identifier, transforming it into something more like: 19150b57cec5SDimitry Andric // typename T_::D typedef D; 19160b57cec5SDimitry Andric if (getLangOpts().MSVCCompat && NextToken().is(tok::kw_typedef)) { 19170b57cec5SDimitry Andric Token TypedefToken; 19180b57cec5SDimitry Andric PP.Lex(TypedefToken); 19190b57cec5SDimitry Andric bool Result = TryAnnotateTypeOrScopeToken(); 19200b57cec5SDimitry Andric PP.EnterToken(Tok, /*IsReinject=*/true); 19210b57cec5SDimitry Andric Tok = TypedefToken; 19220b57cec5SDimitry Andric if (!Result) 19230b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename); 19240b57cec5SDimitry Andric return Result; 19250b57cec5SDimitry Andric } 19260b57cec5SDimitry Andric 19270b57cec5SDimitry Andric // Parse a C++ typename-specifier, e.g., "typename T::type". 19280b57cec5SDimitry Andric // 19290b57cec5SDimitry Andric // typename-specifier: 19300b57cec5SDimitry Andric // 'typename' '::' [opt] nested-name-specifier identifier 19310b57cec5SDimitry Andric // 'typename' '::' [opt] nested-name-specifier template [opt] 19320b57cec5SDimitry Andric // simple-template-id 19330b57cec5SDimitry Andric SourceLocation TypenameLoc = ConsumeToken(); 19340b57cec5SDimitry Andric CXXScopeSpec SS; 19350b57cec5SDimitry Andric if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 193604eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 19370b57cec5SDimitry Andric /*EnteringContext=*/false, nullptr, 19380b57cec5SDimitry Andric /*IsTypename*/ true)) 19390b57cec5SDimitry Andric return true; 194055e4f9d5SDimitry Andric if (SS.isEmpty()) { 19410b57cec5SDimitry Andric if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) || 19420b57cec5SDimitry Andric Tok.is(tok::annot_decltype)) { 19430b57cec5SDimitry Andric // Attempt to recover by skipping the invalid 'typename' 19440b57cec5SDimitry Andric if (Tok.is(tok::annot_decltype) || 19450b57cec5SDimitry Andric (!TryAnnotateTypeOrScopeToken() && Tok.isAnnotation())) { 19460b57cec5SDimitry Andric unsigned DiagID = diag::err_expected_qualified_after_typename; 19470b57cec5SDimitry Andric // MS compatibility: MSVC permits using known types with typename. 19480b57cec5SDimitry Andric // e.g. "typedef typename T* pointer_type" 19490b57cec5SDimitry Andric if (getLangOpts().MicrosoftExt) 19500b57cec5SDimitry Andric DiagID = diag::warn_expected_qualified_after_typename; 19510b57cec5SDimitry Andric Diag(Tok.getLocation(), DiagID); 19520b57cec5SDimitry Andric return false; 19530b57cec5SDimitry Andric } 19540b57cec5SDimitry Andric } 19550b57cec5SDimitry Andric if (Tok.isEditorPlaceholder()) 19560b57cec5SDimitry Andric return true; 19570b57cec5SDimitry Andric 19580b57cec5SDimitry Andric Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename); 19590b57cec5SDimitry Andric return true; 19600b57cec5SDimitry Andric } 19610b57cec5SDimitry Andric 19620b57cec5SDimitry Andric TypeResult Ty; 19630b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 19640b57cec5SDimitry Andric // FIXME: check whether the next token is '<', first! 19650b57cec5SDimitry Andric Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, 19660b57cec5SDimitry Andric *Tok.getIdentifierInfo(), 19670b57cec5SDimitry Andric Tok.getLocation()); 19680b57cec5SDimitry Andric } else if (Tok.is(tok::annot_template_id)) { 19690b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 19705ffd83dbSDimitry Andric if (!TemplateId->mightBeType()) { 19710b57cec5SDimitry Andric Diag(Tok, diag::err_typename_refers_to_non_type_template) 19720b57cec5SDimitry Andric << Tok.getAnnotationRange(); 19730b57cec5SDimitry Andric return true; 19740b57cec5SDimitry Andric } 19750b57cec5SDimitry Andric 19760b57cec5SDimitry Andric ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), 19770b57cec5SDimitry Andric TemplateId->NumArgs); 19780b57cec5SDimitry Andric 19795ffd83dbSDimitry Andric Ty = TemplateId->isInvalid() 19805ffd83dbSDimitry Andric ? TypeError() 19815ffd83dbSDimitry Andric : Actions.ActOnTypenameType( 19825ffd83dbSDimitry Andric getCurScope(), TypenameLoc, SS, TemplateId->TemplateKWLoc, 19835ffd83dbSDimitry Andric TemplateId->Template, TemplateId->Name, 19845ffd83dbSDimitry Andric TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, 19855ffd83dbSDimitry Andric TemplateArgsPtr, TemplateId->RAngleLoc); 19860b57cec5SDimitry Andric } else { 19870b57cec5SDimitry Andric Diag(Tok, diag::err_expected_type_name_after_typename) 19880b57cec5SDimitry Andric << SS.getRange(); 19890b57cec5SDimitry Andric return true; 19900b57cec5SDimitry Andric } 19910b57cec5SDimitry Andric 19920b57cec5SDimitry Andric SourceLocation EndLoc = Tok.getLastLoc(); 19930b57cec5SDimitry Andric Tok.setKind(tok::annot_typename); 19945ffd83dbSDimitry Andric setTypeAnnotation(Tok, Ty); 19950b57cec5SDimitry Andric Tok.setAnnotationEndLoc(EndLoc); 19960b57cec5SDimitry Andric Tok.setLocation(TypenameLoc); 19970b57cec5SDimitry Andric PP.AnnotateCachedTokens(Tok); 19980b57cec5SDimitry Andric return false; 19990b57cec5SDimitry Andric } 20000b57cec5SDimitry Andric 20010b57cec5SDimitry Andric // Remembers whether the token was originally a scope annotation. 20020b57cec5SDimitry Andric bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope); 20030b57cec5SDimitry Andric 20040b57cec5SDimitry Andric CXXScopeSpec SS; 20050b57cec5SDimitry Andric if (getLangOpts().CPlusPlus) 20065ffd83dbSDimitry Andric if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 200704eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 20085ffd83dbSDimitry Andric /*EnteringContext*/ false)) 20090b57cec5SDimitry Andric return true; 20100b57cec5SDimitry Andric 20110b57cec5SDimitry Andric return TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation); 20120b57cec5SDimitry Andric } 20130b57cec5SDimitry Andric 20140b57cec5SDimitry Andric /// Try to annotate a type or scope token, having already parsed an 20150b57cec5SDimitry Andric /// optional scope specifier. \p IsNewScope should be \c true unless the scope 20160b57cec5SDimitry Andric /// specifier was extracted from an existing tok::annot_cxxscope annotation. 20170b57cec5SDimitry Andric bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS, 20180b57cec5SDimitry Andric bool IsNewScope) { 20190b57cec5SDimitry Andric if (Tok.is(tok::identifier)) { 20200b57cec5SDimitry Andric // Determine whether the identifier is a type name. 20210b57cec5SDimitry Andric if (ParsedType Ty = Actions.getTypeName( 20220b57cec5SDimitry Andric *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS, 20230b57cec5SDimitry Andric false, NextToken().is(tok::period), nullptr, 20240b57cec5SDimitry Andric /*IsCtorOrDtorName=*/false, 20250b57cec5SDimitry Andric /*NonTrivialTypeSourceInfo*/true, 20260b57cec5SDimitry Andric /*IsClassTemplateDeductionContext*/true)) { 20270b57cec5SDimitry Andric SourceLocation BeginLoc = Tok.getLocation(); 20280b57cec5SDimitry Andric if (SS.isNotEmpty()) // it was a C++ qualified type name. 20290b57cec5SDimitry Andric BeginLoc = SS.getBeginLoc(); 20300b57cec5SDimitry Andric 20310b57cec5SDimitry Andric /// An Objective-C object type followed by '<' is a specialization of 20320b57cec5SDimitry Andric /// a parameterized class type or a protocol-qualified type. 20330b57cec5SDimitry Andric if (getLangOpts().ObjC && NextToken().is(tok::less) && 20340b57cec5SDimitry Andric (Ty.get()->isObjCObjectType() || 20350b57cec5SDimitry Andric Ty.get()->isObjCObjectPointerType())) { 20360b57cec5SDimitry Andric // Consume the name. 20370b57cec5SDimitry Andric SourceLocation IdentifierLoc = ConsumeToken(); 20380b57cec5SDimitry Andric SourceLocation NewEndLoc; 20390b57cec5SDimitry Andric TypeResult NewType 20400b57cec5SDimitry Andric = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty, 20410b57cec5SDimitry Andric /*consumeLastToken=*/false, 20420b57cec5SDimitry Andric NewEndLoc); 20430b57cec5SDimitry Andric if (NewType.isUsable()) 20440b57cec5SDimitry Andric Ty = NewType.get(); 20450b57cec5SDimitry Andric else if (Tok.is(tok::eof)) // Nothing to do here, bail out... 20460b57cec5SDimitry Andric return false; 20470b57cec5SDimitry Andric } 20480b57cec5SDimitry Andric 20490b57cec5SDimitry Andric // This is a typename. Replace the current token in-place with an 20500b57cec5SDimitry Andric // annotation type token. 20510b57cec5SDimitry Andric Tok.setKind(tok::annot_typename); 20520b57cec5SDimitry Andric setTypeAnnotation(Tok, Ty); 20530b57cec5SDimitry Andric Tok.setAnnotationEndLoc(Tok.getLocation()); 20540b57cec5SDimitry Andric Tok.setLocation(BeginLoc); 20550b57cec5SDimitry Andric 20560b57cec5SDimitry Andric // In case the tokens were cached, have Preprocessor replace 20570b57cec5SDimitry Andric // them with the annotation token. 20580b57cec5SDimitry Andric PP.AnnotateCachedTokens(Tok); 20590b57cec5SDimitry Andric return false; 20600b57cec5SDimitry Andric } 20610b57cec5SDimitry Andric 20620b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 20630b57cec5SDimitry Andric // If we're in C, we can't have :: tokens at all (the lexer won't return 20640b57cec5SDimitry Andric // them). If the identifier is not a type, then it can't be scope either, 20650b57cec5SDimitry Andric // just early exit. 20660b57cec5SDimitry Andric return false; 20670b57cec5SDimitry Andric } 20680b57cec5SDimitry Andric 20690b57cec5SDimitry Andric // If this is a template-id, annotate with a template-id or type token. 20700b57cec5SDimitry Andric // FIXME: This appears to be dead code. We already have formed template-id 20710b57cec5SDimitry Andric // tokens when parsing the scope specifier; this can never form a new one. 20720b57cec5SDimitry Andric if (NextToken().is(tok::less)) { 20730b57cec5SDimitry Andric TemplateTy Template; 20740b57cec5SDimitry Andric UnqualifiedId TemplateName; 20750b57cec5SDimitry Andric TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); 20760b57cec5SDimitry Andric bool MemberOfUnknownSpecialization; 20770b57cec5SDimitry Andric if (TemplateNameKind TNK = Actions.isTemplateName( 20780b57cec5SDimitry Andric getCurScope(), SS, 20790b57cec5SDimitry Andric /*hasTemplateKeyword=*/false, TemplateName, 20800b57cec5SDimitry Andric /*ObjectType=*/nullptr, /*EnteringContext*/false, Template, 20810b57cec5SDimitry Andric MemberOfUnknownSpecialization)) { 20820b57cec5SDimitry Andric // Only annotate an undeclared template name as a template-id if the 20830b57cec5SDimitry Andric // following tokens have the form of a template argument list. 20840b57cec5SDimitry Andric if (TNK != TNK_Undeclared_template || 20850b57cec5SDimitry Andric isTemplateArgumentList(1) != TPResult::False) { 20860b57cec5SDimitry Andric // Consume the identifier. 20870b57cec5SDimitry Andric ConsumeToken(); 20880b57cec5SDimitry Andric if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), 20890b57cec5SDimitry Andric TemplateName)) { 20900b57cec5SDimitry Andric // If an unrecoverable error occurred, we need to return true here, 20910b57cec5SDimitry Andric // because the token stream is in a damaged state. We may not 20920b57cec5SDimitry Andric // return a valid identifier. 20930b57cec5SDimitry Andric return true; 20940b57cec5SDimitry Andric } 20950b57cec5SDimitry Andric } 20960b57cec5SDimitry Andric } 20970b57cec5SDimitry Andric } 20980b57cec5SDimitry Andric 20990b57cec5SDimitry Andric // The current token, which is either an identifier or a 21000b57cec5SDimitry Andric // template-id, is not part of the annotation. Fall through to 21010b57cec5SDimitry Andric // push that token back into the stream and complete the C++ scope 21020b57cec5SDimitry Andric // specifier annotation. 21030b57cec5SDimitry Andric } 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andric if (Tok.is(tok::annot_template_id)) { 21060b57cec5SDimitry Andric TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); 21070b57cec5SDimitry Andric if (TemplateId->Kind == TNK_Type_template) { 21080b57cec5SDimitry Andric // A template-id that refers to a type was parsed into a 21090b57cec5SDimitry Andric // template-id annotation in a context where we weren't allowed 21100b57cec5SDimitry Andric // to produce a type annotation token. Update the template-id 21110b57cec5SDimitry Andric // annotation token to a type annotation token now. 211255e4f9d5SDimitry Andric AnnotateTemplateIdTokenAsType(SS); 21130b57cec5SDimitry Andric return false; 21140b57cec5SDimitry Andric } 21150b57cec5SDimitry Andric } 21160b57cec5SDimitry Andric 21170b57cec5SDimitry Andric if (SS.isEmpty()) 21180b57cec5SDimitry Andric return false; 21190b57cec5SDimitry Andric 21200b57cec5SDimitry Andric // A C++ scope specifier that isn't followed by a typename. 21210b57cec5SDimitry Andric AnnotateScopeToken(SS, IsNewScope); 21220b57cec5SDimitry Andric return false; 21230b57cec5SDimitry Andric } 21240b57cec5SDimitry Andric 21250b57cec5SDimitry Andric /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only 21260b57cec5SDimitry Andric /// annotates C++ scope specifiers and template-ids. This returns 21270b57cec5SDimitry Andric /// true if there was an error that could not be recovered from. 21280b57cec5SDimitry Andric /// 21290b57cec5SDimitry Andric /// Note that this routine emits an error if you call it with ::new or ::delete 21300b57cec5SDimitry Andric /// as the current tokens, so only call it in contexts where these are invalid. 21310b57cec5SDimitry Andric bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { 21320b57cec5SDimitry Andric assert(getLangOpts().CPlusPlus && 21330b57cec5SDimitry Andric "Call sites of this function should be guarded by checking for C++"); 213455e4f9d5SDimitry Andric assert(MightBeCXXScopeToken() && "Cannot be a type or scope token!"); 21350b57cec5SDimitry Andric 21360b57cec5SDimitry Andric CXXScopeSpec SS; 21375ffd83dbSDimitry Andric if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, 213804eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 21395ffd83dbSDimitry Andric EnteringContext)) 21400b57cec5SDimitry Andric return true; 21410b57cec5SDimitry Andric if (SS.isEmpty()) 21420b57cec5SDimitry Andric return false; 21430b57cec5SDimitry Andric 21440b57cec5SDimitry Andric AnnotateScopeToken(SS, true); 21450b57cec5SDimitry Andric return false; 21460b57cec5SDimitry Andric } 21470b57cec5SDimitry Andric 21480b57cec5SDimitry Andric bool Parser::isTokenEqualOrEqualTypo() { 21490b57cec5SDimitry Andric tok::TokenKind Kind = Tok.getKind(); 21500b57cec5SDimitry Andric switch (Kind) { 21510b57cec5SDimitry Andric default: 21520b57cec5SDimitry Andric return false; 21530b57cec5SDimitry Andric case tok::ampequal: // &= 21540b57cec5SDimitry Andric case tok::starequal: // *= 21550b57cec5SDimitry Andric case tok::plusequal: // += 21560b57cec5SDimitry Andric case tok::minusequal: // -= 21570b57cec5SDimitry Andric case tok::exclaimequal: // != 21580b57cec5SDimitry Andric case tok::slashequal: // /= 21590b57cec5SDimitry Andric case tok::percentequal: // %= 21600b57cec5SDimitry Andric case tok::lessequal: // <= 21610b57cec5SDimitry Andric case tok::lesslessequal: // <<= 21620b57cec5SDimitry Andric case tok::greaterequal: // >= 21630b57cec5SDimitry Andric case tok::greatergreaterequal: // >>= 21640b57cec5SDimitry Andric case tok::caretequal: // ^= 21650b57cec5SDimitry Andric case tok::pipeequal: // |= 21660b57cec5SDimitry Andric case tok::equalequal: // == 21670b57cec5SDimitry Andric Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal) 21680b57cec5SDimitry Andric << Kind 21690b57cec5SDimitry Andric << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "="); 21700b57cec5SDimitry Andric LLVM_FALLTHROUGH; 21710b57cec5SDimitry Andric case tok::equal: 21720b57cec5SDimitry Andric return true; 21730b57cec5SDimitry Andric } 21740b57cec5SDimitry Andric } 21750b57cec5SDimitry Andric 21760b57cec5SDimitry Andric SourceLocation Parser::handleUnexpectedCodeCompletionToken() { 21770b57cec5SDimitry Andric assert(Tok.is(tok::code_completion)); 21780b57cec5SDimitry Andric PrevTokLocation = Tok.getLocation(); 21790b57cec5SDimitry Andric 21800b57cec5SDimitry Andric for (Scope *S = getCurScope(); S; S = S->getParent()) { 218181ad6265SDimitry Andric if (S->isFunctionScope()) { 2182fe6060f1SDimitry Andric cutOffParsing(); 21830b57cec5SDimitry Andric Actions.CodeCompleteOrdinaryName(getCurScope(), 21840b57cec5SDimitry Andric Sema::PCC_RecoveryInFunction); 21850b57cec5SDimitry Andric return PrevTokLocation; 21860b57cec5SDimitry Andric } 21870b57cec5SDimitry Andric 218881ad6265SDimitry Andric if (S->isClassScope()) { 21890b57cec5SDimitry Andric cutOffParsing(); 2190fe6060f1SDimitry Andric Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class); 21910b57cec5SDimitry Andric return PrevTokLocation; 21920b57cec5SDimitry Andric } 21930b57cec5SDimitry Andric } 21940b57cec5SDimitry Andric 21950b57cec5SDimitry Andric cutOffParsing(); 2196fe6060f1SDimitry Andric Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace); 21970b57cec5SDimitry Andric return PrevTokLocation; 21980b57cec5SDimitry Andric } 21990b57cec5SDimitry Andric 22000b57cec5SDimitry Andric // Code-completion pass-through functions 22010b57cec5SDimitry Andric 22020b57cec5SDimitry Andric void Parser::CodeCompleteDirective(bool InConditional) { 22030b57cec5SDimitry Andric Actions.CodeCompletePreprocessorDirective(InConditional); 22040b57cec5SDimitry Andric } 22050b57cec5SDimitry Andric 22060b57cec5SDimitry Andric void Parser::CodeCompleteInConditionalExclusion() { 22070b57cec5SDimitry Andric Actions.CodeCompleteInPreprocessorConditionalExclusion(getCurScope()); 22080b57cec5SDimitry Andric } 22090b57cec5SDimitry Andric 22100b57cec5SDimitry Andric void Parser::CodeCompleteMacroName(bool IsDefinition) { 22110b57cec5SDimitry Andric Actions.CodeCompletePreprocessorMacroName(IsDefinition); 22120b57cec5SDimitry Andric } 22130b57cec5SDimitry Andric 22140b57cec5SDimitry Andric void Parser::CodeCompletePreprocessorExpression() { 22150b57cec5SDimitry Andric Actions.CodeCompletePreprocessorExpression(); 22160b57cec5SDimitry Andric } 22170b57cec5SDimitry Andric 22180b57cec5SDimitry Andric void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro, 22190b57cec5SDimitry Andric MacroInfo *MacroInfo, 22200b57cec5SDimitry Andric unsigned ArgumentIndex) { 22210b57cec5SDimitry Andric Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo, 22220b57cec5SDimitry Andric ArgumentIndex); 22230b57cec5SDimitry Andric } 22240b57cec5SDimitry Andric 22250b57cec5SDimitry Andric void Parser::CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) { 22260b57cec5SDimitry Andric Actions.CodeCompleteIncludedFile(Dir, IsAngled); 22270b57cec5SDimitry Andric } 22280b57cec5SDimitry Andric 22290b57cec5SDimitry Andric void Parser::CodeCompleteNaturalLanguage() { 22300b57cec5SDimitry Andric Actions.CodeCompleteNaturalLanguage(); 22310b57cec5SDimitry Andric } 22320b57cec5SDimitry Andric 22330b57cec5SDimitry Andric bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) { 22340b57cec5SDimitry Andric assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) && 22350b57cec5SDimitry Andric "Expected '__if_exists' or '__if_not_exists'"); 22360b57cec5SDimitry Andric Result.IsIfExists = Tok.is(tok::kw___if_exists); 22370b57cec5SDimitry Andric Result.KeywordLoc = ConsumeToken(); 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andric BalancedDelimiterTracker T(*this, tok::l_paren); 22400b57cec5SDimitry Andric if (T.consumeOpen()) { 22410b57cec5SDimitry Andric Diag(Tok, diag::err_expected_lparen_after) 22420b57cec5SDimitry Andric << (Result.IsIfExists? "__if_exists" : "__if_not_exists"); 22430b57cec5SDimitry Andric return true; 22440b57cec5SDimitry Andric } 22450b57cec5SDimitry Andric 22460b57cec5SDimitry Andric // Parse nested-name-specifier. 22470b57cec5SDimitry Andric if (getLangOpts().CPlusPlus) 22485ffd83dbSDimitry Andric ParseOptionalCXXScopeSpecifier(Result.SS, /*ObjectType=*/nullptr, 224904eeddc0SDimitry Andric /*ObjectHasErrors=*/false, 22500b57cec5SDimitry Andric /*EnteringContext=*/false); 22510b57cec5SDimitry Andric 22520b57cec5SDimitry Andric // Check nested-name specifier. 22530b57cec5SDimitry Andric if (Result.SS.isInvalid()) { 22540b57cec5SDimitry Andric T.skipToEnd(); 22550b57cec5SDimitry Andric return true; 22560b57cec5SDimitry Andric } 22570b57cec5SDimitry Andric 22580b57cec5SDimitry Andric // Parse the unqualified-id. 22590b57cec5SDimitry Andric SourceLocation TemplateKWLoc; // FIXME: parsed, but unused. 22605ffd83dbSDimitry Andric if (ParseUnqualifiedId(Result.SS, /*ObjectType=*/nullptr, 22615ffd83dbSDimitry Andric /*ObjectHadErrors=*/false, /*EnteringContext*/ false, 22625ffd83dbSDimitry Andric /*AllowDestructorName*/ true, 22635ffd83dbSDimitry Andric /*AllowConstructorName*/ true, 22645ffd83dbSDimitry Andric /*AllowDeductionGuide*/ false, &TemplateKWLoc, 22655ffd83dbSDimitry Andric Result.Name)) { 22660b57cec5SDimitry Andric T.skipToEnd(); 22670b57cec5SDimitry Andric return true; 22680b57cec5SDimitry Andric } 22690b57cec5SDimitry Andric 22700b57cec5SDimitry Andric if (T.consumeClose()) 22710b57cec5SDimitry Andric return true; 22720b57cec5SDimitry Andric 22730b57cec5SDimitry Andric // Check if the symbol exists. 22740b57cec5SDimitry Andric switch (Actions.CheckMicrosoftIfExistsSymbol(getCurScope(), Result.KeywordLoc, 22750b57cec5SDimitry Andric Result.IsIfExists, Result.SS, 22760b57cec5SDimitry Andric Result.Name)) { 22770b57cec5SDimitry Andric case Sema::IER_Exists: 22780b57cec5SDimitry Andric Result.Behavior = Result.IsIfExists ? IEB_Parse : IEB_Skip; 22790b57cec5SDimitry Andric break; 22800b57cec5SDimitry Andric 22810b57cec5SDimitry Andric case Sema::IER_DoesNotExist: 22820b57cec5SDimitry Andric Result.Behavior = !Result.IsIfExists ? IEB_Parse : IEB_Skip; 22830b57cec5SDimitry Andric break; 22840b57cec5SDimitry Andric 22850b57cec5SDimitry Andric case Sema::IER_Dependent: 22860b57cec5SDimitry Andric Result.Behavior = IEB_Dependent; 22870b57cec5SDimitry Andric break; 22880b57cec5SDimitry Andric 22890b57cec5SDimitry Andric case Sema::IER_Error: 22900b57cec5SDimitry Andric return true; 22910b57cec5SDimitry Andric } 22920b57cec5SDimitry Andric 22930b57cec5SDimitry Andric return false; 22940b57cec5SDimitry Andric } 22950b57cec5SDimitry Andric 22960b57cec5SDimitry Andric void Parser::ParseMicrosoftIfExistsExternalDeclaration() { 22970b57cec5SDimitry Andric IfExistsCondition Result; 22980b57cec5SDimitry Andric if (ParseMicrosoftIfExistsCondition(Result)) 22990b57cec5SDimitry Andric return; 23000b57cec5SDimitry Andric 23010b57cec5SDimitry Andric BalancedDelimiterTracker Braces(*this, tok::l_brace); 23020b57cec5SDimitry Andric if (Braces.consumeOpen()) { 23030b57cec5SDimitry Andric Diag(Tok, diag::err_expected) << tok::l_brace; 23040b57cec5SDimitry Andric return; 23050b57cec5SDimitry Andric } 23060b57cec5SDimitry Andric 23070b57cec5SDimitry Andric switch (Result.Behavior) { 23080b57cec5SDimitry Andric case IEB_Parse: 23090b57cec5SDimitry Andric // Parse declarations below. 23100b57cec5SDimitry Andric break; 23110b57cec5SDimitry Andric 23120b57cec5SDimitry Andric case IEB_Dependent: 23130b57cec5SDimitry Andric llvm_unreachable("Cannot have a dependent external declaration"); 23140b57cec5SDimitry Andric 23150b57cec5SDimitry Andric case IEB_Skip: 23160b57cec5SDimitry Andric Braces.skipToEnd(); 23170b57cec5SDimitry Andric return; 23180b57cec5SDimitry Andric } 23190b57cec5SDimitry Andric 23200b57cec5SDimitry Andric // Parse the declarations. 23210b57cec5SDimitry Andric // FIXME: Support module import within __if_exists? 23220b57cec5SDimitry Andric while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { 232381ad6265SDimitry Andric ParsedAttributes Attrs(AttrFactory); 232481ad6265SDimitry Andric MaybeParseCXX11Attributes(Attrs); 232581ad6265SDimitry Andric DeclGroupPtrTy Result = ParseExternalDeclaration(Attrs); 23260b57cec5SDimitry Andric if (Result && !getCurScope()->getParent()) 23270b57cec5SDimitry Andric Actions.getASTConsumer().HandleTopLevelDecl(Result.get()); 23280b57cec5SDimitry Andric } 23290b57cec5SDimitry Andric Braces.consumeClose(); 23300b57cec5SDimitry Andric } 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andric /// Parse a declaration beginning with the 'module' keyword or C++20 23330b57cec5SDimitry Andric /// context-sensitive keyword (optionally preceded by 'export'). 23340b57cec5SDimitry Andric /// 23350b57cec5SDimitry Andric /// module-declaration: [Modules TS + P0629R0] 23360b57cec5SDimitry Andric /// 'export'[opt] 'module' module-name attribute-specifier-seq[opt] ';' 23370b57cec5SDimitry Andric /// 23380b57cec5SDimitry Andric /// global-module-fragment: [C++2a] 23390b57cec5SDimitry Andric /// 'module' ';' top-level-declaration-seq[opt] 23400b57cec5SDimitry Andric /// module-declaration: [C++2a] 23410b57cec5SDimitry Andric /// 'export'[opt] 'module' module-name module-partition[opt] 23420b57cec5SDimitry Andric /// attribute-specifier-seq[opt] ';' 23430b57cec5SDimitry Andric /// private-module-fragment: [C++2a] 23440b57cec5SDimitry Andric /// 'module' ':' 'private' ';' top-level-declaration-seq[opt] 234581ad6265SDimitry Andric Parser::DeclGroupPtrTy 234681ad6265SDimitry Andric Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) { 23470b57cec5SDimitry Andric SourceLocation StartLoc = Tok.getLocation(); 23480b57cec5SDimitry Andric 23490b57cec5SDimitry Andric Sema::ModuleDeclKind MDK = TryConsumeToken(tok::kw_export) 23500b57cec5SDimitry Andric ? Sema::ModuleDeclKind::Interface 23510b57cec5SDimitry Andric : Sema::ModuleDeclKind::Implementation; 23520b57cec5SDimitry Andric 23530b57cec5SDimitry Andric assert( 23540b57cec5SDimitry Andric (Tok.is(tok::kw_module) || 23550b57cec5SDimitry Andric (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_module)) && 23560b57cec5SDimitry Andric "not a module declaration"); 23570b57cec5SDimitry Andric SourceLocation ModuleLoc = ConsumeToken(); 23580b57cec5SDimitry Andric 23590b57cec5SDimitry Andric // Attributes appear after the module name, not before. 23600b57cec5SDimitry Andric // FIXME: Suggest moving the attributes later with a fixit. 23610b57cec5SDimitry Andric DiagnoseAndSkipCXX11Attributes(); 23620b57cec5SDimitry Andric 23630b57cec5SDimitry Andric // Parse a global-module-fragment, if present. 23640b57cec5SDimitry Andric if (getLangOpts().CPlusPlusModules && Tok.is(tok::semi)) { 23650b57cec5SDimitry Andric SourceLocation SemiLoc = ConsumeToken(); 236681ad6265SDimitry Andric if (ImportState != Sema::ModuleImportState::FirstDecl) { 23670b57cec5SDimitry Andric Diag(StartLoc, diag::err_global_module_introducer_not_at_start) 23680b57cec5SDimitry Andric << SourceRange(StartLoc, SemiLoc); 23690b57cec5SDimitry Andric return nullptr; 23700b57cec5SDimitry Andric } 23710b57cec5SDimitry Andric if (MDK == Sema::ModuleDeclKind::Interface) { 23720b57cec5SDimitry Andric Diag(StartLoc, diag::err_module_fragment_exported) 23730b57cec5SDimitry Andric << /*global*/0 << FixItHint::CreateRemoval(StartLoc); 23740b57cec5SDimitry Andric } 237581ad6265SDimitry Andric ImportState = Sema::ModuleImportState::GlobalFragment; 23760b57cec5SDimitry Andric return Actions.ActOnGlobalModuleFragmentDecl(ModuleLoc); 23770b57cec5SDimitry Andric } 23780b57cec5SDimitry Andric 23790b57cec5SDimitry Andric // Parse a private-module-fragment, if present. 23800b57cec5SDimitry Andric if (getLangOpts().CPlusPlusModules && Tok.is(tok::colon) && 23810b57cec5SDimitry Andric NextToken().is(tok::kw_private)) { 23820b57cec5SDimitry Andric if (MDK == Sema::ModuleDeclKind::Interface) { 23830b57cec5SDimitry Andric Diag(StartLoc, diag::err_module_fragment_exported) 23840b57cec5SDimitry Andric << /*private*/1 << FixItHint::CreateRemoval(StartLoc); 23850b57cec5SDimitry Andric } 23860b57cec5SDimitry Andric ConsumeToken(); 23870b57cec5SDimitry Andric SourceLocation PrivateLoc = ConsumeToken(); 23880b57cec5SDimitry Andric DiagnoseAndSkipCXX11Attributes(); 23890b57cec5SDimitry Andric ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi); 239081ad6265SDimitry Andric ImportState = Sema::ModuleImportState::PrivateFragment; 23910b57cec5SDimitry Andric return Actions.ActOnPrivateModuleFragmentDecl(ModuleLoc, PrivateLoc); 23920b57cec5SDimitry Andric } 23930b57cec5SDimitry Andric 23940b57cec5SDimitry Andric SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 23950b57cec5SDimitry Andric if (ParseModuleName(ModuleLoc, Path, /*IsImport*/ false)) 23960b57cec5SDimitry Andric return nullptr; 23970b57cec5SDimitry Andric 23980b57cec5SDimitry Andric // Parse the optional module-partition. 239981ad6265SDimitry Andric SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Partition; 24000b57cec5SDimitry Andric if (Tok.is(tok::colon)) { 24010b57cec5SDimitry Andric SourceLocation ColonLoc = ConsumeToken(); 240281ad6265SDimitry Andric if (!getLangOpts().CPlusPlusModules) 24030b57cec5SDimitry Andric Diag(ColonLoc, diag::err_unsupported_module_partition) 24040b57cec5SDimitry Andric << SourceRange(ColonLoc, Partition.back().second); 240581ad6265SDimitry Andric // Recover by ignoring the partition name. 240681ad6265SDimitry Andric else if (ParseModuleName(ModuleLoc, Partition, /*IsImport*/ false)) 240781ad6265SDimitry Andric return nullptr; 24080b57cec5SDimitry Andric } 24090b57cec5SDimitry Andric 24100b57cec5SDimitry Andric // We don't support any module attributes yet; just parse them and diagnose. 241181ad6265SDimitry Andric ParsedAttributes Attrs(AttrFactory); 24120b57cec5SDimitry Andric MaybeParseCXX11Attributes(Attrs); 241381ad6265SDimitry Andric ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr, 241481ad6265SDimitry Andric /*DiagnoseEmptyAttrs=*/false, 241581ad6265SDimitry Andric /*WarnOnUnknownAttrs=*/true); 24160b57cec5SDimitry Andric 24170b57cec5SDimitry Andric ExpectAndConsumeSemi(diag::err_module_expected_semi); 24180b57cec5SDimitry Andric 241981ad6265SDimitry Andric return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, Partition, 242081ad6265SDimitry Andric ImportState); 24210b57cec5SDimitry Andric } 24220b57cec5SDimitry Andric 24230b57cec5SDimitry Andric /// Parse a module import declaration. This is essentially the same for 242481ad6265SDimitry Andric /// Objective-C and C++20 except for the leading '@' (in ObjC) and the 242581ad6265SDimitry Andric /// trailing optional attributes (in C++). 24260b57cec5SDimitry Andric /// 24270b57cec5SDimitry Andric /// [ObjC] @import declaration: 24280b57cec5SDimitry Andric /// '@' 'import' module-name ';' 24290b57cec5SDimitry Andric /// [ModTS] module-import-declaration: 24300b57cec5SDimitry Andric /// 'import' module-name attribute-specifier-seq[opt] ';' 243181ad6265SDimitry Andric /// [C++20] module-import-declaration: 24320b57cec5SDimitry Andric /// 'export'[opt] 'import' module-name 24330b57cec5SDimitry Andric /// attribute-specifier-seq[opt] ';' 24340b57cec5SDimitry Andric /// 'export'[opt] 'import' module-partition 24350b57cec5SDimitry Andric /// attribute-specifier-seq[opt] ';' 24360b57cec5SDimitry Andric /// 'export'[opt] 'import' header-name 24370b57cec5SDimitry Andric /// attribute-specifier-seq[opt] ';' 243881ad6265SDimitry Andric Decl *Parser::ParseModuleImport(SourceLocation AtLoc, 243981ad6265SDimitry Andric Sema::ModuleImportState &ImportState) { 24400b57cec5SDimitry Andric SourceLocation StartLoc = AtLoc.isInvalid() ? Tok.getLocation() : AtLoc; 24410b57cec5SDimitry Andric 24420b57cec5SDimitry Andric SourceLocation ExportLoc; 24430b57cec5SDimitry Andric TryConsumeToken(tok::kw_export, ExportLoc); 24440b57cec5SDimitry Andric 24450b57cec5SDimitry Andric assert((AtLoc.isInvalid() ? Tok.isOneOf(tok::kw_import, tok::identifier) 24460b57cec5SDimitry Andric : Tok.isObjCAtKeyword(tok::objc_import)) && 24470b57cec5SDimitry Andric "Improper start to module import"); 24480b57cec5SDimitry Andric bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import); 24490b57cec5SDimitry Andric SourceLocation ImportLoc = ConsumeToken(); 24500b57cec5SDimitry Andric 245181ad6265SDimitry Andric // For C++20 modules, we can have "name" or ":Partition name" as valid input. 24520b57cec5SDimitry Andric SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 245381ad6265SDimitry Andric bool IsPartition = false; 24540b57cec5SDimitry Andric Module *HeaderUnit = nullptr; 24550b57cec5SDimitry Andric if (Tok.is(tok::header_name)) { 24560b57cec5SDimitry Andric // This is a header import that the preprocessor decided we should skip 24570b57cec5SDimitry Andric // because it was malformed in some way. Parse and ignore it; it's already 24580b57cec5SDimitry Andric // been diagnosed. 24590b57cec5SDimitry Andric ConsumeToken(); 24600b57cec5SDimitry Andric } else if (Tok.is(tok::annot_header_unit)) { 24610b57cec5SDimitry Andric // This is a header import that the preprocessor mapped to a module import. 24620b57cec5SDimitry Andric HeaderUnit = reinterpret_cast<Module *>(Tok.getAnnotationValue()); 24630b57cec5SDimitry Andric ConsumeAnnotationToken(); 246481ad6265SDimitry Andric } else if (Tok.is(tok::colon)) { 24650b57cec5SDimitry Andric SourceLocation ColonLoc = ConsumeToken(); 246681ad6265SDimitry Andric if (!getLangOpts().CPlusPlusModules) 24670b57cec5SDimitry Andric Diag(ColonLoc, diag::err_unsupported_module_partition) 24680b57cec5SDimitry Andric << SourceRange(ColonLoc, Path.back().second); 246981ad6265SDimitry Andric // Recover by leaving partition empty. 247081ad6265SDimitry Andric else if (ParseModuleName(ColonLoc, Path, /*IsImport*/ true)) 24710b57cec5SDimitry Andric return nullptr; 247281ad6265SDimitry Andric else 247381ad6265SDimitry Andric IsPartition = true; 24740b57cec5SDimitry Andric } else { 24750b57cec5SDimitry Andric if (ParseModuleName(ImportLoc, Path, /*IsImport*/ true)) 24760b57cec5SDimitry Andric return nullptr; 24770b57cec5SDimitry Andric } 24780b57cec5SDimitry Andric 247981ad6265SDimitry Andric ParsedAttributes Attrs(AttrFactory); 24800b57cec5SDimitry Andric MaybeParseCXX11Attributes(Attrs); 24810b57cec5SDimitry Andric // We don't support any module import attributes yet. 248281ad6265SDimitry Andric ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr, 248381ad6265SDimitry Andric /*DiagnoseEmptyAttrs=*/false, 248481ad6265SDimitry Andric /*WarnOnUnknownAttrs=*/true); 24850b57cec5SDimitry Andric 24860b57cec5SDimitry Andric if (PP.hadModuleLoaderFatalFailure()) { 24870b57cec5SDimitry Andric // With a fatal failure in the module loader, we abort parsing. 24880b57cec5SDimitry Andric cutOffParsing(); 24890b57cec5SDimitry Andric return nullptr; 24900b57cec5SDimitry Andric } 24910b57cec5SDimitry Andric 249281ad6265SDimitry Andric // Diagnose mis-imports. 249381ad6265SDimitry Andric bool SeenError = true; 249481ad6265SDimitry Andric switch (ImportState) { 249581ad6265SDimitry Andric case Sema::ModuleImportState::ImportAllowed: 249681ad6265SDimitry Andric SeenError = false; 249781ad6265SDimitry Andric break; 249881ad6265SDimitry Andric case Sema::ModuleImportState::FirstDecl: 249981ad6265SDimitry Andric case Sema::ModuleImportState::NotACXX20Module: 250081ad6265SDimitry Andric // We can only import a partition within a module purview. 250181ad6265SDimitry Andric if (IsPartition) 250281ad6265SDimitry Andric Diag(ImportLoc, diag::err_partition_import_outside_module); 250381ad6265SDimitry Andric else 250481ad6265SDimitry Andric SeenError = false; 250581ad6265SDimitry Andric break; 250681ad6265SDimitry Andric case Sema::ModuleImportState::GlobalFragment: 250781ad6265SDimitry Andric // We can only have pre-processor directives in the global module 250881ad6265SDimitry Andric // fragment. We cannot import a named modules here, however we have a 250981ad6265SDimitry Andric // header unit import. 251081ad6265SDimitry Andric if (!HeaderUnit || HeaderUnit->Kind != Module::ModuleKind::ModuleHeaderUnit) 251181ad6265SDimitry Andric Diag(ImportLoc, diag::err_import_in_wrong_fragment) << IsPartition << 0; 251281ad6265SDimitry Andric else 251381ad6265SDimitry Andric SeenError = false; 251481ad6265SDimitry Andric break; 251581ad6265SDimitry Andric case Sema::ModuleImportState::ImportFinished: 251681ad6265SDimitry Andric if (getLangOpts().CPlusPlusModules) 251781ad6265SDimitry Andric Diag(ImportLoc, diag::err_import_not_allowed_here); 251881ad6265SDimitry Andric else 251981ad6265SDimitry Andric SeenError = false; 252081ad6265SDimitry Andric break; 252181ad6265SDimitry Andric case Sema::ModuleImportState::PrivateFragment: 252281ad6265SDimitry Andric Diag(ImportLoc, diag::err_import_in_wrong_fragment) << IsPartition << 1; 252381ad6265SDimitry Andric break; 252481ad6265SDimitry Andric } 252581ad6265SDimitry Andric if (SeenError) { 252681ad6265SDimitry Andric ExpectAndConsumeSemi(diag::err_module_expected_semi); 252781ad6265SDimitry Andric return nullptr; 252881ad6265SDimitry Andric } 252981ad6265SDimitry Andric 25300b57cec5SDimitry Andric DeclResult Import; 25310b57cec5SDimitry Andric if (HeaderUnit) 25320b57cec5SDimitry Andric Import = 25330b57cec5SDimitry Andric Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, HeaderUnit); 25340b57cec5SDimitry Andric else if (!Path.empty()) 253581ad6265SDimitry Andric Import = Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Path, 253681ad6265SDimitry Andric IsPartition); 25370b57cec5SDimitry Andric ExpectAndConsumeSemi(diag::err_module_expected_semi); 25380b57cec5SDimitry Andric if (Import.isInvalid()) 25390b57cec5SDimitry Andric return nullptr; 25400b57cec5SDimitry Andric 25410b57cec5SDimitry Andric // Using '@import' in framework headers requires modules to be enabled so that 25420b57cec5SDimitry Andric // the header is parseable. Emit a warning to make the user aware. 25430b57cec5SDimitry Andric if (IsObjCAtImport && AtLoc.isValid()) { 25440b57cec5SDimitry Andric auto &SrcMgr = PP.getSourceManager(); 254581ad6265SDimitry Andric auto FE = SrcMgr.getFileEntryRefForID(SrcMgr.getFileID(AtLoc)); 254681ad6265SDimitry Andric if (FE && llvm::sys::path::parent_path(FE->getDir().getName()) 25470b57cec5SDimitry Andric .endswith(".framework")) 25480b57cec5SDimitry Andric Diags.Report(AtLoc, diag::warn_atimport_in_framework_header); 25490b57cec5SDimitry Andric } 25500b57cec5SDimitry Andric 25510b57cec5SDimitry Andric return Import.get(); 25520b57cec5SDimitry Andric } 25530b57cec5SDimitry Andric 25540b57cec5SDimitry Andric /// Parse a C++ Modules TS / Objective-C module name (both forms use the same 25550b57cec5SDimitry Andric /// grammar). 25560b57cec5SDimitry Andric /// 25570b57cec5SDimitry Andric /// module-name: 25580b57cec5SDimitry Andric /// module-name-qualifier[opt] identifier 25590b57cec5SDimitry Andric /// module-name-qualifier: 25600b57cec5SDimitry Andric /// module-name-qualifier[opt] identifier '.' 25610b57cec5SDimitry Andric bool Parser::ParseModuleName( 25620b57cec5SDimitry Andric SourceLocation UseLoc, 25630b57cec5SDimitry Andric SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path, 25640b57cec5SDimitry Andric bool IsImport) { 25650b57cec5SDimitry Andric // Parse the module path. 25660b57cec5SDimitry Andric while (true) { 25670b57cec5SDimitry Andric if (!Tok.is(tok::identifier)) { 25680b57cec5SDimitry Andric if (Tok.is(tok::code_completion)) { 25690b57cec5SDimitry Andric cutOffParsing(); 2570fe6060f1SDimitry Andric Actions.CodeCompleteModuleImport(UseLoc, Path); 25710b57cec5SDimitry Andric return true; 25720b57cec5SDimitry Andric } 25730b57cec5SDimitry Andric 25740b57cec5SDimitry Andric Diag(Tok, diag::err_module_expected_ident) << IsImport; 25750b57cec5SDimitry Andric SkipUntil(tok::semi); 25760b57cec5SDimitry Andric return true; 25770b57cec5SDimitry Andric } 25780b57cec5SDimitry Andric 25790b57cec5SDimitry Andric // Record this part of the module path. 25800b57cec5SDimitry Andric Path.push_back(std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation())); 25810b57cec5SDimitry Andric ConsumeToken(); 25820b57cec5SDimitry Andric 25830b57cec5SDimitry Andric if (Tok.isNot(tok::period)) 25840b57cec5SDimitry Andric return false; 25850b57cec5SDimitry Andric 25860b57cec5SDimitry Andric ConsumeToken(); 25870b57cec5SDimitry Andric } 25880b57cec5SDimitry Andric } 25890b57cec5SDimitry Andric 25900b57cec5SDimitry Andric /// Try recover parser when module annotation appears where it must not 25910b57cec5SDimitry Andric /// be found. 25920b57cec5SDimitry Andric /// \returns false if the recover was successful and parsing may be continued, or 25930b57cec5SDimitry Andric /// true if parser must bail out to top level and handle the token there. 25940b57cec5SDimitry Andric bool Parser::parseMisplacedModuleImport() { 25950b57cec5SDimitry Andric while (true) { 25960b57cec5SDimitry Andric switch (Tok.getKind()) { 25970b57cec5SDimitry Andric case tok::annot_module_end: 25980b57cec5SDimitry Andric // If we recovered from a misplaced module begin, we expect to hit a 25990b57cec5SDimitry Andric // misplaced module end too. Stay in the current context when this 26000b57cec5SDimitry Andric // happens. 26010b57cec5SDimitry Andric if (MisplacedModuleBeginCount) { 26020b57cec5SDimitry Andric --MisplacedModuleBeginCount; 26030b57cec5SDimitry Andric Actions.ActOnModuleEnd(Tok.getLocation(), 26040b57cec5SDimitry Andric reinterpret_cast<Module *>( 26050b57cec5SDimitry Andric Tok.getAnnotationValue())); 26060b57cec5SDimitry Andric ConsumeAnnotationToken(); 26070b57cec5SDimitry Andric continue; 26080b57cec5SDimitry Andric } 26090b57cec5SDimitry Andric // Inform caller that recovery failed, the error must be handled at upper 26100b57cec5SDimitry Andric // level. This will generate the desired "missing '}' at end of module" 26110b57cec5SDimitry Andric // diagnostics on the way out. 26120b57cec5SDimitry Andric return true; 26130b57cec5SDimitry Andric case tok::annot_module_begin: 26140b57cec5SDimitry Andric // Recover by entering the module (Sema will diagnose). 26150b57cec5SDimitry Andric Actions.ActOnModuleBegin(Tok.getLocation(), 26160b57cec5SDimitry Andric reinterpret_cast<Module *>( 26170b57cec5SDimitry Andric Tok.getAnnotationValue())); 26180b57cec5SDimitry Andric ConsumeAnnotationToken(); 26190b57cec5SDimitry Andric ++MisplacedModuleBeginCount; 26200b57cec5SDimitry Andric continue; 26210b57cec5SDimitry Andric case tok::annot_module_include: 26220b57cec5SDimitry Andric // Module import found where it should not be, for instance, inside a 26230b57cec5SDimitry Andric // namespace. Recover by importing the module. 26240b57cec5SDimitry Andric Actions.ActOnModuleInclude(Tok.getLocation(), 26250b57cec5SDimitry Andric reinterpret_cast<Module *>( 26260b57cec5SDimitry Andric Tok.getAnnotationValue())); 26270b57cec5SDimitry Andric ConsumeAnnotationToken(); 26280b57cec5SDimitry Andric // If there is another module import, process it. 26290b57cec5SDimitry Andric continue; 26300b57cec5SDimitry Andric default: 26310b57cec5SDimitry Andric return false; 26320b57cec5SDimitry Andric } 26330b57cec5SDimitry Andric } 26340b57cec5SDimitry Andric return false; 26350b57cec5SDimitry Andric } 26360b57cec5SDimitry Andric 26370b57cec5SDimitry Andric bool BalancedDelimiterTracker::diagnoseOverflow() { 26380b57cec5SDimitry Andric P.Diag(P.Tok, diag::err_bracket_depth_exceeded) 26390b57cec5SDimitry Andric << P.getLangOpts().BracketDepth; 26400b57cec5SDimitry Andric P.Diag(P.Tok, diag::note_bracket_depth); 26410b57cec5SDimitry Andric P.cutOffParsing(); 26420b57cec5SDimitry Andric return true; 26430b57cec5SDimitry Andric } 26440b57cec5SDimitry Andric 26450b57cec5SDimitry Andric bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID, 26460b57cec5SDimitry Andric const char *Msg, 26470b57cec5SDimitry Andric tok::TokenKind SkipToTok) { 26480b57cec5SDimitry Andric LOpen = P.Tok.getLocation(); 26490b57cec5SDimitry Andric if (P.ExpectAndConsume(Kind, DiagID, Msg)) { 26500b57cec5SDimitry Andric if (SkipToTok != tok::unknown) 26510b57cec5SDimitry Andric P.SkipUntil(SkipToTok, Parser::StopAtSemi); 26520b57cec5SDimitry Andric return true; 26530b57cec5SDimitry Andric } 26540b57cec5SDimitry Andric 26550b57cec5SDimitry Andric if (getDepth() < P.getLangOpts().BracketDepth) 26560b57cec5SDimitry Andric return false; 26570b57cec5SDimitry Andric 26580b57cec5SDimitry Andric return diagnoseOverflow(); 26590b57cec5SDimitry Andric } 26600b57cec5SDimitry Andric 26610b57cec5SDimitry Andric bool BalancedDelimiterTracker::diagnoseMissingClose() { 26620b57cec5SDimitry Andric assert(!P.Tok.is(Close) && "Should have consumed closing delimiter"); 26630b57cec5SDimitry Andric 26640b57cec5SDimitry Andric if (P.Tok.is(tok::annot_module_end)) 26650b57cec5SDimitry Andric P.Diag(P.Tok, diag::err_missing_before_module_end) << Close; 26660b57cec5SDimitry Andric else 26670b57cec5SDimitry Andric P.Diag(P.Tok, diag::err_expected) << Close; 26680b57cec5SDimitry Andric P.Diag(LOpen, diag::note_matching) << Kind; 26690b57cec5SDimitry Andric 26700b57cec5SDimitry Andric // If we're not already at some kind of closing bracket, skip to our closing 26710b57cec5SDimitry Andric // token. 26720b57cec5SDimitry Andric if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) && 26730b57cec5SDimitry Andric P.Tok.isNot(tok::r_square) && 26740b57cec5SDimitry Andric P.SkipUntil(Close, FinalToken, 26750b57cec5SDimitry Andric Parser::StopAtSemi | Parser::StopBeforeMatch) && 26760b57cec5SDimitry Andric P.Tok.is(Close)) 26770b57cec5SDimitry Andric LClose = P.ConsumeAnyToken(); 26780b57cec5SDimitry Andric return true; 26790b57cec5SDimitry Andric } 26800b57cec5SDimitry Andric 26810b57cec5SDimitry Andric void BalancedDelimiterTracker::skipToEnd() { 26820b57cec5SDimitry Andric P.SkipUntil(Close, Parser::StopBeforeMatch); 26830b57cec5SDimitry Andric consumeClose(); 26840b57cec5SDimitry Andric } 2685