17330f729Sjoerg //===--- Parser.cpp - C Language Family Parser ----------------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the Parser interfaces.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #include "clang/Parse/Parser.h"
147330f729Sjoerg #include "clang/AST/ASTConsumer.h"
157330f729Sjoerg #include "clang/AST/ASTContext.h"
167330f729Sjoerg #include "clang/AST/DeclTemplate.h"
17*e038c9c4Sjoerg #include "clang/Basic/FileManager.h"
187330f729Sjoerg #include "clang/Parse/ParseDiagnostic.h"
197330f729Sjoerg #include "clang/Parse/RAIIObjectsForParser.h"
207330f729Sjoerg #include "clang/Sema/DeclSpec.h"
217330f729Sjoerg #include "clang/Sema/ParsedTemplate.h"
227330f729Sjoerg #include "clang/Sema/Scope.h"
237330f729Sjoerg #include "llvm/Support/Path.h"
247330f729Sjoerg using namespace clang;
257330f729Sjoerg
267330f729Sjoerg
277330f729Sjoerg namespace {
287330f729Sjoerg /// A comment handler that passes comments found by the preprocessor
297330f729Sjoerg /// to the parser action.
307330f729Sjoerg class ActionCommentHandler : public CommentHandler {
317330f729Sjoerg Sema &S;
327330f729Sjoerg
337330f729Sjoerg public:
ActionCommentHandler(Sema & S)347330f729Sjoerg explicit ActionCommentHandler(Sema &S) : S(S) { }
357330f729Sjoerg
HandleComment(Preprocessor & PP,SourceRange Comment)367330f729Sjoerg bool HandleComment(Preprocessor &PP, SourceRange Comment) override {
377330f729Sjoerg S.ActOnComment(Comment);
387330f729Sjoerg return false;
397330f729Sjoerg }
407330f729Sjoerg };
417330f729Sjoerg } // end anonymous namespace
427330f729Sjoerg
getSEHExceptKeyword()437330f729Sjoerg IdentifierInfo *Parser::getSEHExceptKeyword() {
447330f729Sjoerg // __except is accepted as a (contextual) keyword
457330f729Sjoerg if (!Ident__except && (getLangOpts().MicrosoftExt || getLangOpts().Borland))
467330f729Sjoerg Ident__except = PP.getIdentifierInfo("__except");
477330f729Sjoerg
487330f729Sjoerg return Ident__except;
497330f729Sjoerg }
507330f729Sjoerg
Parser(Preprocessor & pp,Sema & actions,bool skipFunctionBodies)517330f729Sjoerg Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
52*e038c9c4Sjoerg : PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),
53*e038c9c4Sjoerg Diags(PP.getDiagnostics()), GreaterThanIsOperator(true),
54*e038c9c4Sjoerg ColonIsSacred(false), InMessageExpression(false),
55*e038c9c4Sjoerg TemplateParameterDepth(0), ParsingInObjCContainer(false) {
567330f729Sjoerg SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
577330f729Sjoerg Tok.startToken();
587330f729Sjoerg Tok.setKind(tok::eof);
597330f729Sjoerg Actions.CurScope = nullptr;
607330f729Sjoerg NumCachedScopes = 0;
617330f729Sjoerg CurParsedObjCImpl = nullptr;
627330f729Sjoerg
637330f729Sjoerg // Add #pragma handlers. These are removed and destroyed in the
647330f729Sjoerg // destructor.
657330f729Sjoerg initializePragmaHandlers();
667330f729Sjoerg
677330f729Sjoerg CommentSemaHandler.reset(new ActionCommentHandler(actions));
687330f729Sjoerg PP.addCommentHandler(CommentSemaHandler.get());
697330f729Sjoerg
707330f729Sjoerg PP.setCodeCompletionHandler(*this);
717330f729Sjoerg }
727330f729Sjoerg
Diag(SourceLocation Loc,unsigned DiagID)737330f729Sjoerg DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
747330f729Sjoerg return Diags.Report(Loc, DiagID);
757330f729Sjoerg }
767330f729Sjoerg
Diag(const Token & Tok,unsigned DiagID)777330f729Sjoerg DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) {
787330f729Sjoerg return Diag(Tok.getLocation(), DiagID);
797330f729Sjoerg }
807330f729Sjoerg
817330f729Sjoerg /// Emits a diagnostic suggesting parentheses surrounding a
827330f729Sjoerg /// given range.
837330f729Sjoerg ///
847330f729Sjoerg /// \param Loc The location where we'll emit the diagnostic.
857330f729Sjoerg /// \param DK The kind of diagnostic to emit.
867330f729Sjoerg /// \param ParenRange Source range enclosing code that should be parenthesized.
SuggestParentheses(SourceLocation Loc,unsigned DK,SourceRange ParenRange)877330f729Sjoerg void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK,
887330f729Sjoerg SourceRange ParenRange) {
897330f729Sjoerg SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd());
907330f729Sjoerg if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) {
917330f729Sjoerg // We can't display the parentheses, so just dig the
927330f729Sjoerg // warning/error and return.
937330f729Sjoerg Diag(Loc, DK);
947330f729Sjoerg return;
957330f729Sjoerg }
967330f729Sjoerg
977330f729Sjoerg Diag(Loc, DK)
987330f729Sjoerg << FixItHint::CreateInsertion(ParenRange.getBegin(), "(")
997330f729Sjoerg << FixItHint::CreateInsertion(EndLoc, ")");
1007330f729Sjoerg }
1017330f729Sjoerg
IsCommonTypo(tok::TokenKind ExpectedTok,const Token & Tok)1027330f729Sjoerg static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok) {
1037330f729Sjoerg switch (ExpectedTok) {
1047330f729Sjoerg case tok::semi:
1057330f729Sjoerg return Tok.is(tok::colon) || Tok.is(tok::comma); // : or , for ;
1067330f729Sjoerg default: return false;
1077330f729Sjoerg }
1087330f729Sjoerg }
1097330f729Sjoerg
ExpectAndConsume(tok::TokenKind ExpectedTok,unsigned DiagID,StringRef Msg)1107330f729Sjoerg bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
1117330f729Sjoerg StringRef Msg) {
1127330f729Sjoerg if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) {
1137330f729Sjoerg ConsumeAnyToken();
1147330f729Sjoerg return false;
1157330f729Sjoerg }
1167330f729Sjoerg
1177330f729Sjoerg // Detect common single-character typos and resume.
1187330f729Sjoerg if (IsCommonTypo(ExpectedTok, Tok)) {
1197330f729Sjoerg SourceLocation Loc = Tok.getLocation();
1207330f729Sjoerg {
1217330f729Sjoerg DiagnosticBuilder DB = Diag(Loc, DiagID);
1227330f729Sjoerg DB << FixItHint::CreateReplacement(
1237330f729Sjoerg SourceRange(Loc), tok::getPunctuatorSpelling(ExpectedTok));
1247330f729Sjoerg if (DiagID == diag::err_expected)
1257330f729Sjoerg DB << ExpectedTok;
1267330f729Sjoerg else if (DiagID == diag::err_expected_after)
1277330f729Sjoerg DB << Msg << ExpectedTok;
1287330f729Sjoerg else
1297330f729Sjoerg DB << Msg;
1307330f729Sjoerg }
1317330f729Sjoerg
1327330f729Sjoerg // Pretend there wasn't a problem.
1337330f729Sjoerg ConsumeAnyToken();
1347330f729Sjoerg return false;
1357330f729Sjoerg }
1367330f729Sjoerg
1377330f729Sjoerg SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
1387330f729Sjoerg const char *Spelling = nullptr;
1397330f729Sjoerg if (EndLoc.isValid())
1407330f729Sjoerg Spelling = tok::getPunctuatorSpelling(ExpectedTok);
1417330f729Sjoerg
1427330f729Sjoerg DiagnosticBuilder DB =
1437330f729Sjoerg Spelling
1447330f729Sjoerg ? Diag(EndLoc, DiagID) << FixItHint::CreateInsertion(EndLoc, Spelling)
1457330f729Sjoerg : Diag(Tok, DiagID);
1467330f729Sjoerg if (DiagID == diag::err_expected)
1477330f729Sjoerg DB << ExpectedTok;
1487330f729Sjoerg else if (DiagID == diag::err_expected_after)
1497330f729Sjoerg DB << Msg << ExpectedTok;
1507330f729Sjoerg else
1517330f729Sjoerg DB << Msg;
1527330f729Sjoerg
1537330f729Sjoerg return true;
1547330f729Sjoerg }
1557330f729Sjoerg
ExpectAndConsumeSemi(unsigned DiagID)1567330f729Sjoerg bool Parser::ExpectAndConsumeSemi(unsigned DiagID) {
1577330f729Sjoerg if (TryConsumeToken(tok::semi))
1587330f729Sjoerg return false;
1597330f729Sjoerg
1607330f729Sjoerg if (Tok.is(tok::code_completion)) {
1617330f729Sjoerg handleUnexpectedCodeCompletionToken();
1627330f729Sjoerg return false;
1637330f729Sjoerg }
1647330f729Sjoerg
1657330f729Sjoerg if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) &&
1667330f729Sjoerg NextToken().is(tok::semi)) {
1677330f729Sjoerg Diag(Tok, diag::err_extraneous_token_before_semi)
1687330f729Sjoerg << PP.getSpelling(Tok)
1697330f729Sjoerg << FixItHint::CreateRemoval(Tok.getLocation());
1707330f729Sjoerg ConsumeAnyToken(); // The ')' or ']'.
1717330f729Sjoerg ConsumeToken(); // The ';'.
1727330f729Sjoerg return false;
1737330f729Sjoerg }
1747330f729Sjoerg
1757330f729Sjoerg return ExpectAndConsume(tok::semi, DiagID);
1767330f729Sjoerg }
1777330f729Sjoerg
ConsumeExtraSemi(ExtraSemiKind Kind,DeclSpec::TST TST)1787330f729Sjoerg void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST TST) {
1797330f729Sjoerg if (!Tok.is(tok::semi)) return;
1807330f729Sjoerg
1817330f729Sjoerg bool HadMultipleSemis = false;
1827330f729Sjoerg SourceLocation StartLoc = Tok.getLocation();
1837330f729Sjoerg SourceLocation EndLoc = Tok.getLocation();
1847330f729Sjoerg ConsumeToken();
1857330f729Sjoerg
1867330f729Sjoerg while ((Tok.is(tok::semi) && !Tok.isAtStartOfLine())) {
1877330f729Sjoerg HadMultipleSemis = true;
1887330f729Sjoerg EndLoc = Tok.getLocation();
1897330f729Sjoerg ConsumeToken();
1907330f729Sjoerg }
1917330f729Sjoerg
1927330f729Sjoerg // C++11 allows extra semicolons at namespace scope, but not in any of the
1937330f729Sjoerg // other contexts.
1947330f729Sjoerg if (Kind == OutsideFunction && getLangOpts().CPlusPlus) {
1957330f729Sjoerg if (getLangOpts().CPlusPlus11)
1967330f729Sjoerg Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi)
1977330f729Sjoerg << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
1987330f729Sjoerg else
1997330f729Sjoerg Diag(StartLoc, diag::ext_extra_semi_cxx11)
2007330f729Sjoerg << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
2017330f729Sjoerg return;
2027330f729Sjoerg }
2037330f729Sjoerg
2047330f729Sjoerg if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis)
2057330f729Sjoerg Diag(StartLoc, diag::ext_extra_semi)
2067330f729Sjoerg << Kind << DeclSpec::getSpecifierName(TST,
2077330f729Sjoerg Actions.getASTContext().getPrintingPolicy())
2087330f729Sjoerg << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
2097330f729Sjoerg else
2107330f729Sjoerg // A single semicolon is valid after a member function definition.
2117330f729Sjoerg Diag(StartLoc, diag::warn_extra_semi_after_mem_fn_def)
2127330f729Sjoerg << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
2137330f729Sjoerg }
2147330f729Sjoerg
expectIdentifier()2157330f729Sjoerg bool Parser::expectIdentifier() {
2167330f729Sjoerg if (Tok.is(tok::identifier))
2177330f729Sjoerg return false;
2187330f729Sjoerg if (const auto *II = Tok.getIdentifierInfo()) {
2197330f729Sjoerg if (II->isCPlusPlusKeyword(getLangOpts())) {
2207330f729Sjoerg Diag(Tok, diag::err_expected_token_instead_of_objcxx_keyword)
2217330f729Sjoerg << tok::identifier << Tok.getIdentifierInfo();
2227330f729Sjoerg // Objective-C++: Recover by treating this keyword as a valid identifier.
2237330f729Sjoerg return false;
2247330f729Sjoerg }
2257330f729Sjoerg }
2267330f729Sjoerg Diag(Tok, diag::err_expected) << tok::identifier;
2277330f729Sjoerg return true;
2287330f729Sjoerg }
2297330f729Sjoerg
checkCompoundToken(SourceLocation FirstTokLoc,tok::TokenKind FirstTokKind,CompoundToken Op)230*e038c9c4Sjoerg void Parser::checkCompoundToken(SourceLocation FirstTokLoc,
231*e038c9c4Sjoerg tok::TokenKind FirstTokKind, CompoundToken Op) {
232*e038c9c4Sjoerg if (FirstTokLoc.isInvalid())
233*e038c9c4Sjoerg return;
234*e038c9c4Sjoerg SourceLocation SecondTokLoc = Tok.getLocation();
235*e038c9c4Sjoerg
236*e038c9c4Sjoerg // If either token is in a macro, we expect both tokens to come from the same
237*e038c9c4Sjoerg // macro expansion.
238*e038c9c4Sjoerg if ((FirstTokLoc.isMacroID() || SecondTokLoc.isMacroID()) &&
239*e038c9c4Sjoerg PP.getSourceManager().getFileID(FirstTokLoc) !=
240*e038c9c4Sjoerg PP.getSourceManager().getFileID(SecondTokLoc)) {
241*e038c9c4Sjoerg Diag(FirstTokLoc, diag::warn_compound_token_split_by_macro)
242*e038c9c4Sjoerg << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind()
243*e038c9c4Sjoerg << static_cast<int>(Op) << SourceRange(FirstTokLoc);
244*e038c9c4Sjoerg Diag(SecondTokLoc, diag::note_compound_token_split_second_token_here)
245*e038c9c4Sjoerg << (FirstTokKind == Tok.getKind()) << Tok.getKind()
246*e038c9c4Sjoerg << SourceRange(SecondTokLoc);
247*e038c9c4Sjoerg return;
248*e038c9c4Sjoerg }
249*e038c9c4Sjoerg
250*e038c9c4Sjoerg // We expect the tokens to abut.
251*e038c9c4Sjoerg if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) {
252*e038c9c4Sjoerg SourceLocation SpaceLoc = PP.getLocForEndOfToken(FirstTokLoc);
253*e038c9c4Sjoerg if (SpaceLoc.isInvalid())
254*e038c9c4Sjoerg SpaceLoc = FirstTokLoc;
255*e038c9c4Sjoerg Diag(SpaceLoc, diag::warn_compound_token_split_by_whitespace)
256*e038c9c4Sjoerg << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind()
257*e038c9c4Sjoerg << static_cast<int>(Op) << SourceRange(FirstTokLoc, SecondTokLoc);
258*e038c9c4Sjoerg return;
259*e038c9c4Sjoerg }
260*e038c9c4Sjoerg }
261*e038c9c4Sjoerg
2627330f729Sjoerg //===----------------------------------------------------------------------===//
2637330f729Sjoerg // Error recovery.
2647330f729Sjoerg //===----------------------------------------------------------------------===//
2657330f729Sjoerg
HasFlagsSet(Parser::SkipUntilFlags L,Parser::SkipUntilFlags R)2667330f729Sjoerg static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) {
2677330f729Sjoerg return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0;
2687330f729Sjoerg }
2697330f729Sjoerg
2707330f729Sjoerg /// SkipUntil - Read tokens until we get to the specified token, then consume
2717330f729Sjoerg /// it (unless no flag StopBeforeMatch). Because we cannot guarantee that the
2727330f729Sjoerg /// token will ever occur, this skips to the next token, or to some likely
2737330f729Sjoerg /// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
2747330f729Sjoerg /// character.
2757330f729Sjoerg ///
2767330f729Sjoerg /// If SkipUntil finds the specified token, it returns true, otherwise it
2777330f729Sjoerg /// returns false.
SkipUntil(ArrayRef<tok::TokenKind> Toks,SkipUntilFlags Flags)2787330f729Sjoerg bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
2797330f729Sjoerg // We always want this function to skip at least one token if the first token
2807330f729Sjoerg // isn't T and if not at EOF.
2817330f729Sjoerg bool isFirstTokenSkipped = true;
2827330f729Sjoerg while (1) {
2837330f729Sjoerg // If we found one of the tokens, stop and return true.
2847330f729Sjoerg for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) {
2857330f729Sjoerg if (Tok.is(Toks[i])) {
2867330f729Sjoerg if (HasFlagsSet(Flags, StopBeforeMatch)) {
2877330f729Sjoerg // Noop, don't consume the token.
2887330f729Sjoerg } else {
2897330f729Sjoerg ConsumeAnyToken();
2907330f729Sjoerg }
2917330f729Sjoerg return true;
2927330f729Sjoerg }
2937330f729Sjoerg }
2947330f729Sjoerg
2957330f729Sjoerg // Important special case: The caller has given up and just wants us to
2967330f729Sjoerg // skip the rest of the file. Do this without recursing, since we can
2977330f729Sjoerg // get here precisely because the caller detected too much recursion.
2987330f729Sjoerg if (Toks.size() == 1 && Toks[0] == tok::eof &&
2997330f729Sjoerg !HasFlagsSet(Flags, StopAtSemi) &&
3007330f729Sjoerg !HasFlagsSet(Flags, StopAtCodeCompletion)) {
3017330f729Sjoerg while (Tok.isNot(tok::eof))
3027330f729Sjoerg ConsumeAnyToken();
3037330f729Sjoerg return true;
3047330f729Sjoerg }
3057330f729Sjoerg
3067330f729Sjoerg switch (Tok.getKind()) {
3077330f729Sjoerg case tok::eof:
3087330f729Sjoerg // Ran out of tokens.
3097330f729Sjoerg return false;
3107330f729Sjoerg
3117330f729Sjoerg case tok::annot_pragma_openmp:
3127330f729Sjoerg case tok::annot_pragma_openmp_end:
3137330f729Sjoerg // Stop before an OpenMP pragma boundary.
314*e038c9c4Sjoerg if (OpenMPDirectiveParsing)
315*e038c9c4Sjoerg return false;
316*e038c9c4Sjoerg ConsumeAnnotationToken();
317*e038c9c4Sjoerg break;
3187330f729Sjoerg case tok::annot_module_begin:
3197330f729Sjoerg case tok::annot_module_end:
3207330f729Sjoerg case tok::annot_module_include:
3217330f729Sjoerg // Stop before we change submodules. They generally indicate a "good"
3227330f729Sjoerg // place to pick up parsing again (except in the special case where
3237330f729Sjoerg // we're trying to skip to EOF).
3247330f729Sjoerg return false;
3257330f729Sjoerg
3267330f729Sjoerg case tok::code_completion:
3277330f729Sjoerg if (!HasFlagsSet(Flags, StopAtCodeCompletion))
3287330f729Sjoerg handleUnexpectedCodeCompletionToken();
3297330f729Sjoerg return false;
3307330f729Sjoerg
3317330f729Sjoerg case tok::l_paren:
3327330f729Sjoerg // Recursively skip properly-nested parens.
3337330f729Sjoerg ConsumeParen();
3347330f729Sjoerg if (HasFlagsSet(Flags, StopAtCodeCompletion))
3357330f729Sjoerg SkipUntil(tok::r_paren, StopAtCodeCompletion);
3367330f729Sjoerg else
3377330f729Sjoerg SkipUntil(tok::r_paren);
3387330f729Sjoerg break;
3397330f729Sjoerg case tok::l_square:
3407330f729Sjoerg // Recursively skip properly-nested square brackets.
3417330f729Sjoerg ConsumeBracket();
3427330f729Sjoerg if (HasFlagsSet(Flags, StopAtCodeCompletion))
3437330f729Sjoerg SkipUntil(tok::r_square, StopAtCodeCompletion);
3447330f729Sjoerg else
3457330f729Sjoerg SkipUntil(tok::r_square);
3467330f729Sjoerg break;
3477330f729Sjoerg case tok::l_brace:
3487330f729Sjoerg // Recursively skip properly-nested braces.
3497330f729Sjoerg ConsumeBrace();
3507330f729Sjoerg if (HasFlagsSet(Flags, StopAtCodeCompletion))
3517330f729Sjoerg SkipUntil(tok::r_brace, StopAtCodeCompletion);
3527330f729Sjoerg else
3537330f729Sjoerg SkipUntil(tok::r_brace);
3547330f729Sjoerg break;
3557330f729Sjoerg case tok::question:
3567330f729Sjoerg // Recursively skip ? ... : pairs; these function as brackets. But
3577330f729Sjoerg // still stop at a semicolon if requested.
3587330f729Sjoerg ConsumeToken();
3597330f729Sjoerg SkipUntil(tok::colon,
3607330f729Sjoerg SkipUntilFlags(unsigned(Flags) &
3617330f729Sjoerg unsigned(StopAtCodeCompletion | StopAtSemi)));
3627330f729Sjoerg break;
3637330f729Sjoerg
3647330f729Sjoerg // Okay, we found a ']' or '}' or ')', which we think should be balanced.
3657330f729Sjoerg // Since the user wasn't looking for this token (if they were, it would
3667330f729Sjoerg // already be handled), this isn't balanced. If there is a LHS token at a
3677330f729Sjoerg // higher level, we will assume that this matches the unbalanced token
3687330f729Sjoerg // and return it. Otherwise, this is a spurious RHS token, which we skip.
3697330f729Sjoerg case tok::r_paren:
3707330f729Sjoerg if (ParenCount && !isFirstTokenSkipped)
3717330f729Sjoerg return false; // Matches something.
3727330f729Sjoerg ConsumeParen();
3737330f729Sjoerg break;
3747330f729Sjoerg case tok::r_square:
3757330f729Sjoerg if (BracketCount && !isFirstTokenSkipped)
3767330f729Sjoerg return false; // Matches something.
3777330f729Sjoerg ConsumeBracket();
3787330f729Sjoerg break;
3797330f729Sjoerg case tok::r_brace:
3807330f729Sjoerg if (BraceCount && !isFirstTokenSkipped)
3817330f729Sjoerg return false; // Matches something.
3827330f729Sjoerg ConsumeBrace();
3837330f729Sjoerg break;
3847330f729Sjoerg
3857330f729Sjoerg case tok::semi:
3867330f729Sjoerg if (HasFlagsSet(Flags, StopAtSemi))
3877330f729Sjoerg return false;
3887330f729Sjoerg LLVM_FALLTHROUGH;
3897330f729Sjoerg default:
3907330f729Sjoerg // Skip this token.
3917330f729Sjoerg ConsumeAnyToken();
3927330f729Sjoerg break;
3937330f729Sjoerg }
3947330f729Sjoerg isFirstTokenSkipped = false;
3957330f729Sjoerg }
3967330f729Sjoerg }
3977330f729Sjoerg
3987330f729Sjoerg //===----------------------------------------------------------------------===//
3997330f729Sjoerg // Scope manipulation
4007330f729Sjoerg //===----------------------------------------------------------------------===//
4017330f729Sjoerg
4027330f729Sjoerg /// EnterScope - Start a new scope.
EnterScope(unsigned ScopeFlags)4037330f729Sjoerg void Parser::EnterScope(unsigned ScopeFlags) {
4047330f729Sjoerg if (NumCachedScopes) {
4057330f729Sjoerg Scope *N = ScopeCache[--NumCachedScopes];
4067330f729Sjoerg N->Init(getCurScope(), ScopeFlags);
4077330f729Sjoerg Actions.CurScope = N;
4087330f729Sjoerg } else {
4097330f729Sjoerg Actions.CurScope = new Scope(getCurScope(), ScopeFlags, Diags);
4107330f729Sjoerg }
4117330f729Sjoerg }
4127330f729Sjoerg
4137330f729Sjoerg /// ExitScope - Pop a scope off the scope stack.
ExitScope()4147330f729Sjoerg void Parser::ExitScope() {
4157330f729Sjoerg assert(getCurScope() && "Scope imbalance!");
4167330f729Sjoerg
4177330f729Sjoerg // Inform the actions module that this scope is going away if there are any
4187330f729Sjoerg // decls in it.
4197330f729Sjoerg Actions.ActOnPopScope(Tok.getLocation(), getCurScope());
4207330f729Sjoerg
4217330f729Sjoerg Scope *OldScope = getCurScope();
4227330f729Sjoerg Actions.CurScope = OldScope->getParent();
4237330f729Sjoerg
4247330f729Sjoerg if (NumCachedScopes == ScopeCacheSize)
4257330f729Sjoerg delete OldScope;
4267330f729Sjoerg else
4277330f729Sjoerg ScopeCache[NumCachedScopes++] = OldScope;
4287330f729Sjoerg }
4297330f729Sjoerg
4307330f729Sjoerg /// Set the flags for the current scope to ScopeFlags. If ManageFlags is false,
4317330f729Sjoerg /// this object does nothing.
ParseScopeFlags(Parser * Self,unsigned ScopeFlags,bool ManageFlags)4327330f729Sjoerg Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags,
4337330f729Sjoerg bool ManageFlags)
4347330f729Sjoerg : CurScope(ManageFlags ? Self->getCurScope() : nullptr) {
4357330f729Sjoerg if (CurScope) {
4367330f729Sjoerg OldFlags = CurScope->getFlags();
4377330f729Sjoerg CurScope->setFlags(ScopeFlags);
4387330f729Sjoerg }
4397330f729Sjoerg }
4407330f729Sjoerg
4417330f729Sjoerg /// Restore the flags for the current scope to what they were before this
4427330f729Sjoerg /// object overrode them.
~ParseScopeFlags()4437330f729Sjoerg Parser::ParseScopeFlags::~ParseScopeFlags() {
4447330f729Sjoerg if (CurScope)
4457330f729Sjoerg CurScope->setFlags(OldFlags);
4467330f729Sjoerg }
4477330f729Sjoerg
4487330f729Sjoerg
4497330f729Sjoerg //===----------------------------------------------------------------------===//
4507330f729Sjoerg // C99 6.9: External Definitions.
4517330f729Sjoerg //===----------------------------------------------------------------------===//
4527330f729Sjoerg
~Parser()4537330f729Sjoerg Parser::~Parser() {
4547330f729Sjoerg // If we still have scopes active, delete the scope tree.
4557330f729Sjoerg delete getCurScope();
4567330f729Sjoerg Actions.CurScope = nullptr;
4577330f729Sjoerg
4587330f729Sjoerg // Free the scope cache.
4597330f729Sjoerg for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
4607330f729Sjoerg delete ScopeCache[i];
4617330f729Sjoerg
4627330f729Sjoerg resetPragmaHandlers();
4637330f729Sjoerg
4647330f729Sjoerg PP.removeCommentHandler(CommentSemaHandler.get());
4657330f729Sjoerg
4667330f729Sjoerg PP.clearCodeCompletionHandler();
4677330f729Sjoerg
468*e038c9c4Sjoerg DestroyTemplateIds();
4697330f729Sjoerg }
4707330f729Sjoerg
4717330f729Sjoerg /// Initialize - Warm up the parser.
4727330f729Sjoerg ///
Initialize()4737330f729Sjoerg void Parser::Initialize() {
4747330f729Sjoerg // Create the translation unit scope. Install it as the current scope.
4757330f729Sjoerg assert(getCurScope() == nullptr && "A scope is already active?");
4767330f729Sjoerg EnterScope(Scope::DeclScope);
4777330f729Sjoerg Actions.ActOnTranslationUnitScope(getCurScope());
4787330f729Sjoerg
4797330f729Sjoerg // Initialization for Objective-C context sensitive keywords recognition.
4807330f729Sjoerg // Referenced in Parser::ParseObjCTypeQualifierList.
4817330f729Sjoerg if (getLangOpts().ObjC) {
4827330f729Sjoerg ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in");
4837330f729Sjoerg ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out");
4847330f729Sjoerg ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout");
4857330f729Sjoerg ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway");
4867330f729Sjoerg ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy");
4877330f729Sjoerg ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref");
4887330f729Sjoerg ObjCTypeQuals[objc_nonnull] = &PP.getIdentifierTable().get("nonnull");
4897330f729Sjoerg ObjCTypeQuals[objc_nullable] = &PP.getIdentifierTable().get("nullable");
4907330f729Sjoerg ObjCTypeQuals[objc_null_unspecified]
4917330f729Sjoerg = &PP.getIdentifierTable().get("null_unspecified");
4927330f729Sjoerg }
4937330f729Sjoerg
4947330f729Sjoerg Ident_instancetype = nullptr;
4957330f729Sjoerg Ident_final = nullptr;
4967330f729Sjoerg Ident_sealed = nullptr;
4977330f729Sjoerg Ident_override = nullptr;
4987330f729Sjoerg Ident_GNU_final = nullptr;
4997330f729Sjoerg Ident_import = nullptr;
5007330f729Sjoerg Ident_module = nullptr;
5017330f729Sjoerg
5027330f729Sjoerg Ident_super = &PP.getIdentifierTable().get("super");
5037330f729Sjoerg
5047330f729Sjoerg Ident_vector = nullptr;
5057330f729Sjoerg Ident_bool = nullptr;
506*e038c9c4Sjoerg Ident_Bool = nullptr;
5077330f729Sjoerg Ident_pixel = nullptr;
5087330f729Sjoerg if (getLangOpts().AltiVec || getLangOpts().ZVector) {
5097330f729Sjoerg Ident_vector = &PP.getIdentifierTable().get("vector");
5107330f729Sjoerg Ident_bool = &PP.getIdentifierTable().get("bool");
511*e038c9c4Sjoerg Ident_Bool = &PP.getIdentifierTable().get("_Bool");
5127330f729Sjoerg }
5137330f729Sjoerg if (getLangOpts().AltiVec)
5147330f729Sjoerg Ident_pixel = &PP.getIdentifierTable().get("pixel");
5157330f729Sjoerg
5167330f729Sjoerg Ident_introduced = nullptr;
5177330f729Sjoerg Ident_deprecated = nullptr;
5187330f729Sjoerg Ident_obsoleted = nullptr;
5197330f729Sjoerg Ident_unavailable = nullptr;
5207330f729Sjoerg Ident_strict = nullptr;
5217330f729Sjoerg Ident_replacement = nullptr;
5227330f729Sjoerg
5237330f729Sjoerg Ident_language = Ident_defined_in = Ident_generated_declaration = nullptr;
5247330f729Sjoerg
5257330f729Sjoerg Ident__except = nullptr;
5267330f729Sjoerg
5277330f729Sjoerg Ident__exception_code = Ident__exception_info = nullptr;
5287330f729Sjoerg Ident__abnormal_termination = Ident___exception_code = nullptr;
5297330f729Sjoerg Ident___exception_info = Ident___abnormal_termination = nullptr;
5307330f729Sjoerg Ident_GetExceptionCode = Ident_GetExceptionInfo = nullptr;
5317330f729Sjoerg Ident_AbnormalTermination = nullptr;
5327330f729Sjoerg
5337330f729Sjoerg if(getLangOpts().Borland) {
5347330f729Sjoerg Ident__exception_info = PP.getIdentifierInfo("_exception_info");
5357330f729Sjoerg Ident___exception_info = PP.getIdentifierInfo("__exception_info");
5367330f729Sjoerg Ident_GetExceptionInfo = PP.getIdentifierInfo("GetExceptionInformation");
5377330f729Sjoerg Ident__exception_code = PP.getIdentifierInfo("_exception_code");
5387330f729Sjoerg Ident___exception_code = PP.getIdentifierInfo("__exception_code");
5397330f729Sjoerg Ident_GetExceptionCode = PP.getIdentifierInfo("GetExceptionCode");
5407330f729Sjoerg Ident__abnormal_termination = PP.getIdentifierInfo("_abnormal_termination");
5417330f729Sjoerg Ident___abnormal_termination = PP.getIdentifierInfo("__abnormal_termination");
5427330f729Sjoerg Ident_AbnormalTermination = PP.getIdentifierInfo("AbnormalTermination");
5437330f729Sjoerg
5447330f729Sjoerg PP.SetPoisonReason(Ident__exception_code,diag::err_seh___except_block);
5457330f729Sjoerg PP.SetPoisonReason(Ident___exception_code,diag::err_seh___except_block);
5467330f729Sjoerg PP.SetPoisonReason(Ident_GetExceptionCode,diag::err_seh___except_block);
5477330f729Sjoerg PP.SetPoisonReason(Ident__exception_info,diag::err_seh___except_filter);
5487330f729Sjoerg PP.SetPoisonReason(Ident___exception_info,diag::err_seh___except_filter);
5497330f729Sjoerg PP.SetPoisonReason(Ident_GetExceptionInfo,diag::err_seh___except_filter);
5507330f729Sjoerg PP.SetPoisonReason(Ident__abnormal_termination,diag::err_seh___finally_block);
5517330f729Sjoerg PP.SetPoisonReason(Ident___abnormal_termination,diag::err_seh___finally_block);
5527330f729Sjoerg PP.SetPoisonReason(Ident_AbnormalTermination,diag::err_seh___finally_block);
5537330f729Sjoerg }
5547330f729Sjoerg
5557330f729Sjoerg if (getLangOpts().CPlusPlusModules) {
5567330f729Sjoerg Ident_import = PP.getIdentifierInfo("import");
5577330f729Sjoerg Ident_module = PP.getIdentifierInfo("module");
5587330f729Sjoerg }
5597330f729Sjoerg
5607330f729Sjoerg Actions.Initialize();
5617330f729Sjoerg
5627330f729Sjoerg // Prime the lexer look-ahead.
5637330f729Sjoerg ConsumeToken();
5647330f729Sjoerg }
5657330f729Sjoerg
DestroyTemplateIds()566*e038c9c4Sjoerg void Parser::DestroyTemplateIds() {
567*e038c9c4Sjoerg for (TemplateIdAnnotation *Id : TemplateIds)
568*e038c9c4Sjoerg Id->Destroy();
569*e038c9c4Sjoerg TemplateIds.clear();
5707330f729Sjoerg }
5717330f729Sjoerg
5727330f729Sjoerg /// Parse the first top-level declaration in a translation unit.
5737330f729Sjoerg ///
5747330f729Sjoerg /// translation-unit:
5757330f729Sjoerg /// [C] external-declaration
5767330f729Sjoerg /// [C] translation-unit external-declaration
5777330f729Sjoerg /// [C++] top-level-declaration-seq[opt]
5787330f729Sjoerg /// [C++20] global-module-fragment[opt] module-declaration
5797330f729Sjoerg /// top-level-declaration-seq[opt] private-module-fragment[opt]
5807330f729Sjoerg ///
5817330f729Sjoerg /// Note that in C, it is an error if there is no first declaration.
ParseFirstTopLevelDecl(DeclGroupPtrTy & Result)5827330f729Sjoerg bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) {
5837330f729Sjoerg Actions.ActOnStartOfTranslationUnit();
5847330f729Sjoerg
5857330f729Sjoerg // C11 6.9p1 says translation units must have at least one top-level
5867330f729Sjoerg // declaration. C++ doesn't have this restriction. We also don't want to
5877330f729Sjoerg // complain if we have a precompiled header, although technically if the PCH
5887330f729Sjoerg // is empty we should still emit the (pedantic) diagnostic.
589*e038c9c4Sjoerg // If the main file is a header, we're only pretending it's a TU; don't warn.
5907330f729Sjoerg bool NoTopLevelDecls = ParseTopLevelDecl(Result, true);
5917330f729Sjoerg if (NoTopLevelDecls && !Actions.getASTContext().getExternalSource() &&
592*e038c9c4Sjoerg !getLangOpts().CPlusPlus && !getLangOpts().IsHeaderFile)
5937330f729Sjoerg Diag(diag::ext_empty_translation_unit);
5947330f729Sjoerg
5957330f729Sjoerg return NoTopLevelDecls;
5967330f729Sjoerg }
5977330f729Sjoerg
5987330f729Sjoerg /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
5997330f729Sjoerg /// action tells us to. This returns true if the EOF was encountered.
6007330f729Sjoerg ///
6017330f729Sjoerg /// top-level-declaration:
6027330f729Sjoerg /// declaration
6037330f729Sjoerg /// [C++20] module-import-declaration
ParseTopLevelDecl(DeclGroupPtrTy & Result,bool IsFirstDecl)6047330f729Sjoerg bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl) {
605*e038c9c4Sjoerg DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
6067330f729Sjoerg
6077330f729Sjoerg // Skip over the EOF token, flagging end of previous input for incremental
6087330f729Sjoerg // processing
6097330f729Sjoerg if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))
6107330f729Sjoerg ConsumeToken();
6117330f729Sjoerg
6127330f729Sjoerg Result = nullptr;
6137330f729Sjoerg switch (Tok.getKind()) {
6147330f729Sjoerg case tok::annot_pragma_unused:
6157330f729Sjoerg HandlePragmaUnused();
6167330f729Sjoerg return false;
6177330f729Sjoerg
6187330f729Sjoerg case tok::kw_export:
6197330f729Sjoerg switch (NextToken().getKind()) {
6207330f729Sjoerg case tok::kw_module:
6217330f729Sjoerg goto module_decl;
6227330f729Sjoerg
6237330f729Sjoerg // Note: no need to handle kw_import here. We only form kw_import under
6247330f729Sjoerg // the Modules TS, and in that case 'export import' is parsed as an
6257330f729Sjoerg // export-declaration containing an import-declaration.
6267330f729Sjoerg
6277330f729Sjoerg // Recognize context-sensitive C++20 'export module' and 'export import'
6287330f729Sjoerg // declarations.
6297330f729Sjoerg case tok::identifier: {
6307330f729Sjoerg IdentifierInfo *II = NextToken().getIdentifierInfo();
6317330f729Sjoerg if ((II == Ident_module || II == Ident_import) &&
6327330f729Sjoerg GetLookAheadToken(2).isNot(tok::coloncolon)) {
6337330f729Sjoerg if (II == Ident_module)
6347330f729Sjoerg goto module_decl;
6357330f729Sjoerg else
6367330f729Sjoerg goto import_decl;
6377330f729Sjoerg }
6387330f729Sjoerg break;
6397330f729Sjoerg }
6407330f729Sjoerg
6417330f729Sjoerg default:
6427330f729Sjoerg break;
6437330f729Sjoerg }
6447330f729Sjoerg break;
6457330f729Sjoerg
6467330f729Sjoerg case tok::kw_module:
6477330f729Sjoerg module_decl:
6487330f729Sjoerg Result = ParseModuleDecl(IsFirstDecl);
6497330f729Sjoerg return false;
6507330f729Sjoerg
6517330f729Sjoerg // tok::kw_import is handled by ParseExternalDeclaration. (Under the Modules
6527330f729Sjoerg // TS, an import can occur within an export block.)
6537330f729Sjoerg import_decl: {
6547330f729Sjoerg Decl *ImportDecl = ParseModuleImport(SourceLocation());
6557330f729Sjoerg Result = Actions.ConvertDeclToDeclGroup(ImportDecl);
6567330f729Sjoerg return false;
6577330f729Sjoerg }
6587330f729Sjoerg
6597330f729Sjoerg case tok::annot_module_include:
6607330f729Sjoerg Actions.ActOnModuleInclude(Tok.getLocation(),
6617330f729Sjoerg reinterpret_cast<Module *>(
6627330f729Sjoerg Tok.getAnnotationValue()));
6637330f729Sjoerg ConsumeAnnotationToken();
6647330f729Sjoerg return false;
6657330f729Sjoerg
6667330f729Sjoerg case tok::annot_module_begin:
6677330f729Sjoerg Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>(
6687330f729Sjoerg Tok.getAnnotationValue()));
6697330f729Sjoerg ConsumeAnnotationToken();
6707330f729Sjoerg return false;
6717330f729Sjoerg
6727330f729Sjoerg case tok::annot_module_end:
6737330f729Sjoerg Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>(
6747330f729Sjoerg Tok.getAnnotationValue()));
6757330f729Sjoerg ConsumeAnnotationToken();
6767330f729Sjoerg return false;
6777330f729Sjoerg
6787330f729Sjoerg case tok::eof:
679*e038c9c4Sjoerg // Check whether -fmax-tokens= was reached.
680*e038c9c4Sjoerg if (PP.getMaxTokens() != 0 && PP.getTokenCount() > PP.getMaxTokens()) {
681*e038c9c4Sjoerg PP.Diag(Tok.getLocation(), diag::warn_max_tokens_total)
682*e038c9c4Sjoerg << PP.getTokenCount() << PP.getMaxTokens();
683*e038c9c4Sjoerg SourceLocation OverrideLoc = PP.getMaxTokensOverrideLoc();
684*e038c9c4Sjoerg if (OverrideLoc.isValid()) {
685*e038c9c4Sjoerg PP.Diag(OverrideLoc, diag::note_max_tokens_total_override);
686*e038c9c4Sjoerg }
687*e038c9c4Sjoerg }
688*e038c9c4Sjoerg
6897330f729Sjoerg // Late template parsing can begin.
690*e038c9c4Sjoerg Actions.SetLateTemplateParser(LateTemplateParserCallback, nullptr, this);
6917330f729Sjoerg if (!PP.isIncrementalProcessingEnabled())
6927330f729Sjoerg Actions.ActOnEndOfTranslationUnit();
6937330f729Sjoerg //else don't tell Sema that we ended parsing: more input might come.
6947330f729Sjoerg return true;
6957330f729Sjoerg
6967330f729Sjoerg case tok::identifier:
6977330f729Sjoerg // C++2a [basic.link]p3:
6987330f729Sjoerg // A token sequence beginning with 'export[opt] module' or
6997330f729Sjoerg // 'export[opt] import' and not immediately followed by '::'
7007330f729Sjoerg // is never interpreted as the declaration of a top-level-declaration.
7017330f729Sjoerg if ((Tok.getIdentifierInfo() == Ident_module ||
7027330f729Sjoerg Tok.getIdentifierInfo() == Ident_import) &&
7037330f729Sjoerg NextToken().isNot(tok::coloncolon)) {
7047330f729Sjoerg if (Tok.getIdentifierInfo() == Ident_module)
7057330f729Sjoerg goto module_decl;
7067330f729Sjoerg else
7077330f729Sjoerg goto import_decl;
7087330f729Sjoerg }
7097330f729Sjoerg break;
7107330f729Sjoerg
7117330f729Sjoerg default:
7127330f729Sjoerg break;
7137330f729Sjoerg }
7147330f729Sjoerg
7157330f729Sjoerg ParsedAttributesWithRange attrs(AttrFactory);
7167330f729Sjoerg MaybeParseCXX11Attributes(attrs);
7177330f729Sjoerg
7187330f729Sjoerg Result = ParseExternalDeclaration(attrs);
7197330f729Sjoerg return false;
7207330f729Sjoerg }
7217330f729Sjoerg
7227330f729Sjoerg /// ParseExternalDeclaration:
7237330f729Sjoerg ///
7247330f729Sjoerg /// external-declaration: [C99 6.9], declaration: [C++ dcl.dcl]
7257330f729Sjoerg /// function-definition
7267330f729Sjoerg /// declaration
7277330f729Sjoerg /// [GNU] asm-definition
7287330f729Sjoerg /// [GNU] __extension__ external-declaration
7297330f729Sjoerg /// [OBJC] objc-class-definition
7307330f729Sjoerg /// [OBJC] objc-class-declaration
7317330f729Sjoerg /// [OBJC] objc-alias-declaration
7327330f729Sjoerg /// [OBJC] objc-protocol-definition
7337330f729Sjoerg /// [OBJC] objc-method-definition
7347330f729Sjoerg /// [OBJC] @end
7357330f729Sjoerg /// [C++] linkage-specification
7367330f729Sjoerg /// [GNU] asm-definition:
7377330f729Sjoerg /// simple-asm-expr ';'
7387330f729Sjoerg /// [C++11] empty-declaration
7397330f729Sjoerg /// [C++11] attribute-declaration
7407330f729Sjoerg ///
7417330f729Sjoerg /// [C++11] empty-declaration:
7427330f729Sjoerg /// ';'
7437330f729Sjoerg ///
7447330f729Sjoerg /// [C++0x/GNU] 'extern' 'template' declaration
7457330f729Sjoerg ///
7467330f729Sjoerg /// [Modules-TS] module-import-declaration
7477330f729Sjoerg ///
7487330f729Sjoerg Parser::DeclGroupPtrTy
ParseExternalDeclaration(ParsedAttributesWithRange & attrs,ParsingDeclSpec * DS)7497330f729Sjoerg Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
7507330f729Sjoerg ParsingDeclSpec *DS) {
751*e038c9c4Sjoerg DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
7527330f729Sjoerg ParenBraceBracketBalancer BalancerRAIIObj(*this);
7537330f729Sjoerg
7547330f729Sjoerg if (PP.isCodeCompletionReached()) {
7557330f729Sjoerg cutOffParsing();
7567330f729Sjoerg return nullptr;
7577330f729Sjoerg }
7587330f729Sjoerg
7597330f729Sjoerg Decl *SingleDecl = nullptr;
7607330f729Sjoerg switch (Tok.getKind()) {
7617330f729Sjoerg case tok::annot_pragma_vis:
7627330f729Sjoerg HandlePragmaVisibility();
7637330f729Sjoerg return nullptr;
7647330f729Sjoerg case tok::annot_pragma_pack:
7657330f729Sjoerg HandlePragmaPack();
7667330f729Sjoerg return nullptr;
7677330f729Sjoerg case tok::annot_pragma_msstruct:
7687330f729Sjoerg HandlePragmaMSStruct();
7697330f729Sjoerg return nullptr;
7707330f729Sjoerg case tok::annot_pragma_align:
7717330f729Sjoerg HandlePragmaAlign();
7727330f729Sjoerg return nullptr;
7737330f729Sjoerg case tok::annot_pragma_weak:
7747330f729Sjoerg HandlePragmaWeak();
7757330f729Sjoerg return nullptr;
7767330f729Sjoerg case tok::annot_pragma_weakalias:
7777330f729Sjoerg HandlePragmaWeakAlias();
7787330f729Sjoerg return nullptr;
7797330f729Sjoerg case tok::annot_pragma_redefine_extname:
7807330f729Sjoerg HandlePragmaRedefineExtname();
7817330f729Sjoerg return nullptr;
7827330f729Sjoerg case tok::annot_pragma_fp_contract:
7837330f729Sjoerg HandlePragmaFPContract();
7847330f729Sjoerg return nullptr;
7857330f729Sjoerg case tok::annot_pragma_fenv_access:
7867330f729Sjoerg HandlePragmaFEnvAccess();
7877330f729Sjoerg return nullptr;
788*e038c9c4Sjoerg case tok::annot_pragma_fenv_round:
789*e038c9c4Sjoerg HandlePragmaFEnvRound();
790*e038c9c4Sjoerg return nullptr;
791*e038c9c4Sjoerg case tok::annot_pragma_float_control:
792*e038c9c4Sjoerg HandlePragmaFloatControl();
793*e038c9c4Sjoerg return nullptr;
7947330f729Sjoerg case tok::annot_pragma_fp:
7957330f729Sjoerg HandlePragmaFP();
7967330f729Sjoerg break;
7977330f729Sjoerg case tok::annot_pragma_opencl_extension:
7987330f729Sjoerg HandlePragmaOpenCLExtension();
7997330f729Sjoerg return nullptr;
8007330f729Sjoerg case tok::annot_pragma_openmp: {
8017330f729Sjoerg AccessSpecifier AS = AS_none;
8027330f729Sjoerg return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, attrs);
8037330f729Sjoerg }
8047330f729Sjoerg case tok::annot_pragma_ms_pointers_to_members:
8057330f729Sjoerg HandlePragmaMSPointersToMembers();
8067330f729Sjoerg return nullptr;
8077330f729Sjoerg case tok::annot_pragma_ms_vtordisp:
8087330f729Sjoerg HandlePragmaMSVtorDisp();
8097330f729Sjoerg return nullptr;
8107330f729Sjoerg case tok::annot_pragma_ms_pragma:
8117330f729Sjoerg HandlePragmaMSPragma();
8127330f729Sjoerg return nullptr;
8137330f729Sjoerg case tok::annot_pragma_dump:
8147330f729Sjoerg HandlePragmaDump();
8157330f729Sjoerg return nullptr;
8167330f729Sjoerg case tok::annot_pragma_attribute:
8177330f729Sjoerg HandlePragmaAttribute();
8187330f729Sjoerg return nullptr;
8197330f729Sjoerg case tok::semi:
8207330f729Sjoerg // Either a C++11 empty-declaration or attribute-declaration.
8217330f729Sjoerg SingleDecl =
8227330f729Sjoerg Actions.ActOnEmptyDeclaration(getCurScope(), attrs, Tok.getLocation());
8237330f729Sjoerg ConsumeExtraSemi(OutsideFunction);
8247330f729Sjoerg break;
8257330f729Sjoerg case tok::r_brace:
8267330f729Sjoerg Diag(Tok, diag::err_extraneous_closing_brace);
8277330f729Sjoerg ConsumeBrace();
8287330f729Sjoerg return nullptr;
8297330f729Sjoerg case tok::eof:
8307330f729Sjoerg Diag(Tok, diag::err_expected_external_declaration);
8317330f729Sjoerg return nullptr;
8327330f729Sjoerg case tok::kw___extension__: {
8337330f729Sjoerg // __extension__ silences extension warnings in the subexpression.
8347330f729Sjoerg ExtensionRAIIObject O(Diags); // Use RAII to do this.
8357330f729Sjoerg ConsumeToken();
8367330f729Sjoerg return ParseExternalDeclaration(attrs);
8377330f729Sjoerg }
8387330f729Sjoerg case tok::kw_asm: {
8397330f729Sjoerg ProhibitAttributes(attrs);
8407330f729Sjoerg
8417330f729Sjoerg SourceLocation StartLoc = Tok.getLocation();
8427330f729Sjoerg SourceLocation EndLoc;
8437330f729Sjoerg
844*e038c9c4Sjoerg ExprResult Result(ParseSimpleAsm(/*ForAsmLabel*/ false, &EndLoc));
8457330f729Sjoerg
8467330f729Sjoerg // Check if GNU-style InlineAsm is disabled.
8477330f729Sjoerg // Empty asm string is allowed because it will not introduce
8487330f729Sjoerg // any assembly code.
8497330f729Sjoerg if (!(getLangOpts().GNUAsm || Result.isInvalid())) {
8507330f729Sjoerg const auto *SL = cast<StringLiteral>(Result.get());
8517330f729Sjoerg if (!SL->getString().trim().empty())
8527330f729Sjoerg Diag(StartLoc, diag::err_gnu_inline_asm_disabled);
8537330f729Sjoerg }
8547330f729Sjoerg
8557330f729Sjoerg ExpectAndConsume(tok::semi, diag::err_expected_after,
8567330f729Sjoerg "top-level asm block");
8577330f729Sjoerg
8587330f729Sjoerg if (Result.isInvalid())
8597330f729Sjoerg return nullptr;
8607330f729Sjoerg SingleDecl = Actions.ActOnFileScopeAsmDecl(Result.get(), StartLoc, EndLoc);
8617330f729Sjoerg break;
8627330f729Sjoerg }
8637330f729Sjoerg case tok::at:
8647330f729Sjoerg return ParseObjCAtDirectives(attrs);
8657330f729Sjoerg case tok::minus:
8667330f729Sjoerg case tok::plus:
8677330f729Sjoerg if (!getLangOpts().ObjC) {
8687330f729Sjoerg Diag(Tok, diag::err_expected_external_declaration);
8697330f729Sjoerg ConsumeToken();
8707330f729Sjoerg return nullptr;
8717330f729Sjoerg }
8727330f729Sjoerg SingleDecl = ParseObjCMethodDefinition();
8737330f729Sjoerg break;
8747330f729Sjoerg case tok::code_completion:
875*e038c9c4Sjoerg cutOffParsing();
8767330f729Sjoerg if (CurParsedObjCImpl) {
8777330f729Sjoerg // Code-complete Objective-C methods even without leading '-'/'+' prefix.
8787330f729Sjoerg Actions.CodeCompleteObjCMethodDecl(getCurScope(),
8797330f729Sjoerg /*IsInstanceMethod=*/None,
8807330f729Sjoerg /*ReturnType=*/nullptr);
8817330f729Sjoerg }
8827330f729Sjoerg Actions.CodeCompleteOrdinaryName(
8837330f729Sjoerg getCurScope(),
8847330f729Sjoerg CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
8857330f729Sjoerg return nullptr;
8867330f729Sjoerg case tok::kw_import:
8877330f729Sjoerg SingleDecl = ParseModuleImport(SourceLocation());
8887330f729Sjoerg break;
8897330f729Sjoerg case tok::kw_export:
8907330f729Sjoerg if (getLangOpts().CPlusPlusModules || getLangOpts().ModulesTS) {
8917330f729Sjoerg SingleDecl = ParseExportDeclaration();
8927330f729Sjoerg break;
8937330f729Sjoerg }
8947330f729Sjoerg // This must be 'export template'. Parse it so we can diagnose our lack
8957330f729Sjoerg // of support.
8967330f729Sjoerg LLVM_FALLTHROUGH;
8977330f729Sjoerg case tok::kw_using:
8987330f729Sjoerg case tok::kw_namespace:
8997330f729Sjoerg case tok::kw_typedef:
9007330f729Sjoerg case tok::kw_template:
9017330f729Sjoerg case tok::kw_static_assert:
9027330f729Sjoerg case tok::kw__Static_assert:
9037330f729Sjoerg // A function definition cannot start with any of these keywords.
9047330f729Sjoerg {
9057330f729Sjoerg SourceLocation DeclEnd;
906*e038c9c4Sjoerg return ParseDeclaration(DeclaratorContext::File, DeclEnd, attrs);
9077330f729Sjoerg }
9087330f729Sjoerg
9097330f729Sjoerg case tok::kw_static:
9107330f729Sjoerg // Parse (then ignore) 'static' prior to a template instantiation. This is
9117330f729Sjoerg // a GCC extension that we intentionally do not support.
9127330f729Sjoerg if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) {
9137330f729Sjoerg Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
9147330f729Sjoerg << 0;
9157330f729Sjoerg SourceLocation DeclEnd;
916*e038c9c4Sjoerg return ParseDeclaration(DeclaratorContext::File, DeclEnd, attrs);
9177330f729Sjoerg }
9187330f729Sjoerg goto dont_know;
9197330f729Sjoerg
9207330f729Sjoerg case tok::kw_inline:
9217330f729Sjoerg if (getLangOpts().CPlusPlus) {
9227330f729Sjoerg tok::TokenKind NextKind = NextToken().getKind();
9237330f729Sjoerg
9247330f729Sjoerg // Inline namespaces. Allowed as an extension even in C++03.
9257330f729Sjoerg if (NextKind == tok::kw_namespace) {
9267330f729Sjoerg SourceLocation DeclEnd;
927*e038c9c4Sjoerg return ParseDeclaration(DeclaratorContext::File, DeclEnd, attrs);
9287330f729Sjoerg }
9297330f729Sjoerg
9307330f729Sjoerg // Parse (then ignore) 'inline' prior to a template instantiation. This is
9317330f729Sjoerg // a GCC extension that we intentionally do not support.
9327330f729Sjoerg if (NextKind == tok::kw_template) {
9337330f729Sjoerg Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
9347330f729Sjoerg << 1;
9357330f729Sjoerg SourceLocation DeclEnd;
936*e038c9c4Sjoerg return ParseDeclaration(DeclaratorContext::File, DeclEnd, attrs);
9377330f729Sjoerg }
9387330f729Sjoerg }
9397330f729Sjoerg goto dont_know;
9407330f729Sjoerg
9417330f729Sjoerg case tok::kw_extern:
9427330f729Sjoerg if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) {
9437330f729Sjoerg // Extern templates
9447330f729Sjoerg SourceLocation ExternLoc = ConsumeToken();
9457330f729Sjoerg SourceLocation TemplateLoc = ConsumeToken();
9467330f729Sjoerg Diag(ExternLoc, getLangOpts().CPlusPlus11 ?
9477330f729Sjoerg diag::warn_cxx98_compat_extern_template :
9487330f729Sjoerg diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
9497330f729Sjoerg SourceLocation DeclEnd;
950*e038c9c4Sjoerg return Actions.ConvertDeclToDeclGroup(ParseExplicitInstantiation(
951*e038c9c4Sjoerg DeclaratorContext::File, ExternLoc, TemplateLoc, DeclEnd, attrs));
9527330f729Sjoerg }
9537330f729Sjoerg goto dont_know;
9547330f729Sjoerg
9557330f729Sjoerg case tok::kw___if_exists:
9567330f729Sjoerg case tok::kw___if_not_exists:
9577330f729Sjoerg ParseMicrosoftIfExistsExternalDeclaration();
9587330f729Sjoerg return nullptr;
9597330f729Sjoerg
9607330f729Sjoerg case tok::kw_module:
9617330f729Sjoerg Diag(Tok, diag::err_unexpected_module_decl);
9627330f729Sjoerg SkipUntil(tok::semi);
9637330f729Sjoerg return nullptr;
9647330f729Sjoerg
9657330f729Sjoerg default:
9667330f729Sjoerg dont_know:
9677330f729Sjoerg if (Tok.isEditorPlaceholder()) {
9687330f729Sjoerg ConsumeToken();
9697330f729Sjoerg return nullptr;
9707330f729Sjoerg }
9717330f729Sjoerg // We can't tell whether this is a function-definition or declaration yet.
9727330f729Sjoerg return ParseDeclarationOrFunctionDefinition(attrs, DS);
9737330f729Sjoerg }
9747330f729Sjoerg
9757330f729Sjoerg // This routine returns a DeclGroup, if the thing we parsed only contains a
9767330f729Sjoerg // single decl, convert it now.
9777330f729Sjoerg return Actions.ConvertDeclToDeclGroup(SingleDecl);
9787330f729Sjoerg }
9797330f729Sjoerg
9807330f729Sjoerg /// Determine whether the current token, if it occurs after a
9817330f729Sjoerg /// declarator, continues a declaration or declaration list.
isDeclarationAfterDeclarator()9827330f729Sjoerg bool Parser::isDeclarationAfterDeclarator() {
9837330f729Sjoerg // Check for '= delete' or '= default'
9847330f729Sjoerg if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) {
9857330f729Sjoerg const Token &KW = NextToken();
9867330f729Sjoerg if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
9877330f729Sjoerg return false;
9887330f729Sjoerg }
9897330f729Sjoerg
9907330f729Sjoerg return Tok.is(tok::equal) || // int X()= -> not a function def
9917330f729Sjoerg Tok.is(tok::comma) || // int X(), -> not a function def
9927330f729Sjoerg Tok.is(tok::semi) || // int X(); -> not a function def
9937330f729Sjoerg Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def
9947330f729Sjoerg Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
9957330f729Sjoerg (getLangOpts().CPlusPlus &&
9967330f729Sjoerg Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++]
9977330f729Sjoerg }
9987330f729Sjoerg
9997330f729Sjoerg /// Determine whether the current token, if it occurs after a
10007330f729Sjoerg /// declarator, indicates the start of a function definition.
isStartOfFunctionDefinition(const ParsingDeclarator & Declarator)10017330f729Sjoerg bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
10027330f729Sjoerg assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator");
10037330f729Sjoerg if (Tok.is(tok::l_brace)) // int X() {}
10047330f729Sjoerg return true;
10057330f729Sjoerg
10067330f729Sjoerg // Handle K&R C argument lists: int X(f) int f; {}
10077330f729Sjoerg if (!getLangOpts().CPlusPlus &&
10087330f729Sjoerg Declarator.getFunctionTypeInfo().isKNRPrototype())
10097330f729Sjoerg return isDeclarationSpecifier();
10107330f729Sjoerg
10117330f729Sjoerg if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) {
10127330f729Sjoerg const Token &KW = NextToken();
10137330f729Sjoerg return KW.is(tok::kw_default) || KW.is(tok::kw_delete);
10147330f729Sjoerg }
10157330f729Sjoerg
10167330f729Sjoerg return Tok.is(tok::colon) || // X() : Base() {} (used for ctors)
10177330f729Sjoerg Tok.is(tok::kw_try); // X() try { ... }
10187330f729Sjoerg }
10197330f729Sjoerg
10207330f729Sjoerg /// Parse either a function-definition or a declaration. We can't tell which
10217330f729Sjoerg /// we have until we read up to the compound-statement in function-definition.
10227330f729Sjoerg /// TemplateParams, if non-NULL, provides the template parameters when we're
10237330f729Sjoerg /// parsing a C++ template-declaration.
10247330f729Sjoerg ///
10257330f729Sjoerg /// function-definition: [C99 6.9.1]
10267330f729Sjoerg /// decl-specs declarator declaration-list[opt] compound-statement
10277330f729Sjoerg /// [C90] function-definition: [C99 6.7.1] - implicit int result
10287330f729Sjoerg /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
10297330f729Sjoerg ///
10307330f729Sjoerg /// declaration: [C99 6.7]
10317330f729Sjoerg /// declaration-specifiers init-declarator-list[opt] ';'
10327330f729Sjoerg /// [!C99] init-declarator-list ';' [TODO: warn in c99 mode]
10337330f729Sjoerg /// [OMP] threadprivate-directive
10347330f729Sjoerg /// [OMP] allocate-directive [TODO]
10357330f729Sjoerg ///
10367330f729Sjoerg Parser::DeclGroupPtrTy
ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange & attrs,ParsingDeclSpec & DS,AccessSpecifier AS)10377330f729Sjoerg Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
10387330f729Sjoerg ParsingDeclSpec &DS,
10397330f729Sjoerg AccessSpecifier AS) {
10407330f729Sjoerg MaybeParseMicrosoftAttributes(DS.getAttributes());
10417330f729Sjoerg // Parse the common declaration-specifiers piece.
10427330f729Sjoerg ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS,
10437330f729Sjoerg DeclSpecContext::DSC_top_level);
10447330f729Sjoerg
10457330f729Sjoerg // If we had a free-standing type definition with a missing semicolon, we
10467330f729Sjoerg // may get this far before the problem becomes obvious.
10477330f729Sjoerg if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition(
10487330f729Sjoerg DS, AS, DeclSpecContext::DSC_top_level))
10497330f729Sjoerg return nullptr;
10507330f729Sjoerg
10517330f729Sjoerg // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
10527330f729Sjoerg // declaration-specifiers init-declarator-list[opt] ';'
10537330f729Sjoerg if (Tok.is(tok::semi)) {
10547330f729Sjoerg auto LengthOfTSTToken = [](DeclSpec::TST TKind) {
10557330f729Sjoerg assert(DeclSpec::isDeclRep(TKind));
10567330f729Sjoerg switch(TKind) {
10577330f729Sjoerg case DeclSpec::TST_class:
10587330f729Sjoerg return 5;
10597330f729Sjoerg case DeclSpec::TST_struct:
10607330f729Sjoerg return 6;
10617330f729Sjoerg case DeclSpec::TST_union:
10627330f729Sjoerg return 5;
10637330f729Sjoerg case DeclSpec::TST_enum:
10647330f729Sjoerg return 4;
10657330f729Sjoerg case DeclSpec::TST_interface:
10667330f729Sjoerg return 9;
10677330f729Sjoerg default:
10687330f729Sjoerg llvm_unreachable("we only expect to get the length of the class/struct/union/enum");
10697330f729Sjoerg }
10707330f729Sjoerg
10717330f729Sjoerg };
10727330f729Sjoerg // Suggest correct location to fix '[[attrib]] struct' to 'struct [[attrib]]'
10737330f729Sjoerg SourceLocation CorrectLocationForAttributes =
10747330f729Sjoerg DeclSpec::isDeclRep(DS.getTypeSpecType())
10757330f729Sjoerg ? DS.getTypeSpecTypeLoc().getLocWithOffset(
10767330f729Sjoerg LengthOfTSTToken(DS.getTypeSpecType()))
10777330f729Sjoerg : SourceLocation();
10787330f729Sjoerg ProhibitAttributes(attrs, CorrectLocationForAttributes);
10797330f729Sjoerg ConsumeToken();
10807330f729Sjoerg RecordDecl *AnonRecord = nullptr;
10817330f729Sjoerg Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
10827330f729Sjoerg DS, AnonRecord);
10837330f729Sjoerg DS.complete(TheDecl);
10847330f729Sjoerg if (AnonRecord) {
10857330f729Sjoerg Decl* decls[] = {AnonRecord, TheDecl};
10867330f729Sjoerg return Actions.BuildDeclaratorGroup(decls);
10877330f729Sjoerg }
10887330f729Sjoerg return Actions.ConvertDeclToDeclGroup(TheDecl);
10897330f729Sjoerg }
10907330f729Sjoerg
10917330f729Sjoerg DS.takeAttributesFrom(attrs);
10927330f729Sjoerg
10937330f729Sjoerg // ObjC2 allows prefix attributes on class interfaces and protocols.
10947330f729Sjoerg // FIXME: This still needs better diagnostics. We should only accept
10957330f729Sjoerg // attributes here, no types, etc.
10967330f729Sjoerg if (getLangOpts().ObjC && Tok.is(tok::at)) {
10977330f729Sjoerg SourceLocation AtLoc = ConsumeToken(); // the "@"
10987330f729Sjoerg if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
10997330f729Sjoerg !Tok.isObjCAtKeyword(tok::objc_protocol) &&
11007330f729Sjoerg !Tok.isObjCAtKeyword(tok::objc_implementation)) {
11017330f729Sjoerg Diag(Tok, diag::err_objc_unexpected_attr);
11027330f729Sjoerg SkipUntil(tok::semi);
11037330f729Sjoerg return nullptr;
11047330f729Sjoerg }
11057330f729Sjoerg
11067330f729Sjoerg DS.abort();
11077330f729Sjoerg
11087330f729Sjoerg const char *PrevSpec = nullptr;
11097330f729Sjoerg unsigned DiagID;
11107330f729Sjoerg if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID,
11117330f729Sjoerg Actions.getASTContext().getPrintingPolicy()))
11127330f729Sjoerg Diag(AtLoc, DiagID) << PrevSpec;
11137330f729Sjoerg
11147330f729Sjoerg if (Tok.isObjCAtKeyword(tok::objc_protocol))
11157330f729Sjoerg return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
11167330f729Sjoerg
11177330f729Sjoerg if (Tok.isObjCAtKeyword(tok::objc_implementation))
11187330f729Sjoerg return ParseObjCAtImplementationDeclaration(AtLoc, DS.getAttributes());
11197330f729Sjoerg
11207330f729Sjoerg return Actions.ConvertDeclToDeclGroup(
11217330f729Sjoerg ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes()));
11227330f729Sjoerg }
11237330f729Sjoerg
11247330f729Sjoerg // If the declspec consisted only of 'extern' and we have a string
11257330f729Sjoerg // literal following it, this must be a C++ linkage specifier like
11267330f729Sjoerg // 'extern "C"'.
11277330f729Sjoerg if (getLangOpts().CPlusPlus && isTokenStringLiteral() &&
11287330f729Sjoerg DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
11297330f729Sjoerg DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
1130*e038c9c4Sjoerg Decl *TheDecl = ParseLinkage(DS, DeclaratorContext::File);
11317330f729Sjoerg return Actions.ConvertDeclToDeclGroup(TheDecl);
11327330f729Sjoerg }
11337330f729Sjoerg
1134*e038c9c4Sjoerg return ParseDeclGroup(DS, DeclaratorContext::File);
11357330f729Sjoerg }
11367330f729Sjoerg
11377330f729Sjoerg Parser::DeclGroupPtrTy
ParseDeclarationOrFunctionDefinition(ParsedAttributesWithRange & attrs,ParsingDeclSpec * DS,AccessSpecifier AS)11387330f729Sjoerg Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributesWithRange &attrs,
11397330f729Sjoerg ParsingDeclSpec *DS,
11407330f729Sjoerg AccessSpecifier AS) {
11417330f729Sjoerg if (DS) {
11427330f729Sjoerg return ParseDeclOrFunctionDefInternal(attrs, *DS, AS);
11437330f729Sjoerg } else {
11447330f729Sjoerg ParsingDeclSpec PDS(*this);
11457330f729Sjoerg // Must temporarily exit the objective-c container scope for
11467330f729Sjoerg // parsing c constructs and re-enter objc container scope
11477330f729Sjoerg // afterwards.
11487330f729Sjoerg ObjCDeclContextSwitch ObjCDC(*this);
11497330f729Sjoerg
11507330f729Sjoerg return ParseDeclOrFunctionDefInternal(attrs, PDS, AS);
11517330f729Sjoerg }
11527330f729Sjoerg }
11537330f729Sjoerg
11547330f729Sjoerg /// ParseFunctionDefinition - We parsed and verified that the specified
11557330f729Sjoerg /// Declarator is well formed. If this is a K&R-style function, read the
11567330f729Sjoerg /// parameters declaration-list, then start the compound-statement.
11577330f729Sjoerg ///
11587330f729Sjoerg /// function-definition: [C99 6.9.1]
11597330f729Sjoerg /// decl-specs declarator declaration-list[opt] compound-statement
11607330f729Sjoerg /// [C90] function-definition: [C99 6.7.1] - implicit int result
11617330f729Sjoerg /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
11627330f729Sjoerg /// [C++] function-definition: [C++ 8.4]
11637330f729Sjoerg /// decl-specifier-seq[opt] declarator ctor-initializer[opt]
11647330f729Sjoerg /// function-body
11657330f729Sjoerg /// [C++] function-definition: [C++ 8.4]
11667330f729Sjoerg /// decl-specifier-seq[opt] declarator function-try-block
11677330f729Sjoerg ///
ParseFunctionDefinition(ParsingDeclarator & D,const ParsedTemplateInfo & TemplateInfo,LateParsedAttrList * LateParsedAttrs)11687330f729Sjoerg Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
11697330f729Sjoerg const ParsedTemplateInfo &TemplateInfo,
11707330f729Sjoerg LateParsedAttrList *LateParsedAttrs) {
11717330f729Sjoerg // Poison SEH identifiers so they are flagged as illegal in function bodies.
11727330f729Sjoerg PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
11737330f729Sjoerg const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
1174*e038c9c4Sjoerg TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
11757330f729Sjoerg
11767330f729Sjoerg // If this is C90 and the declspecs were completely missing, fudge in an
11777330f729Sjoerg // implicit int. We do this here because this is the only place where
11787330f729Sjoerg // declaration-specifiers are completely optional in the grammar.
11797330f729Sjoerg if (getLangOpts().ImplicitInt && D.getDeclSpec().isEmpty()) {
11807330f729Sjoerg const char *PrevSpec;
11817330f729Sjoerg unsigned DiagID;
11827330f729Sjoerg const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
11837330f729Sjoerg D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
11847330f729Sjoerg D.getIdentifierLoc(),
11857330f729Sjoerg PrevSpec, DiagID,
11867330f729Sjoerg Policy);
11877330f729Sjoerg D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin());
11887330f729Sjoerg }
11897330f729Sjoerg
11907330f729Sjoerg // If this declaration was formed with a K&R-style identifier list for the
11917330f729Sjoerg // arguments, parse declarations for all of the args next.
11927330f729Sjoerg // int foo(a,b) int a; float b; {}
11937330f729Sjoerg if (FTI.isKNRPrototype())
11947330f729Sjoerg ParseKNRParamDeclarations(D);
11957330f729Sjoerg
11967330f729Sjoerg // We should have either an opening brace or, in a C++ constructor,
11977330f729Sjoerg // we may have a colon.
11987330f729Sjoerg if (Tok.isNot(tok::l_brace) &&
11997330f729Sjoerg (!getLangOpts().CPlusPlus ||
12007330f729Sjoerg (Tok.isNot(tok::colon) && Tok.isNot(tok::kw_try) &&
12017330f729Sjoerg Tok.isNot(tok::equal)))) {
12027330f729Sjoerg Diag(Tok, diag::err_expected_fn_body);
12037330f729Sjoerg
12047330f729Sjoerg // Skip over garbage, until we get to '{'. Don't eat the '{'.
12057330f729Sjoerg SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
12067330f729Sjoerg
12077330f729Sjoerg // If we didn't find the '{', bail out.
12087330f729Sjoerg if (Tok.isNot(tok::l_brace))
12097330f729Sjoerg return nullptr;
12107330f729Sjoerg }
12117330f729Sjoerg
12127330f729Sjoerg // Check to make sure that any normal attributes are allowed to be on
12137330f729Sjoerg // a definition. Late parsed attributes are checked at the end.
12147330f729Sjoerg if (Tok.isNot(tok::equal)) {
12157330f729Sjoerg for (const ParsedAttr &AL : D.getAttributes())
12167330f729Sjoerg if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
12177330f729Sjoerg Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) << AL;
12187330f729Sjoerg }
12197330f729Sjoerg
12207330f729Sjoerg // In delayed template parsing mode, for function template we consume the
12217330f729Sjoerg // tokens and store them for late parsing at the end of the translation unit.
12227330f729Sjoerg if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) &&
12237330f729Sjoerg TemplateInfo.Kind == ParsedTemplateInfo::Template &&
12247330f729Sjoerg Actions.canDelayFunctionBody(D)) {
12257330f729Sjoerg MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams);
12267330f729Sjoerg
12277330f729Sjoerg ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
12287330f729Sjoerg Scope::CompoundStmtScope);
12297330f729Sjoerg Scope *ParentScope = getCurScope()->getParent();
12307330f729Sjoerg
1231*e038c9c4Sjoerg D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
12327330f729Sjoerg Decl *DP = Actions.HandleDeclarator(ParentScope, D,
12337330f729Sjoerg TemplateParameterLists);
12347330f729Sjoerg D.complete(DP);
12357330f729Sjoerg D.getMutableDeclSpec().abort();
12367330f729Sjoerg
12377330f729Sjoerg if (SkipFunctionBodies && (!DP || Actions.canSkipFunctionBody(DP)) &&
12387330f729Sjoerg trySkippingFunctionBody()) {
12397330f729Sjoerg BodyScope.Exit();
12407330f729Sjoerg return Actions.ActOnSkippedFunctionBody(DP);
12417330f729Sjoerg }
12427330f729Sjoerg
12437330f729Sjoerg CachedTokens Toks;
12447330f729Sjoerg LexTemplateFunctionForLateParsing(Toks);
12457330f729Sjoerg
12467330f729Sjoerg if (DP) {
12477330f729Sjoerg FunctionDecl *FnD = DP->getAsFunction();
12487330f729Sjoerg Actions.CheckForFunctionRedefinition(FnD);
12497330f729Sjoerg Actions.MarkAsLateParsedTemplate(FnD, DP, Toks);
12507330f729Sjoerg }
12517330f729Sjoerg return DP;
12527330f729Sjoerg }
12537330f729Sjoerg else if (CurParsedObjCImpl &&
12547330f729Sjoerg !TemplateInfo.TemplateParams &&
12557330f729Sjoerg (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
12567330f729Sjoerg Tok.is(tok::colon)) &&
12577330f729Sjoerg Actions.CurContext->isTranslationUnit()) {
12587330f729Sjoerg ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
12597330f729Sjoerg Scope::CompoundStmtScope);
12607330f729Sjoerg Scope *ParentScope = getCurScope()->getParent();
12617330f729Sjoerg
1262*e038c9c4Sjoerg D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
12637330f729Sjoerg Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D,
12647330f729Sjoerg MultiTemplateParamsArg());
12657330f729Sjoerg D.complete(FuncDecl);
12667330f729Sjoerg D.getMutableDeclSpec().abort();
12677330f729Sjoerg if (FuncDecl) {
12687330f729Sjoerg // Consume the tokens and store them for later parsing.
12697330f729Sjoerg StashAwayMethodOrFunctionBodyTokens(FuncDecl);
12707330f729Sjoerg CurParsedObjCImpl->HasCFunction = true;
12717330f729Sjoerg return FuncDecl;
12727330f729Sjoerg }
12737330f729Sjoerg // FIXME: Should we really fall through here?
12747330f729Sjoerg }
12757330f729Sjoerg
12767330f729Sjoerg // Enter a scope for the function body.
12777330f729Sjoerg ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
12787330f729Sjoerg Scope::CompoundStmtScope);
12797330f729Sjoerg
12807330f729Sjoerg // Tell the actions module that we have entered a function definition with the
12817330f729Sjoerg // specified Declarator for the function.
12827330f729Sjoerg Sema::SkipBodyInfo SkipBody;
12837330f729Sjoerg Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
12847330f729Sjoerg TemplateInfo.TemplateParams
12857330f729Sjoerg ? *TemplateInfo.TemplateParams
12867330f729Sjoerg : MultiTemplateParamsArg(),
12877330f729Sjoerg &SkipBody);
12887330f729Sjoerg
12897330f729Sjoerg if (SkipBody.ShouldSkip) {
12907330f729Sjoerg SkipFunctionBody();
12917330f729Sjoerg return Res;
12927330f729Sjoerg }
12937330f729Sjoerg
12947330f729Sjoerg // Break out of the ParsingDeclarator context before we parse the body.
12957330f729Sjoerg D.complete(Res);
12967330f729Sjoerg
12977330f729Sjoerg // Break out of the ParsingDeclSpec context, too. This const_cast is
12987330f729Sjoerg // safe because we're always the sole owner.
12997330f729Sjoerg D.getMutableDeclSpec().abort();
13007330f729Sjoerg
1301*e038c9c4Sjoerg // With abbreviated function templates - we need to explicitly add depth to
1302*e038c9c4Sjoerg // account for the implicit template parameter list induced by the template.
1303*e038c9c4Sjoerg if (auto *Template = dyn_cast_or_null<FunctionTemplateDecl>(Res))
1304*e038c9c4Sjoerg if (Template->isAbbreviated() &&
1305*e038c9c4Sjoerg Template->getTemplateParameters()->getParam(0)->isImplicit())
1306*e038c9c4Sjoerg // First template parameter is implicit - meaning no explicit template
1307*e038c9c4Sjoerg // parameter list was specified.
1308*e038c9c4Sjoerg CurTemplateDepthTracker.addDepth(1);
1309*e038c9c4Sjoerg
13107330f729Sjoerg if (TryConsumeToken(tok::equal)) {
13117330f729Sjoerg assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
13127330f729Sjoerg
13137330f729Sjoerg bool Delete = false;
13147330f729Sjoerg SourceLocation KWLoc;
13157330f729Sjoerg if (TryConsumeToken(tok::kw_delete, KWLoc)) {
13167330f729Sjoerg Diag(KWLoc, getLangOpts().CPlusPlus11
13177330f729Sjoerg ? diag::warn_cxx98_compat_defaulted_deleted_function
13187330f729Sjoerg : diag::ext_defaulted_deleted_function)
13197330f729Sjoerg << 1 /* deleted */;
13207330f729Sjoerg Actions.SetDeclDeleted(Res, KWLoc);
13217330f729Sjoerg Delete = true;
13227330f729Sjoerg } else if (TryConsumeToken(tok::kw_default, KWLoc)) {
13237330f729Sjoerg Diag(KWLoc, getLangOpts().CPlusPlus11
13247330f729Sjoerg ? diag::warn_cxx98_compat_defaulted_deleted_function
13257330f729Sjoerg : diag::ext_defaulted_deleted_function)
13267330f729Sjoerg << 0 /* defaulted */;
13277330f729Sjoerg Actions.SetDeclDefaulted(Res, KWLoc);
13287330f729Sjoerg } else {
13297330f729Sjoerg llvm_unreachable("function definition after = not 'delete' or 'default'");
13307330f729Sjoerg }
13317330f729Sjoerg
13327330f729Sjoerg if (Tok.is(tok::comma)) {
13337330f729Sjoerg Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
13347330f729Sjoerg << Delete;
13357330f729Sjoerg SkipUntil(tok::semi);
13367330f729Sjoerg } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
13377330f729Sjoerg Delete ? "delete" : "default")) {
13387330f729Sjoerg SkipUntil(tok::semi);
13397330f729Sjoerg }
13407330f729Sjoerg
13417330f729Sjoerg Stmt *GeneratedBody = Res ? Res->getBody() : nullptr;
13427330f729Sjoerg Actions.ActOnFinishFunctionBody(Res, GeneratedBody, false);
13437330f729Sjoerg return Res;
13447330f729Sjoerg }
13457330f729Sjoerg
13467330f729Sjoerg if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) &&
13477330f729Sjoerg trySkippingFunctionBody()) {
13487330f729Sjoerg BodyScope.Exit();
13497330f729Sjoerg Actions.ActOnSkippedFunctionBody(Res);
13507330f729Sjoerg return Actions.ActOnFinishFunctionBody(Res, nullptr, false);
13517330f729Sjoerg }
13527330f729Sjoerg
13537330f729Sjoerg if (Tok.is(tok::kw_try))
13547330f729Sjoerg return ParseFunctionTryBlock(Res, BodyScope);
13557330f729Sjoerg
13567330f729Sjoerg // If we have a colon, then we're probably parsing a C++
13577330f729Sjoerg // ctor-initializer.
13587330f729Sjoerg if (Tok.is(tok::colon)) {
13597330f729Sjoerg ParseConstructorInitializer(Res);
13607330f729Sjoerg
13617330f729Sjoerg // Recover from error.
13627330f729Sjoerg if (!Tok.is(tok::l_brace)) {
13637330f729Sjoerg BodyScope.Exit();
13647330f729Sjoerg Actions.ActOnFinishFunctionBody(Res, nullptr);
13657330f729Sjoerg return Res;
13667330f729Sjoerg }
13677330f729Sjoerg } else
13687330f729Sjoerg Actions.ActOnDefaultCtorInitializers(Res);
13697330f729Sjoerg
13707330f729Sjoerg // Late attributes are parsed in the same scope as the function body.
13717330f729Sjoerg if (LateParsedAttrs)
13727330f729Sjoerg ParseLexedAttributeList(*LateParsedAttrs, Res, false, true);
13737330f729Sjoerg
13747330f729Sjoerg return ParseFunctionStatementBody(Res, BodyScope);
13757330f729Sjoerg }
13767330f729Sjoerg
SkipFunctionBody()13777330f729Sjoerg void Parser::SkipFunctionBody() {
13787330f729Sjoerg if (Tok.is(tok::equal)) {
13797330f729Sjoerg SkipUntil(tok::semi);
13807330f729Sjoerg return;
13817330f729Sjoerg }
13827330f729Sjoerg
13837330f729Sjoerg bool IsFunctionTryBlock = Tok.is(tok::kw_try);
13847330f729Sjoerg if (IsFunctionTryBlock)
13857330f729Sjoerg ConsumeToken();
13867330f729Sjoerg
13877330f729Sjoerg CachedTokens Skipped;
13887330f729Sjoerg if (ConsumeAndStoreFunctionPrologue(Skipped))
13897330f729Sjoerg SkipMalformedDecl();
13907330f729Sjoerg else {
13917330f729Sjoerg SkipUntil(tok::r_brace);
13927330f729Sjoerg while (IsFunctionTryBlock && Tok.is(tok::kw_catch)) {
13937330f729Sjoerg SkipUntil(tok::l_brace);
13947330f729Sjoerg SkipUntil(tok::r_brace);
13957330f729Sjoerg }
13967330f729Sjoerg }
13977330f729Sjoerg }
13987330f729Sjoerg
13997330f729Sjoerg /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
14007330f729Sjoerg /// types for a function with a K&R-style identifier list for arguments.
ParseKNRParamDeclarations(Declarator & D)14017330f729Sjoerg void Parser::ParseKNRParamDeclarations(Declarator &D) {
14027330f729Sjoerg // We know that the top-level of this declarator is a function.
14037330f729Sjoerg DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
14047330f729Sjoerg
14057330f729Sjoerg // Enter function-declaration scope, limiting any declarators to the
14067330f729Sjoerg // function prototype scope, including parameter declarators.
14077330f729Sjoerg ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
14087330f729Sjoerg Scope::FunctionDeclarationScope | Scope::DeclScope);
14097330f729Sjoerg
14107330f729Sjoerg // Read all the argument declarations.
14117330f729Sjoerg while (isDeclarationSpecifier()) {
14127330f729Sjoerg SourceLocation DSStart = Tok.getLocation();
14137330f729Sjoerg
14147330f729Sjoerg // Parse the common declaration-specifiers piece.
14157330f729Sjoerg DeclSpec DS(AttrFactory);
14167330f729Sjoerg ParseDeclarationSpecifiers(DS);
14177330f729Sjoerg
14187330f729Sjoerg // C99 6.9.1p6: 'each declaration in the declaration list shall have at
14197330f729Sjoerg // least one declarator'.
14207330f729Sjoerg // NOTE: GCC just makes this an ext-warn. It's not clear what it does with
14217330f729Sjoerg // the declarations though. It's trivial to ignore them, really hard to do
14227330f729Sjoerg // anything else with them.
14237330f729Sjoerg if (TryConsumeToken(tok::semi)) {
14247330f729Sjoerg Diag(DSStart, diag::err_declaration_does_not_declare_param);
14257330f729Sjoerg continue;
14267330f729Sjoerg }
14277330f729Sjoerg
14287330f729Sjoerg // C99 6.9.1p6: Declarations shall contain no storage-class specifiers other
14297330f729Sjoerg // than register.
14307330f729Sjoerg if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified &&
14317330f729Sjoerg DS.getStorageClassSpec() != DeclSpec::SCS_register) {
14327330f729Sjoerg Diag(DS.getStorageClassSpecLoc(),
14337330f729Sjoerg diag::err_invalid_storage_class_in_func_decl);
14347330f729Sjoerg DS.ClearStorageClassSpecs();
14357330f729Sjoerg }
14367330f729Sjoerg if (DS.getThreadStorageClassSpec() != DeclSpec::TSCS_unspecified) {
14377330f729Sjoerg Diag(DS.getThreadStorageClassSpecLoc(),
14387330f729Sjoerg diag::err_invalid_storage_class_in_func_decl);
14397330f729Sjoerg DS.ClearStorageClassSpecs();
14407330f729Sjoerg }
14417330f729Sjoerg
14427330f729Sjoerg // Parse the first declarator attached to this declspec.
1443*e038c9c4Sjoerg Declarator ParmDeclarator(DS, DeclaratorContext::KNRTypeList);
14447330f729Sjoerg ParseDeclarator(ParmDeclarator);
14457330f729Sjoerg
14467330f729Sjoerg // Handle the full declarator list.
14477330f729Sjoerg while (1) {
14487330f729Sjoerg // If attributes are present, parse them.
14497330f729Sjoerg MaybeParseGNUAttributes(ParmDeclarator);
14507330f729Sjoerg
14517330f729Sjoerg // Ask the actions module to compute the type for this declarator.
14527330f729Sjoerg Decl *Param =
14537330f729Sjoerg Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);
14547330f729Sjoerg
14557330f729Sjoerg if (Param &&
14567330f729Sjoerg // A missing identifier has already been diagnosed.
14577330f729Sjoerg ParmDeclarator.getIdentifier()) {
14587330f729Sjoerg
14597330f729Sjoerg // Scan the argument list looking for the correct param to apply this
14607330f729Sjoerg // type.
14617330f729Sjoerg for (unsigned i = 0; ; ++i) {
14627330f729Sjoerg // C99 6.9.1p6: those declarators shall declare only identifiers from
14637330f729Sjoerg // the identifier list.
14647330f729Sjoerg if (i == FTI.NumParams) {
14657330f729Sjoerg Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param)
14667330f729Sjoerg << ParmDeclarator.getIdentifier();
14677330f729Sjoerg break;
14687330f729Sjoerg }
14697330f729Sjoerg
14707330f729Sjoerg if (FTI.Params[i].Ident == ParmDeclarator.getIdentifier()) {
14717330f729Sjoerg // Reject redefinitions of parameters.
14727330f729Sjoerg if (FTI.Params[i].Param) {
14737330f729Sjoerg Diag(ParmDeclarator.getIdentifierLoc(),
14747330f729Sjoerg diag::err_param_redefinition)
14757330f729Sjoerg << ParmDeclarator.getIdentifier();
14767330f729Sjoerg } else {
14777330f729Sjoerg FTI.Params[i].Param = Param;
14787330f729Sjoerg }
14797330f729Sjoerg break;
14807330f729Sjoerg }
14817330f729Sjoerg }
14827330f729Sjoerg }
14837330f729Sjoerg
14847330f729Sjoerg // If we don't have a comma, it is either the end of the list (a ';') or
14857330f729Sjoerg // an error, bail out.
14867330f729Sjoerg if (Tok.isNot(tok::comma))
14877330f729Sjoerg break;
14887330f729Sjoerg
14897330f729Sjoerg ParmDeclarator.clear();
14907330f729Sjoerg
14917330f729Sjoerg // Consume the comma.
14927330f729Sjoerg ParmDeclarator.setCommaLoc(ConsumeToken());
14937330f729Sjoerg
14947330f729Sjoerg // Parse the next declarator.
14957330f729Sjoerg ParseDeclarator(ParmDeclarator);
14967330f729Sjoerg }
14977330f729Sjoerg
14987330f729Sjoerg // Consume ';' and continue parsing.
14997330f729Sjoerg if (!ExpectAndConsumeSemi(diag::err_expected_semi_declaration))
15007330f729Sjoerg continue;
15017330f729Sjoerg
15027330f729Sjoerg // Otherwise recover by skipping to next semi or mandatory function body.
15037330f729Sjoerg if (SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch))
15047330f729Sjoerg break;
15057330f729Sjoerg TryConsumeToken(tok::semi);
15067330f729Sjoerg }
15077330f729Sjoerg
15087330f729Sjoerg // The actions module must verify that all arguments were declared.
15097330f729Sjoerg Actions.ActOnFinishKNRParamDeclarations(getCurScope(), D, Tok.getLocation());
15107330f729Sjoerg }
15117330f729Sjoerg
15127330f729Sjoerg
15137330f729Sjoerg /// ParseAsmStringLiteral - This is just a normal string-literal, but is not
15147330f729Sjoerg /// allowed to be a wide string, and is not subject to character translation.
1515*e038c9c4Sjoerg /// Unlike GCC, we also diagnose an empty string literal when parsing for an
1516*e038c9c4Sjoerg /// asm label as opposed to an asm statement, because such a construct does not
1517*e038c9c4Sjoerg /// behave well.
15187330f729Sjoerg ///
15197330f729Sjoerg /// [GNU] asm-string-literal:
15207330f729Sjoerg /// string-literal
15217330f729Sjoerg ///
ParseAsmStringLiteral(bool ForAsmLabel)1522*e038c9c4Sjoerg ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {
15237330f729Sjoerg if (!isTokenStringLiteral()) {
15247330f729Sjoerg Diag(Tok, diag::err_expected_string_literal)
15257330f729Sjoerg << /*Source='in...'*/0 << "'asm'";
15267330f729Sjoerg return ExprError();
15277330f729Sjoerg }
15287330f729Sjoerg
15297330f729Sjoerg ExprResult AsmString(ParseStringLiteralExpression());
15307330f729Sjoerg if (!AsmString.isInvalid()) {
15317330f729Sjoerg const auto *SL = cast<StringLiteral>(AsmString.get());
15327330f729Sjoerg if (!SL->isAscii()) {
15337330f729Sjoerg Diag(Tok, diag::err_asm_operand_wide_string_literal)
15347330f729Sjoerg << SL->isWide()
15357330f729Sjoerg << SL->getSourceRange();
15367330f729Sjoerg return ExprError();
15377330f729Sjoerg }
1538*e038c9c4Sjoerg if (ForAsmLabel && SL->getString().empty()) {
1539*e038c9c4Sjoerg Diag(Tok, diag::err_asm_operand_wide_string_literal)
1540*e038c9c4Sjoerg << 2 /* an empty */ << SL->getSourceRange();
1541*e038c9c4Sjoerg return ExprError();
1542*e038c9c4Sjoerg }
15437330f729Sjoerg }
15447330f729Sjoerg return AsmString;
15457330f729Sjoerg }
15467330f729Sjoerg
15477330f729Sjoerg /// ParseSimpleAsm
15487330f729Sjoerg ///
15497330f729Sjoerg /// [GNU] simple-asm-expr:
15507330f729Sjoerg /// 'asm' '(' asm-string-literal ')'
15517330f729Sjoerg ///
ParseSimpleAsm(bool ForAsmLabel,SourceLocation * EndLoc)1552*e038c9c4Sjoerg ExprResult Parser::ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc) {
15537330f729Sjoerg assert(Tok.is(tok::kw_asm) && "Not an asm!");
15547330f729Sjoerg SourceLocation Loc = ConsumeToken();
15557330f729Sjoerg
1556*e038c9c4Sjoerg if (isGNUAsmQualifier(Tok)) {
1557*e038c9c4Sjoerg // Remove from the end of 'asm' to the end of the asm qualifier.
15587330f729Sjoerg SourceRange RemovalRange(PP.getLocForEndOfToken(Loc),
15597330f729Sjoerg PP.getLocForEndOfToken(Tok.getLocation()));
1560*e038c9c4Sjoerg Diag(Tok, diag::err_global_asm_qualifier_ignored)
1561*e038c9c4Sjoerg << GNUAsmQualifiers::getQualifierName(getGNUAsmQualifier(Tok))
15627330f729Sjoerg << FixItHint::CreateRemoval(RemovalRange);
15637330f729Sjoerg ConsumeToken();
15647330f729Sjoerg }
15657330f729Sjoerg
15667330f729Sjoerg BalancedDelimiterTracker T(*this, tok::l_paren);
15677330f729Sjoerg if (T.consumeOpen()) {
15687330f729Sjoerg Diag(Tok, diag::err_expected_lparen_after) << "asm";
15697330f729Sjoerg return ExprError();
15707330f729Sjoerg }
15717330f729Sjoerg
1572*e038c9c4Sjoerg ExprResult Result(ParseAsmStringLiteral(ForAsmLabel));
15737330f729Sjoerg
15747330f729Sjoerg if (!Result.isInvalid()) {
15757330f729Sjoerg // Close the paren and get the location of the end bracket
15767330f729Sjoerg T.consumeClose();
15777330f729Sjoerg if (EndLoc)
15787330f729Sjoerg *EndLoc = T.getCloseLocation();
15797330f729Sjoerg } else if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
15807330f729Sjoerg if (EndLoc)
15817330f729Sjoerg *EndLoc = Tok.getLocation();
15827330f729Sjoerg ConsumeParen();
15837330f729Sjoerg }
15847330f729Sjoerg
15857330f729Sjoerg return Result;
15867330f729Sjoerg }
15877330f729Sjoerg
15887330f729Sjoerg /// Get the TemplateIdAnnotation from the token and put it in the
15897330f729Sjoerg /// cleanup pool so that it gets destroyed when parsing the current top level
15907330f729Sjoerg /// declaration is finished.
takeTemplateIdAnnotation(const Token & tok)15917330f729Sjoerg TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) {
15927330f729Sjoerg assert(tok.is(tok::annot_template_id) && "Expected template-id token");
15937330f729Sjoerg TemplateIdAnnotation *
15947330f729Sjoerg Id = static_cast<TemplateIdAnnotation *>(tok.getAnnotationValue());
15957330f729Sjoerg return Id;
15967330f729Sjoerg }
15977330f729Sjoerg
AnnotateScopeToken(CXXScopeSpec & SS,bool IsNewAnnotation)15987330f729Sjoerg void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {
15997330f729Sjoerg // Push the current token back into the token stream (or revert it if it is
16007330f729Sjoerg // cached) and use an annotation scope token for current token.
16017330f729Sjoerg if (PP.isBacktrackEnabled())
16027330f729Sjoerg PP.RevertCachedTokens(1);
16037330f729Sjoerg else
16047330f729Sjoerg PP.EnterToken(Tok, /*IsReinject=*/true);
16057330f729Sjoerg Tok.setKind(tok::annot_cxxscope);
16067330f729Sjoerg Tok.setAnnotationValue(Actions.SaveNestedNameSpecifierAnnotation(SS));
16077330f729Sjoerg Tok.setAnnotationRange(SS.getRange());
16087330f729Sjoerg
16097330f729Sjoerg // In case the tokens were cached, have Preprocessor replace them
16107330f729Sjoerg // with the annotation token. We don't need to do this if we've
16117330f729Sjoerg // just reverted back to a prior state.
16127330f729Sjoerg if (IsNewAnnotation)
16137330f729Sjoerg PP.AnnotateCachedTokens(Tok);
16147330f729Sjoerg }
16157330f729Sjoerg
16167330f729Sjoerg /// Attempt to classify the name at the current token position. This may
16177330f729Sjoerg /// form a type, scope or primary expression annotation, or replace the token
16187330f729Sjoerg /// with a typo-corrected keyword. This is only appropriate when the current
16197330f729Sjoerg /// name must refer to an entity which has already been declared.
16207330f729Sjoerg ///
16217330f729Sjoerg /// \param CCC Indicates how to perform typo-correction for this name. If NULL,
16227330f729Sjoerg /// no typo correction will be performed.
16237330f729Sjoerg Parser::AnnotatedNameKind
TryAnnotateName(CorrectionCandidateCallback * CCC)16247330f729Sjoerg Parser::TryAnnotateName(CorrectionCandidateCallback *CCC) {
16257330f729Sjoerg assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope));
16267330f729Sjoerg
16277330f729Sjoerg const bool EnteringContext = false;
16287330f729Sjoerg const bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
16297330f729Sjoerg
16307330f729Sjoerg CXXScopeSpec SS;
16317330f729Sjoerg if (getLangOpts().CPlusPlus &&
1632*e038c9c4Sjoerg ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1633*e038c9c4Sjoerg /*ObjectHadErrors=*/false,
1634*e038c9c4Sjoerg EnteringContext))
16357330f729Sjoerg return ANK_Error;
16367330f729Sjoerg
16377330f729Sjoerg if (Tok.isNot(tok::identifier) || SS.isInvalid()) {
16387330f729Sjoerg if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation))
16397330f729Sjoerg return ANK_Error;
16407330f729Sjoerg return ANK_Unresolved;
16417330f729Sjoerg }
16427330f729Sjoerg
16437330f729Sjoerg IdentifierInfo *Name = Tok.getIdentifierInfo();
16447330f729Sjoerg SourceLocation NameLoc = Tok.getLocation();
16457330f729Sjoerg
16467330f729Sjoerg // FIXME: Move the tentative declaration logic into ClassifyName so we can
16477330f729Sjoerg // typo-correct to tentatively-declared identifiers.
16487330f729Sjoerg if (isTentativelyDeclared(Name)) {
16497330f729Sjoerg // Identifier has been tentatively declared, and thus cannot be resolved as
16507330f729Sjoerg // an expression. Fall back to annotating it as a type.
16517330f729Sjoerg if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation))
16527330f729Sjoerg return ANK_Error;
16537330f729Sjoerg return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl;
16547330f729Sjoerg }
16557330f729Sjoerg
16567330f729Sjoerg Token Next = NextToken();
16577330f729Sjoerg
16587330f729Sjoerg // Look up and classify the identifier. We don't perform any typo-correction
16597330f729Sjoerg // after a scope specifier, because in general we can't recover from typos
16607330f729Sjoerg // there (eg, after correcting 'A::template B<X>::C' [sic], we would need to
16617330f729Sjoerg // jump back into scope specifier parsing).
16627330f729Sjoerg Sema::NameClassification Classification = Actions.ClassifyName(
16637330f729Sjoerg getCurScope(), SS, Name, NameLoc, Next, SS.isEmpty() ? CCC : nullptr);
16647330f729Sjoerg
16657330f729Sjoerg // If name lookup found nothing and we guessed that this was a template name,
16667330f729Sjoerg // double-check before committing to that interpretation. C++20 requires that
16677330f729Sjoerg // we interpret this as a template-id if it can be, but if it can't be, then
16687330f729Sjoerg // this is an error recovery case.
16697330f729Sjoerg if (Classification.getKind() == Sema::NC_UndeclaredTemplate &&
16707330f729Sjoerg isTemplateArgumentList(1) == TPResult::False) {
16717330f729Sjoerg // It's not a template-id; re-classify without the '<' as a hint.
16727330f729Sjoerg Token FakeNext = Next;
16737330f729Sjoerg FakeNext.setKind(tok::unknown);
16747330f729Sjoerg Classification =
16757330f729Sjoerg Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, FakeNext,
16767330f729Sjoerg SS.isEmpty() ? CCC : nullptr);
16777330f729Sjoerg }
16787330f729Sjoerg
16797330f729Sjoerg switch (Classification.getKind()) {
16807330f729Sjoerg case Sema::NC_Error:
16817330f729Sjoerg return ANK_Error;
16827330f729Sjoerg
16837330f729Sjoerg case Sema::NC_Keyword:
16847330f729Sjoerg // The identifier was typo-corrected to a keyword.
16857330f729Sjoerg Tok.setIdentifierInfo(Name);
16867330f729Sjoerg Tok.setKind(Name->getTokenID());
16877330f729Sjoerg PP.TypoCorrectToken(Tok);
16887330f729Sjoerg if (SS.isNotEmpty())
16897330f729Sjoerg AnnotateScopeToken(SS, !WasScopeAnnotation);
16907330f729Sjoerg // We've "annotated" this as a keyword.
16917330f729Sjoerg return ANK_Success;
16927330f729Sjoerg
16937330f729Sjoerg case Sema::NC_Unknown:
16947330f729Sjoerg // It's not something we know about. Leave it unannotated.
16957330f729Sjoerg break;
16967330f729Sjoerg
16977330f729Sjoerg case Sema::NC_Type: {
1698*e038c9c4Sjoerg if (TryAltiVecVectorToken())
1699*e038c9c4Sjoerg // vector has been found as a type id when altivec is enabled but
1700*e038c9c4Sjoerg // this is followed by a declaration specifier so this is really the
1701*e038c9c4Sjoerg // altivec vector token. Leave it unannotated.
1702*e038c9c4Sjoerg break;
17037330f729Sjoerg SourceLocation BeginLoc = NameLoc;
17047330f729Sjoerg if (SS.isNotEmpty())
17057330f729Sjoerg BeginLoc = SS.getBeginLoc();
17067330f729Sjoerg
17077330f729Sjoerg /// An Objective-C object type followed by '<' is a specialization of
17087330f729Sjoerg /// a parameterized class type or a protocol-qualified type.
17097330f729Sjoerg ParsedType Ty = Classification.getType();
17107330f729Sjoerg if (getLangOpts().ObjC && NextToken().is(tok::less) &&
17117330f729Sjoerg (Ty.get()->isObjCObjectType() ||
17127330f729Sjoerg Ty.get()->isObjCObjectPointerType())) {
17137330f729Sjoerg // Consume the name.
17147330f729Sjoerg SourceLocation IdentifierLoc = ConsumeToken();
17157330f729Sjoerg SourceLocation NewEndLoc;
17167330f729Sjoerg TypeResult NewType
17177330f729Sjoerg = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,
17187330f729Sjoerg /*consumeLastToken=*/false,
17197330f729Sjoerg NewEndLoc);
17207330f729Sjoerg if (NewType.isUsable())
17217330f729Sjoerg Ty = NewType.get();
17227330f729Sjoerg else if (Tok.is(tok::eof)) // Nothing to do here, bail out...
17237330f729Sjoerg return ANK_Error;
17247330f729Sjoerg }
17257330f729Sjoerg
17267330f729Sjoerg Tok.setKind(tok::annot_typename);
17277330f729Sjoerg setTypeAnnotation(Tok, Ty);
17287330f729Sjoerg Tok.setAnnotationEndLoc(Tok.getLocation());
17297330f729Sjoerg Tok.setLocation(BeginLoc);
17307330f729Sjoerg PP.AnnotateCachedTokens(Tok);
17317330f729Sjoerg return ANK_Success;
17327330f729Sjoerg }
17337330f729Sjoerg
1734*e038c9c4Sjoerg case Sema::NC_OverloadSet:
1735*e038c9c4Sjoerg Tok.setKind(tok::annot_overload_set);
17367330f729Sjoerg setExprAnnotation(Tok, Classification.getExpression());
17377330f729Sjoerg Tok.setAnnotationEndLoc(NameLoc);
17387330f729Sjoerg if (SS.isNotEmpty())
17397330f729Sjoerg Tok.setLocation(SS.getBeginLoc());
17407330f729Sjoerg PP.AnnotateCachedTokens(Tok);
17417330f729Sjoerg return ANK_Success;
17427330f729Sjoerg
17437330f729Sjoerg case Sema::NC_NonType:
1744*e038c9c4Sjoerg if (TryAltiVecVectorToken())
1745*e038c9c4Sjoerg // vector has been found as a non-type id when altivec is enabled but
1746*e038c9c4Sjoerg // this is followed by a declaration specifier so this is really the
1747*e038c9c4Sjoerg // altivec vector token. Leave it unannotated.
1748*e038c9c4Sjoerg break;
17497330f729Sjoerg Tok.setKind(tok::annot_non_type);
17507330f729Sjoerg setNonTypeAnnotation(Tok, Classification.getNonTypeDecl());
17517330f729Sjoerg Tok.setLocation(NameLoc);
17527330f729Sjoerg Tok.setAnnotationEndLoc(NameLoc);
17537330f729Sjoerg PP.AnnotateCachedTokens(Tok);
17547330f729Sjoerg if (SS.isNotEmpty())
17557330f729Sjoerg AnnotateScopeToken(SS, !WasScopeAnnotation);
17567330f729Sjoerg return ANK_Success;
17577330f729Sjoerg
17587330f729Sjoerg case Sema::NC_UndeclaredNonType:
17597330f729Sjoerg case Sema::NC_DependentNonType:
17607330f729Sjoerg Tok.setKind(Classification.getKind() == Sema::NC_UndeclaredNonType
17617330f729Sjoerg ? tok::annot_non_type_undeclared
17627330f729Sjoerg : tok::annot_non_type_dependent);
17637330f729Sjoerg setIdentifierAnnotation(Tok, Name);
17647330f729Sjoerg Tok.setLocation(NameLoc);
17657330f729Sjoerg Tok.setAnnotationEndLoc(NameLoc);
17667330f729Sjoerg PP.AnnotateCachedTokens(Tok);
17677330f729Sjoerg if (SS.isNotEmpty())
17687330f729Sjoerg AnnotateScopeToken(SS, !WasScopeAnnotation);
17697330f729Sjoerg return ANK_Success;
17707330f729Sjoerg
17717330f729Sjoerg case Sema::NC_TypeTemplate:
17727330f729Sjoerg if (Next.isNot(tok::less)) {
17737330f729Sjoerg // This may be a type template being used as a template template argument.
17747330f729Sjoerg if (SS.isNotEmpty())
17757330f729Sjoerg AnnotateScopeToken(SS, !WasScopeAnnotation);
17767330f729Sjoerg return ANK_TemplateName;
17777330f729Sjoerg }
17787330f729Sjoerg LLVM_FALLTHROUGH;
17797330f729Sjoerg case Sema::NC_VarTemplate:
17807330f729Sjoerg case Sema::NC_FunctionTemplate:
17817330f729Sjoerg case Sema::NC_UndeclaredTemplate: {
17827330f729Sjoerg // We have a type, variable or function template followed by '<'.
17837330f729Sjoerg ConsumeToken();
17847330f729Sjoerg UnqualifiedId Id;
17857330f729Sjoerg Id.setIdentifier(Name, NameLoc);
17867330f729Sjoerg if (AnnotateTemplateIdToken(
17877330f729Sjoerg TemplateTy::make(Classification.getTemplateName()),
17887330f729Sjoerg Classification.getTemplateNameKind(), SS, SourceLocation(), Id))
17897330f729Sjoerg return ANK_Error;
17907330f729Sjoerg return ANK_Success;
17917330f729Sjoerg }
1792*e038c9c4Sjoerg case Sema::NC_Concept: {
1793*e038c9c4Sjoerg UnqualifiedId Id;
1794*e038c9c4Sjoerg Id.setIdentifier(Name, NameLoc);
1795*e038c9c4Sjoerg if (Next.is(tok::less))
1796*e038c9c4Sjoerg // We have a concept name followed by '<'. Consume the identifier token so
1797*e038c9c4Sjoerg // we reach the '<' and annotate it.
1798*e038c9c4Sjoerg ConsumeToken();
1799*e038c9c4Sjoerg if (AnnotateTemplateIdToken(
1800*e038c9c4Sjoerg TemplateTy::make(Classification.getTemplateName()),
1801*e038c9c4Sjoerg Classification.getTemplateNameKind(), SS, SourceLocation(), Id,
1802*e038c9c4Sjoerg /*AllowTypeAnnotation=*/false, /*TypeConstraint=*/true))
1803*e038c9c4Sjoerg return ANK_Error;
1804*e038c9c4Sjoerg return ANK_Success;
1805*e038c9c4Sjoerg }
18067330f729Sjoerg }
18077330f729Sjoerg
18087330f729Sjoerg // Unable to classify the name, but maybe we can annotate a scope specifier.
18097330f729Sjoerg if (SS.isNotEmpty())
18107330f729Sjoerg AnnotateScopeToken(SS, !WasScopeAnnotation);
18117330f729Sjoerg return ANK_Unresolved;
18127330f729Sjoerg }
18137330f729Sjoerg
TryKeywordIdentFallback(bool DisableKeyword)18147330f729Sjoerg bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
18157330f729Sjoerg assert(Tok.isNot(tok::identifier));
18167330f729Sjoerg Diag(Tok, diag::ext_keyword_as_ident)
18177330f729Sjoerg << PP.getSpelling(Tok)
18187330f729Sjoerg << DisableKeyword;
18197330f729Sjoerg if (DisableKeyword)
18207330f729Sjoerg Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
18217330f729Sjoerg Tok.setKind(tok::identifier);
18227330f729Sjoerg return true;
18237330f729Sjoerg }
18247330f729Sjoerg
18257330f729Sjoerg /// TryAnnotateTypeOrScopeToken - If the current token position is on a
18267330f729Sjoerg /// typename (possibly qualified in C++) or a C++ scope specifier not followed
18277330f729Sjoerg /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
18287330f729Sjoerg /// with a single annotation token representing the typename or C++ scope
18297330f729Sjoerg /// respectively.
18307330f729Sjoerg /// This simplifies handling of C++ scope specifiers and allows efficient
18317330f729Sjoerg /// backtracking without the need to re-parse and resolve nested-names and
18327330f729Sjoerg /// typenames.
18337330f729Sjoerg /// It will mainly be called when we expect to treat identifiers as typenames
18347330f729Sjoerg /// (if they are typenames). For example, in C we do not expect identifiers
18357330f729Sjoerg /// inside expressions to be treated as typenames so it will not be called
18367330f729Sjoerg /// for expressions in C.
18377330f729Sjoerg /// The benefit for C/ObjC is that a typename will be annotated and
18387330f729Sjoerg /// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
18397330f729Sjoerg /// will not be called twice, once to check whether we have a declaration
18407330f729Sjoerg /// specifier, and another one to get the actual type inside
18417330f729Sjoerg /// ParseDeclarationSpecifiers).
18427330f729Sjoerg ///
18437330f729Sjoerg /// This returns true if an error occurred.
18447330f729Sjoerg ///
18457330f729Sjoerg /// Note that this routine emits an error if you call it with ::new or ::delete
18467330f729Sjoerg /// as the current tokens, so only call it in contexts where these are invalid.
TryAnnotateTypeOrScopeToken()18477330f729Sjoerg bool Parser::TryAnnotateTypeOrScopeToken() {
18487330f729Sjoerg assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
18497330f729Sjoerg Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) ||
18507330f729Sjoerg Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) ||
18517330f729Sjoerg Tok.is(tok::kw___super)) &&
18527330f729Sjoerg "Cannot be a type or scope token!");
18537330f729Sjoerg
18547330f729Sjoerg if (Tok.is(tok::kw_typename)) {
18557330f729Sjoerg // MSVC lets you do stuff like:
18567330f729Sjoerg // typename typedef T_::D D;
18577330f729Sjoerg //
18587330f729Sjoerg // We will consume the typedef token here and put it back after we have
18597330f729Sjoerg // parsed the first identifier, transforming it into something more like:
18607330f729Sjoerg // typename T_::D typedef D;
18617330f729Sjoerg if (getLangOpts().MSVCCompat && NextToken().is(tok::kw_typedef)) {
18627330f729Sjoerg Token TypedefToken;
18637330f729Sjoerg PP.Lex(TypedefToken);
18647330f729Sjoerg bool Result = TryAnnotateTypeOrScopeToken();
18657330f729Sjoerg PP.EnterToken(Tok, /*IsReinject=*/true);
18667330f729Sjoerg Tok = TypedefToken;
18677330f729Sjoerg if (!Result)
18687330f729Sjoerg Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename);
18697330f729Sjoerg return Result;
18707330f729Sjoerg }
18717330f729Sjoerg
18727330f729Sjoerg // Parse a C++ typename-specifier, e.g., "typename T::type".
18737330f729Sjoerg //
18747330f729Sjoerg // typename-specifier:
18757330f729Sjoerg // 'typename' '::' [opt] nested-name-specifier identifier
18767330f729Sjoerg // 'typename' '::' [opt] nested-name-specifier template [opt]
18777330f729Sjoerg // simple-template-id
18787330f729Sjoerg SourceLocation TypenameLoc = ConsumeToken();
18797330f729Sjoerg CXXScopeSpec SS;
18807330f729Sjoerg if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1881*e038c9c4Sjoerg /*ObjectHadErrors=*/false,
18827330f729Sjoerg /*EnteringContext=*/false, nullptr,
18837330f729Sjoerg /*IsTypename*/ true))
18847330f729Sjoerg return true;
1885*e038c9c4Sjoerg if (SS.isEmpty()) {
18867330f729Sjoerg if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||
18877330f729Sjoerg Tok.is(tok::annot_decltype)) {
18887330f729Sjoerg // Attempt to recover by skipping the invalid 'typename'
18897330f729Sjoerg if (Tok.is(tok::annot_decltype) ||
18907330f729Sjoerg (!TryAnnotateTypeOrScopeToken() && Tok.isAnnotation())) {
18917330f729Sjoerg unsigned DiagID = diag::err_expected_qualified_after_typename;
18927330f729Sjoerg // MS compatibility: MSVC permits using known types with typename.
18937330f729Sjoerg // e.g. "typedef typename T* pointer_type"
18947330f729Sjoerg if (getLangOpts().MicrosoftExt)
18957330f729Sjoerg DiagID = diag::warn_expected_qualified_after_typename;
18967330f729Sjoerg Diag(Tok.getLocation(), DiagID);
18977330f729Sjoerg return false;
18987330f729Sjoerg }
18997330f729Sjoerg }
19007330f729Sjoerg if (Tok.isEditorPlaceholder())
19017330f729Sjoerg return true;
19027330f729Sjoerg
19037330f729Sjoerg Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
19047330f729Sjoerg return true;
19057330f729Sjoerg }
19067330f729Sjoerg
19077330f729Sjoerg TypeResult Ty;
19087330f729Sjoerg if (Tok.is(tok::identifier)) {
19097330f729Sjoerg // FIXME: check whether the next token is '<', first!
19107330f729Sjoerg Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS,
19117330f729Sjoerg *Tok.getIdentifierInfo(),
19127330f729Sjoerg Tok.getLocation());
19137330f729Sjoerg } else if (Tok.is(tok::annot_template_id)) {
19147330f729Sjoerg TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1915*e038c9c4Sjoerg if (!TemplateId->mightBeType()) {
19167330f729Sjoerg Diag(Tok, diag::err_typename_refers_to_non_type_template)
19177330f729Sjoerg << Tok.getAnnotationRange();
19187330f729Sjoerg return true;
19197330f729Sjoerg }
19207330f729Sjoerg
19217330f729Sjoerg ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
19227330f729Sjoerg TemplateId->NumArgs);
19237330f729Sjoerg
1924*e038c9c4Sjoerg Ty = TemplateId->isInvalid()
1925*e038c9c4Sjoerg ? TypeError()
1926*e038c9c4Sjoerg : Actions.ActOnTypenameType(
1927*e038c9c4Sjoerg getCurScope(), TypenameLoc, SS, TemplateId->TemplateKWLoc,
1928*e038c9c4Sjoerg TemplateId->Template, TemplateId->Name,
1929*e038c9c4Sjoerg TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
1930*e038c9c4Sjoerg TemplateArgsPtr, TemplateId->RAngleLoc);
19317330f729Sjoerg } else {
19327330f729Sjoerg Diag(Tok, diag::err_expected_type_name_after_typename)
19337330f729Sjoerg << SS.getRange();
19347330f729Sjoerg return true;
19357330f729Sjoerg }
19367330f729Sjoerg
19377330f729Sjoerg SourceLocation EndLoc = Tok.getLastLoc();
19387330f729Sjoerg Tok.setKind(tok::annot_typename);
1939*e038c9c4Sjoerg setTypeAnnotation(Tok, Ty);
19407330f729Sjoerg Tok.setAnnotationEndLoc(EndLoc);
19417330f729Sjoerg Tok.setLocation(TypenameLoc);
19427330f729Sjoerg PP.AnnotateCachedTokens(Tok);
19437330f729Sjoerg return false;
19447330f729Sjoerg }
19457330f729Sjoerg
19467330f729Sjoerg // Remembers whether the token was originally a scope annotation.
19477330f729Sjoerg bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
19487330f729Sjoerg
19497330f729Sjoerg CXXScopeSpec SS;
19507330f729Sjoerg if (getLangOpts().CPlusPlus)
1951*e038c9c4Sjoerg if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1952*e038c9c4Sjoerg /*ObjectHadErrors=*/false,
1953*e038c9c4Sjoerg /*EnteringContext*/ false))
19547330f729Sjoerg return true;
19557330f729Sjoerg
19567330f729Sjoerg return TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation);
19577330f729Sjoerg }
19587330f729Sjoerg
19597330f729Sjoerg /// Try to annotate a type or scope token, having already parsed an
19607330f729Sjoerg /// optional scope specifier. \p IsNewScope should be \c true unless the scope
19617330f729Sjoerg /// specifier was extracted from an existing tok::annot_cxxscope annotation.
TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec & SS,bool IsNewScope)19627330f729Sjoerg bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS,
19637330f729Sjoerg bool IsNewScope) {
19647330f729Sjoerg if (Tok.is(tok::identifier)) {
19657330f729Sjoerg // Determine whether the identifier is a type name.
19667330f729Sjoerg if (ParsedType Ty = Actions.getTypeName(
19677330f729Sjoerg *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS,
19687330f729Sjoerg false, NextToken().is(tok::period), nullptr,
19697330f729Sjoerg /*IsCtorOrDtorName=*/false,
19707330f729Sjoerg /*NonTrivialTypeSourceInfo*/true,
19717330f729Sjoerg /*IsClassTemplateDeductionContext*/true)) {
19727330f729Sjoerg SourceLocation BeginLoc = Tok.getLocation();
19737330f729Sjoerg if (SS.isNotEmpty()) // it was a C++ qualified type name.
19747330f729Sjoerg BeginLoc = SS.getBeginLoc();
19757330f729Sjoerg
19767330f729Sjoerg /// An Objective-C object type followed by '<' is a specialization of
19777330f729Sjoerg /// a parameterized class type or a protocol-qualified type.
19787330f729Sjoerg if (getLangOpts().ObjC && NextToken().is(tok::less) &&
19797330f729Sjoerg (Ty.get()->isObjCObjectType() ||
19807330f729Sjoerg Ty.get()->isObjCObjectPointerType())) {
19817330f729Sjoerg // Consume the name.
19827330f729Sjoerg SourceLocation IdentifierLoc = ConsumeToken();
19837330f729Sjoerg SourceLocation NewEndLoc;
19847330f729Sjoerg TypeResult NewType
19857330f729Sjoerg = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,
19867330f729Sjoerg /*consumeLastToken=*/false,
19877330f729Sjoerg NewEndLoc);
19887330f729Sjoerg if (NewType.isUsable())
19897330f729Sjoerg Ty = NewType.get();
19907330f729Sjoerg else if (Tok.is(tok::eof)) // Nothing to do here, bail out...
19917330f729Sjoerg return false;
19927330f729Sjoerg }
19937330f729Sjoerg
19947330f729Sjoerg // This is a typename. Replace the current token in-place with an
19957330f729Sjoerg // annotation type token.
19967330f729Sjoerg Tok.setKind(tok::annot_typename);
19977330f729Sjoerg setTypeAnnotation(Tok, Ty);
19987330f729Sjoerg Tok.setAnnotationEndLoc(Tok.getLocation());
19997330f729Sjoerg Tok.setLocation(BeginLoc);
20007330f729Sjoerg
20017330f729Sjoerg // In case the tokens were cached, have Preprocessor replace
20027330f729Sjoerg // them with the annotation token.
20037330f729Sjoerg PP.AnnotateCachedTokens(Tok);
20047330f729Sjoerg return false;
20057330f729Sjoerg }
20067330f729Sjoerg
20077330f729Sjoerg if (!getLangOpts().CPlusPlus) {
20087330f729Sjoerg // If we're in C, we can't have :: tokens at all (the lexer won't return
20097330f729Sjoerg // them). If the identifier is not a type, then it can't be scope either,
20107330f729Sjoerg // just early exit.
20117330f729Sjoerg return false;
20127330f729Sjoerg }
20137330f729Sjoerg
20147330f729Sjoerg // If this is a template-id, annotate with a template-id or type token.
20157330f729Sjoerg // FIXME: This appears to be dead code. We already have formed template-id
20167330f729Sjoerg // tokens when parsing the scope specifier; this can never form a new one.
20177330f729Sjoerg if (NextToken().is(tok::less)) {
20187330f729Sjoerg TemplateTy Template;
20197330f729Sjoerg UnqualifiedId TemplateName;
20207330f729Sjoerg TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
20217330f729Sjoerg bool MemberOfUnknownSpecialization;
20227330f729Sjoerg if (TemplateNameKind TNK = Actions.isTemplateName(
20237330f729Sjoerg getCurScope(), SS,
20247330f729Sjoerg /*hasTemplateKeyword=*/false, TemplateName,
20257330f729Sjoerg /*ObjectType=*/nullptr, /*EnteringContext*/false, Template,
20267330f729Sjoerg MemberOfUnknownSpecialization)) {
20277330f729Sjoerg // Only annotate an undeclared template name as a template-id if the
20287330f729Sjoerg // following tokens have the form of a template argument list.
20297330f729Sjoerg if (TNK != TNK_Undeclared_template ||
20307330f729Sjoerg isTemplateArgumentList(1) != TPResult::False) {
20317330f729Sjoerg // Consume the identifier.
20327330f729Sjoerg ConsumeToken();
20337330f729Sjoerg if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
20347330f729Sjoerg TemplateName)) {
20357330f729Sjoerg // If an unrecoverable error occurred, we need to return true here,
20367330f729Sjoerg // because the token stream is in a damaged state. We may not
20377330f729Sjoerg // return a valid identifier.
20387330f729Sjoerg return true;
20397330f729Sjoerg }
20407330f729Sjoerg }
20417330f729Sjoerg }
20427330f729Sjoerg }
20437330f729Sjoerg
20447330f729Sjoerg // The current token, which is either an identifier or a
20457330f729Sjoerg // template-id, is not part of the annotation. Fall through to
20467330f729Sjoerg // push that token back into the stream and complete the C++ scope
20477330f729Sjoerg // specifier annotation.
20487330f729Sjoerg }
20497330f729Sjoerg
20507330f729Sjoerg if (Tok.is(tok::annot_template_id)) {
20517330f729Sjoerg TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
20527330f729Sjoerg if (TemplateId->Kind == TNK_Type_template) {
20537330f729Sjoerg // A template-id that refers to a type was parsed into a
20547330f729Sjoerg // template-id annotation in a context where we weren't allowed
20557330f729Sjoerg // to produce a type annotation token. Update the template-id
20567330f729Sjoerg // annotation token to a type annotation token now.
2057*e038c9c4Sjoerg AnnotateTemplateIdTokenAsType(SS);
20587330f729Sjoerg return false;
20597330f729Sjoerg }
20607330f729Sjoerg }
20617330f729Sjoerg
20627330f729Sjoerg if (SS.isEmpty())
20637330f729Sjoerg return false;
20647330f729Sjoerg
20657330f729Sjoerg // A C++ scope specifier that isn't followed by a typename.
20667330f729Sjoerg AnnotateScopeToken(SS, IsNewScope);
20677330f729Sjoerg return false;
20687330f729Sjoerg }
20697330f729Sjoerg
20707330f729Sjoerg /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
20717330f729Sjoerg /// annotates C++ scope specifiers and template-ids. This returns
20727330f729Sjoerg /// true if there was an error that could not be recovered from.
20737330f729Sjoerg ///
20747330f729Sjoerg /// Note that this routine emits an error if you call it with ::new or ::delete
20757330f729Sjoerg /// as the current tokens, so only call it in contexts where these are invalid.
TryAnnotateCXXScopeToken(bool EnteringContext)20767330f729Sjoerg bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
20777330f729Sjoerg assert(getLangOpts().CPlusPlus &&
20787330f729Sjoerg "Call sites of this function should be guarded by checking for C++");
2079*e038c9c4Sjoerg assert(MightBeCXXScopeToken() && "Cannot be a type or scope token!");
20807330f729Sjoerg
20817330f729Sjoerg CXXScopeSpec SS;
2082*e038c9c4Sjoerg if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2083*e038c9c4Sjoerg /*ObjectHadErrors=*/false,
2084*e038c9c4Sjoerg EnteringContext))
20857330f729Sjoerg return true;
20867330f729Sjoerg if (SS.isEmpty())
20877330f729Sjoerg return false;
20887330f729Sjoerg
20897330f729Sjoerg AnnotateScopeToken(SS, true);
20907330f729Sjoerg return false;
20917330f729Sjoerg }
20927330f729Sjoerg
isTokenEqualOrEqualTypo()20937330f729Sjoerg bool Parser::isTokenEqualOrEqualTypo() {
20947330f729Sjoerg tok::TokenKind Kind = Tok.getKind();
20957330f729Sjoerg switch (Kind) {
20967330f729Sjoerg default:
20977330f729Sjoerg return false;
20987330f729Sjoerg case tok::ampequal: // &=
20997330f729Sjoerg case tok::starequal: // *=
21007330f729Sjoerg case tok::plusequal: // +=
21017330f729Sjoerg case tok::minusequal: // -=
21027330f729Sjoerg case tok::exclaimequal: // !=
21037330f729Sjoerg case tok::slashequal: // /=
21047330f729Sjoerg case tok::percentequal: // %=
21057330f729Sjoerg case tok::lessequal: // <=
21067330f729Sjoerg case tok::lesslessequal: // <<=
21077330f729Sjoerg case tok::greaterequal: // >=
21087330f729Sjoerg case tok::greatergreaterequal: // >>=
21097330f729Sjoerg case tok::caretequal: // ^=
21107330f729Sjoerg case tok::pipeequal: // |=
21117330f729Sjoerg case tok::equalequal: // ==
21127330f729Sjoerg Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)
21137330f729Sjoerg << Kind
21147330f729Sjoerg << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "=");
21157330f729Sjoerg LLVM_FALLTHROUGH;
21167330f729Sjoerg case tok::equal:
21177330f729Sjoerg return true;
21187330f729Sjoerg }
21197330f729Sjoerg }
21207330f729Sjoerg
handleUnexpectedCodeCompletionToken()21217330f729Sjoerg SourceLocation Parser::handleUnexpectedCodeCompletionToken() {
21227330f729Sjoerg assert(Tok.is(tok::code_completion));
21237330f729Sjoerg PrevTokLocation = Tok.getLocation();
21247330f729Sjoerg
21257330f729Sjoerg for (Scope *S = getCurScope(); S; S = S->getParent()) {
21267330f729Sjoerg if (S->getFlags() & Scope::FnScope) {
2127*e038c9c4Sjoerg cutOffParsing();
21287330f729Sjoerg Actions.CodeCompleteOrdinaryName(getCurScope(),
21297330f729Sjoerg Sema::PCC_RecoveryInFunction);
21307330f729Sjoerg return PrevTokLocation;
21317330f729Sjoerg }
21327330f729Sjoerg
21337330f729Sjoerg if (S->getFlags() & Scope::ClassScope) {
21347330f729Sjoerg cutOffParsing();
2135*e038c9c4Sjoerg Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class);
21367330f729Sjoerg return PrevTokLocation;
21377330f729Sjoerg }
21387330f729Sjoerg }
21397330f729Sjoerg
21407330f729Sjoerg cutOffParsing();
2141*e038c9c4Sjoerg Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace);
21427330f729Sjoerg return PrevTokLocation;
21437330f729Sjoerg }
21447330f729Sjoerg
21457330f729Sjoerg // Code-completion pass-through functions
21467330f729Sjoerg
CodeCompleteDirective(bool InConditional)21477330f729Sjoerg void Parser::CodeCompleteDirective(bool InConditional) {
21487330f729Sjoerg Actions.CodeCompletePreprocessorDirective(InConditional);
21497330f729Sjoerg }
21507330f729Sjoerg
CodeCompleteInConditionalExclusion()21517330f729Sjoerg void Parser::CodeCompleteInConditionalExclusion() {
21527330f729Sjoerg Actions.CodeCompleteInPreprocessorConditionalExclusion(getCurScope());
21537330f729Sjoerg }
21547330f729Sjoerg
CodeCompleteMacroName(bool IsDefinition)21557330f729Sjoerg void Parser::CodeCompleteMacroName(bool IsDefinition) {
21567330f729Sjoerg Actions.CodeCompletePreprocessorMacroName(IsDefinition);
21577330f729Sjoerg }
21587330f729Sjoerg
CodeCompletePreprocessorExpression()21597330f729Sjoerg void Parser::CodeCompletePreprocessorExpression() {
21607330f729Sjoerg Actions.CodeCompletePreprocessorExpression();
21617330f729Sjoerg }
21627330f729Sjoerg
CodeCompleteMacroArgument(IdentifierInfo * Macro,MacroInfo * MacroInfo,unsigned ArgumentIndex)21637330f729Sjoerg void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,
21647330f729Sjoerg MacroInfo *MacroInfo,
21657330f729Sjoerg unsigned ArgumentIndex) {
21667330f729Sjoerg Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo,
21677330f729Sjoerg ArgumentIndex);
21687330f729Sjoerg }
21697330f729Sjoerg
CodeCompleteIncludedFile(llvm::StringRef Dir,bool IsAngled)21707330f729Sjoerg void Parser::CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) {
21717330f729Sjoerg Actions.CodeCompleteIncludedFile(Dir, IsAngled);
21727330f729Sjoerg }
21737330f729Sjoerg
CodeCompleteNaturalLanguage()21747330f729Sjoerg void Parser::CodeCompleteNaturalLanguage() {
21757330f729Sjoerg Actions.CodeCompleteNaturalLanguage();
21767330f729Sjoerg }
21777330f729Sjoerg
ParseMicrosoftIfExistsCondition(IfExistsCondition & Result)21787330f729Sjoerg bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) {
21797330f729Sjoerg assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) &&
21807330f729Sjoerg "Expected '__if_exists' or '__if_not_exists'");
21817330f729Sjoerg Result.IsIfExists = Tok.is(tok::kw___if_exists);
21827330f729Sjoerg Result.KeywordLoc = ConsumeToken();
21837330f729Sjoerg
21847330f729Sjoerg BalancedDelimiterTracker T(*this, tok::l_paren);
21857330f729Sjoerg if (T.consumeOpen()) {
21867330f729Sjoerg Diag(Tok, diag::err_expected_lparen_after)
21877330f729Sjoerg << (Result.IsIfExists? "__if_exists" : "__if_not_exists");
21887330f729Sjoerg return true;
21897330f729Sjoerg }
21907330f729Sjoerg
21917330f729Sjoerg // Parse nested-name-specifier.
21927330f729Sjoerg if (getLangOpts().CPlusPlus)
2193*e038c9c4Sjoerg ParseOptionalCXXScopeSpecifier(Result.SS, /*ObjectType=*/nullptr,
2194*e038c9c4Sjoerg /*ObjectHadErrors=*/false,
21957330f729Sjoerg /*EnteringContext=*/false);
21967330f729Sjoerg
21977330f729Sjoerg // Check nested-name specifier.
21987330f729Sjoerg if (Result.SS.isInvalid()) {
21997330f729Sjoerg T.skipToEnd();
22007330f729Sjoerg return true;
22017330f729Sjoerg }
22027330f729Sjoerg
22037330f729Sjoerg // Parse the unqualified-id.
22047330f729Sjoerg SourceLocation TemplateKWLoc; // FIXME: parsed, but unused.
2205*e038c9c4Sjoerg if (ParseUnqualifiedId(Result.SS, /*ObjectType=*/nullptr,
2206*e038c9c4Sjoerg /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
2207*e038c9c4Sjoerg /*AllowDestructorName*/ true,
2208*e038c9c4Sjoerg /*AllowConstructorName*/ true,
2209*e038c9c4Sjoerg /*AllowDeductionGuide*/ false, &TemplateKWLoc,
2210*e038c9c4Sjoerg Result.Name)) {
22117330f729Sjoerg T.skipToEnd();
22127330f729Sjoerg return true;
22137330f729Sjoerg }
22147330f729Sjoerg
22157330f729Sjoerg if (T.consumeClose())
22167330f729Sjoerg return true;
22177330f729Sjoerg
22187330f729Sjoerg // Check if the symbol exists.
22197330f729Sjoerg switch (Actions.CheckMicrosoftIfExistsSymbol(getCurScope(), Result.KeywordLoc,
22207330f729Sjoerg Result.IsIfExists, Result.SS,
22217330f729Sjoerg Result.Name)) {
22227330f729Sjoerg case Sema::IER_Exists:
22237330f729Sjoerg Result.Behavior = Result.IsIfExists ? IEB_Parse : IEB_Skip;
22247330f729Sjoerg break;
22257330f729Sjoerg
22267330f729Sjoerg case Sema::IER_DoesNotExist:
22277330f729Sjoerg Result.Behavior = !Result.IsIfExists ? IEB_Parse : IEB_Skip;
22287330f729Sjoerg break;
22297330f729Sjoerg
22307330f729Sjoerg case Sema::IER_Dependent:
22317330f729Sjoerg Result.Behavior = IEB_Dependent;
22327330f729Sjoerg break;
22337330f729Sjoerg
22347330f729Sjoerg case Sema::IER_Error:
22357330f729Sjoerg return true;
22367330f729Sjoerg }
22377330f729Sjoerg
22387330f729Sjoerg return false;
22397330f729Sjoerg }
22407330f729Sjoerg
ParseMicrosoftIfExistsExternalDeclaration()22417330f729Sjoerg void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
22427330f729Sjoerg IfExistsCondition Result;
22437330f729Sjoerg if (ParseMicrosoftIfExistsCondition(Result))
22447330f729Sjoerg return;
22457330f729Sjoerg
22467330f729Sjoerg BalancedDelimiterTracker Braces(*this, tok::l_brace);
22477330f729Sjoerg if (Braces.consumeOpen()) {
22487330f729Sjoerg Diag(Tok, diag::err_expected) << tok::l_brace;
22497330f729Sjoerg return;
22507330f729Sjoerg }
22517330f729Sjoerg
22527330f729Sjoerg switch (Result.Behavior) {
22537330f729Sjoerg case IEB_Parse:
22547330f729Sjoerg // Parse declarations below.
22557330f729Sjoerg break;
22567330f729Sjoerg
22577330f729Sjoerg case IEB_Dependent:
22587330f729Sjoerg llvm_unreachable("Cannot have a dependent external declaration");
22597330f729Sjoerg
22607330f729Sjoerg case IEB_Skip:
22617330f729Sjoerg Braces.skipToEnd();
22627330f729Sjoerg return;
22637330f729Sjoerg }
22647330f729Sjoerg
22657330f729Sjoerg // Parse the declarations.
22667330f729Sjoerg // FIXME: Support module import within __if_exists?
22677330f729Sjoerg while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
22687330f729Sjoerg ParsedAttributesWithRange attrs(AttrFactory);
22697330f729Sjoerg MaybeParseCXX11Attributes(attrs);
22707330f729Sjoerg DeclGroupPtrTy Result = ParseExternalDeclaration(attrs);
22717330f729Sjoerg if (Result && !getCurScope()->getParent())
22727330f729Sjoerg Actions.getASTConsumer().HandleTopLevelDecl(Result.get());
22737330f729Sjoerg }
22747330f729Sjoerg Braces.consumeClose();
22757330f729Sjoerg }
22767330f729Sjoerg
22777330f729Sjoerg /// Parse a declaration beginning with the 'module' keyword or C++20
22787330f729Sjoerg /// context-sensitive keyword (optionally preceded by 'export').
22797330f729Sjoerg ///
22807330f729Sjoerg /// module-declaration: [Modules TS + P0629R0]
22817330f729Sjoerg /// 'export'[opt] 'module' module-name attribute-specifier-seq[opt] ';'
22827330f729Sjoerg ///
22837330f729Sjoerg /// global-module-fragment: [C++2a]
22847330f729Sjoerg /// 'module' ';' top-level-declaration-seq[opt]
22857330f729Sjoerg /// module-declaration: [C++2a]
22867330f729Sjoerg /// 'export'[opt] 'module' module-name module-partition[opt]
22877330f729Sjoerg /// attribute-specifier-seq[opt] ';'
22887330f729Sjoerg /// private-module-fragment: [C++2a]
22897330f729Sjoerg /// 'module' ':' 'private' ';' top-level-declaration-seq[opt]
ParseModuleDecl(bool IsFirstDecl)22907330f729Sjoerg Parser::DeclGroupPtrTy Parser::ParseModuleDecl(bool IsFirstDecl) {
22917330f729Sjoerg SourceLocation StartLoc = Tok.getLocation();
22927330f729Sjoerg
22937330f729Sjoerg Sema::ModuleDeclKind MDK = TryConsumeToken(tok::kw_export)
22947330f729Sjoerg ? Sema::ModuleDeclKind::Interface
22957330f729Sjoerg : Sema::ModuleDeclKind::Implementation;
22967330f729Sjoerg
22977330f729Sjoerg assert(
22987330f729Sjoerg (Tok.is(tok::kw_module) ||
22997330f729Sjoerg (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_module)) &&
23007330f729Sjoerg "not a module declaration");
23017330f729Sjoerg SourceLocation ModuleLoc = ConsumeToken();
23027330f729Sjoerg
23037330f729Sjoerg // Attributes appear after the module name, not before.
23047330f729Sjoerg // FIXME: Suggest moving the attributes later with a fixit.
23057330f729Sjoerg DiagnoseAndSkipCXX11Attributes();
23067330f729Sjoerg
23077330f729Sjoerg // Parse a global-module-fragment, if present.
23087330f729Sjoerg if (getLangOpts().CPlusPlusModules && Tok.is(tok::semi)) {
23097330f729Sjoerg SourceLocation SemiLoc = ConsumeToken();
23107330f729Sjoerg if (!IsFirstDecl) {
23117330f729Sjoerg Diag(StartLoc, diag::err_global_module_introducer_not_at_start)
23127330f729Sjoerg << SourceRange(StartLoc, SemiLoc);
23137330f729Sjoerg return nullptr;
23147330f729Sjoerg }
23157330f729Sjoerg if (MDK == Sema::ModuleDeclKind::Interface) {
23167330f729Sjoerg Diag(StartLoc, diag::err_module_fragment_exported)
23177330f729Sjoerg << /*global*/0 << FixItHint::CreateRemoval(StartLoc);
23187330f729Sjoerg }
23197330f729Sjoerg return Actions.ActOnGlobalModuleFragmentDecl(ModuleLoc);
23207330f729Sjoerg }
23217330f729Sjoerg
23227330f729Sjoerg // Parse a private-module-fragment, if present.
23237330f729Sjoerg if (getLangOpts().CPlusPlusModules && Tok.is(tok::colon) &&
23247330f729Sjoerg NextToken().is(tok::kw_private)) {
23257330f729Sjoerg if (MDK == Sema::ModuleDeclKind::Interface) {
23267330f729Sjoerg Diag(StartLoc, diag::err_module_fragment_exported)
23277330f729Sjoerg << /*private*/1 << FixItHint::CreateRemoval(StartLoc);
23287330f729Sjoerg }
23297330f729Sjoerg ConsumeToken();
23307330f729Sjoerg SourceLocation PrivateLoc = ConsumeToken();
23317330f729Sjoerg DiagnoseAndSkipCXX11Attributes();
23327330f729Sjoerg ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);
23337330f729Sjoerg return Actions.ActOnPrivateModuleFragmentDecl(ModuleLoc, PrivateLoc);
23347330f729Sjoerg }
23357330f729Sjoerg
23367330f729Sjoerg SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
23377330f729Sjoerg if (ParseModuleName(ModuleLoc, Path, /*IsImport*/false))
23387330f729Sjoerg return nullptr;
23397330f729Sjoerg
23407330f729Sjoerg // Parse the optional module-partition.
23417330f729Sjoerg if (Tok.is(tok::colon)) {
23427330f729Sjoerg SourceLocation ColonLoc = ConsumeToken();
23437330f729Sjoerg SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Partition;
23447330f729Sjoerg if (ParseModuleName(ModuleLoc, Partition, /*IsImport*/false))
23457330f729Sjoerg return nullptr;
23467330f729Sjoerg
23477330f729Sjoerg // FIXME: Support module partition declarations.
23487330f729Sjoerg Diag(ColonLoc, diag::err_unsupported_module_partition)
23497330f729Sjoerg << SourceRange(ColonLoc, Partition.back().second);
23507330f729Sjoerg // Recover by parsing as a non-partition.
23517330f729Sjoerg }
23527330f729Sjoerg
23537330f729Sjoerg // We don't support any module attributes yet; just parse them and diagnose.
23547330f729Sjoerg ParsedAttributesWithRange Attrs(AttrFactory);
23557330f729Sjoerg MaybeParseCXX11Attributes(Attrs);
23567330f729Sjoerg ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr);
23577330f729Sjoerg
23587330f729Sjoerg ExpectAndConsumeSemi(diag::err_module_expected_semi);
23597330f729Sjoerg
23607330f729Sjoerg return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, IsFirstDecl);
23617330f729Sjoerg }
23627330f729Sjoerg
23637330f729Sjoerg /// Parse a module import declaration. This is essentially the same for
23647330f729Sjoerg /// Objective-C and the C++ Modules TS, except for the leading '@' (in ObjC)
23657330f729Sjoerg /// and the trailing optional attributes (in C++).
23667330f729Sjoerg ///
23677330f729Sjoerg /// [ObjC] @import declaration:
23687330f729Sjoerg /// '@' 'import' module-name ';'
23697330f729Sjoerg /// [ModTS] module-import-declaration:
23707330f729Sjoerg /// 'import' module-name attribute-specifier-seq[opt] ';'
23717330f729Sjoerg /// [C++2a] module-import-declaration:
23727330f729Sjoerg /// 'export'[opt] 'import' module-name
23737330f729Sjoerg /// attribute-specifier-seq[opt] ';'
23747330f729Sjoerg /// 'export'[opt] 'import' module-partition
23757330f729Sjoerg /// attribute-specifier-seq[opt] ';'
23767330f729Sjoerg /// 'export'[opt] 'import' header-name
23777330f729Sjoerg /// attribute-specifier-seq[opt] ';'
ParseModuleImport(SourceLocation AtLoc)23787330f729Sjoerg Decl *Parser::ParseModuleImport(SourceLocation AtLoc) {
23797330f729Sjoerg SourceLocation StartLoc = AtLoc.isInvalid() ? Tok.getLocation() : AtLoc;
23807330f729Sjoerg
23817330f729Sjoerg SourceLocation ExportLoc;
23827330f729Sjoerg TryConsumeToken(tok::kw_export, ExportLoc);
23837330f729Sjoerg
23847330f729Sjoerg assert((AtLoc.isInvalid() ? Tok.isOneOf(tok::kw_import, tok::identifier)
23857330f729Sjoerg : Tok.isObjCAtKeyword(tok::objc_import)) &&
23867330f729Sjoerg "Improper start to module import");
23877330f729Sjoerg bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import);
23887330f729Sjoerg SourceLocation ImportLoc = ConsumeToken();
23897330f729Sjoerg
23907330f729Sjoerg SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
23917330f729Sjoerg Module *HeaderUnit = nullptr;
23927330f729Sjoerg
23937330f729Sjoerg if (Tok.is(tok::header_name)) {
23947330f729Sjoerg // This is a header import that the preprocessor decided we should skip
23957330f729Sjoerg // because it was malformed in some way. Parse and ignore it; it's already
23967330f729Sjoerg // been diagnosed.
23977330f729Sjoerg ConsumeToken();
23987330f729Sjoerg } else if (Tok.is(tok::annot_header_unit)) {
23997330f729Sjoerg // This is a header import that the preprocessor mapped to a module import.
24007330f729Sjoerg HeaderUnit = reinterpret_cast<Module *>(Tok.getAnnotationValue());
24017330f729Sjoerg ConsumeAnnotationToken();
24027330f729Sjoerg } else if (getLangOpts().CPlusPlusModules && Tok.is(tok::colon)) {
24037330f729Sjoerg SourceLocation ColonLoc = ConsumeToken();
24047330f729Sjoerg if (ParseModuleName(ImportLoc, Path, /*IsImport*/true))
24057330f729Sjoerg return nullptr;
24067330f729Sjoerg
24077330f729Sjoerg // FIXME: Support module partition import.
24087330f729Sjoerg Diag(ColonLoc, diag::err_unsupported_module_partition)
24097330f729Sjoerg << SourceRange(ColonLoc, Path.back().second);
24107330f729Sjoerg return nullptr;
24117330f729Sjoerg } else {
24127330f729Sjoerg if (ParseModuleName(ImportLoc, Path, /*IsImport*/true))
24137330f729Sjoerg return nullptr;
24147330f729Sjoerg }
24157330f729Sjoerg
24167330f729Sjoerg ParsedAttributesWithRange Attrs(AttrFactory);
24177330f729Sjoerg MaybeParseCXX11Attributes(Attrs);
24187330f729Sjoerg // We don't support any module import attributes yet.
24197330f729Sjoerg ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr);
24207330f729Sjoerg
24217330f729Sjoerg if (PP.hadModuleLoaderFatalFailure()) {
24227330f729Sjoerg // With a fatal failure in the module loader, we abort parsing.
24237330f729Sjoerg cutOffParsing();
24247330f729Sjoerg return nullptr;
24257330f729Sjoerg }
24267330f729Sjoerg
24277330f729Sjoerg DeclResult Import;
24287330f729Sjoerg if (HeaderUnit)
24297330f729Sjoerg Import =
24307330f729Sjoerg Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, HeaderUnit);
24317330f729Sjoerg else if (!Path.empty())
24327330f729Sjoerg Import = Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Path);
24337330f729Sjoerg ExpectAndConsumeSemi(diag::err_module_expected_semi);
24347330f729Sjoerg if (Import.isInvalid())
24357330f729Sjoerg return nullptr;
24367330f729Sjoerg
24377330f729Sjoerg // Using '@import' in framework headers requires modules to be enabled so that
24387330f729Sjoerg // the header is parseable. Emit a warning to make the user aware.
24397330f729Sjoerg if (IsObjCAtImport && AtLoc.isValid()) {
24407330f729Sjoerg auto &SrcMgr = PP.getSourceManager();
24417330f729Sjoerg auto *FE = SrcMgr.getFileEntryForID(SrcMgr.getFileID(AtLoc));
24427330f729Sjoerg if (FE && llvm::sys::path::parent_path(FE->getDir()->getName())
24437330f729Sjoerg .endswith(".framework"))
24447330f729Sjoerg Diags.Report(AtLoc, diag::warn_atimport_in_framework_header);
24457330f729Sjoerg }
24467330f729Sjoerg
24477330f729Sjoerg return Import.get();
24487330f729Sjoerg }
24497330f729Sjoerg
24507330f729Sjoerg /// Parse a C++ Modules TS / Objective-C module name (both forms use the same
24517330f729Sjoerg /// grammar).
24527330f729Sjoerg ///
24537330f729Sjoerg /// module-name:
24547330f729Sjoerg /// module-name-qualifier[opt] identifier
24557330f729Sjoerg /// module-name-qualifier:
24567330f729Sjoerg /// module-name-qualifier[opt] identifier '.'
ParseModuleName(SourceLocation UseLoc,SmallVectorImpl<std::pair<IdentifierInfo *,SourceLocation>> & Path,bool IsImport)24577330f729Sjoerg bool Parser::ParseModuleName(
24587330f729Sjoerg SourceLocation UseLoc,
24597330f729Sjoerg SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
24607330f729Sjoerg bool IsImport) {
24617330f729Sjoerg // Parse the module path.
24627330f729Sjoerg while (true) {
24637330f729Sjoerg if (!Tok.is(tok::identifier)) {
24647330f729Sjoerg if (Tok.is(tok::code_completion)) {
24657330f729Sjoerg cutOffParsing();
2466*e038c9c4Sjoerg Actions.CodeCompleteModuleImport(UseLoc, Path);
24677330f729Sjoerg return true;
24687330f729Sjoerg }
24697330f729Sjoerg
24707330f729Sjoerg Diag(Tok, diag::err_module_expected_ident) << IsImport;
24717330f729Sjoerg SkipUntil(tok::semi);
24727330f729Sjoerg return true;
24737330f729Sjoerg }
24747330f729Sjoerg
24757330f729Sjoerg // Record this part of the module path.
24767330f729Sjoerg Path.push_back(std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation()));
24777330f729Sjoerg ConsumeToken();
24787330f729Sjoerg
24797330f729Sjoerg if (Tok.isNot(tok::period))
24807330f729Sjoerg return false;
24817330f729Sjoerg
24827330f729Sjoerg ConsumeToken();
24837330f729Sjoerg }
24847330f729Sjoerg }
24857330f729Sjoerg
24867330f729Sjoerg /// Try recover parser when module annotation appears where it must not
24877330f729Sjoerg /// be found.
24887330f729Sjoerg /// \returns false if the recover was successful and parsing may be continued, or
24897330f729Sjoerg /// true if parser must bail out to top level and handle the token there.
parseMisplacedModuleImport()24907330f729Sjoerg bool Parser::parseMisplacedModuleImport() {
24917330f729Sjoerg while (true) {
24927330f729Sjoerg switch (Tok.getKind()) {
24937330f729Sjoerg case tok::annot_module_end:
24947330f729Sjoerg // If we recovered from a misplaced module begin, we expect to hit a
24957330f729Sjoerg // misplaced module end too. Stay in the current context when this
24967330f729Sjoerg // happens.
24977330f729Sjoerg if (MisplacedModuleBeginCount) {
24987330f729Sjoerg --MisplacedModuleBeginCount;
24997330f729Sjoerg Actions.ActOnModuleEnd(Tok.getLocation(),
25007330f729Sjoerg reinterpret_cast<Module *>(
25017330f729Sjoerg Tok.getAnnotationValue()));
25027330f729Sjoerg ConsumeAnnotationToken();
25037330f729Sjoerg continue;
25047330f729Sjoerg }
25057330f729Sjoerg // Inform caller that recovery failed, the error must be handled at upper
25067330f729Sjoerg // level. This will generate the desired "missing '}' at end of module"
25077330f729Sjoerg // diagnostics on the way out.
25087330f729Sjoerg return true;
25097330f729Sjoerg case tok::annot_module_begin:
25107330f729Sjoerg // Recover by entering the module (Sema will diagnose).
25117330f729Sjoerg Actions.ActOnModuleBegin(Tok.getLocation(),
25127330f729Sjoerg reinterpret_cast<Module *>(
25137330f729Sjoerg Tok.getAnnotationValue()));
25147330f729Sjoerg ConsumeAnnotationToken();
25157330f729Sjoerg ++MisplacedModuleBeginCount;
25167330f729Sjoerg continue;
25177330f729Sjoerg case tok::annot_module_include:
25187330f729Sjoerg // Module import found where it should not be, for instance, inside a
25197330f729Sjoerg // namespace. Recover by importing the module.
25207330f729Sjoerg Actions.ActOnModuleInclude(Tok.getLocation(),
25217330f729Sjoerg reinterpret_cast<Module *>(
25227330f729Sjoerg Tok.getAnnotationValue()));
25237330f729Sjoerg ConsumeAnnotationToken();
25247330f729Sjoerg // If there is another module import, process it.
25257330f729Sjoerg continue;
25267330f729Sjoerg default:
25277330f729Sjoerg return false;
25287330f729Sjoerg }
25297330f729Sjoerg }
25307330f729Sjoerg return false;
25317330f729Sjoerg }
25327330f729Sjoerg
diagnoseOverflow()25337330f729Sjoerg bool BalancedDelimiterTracker::diagnoseOverflow() {
25347330f729Sjoerg P.Diag(P.Tok, diag::err_bracket_depth_exceeded)
25357330f729Sjoerg << P.getLangOpts().BracketDepth;
25367330f729Sjoerg P.Diag(P.Tok, diag::note_bracket_depth);
25377330f729Sjoerg P.cutOffParsing();
25387330f729Sjoerg return true;
25397330f729Sjoerg }
25407330f729Sjoerg
expectAndConsume(unsigned DiagID,const char * Msg,tok::TokenKind SkipToTok)25417330f729Sjoerg bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
25427330f729Sjoerg const char *Msg,
25437330f729Sjoerg tok::TokenKind SkipToTok) {
25447330f729Sjoerg LOpen = P.Tok.getLocation();
25457330f729Sjoerg if (P.ExpectAndConsume(Kind, DiagID, Msg)) {
25467330f729Sjoerg if (SkipToTok != tok::unknown)
25477330f729Sjoerg P.SkipUntil(SkipToTok, Parser::StopAtSemi);
25487330f729Sjoerg return true;
25497330f729Sjoerg }
25507330f729Sjoerg
25517330f729Sjoerg if (getDepth() < P.getLangOpts().BracketDepth)
25527330f729Sjoerg return false;
25537330f729Sjoerg
25547330f729Sjoerg return diagnoseOverflow();
25557330f729Sjoerg }
25567330f729Sjoerg
diagnoseMissingClose()25577330f729Sjoerg bool BalancedDelimiterTracker::diagnoseMissingClose() {
25587330f729Sjoerg assert(!P.Tok.is(Close) && "Should have consumed closing delimiter");
25597330f729Sjoerg
25607330f729Sjoerg if (P.Tok.is(tok::annot_module_end))
25617330f729Sjoerg P.Diag(P.Tok, diag::err_missing_before_module_end) << Close;
25627330f729Sjoerg else
25637330f729Sjoerg P.Diag(P.Tok, diag::err_expected) << Close;
25647330f729Sjoerg P.Diag(LOpen, diag::note_matching) << Kind;
25657330f729Sjoerg
25667330f729Sjoerg // If we're not already at some kind of closing bracket, skip to our closing
25677330f729Sjoerg // token.
25687330f729Sjoerg if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) &&
25697330f729Sjoerg P.Tok.isNot(tok::r_square) &&
25707330f729Sjoerg P.SkipUntil(Close, FinalToken,
25717330f729Sjoerg Parser::StopAtSemi | Parser::StopBeforeMatch) &&
25727330f729Sjoerg P.Tok.is(Close))
25737330f729Sjoerg LClose = P.ConsumeAnyToken();
25747330f729Sjoerg return true;
25757330f729Sjoerg }
25767330f729Sjoerg
skipToEnd()25777330f729Sjoerg void BalancedDelimiterTracker::skipToEnd() {
25787330f729Sjoerg P.SkipUntil(Close, Parser::StopBeforeMatch);
25797330f729Sjoerg consumeClose();
25807330f729Sjoerg }
2581