1e5dd7070Spatrick //===--- Parser.cpp - C Language Family Parser ----------------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements the Parser interfaces.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "clang/Parse/Parser.h"
14e5dd7070Spatrick #include "clang/AST/ASTConsumer.h"
15e5dd7070Spatrick #include "clang/AST/ASTContext.h"
16e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
17ec727ea7Spatrick #include "clang/Basic/FileManager.h"
18e5dd7070Spatrick #include "clang/Parse/ParseDiagnostic.h"
19e5dd7070Spatrick #include "clang/Parse/RAIIObjectsForParser.h"
20e5dd7070Spatrick #include "clang/Sema/DeclSpec.h"
21e5dd7070Spatrick #include "clang/Sema/ParsedTemplate.h"
22e5dd7070Spatrick #include "clang/Sema/Scope.h"
23e5dd7070Spatrick #include "llvm/Support/Path.h"
24e5dd7070Spatrick using namespace clang;
25e5dd7070Spatrick
26e5dd7070Spatrick
27e5dd7070Spatrick namespace {
28e5dd7070Spatrick /// A comment handler that passes comments found by the preprocessor
29e5dd7070Spatrick /// to the parser action.
30e5dd7070Spatrick class ActionCommentHandler : public CommentHandler {
31e5dd7070Spatrick Sema &S;
32e5dd7070Spatrick
33e5dd7070Spatrick public:
ActionCommentHandler(Sema & S)34e5dd7070Spatrick explicit ActionCommentHandler(Sema &S) : S(S) { }
35e5dd7070Spatrick
HandleComment(Preprocessor & PP,SourceRange Comment)36e5dd7070Spatrick bool HandleComment(Preprocessor &PP, SourceRange Comment) override {
37e5dd7070Spatrick S.ActOnComment(Comment);
38e5dd7070Spatrick return false;
39e5dd7070Spatrick }
40e5dd7070Spatrick };
41e5dd7070Spatrick } // end anonymous namespace
42e5dd7070Spatrick
getSEHExceptKeyword()43e5dd7070Spatrick IdentifierInfo *Parser::getSEHExceptKeyword() {
44e5dd7070Spatrick // __except is accepted as a (contextual) keyword
45e5dd7070Spatrick if (!Ident__except && (getLangOpts().MicrosoftExt || getLangOpts().Borland))
46e5dd7070Spatrick Ident__except = PP.getIdentifierInfo("__except");
47e5dd7070Spatrick
48e5dd7070Spatrick return Ident__except;
49e5dd7070Spatrick }
50e5dd7070Spatrick
Parser(Preprocessor & pp,Sema & actions,bool skipFunctionBodies)51e5dd7070Spatrick Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
52a9ac8606Spatrick : PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),
53a9ac8606Spatrick Diags(PP.getDiagnostics()), GreaterThanIsOperator(true),
54a9ac8606Spatrick ColonIsSacred(false), InMessageExpression(false),
55a9ac8606Spatrick TemplateParameterDepth(0), ParsingInObjCContainer(false) {
56e5dd7070Spatrick SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
57e5dd7070Spatrick Tok.startToken();
58e5dd7070Spatrick Tok.setKind(tok::eof);
59e5dd7070Spatrick Actions.CurScope = nullptr;
60e5dd7070Spatrick NumCachedScopes = 0;
61e5dd7070Spatrick CurParsedObjCImpl = nullptr;
62e5dd7070Spatrick
63e5dd7070Spatrick // Add #pragma handlers. These are removed and destroyed in the
64e5dd7070Spatrick // destructor.
65e5dd7070Spatrick initializePragmaHandlers();
66e5dd7070Spatrick
67e5dd7070Spatrick CommentSemaHandler.reset(new ActionCommentHandler(actions));
68e5dd7070Spatrick PP.addCommentHandler(CommentSemaHandler.get());
69e5dd7070Spatrick
70e5dd7070Spatrick PP.setCodeCompletionHandler(*this);
71e5dd7070Spatrick }
72e5dd7070Spatrick
Diag(SourceLocation Loc,unsigned DiagID)73e5dd7070Spatrick DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
74e5dd7070Spatrick return Diags.Report(Loc, DiagID);
75e5dd7070Spatrick }
76e5dd7070Spatrick
Diag(const Token & Tok,unsigned DiagID)77e5dd7070Spatrick DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) {
78e5dd7070Spatrick return Diag(Tok.getLocation(), DiagID);
79e5dd7070Spatrick }
80e5dd7070Spatrick
81e5dd7070Spatrick /// Emits a diagnostic suggesting parentheses surrounding a
82e5dd7070Spatrick /// given range.
83e5dd7070Spatrick ///
84e5dd7070Spatrick /// \param Loc The location where we'll emit the diagnostic.
85e5dd7070Spatrick /// \param DK The kind of diagnostic to emit.
86e5dd7070Spatrick /// \param ParenRange Source range enclosing code that should be parenthesized.
SuggestParentheses(SourceLocation Loc,unsigned DK,SourceRange ParenRange)87e5dd7070Spatrick void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK,
88e5dd7070Spatrick SourceRange ParenRange) {
89e5dd7070Spatrick SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd());
90e5dd7070Spatrick if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) {
91e5dd7070Spatrick // We can't display the parentheses, so just dig the
92e5dd7070Spatrick // warning/error and return.
93e5dd7070Spatrick Diag(Loc, DK);
94e5dd7070Spatrick return;
95e5dd7070Spatrick }
96e5dd7070Spatrick
97e5dd7070Spatrick Diag(Loc, DK)
98e5dd7070Spatrick << FixItHint::CreateInsertion(ParenRange.getBegin(), "(")
99e5dd7070Spatrick << FixItHint::CreateInsertion(EndLoc, ")");
100e5dd7070Spatrick }
101e5dd7070Spatrick
IsCommonTypo(tok::TokenKind ExpectedTok,const Token & Tok)102e5dd7070Spatrick static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok) {
103e5dd7070Spatrick switch (ExpectedTok) {
104e5dd7070Spatrick case tok::semi:
105e5dd7070Spatrick return Tok.is(tok::colon) || Tok.is(tok::comma); // : or , for ;
106e5dd7070Spatrick default: return false;
107e5dd7070Spatrick }
108e5dd7070Spatrick }
109e5dd7070Spatrick
ExpectAndConsume(tok::TokenKind ExpectedTok,unsigned DiagID,StringRef Msg)110e5dd7070Spatrick bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
111e5dd7070Spatrick StringRef Msg) {
112e5dd7070Spatrick if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) {
113e5dd7070Spatrick ConsumeAnyToken();
114e5dd7070Spatrick return false;
115e5dd7070Spatrick }
116e5dd7070Spatrick
117e5dd7070Spatrick // Detect common single-character typos and resume.
118e5dd7070Spatrick if (IsCommonTypo(ExpectedTok, Tok)) {
119e5dd7070Spatrick SourceLocation Loc = Tok.getLocation();
120e5dd7070Spatrick {
121e5dd7070Spatrick DiagnosticBuilder DB = Diag(Loc, DiagID);
122e5dd7070Spatrick DB << FixItHint::CreateReplacement(
123e5dd7070Spatrick SourceRange(Loc), tok::getPunctuatorSpelling(ExpectedTok));
124e5dd7070Spatrick if (DiagID == diag::err_expected)
125e5dd7070Spatrick DB << ExpectedTok;
126e5dd7070Spatrick else if (DiagID == diag::err_expected_after)
127e5dd7070Spatrick DB << Msg << ExpectedTok;
128e5dd7070Spatrick else
129e5dd7070Spatrick DB << Msg;
130e5dd7070Spatrick }
131e5dd7070Spatrick
132e5dd7070Spatrick // Pretend there wasn't a problem.
133e5dd7070Spatrick ConsumeAnyToken();
134e5dd7070Spatrick return false;
135e5dd7070Spatrick }
136e5dd7070Spatrick
137e5dd7070Spatrick SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
138e5dd7070Spatrick const char *Spelling = nullptr;
139e5dd7070Spatrick if (EndLoc.isValid())
140e5dd7070Spatrick Spelling = tok::getPunctuatorSpelling(ExpectedTok);
141e5dd7070Spatrick
142e5dd7070Spatrick DiagnosticBuilder DB =
143e5dd7070Spatrick Spelling
144e5dd7070Spatrick ? Diag(EndLoc, DiagID) << FixItHint::CreateInsertion(EndLoc, Spelling)
145e5dd7070Spatrick : Diag(Tok, DiagID);
146e5dd7070Spatrick if (DiagID == diag::err_expected)
147e5dd7070Spatrick DB << ExpectedTok;
148e5dd7070Spatrick else if (DiagID == diag::err_expected_after)
149e5dd7070Spatrick DB << Msg << ExpectedTok;
150e5dd7070Spatrick else
151e5dd7070Spatrick DB << Msg;
152e5dd7070Spatrick
153e5dd7070Spatrick return true;
154e5dd7070Spatrick }
155e5dd7070Spatrick
ExpectAndConsumeSemi(unsigned DiagID,StringRef TokenUsed)156*12c85518Srobert bool Parser::ExpectAndConsumeSemi(unsigned DiagID, StringRef TokenUsed) {
157e5dd7070Spatrick if (TryConsumeToken(tok::semi))
158e5dd7070Spatrick return false;
159e5dd7070Spatrick
160e5dd7070Spatrick if (Tok.is(tok::code_completion)) {
161e5dd7070Spatrick handleUnexpectedCodeCompletionToken();
162e5dd7070Spatrick return false;
163e5dd7070Spatrick }
164e5dd7070Spatrick
165e5dd7070Spatrick if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) &&
166e5dd7070Spatrick NextToken().is(tok::semi)) {
167e5dd7070Spatrick Diag(Tok, diag::err_extraneous_token_before_semi)
168e5dd7070Spatrick << PP.getSpelling(Tok)
169e5dd7070Spatrick << FixItHint::CreateRemoval(Tok.getLocation());
170e5dd7070Spatrick ConsumeAnyToken(); // The ')' or ']'.
171e5dd7070Spatrick ConsumeToken(); // The ';'.
172e5dd7070Spatrick return false;
173e5dd7070Spatrick }
174e5dd7070Spatrick
175*12c85518Srobert return ExpectAndConsume(tok::semi, DiagID , TokenUsed);
176e5dd7070Spatrick }
177e5dd7070Spatrick
ConsumeExtraSemi(ExtraSemiKind Kind,DeclSpec::TST TST)178e5dd7070Spatrick void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, DeclSpec::TST TST) {
179e5dd7070Spatrick if (!Tok.is(tok::semi)) return;
180e5dd7070Spatrick
181e5dd7070Spatrick bool HadMultipleSemis = false;
182e5dd7070Spatrick SourceLocation StartLoc = Tok.getLocation();
183e5dd7070Spatrick SourceLocation EndLoc = Tok.getLocation();
184e5dd7070Spatrick ConsumeToken();
185e5dd7070Spatrick
186e5dd7070Spatrick while ((Tok.is(tok::semi) && !Tok.isAtStartOfLine())) {
187e5dd7070Spatrick HadMultipleSemis = true;
188e5dd7070Spatrick EndLoc = Tok.getLocation();
189e5dd7070Spatrick ConsumeToken();
190e5dd7070Spatrick }
191e5dd7070Spatrick
192e5dd7070Spatrick // C++11 allows extra semicolons at namespace scope, but not in any of the
193e5dd7070Spatrick // other contexts.
194e5dd7070Spatrick if (Kind == OutsideFunction && getLangOpts().CPlusPlus) {
195e5dd7070Spatrick if (getLangOpts().CPlusPlus11)
196e5dd7070Spatrick Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi)
197e5dd7070Spatrick << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
198e5dd7070Spatrick else
199e5dd7070Spatrick Diag(StartLoc, diag::ext_extra_semi_cxx11)
200e5dd7070Spatrick << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
201e5dd7070Spatrick return;
202e5dd7070Spatrick }
203e5dd7070Spatrick
204e5dd7070Spatrick if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis)
205e5dd7070Spatrick Diag(StartLoc, diag::ext_extra_semi)
206e5dd7070Spatrick << Kind << DeclSpec::getSpecifierName(TST,
207e5dd7070Spatrick Actions.getASTContext().getPrintingPolicy())
208e5dd7070Spatrick << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
209e5dd7070Spatrick else
210e5dd7070Spatrick // A single semicolon is valid after a member function definition.
211e5dd7070Spatrick Diag(StartLoc, diag::warn_extra_semi_after_mem_fn_def)
212e5dd7070Spatrick << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
213e5dd7070Spatrick }
214e5dd7070Spatrick
expectIdentifier()215e5dd7070Spatrick bool Parser::expectIdentifier() {
216e5dd7070Spatrick if (Tok.is(tok::identifier))
217e5dd7070Spatrick return false;
218e5dd7070Spatrick if (const auto *II = Tok.getIdentifierInfo()) {
219e5dd7070Spatrick if (II->isCPlusPlusKeyword(getLangOpts())) {
220e5dd7070Spatrick Diag(Tok, diag::err_expected_token_instead_of_objcxx_keyword)
221e5dd7070Spatrick << tok::identifier << Tok.getIdentifierInfo();
222e5dd7070Spatrick // Objective-C++: Recover by treating this keyword as a valid identifier.
223e5dd7070Spatrick return false;
224e5dd7070Spatrick }
225e5dd7070Spatrick }
226e5dd7070Spatrick Diag(Tok, diag::err_expected) << tok::identifier;
227e5dd7070Spatrick return true;
228e5dd7070Spatrick }
229e5dd7070Spatrick
checkCompoundToken(SourceLocation FirstTokLoc,tok::TokenKind FirstTokKind,CompoundToken Op)230a9ac8606Spatrick void Parser::checkCompoundToken(SourceLocation FirstTokLoc,
231a9ac8606Spatrick tok::TokenKind FirstTokKind, CompoundToken Op) {
232a9ac8606Spatrick if (FirstTokLoc.isInvalid())
233a9ac8606Spatrick return;
234a9ac8606Spatrick SourceLocation SecondTokLoc = Tok.getLocation();
235a9ac8606Spatrick
236a9ac8606Spatrick // If either token is in a macro, we expect both tokens to come from the same
237a9ac8606Spatrick // macro expansion.
238a9ac8606Spatrick if ((FirstTokLoc.isMacroID() || SecondTokLoc.isMacroID()) &&
239a9ac8606Spatrick PP.getSourceManager().getFileID(FirstTokLoc) !=
240a9ac8606Spatrick PP.getSourceManager().getFileID(SecondTokLoc)) {
241a9ac8606Spatrick Diag(FirstTokLoc, diag::warn_compound_token_split_by_macro)
242a9ac8606Spatrick << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind()
243a9ac8606Spatrick << static_cast<int>(Op) << SourceRange(FirstTokLoc);
244a9ac8606Spatrick Diag(SecondTokLoc, diag::note_compound_token_split_second_token_here)
245a9ac8606Spatrick << (FirstTokKind == Tok.getKind()) << Tok.getKind()
246a9ac8606Spatrick << SourceRange(SecondTokLoc);
247a9ac8606Spatrick return;
248a9ac8606Spatrick }
249a9ac8606Spatrick
250a9ac8606Spatrick // We expect the tokens to abut.
251a9ac8606Spatrick if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) {
252a9ac8606Spatrick SourceLocation SpaceLoc = PP.getLocForEndOfToken(FirstTokLoc);
253a9ac8606Spatrick if (SpaceLoc.isInvalid())
254a9ac8606Spatrick SpaceLoc = FirstTokLoc;
255a9ac8606Spatrick Diag(SpaceLoc, diag::warn_compound_token_split_by_whitespace)
256a9ac8606Spatrick << (FirstTokKind == Tok.getKind()) << FirstTokKind << Tok.getKind()
257a9ac8606Spatrick << static_cast<int>(Op) << SourceRange(FirstTokLoc, SecondTokLoc);
258a9ac8606Spatrick return;
259a9ac8606Spatrick }
260a9ac8606Spatrick }
261a9ac8606Spatrick
262e5dd7070Spatrick //===----------------------------------------------------------------------===//
263e5dd7070Spatrick // Error recovery.
264e5dd7070Spatrick //===----------------------------------------------------------------------===//
265e5dd7070Spatrick
HasFlagsSet(Parser::SkipUntilFlags L,Parser::SkipUntilFlags R)266e5dd7070Spatrick static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) {
267e5dd7070Spatrick return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0;
268e5dd7070Spatrick }
269e5dd7070Spatrick
270e5dd7070Spatrick /// SkipUntil - Read tokens until we get to the specified token, then consume
271e5dd7070Spatrick /// it (unless no flag StopBeforeMatch). Because we cannot guarantee that the
272e5dd7070Spatrick /// token will ever occur, this skips to the next token, or to some likely
273e5dd7070Spatrick /// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
274e5dd7070Spatrick /// character.
275e5dd7070Spatrick ///
276e5dd7070Spatrick /// If SkipUntil finds the specified token, it returns true, otherwise it
277e5dd7070Spatrick /// returns false.
SkipUntil(ArrayRef<tok::TokenKind> Toks,SkipUntilFlags Flags)278e5dd7070Spatrick bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
279e5dd7070Spatrick // We always want this function to skip at least one token if the first token
280e5dd7070Spatrick // isn't T and if not at EOF.
281e5dd7070Spatrick bool isFirstTokenSkipped = true;
282*12c85518Srobert while (true) {
283e5dd7070Spatrick // If we found one of the tokens, stop and return true.
284e5dd7070Spatrick for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) {
285e5dd7070Spatrick if (Tok.is(Toks[i])) {
286e5dd7070Spatrick if (HasFlagsSet(Flags, StopBeforeMatch)) {
287e5dd7070Spatrick // Noop, don't consume the token.
288e5dd7070Spatrick } else {
289e5dd7070Spatrick ConsumeAnyToken();
290e5dd7070Spatrick }
291e5dd7070Spatrick return true;
292e5dd7070Spatrick }
293e5dd7070Spatrick }
294e5dd7070Spatrick
295e5dd7070Spatrick // Important special case: The caller has given up and just wants us to
296e5dd7070Spatrick // skip the rest of the file. Do this without recursing, since we can
297e5dd7070Spatrick // get here precisely because the caller detected too much recursion.
298e5dd7070Spatrick if (Toks.size() == 1 && Toks[0] == tok::eof &&
299e5dd7070Spatrick !HasFlagsSet(Flags, StopAtSemi) &&
300e5dd7070Spatrick !HasFlagsSet(Flags, StopAtCodeCompletion)) {
301e5dd7070Spatrick while (Tok.isNot(tok::eof))
302e5dd7070Spatrick ConsumeAnyToken();
303e5dd7070Spatrick return true;
304e5dd7070Spatrick }
305e5dd7070Spatrick
306e5dd7070Spatrick switch (Tok.getKind()) {
307e5dd7070Spatrick case tok::eof:
308e5dd7070Spatrick // Ran out of tokens.
309e5dd7070Spatrick return false;
310e5dd7070Spatrick
311e5dd7070Spatrick case tok::annot_pragma_openmp:
312a9ac8606Spatrick case tok::annot_attr_openmp:
313e5dd7070Spatrick case tok::annot_pragma_openmp_end:
314e5dd7070Spatrick // Stop before an OpenMP pragma boundary.
315e5dd7070Spatrick if (OpenMPDirectiveParsing)
316e5dd7070Spatrick return false;
317e5dd7070Spatrick ConsumeAnnotationToken();
318e5dd7070Spatrick break;
319e5dd7070Spatrick case tok::annot_module_begin:
320e5dd7070Spatrick case tok::annot_module_end:
321e5dd7070Spatrick case tok::annot_module_include:
322e5dd7070Spatrick // Stop before we change submodules. They generally indicate a "good"
323e5dd7070Spatrick // place to pick up parsing again (except in the special case where
324e5dd7070Spatrick // we're trying to skip to EOF).
325e5dd7070Spatrick return false;
326e5dd7070Spatrick
327e5dd7070Spatrick case tok::code_completion:
328e5dd7070Spatrick if (!HasFlagsSet(Flags, StopAtCodeCompletion))
329e5dd7070Spatrick handleUnexpectedCodeCompletionToken();
330e5dd7070Spatrick return false;
331e5dd7070Spatrick
332e5dd7070Spatrick case tok::l_paren:
333e5dd7070Spatrick // Recursively skip properly-nested parens.
334e5dd7070Spatrick ConsumeParen();
335e5dd7070Spatrick if (HasFlagsSet(Flags, StopAtCodeCompletion))
336e5dd7070Spatrick SkipUntil(tok::r_paren, StopAtCodeCompletion);
337e5dd7070Spatrick else
338e5dd7070Spatrick SkipUntil(tok::r_paren);
339e5dd7070Spatrick break;
340e5dd7070Spatrick case tok::l_square:
341e5dd7070Spatrick // Recursively skip properly-nested square brackets.
342e5dd7070Spatrick ConsumeBracket();
343e5dd7070Spatrick if (HasFlagsSet(Flags, StopAtCodeCompletion))
344e5dd7070Spatrick SkipUntil(tok::r_square, StopAtCodeCompletion);
345e5dd7070Spatrick else
346e5dd7070Spatrick SkipUntil(tok::r_square);
347e5dd7070Spatrick break;
348e5dd7070Spatrick case tok::l_brace:
349e5dd7070Spatrick // Recursively skip properly-nested braces.
350e5dd7070Spatrick ConsumeBrace();
351e5dd7070Spatrick if (HasFlagsSet(Flags, StopAtCodeCompletion))
352e5dd7070Spatrick SkipUntil(tok::r_brace, StopAtCodeCompletion);
353e5dd7070Spatrick else
354e5dd7070Spatrick SkipUntil(tok::r_brace);
355e5dd7070Spatrick break;
356e5dd7070Spatrick case tok::question:
357e5dd7070Spatrick // Recursively skip ? ... : pairs; these function as brackets. But
358e5dd7070Spatrick // still stop at a semicolon if requested.
359e5dd7070Spatrick ConsumeToken();
360e5dd7070Spatrick SkipUntil(tok::colon,
361e5dd7070Spatrick SkipUntilFlags(unsigned(Flags) &
362e5dd7070Spatrick unsigned(StopAtCodeCompletion | StopAtSemi)));
363e5dd7070Spatrick break;
364e5dd7070Spatrick
365e5dd7070Spatrick // Okay, we found a ']' or '}' or ')', which we think should be balanced.
366e5dd7070Spatrick // Since the user wasn't looking for this token (if they were, it would
367e5dd7070Spatrick // already be handled), this isn't balanced. If there is a LHS token at a
368e5dd7070Spatrick // higher level, we will assume that this matches the unbalanced token
369e5dd7070Spatrick // and return it. Otherwise, this is a spurious RHS token, which we skip.
370e5dd7070Spatrick case tok::r_paren:
371e5dd7070Spatrick if (ParenCount && !isFirstTokenSkipped)
372e5dd7070Spatrick return false; // Matches something.
373e5dd7070Spatrick ConsumeParen();
374e5dd7070Spatrick break;
375e5dd7070Spatrick case tok::r_square:
376e5dd7070Spatrick if (BracketCount && !isFirstTokenSkipped)
377e5dd7070Spatrick return false; // Matches something.
378e5dd7070Spatrick ConsumeBracket();
379e5dd7070Spatrick break;
380e5dd7070Spatrick case tok::r_brace:
381e5dd7070Spatrick if (BraceCount && !isFirstTokenSkipped)
382e5dd7070Spatrick return false; // Matches something.
383e5dd7070Spatrick ConsumeBrace();
384e5dd7070Spatrick break;
385e5dd7070Spatrick
386e5dd7070Spatrick case tok::semi:
387e5dd7070Spatrick if (HasFlagsSet(Flags, StopAtSemi))
388e5dd7070Spatrick return false;
389*12c85518Srobert [[fallthrough]];
390e5dd7070Spatrick default:
391e5dd7070Spatrick // Skip this token.
392e5dd7070Spatrick ConsumeAnyToken();
393e5dd7070Spatrick break;
394e5dd7070Spatrick }
395e5dd7070Spatrick isFirstTokenSkipped = false;
396e5dd7070Spatrick }
397e5dd7070Spatrick }
398e5dd7070Spatrick
399e5dd7070Spatrick //===----------------------------------------------------------------------===//
400e5dd7070Spatrick // Scope manipulation
401e5dd7070Spatrick //===----------------------------------------------------------------------===//
402e5dd7070Spatrick
403e5dd7070Spatrick /// EnterScope - Start a new scope.
EnterScope(unsigned ScopeFlags)404e5dd7070Spatrick void Parser::EnterScope(unsigned ScopeFlags) {
405e5dd7070Spatrick if (NumCachedScopes) {
406e5dd7070Spatrick Scope *N = ScopeCache[--NumCachedScopes];
407e5dd7070Spatrick N->Init(getCurScope(), ScopeFlags);
408e5dd7070Spatrick Actions.CurScope = N;
409e5dd7070Spatrick } else {
410e5dd7070Spatrick Actions.CurScope = new Scope(getCurScope(), ScopeFlags, Diags);
411e5dd7070Spatrick }
412e5dd7070Spatrick }
413e5dd7070Spatrick
414e5dd7070Spatrick /// ExitScope - Pop a scope off the scope stack.
ExitScope()415e5dd7070Spatrick void Parser::ExitScope() {
416e5dd7070Spatrick assert(getCurScope() && "Scope imbalance!");
417e5dd7070Spatrick
418e5dd7070Spatrick // Inform the actions module that this scope is going away if there are any
419e5dd7070Spatrick // decls in it.
420e5dd7070Spatrick Actions.ActOnPopScope(Tok.getLocation(), getCurScope());
421e5dd7070Spatrick
422e5dd7070Spatrick Scope *OldScope = getCurScope();
423e5dd7070Spatrick Actions.CurScope = OldScope->getParent();
424e5dd7070Spatrick
425e5dd7070Spatrick if (NumCachedScopes == ScopeCacheSize)
426e5dd7070Spatrick delete OldScope;
427e5dd7070Spatrick else
428e5dd7070Spatrick ScopeCache[NumCachedScopes++] = OldScope;
429e5dd7070Spatrick }
430e5dd7070Spatrick
431e5dd7070Spatrick /// Set the flags for the current scope to ScopeFlags. If ManageFlags is false,
432e5dd7070Spatrick /// this object does nothing.
ParseScopeFlags(Parser * Self,unsigned ScopeFlags,bool ManageFlags)433e5dd7070Spatrick Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags,
434e5dd7070Spatrick bool ManageFlags)
435e5dd7070Spatrick : CurScope(ManageFlags ? Self->getCurScope() : nullptr) {
436e5dd7070Spatrick if (CurScope) {
437e5dd7070Spatrick OldFlags = CurScope->getFlags();
438e5dd7070Spatrick CurScope->setFlags(ScopeFlags);
439e5dd7070Spatrick }
440e5dd7070Spatrick }
441e5dd7070Spatrick
442e5dd7070Spatrick /// Restore the flags for the current scope to what they were before this
443e5dd7070Spatrick /// object overrode them.
~ParseScopeFlags()444e5dd7070Spatrick Parser::ParseScopeFlags::~ParseScopeFlags() {
445e5dd7070Spatrick if (CurScope)
446e5dd7070Spatrick CurScope->setFlags(OldFlags);
447e5dd7070Spatrick }
448e5dd7070Spatrick
449e5dd7070Spatrick
450e5dd7070Spatrick //===----------------------------------------------------------------------===//
451e5dd7070Spatrick // C99 6.9: External Definitions.
452e5dd7070Spatrick //===----------------------------------------------------------------------===//
453e5dd7070Spatrick
~Parser()454e5dd7070Spatrick Parser::~Parser() {
455e5dd7070Spatrick // If we still have scopes active, delete the scope tree.
456e5dd7070Spatrick delete getCurScope();
457e5dd7070Spatrick Actions.CurScope = nullptr;
458e5dd7070Spatrick
459e5dd7070Spatrick // Free the scope cache.
460e5dd7070Spatrick for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
461e5dd7070Spatrick delete ScopeCache[i];
462e5dd7070Spatrick
463e5dd7070Spatrick resetPragmaHandlers();
464e5dd7070Spatrick
465e5dd7070Spatrick PP.removeCommentHandler(CommentSemaHandler.get());
466e5dd7070Spatrick
467e5dd7070Spatrick PP.clearCodeCompletionHandler();
468e5dd7070Spatrick
469ec727ea7Spatrick DestroyTemplateIds();
470e5dd7070Spatrick }
471e5dd7070Spatrick
472e5dd7070Spatrick /// Initialize - Warm up the parser.
473e5dd7070Spatrick ///
Initialize()474e5dd7070Spatrick void Parser::Initialize() {
475e5dd7070Spatrick // Create the translation unit scope. Install it as the current scope.
476e5dd7070Spatrick assert(getCurScope() == nullptr && "A scope is already active?");
477e5dd7070Spatrick EnterScope(Scope::DeclScope);
478e5dd7070Spatrick Actions.ActOnTranslationUnitScope(getCurScope());
479e5dd7070Spatrick
480e5dd7070Spatrick // Initialization for Objective-C context sensitive keywords recognition.
481e5dd7070Spatrick // Referenced in Parser::ParseObjCTypeQualifierList.
482e5dd7070Spatrick if (getLangOpts().ObjC) {
483e5dd7070Spatrick ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in");
484e5dd7070Spatrick ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out");
485e5dd7070Spatrick ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout");
486e5dd7070Spatrick ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway");
487e5dd7070Spatrick ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy");
488e5dd7070Spatrick ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref");
489e5dd7070Spatrick ObjCTypeQuals[objc_nonnull] = &PP.getIdentifierTable().get("nonnull");
490e5dd7070Spatrick ObjCTypeQuals[objc_nullable] = &PP.getIdentifierTable().get("nullable");
491e5dd7070Spatrick ObjCTypeQuals[objc_null_unspecified]
492e5dd7070Spatrick = &PP.getIdentifierTable().get("null_unspecified");
493e5dd7070Spatrick }
494e5dd7070Spatrick
495e5dd7070Spatrick Ident_instancetype = nullptr;
496e5dd7070Spatrick Ident_final = nullptr;
497e5dd7070Spatrick Ident_sealed = nullptr;
498a9ac8606Spatrick Ident_abstract = nullptr;
499e5dd7070Spatrick Ident_override = nullptr;
500e5dd7070Spatrick Ident_GNU_final = nullptr;
501e5dd7070Spatrick Ident_import = nullptr;
502e5dd7070Spatrick Ident_module = nullptr;
503e5dd7070Spatrick
504e5dd7070Spatrick Ident_super = &PP.getIdentifierTable().get("super");
505e5dd7070Spatrick
506e5dd7070Spatrick Ident_vector = nullptr;
507e5dd7070Spatrick Ident_bool = nullptr;
508a9ac8606Spatrick Ident_Bool = nullptr;
509e5dd7070Spatrick Ident_pixel = nullptr;
510e5dd7070Spatrick if (getLangOpts().AltiVec || getLangOpts().ZVector) {
511e5dd7070Spatrick Ident_vector = &PP.getIdentifierTable().get("vector");
512e5dd7070Spatrick Ident_bool = &PP.getIdentifierTable().get("bool");
513a9ac8606Spatrick Ident_Bool = &PP.getIdentifierTable().get("_Bool");
514e5dd7070Spatrick }
515e5dd7070Spatrick if (getLangOpts().AltiVec)
516e5dd7070Spatrick Ident_pixel = &PP.getIdentifierTable().get("pixel");
517e5dd7070Spatrick
518e5dd7070Spatrick Ident_introduced = nullptr;
519e5dd7070Spatrick Ident_deprecated = nullptr;
520e5dd7070Spatrick Ident_obsoleted = nullptr;
521e5dd7070Spatrick Ident_unavailable = nullptr;
522e5dd7070Spatrick Ident_strict = nullptr;
523e5dd7070Spatrick Ident_replacement = nullptr;
524e5dd7070Spatrick
525e5dd7070Spatrick Ident_language = Ident_defined_in = Ident_generated_declaration = nullptr;
526e5dd7070Spatrick
527e5dd7070Spatrick Ident__except = nullptr;
528e5dd7070Spatrick
529e5dd7070Spatrick Ident__exception_code = Ident__exception_info = nullptr;
530e5dd7070Spatrick Ident__abnormal_termination = Ident___exception_code = nullptr;
531e5dd7070Spatrick Ident___exception_info = Ident___abnormal_termination = nullptr;
532e5dd7070Spatrick Ident_GetExceptionCode = Ident_GetExceptionInfo = nullptr;
533e5dd7070Spatrick Ident_AbnormalTermination = nullptr;
534e5dd7070Spatrick
535e5dd7070Spatrick if(getLangOpts().Borland) {
536e5dd7070Spatrick Ident__exception_info = PP.getIdentifierInfo("_exception_info");
537e5dd7070Spatrick Ident___exception_info = PP.getIdentifierInfo("__exception_info");
538e5dd7070Spatrick Ident_GetExceptionInfo = PP.getIdentifierInfo("GetExceptionInformation");
539e5dd7070Spatrick Ident__exception_code = PP.getIdentifierInfo("_exception_code");
540e5dd7070Spatrick Ident___exception_code = PP.getIdentifierInfo("__exception_code");
541e5dd7070Spatrick Ident_GetExceptionCode = PP.getIdentifierInfo("GetExceptionCode");
542e5dd7070Spatrick Ident__abnormal_termination = PP.getIdentifierInfo("_abnormal_termination");
543e5dd7070Spatrick Ident___abnormal_termination = PP.getIdentifierInfo("__abnormal_termination");
544e5dd7070Spatrick Ident_AbnormalTermination = PP.getIdentifierInfo("AbnormalTermination");
545e5dd7070Spatrick
546e5dd7070Spatrick PP.SetPoisonReason(Ident__exception_code,diag::err_seh___except_block);
547e5dd7070Spatrick PP.SetPoisonReason(Ident___exception_code,diag::err_seh___except_block);
548e5dd7070Spatrick PP.SetPoisonReason(Ident_GetExceptionCode,diag::err_seh___except_block);
549e5dd7070Spatrick PP.SetPoisonReason(Ident__exception_info,diag::err_seh___except_filter);
550e5dd7070Spatrick PP.SetPoisonReason(Ident___exception_info,diag::err_seh___except_filter);
551e5dd7070Spatrick PP.SetPoisonReason(Ident_GetExceptionInfo,diag::err_seh___except_filter);
552e5dd7070Spatrick PP.SetPoisonReason(Ident__abnormal_termination,diag::err_seh___finally_block);
553e5dd7070Spatrick PP.SetPoisonReason(Ident___abnormal_termination,diag::err_seh___finally_block);
554e5dd7070Spatrick PP.SetPoisonReason(Ident_AbnormalTermination,diag::err_seh___finally_block);
555e5dd7070Spatrick }
556e5dd7070Spatrick
557e5dd7070Spatrick if (getLangOpts().CPlusPlusModules) {
558e5dd7070Spatrick Ident_import = PP.getIdentifierInfo("import");
559e5dd7070Spatrick Ident_module = PP.getIdentifierInfo("module");
560e5dd7070Spatrick }
561e5dd7070Spatrick
562e5dd7070Spatrick Actions.Initialize();
563e5dd7070Spatrick
564e5dd7070Spatrick // Prime the lexer look-ahead.
565e5dd7070Spatrick ConsumeToken();
566e5dd7070Spatrick }
567e5dd7070Spatrick
DestroyTemplateIds()568ec727ea7Spatrick void Parser::DestroyTemplateIds() {
569ec727ea7Spatrick for (TemplateIdAnnotation *Id : TemplateIds)
570ec727ea7Spatrick Id->Destroy();
571ec727ea7Spatrick TemplateIds.clear();
572e5dd7070Spatrick }
573e5dd7070Spatrick
574e5dd7070Spatrick /// Parse the first top-level declaration in a translation unit.
575e5dd7070Spatrick ///
576e5dd7070Spatrick /// translation-unit:
577e5dd7070Spatrick /// [C] external-declaration
578e5dd7070Spatrick /// [C] translation-unit external-declaration
579e5dd7070Spatrick /// [C++] top-level-declaration-seq[opt]
580e5dd7070Spatrick /// [C++20] global-module-fragment[opt] module-declaration
581e5dd7070Spatrick /// top-level-declaration-seq[opt] private-module-fragment[opt]
582e5dd7070Spatrick ///
583e5dd7070Spatrick /// Note that in C, it is an error if there is no first declaration.
ParseFirstTopLevelDecl(DeclGroupPtrTy & Result,Sema::ModuleImportState & ImportState)584*12c85518Srobert bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
585*12c85518Srobert Sema::ModuleImportState &ImportState) {
586e5dd7070Spatrick Actions.ActOnStartOfTranslationUnit();
587e5dd7070Spatrick
588*12c85518Srobert // For C++20 modules, a module decl must be the first in the TU. We also
589*12c85518Srobert // need to track module imports.
590*12c85518Srobert ImportState = Sema::ModuleImportState::FirstDecl;
591*12c85518Srobert bool NoTopLevelDecls = ParseTopLevelDecl(Result, ImportState);
592*12c85518Srobert
593e5dd7070Spatrick // C11 6.9p1 says translation units must have at least one top-level
594e5dd7070Spatrick // declaration. C++ doesn't have this restriction. We also don't want to
595e5dd7070Spatrick // complain if we have a precompiled header, although technically if the PCH
596e5dd7070Spatrick // is empty we should still emit the (pedantic) diagnostic.
597a9ac8606Spatrick // If the main file is a header, we're only pretending it's a TU; don't warn.
598e5dd7070Spatrick if (NoTopLevelDecls && !Actions.getASTContext().getExternalSource() &&
599a9ac8606Spatrick !getLangOpts().CPlusPlus && !getLangOpts().IsHeaderFile)
600e5dd7070Spatrick Diag(diag::ext_empty_translation_unit);
601e5dd7070Spatrick
602e5dd7070Spatrick return NoTopLevelDecls;
603e5dd7070Spatrick }
604e5dd7070Spatrick
605e5dd7070Spatrick /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
606e5dd7070Spatrick /// action tells us to. This returns true if the EOF was encountered.
607e5dd7070Spatrick ///
608e5dd7070Spatrick /// top-level-declaration:
609e5dd7070Spatrick /// declaration
610e5dd7070Spatrick /// [C++20] module-import-declaration
ParseTopLevelDecl(DeclGroupPtrTy & Result,Sema::ModuleImportState & ImportState)611*12c85518Srobert bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
612*12c85518Srobert Sema::ModuleImportState &ImportState) {
613ec727ea7Spatrick DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
614e5dd7070Spatrick
615e5dd7070Spatrick // Skip over the EOF token, flagging end of previous input for incremental
616e5dd7070Spatrick // processing
617e5dd7070Spatrick if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))
618e5dd7070Spatrick ConsumeToken();
619e5dd7070Spatrick
620e5dd7070Spatrick Result = nullptr;
621e5dd7070Spatrick switch (Tok.getKind()) {
622e5dd7070Spatrick case tok::annot_pragma_unused:
623e5dd7070Spatrick HandlePragmaUnused();
624e5dd7070Spatrick return false;
625e5dd7070Spatrick
626e5dd7070Spatrick case tok::kw_export:
627e5dd7070Spatrick switch (NextToken().getKind()) {
628e5dd7070Spatrick case tok::kw_module:
629e5dd7070Spatrick goto module_decl;
630e5dd7070Spatrick
631e5dd7070Spatrick // Note: no need to handle kw_import here. We only form kw_import under
632e5dd7070Spatrick // the Modules TS, and in that case 'export import' is parsed as an
633e5dd7070Spatrick // export-declaration containing an import-declaration.
634e5dd7070Spatrick
635e5dd7070Spatrick // Recognize context-sensitive C++20 'export module' and 'export import'
636e5dd7070Spatrick // declarations.
637e5dd7070Spatrick case tok::identifier: {
638e5dd7070Spatrick IdentifierInfo *II = NextToken().getIdentifierInfo();
639e5dd7070Spatrick if ((II == Ident_module || II == Ident_import) &&
640e5dd7070Spatrick GetLookAheadToken(2).isNot(tok::coloncolon)) {
641e5dd7070Spatrick if (II == Ident_module)
642e5dd7070Spatrick goto module_decl;
643e5dd7070Spatrick else
644e5dd7070Spatrick goto import_decl;
645e5dd7070Spatrick }
646e5dd7070Spatrick break;
647e5dd7070Spatrick }
648e5dd7070Spatrick
649e5dd7070Spatrick default:
650e5dd7070Spatrick break;
651e5dd7070Spatrick }
652e5dd7070Spatrick break;
653e5dd7070Spatrick
654e5dd7070Spatrick case tok::kw_module:
655e5dd7070Spatrick module_decl:
656*12c85518Srobert Result = ParseModuleDecl(ImportState);
657e5dd7070Spatrick return false;
658e5dd7070Spatrick
659*12c85518Srobert case tok::kw_import:
660e5dd7070Spatrick import_decl: {
661*12c85518Srobert Decl *ImportDecl = ParseModuleImport(SourceLocation(), ImportState);
662e5dd7070Spatrick Result = Actions.ConvertDeclToDeclGroup(ImportDecl);
663e5dd7070Spatrick return false;
664e5dd7070Spatrick }
665e5dd7070Spatrick
666*12c85518Srobert case tok::annot_module_include: {
667*12c85518Srobert auto Loc = Tok.getLocation();
668*12c85518Srobert Module *Mod = reinterpret_cast<Module *>(Tok.getAnnotationValue());
669*12c85518Srobert // FIXME: We need a better way to disambiguate C++ clang modules and
670*12c85518Srobert // standard C++ modules.
671*12c85518Srobert if (!getLangOpts().CPlusPlusModules || !Mod->isHeaderUnit())
672*12c85518Srobert Actions.ActOnModuleInclude(Loc, Mod);
673*12c85518Srobert else {
674*12c85518Srobert DeclResult Import =
675*12c85518Srobert Actions.ActOnModuleImport(Loc, SourceLocation(), Loc, Mod);
676*12c85518Srobert Decl *ImportDecl = Import.isInvalid() ? nullptr : Import.get();
677*12c85518Srobert Result = Actions.ConvertDeclToDeclGroup(ImportDecl);
678*12c85518Srobert }
679e5dd7070Spatrick ConsumeAnnotationToken();
680e5dd7070Spatrick return false;
681*12c85518Srobert }
682e5dd7070Spatrick
683e5dd7070Spatrick case tok::annot_module_begin:
684e5dd7070Spatrick Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>(
685e5dd7070Spatrick Tok.getAnnotationValue()));
686e5dd7070Spatrick ConsumeAnnotationToken();
687*12c85518Srobert ImportState = Sema::ModuleImportState::NotACXX20Module;
688e5dd7070Spatrick return false;
689e5dd7070Spatrick
690e5dd7070Spatrick case tok::annot_module_end:
691e5dd7070Spatrick Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>(
692e5dd7070Spatrick Tok.getAnnotationValue()));
693e5dd7070Spatrick ConsumeAnnotationToken();
694*12c85518Srobert ImportState = Sema::ModuleImportState::NotACXX20Module;
695e5dd7070Spatrick return false;
696e5dd7070Spatrick
697e5dd7070Spatrick case tok::eof:
698ec727ea7Spatrick // Check whether -fmax-tokens= was reached.
699ec727ea7Spatrick if (PP.getMaxTokens() != 0 && PP.getTokenCount() > PP.getMaxTokens()) {
700ec727ea7Spatrick PP.Diag(Tok.getLocation(), diag::warn_max_tokens_total)
701ec727ea7Spatrick << PP.getTokenCount() << PP.getMaxTokens();
702ec727ea7Spatrick SourceLocation OverrideLoc = PP.getMaxTokensOverrideLoc();
703ec727ea7Spatrick if (OverrideLoc.isValid()) {
704ec727ea7Spatrick PP.Diag(OverrideLoc, diag::note_max_tokens_total_override);
705ec727ea7Spatrick }
706ec727ea7Spatrick }
707ec727ea7Spatrick
708e5dd7070Spatrick // Late template parsing can begin.
709ec727ea7Spatrick Actions.SetLateTemplateParser(LateTemplateParserCallback, nullptr, this);
710e5dd7070Spatrick Actions.ActOnEndOfTranslationUnit();
711e5dd7070Spatrick //else don't tell Sema that we ended parsing: more input might come.
712e5dd7070Spatrick return true;
713e5dd7070Spatrick
714e5dd7070Spatrick case tok::identifier:
715e5dd7070Spatrick // C++2a [basic.link]p3:
716e5dd7070Spatrick // A token sequence beginning with 'export[opt] module' or
717e5dd7070Spatrick // 'export[opt] import' and not immediately followed by '::'
718e5dd7070Spatrick // is never interpreted as the declaration of a top-level-declaration.
719e5dd7070Spatrick if ((Tok.getIdentifierInfo() == Ident_module ||
720e5dd7070Spatrick Tok.getIdentifierInfo() == Ident_import) &&
721e5dd7070Spatrick NextToken().isNot(tok::coloncolon)) {
722e5dd7070Spatrick if (Tok.getIdentifierInfo() == Ident_module)
723e5dd7070Spatrick goto module_decl;
724e5dd7070Spatrick else
725e5dd7070Spatrick goto import_decl;
726e5dd7070Spatrick }
727e5dd7070Spatrick break;
728e5dd7070Spatrick
729e5dd7070Spatrick default:
730e5dd7070Spatrick break;
731e5dd7070Spatrick }
732e5dd7070Spatrick
733*12c85518Srobert ParsedAttributes DeclAttrs(AttrFactory);
734*12c85518Srobert ParsedAttributes DeclSpecAttrs(AttrFactory);
735*12c85518Srobert // GNU attributes are applied to the declaration specification while the
736*12c85518Srobert // standard attributes are applied to the declaration. We parse the two
737*12c85518Srobert // attribute sets into different containters so we can apply them during
738*12c85518Srobert // the regular parsing process.
739*12c85518Srobert while (MaybeParseCXX11Attributes(DeclAttrs) ||
740*12c85518Srobert MaybeParseGNUAttributes(DeclSpecAttrs))
741*12c85518Srobert ;
742e5dd7070Spatrick
743*12c85518Srobert Result = ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
744*12c85518Srobert // An empty Result might mean a line with ';' or some parsing error, ignore
745*12c85518Srobert // it.
746*12c85518Srobert if (Result) {
747*12c85518Srobert if (ImportState == Sema::ModuleImportState::FirstDecl)
748*12c85518Srobert // First decl was not modular.
749*12c85518Srobert ImportState = Sema::ModuleImportState::NotACXX20Module;
750*12c85518Srobert else if (ImportState == Sema::ModuleImportState::ImportAllowed)
751*12c85518Srobert // Non-imports disallow further imports.
752*12c85518Srobert ImportState = Sema::ModuleImportState::ImportFinished;
753*12c85518Srobert else if (ImportState ==
754*12c85518Srobert Sema::ModuleImportState::PrivateFragmentImportAllowed)
755*12c85518Srobert // Non-imports disallow further imports.
756*12c85518Srobert ImportState = Sema::ModuleImportState::PrivateFragmentImportFinished;
757*12c85518Srobert }
758e5dd7070Spatrick return false;
759e5dd7070Spatrick }
760e5dd7070Spatrick
761e5dd7070Spatrick /// ParseExternalDeclaration:
762e5dd7070Spatrick ///
763*12c85518Srobert /// The `Attrs` that are passed in are C++11 attributes and appertain to the
764*12c85518Srobert /// declaration.
765*12c85518Srobert ///
766e5dd7070Spatrick /// external-declaration: [C99 6.9], declaration: [C++ dcl.dcl]
767e5dd7070Spatrick /// function-definition
768e5dd7070Spatrick /// declaration
769e5dd7070Spatrick /// [GNU] asm-definition
770e5dd7070Spatrick /// [GNU] __extension__ external-declaration
771e5dd7070Spatrick /// [OBJC] objc-class-definition
772e5dd7070Spatrick /// [OBJC] objc-class-declaration
773e5dd7070Spatrick /// [OBJC] objc-alias-declaration
774e5dd7070Spatrick /// [OBJC] objc-protocol-definition
775e5dd7070Spatrick /// [OBJC] objc-method-definition
776e5dd7070Spatrick /// [OBJC] @end
777e5dd7070Spatrick /// [C++] linkage-specification
778e5dd7070Spatrick /// [GNU] asm-definition:
779e5dd7070Spatrick /// simple-asm-expr ';'
780e5dd7070Spatrick /// [C++11] empty-declaration
781e5dd7070Spatrick /// [C++11] attribute-declaration
782e5dd7070Spatrick ///
783e5dd7070Spatrick /// [C++11] empty-declaration:
784e5dd7070Spatrick /// ';'
785e5dd7070Spatrick ///
786e5dd7070Spatrick /// [C++0x/GNU] 'extern' 'template' declaration
787e5dd7070Spatrick ///
788e5dd7070Spatrick /// [Modules-TS] module-import-declaration
789e5dd7070Spatrick ///
790e5dd7070Spatrick Parser::DeclGroupPtrTy
ParseExternalDeclaration(ParsedAttributes & Attrs,ParsedAttributes & DeclSpecAttrs,ParsingDeclSpec * DS)791*12c85518Srobert Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
792*12c85518Srobert ParsedAttributes &DeclSpecAttrs,
793e5dd7070Spatrick ParsingDeclSpec *DS) {
794ec727ea7Spatrick DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
795e5dd7070Spatrick ParenBraceBracketBalancer BalancerRAIIObj(*this);
796e5dd7070Spatrick
797e5dd7070Spatrick if (PP.isCodeCompletionReached()) {
798e5dd7070Spatrick cutOffParsing();
799e5dd7070Spatrick return nullptr;
800e5dd7070Spatrick }
801e5dd7070Spatrick
802e5dd7070Spatrick Decl *SingleDecl = nullptr;
803e5dd7070Spatrick switch (Tok.getKind()) {
804e5dd7070Spatrick case tok::annot_pragma_vis:
805e5dd7070Spatrick HandlePragmaVisibility();
806e5dd7070Spatrick return nullptr;
807e5dd7070Spatrick case tok::annot_pragma_pack:
808e5dd7070Spatrick HandlePragmaPack();
809e5dd7070Spatrick return nullptr;
810e5dd7070Spatrick case tok::annot_pragma_msstruct:
811e5dd7070Spatrick HandlePragmaMSStruct();
812e5dd7070Spatrick return nullptr;
813e5dd7070Spatrick case tok::annot_pragma_align:
814e5dd7070Spatrick HandlePragmaAlign();
815e5dd7070Spatrick return nullptr;
816e5dd7070Spatrick case tok::annot_pragma_weak:
817e5dd7070Spatrick HandlePragmaWeak();
818e5dd7070Spatrick return nullptr;
819e5dd7070Spatrick case tok::annot_pragma_weakalias:
820e5dd7070Spatrick HandlePragmaWeakAlias();
821e5dd7070Spatrick return nullptr;
822e5dd7070Spatrick case tok::annot_pragma_redefine_extname:
823e5dd7070Spatrick HandlePragmaRedefineExtname();
824e5dd7070Spatrick return nullptr;
825e5dd7070Spatrick case tok::annot_pragma_fp_contract:
826e5dd7070Spatrick HandlePragmaFPContract();
827e5dd7070Spatrick return nullptr;
828e5dd7070Spatrick case tok::annot_pragma_fenv_access:
829*12c85518Srobert case tok::annot_pragma_fenv_access_ms:
830e5dd7070Spatrick HandlePragmaFEnvAccess();
831e5dd7070Spatrick return nullptr;
832a9ac8606Spatrick case tok::annot_pragma_fenv_round:
833a9ac8606Spatrick HandlePragmaFEnvRound();
834a9ac8606Spatrick return nullptr;
835ec727ea7Spatrick case tok::annot_pragma_float_control:
836ec727ea7Spatrick HandlePragmaFloatControl();
837ec727ea7Spatrick return nullptr;
838e5dd7070Spatrick case tok::annot_pragma_fp:
839e5dd7070Spatrick HandlePragmaFP();
840e5dd7070Spatrick break;
841e5dd7070Spatrick case tok::annot_pragma_opencl_extension:
842e5dd7070Spatrick HandlePragmaOpenCLExtension();
843e5dd7070Spatrick return nullptr;
844a9ac8606Spatrick case tok::annot_attr_openmp:
845e5dd7070Spatrick case tok::annot_pragma_openmp: {
846e5dd7070Spatrick AccessSpecifier AS = AS_none;
847*12c85518Srobert return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
848e5dd7070Spatrick }
849e5dd7070Spatrick case tok::annot_pragma_ms_pointers_to_members:
850e5dd7070Spatrick HandlePragmaMSPointersToMembers();
851e5dd7070Spatrick return nullptr;
852e5dd7070Spatrick case tok::annot_pragma_ms_vtordisp:
853e5dd7070Spatrick HandlePragmaMSVtorDisp();
854e5dd7070Spatrick return nullptr;
855e5dd7070Spatrick case tok::annot_pragma_ms_pragma:
856e5dd7070Spatrick HandlePragmaMSPragma();
857e5dd7070Spatrick return nullptr;
858e5dd7070Spatrick case tok::annot_pragma_dump:
859e5dd7070Spatrick HandlePragmaDump();
860e5dd7070Spatrick return nullptr;
861e5dd7070Spatrick case tok::annot_pragma_attribute:
862e5dd7070Spatrick HandlePragmaAttribute();
863e5dd7070Spatrick return nullptr;
864e5dd7070Spatrick case tok::semi:
865e5dd7070Spatrick // Either a C++11 empty-declaration or attribute-declaration.
866e5dd7070Spatrick SingleDecl =
867*12c85518Srobert Actions.ActOnEmptyDeclaration(getCurScope(), Attrs, Tok.getLocation());
868e5dd7070Spatrick ConsumeExtraSemi(OutsideFunction);
869e5dd7070Spatrick break;
870e5dd7070Spatrick case tok::r_brace:
871e5dd7070Spatrick Diag(Tok, diag::err_extraneous_closing_brace);
872e5dd7070Spatrick ConsumeBrace();
873e5dd7070Spatrick return nullptr;
874e5dd7070Spatrick case tok::eof:
875e5dd7070Spatrick Diag(Tok, diag::err_expected_external_declaration);
876e5dd7070Spatrick return nullptr;
877e5dd7070Spatrick case tok::kw___extension__: {
878e5dd7070Spatrick // __extension__ silences extension warnings in the subexpression.
879e5dd7070Spatrick ExtensionRAIIObject O(Diags); // Use RAII to do this.
880e5dd7070Spatrick ConsumeToken();
881*12c85518Srobert return ParseExternalDeclaration(Attrs, DeclSpecAttrs);
882e5dd7070Spatrick }
883e5dd7070Spatrick case tok::kw_asm: {
884*12c85518Srobert ProhibitAttributes(Attrs);
885e5dd7070Spatrick
886e5dd7070Spatrick SourceLocation StartLoc = Tok.getLocation();
887e5dd7070Spatrick SourceLocation EndLoc;
888e5dd7070Spatrick
889e5dd7070Spatrick ExprResult Result(ParseSimpleAsm(/*ForAsmLabel*/ false, &EndLoc));
890e5dd7070Spatrick
891e5dd7070Spatrick // Check if GNU-style InlineAsm is disabled.
892e5dd7070Spatrick // Empty asm string is allowed because it will not introduce
893e5dd7070Spatrick // any assembly code.
894e5dd7070Spatrick if (!(getLangOpts().GNUAsm || Result.isInvalid())) {
895e5dd7070Spatrick const auto *SL = cast<StringLiteral>(Result.get());
896e5dd7070Spatrick if (!SL->getString().trim().empty())
897e5dd7070Spatrick Diag(StartLoc, diag::err_gnu_inline_asm_disabled);
898e5dd7070Spatrick }
899e5dd7070Spatrick
900e5dd7070Spatrick ExpectAndConsume(tok::semi, diag::err_expected_after,
901e5dd7070Spatrick "top-level asm block");
902e5dd7070Spatrick
903e5dd7070Spatrick if (Result.isInvalid())
904e5dd7070Spatrick return nullptr;
905e5dd7070Spatrick SingleDecl = Actions.ActOnFileScopeAsmDecl(Result.get(), StartLoc, EndLoc);
906e5dd7070Spatrick break;
907e5dd7070Spatrick }
908e5dd7070Spatrick case tok::at:
909*12c85518Srobert return ParseObjCAtDirectives(Attrs, DeclSpecAttrs);
910e5dd7070Spatrick case tok::minus:
911e5dd7070Spatrick case tok::plus:
912e5dd7070Spatrick if (!getLangOpts().ObjC) {
913e5dd7070Spatrick Diag(Tok, diag::err_expected_external_declaration);
914e5dd7070Spatrick ConsumeToken();
915e5dd7070Spatrick return nullptr;
916e5dd7070Spatrick }
917e5dd7070Spatrick SingleDecl = ParseObjCMethodDefinition();
918e5dd7070Spatrick break;
919e5dd7070Spatrick case tok::code_completion:
920a9ac8606Spatrick cutOffParsing();
921e5dd7070Spatrick if (CurParsedObjCImpl) {
922e5dd7070Spatrick // Code-complete Objective-C methods even without leading '-'/'+' prefix.
923e5dd7070Spatrick Actions.CodeCompleteObjCMethodDecl(getCurScope(),
924*12c85518Srobert /*IsInstanceMethod=*/std::nullopt,
925e5dd7070Spatrick /*ReturnType=*/nullptr);
926e5dd7070Spatrick }
927e5dd7070Spatrick Actions.CodeCompleteOrdinaryName(
928e5dd7070Spatrick getCurScope(),
929e5dd7070Spatrick CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
930e5dd7070Spatrick return nullptr;
931*12c85518Srobert case tok::kw_import: {
932*12c85518Srobert Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
933*12c85518Srobert if (getLangOpts().CPlusPlusModules) {
934*12c85518Srobert llvm_unreachable("not expecting a c++20 import here");
935*12c85518Srobert ProhibitAttributes(Attrs);
936*12c85518Srobert }
937*12c85518Srobert SingleDecl = ParseModuleImport(SourceLocation(), IS);
938*12c85518Srobert } break;
939e5dd7070Spatrick case tok::kw_export:
940e5dd7070Spatrick if (getLangOpts().CPlusPlusModules || getLangOpts().ModulesTS) {
941*12c85518Srobert ProhibitAttributes(Attrs);
942e5dd7070Spatrick SingleDecl = ParseExportDeclaration();
943e5dd7070Spatrick break;
944e5dd7070Spatrick }
945e5dd7070Spatrick // This must be 'export template'. Parse it so we can diagnose our lack
946e5dd7070Spatrick // of support.
947*12c85518Srobert [[fallthrough]];
948e5dd7070Spatrick case tok::kw_using:
949e5dd7070Spatrick case tok::kw_namespace:
950e5dd7070Spatrick case tok::kw_typedef:
951e5dd7070Spatrick case tok::kw_template:
952e5dd7070Spatrick case tok::kw_static_assert:
953e5dd7070Spatrick case tok::kw__Static_assert:
954e5dd7070Spatrick // A function definition cannot start with any of these keywords.
955e5dd7070Spatrick {
956e5dd7070Spatrick SourceLocation DeclEnd;
957*12c85518Srobert return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
958*12c85518Srobert DeclSpecAttrs);
959e5dd7070Spatrick }
960e5dd7070Spatrick
961*12c85518Srobert case tok::kw_cbuffer:
962*12c85518Srobert case tok::kw_tbuffer:
963*12c85518Srobert if (getLangOpts().HLSL) {
964*12c85518Srobert SourceLocation DeclEnd;
965*12c85518Srobert return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
966*12c85518Srobert DeclSpecAttrs);
967*12c85518Srobert }
968*12c85518Srobert goto dont_know;
969*12c85518Srobert
970e5dd7070Spatrick case tok::kw_static:
971e5dd7070Spatrick // Parse (then ignore) 'static' prior to a template instantiation. This is
972e5dd7070Spatrick // a GCC extension that we intentionally do not support.
973e5dd7070Spatrick if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) {
974e5dd7070Spatrick Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
975e5dd7070Spatrick << 0;
976e5dd7070Spatrick SourceLocation DeclEnd;
977*12c85518Srobert return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
978*12c85518Srobert DeclSpecAttrs);
979e5dd7070Spatrick }
980e5dd7070Spatrick goto dont_know;
981e5dd7070Spatrick
982e5dd7070Spatrick case tok::kw_inline:
983e5dd7070Spatrick if (getLangOpts().CPlusPlus) {
984e5dd7070Spatrick tok::TokenKind NextKind = NextToken().getKind();
985e5dd7070Spatrick
986e5dd7070Spatrick // Inline namespaces. Allowed as an extension even in C++03.
987e5dd7070Spatrick if (NextKind == tok::kw_namespace) {
988e5dd7070Spatrick SourceLocation DeclEnd;
989*12c85518Srobert return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
990*12c85518Srobert DeclSpecAttrs);
991e5dd7070Spatrick }
992e5dd7070Spatrick
993e5dd7070Spatrick // Parse (then ignore) 'inline' prior to a template instantiation. This is
994e5dd7070Spatrick // a GCC extension that we intentionally do not support.
995e5dd7070Spatrick if (NextKind == tok::kw_template) {
996e5dd7070Spatrick Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
997e5dd7070Spatrick << 1;
998e5dd7070Spatrick SourceLocation DeclEnd;
999*12c85518Srobert return ParseDeclaration(DeclaratorContext::File, DeclEnd, Attrs,
1000*12c85518Srobert DeclSpecAttrs);
1001e5dd7070Spatrick }
1002e5dd7070Spatrick }
1003e5dd7070Spatrick goto dont_know;
1004e5dd7070Spatrick
1005e5dd7070Spatrick case tok::kw_extern:
1006e5dd7070Spatrick if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) {
1007e5dd7070Spatrick // Extern templates
1008e5dd7070Spatrick SourceLocation ExternLoc = ConsumeToken();
1009e5dd7070Spatrick SourceLocation TemplateLoc = ConsumeToken();
1010e5dd7070Spatrick Diag(ExternLoc, getLangOpts().CPlusPlus11 ?
1011e5dd7070Spatrick diag::warn_cxx98_compat_extern_template :
1012e5dd7070Spatrick diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
1013e5dd7070Spatrick SourceLocation DeclEnd;
1014a9ac8606Spatrick return Actions.ConvertDeclToDeclGroup(ParseExplicitInstantiation(
1015*12c85518Srobert DeclaratorContext::File, ExternLoc, TemplateLoc, DeclEnd, Attrs));
1016e5dd7070Spatrick }
1017e5dd7070Spatrick goto dont_know;
1018e5dd7070Spatrick
1019e5dd7070Spatrick case tok::kw___if_exists:
1020e5dd7070Spatrick case tok::kw___if_not_exists:
1021e5dd7070Spatrick ParseMicrosoftIfExistsExternalDeclaration();
1022e5dd7070Spatrick return nullptr;
1023e5dd7070Spatrick
1024e5dd7070Spatrick case tok::kw_module:
1025e5dd7070Spatrick Diag(Tok, diag::err_unexpected_module_decl);
1026e5dd7070Spatrick SkipUntil(tok::semi);
1027e5dd7070Spatrick return nullptr;
1028e5dd7070Spatrick
1029e5dd7070Spatrick default:
1030e5dd7070Spatrick dont_know:
1031e5dd7070Spatrick if (Tok.isEditorPlaceholder()) {
1032e5dd7070Spatrick ConsumeToken();
1033e5dd7070Spatrick return nullptr;
1034e5dd7070Spatrick }
1035*12c85518Srobert if (PP.isIncrementalProcessingEnabled() &&
1036*12c85518Srobert !isDeclarationStatement(/*DisambiguatingWithExpression=*/true))
1037*12c85518Srobert return ParseTopLevelStmtDecl();
1038*12c85518Srobert
1039e5dd7070Spatrick // We can't tell whether this is a function-definition or declaration yet.
1040*12c85518Srobert if (!SingleDecl)
1041*12c85518Srobert return ParseDeclarationOrFunctionDefinition(Attrs, DeclSpecAttrs, DS);
1042e5dd7070Spatrick }
1043e5dd7070Spatrick
1044e5dd7070Spatrick // This routine returns a DeclGroup, if the thing we parsed only contains a
1045e5dd7070Spatrick // single decl, convert it now.
1046e5dd7070Spatrick return Actions.ConvertDeclToDeclGroup(SingleDecl);
1047e5dd7070Spatrick }
1048e5dd7070Spatrick
1049e5dd7070Spatrick /// Determine whether the current token, if it occurs after a
1050e5dd7070Spatrick /// declarator, continues a declaration or declaration list.
isDeclarationAfterDeclarator()1051e5dd7070Spatrick bool Parser::isDeclarationAfterDeclarator() {
1052e5dd7070Spatrick // Check for '= delete' or '= default'
1053e5dd7070Spatrick if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) {
1054e5dd7070Spatrick const Token &KW = NextToken();
1055e5dd7070Spatrick if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
1056e5dd7070Spatrick return false;
1057e5dd7070Spatrick }
1058e5dd7070Spatrick
1059e5dd7070Spatrick return Tok.is(tok::equal) || // int X()= -> not a function def
1060e5dd7070Spatrick Tok.is(tok::comma) || // int X(), -> not a function def
1061e5dd7070Spatrick Tok.is(tok::semi) || // int X(); -> not a function def
1062e5dd7070Spatrick Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def
1063e5dd7070Spatrick Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
1064e5dd7070Spatrick (getLangOpts().CPlusPlus &&
1065e5dd7070Spatrick Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++]
1066e5dd7070Spatrick }
1067e5dd7070Spatrick
1068e5dd7070Spatrick /// Determine whether the current token, if it occurs after a
1069e5dd7070Spatrick /// declarator, indicates the start of a function definition.
isStartOfFunctionDefinition(const ParsingDeclarator & Declarator)1070e5dd7070Spatrick bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
1071e5dd7070Spatrick assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator");
1072e5dd7070Spatrick if (Tok.is(tok::l_brace)) // int X() {}
1073e5dd7070Spatrick return true;
1074e5dd7070Spatrick
1075e5dd7070Spatrick // Handle K&R C argument lists: int X(f) int f; {}
1076e5dd7070Spatrick if (!getLangOpts().CPlusPlus &&
1077e5dd7070Spatrick Declarator.getFunctionTypeInfo().isKNRPrototype())
1078*12c85518Srobert return isDeclarationSpecifier(ImplicitTypenameContext::No);
1079e5dd7070Spatrick
1080e5dd7070Spatrick if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) {
1081e5dd7070Spatrick const Token &KW = NextToken();
1082e5dd7070Spatrick return KW.is(tok::kw_default) || KW.is(tok::kw_delete);
1083e5dd7070Spatrick }
1084e5dd7070Spatrick
1085e5dd7070Spatrick return Tok.is(tok::colon) || // X() : Base() {} (used for ctors)
1086e5dd7070Spatrick Tok.is(tok::kw_try); // X() try { ... }
1087e5dd7070Spatrick }
1088e5dd7070Spatrick
1089e5dd7070Spatrick /// Parse either a function-definition or a declaration. We can't tell which
1090e5dd7070Spatrick /// we have until we read up to the compound-statement in function-definition.
1091e5dd7070Spatrick /// TemplateParams, if non-NULL, provides the template parameters when we're
1092e5dd7070Spatrick /// parsing a C++ template-declaration.
1093e5dd7070Spatrick ///
1094e5dd7070Spatrick /// function-definition: [C99 6.9.1]
1095e5dd7070Spatrick /// decl-specs declarator declaration-list[opt] compound-statement
1096e5dd7070Spatrick /// [C90] function-definition: [C99 6.7.1] - implicit int result
1097e5dd7070Spatrick /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
1098e5dd7070Spatrick ///
1099e5dd7070Spatrick /// declaration: [C99 6.7]
1100e5dd7070Spatrick /// declaration-specifiers init-declarator-list[opt] ';'
1101e5dd7070Spatrick /// [!C99] init-declarator-list ';' [TODO: warn in c99 mode]
1102e5dd7070Spatrick /// [OMP] threadprivate-directive
1103e5dd7070Spatrick /// [OMP] allocate-directive [TODO]
1104e5dd7070Spatrick ///
ParseDeclOrFunctionDefInternal(ParsedAttributes & Attrs,ParsedAttributes & DeclSpecAttrs,ParsingDeclSpec & DS,AccessSpecifier AS)1105*12c85518Srobert Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
1106*12c85518Srobert ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,
1107*12c85518Srobert ParsingDeclSpec &DS, AccessSpecifier AS) {
1108*12c85518Srobert // Because we assume that the DeclSpec has not yet been initialised, we simply
1109*12c85518Srobert // overwrite the source range and attribute the provided leading declspec
1110*12c85518Srobert // attributes.
1111*12c85518Srobert assert(DS.getSourceRange().isInvalid() &&
1112*12c85518Srobert "expected uninitialised source range");
1113*12c85518Srobert DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());
1114*12c85518Srobert DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());
1115*12c85518Srobert DS.takeAttributesFrom(DeclSpecAttrs);
1116*12c85518Srobert
1117e5dd7070Spatrick MaybeParseMicrosoftAttributes(DS.getAttributes());
1118e5dd7070Spatrick // Parse the common declaration-specifiers piece.
1119e5dd7070Spatrick ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS,
1120e5dd7070Spatrick DeclSpecContext::DSC_top_level);
1121e5dd7070Spatrick
1122e5dd7070Spatrick // If we had a free-standing type definition with a missing semicolon, we
1123e5dd7070Spatrick // may get this far before the problem becomes obvious.
1124e5dd7070Spatrick if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition(
1125e5dd7070Spatrick DS, AS, DeclSpecContext::DSC_top_level))
1126e5dd7070Spatrick return nullptr;
1127e5dd7070Spatrick
1128e5dd7070Spatrick // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
1129e5dd7070Spatrick // declaration-specifiers init-declarator-list[opt] ';'
1130e5dd7070Spatrick if (Tok.is(tok::semi)) {
1131e5dd7070Spatrick auto LengthOfTSTToken = [](DeclSpec::TST TKind) {
1132e5dd7070Spatrick assert(DeclSpec::isDeclRep(TKind));
1133e5dd7070Spatrick switch(TKind) {
1134e5dd7070Spatrick case DeclSpec::TST_class:
1135e5dd7070Spatrick return 5;
1136e5dd7070Spatrick case DeclSpec::TST_struct:
1137e5dd7070Spatrick return 6;
1138e5dd7070Spatrick case DeclSpec::TST_union:
1139e5dd7070Spatrick return 5;
1140e5dd7070Spatrick case DeclSpec::TST_enum:
1141e5dd7070Spatrick return 4;
1142e5dd7070Spatrick case DeclSpec::TST_interface:
1143e5dd7070Spatrick return 9;
1144e5dd7070Spatrick default:
1145e5dd7070Spatrick llvm_unreachable("we only expect to get the length of the class/struct/union/enum");
1146e5dd7070Spatrick }
1147e5dd7070Spatrick
1148e5dd7070Spatrick };
1149e5dd7070Spatrick // Suggest correct location to fix '[[attrib]] struct' to 'struct [[attrib]]'
1150e5dd7070Spatrick SourceLocation CorrectLocationForAttributes =
1151e5dd7070Spatrick DeclSpec::isDeclRep(DS.getTypeSpecType())
1152e5dd7070Spatrick ? DS.getTypeSpecTypeLoc().getLocWithOffset(
1153e5dd7070Spatrick LengthOfTSTToken(DS.getTypeSpecType()))
1154e5dd7070Spatrick : SourceLocation();
1155*12c85518Srobert ProhibitAttributes(Attrs, CorrectLocationForAttributes);
1156e5dd7070Spatrick ConsumeToken();
1157e5dd7070Spatrick RecordDecl *AnonRecord = nullptr;
1158*12c85518Srobert Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1159*12c85518Srobert getCurScope(), AS_none, DS, ParsedAttributesView::none(), AnonRecord);
1160e5dd7070Spatrick DS.complete(TheDecl);
1161e5dd7070Spatrick if (AnonRecord) {
1162e5dd7070Spatrick Decl* decls[] = {AnonRecord, TheDecl};
1163e5dd7070Spatrick return Actions.BuildDeclaratorGroup(decls);
1164e5dd7070Spatrick }
1165e5dd7070Spatrick return Actions.ConvertDeclToDeclGroup(TheDecl);
1166e5dd7070Spatrick }
1167e5dd7070Spatrick
1168e5dd7070Spatrick // ObjC2 allows prefix attributes on class interfaces and protocols.
1169e5dd7070Spatrick // FIXME: This still needs better diagnostics. We should only accept
1170e5dd7070Spatrick // attributes here, no types, etc.
1171e5dd7070Spatrick if (getLangOpts().ObjC && Tok.is(tok::at)) {
1172e5dd7070Spatrick SourceLocation AtLoc = ConsumeToken(); // the "@"
1173e5dd7070Spatrick if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
1174e5dd7070Spatrick !Tok.isObjCAtKeyword(tok::objc_protocol) &&
1175e5dd7070Spatrick !Tok.isObjCAtKeyword(tok::objc_implementation)) {
1176e5dd7070Spatrick Diag(Tok, diag::err_objc_unexpected_attr);
1177e5dd7070Spatrick SkipUntil(tok::semi);
1178e5dd7070Spatrick return nullptr;
1179e5dd7070Spatrick }
1180e5dd7070Spatrick
1181e5dd7070Spatrick DS.abort();
1182*12c85518Srobert DS.takeAttributesFrom(Attrs);
1183e5dd7070Spatrick
1184e5dd7070Spatrick const char *PrevSpec = nullptr;
1185e5dd7070Spatrick unsigned DiagID;
1186e5dd7070Spatrick if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID,
1187e5dd7070Spatrick Actions.getASTContext().getPrintingPolicy()))
1188e5dd7070Spatrick Diag(AtLoc, DiagID) << PrevSpec;
1189e5dd7070Spatrick
1190e5dd7070Spatrick if (Tok.isObjCAtKeyword(tok::objc_protocol))
1191e5dd7070Spatrick return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
1192e5dd7070Spatrick
1193e5dd7070Spatrick if (Tok.isObjCAtKeyword(tok::objc_implementation))
1194e5dd7070Spatrick return ParseObjCAtImplementationDeclaration(AtLoc, DS.getAttributes());
1195e5dd7070Spatrick
1196e5dd7070Spatrick return Actions.ConvertDeclToDeclGroup(
1197e5dd7070Spatrick ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes()));
1198e5dd7070Spatrick }
1199e5dd7070Spatrick
1200e5dd7070Spatrick // If the declspec consisted only of 'extern' and we have a string
1201e5dd7070Spatrick // literal following it, this must be a C++ linkage specifier like
1202e5dd7070Spatrick // 'extern "C"'.
1203e5dd7070Spatrick if (getLangOpts().CPlusPlus && isTokenStringLiteral() &&
1204e5dd7070Spatrick DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
1205e5dd7070Spatrick DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
1206*12c85518Srobert ProhibitAttributes(Attrs);
1207a9ac8606Spatrick Decl *TheDecl = ParseLinkage(DS, DeclaratorContext::File);
1208e5dd7070Spatrick return Actions.ConvertDeclToDeclGroup(TheDecl);
1209e5dd7070Spatrick }
1210e5dd7070Spatrick
1211*12c85518Srobert return ParseDeclGroup(DS, DeclaratorContext::File, Attrs);
1212e5dd7070Spatrick }
1213e5dd7070Spatrick
ParseDeclarationOrFunctionDefinition(ParsedAttributes & Attrs,ParsedAttributes & DeclSpecAttrs,ParsingDeclSpec * DS,AccessSpecifier AS)1214*12c85518Srobert Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition(
1215*12c85518Srobert ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,
1216*12c85518Srobert ParsingDeclSpec *DS, AccessSpecifier AS) {
1217e5dd7070Spatrick if (DS) {
1218*12c85518Srobert return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS);
1219e5dd7070Spatrick } else {
1220e5dd7070Spatrick ParsingDeclSpec PDS(*this);
1221e5dd7070Spatrick // Must temporarily exit the objective-c container scope for
1222e5dd7070Spatrick // parsing c constructs and re-enter objc container scope
1223e5dd7070Spatrick // afterwards.
1224e5dd7070Spatrick ObjCDeclContextSwitch ObjCDC(*this);
1225e5dd7070Spatrick
1226*12c85518Srobert return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, PDS, AS);
1227e5dd7070Spatrick }
1228e5dd7070Spatrick }
1229e5dd7070Spatrick
1230e5dd7070Spatrick /// ParseFunctionDefinition - We parsed and verified that the specified
1231e5dd7070Spatrick /// Declarator is well formed. If this is a K&R-style function, read the
1232e5dd7070Spatrick /// parameters declaration-list, then start the compound-statement.
1233e5dd7070Spatrick ///
1234e5dd7070Spatrick /// function-definition: [C99 6.9.1]
1235e5dd7070Spatrick /// decl-specs declarator declaration-list[opt] compound-statement
1236e5dd7070Spatrick /// [C90] function-definition: [C99 6.7.1] - implicit int result
1237e5dd7070Spatrick /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
1238e5dd7070Spatrick /// [C++] function-definition: [C++ 8.4]
1239e5dd7070Spatrick /// decl-specifier-seq[opt] declarator ctor-initializer[opt]
1240e5dd7070Spatrick /// function-body
1241e5dd7070Spatrick /// [C++] function-definition: [C++ 8.4]
1242e5dd7070Spatrick /// decl-specifier-seq[opt] declarator function-try-block
1243e5dd7070Spatrick ///
ParseFunctionDefinition(ParsingDeclarator & D,const ParsedTemplateInfo & TemplateInfo,LateParsedAttrList * LateParsedAttrs)1244e5dd7070Spatrick Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
1245e5dd7070Spatrick const ParsedTemplateInfo &TemplateInfo,
1246e5dd7070Spatrick LateParsedAttrList *LateParsedAttrs) {
1247e5dd7070Spatrick // Poison SEH identifiers so they are flagged as illegal in function bodies.
1248e5dd7070Spatrick PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
1249e5dd7070Spatrick const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
1250e5dd7070Spatrick TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
1251e5dd7070Spatrick
1252*12c85518Srobert // If this is C89 and the declspecs were completely missing, fudge in an
1253e5dd7070Spatrick // implicit int. We do this here because this is the only place where
1254e5dd7070Spatrick // declaration-specifiers are completely optional in the grammar.
1255*12c85518Srobert if (getLangOpts().isImplicitIntRequired() && D.getDeclSpec().isEmpty()) {
1256*12c85518Srobert Diag(D.getIdentifierLoc(), diag::warn_missing_type_specifier)
1257*12c85518Srobert << D.getDeclSpec().getSourceRange();
1258e5dd7070Spatrick const char *PrevSpec;
1259e5dd7070Spatrick unsigned DiagID;
1260e5dd7070Spatrick const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
1261e5dd7070Spatrick D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
1262e5dd7070Spatrick D.getIdentifierLoc(),
1263e5dd7070Spatrick PrevSpec, DiagID,
1264e5dd7070Spatrick Policy);
1265e5dd7070Spatrick D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin());
1266e5dd7070Spatrick }
1267e5dd7070Spatrick
1268e5dd7070Spatrick // If this declaration was formed with a K&R-style identifier list for the
1269e5dd7070Spatrick // arguments, parse declarations for all of the args next.
1270e5dd7070Spatrick // int foo(a,b) int a; float b; {}
1271e5dd7070Spatrick if (FTI.isKNRPrototype())
1272e5dd7070Spatrick ParseKNRParamDeclarations(D);
1273e5dd7070Spatrick
1274e5dd7070Spatrick // We should have either an opening brace or, in a C++ constructor,
1275e5dd7070Spatrick // we may have a colon.
1276e5dd7070Spatrick if (Tok.isNot(tok::l_brace) &&
1277e5dd7070Spatrick (!getLangOpts().CPlusPlus ||
1278e5dd7070Spatrick (Tok.isNot(tok::colon) && Tok.isNot(tok::kw_try) &&
1279e5dd7070Spatrick Tok.isNot(tok::equal)))) {
1280e5dd7070Spatrick Diag(Tok, diag::err_expected_fn_body);
1281e5dd7070Spatrick
1282e5dd7070Spatrick // Skip over garbage, until we get to '{'. Don't eat the '{'.
1283e5dd7070Spatrick SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
1284e5dd7070Spatrick
1285e5dd7070Spatrick // If we didn't find the '{', bail out.
1286e5dd7070Spatrick if (Tok.isNot(tok::l_brace))
1287e5dd7070Spatrick return nullptr;
1288e5dd7070Spatrick }
1289e5dd7070Spatrick
1290e5dd7070Spatrick // Check to make sure that any normal attributes are allowed to be on
1291e5dd7070Spatrick // a definition. Late parsed attributes are checked at the end.
1292e5dd7070Spatrick if (Tok.isNot(tok::equal)) {
1293e5dd7070Spatrick for (const ParsedAttr &AL : D.getAttributes())
1294a9ac8606Spatrick if (AL.isKnownToGCC() && !AL.isStandardAttributeSyntax())
1295e5dd7070Spatrick Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) << AL;
1296e5dd7070Spatrick }
1297e5dd7070Spatrick
1298e5dd7070Spatrick // In delayed template parsing mode, for function template we consume the
1299e5dd7070Spatrick // tokens and store them for late parsing at the end of the translation unit.
1300e5dd7070Spatrick if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) &&
1301e5dd7070Spatrick TemplateInfo.Kind == ParsedTemplateInfo::Template &&
1302e5dd7070Spatrick Actions.canDelayFunctionBody(D)) {
1303e5dd7070Spatrick MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams);
1304e5dd7070Spatrick
1305e5dd7070Spatrick ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
1306e5dd7070Spatrick Scope::CompoundStmtScope);
1307e5dd7070Spatrick Scope *ParentScope = getCurScope()->getParent();
1308e5dd7070Spatrick
1309a9ac8606Spatrick D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
1310e5dd7070Spatrick Decl *DP = Actions.HandleDeclarator(ParentScope, D,
1311e5dd7070Spatrick TemplateParameterLists);
1312e5dd7070Spatrick D.complete(DP);
1313e5dd7070Spatrick D.getMutableDeclSpec().abort();
1314e5dd7070Spatrick
1315e5dd7070Spatrick if (SkipFunctionBodies && (!DP || Actions.canSkipFunctionBody(DP)) &&
1316e5dd7070Spatrick trySkippingFunctionBody()) {
1317e5dd7070Spatrick BodyScope.Exit();
1318e5dd7070Spatrick return Actions.ActOnSkippedFunctionBody(DP);
1319e5dd7070Spatrick }
1320e5dd7070Spatrick
1321e5dd7070Spatrick CachedTokens Toks;
1322e5dd7070Spatrick LexTemplateFunctionForLateParsing(Toks);
1323e5dd7070Spatrick
1324e5dd7070Spatrick if (DP) {
1325e5dd7070Spatrick FunctionDecl *FnD = DP->getAsFunction();
1326e5dd7070Spatrick Actions.CheckForFunctionRedefinition(FnD);
1327e5dd7070Spatrick Actions.MarkAsLateParsedTemplate(FnD, DP, Toks);
1328e5dd7070Spatrick }
1329e5dd7070Spatrick return DP;
1330e5dd7070Spatrick }
1331e5dd7070Spatrick else if (CurParsedObjCImpl &&
1332e5dd7070Spatrick !TemplateInfo.TemplateParams &&
1333e5dd7070Spatrick (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
1334e5dd7070Spatrick Tok.is(tok::colon)) &&
1335e5dd7070Spatrick Actions.CurContext->isTranslationUnit()) {
1336e5dd7070Spatrick ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
1337e5dd7070Spatrick Scope::CompoundStmtScope);
1338e5dd7070Spatrick Scope *ParentScope = getCurScope()->getParent();
1339e5dd7070Spatrick
1340a9ac8606Spatrick D.setFunctionDefinitionKind(FunctionDefinitionKind::Definition);
1341e5dd7070Spatrick Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D,
1342e5dd7070Spatrick MultiTemplateParamsArg());
1343e5dd7070Spatrick D.complete(FuncDecl);
1344e5dd7070Spatrick D.getMutableDeclSpec().abort();
1345e5dd7070Spatrick if (FuncDecl) {
1346e5dd7070Spatrick // Consume the tokens and store them for later parsing.
1347e5dd7070Spatrick StashAwayMethodOrFunctionBodyTokens(FuncDecl);
1348e5dd7070Spatrick CurParsedObjCImpl->HasCFunction = true;
1349e5dd7070Spatrick return FuncDecl;
1350e5dd7070Spatrick }
1351e5dd7070Spatrick // FIXME: Should we really fall through here?
1352e5dd7070Spatrick }
1353e5dd7070Spatrick
1354e5dd7070Spatrick // Enter a scope for the function body.
1355e5dd7070Spatrick ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope |
1356e5dd7070Spatrick Scope::CompoundStmtScope);
1357e5dd7070Spatrick
1358*12c85518Srobert // Parse function body eagerly if it is either '= delete;' or '= default;' as
1359*12c85518Srobert // ActOnStartOfFunctionDef needs to know whether the function is deleted.
1360*12c85518Srobert Sema::FnBodyKind BodyKind = Sema::FnBodyKind::Other;
1361*12c85518Srobert SourceLocation KWLoc;
1362*12c85518Srobert if (TryConsumeToken(tok::equal)) {
1363*12c85518Srobert assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
1364*12c85518Srobert
1365*12c85518Srobert if (TryConsumeToken(tok::kw_delete, KWLoc)) {
1366*12c85518Srobert Diag(KWLoc, getLangOpts().CPlusPlus11
1367*12c85518Srobert ? diag::warn_cxx98_compat_defaulted_deleted_function
1368*12c85518Srobert : diag::ext_defaulted_deleted_function)
1369*12c85518Srobert << 1 /* deleted */;
1370*12c85518Srobert BodyKind = Sema::FnBodyKind::Delete;
1371*12c85518Srobert } else if (TryConsumeToken(tok::kw_default, KWLoc)) {
1372*12c85518Srobert Diag(KWLoc, getLangOpts().CPlusPlus11
1373*12c85518Srobert ? diag::warn_cxx98_compat_defaulted_deleted_function
1374*12c85518Srobert : diag::ext_defaulted_deleted_function)
1375*12c85518Srobert << 0 /* defaulted */;
1376*12c85518Srobert BodyKind = Sema::FnBodyKind::Default;
1377*12c85518Srobert } else {
1378*12c85518Srobert llvm_unreachable("function definition after = not 'delete' or 'default'");
1379*12c85518Srobert }
1380*12c85518Srobert
1381*12c85518Srobert if (Tok.is(tok::comma)) {
1382*12c85518Srobert Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
1383*12c85518Srobert << (BodyKind == Sema::FnBodyKind::Delete);
1384*12c85518Srobert SkipUntil(tok::semi);
1385*12c85518Srobert } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
1386*12c85518Srobert BodyKind == Sema::FnBodyKind::Delete
1387*12c85518Srobert ? "delete"
1388*12c85518Srobert : "default")) {
1389*12c85518Srobert SkipUntil(tok::semi);
1390*12c85518Srobert }
1391*12c85518Srobert }
1392*12c85518Srobert
1393e5dd7070Spatrick // Tell the actions module that we have entered a function definition with the
1394e5dd7070Spatrick // specified Declarator for the function.
1395e5dd7070Spatrick Sema::SkipBodyInfo SkipBody;
1396e5dd7070Spatrick Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D,
1397e5dd7070Spatrick TemplateInfo.TemplateParams
1398e5dd7070Spatrick ? *TemplateInfo.TemplateParams
1399e5dd7070Spatrick : MultiTemplateParamsArg(),
1400*12c85518Srobert &SkipBody, BodyKind);
1401e5dd7070Spatrick
1402e5dd7070Spatrick if (SkipBody.ShouldSkip) {
1403*12c85518Srobert // Do NOT enter SkipFunctionBody if we already consumed the tokens.
1404*12c85518Srobert if (BodyKind == Sema::FnBodyKind::Other)
1405e5dd7070Spatrick SkipFunctionBody();
1406*12c85518Srobert
1407e5dd7070Spatrick return Res;
1408e5dd7070Spatrick }
1409e5dd7070Spatrick
1410e5dd7070Spatrick // Break out of the ParsingDeclarator context before we parse the body.
1411e5dd7070Spatrick D.complete(Res);
1412e5dd7070Spatrick
1413e5dd7070Spatrick // Break out of the ParsingDeclSpec context, too. This const_cast is
1414e5dd7070Spatrick // safe because we're always the sole owner.
1415e5dd7070Spatrick D.getMutableDeclSpec().abort();
1416e5dd7070Spatrick
1417*12c85518Srobert if (BodyKind != Sema::FnBodyKind::Other) {
1418*12c85518Srobert Actions.SetFunctionBodyKind(Res, KWLoc, BodyKind);
1419*12c85518Srobert Stmt *GeneratedBody = Res ? Res->getBody() : nullptr;
1420*12c85518Srobert Actions.ActOnFinishFunctionBody(Res, GeneratedBody, false);
1421*12c85518Srobert return Res;
1422*12c85518Srobert }
1423*12c85518Srobert
1424e5dd7070Spatrick // With abbreviated function templates - we need to explicitly add depth to
1425e5dd7070Spatrick // account for the implicit template parameter list induced by the template.
1426e5dd7070Spatrick if (auto *Template = dyn_cast_or_null<FunctionTemplateDecl>(Res))
1427e5dd7070Spatrick if (Template->isAbbreviated() &&
1428e5dd7070Spatrick Template->getTemplateParameters()->getParam(0)->isImplicit())
1429e5dd7070Spatrick // First template parameter is implicit - meaning no explicit template
1430e5dd7070Spatrick // parameter list was specified.
1431e5dd7070Spatrick CurTemplateDepthTracker.addDepth(1);
1432e5dd7070Spatrick
1433e5dd7070Spatrick if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) &&
1434e5dd7070Spatrick trySkippingFunctionBody()) {
1435e5dd7070Spatrick BodyScope.Exit();
1436e5dd7070Spatrick Actions.ActOnSkippedFunctionBody(Res);
1437e5dd7070Spatrick return Actions.ActOnFinishFunctionBody(Res, nullptr, false);
1438e5dd7070Spatrick }
1439e5dd7070Spatrick
1440e5dd7070Spatrick if (Tok.is(tok::kw_try))
1441e5dd7070Spatrick return ParseFunctionTryBlock(Res, BodyScope);
1442e5dd7070Spatrick
1443e5dd7070Spatrick // If we have a colon, then we're probably parsing a C++
1444e5dd7070Spatrick // ctor-initializer.
1445e5dd7070Spatrick if (Tok.is(tok::colon)) {
1446e5dd7070Spatrick ParseConstructorInitializer(Res);
1447e5dd7070Spatrick
1448e5dd7070Spatrick // Recover from error.
1449e5dd7070Spatrick if (!Tok.is(tok::l_brace)) {
1450e5dd7070Spatrick BodyScope.Exit();
1451e5dd7070Spatrick Actions.ActOnFinishFunctionBody(Res, nullptr);
1452e5dd7070Spatrick return Res;
1453e5dd7070Spatrick }
1454e5dd7070Spatrick } else
1455e5dd7070Spatrick Actions.ActOnDefaultCtorInitializers(Res);
1456e5dd7070Spatrick
1457e5dd7070Spatrick // Late attributes are parsed in the same scope as the function body.
1458e5dd7070Spatrick if (LateParsedAttrs)
1459e5dd7070Spatrick ParseLexedAttributeList(*LateParsedAttrs, Res, false, true);
1460e5dd7070Spatrick
1461e5dd7070Spatrick return ParseFunctionStatementBody(Res, BodyScope);
1462e5dd7070Spatrick }
1463e5dd7070Spatrick
SkipFunctionBody()1464e5dd7070Spatrick void Parser::SkipFunctionBody() {
1465e5dd7070Spatrick if (Tok.is(tok::equal)) {
1466e5dd7070Spatrick SkipUntil(tok::semi);
1467e5dd7070Spatrick return;
1468e5dd7070Spatrick }
1469e5dd7070Spatrick
1470e5dd7070Spatrick bool IsFunctionTryBlock = Tok.is(tok::kw_try);
1471e5dd7070Spatrick if (IsFunctionTryBlock)
1472e5dd7070Spatrick ConsumeToken();
1473e5dd7070Spatrick
1474e5dd7070Spatrick CachedTokens Skipped;
1475e5dd7070Spatrick if (ConsumeAndStoreFunctionPrologue(Skipped))
1476e5dd7070Spatrick SkipMalformedDecl();
1477e5dd7070Spatrick else {
1478e5dd7070Spatrick SkipUntil(tok::r_brace);
1479e5dd7070Spatrick while (IsFunctionTryBlock && Tok.is(tok::kw_catch)) {
1480e5dd7070Spatrick SkipUntil(tok::l_brace);
1481e5dd7070Spatrick SkipUntil(tok::r_brace);
1482e5dd7070Spatrick }
1483e5dd7070Spatrick }
1484e5dd7070Spatrick }
1485e5dd7070Spatrick
1486e5dd7070Spatrick /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
1487e5dd7070Spatrick /// types for a function with a K&R-style identifier list for arguments.
ParseKNRParamDeclarations(Declarator & D)1488e5dd7070Spatrick void Parser::ParseKNRParamDeclarations(Declarator &D) {
1489e5dd7070Spatrick // We know that the top-level of this declarator is a function.
1490e5dd7070Spatrick DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
1491e5dd7070Spatrick
1492e5dd7070Spatrick // Enter function-declaration scope, limiting any declarators to the
1493e5dd7070Spatrick // function prototype scope, including parameter declarators.
1494e5dd7070Spatrick ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
1495e5dd7070Spatrick Scope::FunctionDeclarationScope | Scope::DeclScope);
1496e5dd7070Spatrick
1497e5dd7070Spatrick // Read all the argument declarations.
1498*12c85518Srobert while (isDeclarationSpecifier(ImplicitTypenameContext::No)) {
1499e5dd7070Spatrick SourceLocation DSStart = Tok.getLocation();
1500e5dd7070Spatrick
1501e5dd7070Spatrick // Parse the common declaration-specifiers piece.
1502e5dd7070Spatrick DeclSpec DS(AttrFactory);
1503e5dd7070Spatrick ParseDeclarationSpecifiers(DS);
1504e5dd7070Spatrick
1505e5dd7070Spatrick // C99 6.9.1p6: 'each declaration in the declaration list shall have at
1506e5dd7070Spatrick // least one declarator'.
1507e5dd7070Spatrick // NOTE: GCC just makes this an ext-warn. It's not clear what it does with
1508e5dd7070Spatrick // the declarations though. It's trivial to ignore them, really hard to do
1509e5dd7070Spatrick // anything else with them.
1510e5dd7070Spatrick if (TryConsumeToken(tok::semi)) {
1511e5dd7070Spatrick Diag(DSStart, diag::err_declaration_does_not_declare_param);
1512e5dd7070Spatrick continue;
1513e5dd7070Spatrick }
1514e5dd7070Spatrick
1515e5dd7070Spatrick // C99 6.9.1p6: Declarations shall contain no storage-class specifiers other
1516e5dd7070Spatrick // than register.
1517e5dd7070Spatrick if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified &&
1518e5dd7070Spatrick DS.getStorageClassSpec() != DeclSpec::SCS_register) {
1519e5dd7070Spatrick Diag(DS.getStorageClassSpecLoc(),
1520e5dd7070Spatrick diag::err_invalid_storage_class_in_func_decl);
1521e5dd7070Spatrick DS.ClearStorageClassSpecs();
1522e5dd7070Spatrick }
1523e5dd7070Spatrick if (DS.getThreadStorageClassSpec() != DeclSpec::TSCS_unspecified) {
1524e5dd7070Spatrick Diag(DS.getThreadStorageClassSpecLoc(),
1525e5dd7070Spatrick diag::err_invalid_storage_class_in_func_decl);
1526e5dd7070Spatrick DS.ClearStorageClassSpecs();
1527e5dd7070Spatrick }
1528e5dd7070Spatrick
1529e5dd7070Spatrick // Parse the first declarator attached to this declspec.
1530*12c85518Srobert Declarator ParmDeclarator(DS, ParsedAttributesView::none(),
1531*12c85518Srobert DeclaratorContext::KNRTypeList);
1532e5dd7070Spatrick ParseDeclarator(ParmDeclarator);
1533e5dd7070Spatrick
1534e5dd7070Spatrick // Handle the full declarator list.
1535*12c85518Srobert while (true) {
1536e5dd7070Spatrick // If attributes are present, parse them.
1537e5dd7070Spatrick MaybeParseGNUAttributes(ParmDeclarator);
1538e5dd7070Spatrick
1539e5dd7070Spatrick // Ask the actions module to compute the type for this declarator.
1540e5dd7070Spatrick Decl *Param =
1541e5dd7070Spatrick Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);
1542e5dd7070Spatrick
1543e5dd7070Spatrick if (Param &&
1544e5dd7070Spatrick // A missing identifier has already been diagnosed.
1545e5dd7070Spatrick ParmDeclarator.getIdentifier()) {
1546e5dd7070Spatrick
1547e5dd7070Spatrick // Scan the argument list looking for the correct param to apply this
1548e5dd7070Spatrick // type.
1549e5dd7070Spatrick for (unsigned i = 0; ; ++i) {
1550e5dd7070Spatrick // C99 6.9.1p6: those declarators shall declare only identifiers from
1551e5dd7070Spatrick // the identifier list.
1552e5dd7070Spatrick if (i == FTI.NumParams) {
1553e5dd7070Spatrick Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param)
1554e5dd7070Spatrick << ParmDeclarator.getIdentifier();
1555e5dd7070Spatrick break;
1556e5dd7070Spatrick }
1557e5dd7070Spatrick
1558e5dd7070Spatrick if (FTI.Params[i].Ident == ParmDeclarator.getIdentifier()) {
1559e5dd7070Spatrick // Reject redefinitions of parameters.
1560e5dd7070Spatrick if (FTI.Params[i].Param) {
1561e5dd7070Spatrick Diag(ParmDeclarator.getIdentifierLoc(),
1562e5dd7070Spatrick diag::err_param_redefinition)
1563e5dd7070Spatrick << ParmDeclarator.getIdentifier();
1564e5dd7070Spatrick } else {
1565e5dd7070Spatrick FTI.Params[i].Param = Param;
1566e5dd7070Spatrick }
1567e5dd7070Spatrick break;
1568e5dd7070Spatrick }
1569e5dd7070Spatrick }
1570e5dd7070Spatrick }
1571e5dd7070Spatrick
1572e5dd7070Spatrick // If we don't have a comma, it is either the end of the list (a ';') or
1573e5dd7070Spatrick // an error, bail out.
1574e5dd7070Spatrick if (Tok.isNot(tok::comma))
1575e5dd7070Spatrick break;
1576e5dd7070Spatrick
1577e5dd7070Spatrick ParmDeclarator.clear();
1578e5dd7070Spatrick
1579e5dd7070Spatrick // Consume the comma.
1580e5dd7070Spatrick ParmDeclarator.setCommaLoc(ConsumeToken());
1581e5dd7070Spatrick
1582e5dd7070Spatrick // Parse the next declarator.
1583e5dd7070Spatrick ParseDeclarator(ParmDeclarator);
1584e5dd7070Spatrick }
1585e5dd7070Spatrick
1586e5dd7070Spatrick // Consume ';' and continue parsing.
1587e5dd7070Spatrick if (!ExpectAndConsumeSemi(diag::err_expected_semi_declaration))
1588e5dd7070Spatrick continue;
1589e5dd7070Spatrick
1590e5dd7070Spatrick // Otherwise recover by skipping to next semi or mandatory function body.
1591e5dd7070Spatrick if (SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch))
1592e5dd7070Spatrick break;
1593e5dd7070Spatrick TryConsumeToken(tok::semi);
1594e5dd7070Spatrick }
1595e5dd7070Spatrick
1596e5dd7070Spatrick // The actions module must verify that all arguments were declared.
1597e5dd7070Spatrick Actions.ActOnFinishKNRParamDeclarations(getCurScope(), D, Tok.getLocation());
1598e5dd7070Spatrick }
1599e5dd7070Spatrick
1600e5dd7070Spatrick
1601e5dd7070Spatrick /// ParseAsmStringLiteral - This is just a normal string-literal, but is not
1602e5dd7070Spatrick /// allowed to be a wide string, and is not subject to character translation.
1603e5dd7070Spatrick /// Unlike GCC, we also diagnose an empty string literal when parsing for an
1604e5dd7070Spatrick /// asm label as opposed to an asm statement, because such a construct does not
1605e5dd7070Spatrick /// behave well.
1606e5dd7070Spatrick ///
1607e5dd7070Spatrick /// [GNU] asm-string-literal:
1608e5dd7070Spatrick /// string-literal
1609e5dd7070Spatrick ///
ParseAsmStringLiteral(bool ForAsmLabel)1610e5dd7070Spatrick ExprResult Parser::ParseAsmStringLiteral(bool ForAsmLabel) {
1611e5dd7070Spatrick if (!isTokenStringLiteral()) {
1612e5dd7070Spatrick Diag(Tok, diag::err_expected_string_literal)
1613e5dd7070Spatrick << /*Source='in...'*/0 << "'asm'";
1614e5dd7070Spatrick return ExprError();
1615e5dd7070Spatrick }
1616e5dd7070Spatrick
1617e5dd7070Spatrick ExprResult AsmString(ParseStringLiteralExpression());
1618e5dd7070Spatrick if (!AsmString.isInvalid()) {
1619e5dd7070Spatrick const auto *SL = cast<StringLiteral>(AsmString.get());
1620*12c85518Srobert if (!SL->isOrdinary()) {
1621e5dd7070Spatrick Diag(Tok, diag::err_asm_operand_wide_string_literal)
1622e5dd7070Spatrick << SL->isWide()
1623e5dd7070Spatrick << SL->getSourceRange();
1624e5dd7070Spatrick return ExprError();
1625e5dd7070Spatrick }
1626e5dd7070Spatrick if (ForAsmLabel && SL->getString().empty()) {
1627e5dd7070Spatrick Diag(Tok, diag::err_asm_operand_wide_string_literal)
1628e5dd7070Spatrick << 2 /* an empty */ << SL->getSourceRange();
1629e5dd7070Spatrick return ExprError();
1630e5dd7070Spatrick }
1631e5dd7070Spatrick }
1632e5dd7070Spatrick return AsmString;
1633e5dd7070Spatrick }
1634e5dd7070Spatrick
1635e5dd7070Spatrick /// ParseSimpleAsm
1636e5dd7070Spatrick ///
1637e5dd7070Spatrick /// [GNU] simple-asm-expr:
1638e5dd7070Spatrick /// 'asm' '(' asm-string-literal ')'
1639e5dd7070Spatrick ///
ParseSimpleAsm(bool ForAsmLabel,SourceLocation * EndLoc)1640e5dd7070Spatrick ExprResult Parser::ParseSimpleAsm(bool ForAsmLabel, SourceLocation *EndLoc) {
1641e5dd7070Spatrick assert(Tok.is(tok::kw_asm) && "Not an asm!");
1642e5dd7070Spatrick SourceLocation Loc = ConsumeToken();
1643e5dd7070Spatrick
1644ec727ea7Spatrick if (isGNUAsmQualifier(Tok)) {
1645ec727ea7Spatrick // Remove from the end of 'asm' to the end of the asm qualifier.
1646e5dd7070Spatrick SourceRange RemovalRange(PP.getLocForEndOfToken(Loc),
1647e5dd7070Spatrick PP.getLocForEndOfToken(Tok.getLocation()));
1648ec727ea7Spatrick Diag(Tok, diag::err_global_asm_qualifier_ignored)
1649ec727ea7Spatrick << GNUAsmQualifiers::getQualifierName(getGNUAsmQualifier(Tok))
1650e5dd7070Spatrick << FixItHint::CreateRemoval(RemovalRange);
1651e5dd7070Spatrick ConsumeToken();
1652e5dd7070Spatrick }
1653e5dd7070Spatrick
1654e5dd7070Spatrick BalancedDelimiterTracker T(*this, tok::l_paren);
1655e5dd7070Spatrick if (T.consumeOpen()) {
1656e5dd7070Spatrick Diag(Tok, diag::err_expected_lparen_after) << "asm";
1657e5dd7070Spatrick return ExprError();
1658e5dd7070Spatrick }
1659e5dd7070Spatrick
1660e5dd7070Spatrick ExprResult Result(ParseAsmStringLiteral(ForAsmLabel));
1661e5dd7070Spatrick
1662e5dd7070Spatrick if (!Result.isInvalid()) {
1663e5dd7070Spatrick // Close the paren and get the location of the end bracket
1664e5dd7070Spatrick T.consumeClose();
1665e5dd7070Spatrick if (EndLoc)
1666e5dd7070Spatrick *EndLoc = T.getCloseLocation();
1667e5dd7070Spatrick } else if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
1668e5dd7070Spatrick if (EndLoc)
1669e5dd7070Spatrick *EndLoc = Tok.getLocation();
1670e5dd7070Spatrick ConsumeParen();
1671e5dd7070Spatrick }
1672e5dd7070Spatrick
1673e5dd7070Spatrick return Result;
1674e5dd7070Spatrick }
1675e5dd7070Spatrick
1676e5dd7070Spatrick /// Get the TemplateIdAnnotation from the token and put it in the
1677e5dd7070Spatrick /// cleanup pool so that it gets destroyed when parsing the current top level
1678e5dd7070Spatrick /// declaration is finished.
takeTemplateIdAnnotation(const Token & tok)1679e5dd7070Spatrick TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) {
1680e5dd7070Spatrick assert(tok.is(tok::annot_template_id) && "Expected template-id token");
1681e5dd7070Spatrick TemplateIdAnnotation *
1682e5dd7070Spatrick Id = static_cast<TemplateIdAnnotation *>(tok.getAnnotationValue());
1683e5dd7070Spatrick return Id;
1684e5dd7070Spatrick }
1685e5dd7070Spatrick
AnnotateScopeToken(CXXScopeSpec & SS,bool IsNewAnnotation)1686e5dd7070Spatrick void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {
1687e5dd7070Spatrick // Push the current token back into the token stream (or revert it if it is
1688e5dd7070Spatrick // cached) and use an annotation scope token for current token.
1689e5dd7070Spatrick if (PP.isBacktrackEnabled())
1690e5dd7070Spatrick PP.RevertCachedTokens(1);
1691e5dd7070Spatrick else
1692e5dd7070Spatrick PP.EnterToken(Tok, /*IsReinject=*/true);
1693e5dd7070Spatrick Tok.setKind(tok::annot_cxxscope);
1694e5dd7070Spatrick Tok.setAnnotationValue(Actions.SaveNestedNameSpecifierAnnotation(SS));
1695e5dd7070Spatrick Tok.setAnnotationRange(SS.getRange());
1696e5dd7070Spatrick
1697e5dd7070Spatrick // In case the tokens were cached, have Preprocessor replace them
1698e5dd7070Spatrick // with the annotation token. We don't need to do this if we've
1699e5dd7070Spatrick // just reverted back to a prior state.
1700e5dd7070Spatrick if (IsNewAnnotation)
1701e5dd7070Spatrick PP.AnnotateCachedTokens(Tok);
1702e5dd7070Spatrick }
1703e5dd7070Spatrick
1704e5dd7070Spatrick /// Attempt to classify the name at the current token position. This may
1705e5dd7070Spatrick /// form a type, scope or primary expression annotation, or replace the token
1706e5dd7070Spatrick /// with a typo-corrected keyword. This is only appropriate when the current
1707e5dd7070Spatrick /// name must refer to an entity which has already been declared.
1708e5dd7070Spatrick ///
1709e5dd7070Spatrick /// \param CCC Indicates how to perform typo-correction for this name. If NULL,
1710e5dd7070Spatrick /// no typo correction will be performed.
1711*12c85518Srobert /// \param AllowImplicitTypename Whether we are in a context where a dependent
1712*12c85518Srobert /// nested-name-specifier without typename is treated as a type (e.g.
1713*12c85518Srobert /// T::type).
1714e5dd7070Spatrick Parser::AnnotatedNameKind
TryAnnotateName(CorrectionCandidateCallback * CCC,ImplicitTypenameContext AllowImplicitTypename)1715*12c85518Srobert Parser::TryAnnotateName(CorrectionCandidateCallback *CCC,
1716*12c85518Srobert ImplicitTypenameContext AllowImplicitTypename) {
1717e5dd7070Spatrick assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope));
1718e5dd7070Spatrick
1719e5dd7070Spatrick const bool EnteringContext = false;
1720e5dd7070Spatrick const bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
1721e5dd7070Spatrick
1722e5dd7070Spatrick CXXScopeSpec SS;
1723e5dd7070Spatrick if (getLangOpts().CPlusPlus &&
1724ec727ea7Spatrick ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1725*12c85518Srobert /*ObjectHasErrors=*/false,
1726ec727ea7Spatrick EnteringContext))
1727e5dd7070Spatrick return ANK_Error;
1728e5dd7070Spatrick
1729e5dd7070Spatrick if (Tok.isNot(tok::identifier) || SS.isInvalid()) {
1730*12c85518Srobert if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation,
1731*12c85518Srobert AllowImplicitTypename))
1732e5dd7070Spatrick return ANK_Error;
1733e5dd7070Spatrick return ANK_Unresolved;
1734e5dd7070Spatrick }
1735e5dd7070Spatrick
1736e5dd7070Spatrick IdentifierInfo *Name = Tok.getIdentifierInfo();
1737e5dd7070Spatrick SourceLocation NameLoc = Tok.getLocation();
1738e5dd7070Spatrick
1739e5dd7070Spatrick // FIXME: Move the tentative declaration logic into ClassifyName so we can
1740e5dd7070Spatrick // typo-correct to tentatively-declared identifiers.
1741*12c85518Srobert if (isTentativelyDeclared(Name) && SS.isEmpty()) {
1742e5dd7070Spatrick // Identifier has been tentatively declared, and thus cannot be resolved as
1743e5dd7070Spatrick // an expression. Fall back to annotating it as a type.
1744*12c85518Srobert if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation,
1745*12c85518Srobert AllowImplicitTypename))
1746e5dd7070Spatrick return ANK_Error;
1747e5dd7070Spatrick return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl;
1748e5dd7070Spatrick }
1749e5dd7070Spatrick
1750e5dd7070Spatrick Token Next = NextToken();
1751e5dd7070Spatrick
1752e5dd7070Spatrick // Look up and classify the identifier. We don't perform any typo-correction
1753e5dd7070Spatrick // after a scope specifier, because in general we can't recover from typos
1754e5dd7070Spatrick // there (eg, after correcting 'A::template B<X>::C' [sic], we would need to
1755e5dd7070Spatrick // jump back into scope specifier parsing).
1756e5dd7070Spatrick Sema::NameClassification Classification = Actions.ClassifyName(
1757e5dd7070Spatrick getCurScope(), SS, Name, NameLoc, Next, SS.isEmpty() ? CCC : nullptr);
1758e5dd7070Spatrick
1759e5dd7070Spatrick // If name lookup found nothing and we guessed that this was a template name,
1760e5dd7070Spatrick // double-check before committing to that interpretation. C++20 requires that
1761e5dd7070Spatrick // we interpret this as a template-id if it can be, but if it can't be, then
1762e5dd7070Spatrick // this is an error recovery case.
1763e5dd7070Spatrick if (Classification.getKind() == Sema::NC_UndeclaredTemplate &&
1764e5dd7070Spatrick isTemplateArgumentList(1) == TPResult::False) {
1765e5dd7070Spatrick // It's not a template-id; re-classify without the '<' as a hint.
1766e5dd7070Spatrick Token FakeNext = Next;
1767e5dd7070Spatrick FakeNext.setKind(tok::unknown);
1768e5dd7070Spatrick Classification =
1769e5dd7070Spatrick Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, FakeNext,
1770e5dd7070Spatrick SS.isEmpty() ? CCC : nullptr);
1771e5dd7070Spatrick }
1772e5dd7070Spatrick
1773e5dd7070Spatrick switch (Classification.getKind()) {
1774e5dd7070Spatrick case Sema::NC_Error:
1775e5dd7070Spatrick return ANK_Error;
1776e5dd7070Spatrick
1777e5dd7070Spatrick case Sema::NC_Keyword:
1778e5dd7070Spatrick // The identifier was typo-corrected to a keyword.
1779e5dd7070Spatrick Tok.setIdentifierInfo(Name);
1780e5dd7070Spatrick Tok.setKind(Name->getTokenID());
1781e5dd7070Spatrick PP.TypoCorrectToken(Tok);
1782e5dd7070Spatrick if (SS.isNotEmpty())
1783e5dd7070Spatrick AnnotateScopeToken(SS, !WasScopeAnnotation);
1784e5dd7070Spatrick // We've "annotated" this as a keyword.
1785e5dd7070Spatrick return ANK_Success;
1786e5dd7070Spatrick
1787e5dd7070Spatrick case Sema::NC_Unknown:
1788e5dd7070Spatrick // It's not something we know about. Leave it unannotated.
1789e5dd7070Spatrick break;
1790e5dd7070Spatrick
1791e5dd7070Spatrick case Sema::NC_Type: {
1792a9ac8606Spatrick if (TryAltiVecVectorToken())
1793a9ac8606Spatrick // vector has been found as a type id when altivec is enabled but
1794a9ac8606Spatrick // this is followed by a declaration specifier so this is really the
1795a9ac8606Spatrick // altivec vector token. Leave it unannotated.
1796a9ac8606Spatrick break;
1797e5dd7070Spatrick SourceLocation BeginLoc = NameLoc;
1798e5dd7070Spatrick if (SS.isNotEmpty())
1799e5dd7070Spatrick BeginLoc = SS.getBeginLoc();
1800e5dd7070Spatrick
1801e5dd7070Spatrick /// An Objective-C object type followed by '<' is a specialization of
1802e5dd7070Spatrick /// a parameterized class type or a protocol-qualified type.
1803e5dd7070Spatrick ParsedType Ty = Classification.getType();
1804e5dd7070Spatrick if (getLangOpts().ObjC && NextToken().is(tok::less) &&
1805e5dd7070Spatrick (Ty.get()->isObjCObjectType() ||
1806e5dd7070Spatrick Ty.get()->isObjCObjectPointerType())) {
1807e5dd7070Spatrick // Consume the name.
1808e5dd7070Spatrick SourceLocation IdentifierLoc = ConsumeToken();
1809e5dd7070Spatrick SourceLocation NewEndLoc;
1810e5dd7070Spatrick TypeResult NewType
1811e5dd7070Spatrick = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,
1812e5dd7070Spatrick /*consumeLastToken=*/false,
1813e5dd7070Spatrick NewEndLoc);
1814e5dd7070Spatrick if (NewType.isUsable())
1815e5dd7070Spatrick Ty = NewType.get();
1816e5dd7070Spatrick else if (Tok.is(tok::eof)) // Nothing to do here, bail out...
1817e5dd7070Spatrick return ANK_Error;
1818e5dd7070Spatrick }
1819e5dd7070Spatrick
1820e5dd7070Spatrick Tok.setKind(tok::annot_typename);
1821e5dd7070Spatrick setTypeAnnotation(Tok, Ty);
1822e5dd7070Spatrick Tok.setAnnotationEndLoc(Tok.getLocation());
1823e5dd7070Spatrick Tok.setLocation(BeginLoc);
1824e5dd7070Spatrick PP.AnnotateCachedTokens(Tok);
1825e5dd7070Spatrick return ANK_Success;
1826e5dd7070Spatrick }
1827e5dd7070Spatrick
1828a9ac8606Spatrick case Sema::NC_OverloadSet:
1829a9ac8606Spatrick Tok.setKind(tok::annot_overload_set);
1830e5dd7070Spatrick setExprAnnotation(Tok, Classification.getExpression());
1831e5dd7070Spatrick Tok.setAnnotationEndLoc(NameLoc);
1832e5dd7070Spatrick if (SS.isNotEmpty())
1833e5dd7070Spatrick Tok.setLocation(SS.getBeginLoc());
1834e5dd7070Spatrick PP.AnnotateCachedTokens(Tok);
1835e5dd7070Spatrick return ANK_Success;
1836e5dd7070Spatrick
1837e5dd7070Spatrick case Sema::NC_NonType:
1838a9ac8606Spatrick if (TryAltiVecVectorToken())
1839a9ac8606Spatrick // vector has been found as a non-type id when altivec is enabled but
1840a9ac8606Spatrick // this is followed by a declaration specifier so this is really the
1841a9ac8606Spatrick // altivec vector token. Leave it unannotated.
1842a9ac8606Spatrick break;
1843e5dd7070Spatrick Tok.setKind(tok::annot_non_type);
1844e5dd7070Spatrick setNonTypeAnnotation(Tok, Classification.getNonTypeDecl());
1845e5dd7070Spatrick Tok.setLocation(NameLoc);
1846e5dd7070Spatrick Tok.setAnnotationEndLoc(NameLoc);
1847e5dd7070Spatrick PP.AnnotateCachedTokens(Tok);
1848e5dd7070Spatrick if (SS.isNotEmpty())
1849e5dd7070Spatrick AnnotateScopeToken(SS, !WasScopeAnnotation);
1850e5dd7070Spatrick return ANK_Success;
1851e5dd7070Spatrick
1852e5dd7070Spatrick case Sema::NC_UndeclaredNonType:
1853e5dd7070Spatrick case Sema::NC_DependentNonType:
1854e5dd7070Spatrick Tok.setKind(Classification.getKind() == Sema::NC_UndeclaredNonType
1855e5dd7070Spatrick ? tok::annot_non_type_undeclared
1856e5dd7070Spatrick : tok::annot_non_type_dependent);
1857e5dd7070Spatrick setIdentifierAnnotation(Tok, Name);
1858e5dd7070Spatrick Tok.setLocation(NameLoc);
1859e5dd7070Spatrick Tok.setAnnotationEndLoc(NameLoc);
1860e5dd7070Spatrick PP.AnnotateCachedTokens(Tok);
1861e5dd7070Spatrick if (SS.isNotEmpty())
1862e5dd7070Spatrick AnnotateScopeToken(SS, !WasScopeAnnotation);
1863e5dd7070Spatrick return ANK_Success;
1864e5dd7070Spatrick
1865e5dd7070Spatrick case Sema::NC_TypeTemplate:
1866e5dd7070Spatrick if (Next.isNot(tok::less)) {
1867e5dd7070Spatrick // This may be a type template being used as a template template argument.
1868e5dd7070Spatrick if (SS.isNotEmpty())
1869e5dd7070Spatrick AnnotateScopeToken(SS, !WasScopeAnnotation);
1870e5dd7070Spatrick return ANK_TemplateName;
1871e5dd7070Spatrick }
1872*12c85518Srobert [[fallthrough]];
1873e5dd7070Spatrick case Sema::NC_VarTemplate:
1874e5dd7070Spatrick case Sema::NC_FunctionTemplate:
1875e5dd7070Spatrick case Sema::NC_UndeclaredTemplate: {
1876e5dd7070Spatrick // We have a type, variable or function template followed by '<'.
1877e5dd7070Spatrick ConsumeToken();
1878e5dd7070Spatrick UnqualifiedId Id;
1879e5dd7070Spatrick Id.setIdentifier(Name, NameLoc);
1880e5dd7070Spatrick if (AnnotateTemplateIdToken(
1881e5dd7070Spatrick TemplateTy::make(Classification.getTemplateName()),
1882e5dd7070Spatrick Classification.getTemplateNameKind(), SS, SourceLocation(), Id))
1883e5dd7070Spatrick return ANK_Error;
1884e5dd7070Spatrick return ANK_Success;
1885e5dd7070Spatrick }
1886e5dd7070Spatrick case Sema::NC_Concept: {
1887e5dd7070Spatrick UnqualifiedId Id;
1888e5dd7070Spatrick Id.setIdentifier(Name, NameLoc);
1889e5dd7070Spatrick if (Next.is(tok::less))
1890e5dd7070Spatrick // We have a concept name followed by '<'. Consume the identifier token so
1891e5dd7070Spatrick // we reach the '<' and annotate it.
1892e5dd7070Spatrick ConsumeToken();
1893e5dd7070Spatrick if (AnnotateTemplateIdToken(
1894e5dd7070Spatrick TemplateTy::make(Classification.getTemplateName()),
1895e5dd7070Spatrick Classification.getTemplateNameKind(), SS, SourceLocation(), Id,
1896e5dd7070Spatrick /*AllowTypeAnnotation=*/false, /*TypeConstraint=*/true))
1897e5dd7070Spatrick return ANK_Error;
1898e5dd7070Spatrick return ANK_Success;
1899e5dd7070Spatrick }
1900e5dd7070Spatrick }
1901e5dd7070Spatrick
1902e5dd7070Spatrick // Unable to classify the name, but maybe we can annotate a scope specifier.
1903e5dd7070Spatrick if (SS.isNotEmpty())
1904e5dd7070Spatrick AnnotateScopeToken(SS, !WasScopeAnnotation);
1905e5dd7070Spatrick return ANK_Unresolved;
1906e5dd7070Spatrick }
1907e5dd7070Spatrick
TryKeywordIdentFallback(bool DisableKeyword)1908e5dd7070Spatrick bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
1909e5dd7070Spatrick assert(Tok.isNot(tok::identifier));
1910e5dd7070Spatrick Diag(Tok, diag::ext_keyword_as_ident)
1911e5dd7070Spatrick << PP.getSpelling(Tok)
1912e5dd7070Spatrick << DisableKeyword;
1913e5dd7070Spatrick if (DisableKeyword)
1914e5dd7070Spatrick Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
1915e5dd7070Spatrick Tok.setKind(tok::identifier);
1916e5dd7070Spatrick return true;
1917e5dd7070Spatrick }
1918e5dd7070Spatrick
1919e5dd7070Spatrick /// TryAnnotateTypeOrScopeToken - If the current token position is on a
1920e5dd7070Spatrick /// typename (possibly qualified in C++) or a C++ scope specifier not followed
1921e5dd7070Spatrick /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
1922e5dd7070Spatrick /// with a single annotation token representing the typename or C++ scope
1923e5dd7070Spatrick /// respectively.
1924e5dd7070Spatrick /// This simplifies handling of C++ scope specifiers and allows efficient
1925e5dd7070Spatrick /// backtracking without the need to re-parse and resolve nested-names and
1926e5dd7070Spatrick /// typenames.
1927e5dd7070Spatrick /// It will mainly be called when we expect to treat identifiers as typenames
1928e5dd7070Spatrick /// (if they are typenames). For example, in C we do not expect identifiers
1929e5dd7070Spatrick /// inside expressions to be treated as typenames so it will not be called
1930e5dd7070Spatrick /// for expressions in C.
1931e5dd7070Spatrick /// The benefit for C/ObjC is that a typename will be annotated and
1932e5dd7070Spatrick /// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
1933e5dd7070Spatrick /// will not be called twice, once to check whether we have a declaration
1934e5dd7070Spatrick /// specifier, and another one to get the actual type inside
1935e5dd7070Spatrick /// ParseDeclarationSpecifiers).
1936e5dd7070Spatrick ///
1937e5dd7070Spatrick /// This returns true if an error occurred.
1938e5dd7070Spatrick ///
1939e5dd7070Spatrick /// Note that this routine emits an error if you call it with ::new or ::delete
1940e5dd7070Spatrick /// as the current tokens, so only call it in contexts where these are invalid.
TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename)1941*12c85518Srobert bool Parser::TryAnnotateTypeOrScopeToken(
1942*12c85518Srobert ImplicitTypenameContext AllowImplicitTypename) {
1943e5dd7070Spatrick assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
1944e5dd7070Spatrick Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) ||
1945e5dd7070Spatrick Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) ||
1946e5dd7070Spatrick Tok.is(tok::kw___super)) &&
1947e5dd7070Spatrick "Cannot be a type or scope token!");
1948e5dd7070Spatrick
1949e5dd7070Spatrick if (Tok.is(tok::kw_typename)) {
1950e5dd7070Spatrick // MSVC lets you do stuff like:
1951e5dd7070Spatrick // typename typedef T_::D D;
1952e5dd7070Spatrick //
1953e5dd7070Spatrick // We will consume the typedef token here and put it back after we have
1954e5dd7070Spatrick // parsed the first identifier, transforming it into something more like:
1955e5dd7070Spatrick // typename T_::D typedef D;
1956e5dd7070Spatrick if (getLangOpts().MSVCCompat && NextToken().is(tok::kw_typedef)) {
1957e5dd7070Spatrick Token TypedefToken;
1958e5dd7070Spatrick PP.Lex(TypedefToken);
1959*12c85518Srobert bool Result = TryAnnotateTypeOrScopeToken(AllowImplicitTypename);
1960e5dd7070Spatrick PP.EnterToken(Tok, /*IsReinject=*/true);
1961e5dd7070Spatrick Tok = TypedefToken;
1962e5dd7070Spatrick if (!Result)
1963e5dd7070Spatrick Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename);
1964e5dd7070Spatrick return Result;
1965e5dd7070Spatrick }
1966e5dd7070Spatrick
1967e5dd7070Spatrick // Parse a C++ typename-specifier, e.g., "typename T::type".
1968e5dd7070Spatrick //
1969e5dd7070Spatrick // typename-specifier:
1970e5dd7070Spatrick // 'typename' '::' [opt] nested-name-specifier identifier
1971e5dd7070Spatrick // 'typename' '::' [opt] nested-name-specifier template [opt]
1972e5dd7070Spatrick // simple-template-id
1973e5dd7070Spatrick SourceLocation TypenameLoc = ConsumeToken();
1974e5dd7070Spatrick CXXScopeSpec SS;
1975e5dd7070Spatrick if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1976*12c85518Srobert /*ObjectHasErrors=*/false,
1977e5dd7070Spatrick /*EnteringContext=*/false, nullptr,
1978e5dd7070Spatrick /*IsTypename*/ true))
1979e5dd7070Spatrick return true;
1980e5dd7070Spatrick if (SS.isEmpty()) {
1981e5dd7070Spatrick if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||
1982e5dd7070Spatrick Tok.is(tok::annot_decltype)) {
1983e5dd7070Spatrick // Attempt to recover by skipping the invalid 'typename'
1984e5dd7070Spatrick if (Tok.is(tok::annot_decltype) ||
1985*12c85518Srobert (!TryAnnotateTypeOrScopeToken(AllowImplicitTypename) &&
1986*12c85518Srobert Tok.isAnnotation())) {
1987e5dd7070Spatrick unsigned DiagID = diag::err_expected_qualified_after_typename;
1988e5dd7070Spatrick // MS compatibility: MSVC permits using known types with typename.
1989e5dd7070Spatrick // e.g. "typedef typename T* pointer_type"
1990e5dd7070Spatrick if (getLangOpts().MicrosoftExt)
1991e5dd7070Spatrick DiagID = diag::warn_expected_qualified_after_typename;
1992e5dd7070Spatrick Diag(Tok.getLocation(), DiagID);
1993e5dd7070Spatrick return false;
1994e5dd7070Spatrick }
1995e5dd7070Spatrick }
1996e5dd7070Spatrick if (Tok.isEditorPlaceholder())
1997e5dd7070Spatrick return true;
1998e5dd7070Spatrick
1999e5dd7070Spatrick Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
2000e5dd7070Spatrick return true;
2001e5dd7070Spatrick }
2002e5dd7070Spatrick
2003e5dd7070Spatrick TypeResult Ty;
2004e5dd7070Spatrick if (Tok.is(tok::identifier)) {
2005e5dd7070Spatrick // FIXME: check whether the next token is '<', first!
2006e5dd7070Spatrick Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS,
2007e5dd7070Spatrick *Tok.getIdentifierInfo(),
2008e5dd7070Spatrick Tok.getLocation());
2009e5dd7070Spatrick } else if (Tok.is(tok::annot_template_id)) {
2010e5dd7070Spatrick TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2011ec727ea7Spatrick if (!TemplateId->mightBeType()) {
2012e5dd7070Spatrick Diag(Tok, diag::err_typename_refers_to_non_type_template)
2013e5dd7070Spatrick << Tok.getAnnotationRange();
2014e5dd7070Spatrick return true;
2015e5dd7070Spatrick }
2016e5dd7070Spatrick
2017e5dd7070Spatrick ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
2018e5dd7070Spatrick TemplateId->NumArgs);
2019e5dd7070Spatrick
2020ec727ea7Spatrick Ty = TemplateId->isInvalid()
2021ec727ea7Spatrick ? TypeError()
2022ec727ea7Spatrick : Actions.ActOnTypenameType(
2023ec727ea7Spatrick getCurScope(), TypenameLoc, SS, TemplateId->TemplateKWLoc,
2024ec727ea7Spatrick TemplateId->Template, TemplateId->Name,
2025ec727ea7Spatrick TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
2026ec727ea7Spatrick TemplateArgsPtr, TemplateId->RAngleLoc);
2027e5dd7070Spatrick } else {
2028e5dd7070Spatrick Diag(Tok, diag::err_expected_type_name_after_typename)
2029e5dd7070Spatrick << SS.getRange();
2030e5dd7070Spatrick return true;
2031e5dd7070Spatrick }
2032e5dd7070Spatrick
2033e5dd7070Spatrick SourceLocation EndLoc = Tok.getLastLoc();
2034e5dd7070Spatrick Tok.setKind(tok::annot_typename);
2035ec727ea7Spatrick setTypeAnnotation(Tok, Ty);
2036e5dd7070Spatrick Tok.setAnnotationEndLoc(EndLoc);
2037e5dd7070Spatrick Tok.setLocation(TypenameLoc);
2038e5dd7070Spatrick PP.AnnotateCachedTokens(Tok);
2039e5dd7070Spatrick return false;
2040e5dd7070Spatrick }
2041e5dd7070Spatrick
2042e5dd7070Spatrick // Remembers whether the token was originally a scope annotation.
2043e5dd7070Spatrick bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
2044e5dd7070Spatrick
2045e5dd7070Spatrick CXXScopeSpec SS;
2046e5dd7070Spatrick if (getLangOpts().CPlusPlus)
2047ec727ea7Spatrick if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2048*12c85518Srobert /*ObjectHasErrors=*/false,
2049ec727ea7Spatrick /*EnteringContext*/ false))
2050e5dd7070Spatrick return true;
2051e5dd7070Spatrick
2052*12c85518Srobert return TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation,
2053*12c85518Srobert AllowImplicitTypename);
2054e5dd7070Spatrick }
2055e5dd7070Spatrick
2056e5dd7070Spatrick /// Try to annotate a type or scope token, having already parsed an
2057e5dd7070Spatrick /// optional scope specifier. \p IsNewScope should be \c true unless the scope
2058e5dd7070Spatrick /// specifier was extracted from an existing tok::annot_cxxscope annotation.
TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec & SS,bool IsNewScope,ImplicitTypenameContext AllowImplicitTypename)2059*12c85518Srobert bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(
2060*12c85518Srobert CXXScopeSpec &SS, bool IsNewScope,
2061*12c85518Srobert ImplicitTypenameContext AllowImplicitTypename) {
2062e5dd7070Spatrick if (Tok.is(tok::identifier)) {
2063e5dd7070Spatrick // Determine whether the identifier is a type name.
2064e5dd7070Spatrick if (ParsedType Ty = Actions.getTypeName(
2065e5dd7070Spatrick *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS,
2066e5dd7070Spatrick false, NextToken().is(tok::period), nullptr,
2067e5dd7070Spatrick /*IsCtorOrDtorName=*/false,
2068*12c85518Srobert /*NonTrivialTypeSourceInfo=*/true,
2069*12c85518Srobert /*IsClassTemplateDeductionContext=*/true, AllowImplicitTypename)) {
2070e5dd7070Spatrick SourceLocation BeginLoc = Tok.getLocation();
2071e5dd7070Spatrick if (SS.isNotEmpty()) // it was a C++ qualified type name.
2072e5dd7070Spatrick BeginLoc = SS.getBeginLoc();
2073e5dd7070Spatrick
2074e5dd7070Spatrick /// An Objective-C object type followed by '<' is a specialization of
2075e5dd7070Spatrick /// a parameterized class type or a protocol-qualified type.
2076e5dd7070Spatrick if (getLangOpts().ObjC && NextToken().is(tok::less) &&
2077e5dd7070Spatrick (Ty.get()->isObjCObjectType() ||
2078e5dd7070Spatrick Ty.get()->isObjCObjectPointerType())) {
2079e5dd7070Spatrick // Consume the name.
2080e5dd7070Spatrick SourceLocation IdentifierLoc = ConsumeToken();
2081e5dd7070Spatrick SourceLocation NewEndLoc;
2082e5dd7070Spatrick TypeResult NewType
2083e5dd7070Spatrick = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty,
2084e5dd7070Spatrick /*consumeLastToken=*/false,
2085e5dd7070Spatrick NewEndLoc);
2086e5dd7070Spatrick if (NewType.isUsable())
2087e5dd7070Spatrick Ty = NewType.get();
2088e5dd7070Spatrick else if (Tok.is(tok::eof)) // Nothing to do here, bail out...
2089e5dd7070Spatrick return false;
2090e5dd7070Spatrick }
2091e5dd7070Spatrick
2092e5dd7070Spatrick // This is a typename. Replace the current token in-place with an
2093e5dd7070Spatrick // annotation type token.
2094e5dd7070Spatrick Tok.setKind(tok::annot_typename);
2095e5dd7070Spatrick setTypeAnnotation(Tok, Ty);
2096e5dd7070Spatrick Tok.setAnnotationEndLoc(Tok.getLocation());
2097e5dd7070Spatrick Tok.setLocation(BeginLoc);
2098e5dd7070Spatrick
2099e5dd7070Spatrick // In case the tokens were cached, have Preprocessor replace
2100e5dd7070Spatrick // them with the annotation token.
2101e5dd7070Spatrick PP.AnnotateCachedTokens(Tok);
2102e5dd7070Spatrick return false;
2103e5dd7070Spatrick }
2104e5dd7070Spatrick
2105e5dd7070Spatrick if (!getLangOpts().CPlusPlus) {
2106*12c85518Srobert // If we're in C, the only place we can have :: tokens is C2x
2107*12c85518Srobert // attribute which is parsed elsewhere. If the identifier is not a type,
2108*12c85518Srobert // then it can't be scope either, just early exit.
2109e5dd7070Spatrick return false;
2110e5dd7070Spatrick }
2111e5dd7070Spatrick
2112e5dd7070Spatrick // If this is a template-id, annotate with a template-id or type token.
2113e5dd7070Spatrick // FIXME: This appears to be dead code. We already have formed template-id
2114e5dd7070Spatrick // tokens when parsing the scope specifier; this can never form a new one.
2115e5dd7070Spatrick if (NextToken().is(tok::less)) {
2116e5dd7070Spatrick TemplateTy Template;
2117e5dd7070Spatrick UnqualifiedId TemplateName;
2118e5dd7070Spatrick TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
2119e5dd7070Spatrick bool MemberOfUnknownSpecialization;
2120e5dd7070Spatrick if (TemplateNameKind TNK = Actions.isTemplateName(
2121e5dd7070Spatrick getCurScope(), SS,
2122e5dd7070Spatrick /*hasTemplateKeyword=*/false, TemplateName,
2123e5dd7070Spatrick /*ObjectType=*/nullptr, /*EnteringContext*/false, Template,
2124e5dd7070Spatrick MemberOfUnknownSpecialization)) {
2125e5dd7070Spatrick // Only annotate an undeclared template name as a template-id if the
2126e5dd7070Spatrick // following tokens have the form of a template argument list.
2127e5dd7070Spatrick if (TNK != TNK_Undeclared_template ||
2128e5dd7070Spatrick isTemplateArgumentList(1) != TPResult::False) {
2129e5dd7070Spatrick // Consume the identifier.
2130e5dd7070Spatrick ConsumeToken();
2131e5dd7070Spatrick if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),
2132e5dd7070Spatrick TemplateName)) {
2133e5dd7070Spatrick // If an unrecoverable error occurred, we need to return true here,
2134e5dd7070Spatrick // because the token stream is in a damaged state. We may not
2135e5dd7070Spatrick // return a valid identifier.
2136e5dd7070Spatrick return true;
2137e5dd7070Spatrick }
2138e5dd7070Spatrick }
2139e5dd7070Spatrick }
2140e5dd7070Spatrick }
2141e5dd7070Spatrick
2142e5dd7070Spatrick // The current token, which is either an identifier or a
2143e5dd7070Spatrick // template-id, is not part of the annotation. Fall through to
2144e5dd7070Spatrick // push that token back into the stream and complete the C++ scope
2145e5dd7070Spatrick // specifier annotation.
2146e5dd7070Spatrick }
2147e5dd7070Spatrick
2148e5dd7070Spatrick if (Tok.is(tok::annot_template_id)) {
2149e5dd7070Spatrick TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
2150e5dd7070Spatrick if (TemplateId->Kind == TNK_Type_template) {
2151e5dd7070Spatrick // A template-id that refers to a type was parsed into a
2152e5dd7070Spatrick // template-id annotation in a context where we weren't allowed
2153e5dd7070Spatrick // to produce a type annotation token. Update the template-id
2154e5dd7070Spatrick // annotation token to a type annotation token now.
2155*12c85518Srobert AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
2156e5dd7070Spatrick return false;
2157e5dd7070Spatrick }
2158e5dd7070Spatrick }
2159e5dd7070Spatrick
2160e5dd7070Spatrick if (SS.isEmpty())
2161e5dd7070Spatrick return false;
2162e5dd7070Spatrick
2163e5dd7070Spatrick // A C++ scope specifier that isn't followed by a typename.
2164e5dd7070Spatrick AnnotateScopeToken(SS, IsNewScope);
2165e5dd7070Spatrick return false;
2166e5dd7070Spatrick }
2167e5dd7070Spatrick
2168e5dd7070Spatrick /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
2169e5dd7070Spatrick /// annotates C++ scope specifiers and template-ids. This returns
2170e5dd7070Spatrick /// true if there was an error that could not be recovered from.
2171e5dd7070Spatrick ///
2172e5dd7070Spatrick /// Note that this routine emits an error if you call it with ::new or ::delete
2173e5dd7070Spatrick /// as the current tokens, so only call it in contexts where these are invalid.
TryAnnotateCXXScopeToken(bool EnteringContext)2174e5dd7070Spatrick bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
2175e5dd7070Spatrick assert(getLangOpts().CPlusPlus &&
2176e5dd7070Spatrick "Call sites of this function should be guarded by checking for C++");
2177e5dd7070Spatrick assert(MightBeCXXScopeToken() && "Cannot be a type or scope token!");
2178e5dd7070Spatrick
2179e5dd7070Spatrick CXXScopeSpec SS;
2180ec727ea7Spatrick if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2181*12c85518Srobert /*ObjectHasErrors=*/false,
2182ec727ea7Spatrick EnteringContext))
2183e5dd7070Spatrick return true;
2184e5dd7070Spatrick if (SS.isEmpty())
2185e5dd7070Spatrick return false;
2186e5dd7070Spatrick
2187e5dd7070Spatrick AnnotateScopeToken(SS, true);
2188e5dd7070Spatrick return false;
2189e5dd7070Spatrick }
2190e5dd7070Spatrick
isTokenEqualOrEqualTypo()2191e5dd7070Spatrick bool Parser::isTokenEqualOrEqualTypo() {
2192e5dd7070Spatrick tok::TokenKind Kind = Tok.getKind();
2193e5dd7070Spatrick switch (Kind) {
2194e5dd7070Spatrick default:
2195e5dd7070Spatrick return false;
2196e5dd7070Spatrick case tok::ampequal: // &=
2197e5dd7070Spatrick case tok::starequal: // *=
2198e5dd7070Spatrick case tok::plusequal: // +=
2199e5dd7070Spatrick case tok::minusequal: // -=
2200e5dd7070Spatrick case tok::exclaimequal: // !=
2201e5dd7070Spatrick case tok::slashequal: // /=
2202e5dd7070Spatrick case tok::percentequal: // %=
2203e5dd7070Spatrick case tok::lessequal: // <=
2204e5dd7070Spatrick case tok::lesslessequal: // <<=
2205e5dd7070Spatrick case tok::greaterequal: // >=
2206e5dd7070Spatrick case tok::greatergreaterequal: // >>=
2207e5dd7070Spatrick case tok::caretequal: // ^=
2208e5dd7070Spatrick case tok::pipeequal: // |=
2209e5dd7070Spatrick case tok::equalequal: // ==
2210e5dd7070Spatrick Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)
2211e5dd7070Spatrick << Kind
2212e5dd7070Spatrick << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "=");
2213*12c85518Srobert [[fallthrough]];
2214e5dd7070Spatrick case tok::equal:
2215e5dd7070Spatrick return true;
2216e5dd7070Spatrick }
2217e5dd7070Spatrick }
2218e5dd7070Spatrick
handleUnexpectedCodeCompletionToken()2219e5dd7070Spatrick SourceLocation Parser::handleUnexpectedCodeCompletionToken() {
2220e5dd7070Spatrick assert(Tok.is(tok::code_completion));
2221e5dd7070Spatrick PrevTokLocation = Tok.getLocation();
2222e5dd7070Spatrick
2223e5dd7070Spatrick for (Scope *S = getCurScope(); S; S = S->getParent()) {
2224*12c85518Srobert if (S->isFunctionScope()) {
2225a9ac8606Spatrick cutOffParsing();
2226e5dd7070Spatrick Actions.CodeCompleteOrdinaryName(getCurScope(),
2227e5dd7070Spatrick Sema::PCC_RecoveryInFunction);
2228e5dd7070Spatrick return PrevTokLocation;
2229e5dd7070Spatrick }
2230e5dd7070Spatrick
2231*12c85518Srobert if (S->isClassScope()) {
2232e5dd7070Spatrick cutOffParsing();
2233a9ac8606Spatrick Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class);
2234e5dd7070Spatrick return PrevTokLocation;
2235e5dd7070Spatrick }
2236e5dd7070Spatrick }
2237e5dd7070Spatrick
2238e5dd7070Spatrick cutOffParsing();
2239a9ac8606Spatrick Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace);
2240e5dd7070Spatrick return PrevTokLocation;
2241e5dd7070Spatrick }
2242e5dd7070Spatrick
2243e5dd7070Spatrick // Code-completion pass-through functions
2244e5dd7070Spatrick
CodeCompleteDirective(bool InConditional)2245e5dd7070Spatrick void Parser::CodeCompleteDirective(bool InConditional) {
2246e5dd7070Spatrick Actions.CodeCompletePreprocessorDirective(InConditional);
2247e5dd7070Spatrick }
2248e5dd7070Spatrick
CodeCompleteInConditionalExclusion()2249e5dd7070Spatrick void Parser::CodeCompleteInConditionalExclusion() {
2250e5dd7070Spatrick Actions.CodeCompleteInPreprocessorConditionalExclusion(getCurScope());
2251e5dd7070Spatrick }
2252e5dd7070Spatrick
CodeCompleteMacroName(bool IsDefinition)2253e5dd7070Spatrick void Parser::CodeCompleteMacroName(bool IsDefinition) {
2254e5dd7070Spatrick Actions.CodeCompletePreprocessorMacroName(IsDefinition);
2255e5dd7070Spatrick }
2256e5dd7070Spatrick
CodeCompletePreprocessorExpression()2257e5dd7070Spatrick void Parser::CodeCompletePreprocessorExpression() {
2258e5dd7070Spatrick Actions.CodeCompletePreprocessorExpression();
2259e5dd7070Spatrick }
2260e5dd7070Spatrick
CodeCompleteMacroArgument(IdentifierInfo * Macro,MacroInfo * MacroInfo,unsigned ArgumentIndex)2261e5dd7070Spatrick void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro,
2262e5dd7070Spatrick MacroInfo *MacroInfo,
2263e5dd7070Spatrick unsigned ArgumentIndex) {
2264e5dd7070Spatrick Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo,
2265e5dd7070Spatrick ArgumentIndex);
2266e5dd7070Spatrick }
2267e5dd7070Spatrick
CodeCompleteIncludedFile(llvm::StringRef Dir,bool IsAngled)2268e5dd7070Spatrick void Parser::CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) {
2269e5dd7070Spatrick Actions.CodeCompleteIncludedFile(Dir, IsAngled);
2270e5dd7070Spatrick }
2271e5dd7070Spatrick
CodeCompleteNaturalLanguage()2272e5dd7070Spatrick void Parser::CodeCompleteNaturalLanguage() {
2273e5dd7070Spatrick Actions.CodeCompleteNaturalLanguage();
2274e5dd7070Spatrick }
2275e5dd7070Spatrick
ParseMicrosoftIfExistsCondition(IfExistsCondition & Result)2276e5dd7070Spatrick bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) {
2277e5dd7070Spatrick assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) &&
2278e5dd7070Spatrick "Expected '__if_exists' or '__if_not_exists'");
2279e5dd7070Spatrick Result.IsIfExists = Tok.is(tok::kw___if_exists);
2280e5dd7070Spatrick Result.KeywordLoc = ConsumeToken();
2281e5dd7070Spatrick
2282e5dd7070Spatrick BalancedDelimiterTracker T(*this, tok::l_paren);
2283e5dd7070Spatrick if (T.consumeOpen()) {
2284e5dd7070Spatrick Diag(Tok, diag::err_expected_lparen_after)
2285e5dd7070Spatrick << (Result.IsIfExists? "__if_exists" : "__if_not_exists");
2286e5dd7070Spatrick return true;
2287e5dd7070Spatrick }
2288e5dd7070Spatrick
2289e5dd7070Spatrick // Parse nested-name-specifier.
2290e5dd7070Spatrick if (getLangOpts().CPlusPlus)
2291ec727ea7Spatrick ParseOptionalCXXScopeSpecifier(Result.SS, /*ObjectType=*/nullptr,
2292*12c85518Srobert /*ObjectHasErrors=*/false,
2293e5dd7070Spatrick /*EnteringContext=*/false);
2294e5dd7070Spatrick
2295e5dd7070Spatrick // Check nested-name specifier.
2296e5dd7070Spatrick if (Result.SS.isInvalid()) {
2297e5dd7070Spatrick T.skipToEnd();
2298e5dd7070Spatrick return true;
2299e5dd7070Spatrick }
2300e5dd7070Spatrick
2301e5dd7070Spatrick // Parse the unqualified-id.
2302e5dd7070Spatrick SourceLocation TemplateKWLoc; // FIXME: parsed, but unused.
2303ec727ea7Spatrick if (ParseUnqualifiedId(Result.SS, /*ObjectType=*/nullptr,
2304ec727ea7Spatrick /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
2305ec727ea7Spatrick /*AllowDestructorName*/ true,
2306ec727ea7Spatrick /*AllowConstructorName*/ true,
2307ec727ea7Spatrick /*AllowDeductionGuide*/ false, &TemplateKWLoc,
2308ec727ea7Spatrick Result.Name)) {
2309e5dd7070Spatrick T.skipToEnd();
2310e5dd7070Spatrick return true;
2311e5dd7070Spatrick }
2312e5dd7070Spatrick
2313e5dd7070Spatrick if (T.consumeClose())
2314e5dd7070Spatrick return true;
2315e5dd7070Spatrick
2316e5dd7070Spatrick // Check if the symbol exists.
2317e5dd7070Spatrick switch (Actions.CheckMicrosoftIfExistsSymbol(getCurScope(), Result.KeywordLoc,
2318e5dd7070Spatrick Result.IsIfExists, Result.SS,
2319e5dd7070Spatrick Result.Name)) {
2320e5dd7070Spatrick case Sema::IER_Exists:
2321e5dd7070Spatrick Result.Behavior = Result.IsIfExists ? IEB_Parse : IEB_Skip;
2322e5dd7070Spatrick break;
2323e5dd7070Spatrick
2324e5dd7070Spatrick case Sema::IER_DoesNotExist:
2325e5dd7070Spatrick Result.Behavior = !Result.IsIfExists ? IEB_Parse : IEB_Skip;
2326e5dd7070Spatrick break;
2327e5dd7070Spatrick
2328e5dd7070Spatrick case Sema::IER_Dependent:
2329e5dd7070Spatrick Result.Behavior = IEB_Dependent;
2330e5dd7070Spatrick break;
2331e5dd7070Spatrick
2332e5dd7070Spatrick case Sema::IER_Error:
2333e5dd7070Spatrick return true;
2334e5dd7070Spatrick }
2335e5dd7070Spatrick
2336e5dd7070Spatrick return false;
2337e5dd7070Spatrick }
2338e5dd7070Spatrick
ParseMicrosoftIfExistsExternalDeclaration()2339e5dd7070Spatrick void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
2340e5dd7070Spatrick IfExistsCondition Result;
2341e5dd7070Spatrick if (ParseMicrosoftIfExistsCondition(Result))
2342e5dd7070Spatrick return;
2343e5dd7070Spatrick
2344e5dd7070Spatrick BalancedDelimiterTracker Braces(*this, tok::l_brace);
2345e5dd7070Spatrick if (Braces.consumeOpen()) {
2346e5dd7070Spatrick Diag(Tok, diag::err_expected) << tok::l_brace;
2347e5dd7070Spatrick return;
2348e5dd7070Spatrick }
2349e5dd7070Spatrick
2350e5dd7070Spatrick switch (Result.Behavior) {
2351e5dd7070Spatrick case IEB_Parse:
2352e5dd7070Spatrick // Parse declarations below.
2353e5dd7070Spatrick break;
2354e5dd7070Spatrick
2355e5dd7070Spatrick case IEB_Dependent:
2356e5dd7070Spatrick llvm_unreachable("Cannot have a dependent external declaration");
2357e5dd7070Spatrick
2358e5dd7070Spatrick case IEB_Skip:
2359e5dd7070Spatrick Braces.skipToEnd();
2360e5dd7070Spatrick return;
2361e5dd7070Spatrick }
2362e5dd7070Spatrick
2363e5dd7070Spatrick // Parse the declarations.
2364e5dd7070Spatrick // FIXME: Support module import within __if_exists?
2365e5dd7070Spatrick while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2366*12c85518Srobert ParsedAttributes Attrs(AttrFactory);
2367*12c85518Srobert MaybeParseCXX11Attributes(Attrs);
2368*12c85518Srobert ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
2369*12c85518Srobert DeclGroupPtrTy Result = ParseExternalDeclaration(Attrs, EmptyDeclSpecAttrs);
2370e5dd7070Spatrick if (Result && !getCurScope()->getParent())
2371e5dd7070Spatrick Actions.getASTConsumer().HandleTopLevelDecl(Result.get());
2372e5dd7070Spatrick }
2373e5dd7070Spatrick Braces.consumeClose();
2374e5dd7070Spatrick }
2375e5dd7070Spatrick
2376e5dd7070Spatrick /// Parse a declaration beginning with the 'module' keyword or C++20
2377e5dd7070Spatrick /// context-sensitive keyword (optionally preceded by 'export').
2378e5dd7070Spatrick ///
2379e5dd7070Spatrick /// module-declaration: [Modules TS + P0629R0]
2380e5dd7070Spatrick /// 'export'[opt] 'module' module-name attribute-specifier-seq[opt] ';'
2381e5dd7070Spatrick ///
2382e5dd7070Spatrick /// global-module-fragment: [C++2a]
2383e5dd7070Spatrick /// 'module' ';' top-level-declaration-seq[opt]
2384e5dd7070Spatrick /// module-declaration: [C++2a]
2385e5dd7070Spatrick /// 'export'[opt] 'module' module-name module-partition[opt]
2386e5dd7070Spatrick /// attribute-specifier-seq[opt] ';'
2387e5dd7070Spatrick /// private-module-fragment: [C++2a]
2388e5dd7070Spatrick /// 'module' ':' 'private' ';' top-level-declaration-seq[opt]
2389*12c85518Srobert Parser::DeclGroupPtrTy
ParseModuleDecl(Sema::ModuleImportState & ImportState)2390*12c85518Srobert Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
2391e5dd7070Spatrick SourceLocation StartLoc = Tok.getLocation();
2392e5dd7070Spatrick
2393e5dd7070Spatrick Sema::ModuleDeclKind MDK = TryConsumeToken(tok::kw_export)
2394e5dd7070Spatrick ? Sema::ModuleDeclKind::Interface
2395e5dd7070Spatrick : Sema::ModuleDeclKind::Implementation;
2396e5dd7070Spatrick
2397e5dd7070Spatrick assert(
2398e5dd7070Spatrick (Tok.is(tok::kw_module) ||
2399e5dd7070Spatrick (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_module)) &&
2400e5dd7070Spatrick "not a module declaration");
2401e5dd7070Spatrick SourceLocation ModuleLoc = ConsumeToken();
2402e5dd7070Spatrick
2403e5dd7070Spatrick // Attributes appear after the module name, not before.
2404e5dd7070Spatrick // FIXME: Suggest moving the attributes later with a fixit.
2405e5dd7070Spatrick DiagnoseAndSkipCXX11Attributes();
2406e5dd7070Spatrick
2407e5dd7070Spatrick // Parse a global-module-fragment, if present.
2408e5dd7070Spatrick if (getLangOpts().CPlusPlusModules && Tok.is(tok::semi)) {
2409e5dd7070Spatrick SourceLocation SemiLoc = ConsumeToken();
2410*12c85518Srobert if (ImportState != Sema::ModuleImportState::FirstDecl) {
2411e5dd7070Spatrick Diag(StartLoc, diag::err_global_module_introducer_not_at_start)
2412e5dd7070Spatrick << SourceRange(StartLoc, SemiLoc);
2413e5dd7070Spatrick return nullptr;
2414e5dd7070Spatrick }
2415e5dd7070Spatrick if (MDK == Sema::ModuleDeclKind::Interface) {
2416e5dd7070Spatrick Diag(StartLoc, diag::err_module_fragment_exported)
2417e5dd7070Spatrick << /*global*/0 << FixItHint::CreateRemoval(StartLoc);
2418e5dd7070Spatrick }
2419*12c85518Srobert ImportState = Sema::ModuleImportState::GlobalFragment;
2420e5dd7070Spatrick return Actions.ActOnGlobalModuleFragmentDecl(ModuleLoc);
2421e5dd7070Spatrick }
2422e5dd7070Spatrick
2423e5dd7070Spatrick // Parse a private-module-fragment, if present.
2424e5dd7070Spatrick if (getLangOpts().CPlusPlusModules && Tok.is(tok::colon) &&
2425e5dd7070Spatrick NextToken().is(tok::kw_private)) {
2426e5dd7070Spatrick if (MDK == Sema::ModuleDeclKind::Interface) {
2427e5dd7070Spatrick Diag(StartLoc, diag::err_module_fragment_exported)
2428e5dd7070Spatrick << /*private*/1 << FixItHint::CreateRemoval(StartLoc);
2429e5dd7070Spatrick }
2430e5dd7070Spatrick ConsumeToken();
2431e5dd7070Spatrick SourceLocation PrivateLoc = ConsumeToken();
2432e5dd7070Spatrick DiagnoseAndSkipCXX11Attributes();
2433e5dd7070Spatrick ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);
2434*12c85518Srobert ImportState = ImportState == Sema::ModuleImportState::ImportAllowed
2435*12c85518Srobert ? Sema::ModuleImportState::PrivateFragmentImportAllowed
2436*12c85518Srobert : Sema::ModuleImportState::PrivateFragmentImportFinished;
2437e5dd7070Spatrick return Actions.ActOnPrivateModuleFragmentDecl(ModuleLoc, PrivateLoc);
2438e5dd7070Spatrick }
2439e5dd7070Spatrick
2440e5dd7070Spatrick SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
2441e5dd7070Spatrick if (ParseModuleName(ModuleLoc, Path, /*IsImport*/ false))
2442e5dd7070Spatrick return nullptr;
2443e5dd7070Spatrick
2444e5dd7070Spatrick // Parse the optional module-partition.
2445*12c85518Srobert SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Partition;
2446e5dd7070Spatrick if (Tok.is(tok::colon)) {
2447e5dd7070Spatrick SourceLocation ColonLoc = ConsumeToken();
2448*12c85518Srobert if (!getLangOpts().CPlusPlusModules)
2449e5dd7070Spatrick Diag(ColonLoc, diag::err_unsupported_module_partition)
2450e5dd7070Spatrick << SourceRange(ColonLoc, Partition.back().second);
2451*12c85518Srobert // Recover by ignoring the partition name.
2452*12c85518Srobert else if (ParseModuleName(ModuleLoc, Partition, /*IsImport*/ false))
2453*12c85518Srobert return nullptr;
2454e5dd7070Spatrick }
2455e5dd7070Spatrick
2456e5dd7070Spatrick // We don't support any module attributes yet; just parse them and diagnose.
2457*12c85518Srobert ParsedAttributes Attrs(AttrFactory);
2458e5dd7070Spatrick MaybeParseCXX11Attributes(Attrs);
2459*12c85518Srobert ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr,
2460*12c85518Srobert /*DiagnoseEmptyAttrs=*/false,
2461*12c85518Srobert /*WarnOnUnknownAttrs=*/true);
2462e5dd7070Spatrick
2463e5dd7070Spatrick ExpectAndConsumeSemi(diag::err_module_expected_semi);
2464e5dd7070Spatrick
2465*12c85518Srobert return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, Partition,
2466*12c85518Srobert ImportState);
2467e5dd7070Spatrick }
2468e5dd7070Spatrick
2469e5dd7070Spatrick /// Parse a module import declaration. This is essentially the same for
2470*12c85518Srobert /// Objective-C and C++20 except for the leading '@' (in ObjC) and the
2471*12c85518Srobert /// trailing optional attributes (in C++).
2472e5dd7070Spatrick ///
2473e5dd7070Spatrick /// [ObjC] @import declaration:
2474e5dd7070Spatrick /// '@' 'import' module-name ';'
2475e5dd7070Spatrick /// [ModTS] module-import-declaration:
2476e5dd7070Spatrick /// 'import' module-name attribute-specifier-seq[opt] ';'
2477*12c85518Srobert /// [C++20] module-import-declaration:
2478e5dd7070Spatrick /// 'export'[opt] 'import' module-name
2479e5dd7070Spatrick /// attribute-specifier-seq[opt] ';'
2480e5dd7070Spatrick /// 'export'[opt] 'import' module-partition
2481e5dd7070Spatrick /// attribute-specifier-seq[opt] ';'
2482e5dd7070Spatrick /// 'export'[opt] 'import' header-name
2483e5dd7070Spatrick /// attribute-specifier-seq[opt] ';'
ParseModuleImport(SourceLocation AtLoc,Sema::ModuleImportState & ImportState)2484*12c85518Srobert Decl *Parser::ParseModuleImport(SourceLocation AtLoc,
2485*12c85518Srobert Sema::ModuleImportState &ImportState) {
2486e5dd7070Spatrick SourceLocation StartLoc = AtLoc.isInvalid() ? Tok.getLocation() : AtLoc;
2487e5dd7070Spatrick
2488e5dd7070Spatrick SourceLocation ExportLoc;
2489e5dd7070Spatrick TryConsumeToken(tok::kw_export, ExportLoc);
2490e5dd7070Spatrick
2491e5dd7070Spatrick assert((AtLoc.isInvalid() ? Tok.isOneOf(tok::kw_import, tok::identifier)
2492e5dd7070Spatrick : Tok.isObjCAtKeyword(tok::objc_import)) &&
2493e5dd7070Spatrick "Improper start to module import");
2494e5dd7070Spatrick bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import);
2495e5dd7070Spatrick SourceLocation ImportLoc = ConsumeToken();
2496e5dd7070Spatrick
2497*12c85518Srobert // For C++20 modules, we can have "name" or ":Partition name" as valid input.
2498e5dd7070Spatrick SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
2499*12c85518Srobert bool IsPartition = false;
2500e5dd7070Spatrick Module *HeaderUnit = nullptr;
2501e5dd7070Spatrick if (Tok.is(tok::header_name)) {
2502e5dd7070Spatrick // This is a header import that the preprocessor decided we should skip
2503e5dd7070Spatrick // because it was malformed in some way. Parse and ignore it; it's already
2504e5dd7070Spatrick // been diagnosed.
2505e5dd7070Spatrick ConsumeToken();
2506e5dd7070Spatrick } else if (Tok.is(tok::annot_header_unit)) {
2507e5dd7070Spatrick // This is a header import that the preprocessor mapped to a module import.
2508e5dd7070Spatrick HeaderUnit = reinterpret_cast<Module *>(Tok.getAnnotationValue());
2509e5dd7070Spatrick ConsumeAnnotationToken();
2510*12c85518Srobert } else if (Tok.is(tok::colon)) {
2511e5dd7070Spatrick SourceLocation ColonLoc = ConsumeToken();
2512*12c85518Srobert if (!getLangOpts().CPlusPlusModules)
2513e5dd7070Spatrick Diag(ColonLoc, diag::err_unsupported_module_partition)
2514e5dd7070Spatrick << SourceRange(ColonLoc, Path.back().second);
2515*12c85518Srobert // Recover by leaving partition empty.
2516*12c85518Srobert else if (ParseModuleName(ColonLoc, Path, /*IsImport*/ true))
2517e5dd7070Spatrick return nullptr;
2518*12c85518Srobert else
2519*12c85518Srobert IsPartition = true;
2520e5dd7070Spatrick } else {
2521e5dd7070Spatrick if (ParseModuleName(ImportLoc, Path, /*IsImport*/ true))
2522e5dd7070Spatrick return nullptr;
2523e5dd7070Spatrick }
2524e5dd7070Spatrick
2525*12c85518Srobert ParsedAttributes Attrs(AttrFactory);
2526e5dd7070Spatrick MaybeParseCXX11Attributes(Attrs);
2527e5dd7070Spatrick // We don't support any module import attributes yet.
2528*12c85518Srobert ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr,
2529*12c85518Srobert /*DiagnoseEmptyAttrs=*/false,
2530*12c85518Srobert /*WarnOnUnknownAttrs=*/true);
2531e5dd7070Spatrick
2532e5dd7070Spatrick if (PP.hadModuleLoaderFatalFailure()) {
2533e5dd7070Spatrick // With a fatal failure in the module loader, we abort parsing.
2534e5dd7070Spatrick cutOffParsing();
2535e5dd7070Spatrick return nullptr;
2536e5dd7070Spatrick }
2537e5dd7070Spatrick
2538*12c85518Srobert // Diagnose mis-imports.
2539*12c85518Srobert bool SeenError = true;
2540*12c85518Srobert switch (ImportState) {
2541*12c85518Srobert case Sema::ModuleImportState::ImportAllowed:
2542*12c85518Srobert SeenError = false;
2543*12c85518Srobert break;
2544*12c85518Srobert case Sema::ModuleImportState::FirstDecl:
2545*12c85518Srobert case Sema::ModuleImportState::NotACXX20Module:
2546*12c85518Srobert // We can only import a partition within a module purview.
2547*12c85518Srobert if (IsPartition)
2548*12c85518Srobert Diag(ImportLoc, diag::err_partition_import_outside_module);
2549*12c85518Srobert else
2550*12c85518Srobert SeenError = false;
2551*12c85518Srobert break;
2552*12c85518Srobert case Sema::ModuleImportState::GlobalFragment:
2553*12c85518Srobert case Sema::ModuleImportState::PrivateFragmentImportAllowed:
2554*12c85518Srobert // We can only have pre-processor directives in the global module fragment
2555*12c85518Srobert // which allows pp-import, but not of a partition (since the global module
2556*12c85518Srobert // does not have partitions).
2557*12c85518Srobert // We cannot import a partition into a private module fragment, since
2558*12c85518Srobert // [module.private.frag]/1 disallows private module fragments in a multi-
2559*12c85518Srobert // TU module.
2560*12c85518Srobert if (IsPartition || (HeaderUnit && HeaderUnit->Kind !=
2561*12c85518Srobert Module::ModuleKind::ModuleHeaderUnit))
2562*12c85518Srobert Diag(ImportLoc, diag::err_import_in_wrong_fragment)
2563*12c85518Srobert << IsPartition
2564*12c85518Srobert << (ImportState == Sema::ModuleImportState::GlobalFragment ? 0 : 1);
2565*12c85518Srobert else
2566*12c85518Srobert SeenError = false;
2567*12c85518Srobert break;
2568*12c85518Srobert case Sema::ModuleImportState::ImportFinished:
2569*12c85518Srobert case Sema::ModuleImportState::PrivateFragmentImportFinished:
2570*12c85518Srobert if (getLangOpts().CPlusPlusModules)
2571*12c85518Srobert Diag(ImportLoc, diag::err_import_not_allowed_here);
2572*12c85518Srobert else
2573*12c85518Srobert SeenError = false;
2574*12c85518Srobert break;
2575*12c85518Srobert }
2576*12c85518Srobert if (SeenError) {
2577*12c85518Srobert ExpectAndConsumeSemi(diag::err_module_expected_semi);
2578*12c85518Srobert return nullptr;
2579*12c85518Srobert }
2580*12c85518Srobert
2581e5dd7070Spatrick DeclResult Import;
2582e5dd7070Spatrick if (HeaderUnit)
2583e5dd7070Spatrick Import =
2584e5dd7070Spatrick Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, HeaderUnit);
2585e5dd7070Spatrick else if (!Path.empty())
2586*12c85518Srobert Import = Actions.ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Path,
2587*12c85518Srobert IsPartition);
2588e5dd7070Spatrick ExpectAndConsumeSemi(diag::err_module_expected_semi);
2589e5dd7070Spatrick if (Import.isInvalid())
2590e5dd7070Spatrick return nullptr;
2591e5dd7070Spatrick
2592e5dd7070Spatrick // Using '@import' in framework headers requires modules to be enabled so that
2593e5dd7070Spatrick // the header is parseable. Emit a warning to make the user aware.
2594e5dd7070Spatrick if (IsObjCAtImport && AtLoc.isValid()) {
2595e5dd7070Spatrick auto &SrcMgr = PP.getSourceManager();
2596*12c85518Srobert auto FE = SrcMgr.getFileEntryRefForID(SrcMgr.getFileID(AtLoc));
2597*12c85518Srobert if (FE && llvm::sys::path::parent_path(FE->getDir().getName())
2598e5dd7070Spatrick .endswith(".framework"))
2599e5dd7070Spatrick Diags.Report(AtLoc, diag::warn_atimport_in_framework_header);
2600e5dd7070Spatrick }
2601e5dd7070Spatrick
2602e5dd7070Spatrick return Import.get();
2603e5dd7070Spatrick }
2604e5dd7070Spatrick
2605e5dd7070Spatrick /// Parse a C++ Modules TS / Objective-C module name (both forms use the same
2606e5dd7070Spatrick /// grammar).
2607e5dd7070Spatrick ///
2608e5dd7070Spatrick /// module-name:
2609e5dd7070Spatrick /// module-name-qualifier[opt] identifier
2610e5dd7070Spatrick /// module-name-qualifier:
2611e5dd7070Spatrick /// module-name-qualifier[opt] identifier '.'
ParseModuleName(SourceLocation UseLoc,SmallVectorImpl<std::pair<IdentifierInfo *,SourceLocation>> & Path,bool IsImport)2612e5dd7070Spatrick bool Parser::ParseModuleName(
2613e5dd7070Spatrick SourceLocation UseLoc,
2614e5dd7070Spatrick SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path,
2615e5dd7070Spatrick bool IsImport) {
2616e5dd7070Spatrick // Parse the module path.
2617e5dd7070Spatrick while (true) {
2618e5dd7070Spatrick if (!Tok.is(tok::identifier)) {
2619e5dd7070Spatrick if (Tok.is(tok::code_completion)) {
2620e5dd7070Spatrick cutOffParsing();
2621a9ac8606Spatrick Actions.CodeCompleteModuleImport(UseLoc, Path);
2622e5dd7070Spatrick return true;
2623e5dd7070Spatrick }
2624e5dd7070Spatrick
2625e5dd7070Spatrick Diag(Tok, diag::err_module_expected_ident) << IsImport;
2626e5dd7070Spatrick SkipUntil(tok::semi);
2627e5dd7070Spatrick return true;
2628e5dd7070Spatrick }
2629e5dd7070Spatrick
2630e5dd7070Spatrick // Record this part of the module path.
2631e5dd7070Spatrick Path.push_back(std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation()));
2632e5dd7070Spatrick ConsumeToken();
2633e5dd7070Spatrick
2634e5dd7070Spatrick if (Tok.isNot(tok::period))
2635e5dd7070Spatrick return false;
2636e5dd7070Spatrick
2637e5dd7070Spatrick ConsumeToken();
2638e5dd7070Spatrick }
2639e5dd7070Spatrick }
2640e5dd7070Spatrick
2641e5dd7070Spatrick /// Try recover parser when module annotation appears where it must not
2642e5dd7070Spatrick /// be found.
2643e5dd7070Spatrick /// \returns false if the recover was successful and parsing may be continued, or
2644e5dd7070Spatrick /// true if parser must bail out to top level and handle the token there.
parseMisplacedModuleImport()2645e5dd7070Spatrick bool Parser::parseMisplacedModuleImport() {
2646e5dd7070Spatrick while (true) {
2647e5dd7070Spatrick switch (Tok.getKind()) {
2648e5dd7070Spatrick case tok::annot_module_end:
2649e5dd7070Spatrick // If we recovered from a misplaced module begin, we expect to hit a
2650e5dd7070Spatrick // misplaced module end too. Stay in the current context when this
2651e5dd7070Spatrick // happens.
2652e5dd7070Spatrick if (MisplacedModuleBeginCount) {
2653e5dd7070Spatrick --MisplacedModuleBeginCount;
2654e5dd7070Spatrick Actions.ActOnModuleEnd(Tok.getLocation(),
2655e5dd7070Spatrick reinterpret_cast<Module *>(
2656e5dd7070Spatrick Tok.getAnnotationValue()));
2657e5dd7070Spatrick ConsumeAnnotationToken();
2658e5dd7070Spatrick continue;
2659e5dd7070Spatrick }
2660e5dd7070Spatrick // Inform caller that recovery failed, the error must be handled at upper
2661e5dd7070Spatrick // level. This will generate the desired "missing '}' at end of module"
2662e5dd7070Spatrick // diagnostics on the way out.
2663e5dd7070Spatrick return true;
2664e5dd7070Spatrick case tok::annot_module_begin:
2665e5dd7070Spatrick // Recover by entering the module (Sema will diagnose).
2666e5dd7070Spatrick Actions.ActOnModuleBegin(Tok.getLocation(),
2667e5dd7070Spatrick reinterpret_cast<Module *>(
2668e5dd7070Spatrick Tok.getAnnotationValue()));
2669e5dd7070Spatrick ConsumeAnnotationToken();
2670e5dd7070Spatrick ++MisplacedModuleBeginCount;
2671e5dd7070Spatrick continue;
2672e5dd7070Spatrick case tok::annot_module_include:
2673e5dd7070Spatrick // Module import found where it should not be, for instance, inside a
2674e5dd7070Spatrick // namespace. Recover by importing the module.
2675e5dd7070Spatrick Actions.ActOnModuleInclude(Tok.getLocation(),
2676e5dd7070Spatrick reinterpret_cast<Module *>(
2677e5dd7070Spatrick Tok.getAnnotationValue()));
2678e5dd7070Spatrick ConsumeAnnotationToken();
2679e5dd7070Spatrick // If there is another module import, process it.
2680e5dd7070Spatrick continue;
2681e5dd7070Spatrick default:
2682e5dd7070Spatrick return false;
2683e5dd7070Spatrick }
2684e5dd7070Spatrick }
2685e5dd7070Spatrick return false;
2686e5dd7070Spatrick }
2687e5dd7070Spatrick
diagnoseOverflow()2688e5dd7070Spatrick bool BalancedDelimiterTracker::diagnoseOverflow() {
2689e5dd7070Spatrick P.Diag(P.Tok, diag::err_bracket_depth_exceeded)
2690e5dd7070Spatrick << P.getLangOpts().BracketDepth;
2691e5dd7070Spatrick P.Diag(P.Tok, diag::note_bracket_depth);
2692e5dd7070Spatrick P.cutOffParsing();
2693e5dd7070Spatrick return true;
2694e5dd7070Spatrick }
2695e5dd7070Spatrick
expectAndConsume(unsigned DiagID,const char * Msg,tok::TokenKind SkipToTok)2696e5dd7070Spatrick bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
2697e5dd7070Spatrick const char *Msg,
2698e5dd7070Spatrick tok::TokenKind SkipToTok) {
2699e5dd7070Spatrick LOpen = P.Tok.getLocation();
2700e5dd7070Spatrick if (P.ExpectAndConsume(Kind, DiagID, Msg)) {
2701e5dd7070Spatrick if (SkipToTok != tok::unknown)
2702e5dd7070Spatrick P.SkipUntil(SkipToTok, Parser::StopAtSemi);
2703e5dd7070Spatrick return true;
2704e5dd7070Spatrick }
2705e5dd7070Spatrick
2706e5dd7070Spatrick if (getDepth() < P.getLangOpts().BracketDepth)
2707e5dd7070Spatrick return false;
2708e5dd7070Spatrick
2709e5dd7070Spatrick return diagnoseOverflow();
2710e5dd7070Spatrick }
2711e5dd7070Spatrick
diagnoseMissingClose()2712e5dd7070Spatrick bool BalancedDelimiterTracker::diagnoseMissingClose() {
2713e5dd7070Spatrick assert(!P.Tok.is(Close) && "Should have consumed closing delimiter");
2714e5dd7070Spatrick
2715e5dd7070Spatrick if (P.Tok.is(tok::annot_module_end))
2716e5dd7070Spatrick P.Diag(P.Tok, diag::err_missing_before_module_end) << Close;
2717e5dd7070Spatrick else
2718e5dd7070Spatrick P.Diag(P.Tok, diag::err_expected) << Close;
2719e5dd7070Spatrick P.Diag(LOpen, diag::note_matching) << Kind;
2720e5dd7070Spatrick
2721e5dd7070Spatrick // If we're not already at some kind of closing bracket, skip to our closing
2722e5dd7070Spatrick // token.
2723e5dd7070Spatrick if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) &&
2724e5dd7070Spatrick P.Tok.isNot(tok::r_square) &&
2725e5dd7070Spatrick P.SkipUntil(Close, FinalToken,
2726e5dd7070Spatrick Parser::StopAtSemi | Parser::StopBeforeMatch) &&
2727e5dd7070Spatrick P.Tok.is(Close))
2728e5dd7070Spatrick LClose = P.ConsumeAnyToken();
2729e5dd7070Spatrick return true;
2730e5dd7070Spatrick }
2731e5dd7070Spatrick
skipToEnd()2732e5dd7070Spatrick void BalancedDelimiterTracker::skipToEnd() {
2733e5dd7070Spatrick P.SkipUntil(Close, Parser::StopBeforeMatch);
2734e5dd7070Spatrick consumeClose();
2735e5dd7070Spatrick }
2736