| Chris Lattner | eb8a28f | 2006-08-10 18:43:39 +0000 | [diff] [blame] | 1 | //===--- Parser.cpp - C Language Family Parser ----------------------------===// | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
| Chris Lattner | 5b12ab8 | 2007-12-29 19:59:25 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | //  This file implements the Parser interfaces. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "clang/Parse/Parser.h" | 
| Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 15 | #include "clang/AST/ASTConsumer.h" | 
| Erik Verbruggen | 888d52a | 2014-01-15 09:15:43 +0000 | [diff] [blame] | 16 | #include "clang/AST/ASTContext.h" | 
| Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 17 | #include "clang/AST/DeclTemplate.h" | 
| Chris Lattner | 60f3622 | 2009-01-29 05:15:15 +0000 | [diff] [blame] | 18 | #include "clang/Parse/ParseDiagnostic.h" | 
| Vassil Vassilev | 11ad339 | 2017-03-23 15:11:07 +0000 | [diff] [blame] | 19 | #include "clang/Parse/RAIIObjectsForParser.h" | 
| John McCall | 8b0666c | 2010-08-20 18:27:03 +0000 | [diff] [blame] | 20 | #include "clang/Sema/DeclSpec.h" | 
| John McCall | 8b0666c | 2010-08-20 18:27:03 +0000 | [diff] [blame] | 21 | #include "clang/Sema/ParsedTemplate.h" | 
| Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 22 | #include "clang/Sema/Scope.h" | 
| Bruno Cardoso Lopes | 03e0d2d | 2018-06-27 20:29:36 +0000 | [diff] [blame] | 23 | #include "llvm/Support/Path.h" | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 24 | using namespace clang; | 
|  | 25 |  | 
| Mahesha S | 5d61097 | 2012-10-27 09:05:45 +0000 | [diff] [blame] | 26 |  | 
| Benjamin Kramer | 7ca3b7c | 2012-07-13 13:25:11 +0000 | [diff] [blame] | 27 | namespace { | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 28 | /// A comment handler that passes comments found by the preprocessor | 
| Dmitri Gribenko | aab8383 | 2012-06-20 00:34:58 +0000 | [diff] [blame] | 29 | /// to the parser action. | 
|  | 30 | class ActionCommentHandler : public CommentHandler { | 
|  | 31 | Sema &S; | 
|  | 32 |  | 
|  | 33 | public: | 
|  | 34 | explicit ActionCommentHandler(Sema &S) : S(S) { } | 
|  | 35 |  | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 36 | bool HandleComment(Preprocessor &PP, SourceRange Comment) override { | 
| Dmitri Gribenko | aab8383 | 2012-06-20 00:34:58 +0000 | [diff] [blame] | 37 | S.ActOnComment(Comment); | 
|  | 38 | return false; | 
|  | 39 | } | 
|  | 40 | }; | 
| Benjamin Kramer | 7ca3b7c | 2012-07-13 13:25:11 +0000 | [diff] [blame] | 41 | } // end anonymous namespace | 
| Dmitri Gribenko | aab8383 | 2012-06-20 00:34:58 +0000 | [diff] [blame] | 42 |  | 
| Douglas Gregor | 60060d6 | 2011-10-21 03:57:52 +0000 | [diff] [blame] | 43 | IdentifierInfo *Parser::getSEHExceptKeyword() { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 44 | // __except is accepted as a (contextual) keyword | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 45 | if (!Ident__except && (getLangOpts().MicrosoftExt || getLangOpts().Borland)) | 
| Douglas Gregor | 60060d6 | 2011-10-21 03:57:52 +0000 | [diff] [blame] | 46 | Ident__except = PP.getIdentifierInfo("__except"); | 
|  | 47 |  | 
|  | 48 | return Ident__except; | 
|  | 49 | } | 
|  | 50 |  | 
| Argyrios Kyrtzidis | 3a6c814 | 2012-10-31 17:29:22 +0000 | [diff] [blame] | 51 | Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies) | 
| Ted Kremenek | 4c9d46b | 2011-03-22 01:15:17 +0000 | [diff] [blame] | 52 | : PP(pp), Actions(actions), Diags(PP.getDiagnostics()), | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 53 | GreaterThanIsOperator(true), ColonIsSacred(false), | 
| Erik Verbruggen | 6e92251 | 2012-04-12 10:11:59 +0000 | [diff] [blame] | 54 | InMessageExpression(false), TemplateParameterDepth(0), | 
| Argyrios Kyrtzidis | 3a6c814 | 2012-10-31 17:29:22 +0000 | [diff] [blame] | 55 | ParsingInObjCContainer(false) { | 
|  | 56 | SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies; | 
| Chris Lattner | d5705d1 | 2012-10-27 19:49:20 +0000 | [diff] [blame] | 57 | Tok.startToken(); | 
| Chris Lattner | 8c20487 | 2006-10-14 05:19:21 +0000 | [diff] [blame] | 58 | Tok.setKind(tok::eof); | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 59 | Actions.CurScope = nullptr; | 
| Chris Lattner | 03928c7 | 2007-07-15 00:04:39 +0000 | [diff] [blame] | 60 | NumCachedScopes = 0; | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 61 | CurParsedObjCImpl = nullptr; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 62 |  | 
|  | 63 | // Add #pragma handlers. These are removed and destroyed in the | 
|  | 64 | // destructor. | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 65 | initializePragmaHandlers(); | 
| Reid Kleckner | 002562a | 2013-05-06 21:02:12 +0000 | [diff] [blame] | 66 |  | 
| Dmitri Gribenko | 17e147f | 2012-06-20 01:06:08 +0000 | [diff] [blame] | 67 | CommentSemaHandler.reset(new ActionCommentHandler(actions)); | 
|  | 68 | PP.addCommentHandler(CommentSemaHandler.get()); | 
| Dmitri Gribenko | aab8383 | 2012-06-20 00:34:58 +0000 | [diff] [blame] | 69 |  | 
| Douglas Gregor | 3a7ad25 | 2010-08-24 19:08:16 +0000 | [diff] [blame] | 70 | PP.setCodeCompletionHandler(*this); | 
| Chris Lattner | 971c6b6 | 2006-08-05 22:46:42 +0000 | [diff] [blame] | 71 | } | 
|  | 72 |  | 
| Chris Lattner | 427c9c1 | 2008-11-22 00:59:29 +0000 | [diff] [blame] | 73 | DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) { | 
| Argyrios Kyrtzidis | d004064 | 2010-11-18 20:06:41 +0000 | [diff] [blame] | 74 | return Diags.Report(Loc, DiagID); | 
| Chris Lattner | 6d29c10 | 2008-11-18 07:48:38 +0000 | [diff] [blame] | 75 | } | 
|  | 76 |  | 
| Chris Lattner | 427c9c1 | 2008-11-22 00:59:29 +0000 | [diff] [blame] | 77 | DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) { | 
| Chris Lattner | 6d29c10 | 2008-11-18 07:48:38 +0000 | [diff] [blame] | 78 | return Diag(Tok.getLocation(), DiagID); | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 79 | } | 
|  | 80 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 81 | /// Emits a diagnostic suggesting parentheses surrounding a | 
| Douglas Gregor | 87f95b0 | 2009-02-26 21:00:50 +0000 | [diff] [blame] | 82 | /// given range. | 
|  | 83 | /// | 
|  | 84 | /// \param Loc The location where we'll emit the diagnostic. | 
| Dmitri Gribenko | adba9be | 2012-08-23 17:58:28 +0000 | [diff] [blame] | 85 | /// \param DK The kind of diagnostic to emit. | 
| Douglas Gregor | 87f95b0 | 2009-02-26 21:00:50 +0000 | [diff] [blame] | 86 | /// \param ParenRange Source range enclosing code that should be parenthesized. | 
|  | 87 | void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK, | 
|  | 88 | SourceRange ParenRange) { | 
| Douglas Gregor | 96977da | 2009-02-27 17:53:17 +0000 | [diff] [blame] | 89 | SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd()); | 
|  | 90 | if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) { | 
| Douglas Gregor | 87f95b0 | 2009-02-26 21:00:50 +0000 | [diff] [blame] | 91 | // We can't display the parentheses, so just dig the | 
|  | 92 | // warning/error and return. | 
|  | 93 | Diag(Loc, DK); | 
|  | 94 | return; | 
|  | 95 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 96 |  | 
|  | 97 | Diag(Loc, DK) | 
| Douglas Gregor | a771f46 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 98 | << FixItHint::CreateInsertion(ParenRange.getBegin(), "(") | 
|  | 99 | << FixItHint::CreateInsertion(EndLoc, ")"); | 
| Douglas Gregor | 87f95b0 | 2009-02-26 21:00:50 +0000 | [diff] [blame] | 100 | } | 
|  | 101 |  | 
| John McCall | 1ca73da | 2010-09-07 18:31:03 +0000 | [diff] [blame] | 102 | static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok) { | 
|  | 103 | switch (ExpectedTok) { | 
| Richard Smith | 0875c53 | 2012-09-18 00:52:05 +0000 | [diff] [blame] | 104 | case tok::semi: | 
|  | 105 | return Tok.is(tok::colon) || Tok.is(tok::comma); // : or , for ; | 
| John McCall | 1ca73da | 2010-09-07 18:31:03 +0000 | [diff] [blame] | 106 | default: return false; | 
|  | 107 | } | 
|  | 108 | } | 
|  | 109 |  | 
| Chris Lattner | dbb2a46 | 2006-08-12 19:26:13 +0000 | [diff] [blame] | 110 | bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID, | 
| Reid Kleckner | 1a711b1 | 2014-07-22 00:53:05 +0000 | [diff] [blame] | 111 | StringRef Msg) { | 
| Douglas Gregor | 6da3db4 | 2010-05-25 05:58:43 +0000 | [diff] [blame] | 112 | if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) { | 
| Chris Lattner | 15a00da | 2006-08-15 04:10:31 +0000 | [diff] [blame] | 113 | ConsumeAnyToken(); | 
| Chris Lattner | dbb2a46 | 2006-08-12 19:26:13 +0000 | [diff] [blame] | 114 | return false; | 
|  | 115 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 116 |  | 
| John McCall | 1ca73da | 2010-09-07 18:31:03 +0000 | [diff] [blame] | 117 | // Detect common single-character typos and resume. | 
|  | 118 | if (IsCommonTypo(ExpectedTok, Tok)) { | 
|  | 119 | SourceLocation Loc = Tok.getLocation(); | 
| Alp Toker | f2b6e79 | 2014-02-23 03:45:03 +0000 | [diff] [blame] | 120 | { | 
|  | 121 | DiagnosticBuilder DB = Diag(Loc, DiagID); | 
|  | 122 | DB << FixItHint::CreateReplacement( | 
|  | 123 | SourceRange(Loc), tok::getPunctuatorSpelling(ExpectedTok)); | 
|  | 124 | if (DiagID == diag::err_expected) | 
|  | 125 | DB << ExpectedTok; | 
|  | 126 | else if (DiagID == diag::err_expected_after) | 
|  | 127 | DB << Msg << ExpectedTok; | 
|  | 128 | else | 
|  | 129 | DB << Msg; | 
|  | 130 | } | 
| John McCall | 1ca73da | 2010-09-07 18:31:03 +0000 | [diff] [blame] | 131 |  | 
|  | 132 | // Pretend there wasn't a problem. | 
| Alp Toker | f2b6e79 | 2014-02-23 03:45:03 +0000 | [diff] [blame] | 133 | ConsumeAnyToken(); | 
| John McCall | 1ca73da | 2010-09-07 18:31:03 +0000 | [diff] [blame] | 134 | return false; | 
|  | 135 | } | 
|  | 136 |  | 
| Douglas Gregor | 96977da | 2009-02-27 17:53:17 +0000 | [diff] [blame] | 137 | SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation); | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 138 | const char *Spelling = nullptr; | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 139 | if (EndLoc.isValid()) | 
| Alp Toker | 6d35eab | 2014-01-06 12:54:07 +0000 | [diff] [blame] | 140 | Spelling = tok::getPunctuatorSpelling(ExpectedTok); | 
| Douglas Gregor | 87f95b0 | 2009-02-26 21:00:50 +0000 | [diff] [blame] | 141 |  | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 142 | DiagnosticBuilder DB = | 
|  | 143 | Spelling | 
|  | 144 | ? Diag(EndLoc, DiagID) << FixItHint::CreateInsertion(EndLoc, Spelling) | 
|  | 145 | : Diag(Tok, DiagID); | 
|  | 146 | if (DiagID == diag::err_expected) | 
|  | 147 | DB << ExpectedTok; | 
|  | 148 | else if (DiagID == diag::err_expected_after) | 
|  | 149 | DB << Msg << ExpectedTok; | 
|  | 150 | else | 
|  | 151 | DB << Msg; | 
|  | 152 |  | 
| Chris Lattner | dbb2a46 | 2006-08-12 19:26:13 +0000 | [diff] [blame] | 153 | return true; | 
|  | 154 | } | 
|  | 155 |  | 
| Douglas Gregor | 45d6bdf | 2010-09-07 15:23:11 +0000 | [diff] [blame] | 156 | bool Parser::ExpectAndConsumeSemi(unsigned DiagID) { | 
| Alp Toker | ec54327 | 2013-12-24 09:48:30 +0000 | [diff] [blame] | 157 | if (TryConsumeToken(tok::semi)) | 
|  | 158 | return false; | 
|  | 159 |  | 
|  | 160 | if (Tok.is(tok::code_completion)) { | 
|  | 161 | handleUnexpectedCodeCompletionToken(); | 
| Douglas Gregor | 45d6bdf | 2010-09-07 15:23:11 +0000 | [diff] [blame] | 162 | return false; | 
|  | 163 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 164 |  | 
|  | 165 | if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) && | 
| Douglas Gregor | 45d6bdf | 2010-09-07 15:23:11 +0000 | [diff] [blame] | 166 | NextToken().is(tok::semi)) { | 
|  | 167 | Diag(Tok, diag::err_extraneous_token_before_semi) | 
|  | 168 | << PP.getSpelling(Tok) | 
|  | 169 | << FixItHint::CreateRemoval(Tok.getLocation()); | 
|  | 170 | ConsumeAnyToken(); // The ')' or ']'. | 
|  | 171 | ConsumeToken(); // The ';'. | 
|  | 172 | return false; | 
|  | 173 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 174 |  | 
| Douglas Gregor | 45d6bdf | 2010-09-07 15:23:11 +0000 | [diff] [blame] | 175 | return ExpectAndConsume(tok::semi, DiagID); | 
|  | 176 | } | 
|  | 177 |  | 
| Faisal Vali | 090da2d | 2018-01-01 18:23:28 +0000 | [diff] [blame] | 178 | void Parser::ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST) { | 
| Richard Trieu | 2f7dc46 | 2012-05-16 19:04:59 +0000 | [diff] [blame] | 179 | if (!Tok.is(tok::semi)) return; | 
|  | 180 |  | 
| Richard Smith | 87f5dc5 | 2012-07-23 05:45:25 +0000 | [diff] [blame] | 181 | bool HadMultipleSemis = false; | 
| Richard Trieu | 2f7dc46 | 2012-05-16 19:04:59 +0000 | [diff] [blame] | 182 | SourceLocation StartLoc = Tok.getLocation(); | 
|  | 183 | SourceLocation EndLoc = Tok.getLocation(); | 
|  | 184 | ConsumeToken(); | 
|  | 185 |  | 
|  | 186 | while ((Tok.is(tok::semi) && !Tok.isAtStartOfLine())) { | 
| Richard Smith | 87f5dc5 | 2012-07-23 05:45:25 +0000 | [diff] [blame] | 187 | HadMultipleSemis = true; | 
| Richard Trieu | 2f7dc46 | 2012-05-16 19:04:59 +0000 | [diff] [blame] | 188 | EndLoc = Tok.getLocation(); | 
|  | 189 | ConsumeToken(); | 
|  | 190 | } | 
|  | 191 |  | 
| Richard Smith | 87f5dc5 | 2012-07-23 05:45:25 +0000 | [diff] [blame] | 192 | // C++11 allows extra semicolons at namespace scope, but not in any of the | 
|  | 193 | // other contexts. | 
|  | 194 | if (Kind == OutsideFunction && getLangOpts().CPlusPlus) { | 
| Richard Smith | 2bf7fdb | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 195 | if (getLangOpts().CPlusPlus11) | 
| Richard Smith | 87f5dc5 | 2012-07-23 05:45:25 +0000 | [diff] [blame] | 196 | Diag(StartLoc, diag::warn_cxx98_compat_top_level_semi) | 
|  | 197 | << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); | 
|  | 198 | else | 
|  | 199 | Diag(StartLoc, diag::ext_extra_semi_cxx11) | 
|  | 200 | << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); | 
| Richard Trieu | 2f7dc46 | 2012-05-16 19:04:59 +0000 | [diff] [blame] | 201 | return; | 
|  | 202 | } | 
|  | 203 |  | 
| Richard Smith | 87f5dc5 | 2012-07-23 05:45:25 +0000 | [diff] [blame] | 204 | if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis) | 
|  | 205 | Diag(StartLoc, diag::ext_extra_semi) | 
| Erik Verbruggen | 888d52a | 2014-01-15 09:15:43 +0000 | [diff] [blame] | 206 | << Kind << DeclSpec::getSpecifierName((DeclSpec::TST)TST, | 
|  | 207 | Actions.getASTContext().getPrintingPolicy()) | 
| Richard Smith | 87f5dc5 | 2012-07-23 05:45:25 +0000 | [diff] [blame] | 208 | << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); | 
|  | 209 | else | 
|  | 210 | // A single semicolon is valid after a member function definition. | 
|  | 211 | Diag(StartLoc, diag::warn_extra_semi_after_mem_fn_def) | 
|  | 212 | << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc)); | 
| Richard Trieu | 2f7dc46 | 2012-05-16 19:04:59 +0000 | [diff] [blame] | 213 | } | 
|  | 214 |  | 
| Alex Lorenz | f127821 | 2017-04-11 15:01:53 +0000 | [diff] [blame] | 215 | bool Parser::expectIdentifier() { | 
|  | 216 | if (Tok.is(tok::identifier)) | 
|  | 217 | return false; | 
|  | 218 | if (const auto *II = Tok.getIdentifierInfo()) { | 
|  | 219 | if (II->isCPlusPlusKeyword(getLangOpts())) { | 
|  | 220 | Diag(Tok, diag::err_expected_token_instead_of_objcxx_keyword) | 
|  | 221 | << tok::identifier << Tok.getIdentifierInfo(); | 
|  | 222 | // Objective-C++: Recover by treating this keyword as a valid identifier. | 
|  | 223 | return false; | 
|  | 224 | } | 
|  | 225 | } | 
|  | 226 | Diag(Tok, diag::err_expected) << tok::identifier; | 
|  | 227 | return true; | 
|  | 228 | } | 
|  | 229 |  | 
| Chris Lattner | 70f32b7 | 2006-07-31 05:09:04 +0000 | [diff] [blame] | 230 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 231 | // Error recovery. | 
|  | 232 | //===----------------------------------------------------------------------===// | 
|  | 233 |  | 
| Benjamin Kramer | a855349 | 2013-11-18 16:50:24 +0000 | [diff] [blame] | 234 | static bool HasFlagsSet(Parser::SkipUntilFlags L, Parser::SkipUntilFlags R) { | 
| Alexey Bataev | ee6507d | 2013-11-18 08:17:37 +0000 | [diff] [blame] | 235 | return (static_cast<unsigned>(L) & static_cast<unsigned>(R)) != 0; | 
|  | 236 | } | 
|  | 237 |  | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 238 | /// SkipUntil - Read tokens until we get to the specified token, then consume | 
| Alexey Bataev | ee6507d | 2013-11-18 08:17:37 +0000 | [diff] [blame] | 239 | /// it (unless no flag StopBeforeMatch).  Because we cannot guarantee that the | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 240 | /// token will ever occur, this skips to the next token, or to some likely | 
|  | 241 | /// good stopping point.  If StopAtSemi is true, skipping will stop at a ';' | 
|  | 242 | /// character. | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 243 | /// | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 244 | /// If SkipUntil finds the specified token, it returns true, otherwise it | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 245 | /// returns false. | 
| Alexey Bataev | ee6507d | 2013-11-18 08:17:37 +0000 | [diff] [blame] | 246 | bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) { | 
| Chris Lattner | 5bd57e0 | 2006-08-11 06:40:25 +0000 | [diff] [blame] | 247 | // We always want this function to skip at least one token if the first token | 
|  | 248 | // isn't T and if not at EOF. | 
|  | 249 | bool isFirstTokenSkipped = true; | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 250 | while (1) { | 
| Chris Lattner | 83b94e0 | 2007-04-27 19:12:15 +0000 | [diff] [blame] | 251 | // If we found one of the tokens, stop and return true. | 
| David Blaikie | 80cdddc | 2012-04-09 16:37:11 +0000 | [diff] [blame] | 252 | for (unsigned i = 0, NumToks = Toks.size(); i != NumToks; ++i) { | 
| Chris Lattner | 0ab032a | 2007-10-09 17:23:58 +0000 | [diff] [blame] | 253 | if (Tok.is(Toks[i])) { | 
| Alexey Bataev | ee6507d | 2013-11-18 08:17:37 +0000 | [diff] [blame] | 254 | if (HasFlagsSet(Flags, StopBeforeMatch)) { | 
| Chris Lattner | 83b94e0 | 2007-04-27 19:12:15 +0000 | [diff] [blame] | 255 | // Noop, don't consume the token. | 
|  | 256 | } else { | 
|  | 257 | ConsumeAnyToken(); | 
|  | 258 | } | 
|  | 259 | return true; | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 260 | } | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 261 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 262 |  | 
| Rafael Espindola | 885a0c4 | 2013-07-25 02:11:20 +0000 | [diff] [blame] | 263 | // Important special case: The caller has given up and just wants us to | 
|  | 264 | // skip the rest of the file. Do this without recursing, since we can | 
|  | 265 | // get here precisely because the caller detected too much recursion. | 
| Alexey Bataev | ee6507d | 2013-11-18 08:17:37 +0000 | [diff] [blame] | 266 | if (Toks.size() == 1 && Toks[0] == tok::eof && | 
|  | 267 | !HasFlagsSet(Flags, StopAtSemi) && | 
|  | 268 | !HasFlagsSet(Flags, StopAtCodeCompletion)) { | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 269 | while (Tok.isNot(tok::eof)) | 
| Rafael Espindola | 885a0c4 | 2013-07-25 02:11:20 +0000 | [diff] [blame] | 270 | ConsumeAnyToken(); | 
|  | 271 | return true; | 
|  | 272 | } | 
|  | 273 |  | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 274 | switch (Tok.getKind()) { | 
|  | 275 | case tok::eof: | 
|  | 276 | // Ran out of tokens. | 
|  | 277 | return false; | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 278 |  | 
| Alexey Bataev | 1d97d2a | 2015-10-19 06:40:17 +0000 | [diff] [blame] | 279 | case tok::annot_pragma_openmp: | 
| Alp Toker | b14a470 | 2013-12-18 19:10:54 +0000 | [diff] [blame] | 280 | case tok::annot_pragma_openmp_end: | 
|  | 281 | // Stop before an OpenMP pragma boundary. | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 282 | case tok::annot_module_begin: | 
|  | 283 | case tok::annot_module_end: | 
|  | 284 | case tok::annot_module_include: | 
|  | 285 | // Stop before we change submodules. They generally indicate a "good" | 
|  | 286 | // place to pick up parsing again (except in the special case where | 
|  | 287 | // we're trying to skip to EOF). | 
|  | 288 | return false; | 
|  | 289 |  | 
| Douglas Gregor | 6da3db4 | 2010-05-25 05:58:43 +0000 | [diff] [blame] | 290 | case tok::code_completion: | 
| Alexey Bataev | ee6507d | 2013-11-18 08:17:37 +0000 | [diff] [blame] | 291 | if (!HasFlagsSet(Flags, StopAtCodeCompletion)) | 
| Alp Toker | ec54327 | 2013-12-24 09:48:30 +0000 | [diff] [blame] | 292 | handleUnexpectedCodeCompletionToken(); | 
| Douglas Gregor | 6da3db4 | 2010-05-25 05:58:43 +0000 | [diff] [blame] | 293 | return false; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 294 |  | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 295 | case tok::l_paren: | 
|  | 296 | // Recursively skip properly-nested parens. | 
|  | 297 | ConsumeParen(); | 
| Alp Toker | d751fa7 | 2013-12-18 19:10:49 +0000 | [diff] [blame] | 298 | if (HasFlagsSet(Flags, StopAtCodeCompletion)) | 
|  | 299 | SkipUntil(tok::r_paren, StopAtCodeCompletion); | 
|  | 300 | else | 
|  | 301 | SkipUntil(tok::r_paren); | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 302 | break; | 
|  | 303 | case tok::l_square: | 
|  | 304 | // Recursively skip properly-nested square brackets. | 
|  | 305 | ConsumeBracket(); | 
| Alp Toker | d751fa7 | 2013-12-18 19:10:49 +0000 | [diff] [blame] | 306 | if (HasFlagsSet(Flags, StopAtCodeCompletion)) | 
|  | 307 | SkipUntil(tok::r_square, StopAtCodeCompletion); | 
|  | 308 | else | 
|  | 309 | SkipUntil(tok::r_square); | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 310 | break; | 
|  | 311 | case tok::l_brace: | 
|  | 312 | // Recursively skip properly-nested braces. | 
|  | 313 | ConsumeBrace(); | 
| Alp Toker | d751fa7 | 2013-12-18 19:10:49 +0000 | [diff] [blame] | 314 | if (HasFlagsSet(Flags, StopAtCodeCompletion)) | 
|  | 315 | SkipUntil(tok::r_brace, StopAtCodeCompletion); | 
|  | 316 | else | 
|  | 317 | SkipUntil(tok::r_brace); | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 318 | break; | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 319 |  | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 320 | // Okay, we found a ']' or '}' or ')', which we think should be balanced. | 
|  | 321 | // Since the user wasn't looking for this token (if they were, it would | 
|  | 322 | // already be handled), this isn't balanced.  If there is a LHS token at a | 
|  | 323 | // higher level, we will assume that this matches the unbalanced token | 
|  | 324 | // and return it.  Otherwise, this is a spurious RHS token, which we skip. | 
|  | 325 | case tok::r_paren: | 
| Alp Toker | d751fa7 | 2013-12-18 19:10:49 +0000 | [diff] [blame] | 326 | if (ParenCount && !isFirstTokenSkipped) | 
| Chris Lattner | 5bd57e0 | 2006-08-11 06:40:25 +0000 | [diff] [blame] | 327 | return false;  // Matches something. | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 328 | ConsumeParen(); | 
|  | 329 | break; | 
|  | 330 | case tok::r_square: | 
| Alp Toker | d751fa7 | 2013-12-18 19:10:49 +0000 | [diff] [blame] | 331 | if (BracketCount && !isFirstTokenSkipped) | 
| Chris Lattner | 5bd57e0 | 2006-08-11 06:40:25 +0000 | [diff] [blame] | 332 | return false;  // Matches something. | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 333 | ConsumeBracket(); | 
|  | 334 | break; | 
|  | 335 | case tok::r_brace: | 
| Alp Toker | d751fa7 | 2013-12-18 19:10:49 +0000 | [diff] [blame] | 336 | if (BraceCount && !isFirstTokenSkipped) | 
| Chris Lattner | 5bd57e0 | 2006-08-11 06:40:25 +0000 | [diff] [blame] | 337 | return false;  // Matches something. | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 338 | ConsumeBrace(); | 
|  | 339 | break; | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 340 |  | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 341 | case tok::semi: | 
| Alexey Bataev | ee6507d | 2013-11-18 08:17:37 +0000 | [diff] [blame] | 342 | if (HasFlagsSet(Flags, StopAtSemi)) | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 343 | return false; | 
| Reid Kleckner | 4dc0b1a | 2018-11-01 19:54:45 +0000 | [diff] [blame] | 344 | LLVM_FALLTHROUGH; | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 345 | default: | 
|  | 346 | // Skip this token. | 
| Richard Smith | af3b325 | 2017-05-18 19:21:48 +0000 | [diff] [blame] | 347 | ConsumeAnyToken(); | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 348 | break; | 
|  | 349 | } | 
| Chris Lattner | 5bd57e0 | 2006-08-11 06:40:25 +0000 | [diff] [blame] | 350 | isFirstTokenSkipped = false; | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 351 | } | 
| Chris Lattner | eec40f9 | 2006-08-06 21:55:29 +0000 | [diff] [blame] | 352 | } | 
|  | 353 |  | 
|  | 354 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | e4e3859 | 2006-08-14 00:15:05 +0000 | [diff] [blame] | 355 | // Scope manipulation | 
|  | 356 | //===----------------------------------------------------------------------===// | 
|  | 357 |  | 
|  | 358 | /// EnterScope - Start a new scope. | 
| Chris Lattner | 33ad2ca | 2006-11-05 23:47:55 +0000 | [diff] [blame] | 359 | void Parser::EnterScope(unsigned ScopeFlags) { | 
| Chris Lattner | 03928c7 | 2007-07-15 00:04:39 +0000 | [diff] [blame] | 360 | if (NumCachedScopes) { | 
|  | 361 | Scope *N = ScopeCache[--NumCachedScopes]; | 
| Douglas Gregor | 0be31a2 | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 362 | N->Init(getCurScope(), ScopeFlags); | 
|  | 363 | Actions.CurScope = N; | 
| Chris Lattner | b6a0e17 | 2006-11-06 00:22:42 +0000 | [diff] [blame] | 364 | } else { | 
| Argyrios Kyrtzidis | 1865342 | 2010-11-19 00:19:12 +0000 | [diff] [blame] | 365 | Actions.CurScope = new Scope(getCurScope(), ScopeFlags, Diags); | 
| Chris Lattner | b6a0e17 | 2006-11-06 00:22:42 +0000 | [diff] [blame] | 366 | } | 
| Chris Lattner | e4e3859 | 2006-08-14 00:15:05 +0000 | [diff] [blame] | 367 | } | 
|  | 368 |  | 
|  | 369 | /// ExitScope - Pop a scope off the scope stack. | 
|  | 370 | void Parser::ExitScope() { | 
| Douglas Gregor | 0be31a2 | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 371 | assert(getCurScope() && "Scope imbalance!"); | 
| Chris Lattner | e4e3859 | 2006-08-14 00:15:05 +0000 | [diff] [blame] | 372 |  | 
| Chris Lattner | 87547e6 | 2007-10-09 20:37:18 +0000 | [diff] [blame] | 373 | // Inform the actions module that this scope is going away if there are any | 
|  | 374 | // decls in it. | 
| Nick Lewycky | d78f92f | 2014-05-03 00:41:18 +0000 | [diff] [blame] | 375 | Actions.ActOnPopScope(Tok.getLocation(), getCurScope()); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 376 |  | 
| Douglas Gregor | 0be31a2 | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 377 | Scope *OldScope = getCurScope(); | 
|  | 378 | Actions.CurScope = OldScope->getParent(); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 379 |  | 
| Chris Lattner | 03928c7 | 2007-07-15 00:04:39 +0000 | [diff] [blame] | 380 | if (NumCachedScopes == ScopeCacheSize) | 
|  | 381 | delete OldScope; | 
| Chris Lattner | b6a0e17 | 2006-11-06 00:22:42 +0000 | [diff] [blame] | 382 | else | 
| Chris Lattner | 03928c7 | 2007-07-15 00:04:39 +0000 | [diff] [blame] | 383 | ScopeCache[NumCachedScopes++] = OldScope; | 
| Chris Lattner | e4e3859 | 2006-08-14 00:15:05 +0000 | [diff] [blame] | 384 | } | 
|  | 385 |  | 
| Richard Smith | 938f40b | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 386 | /// Set the flags for the current scope to ScopeFlags. If ManageFlags is false, | 
|  | 387 | /// this object does nothing. | 
|  | 388 | Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags, | 
|  | 389 | bool ManageFlags) | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 390 | : CurScope(ManageFlags ? Self->getCurScope() : nullptr) { | 
| Richard Smith | 938f40b | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 391 | if (CurScope) { | 
|  | 392 | OldFlags = CurScope->getFlags(); | 
|  | 393 | CurScope->setFlags(ScopeFlags); | 
|  | 394 | } | 
|  | 395 | } | 
| Chris Lattner | e4e3859 | 2006-08-14 00:15:05 +0000 | [diff] [blame] | 396 |  | 
| Richard Smith | 938f40b | 2011-06-11 17:19:42 +0000 | [diff] [blame] | 397 | /// Restore the flags for the current scope to what they were before this | 
|  | 398 | /// object overrode them. | 
|  | 399 | Parser::ParseScopeFlags::~ParseScopeFlags() { | 
|  | 400 | if (CurScope) | 
|  | 401 | CurScope->setFlags(OldFlags); | 
|  | 402 | } | 
| Chris Lattner | e4e3859 | 2006-08-14 00:15:05 +0000 | [diff] [blame] | 403 |  | 
|  | 404 |  | 
|  | 405 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 70f32b7 | 2006-07-31 05:09:04 +0000 | [diff] [blame] | 406 | // C99 6.9: External Definitions. | 
|  | 407 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 408 |  | 
| Chris Lattner | b6a0e17 | 2006-11-06 00:22:42 +0000 | [diff] [blame] | 409 | Parser::~Parser() { | 
|  | 410 | // If we still have scopes active, delete the scope tree. | 
| Douglas Gregor | 0be31a2 | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 411 | delete getCurScope(); | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 412 | Actions.CurScope = nullptr; | 
|  | 413 |  | 
| Chris Lattner | b6a0e17 | 2006-11-06 00:22:42 +0000 | [diff] [blame] | 414 | // Free the scope cache. | 
| Chris Lattner | 03928c7 | 2007-07-15 00:04:39 +0000 | [diff] [blame] | 415 | for (unsigned i = 0, e = NumCachedScopes; i != e; ++i) | 
|  | 416 | delete ScopeCache[i]; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 417 |  | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 418 | resetPragmaHandlers(); | 
| Dmitri Gribenko | aab8383 | 2012-06-20 00:34:58 +0000 | [diff] [blame] | 419 |  | 
| Dmitri Gribenko | 17e147f | 2012-06-20 01:06:08 +0000 | [diff] [blame] | 420 | PP.removeCommentHandler(CommentSemaHandler.get()); | 
| Dmitri Gribenko | aab8383 | 2012-06-20 00:34:58 +0000 | [diff] [blame] | 421 |  | 
| Douglas Gregor | 3a7ad25 | 2010-08-24 19:08:16 +0000 | [diff] [blame] | 422 | PP.clearCodeCompletionHandler(); | 
| Benjamin Kramer | 1e6b606 | 2012-04-14 12:14:03 +0000 | [diff] [blame] | 423 |  | 
| Nico Weber | 28e0f24 | 2015-05-17 01:07:16 +0000 | [diff] [blame] | 424 | if (getLangOpts().DelayedTemplateParsing && | 
|  | 425 | !PP.isIncrementalProcessingEnabled() && !TemplateIds.empty()) { | 
|  | 426 | // If an ASTConsumer parsed delay-parsed templates in their | 
|  | 427 | // HandleTranslationUnit() method, TemplateIds created there were not | 
|  | 428 | // guarded by a DestroyTemplateIdAnnotationsRAIIObj object in | 
|  | 429 | // ParseTopLevelDecl(). Destroy them here. | 
|  | 430 | DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); | 
|  | 431 | } | 
|  | 432 |  | 
| Benjamin Kramer | 1e6b606 | 2012-04-14 12:14:03 +0000 | [diff] [blame] | 433 | assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?"); | 
| Chris Lattner | b6a0e17 | 2006-11-06 00:22:42 +0000 | [diff] [blame] | 434 | } | 
|  | 435 |  | 
| Chris Lattner | 38ba336 | 2006-08-17 07:04:37 +0000 | [diff] [blame] | 436 | /// Initialize - Warm up the parser. | 
|  | 437 | /// | 
|  | 438 | void Parser::Initialize() { | 
| Chris Lattner | 1a76a3c | 2007-08-26 06:24:45 +0000 | [diff] [blame] | 439 | // Create the translation unit scope.  Install it as the current scope. | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 440 | assert(getCurScope() == nullptr && "A scope is already active?"); | 
| Chris Lattner | 1a76a3c | 2007-08-26 06:24:45 +0000 | [diff] [blame] | 441 | EnterScope(Scope::DeclScope); | 
| Douglas Gregor | f11096c | 2010-08-25 18:07:12 +0000 | [diff] [blame] | 442 | Actions.ActOnTranslationUnitScope(getCurScope()); | 
|  | 443 |  | 
| Chris Lattner | 6678284 | 2007-08-29 22:54:08 +0000 | [diff] [blame] | 444 | // Initialization for Objective-C context sensitive keywords recognition. | 
| Ted Kremenek | 1b0ea82 | 2008-01-07 19:49:32 +0000 | [diff] [blame] | 445 | // Referenced in Parser::ParseObjCTypeQualifierList. | 
| Erik Pilkington | fa98390 | 2018-10-30 20:31:30 +0000 | [diff] [blame] | 446 | if (getLangOpts().ObjC) { | 
| Ted Kremenek | 1b0ea82 | 2008-01-07 19:49:32 +0000 | [diff] [blame] | 447 | ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in"); | 
|  | 448 | ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out"); | 
|  | 449 | ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout"); | 
|  | 450 | ObjCTypeQuals[objc_oneway] = &PP.getIdentifierTable().get("oneway"); | 
|  | 451 | ObjCTypeQuals[objc_bycopy] = &PP.getIdentifierTable().get("bycopy"); | 
|  | 452 | ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref"); | 
| Douglas Gregor | 813a066 | 2015-06-19 18:14:38 +0000 | [diff] [blame] | 453 | ObjCTypeQuals[objc_nonnull] = &PP.getIdentifierTable().get("nonnull"); | 
|  | 454 | ObjCTypeQuals[objc_nullable] = &PP.getIdentifierTable().get("nullable"); | 
|  | 455 | ObjCTypeQuals[objc_null_unspecified] | 
|  | 456 | = &PP.getIdentifierTable().get("null_unspecified"); | 
| Chris Lattner | 6678284 | 2007-08-29 22:54:08 +0000 | [diff] [blame] | 457 | } | 
| Daniel Dunbar | 12c9ddc | 2008-08-14 22:04:54 +0000 | [diff] [blame] | 458 |  | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 459 | Ident_instancetype = nullptr; | 
|  | 460 | Ident_final = nullptr; | 
|  | 461 | Ident_sealed = nullptr; | 
|  | 462 | Ident_override = nullptr; | 
| David Majnemer | a6b68bf | 2016-07-29 20:01:12 +0000 | [diff] [blame] | 463 | Ident_GNU_final = nullptr; | 
| Anders Carlsson | 11fdbbc | 2011-01-16 23:56:42 +0000 | [diff] [blame] | 464 |  | 
| Daniel Dunbar | 12c9ddc | 2008-08-14 22:04:54 +0000 | [diff] [blame] | 465 | Ident_super = &PP.getIdentifierTable().get("super"); | 
| John Thompson | 2233460 | 2010-02-05 00:12:22 +0000 | [diff] [blame] | 466 |  | 
| Ulrich Weigand | d666517 | 2015-07-30 15:53:58 +0000 | [diff] [blame] | 467 | Ident_vector = nullptr; | 
|  | 468 | Ident_bool = nullptr; | 
|  | 469 | Ident_pixel = nullptr; | 
| Ulrich Weigand | 3c5038a | 2015-07-30 14:08:36 +0000 | [diff] [blame] | 470 | if (getLangOpts().AltiVec || getLangOpts().ZVector) { | 
| John Thompson | 2233460 | 2010-02-05 00:12:22 +0000 | [diff] [blame] | 471 | Ident_vector = &PP.getIdentifierTable().get("vector"); | 
| Bill Schmidt | 99a084b | 2013-07-03 20:54:09 +0000 | [diff] [blame] | 472 | Ident_bool = &PP.getIdentifierTable().get("bool"); | 
| John Thompson | 2233460 | 2010-02-05 00:12:22 +0000 | [diff] [blame] | 473 | } | 
| Ulrich Weigand | 3c5038a | 2015-07-30 14:08:36 +0000 | [diff] [blame] | 474 | if (getLangOpts().AltiVec) | 
|  | 475 | Ident_pixel = &PP.getIdentifierTable().get("pixel"); | 
| Douglas Gregor | 20b2ebd | 2011-03-23 00:50:03 +0000 | [diff] [blame] | 476 |  | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 477 | Ident_introduced = nullptr; | 
|  | 478 | Ident_deprecated = nullptr; | 
|  | 479 | Ident_obsoleted = nullptr; | 
|  | 480 | Ident_unavailable = nullptr; | 
| Manman Ren | d8039df | 2016-02-22 04:47:24 +0000 | [diff] [blame] | 481 | Ident_strict = nullptr; | 
| Manman Ren | 75bc676 | 2016-03-21 17:30:55 +0000 | [diff] [blame] | 482 | Ident_replacement = nullptr; | 
| John Wiegley | 1c0675e | 2011-04-28 01:08:34 +0000 | [diff] [blame] | 483 |  | 
| Alex Lorenz | d5d27e1 | 2017-03-01 18:06:25 +0000 | [diff] [blame] | 484 | Ident_language = Ident_defined_in = Ident_generated_declaration = nullptr; | 
|  | 485 |  | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 486 | Ident__except = nullptr; | 
|  | 487 |  | 
|  | 488 | Ident__exception_code = Ident__exception_info = nullptr; | 
|  | 489 | Ident__abnormal_termination = Ident___exception_code = nullptr; | 
|  | 490 | Ident___exception_info = Ident___abnormal_termination = nullptr; | 
|  | 491 | Ident_GetExceptionCode = Ident_GetExceptionInfo = nullptr; | 
|  | 492 | Ident_AbnormalTermination = nullptr; | 
| John Wiegley | 1c0675e | 2011-04-28 01:08:34 +0000 | [diff] [blame] | 493 |  | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 494 | if(getLangOpts().Borland) { | 
| John Wiegley | 1c0675e | 2011-04-28 01:08:34 +0000 | [diff] [blame] | 495 | Ident__exception_info        = PP.getIdentifierInfo("_exception_info"); | 
|  | 496 | Ident___exception_info       = PP.getIdentifierInfo("__exception_info"); | 
|  | 497 | Ident_GetExceptionInfo       = PP.getIdentifierInfo("GetExceptionInformation"); | 
|  | 498 | Ident__exception_code        = PP.getIdentifierInfo("_exception_code"); | 
|  | 499 | Ident___exception_code       = PP.getIdentifierInfo("__exception_code"); | 
|  | 500 | Ident_GetExceptionCode       = PP.getIdentifierInfo("GetExceptionCode"); | 
|  | 501 | Ident__abnormal_termination  = PP.getIdentifierInfo("_abnormal_termination"); | 
|  | 502 | Ident___abnormal_termination = PP.getIdentifierInfo("__abnormal_termination"); | 
|  | 503 | Ident_AbnormalTermination    = PP.getIdentifierInfo("AbnormalTermination"); | 
|  | 504 |  | 
|  | 505 | PP.SetPoisonReason(Ident__exception_code,diag::err_seh___except_block); | 
|  | 506 | PP.SetPoisonReason(Ident___exception_code,diag::err_seh___except_block); | 
|  | 507 | PP.SetPoisonReason(Ident_GetExceptionCode,diag::err_seh___except_block); | 
|  | 508 | PP.SetPoisonReason(Ident__exception_info,diag::err_seh___except_filter); | 
|  | 509 | PP.SetPoisonReason(Ident___exception_info,diag::err_seh___except_filter); | 
|  | 510 | PP.SetPoisonReason(Ident_GetExceptionInfo,diag::err_seh___except_filter); | 
|  | 511 | PP.SetPoisonReason(Ident__abnormal_termination,diag::err_seh___finally_block); | 
|  | 512 | PP.SetPoisonReason(Ident___abnormal_termination,diag::err_seh___finally_block); | 
|  | 513 | PP.SetPoisonReason(Ident_AbnormalTermination,diag::err_seh___finally_block); | 
|  | 514 | } | 
| Douglas Gregor | d612566 | 2012-11-05 23:58:27 +0000 | [diff] [blame] | 515 |  | 
|  | 516 | Actions.Initialize(); | 
|  | 517 |  | 
|  | 518 | // Prime the lexer look-ahead. | 
|  | 519 | ConsumeToken(); | 
| Chris Lattner | 38ba336 | 2006-08-17 07:04:37 +0000 | [diff] [blame] | 520 | } | 
|  | 521 |  | 
| Reid Kleckner | 89bd8d6 | 2014-10-22 17:50:19 +0000 | [diff] [blame] | 522 | void Parser::LateTemplateParserCleanupCallback(void *P) { | 
|  | 523 | // While this RAII helper doesn't bracket any actual work, the destructor will | 
|  | 524 | // clean up annotations that were created during ActOnEndOfTranslationUnit | 
|  | 525 | // when incremental processing is enabled. | 
|  | 526 | DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(((Parser *)P)->TemplateIds); | 
|  | 527 | } | 
|  | 528 |  | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 529 | bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) { | 
| Richard Smith | e03a654 | 2017-07-05 01:42:07 +0000 | [diff] [blame] | 530 | Actions.ActOnStartOfTranslationUnit(); | 
|  | 531 |  | 
| Richard Smith | bbcc9f0 | 2016-08-26 00:14:38 +0000 | [diff] [blame] | 532 | // C11 6.9p1 says translation units must have at least one top-level | 
|  | 533 | // declaration. C++ doesn't have this restriction. We also don't want to | 
|  | 534 | // complain if we have a precompiled header, although technically if the PCH | 
|  | 535 | // is empty we should still emit the (pedantic) diagnostic. | 
|  | 536 | bool NoTopLevelDecls = ParseTopLevelDecl(Result); | 
|  | 537 | if (NoTopLevelDecls && !Actions.getASTContext().getExternalSource() && | 
|  | 538 | !getLangOpts().CPlusPlus) | 
|  | 539 | Diag(diag::ext_empty_translation_unit); | 
|  | 540 |  | 
|  | 541 | return NoTopLevelDecls; | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 542 | } | 
|  | 543 |  | 
| Chris Lattner | 38ba336 | 2006-08-17 07:04:37 +0000 | [diff] [blame] | 544 | /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the | 
|  | 545 | /// action tells us to.  This returns true if the EOF was encountered. | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 546 | bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) { | 
| Benjamin Kramer | 1e6b606 | 2012-04-14 12:14:03 +0000 | [diff] [blame] | 547 | DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); | 
| Argyrios Kyrtzidis | ee56962 | 2011-01-17 18:58:44 +0000 | [diff] [blame] | 548 |  | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 549 | // Skip over the EOF token, flagging end of previous input for incremental | 
| Axel Naumann | 2eb1d90 | 2012-03-16 10:40:17 +0000 | [diff] [blame] | 550 | // processing | 
| Argyrios Kyrtzidis | 336fcd9 | 2013-11-24 02:12:18 +0000 | [diff] [blame] | 551 | if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof)) | 
| Axel Naumann | 2eb1d90 | 2012-03-16 10:40:17 +0000 | [diff] [blame] | 552 | ConsumeToken(); | 
|  | 553 |  | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 554 | Result = nullptr; | 
| Richard Smith | ce587f5 | 2013-11-15 04:24:58 +0000 | [diff] [blame] | 555 | switch (Tok.getKind()) { | 
|  | 556 | case tok::annot_pragma_unused: | 
|  | 557 | HandlePragmaUnused(); | 
|  | 558 | return false; | 
|  | 559 |  | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 560 | case tok::kw_export: | 
|  | 561 | if (NextToken().isNot(tok::kw_module)) | 
|  | 562 | break; | 
|  | 563 | LLVM_FALLTHROUGH; | 
|  | 564 | case tok::kw_module: | 
|  | 565 | Result = ParseModuleDecl(); | 
|  | 566 | return false; | 
|  | 567 |  | 
| Richard Smith | ce587f5 | 2013-11-15 04:24:58 +0000 | [diff] [blame] | 568 | case tok::annot_module_include: | 
|  | 569 | Actions.ActOnModuleInclude(Tok.getLocation(), | 
|  | 570 | reinterpret_cast<Module *>( | 
|  | 571 | Tok.getAnnotationValue())); | 
| Richard Smith | af3b325 | 2017-05-18 19:21:48 +0000 | [diff] [blame] | 572 | ConsumeAnnotationToken(); | 
| Richard Smith | ce587f5 | 2013-11-15 04:24:58 +0000 | [diff] [blame] | 573 | return false; | 
|  | 574 |  | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 575 | case tok::annot_module_begin: | 
| Richard Smith | 4241314 | 2015-05-15 20:05:43 +0000 | [diff] [blame] | 576 | Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>( | 
|  | 577 | Tok.getAnnotationValue())); | 
| Richard Smith | af3b325 | 2017-05-18 19:21:48 +0000 | [diff] [blame] | 578 | ConsumeAnnotationToken(); | 
| Richard Smith | 4241314 | 2015-05-15 20:05:43 +0000 | [diff] [blame] | 579 | return false; | 
|  | 580 |  | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 581 | case tok::annot_module_end: | 
| Richard Smith | 4241314 | 2015-05-15 20:05:43 +0000 | [diff] [blame] | 582 | Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>( | 
|  | 583 | Tok.getAnnotationValue())); | 
| Richard Smith | af3b325 | 2017-05-18 19:21:48 +0000 | [diff] [blame] | 584 | ConsumeAnnotationToken(); | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 585 | return false; | 
|  | 586 |  | 
| Alex Lorenz | 9e7bf16 | 2017-04-18 14:33:39 +0000 | [diff] [blame] | 587 | case tok::annot_pragma_attribute: | 
|  | 588 | HandlePragmaAttribute(); | 
|  | 589 | return false; | 
|  | 590 |  | 
| Richard Smith | ce587f5 | 2013-11-15 04:24:58 +0000 | [diff] [blame] | 591 | case tok::eof: | 
| Francois Pichet | 1c229c0 | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 592 | // Late template parsing can begin. | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 593 | if (getLangOpts().DelayedTemplateParsing) | 
| Reid Kleckner | 89bd8d6 | 2014-10-22 17:50:19 +0000 | [diff] [blame] | 594 | Actions.SetLateTemplateParser(LateTemplateParserCallback, | 
|  | 595 | PP.isIncrementalProcessingEnabled() ? | 
|  | 596 | LateTemplateParserCleanupCallback : nullptr, | 
|  | 597 | this); | 
| Axel Naumann | 2eb1d90 | 2012-03-16 10:40:17 +0000 | [diff] [blame] | 598 | if (!PP.isIncrementalProcessingEnabled()) | 
|  | 599 | Actions.ActOnEndOfTranslationUnit(); | 
|  | 600 | //else don't tell Sema that we ended parsing: more input might come. | 
| Chris Lattner | f440440 | 2008-08-23 03:19:52 +0000 | [diff] [blame] | 601 | return true; | 
| Richard Smith | ce587f5 | 2013-11-15 04:24:58 +0000 | [diff] [blame] | 602 |  | 
|  | 603 | default: | 
|  | 604 | break; | 
| Chris Lattner | f440440 | 2008-08-23 03:19:52 +0000 | [diff] [blame] | 605 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 606 |  | 
| John McCall | 084e83d | 2011-03-24 11:26:52 +0000 | [diff] [blame] | 607 | ParsedAttributesWithRange attrs(AttrFactory); | 
| Richard Smith | 89645bc | 2013-01-02 12:01:23 +0000 | [diff] [blame] | 608 | MaybeParseCXX11Attributes(attrs); | 
| Axel Naumann | 2eb1d90 | 2012-03-16 10:40:17 +0000 | [diff] [blame] | 609 |  | 
| John McCall | 53fa714 | 2010-12-24 02:08:15 +0000 | [diff] [blame] | 610 | Result = ParseExternalDeclaration(attrs); | 
| Chris Lattner | 38ba336 | 2006-08-17 07:04:37 +0000 | [diff] [blame] | 611 | return false; | 
|  | 612 | } | 
|  | 613 |  | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 614 | /// ParseExternalDeclaration: | 
| Chris Lattner | 4641526 | 2008-12-08 21:59:01 +0000 | [diff] [blame] | 615 | /// | 
| Douglas Gregor | 15799fd | 2008-11-21 16:10:08 +0000 | [diff] [blame] | 616 | ///       external-declaration: [C99 6.9], declaration: [C++ dcl.dcl] | 
| Chris Lattner | cccc311 | 2007-08-10 20:57:02 +0000 | [diff] [blame] | 617 | ///         function-definition | 
|  | 618 | ///         declaration | 
| Chris Lattner | 6d7e634 | 2006-08-15 03:41:14 +0000 | [diff] [blame] | 619 | /// [GNU]   asm-definition | 
| Chris Lattner | cccc311 | 2007-08-10 20:57:02 +0000 | [diff] [blame] | 620 | /// [GNU]   __extension__ external-declaration | 
| Chris Lattner | 40f16b5 | 2006-11-05 02:05:37 +0000 | [diff] [blame] | 621 | /// [OBJC]  objc-class-definition | 
|  | 622 | /// [OBJC]  objc-class-declaration | 
|  | 623 | /// [OBJC]  objc-alias-declaration | 
|  | 624 | /// [OBJC]  objc-protocol-definition | 
|  | 625 | /// [OBJC]  objc-method-definition | 
|  | 626 | /// [OBJC]  @end | 
| Douglas Gregor | 15799fd | 2008-11-21 16:10:08 +0000 | [diff] [blame] | 627 | /// [C++]   linkage-specification | 
| Chris Lattner | 6d7e634 | 2006-08-15 03:41:14 +0000 | [diff] [blame] | 628 | /// [GNU] asm-definition: | 
|  | 629 | ///         simple-asm-expr ';' | 
| Richard Smith | 54ecd98 | 2013-02-20 19:22:51 +0000 | [diff] [blame] | 630 | /// [C++11] empty-declaration | 
|  | 631 | /// [C++11] attribute-declaration | 
| Chris Lattner | 6d7e634 | 2006-08-15 03:41:14 +0000 | [diff] [blame] | 632 | /// | 
| Richard Smith | 54ecd98 | 2013-02-20 19:22:51 +0000 | [diff] [blame] | 633 | /// [C++11] empty-declaration: | 
| Douglas Gregor | 8b9575f | 2009-08-24 12:17:54 +0000 | [diff] [blame] | 634 | ///           ';' | 
|  | 635 | /// | 
| Douglas Gregor | 43e7517 | 2009-09-04 06:33:52 +0000 | [diff] [blame] | 636 | /// [C++0x/GNU] 'extern' 'template' declaration | 
| Hamza Sood | 81fe14e | 2017-11-21 09:42:42 +0000 | [diff] [blame] | 637 | /// | 
|  | 638 | /// [Modules-TS] module-import-declaration | 
|  | 639 | /// | 
| John McCall | 53fa714 | 2010-12-24 02:08:15 +0000 | [diff] [blame] | 640 | Parser::DeclGroupPtrTy | 
|  | 641 | Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, | 
|  | 642 | ParsingDeclSpec *DS) { | 
| Benjamin Kramer | 1e6b606 | 2012-04-14 12:14:03 +0000 | [diff] [blame] | 643 | DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); | 
| Argyrios Kyrtzidis | 355094e | 2010-06-17 10:52:18 +0000 | [diff] [blame] | 644 | ParenBraceBracketBalancer BalancerRAIIObj(*this); | 
| Argyrios Kyrtzidis | 5cec2ae | 2011-09-04 03:32:15 +0000 | [diff] [blame] | 645 |  | 
|  | 646 | if (PP.isCodeCompletionReached()) { | 
|  | 647 | cutOffParsing(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 648 | return nullptr; | 
| Argyrios Kyrtzidis | 5cec2ae | 2011-09-04 03:32:15 +0000 | [diff] [blame] | 649 | } | 
|  | 650 |  | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 651 | Decl *SingleDecl = nullptr; | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 652 | switch (Tok.getKind()) { | 
| Rafael Espindola | 273fd77 | 2012-01-26 02:02:57 +0000 | [diff] [blame] | 653 | case tok::annot_pragma_vis: | 
|  | 654 | HandlePragmaVisibility(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 655 | return nullptr; | 
| Eli Friedman | ec52f92 | 2012-02-23 23:47:16 +0000 | [diff] [blame] | 656 | case tok::annot_pragma_pack: | 
|  | 657 | HandlePragmaPack(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 658 | return nullptr; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 659 | case tok::annot_pragma_msstruct: | 
|  | 660 | HandlePragmaMSStruct(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 661 | return nullptr; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 662 | case tok::annot_pragma_align: | 
|  | 663 | HandlePragmaAlign(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 664 | return nullptr; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 665 | case tok::annot_pragma_weak: | 
|  | 666 | HandlePragmaWeak(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 667 | return nullptr; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 668 | case tok::annot_pragma_weakalias: | 
|  | 669 | HandlePragmaWeakAlias(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 670 | return nullptr; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 671 | case tok::annot_pragma_redefine_extname: | 
|  | 672 | HandlePragmaRedefineExtname(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 673 | return nullptr; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 674 | case tok::annot_pragma_fp_contract: | 
|  | 675 | HandlePragmaFPContract(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 676 | return nullptr; | 
| Kevin P. Neal | 2c0bc8b | 2018-08-14 17:06:56 +0000 | [diff] [blame] | 677 | case tok::annot_pragma_fenv_access: | 
|  | 678 | HandlePragmaFEnvAccess(); | 
|  | 679 | return nullptr; | 
| Adam Nemet | 60d3264 | 2017-04-04 21:18:36 +0000 | [diff] [blame] | 680 | case tok::annot_pragma_fp: | 
|  | 681 | HandlePragmaFP(); | 
|  | 682 | break; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 683 | case tok::annot_pragma_opencl_extension: | 
|  | 684 | HandlePragmaOpenCLExtension(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 685 | return nullptr; | 
| Alexey Bataev | 587e1de | 2016-03-30 10:43:55 +0000 | [diff] [blame] | 686 | case tok::annot_pragma_openmp: { | 
|  | 687 | AccessSpecifier AS = AS_none; | 
|  | 688 | return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, attrs); | 
|  | 689 | } | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 690 | case tok::annot_pragma_ms_pointers_to_members: | 
|  | 691 | HandlePragmaMSPointersToMembers(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 692 | return nullptr; | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 693 | case tok::annot_pragma_ms_vtordisp: | 
|  | 694 | HandlePragmaMSVtorDisp(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 695 | return nullptr; | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 696 | case tok::annot_pragma_ms_pragma: | 
|  | 697 | HandlePragmaMSPragma(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 698 | return nullptr; | 
| Richard Smith | ba3a4f9 | 2016-01-12 21:59:26 +0000 | [diff] [blame] | 699 | case tok::annot_pragma_dump: | 
|  | 700 | HandlePragmaDump(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 701 | return nullptr; | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 702 | case tok::semi: | 
| Richard Smith | 54ecd98 | 2013-02-20 19:22:51 +0000 | [diff] [blame] | 703 | // Either a C++11 empty-declaration or attribute-declaration. | 
| Erich Keane | c480f30 | 2018-07-12 21:09:05 +0000 | [diff] [blame] | 704 | SingleDecl = | 
|  | 705 | Actions.ActOnEmptyDeclaration(getCurScope(), attrs, Tok.getLocation()); | 
| Richard Trieu | 2f7dc46 | 2012-05-16 19:04:59 +0000 | [diff] [blame] | 706 | ConsumeExtraSemi(OutsideFunction); | 
| Michael Han | 8432435 | 2013-02-22 17:15:32 +0000 | [diff] [blame] | 707 | break; | 
| Chris Lattner | 4641526 | 2008-12-08 21:59:01 +0000 | [diff] [blame] | 708 | case tok::r_brace: | 
| Nico Weber | e1df10a | 2012-01-17 01:04:27 +0000 | [diff] [blame] | 709 | Diag(Tok, diag::err_extraneous_closing_brace); | 
| Chris Lattner | 4641526 | 2008-12-08 21:59:01 +0000 | [diff] [blame] | 710 | ConsumeBrace(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 711 | return nullptr; | 
| Chris Lattner | 4641526 | 2008-12-08 21:59:01 +0000 | [diff] [blame] | 712 | case tok::eof: | 
|  | 713 | Diag(Tok, diag::err_expected_external_declaration); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 714 | return nullptr; | 
| Chris Lattner | cccc311 | 2007-08-10 20:57:02 +0000 | [diff] [blame] | 715 | case tok::kw___extension__: { | 
| Chris Lattner | f02ef3e | 2008-10-20 06:45:43 +0000 | [diff] [blame] | 716 | // __extension__ silences extension warnings in the subexpression. | 
|  | 717 | ExtensionRAIIObject O(Diags);  // Use RAII to do this. | 
| Chris Lattner | 1ff6e73 | 2008-10-20 06:51:33 +0000 | [diff] [blame] | 718 | ConsumeToken(); | 
| John McCall | 53fa714 | 2010-12-24 02:08:15 +0000 | [diff] [blame] | 719 | return ParseExternalDeclaration(attrs); | 
| Chris Lattner | cccc311 | 2007-08-10 20:57:02 +0000 | [diff] [blame] | 720 | } | 
| Anders Carlsson | 5c6c059 | 2008-02-08 00:33:21 +0000 | [diff] [blame] | 721 | case tok::kw_asm: { | 
| John McCall | 53fa714 | 2010-12-24 02:08:15 +0000 | [diff] [blame] | 722 | ProhibitAttributes(attrs); | 
| Alexis Hunt | 96d5c76 | 2009-11-21 08:43:09 +0000 | [diff] [blame] | 723 |  | 
| Abramo Bagnara | 348823a | 2011-03-03 14:20:18 +0000 | [diff] [blame] | 724 | SourceLocation StartLoc = Tok.getLocation(); | 
|  | 725 | SourceLocation EndLoc; | 
| Steven Wu | 6b72a67 | 2015-05-11 21:14:09 +0000 | [diff] [blame] | 726 |  | 
| Abramo Bagnara | 348823a | 2011-03-03 14:20:18 +0000 | [diff] [blame] | 727 | ExprResult Result(ParseSimpleAsm(&EndLoc)); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 728 |  | 
| Steven Wu | 18bbe19 | 2015-05-12 00:16:37 +0000 | [diff] [blame] | 729 | // Check if GNU-style InlineAsm is disabled. | 
|  | 730 | // Empty asm string is allowed because it will not introduce | 
|  | 731 | // any assembly code. | 
|  | 732 | if (!(getLangOpts().GNUAsm || Result.isInvalid())) { | 
|  | 733 | const auto *SL = cast<StringLiteral>(Result.get()); | 
|  | 734 | if (!SL->getString().trim().empty()) | 
|  | 735 | Diag(StartLoc, diag::err_gnu_inline_asm_disabled); | 
|  | 736 | } | 
|  | 737 |  | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 738 | ExpectAndConsume(tok::semi, diag::err_expected_after, | 
| Anders Carlsson | 0fae4f5 | 2008-02-08 00:23:11 +0000 | [diff] [blame] | 739 | "top-level asm block"); | 
| Anders Carlsson | 5c6c059 | 2008-02-08 00:33:21 +0000 | [diff] [blame] | 740 |  | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 741 | if (Result.isInvalid()) | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 742 | return nullptr; | 
| Abramo Bagnara | 348823a | 2011-03-03 14:20:18 +0000 | [diff] [blame] | 743 | SingleDecl = Actions.ActOnFileScopeAsmDecl(Result.get(), StartLoc, EndLoc); | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 744 | break; | 
| Anders Carlsson | 5c6c059 | 2008-02-08 00:33:21 +0000 | [diff] [blame] | 745 | } | 
| Steve Naroff | b419d3a | 2006-10-27 23:18:49 +0000 | [diff] [blame] | 746 | case tok::at: | 
| Aaron Ballman | 1c606c2 | 2018-02-12 13:38:25 +0000 | [diff] [blame] | 747 | return ParseObjCAtDirectives(attrs); | 
| Steve Naroff | b419d3a | 2006-10-27 23:18:49 +0000 | [diff] [blame] | 748 | case tok::minus: | 
| Steve Naroff | b419d3a | 2006-10-27 23:18:49 +0000 | [diff] [blame] | 749 | case tok::plus: | 
| Erik Pilkington | fa98390 | 2018-10-30 20:31:30 +0000 | [diff] [blame] | 750 | if (!getLangOpts().ObjC) { | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 751 | Diag(Tok, diag::err_expected_external_declaration); | 
|  | 752 | ConsumeToken(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 753 | return nullptr; | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 754 | } | 
|  | 755 | SingleDecl = ParseObjCMethodDefinition(); | 
|  | 756 | break; | 
| Douglas Gregor | 9d64c5e | 2009-09-21 20:51:25 +0000 | [diff] [blame] | 757 | case tok::code_completion: | 
| Alex Lorenz | b874042 | 2017-10-24 16:39:37 +0000 | [diff] [blame] | 758 | if (CurParsedObjCImpl) { | 
|  | 759 | // Code-complete Objective-C methods even without leading '-'/'+' prefix. | 
|  | 760 | Actions.CodeCompleteObjCMethodDecl(getCurScope(), | 
|  | 761 | /*IsInstanceMethod=*/None, | 
|  | 762 | /*ReturnType=*/nullptr); | 
|  | 763 | } | 
|  | 764 | Actions.CodeCompleteOrdinaryName( | 
|  | 765 | getCurScope(), | 
|  | 766 | CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace); | 
| Argyrios Kyrtzidis | 5cec2ae | 2011-09-04 03:32:15 +0000 | [diff] [blame] | 767 | cutOffParsing(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 768 | return nullptr; | 
| Hamza Sood | 81fe14e | 2017-11-21 09:42:42 +0000 | [diff] [blame] | 769 | case tok::kw_import: | 
|  | 770 | SingleDecl = ParseModuleImport(SourceLocation()); | 
|  | 771 | break; | 
| Richard Smith | 8df390f | 2016-09-08 23:14:54 +0000 | [diff] [blame] | 772 | case tok::kw_export: | 
|  | 773 | if (getLangOpts().ModulesTS) { | 
|  | 774 | SingleDecl = ParseExportDeclaration(); | 
|  | 775 | break; | 
|  | 776 | } | 
|  | 777 | // This must be 'export template'. Parse it so we can diagnose our lack | 
|  | 778 | // of support. | 
| Galina Kistanova | 27daec6 | 2017-06-03 06:29:16 +0000 | [diff] [blame] | 779 | LLVM_FALLTHROUGH; | 
| Douglas Gregor | d7c4d98 | 2008-12-30 03:27:21 +0000 | [diff] [blame] | 780 | case tok::kw_using: | 
| Chris Lattner | a523517 | 2007-08-25 06:57:03 +0000 | [diff] [blame] | 781 | case tok::kw_namespace: | 
| Chris Lattner | 302b4be | 2006-11-19 02:31:38 +0000 | [diff] [blame] | 782 | case tok::kw_typedef: | 
| Douglas Gregor | eb31f39 | 2008-12-01 23:54:00 +0000 | [diff] [blame] | 783 | case tok::kw_template: | 
| Anders Carlsson | f24fcff6 | 2009-03-11 16:27:10 +0000 | [diff] [blame] | 784 | case tok::kw_static_assert: | 
| Peter Collingbourne | 3d9cbdc | 2011-04-15 00:35:57 +0000 | [diff] [blame] | 785 | case tok::kw__Static_assert: | 
| Chad Rosier | e38c006 | 2012-04-25 22:51:41 +0000 | [diff] [blame] | 786 | // A function definition cannot start with any of these keywords. | 
| Chris Lattner | 49836b4 | 2009-04-02 04:16:50 +0000 | [diff] [blame] | 787 | { | 
|  | 788 | SourceLocation DeclEnd; | 
| Faisal Vali | 421b2d1 | 2017-12-29 05:41:00 +0000 | [diff] [blame] | 789 | return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs); | 
| Chris Lattner | 49836b4 | 2009-04-02 04:16:50 +0000 | [diff] [blame] | 790 | } | 
| Sebastian Redl | 6766794 | 2010-08-27 23:12:46 +0000 | [diff] [blame] | 791 |  | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 792 | case tok::kw_static: | 
|  | 793 | // Parse (then ignore) 'static' prior to a template instantiation. This is | 
|  | 794 | // a GCC extension that we intentionally do not support. | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 795 | if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) { | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 796 | Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) | 
|  | 797 | << 0; | 
| Sebastian Redl | 6766794 | 2010-08-27 23:12:46 +0000 | [diff] [blame] | 798 | SourceLocation DeclEnd; | 
| Faisal Vali | 421b2d1 | 2017-12-29 05:41:00 +0000 | [diff] [blame] | 799 | return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs); | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 800 | } | 
|  | 801 | goto dont_know; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 802 |  | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 803 | case tok::kw_inline: | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 804 | if (getLangOpts().CPlusPlus) { | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 805 | tok::TokenKind NextKind = NextToken().getKind(); | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 806 |  | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 807 | // Inline namespaces. Allowed as an extension even in C++03. | 
|  | 808 | if (NextKind == tok::kw_namespace) { | 
|  | 809 | SourceLocation DeclEnd; | 
| Faisal Vali | 421b2d1 | 2017-12-29 05:41:00 +0000 | [diff] [blame] | 810 | return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs); | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 811 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 812 |  | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 813 | // Parse (then ignore) 'inline' prior to a template instantiation. This is | 
|  | 814 | // a GCC extension that we intentionally do not support. | 
|  | 815 | if (NextKind == tok::kw_template) { | 
|  | 816 | Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) | 
|  | 817 | << 1; | 
|  | 818 | SourceLocation DeclEnd; | 
| Faisal Vali | 421b2d1 | 2017-12-29 05:41:00 +0000 | [diff] [blame] | 819 | return ParseDeclaration(DeclaratorContext::FileContext, DeclEnd, attrs); | 
| Douglas Gregor | aa49ecc | 2010-12-01 20:32:20 +0000 | [diff] [blame] | 820 | } | 
| Sebastian Redl | 6766794 | 2010-08-27 23:12:46 +0000 | [diff] [blame] | 821 | } | 
|  | 822 | goto dont_know; | 
|  | 823 |  | 
| Douglas Gregor | 43e7517 | 2009-09-04 06:33:52 +0000 | [diff] [blame] | 824 | case tok::kw_extern: | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 825 | if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) { | 
| Douglas Gregor | 43e7517 | 2009-09-04 06:33:52 +0000 | [diff] [blame] | 826 | // Extern templates | 
|  | 827 | SourceLocation ExternLoc = ConsumeToken(); | 
|  | 828 | SourceLocation TemplateLoc = ConsumeToken(); | 
| Richard Smith | 2bf7fdb | 2013-01-02 11:42:31 +0000 | [diff] [blame] | 829 | Diag(ExternLoc, getLangOpts().CPlusPlus11 ? | 
| Richard Smith | f411196 | 2011-10-20 18:35:58 +0000 | [diff] [blame] | 830 | diag::warn_cxx98_compat_extern_template : | 
|  | 831 | diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc); | 
| Douglas Gregor | 43e7517 | 2009-09-04 06:33:52 +0000 | [diff] [blame] | 832 | SourceLocation DeclEnd; | 
|  | 833 | return Actions.ConvertDeclToDeclGroup( | 
| Erich Keane | c480f30 | 2018-07-12 21:09:05 +0000 | [diff] [blame] | 834 | ParseExplicitInstantiation(DeclaratorContext::FileContext, ExternLoc, | 
|  | 835 | TemplateLoc, DeclEnd, attrs)); | 
| Douglas Gregor | 43e7517 | 2009-09-04 06:33:52 +0000 | [diff] [blame] | 836 | } | 
| Sebastian Redl | 6766794 | 2010-08-27 23:12:46 +0000 | [diff] [blame] | 837 | goto dont_know; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 838 |  | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 839 | case tok::kw___if_exists: | 
|  | 840 | case tok::kw___if_not_exists: | 
| Francois Pichet | 8f981d5 | 2011-05-25 10:19:49 +0000 | [diff] [blame] | 841 | ParseMicrosoftIfExistsExternalDeclaration(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 842 | return nullptr; | 
|  | 843 |  | 
| Richard Smith | bbcc9f0 | 2016-08-26 00:14:38 +0000 | [diff] [blame] | 844 | case tok::kw_module: | 
|  | 845 | Diag(Tok, diag::err_unexpected_module_decl); | 
|  | 846 | SkipUntil(tok::semi); | 
|  | 847 | return nullptr; | 
|  | 848 |  | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 849 | default: | 
| Sebastian Redl | 6766794 | 2010-08-27 23:12:46 +0000 | [diff] [blame] | 850 | dont_know: | 
| Alex Lorenz | 1be800c5 | 2017-04-19 08:58:56 +0000 | [diff] [blame] | 851 | if (Tok.isEditorPlaceholder()) { | 
|  | 852 | ConsumeToken(); | 
|  | 853 | return nullptr; | 
|  | 854 | } | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 855 | // We can't tell whether this is a function-definition or declaration yet. | 
| Rafael Espindola | db7325e | 2012-12-29 01:09:46 +0000 | [diff] [blame] | 856 | return ParseDeclarationOrFunctionDefinition(attrs, DS); | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 857 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 858 |  | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 859 | // This routine returns a DeclGroup, if the thing we parsed only contains a | 
|  | 860 | // single decl, convert it now. | 
|  | 861 | return Actions.ConvertDeclToDeclGroup(SingleDecl); | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 862 | } | 
|  | 863 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 864 | /// Determine whether the current token, if it occurs after a | 
| Douglas Gregor | 2399628 | 2009-05-12 21:31:51 +0000 | [diff] [blame] | 865 | /// declarator, continues a declaration or declaration list. | 
| Alexis Hunt | 5a7fa25 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 866 | bool Parser::isDeclarationAfterDeclarator() { | 
|  | 867 | // Check for '= delete' or '= default' | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 868 | if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) { | 
| Alexis Hunt | 5a7fa25 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 869 | const Token &KW = NextToken(); | 
|  | 870 | if (KW.is(tok::kw_default) || KW.is(tok::kw_delete)) | 
|  | 871 | return false; | 
|  | 872 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 873 |  | 
| Douglas Gregor | 2399628 | 2009-05-12 21:31:51 +0000 | [diff] [blame] | 874 | return Tok.is(tok::equal) ||      // int X()=  -> not a function def | 
|  | 875 | Tok.is(tok::comma) ||           // int X(),  -> not a function def | 
|  | 876 | Tok.is(tok::semi)  ||           // int X();  -> not a function def | 
|  | 877 | Tok.is(tok::kw_asm) ||          // int X() __asm__ -> not a function def | 
|  | 878 | Tok.is(tok::kw___attribute) ||  // int X() __attr__ -> not a function def | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 879 | (getLangOpts().CPlusPlus && | 
| Fariborz Jahanian | 8de7955 | 2012-07-05 19:34:20 +0000 | [diff] [blame] | 880 | Tok.is(tok::l_paren));         // int X(0) -> not a function def [C++] | 
| Douglas Gregor | 2399628 | 2009-05-12 21:31:51 +0000 | [diff] [blame] | 881 | } | 
|  | 882 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 883 | /// Determine whether the current token, if it occurs after a | 
| Douglas Gregor | 2399628 | 2009-05-12 21:31:51 +0000 | [diff] [blame] | 884 | /// declarator, indicates the start of a function definition. | 
| Chris Lattner | 1390134 | 2010-07-11 22:42:07 +0000 | [diff] [blame] | 885 | bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) { | 
| Abramo Bagnara | 924a8f3 | 2010-12-10 16:29:40 +0000 | [diff] [blame] | 886 | assert(Declarator.isFunctionDeclarator() && "Isn't a function declarator"); | 
| Chris Lattner | 8c56c49 | 2009-12-06 18:34:27 +0000 | [diff] [blame] | 887 | if (Tok.is(tok::l_brace))   // int X() {} | 
|  | 888 | return true; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 889 |  | 
| Chris Lattner | 1390134 | 2010-07-11 22:42:07 +0000 | [diff] [blame] | 890 | // Handle K&R C argument lists: int X(f) int f; {} | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 891 | if (!getLangOpts().CPlusPlus && | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 892 | Declarator.getFunctionTypeInfo().isKNRPrototype()) | 
| Chris Lattner | 1390134 | 2010-07-11 22:42:07 +0000 | [diff] [blame] | 893 | return isDeclarationSpecifier(); | 
| Alexis Hunt | 5a7fa25 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 894 |  | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 895 | if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) { | 
| Alexis Hunt | 5a7fa25 | 2011-05-12 06:15:49 +0000 | [diff] [blame] | 896 | const Token &KW = NextToken(); | 
|  | 897 | return KW.is(tok::kw_default) || KW.is(tok::kw_delete); | 
|  | 898 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 899 |  | 
| Chris Lattner | 8c56c49 | 2009-12-06 18:34:27 +0000 | [diff] [blame] | 900 | return Tok.is(tok::colon) ||         // X() : Base() {} (used for ctors) | 
|  | 901 | Tok.is(tok::kw_try);          // X() try { ... } | 
| Douglas Gregor | 2399628 | 2009-05-12 21:31:51 +0000 | [diff] [blame] | 902 | } | 
|  | 903 |  | 
| Nico Weber | cb7f722 | 2016-09-03 02:41:17 +0000 | [diff] [blame] | 904 | /// Parse either a function-definition or a declaration.  We can't tell which | 
|  | 905 | /// we have until we read up to the compound-statement in function-definition. | 
|  | 906 | /// TemplateParams, if non-NULL, provides the template parameters when we're | 
|  | 907 | /// parsing a C++ template-declaration. | 
| Chris Lattner | 0bb5f83 | 2006-07-31 01:59:18 +0000 | [diff] [blame] | 908 | /// | 
| Chris Lattner | 70f32b7 | 2006-07-31 05:09:04 +0000 | [diff] [blame] | 909 | ///       function-definition: [C99 6.9.1] | 
| Chris Lattner | 94fc806 | 2008-04-05 05:52:15 +0000 | [diff] [blame] | 910 | ///         decl-specs      declarator declaration-list[opt] compound-statement | 
|  | 911 | /// [C90] function-definition: [C99 6.7.1] - implicit int result | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 912 | /// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement | 
| Chris Lattner | 94fc806 | 2008-04-05 05:52:15 +0000 | [diff] [blame] | 913 | /// | 
| Chris Lattner | 70f32b7 | 2006-07-31 05:09:04 +0000 | [diff] [blame] | 914 | ///       declaration: [C99 6.7] | 
| Chris Lattner | f265939 | 2007-08-22 06:06:56 +0000 | [diff] [blame] | 915 | ///         declaration-specifiers init-declarator-list[opt] ';' | 
|  | 916 | /// [!C99]  init-declarator-list ';'                   [TODO: warn in c99 mode] | 
| Chris Lattner | 70f32b7 | 2006-07-31 05:09:04 +0000 | [diff] [blame] | 917 | /// [OMP]   threadprivate-directive                              [TODO] | 
|  | 918 | /// | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 919 | Parser::DeclGroupPtrTy | 
| Alexis Hunt | 6aa9bee | 2012-06-23 05:07:58 +0000 | [diff] [blame] | 920 | Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs, | 
|  | 921 | ParsingDeclSpec &DS, | 
|  | 922 | AccessSpecifier AS) { | 
| Nico Weber | 8452327 | 2016-09-03 02:48:03 +0000 | [diff] [blame] | 923 | MaybeParseMicrosoftAttributes(DS.getAttributes()); | 
| Chris Lattner | 70f32b7 | 2006-07-31 05:09:04 +0000 | [diff] [blame] | 924 | // Parse the common declaration-specifiers piece. | 
| Faisal Vali | a534f07 | 2018-04-26 00:42:40 +0000 | [diff] [blame] | 925 | ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, | 
| Faisal Vali | 7db85c5 | 2017-12-31 00:06:40 +0000 | [diff] [blame] | 926 | DeclSpecContext::DSC_top_level); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 927 |  | 
| Richard Smith | 404dfb4 | 2013-11-19 22:47:36 +0000 | [diff] [blame] | 928 | // If we had a free-standing type definition with a missing semicolon, we | 
|  | 929 | // may get this far before the problem becomes obvious. | 
| Faisal Vali | 7db85c5 | 2017-12-31 00:06:40 +0000 | [diff] [blame] | 930 | if (DS.hasTagDefinition() && DiagnoseMissingSemiAfterTagDefinition( | 
|  | 931 | DS, AS, DeclSpecContext::DSC_top_level)) | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 932 | return nullptr; | 
| Richard Smith | 404dfb4 | 2013-11-19 22:47:36 +0000 | [diff] [blame] | 933 |  | 
| Chris Lattner | d286488 | 2006-08-05 08:09:44 +0000 | [diff] [blame] | 934 | // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" | 
| Chris Lattner | 53361ac | 2006-08-10 05:19:57 +0000 | [diff] [blame] | 935 | // declaration-specifiers init-declarator-list[opt] ';' | 
| Chris Lattner | 0ab032a | 2007-10-09 17:23:58 +0000 | [diff] [blame] | 936 | if (Tok.is(tok::semi)) { | 
| Faisal Vali | c5089c0 | 2017-12-25 22:23:20 +0000 | [diff] [blame] | 937 | auto LengthOfTSTToken = [](DeclSpec::TST TKind) { | 
|  | 938 | assert(DeclSpec::isDeclRep(TKind)); | 
|  | 939 | switch(TKind) { | 
|  | 940 | case DeclSpec::TST_class: | 
|  | 941 | return 5; | 
|  | 942 | case DeclSpec::TST_struct: | 
|  | 943 | return 6; | 
|  | 944 | case DeclSpec::TST_union: | 
|  | 945 | return 5; | 
|  | 946 | case DeclSpec::TST_enum: | 
|  | 947 | return 4; | 
|  | 948 | case DeclSpec::TST_interface: | 
|  | 949 | return 9; | 
|  | 950 | default: | 
|  | 951 | llvm_unreachable("we only expect to get the length of the class/struct/union/enum"); | 
|  | 952 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 953 |  | 
| Faisal Vali | c5089c0 | 2017-12-25 22:23:20 +0000 | [diff] [blame] | 954 | }; | 
|  | 955 | // Suggest correct location to fix '[[attrib]] struct' to 'struct [[attrib]]' | 
|  | 956 | SourceLocation CorrectLocationForAttributes = | 
|  | 957 | DeclSpec::isDeclRep(DS.getTypeSpecType()) | 
|  | 958 | ? DS.getTypeSpecTypeLoc().getLocWithOffset( | 
|  | 959 | LengthOfTSTToken(DS.getTypeSpecType())) | 
|  | 960 | : SourceLocation(); | 
|  | 961 | ProhibitAttributes(attrs, CorrectLocationForAttributes); | 
| Chris Lattner | 0e89462 | 2006-08-13 19:58:17 +0000 | [diff] [blame] | 962 | ConsumeToken(); | 
| Nico Weber | 7b837f5 | 2016-01-28 19:25:00 +0000 | [diff] [blame] | 963 | RecordDecl *AnonRecord = nullptr; | 
|  | 964 | Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, | 
|  | 965 | DS, AnonRecord); | 
| John McCall | 28a6aea | 2009-11-04 02:18:39 +0000 | [diff] [blame] | 966 | DS.complete(TheDecl); | 
| Yaxun Liu | 5b74665 | 2016-12-18 05:18:55 +0000 | [diff] [blame] | 967 | if (getLangOpts().OpenCL) | 
|  | 968 | Actions.setCurrentOpenCLExtensionForDecl(TheDecl); | 
| Nico Weber | 7b837f5 | 2016-01-28 19:25:00 +0000 | [diff] [blame] | 969 | if (AnonRecord) { | 
|  | 970 | Decl* decls[] = {AnonRecord, TheDecl}; | 
| Richard Smith | 3beb7c6 | 2017-01-12 02:27:38 +0000 | [diff] [blame] | 971 | return Actions.BuildDeclaratorGroup(decls); | 
| Nico Weber | 7b837f5 | 2016-01-28 19:25:00 +0000 | [diff] [blame] | 972 | } | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 973 | return Actions.ConvertDeclToDeclGroup(TheDecl); | 
| Chris Lattner | 0e89462 | 2006-08-13 19:58:17 +0000 | [diff] [blame] | 974 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 975 |  | 
| Alexis Hunt | 6aa9bee | 2012-06-23 05:07:58 +0000 | [diff] [blame] | 976 | DS.takeAttributesFrom(attrs); | 
|  | 977 |  | 
| Daniel Dunbar | 26e2ab4 | 2008-09-26 04:48:09 +0000 | [diff] [blame] | 978 | // ObjC2 allows prefix attributes on class interfaces and protocols. | 
|  | 979 | // FIXME: This still needs better diagnostics. We should only accept | 
|  | 980 | // attributes here, no types, etc. | 
| Erik Pilkington | fa98390 | 2018-10-30 20:31:30 +0000 | [diff] [blame] | 981 | if (getLangOpts().ObjC && Tok.is(tok::at)) { | 
| Steve Naroff | 1eb1ad6 | 2007-08-20 21:31:48 +0000 | [diff] [blame] | 982 | SourceLocation AtLoc = ConsumeToken(); // the "@" | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 983 | if (!Tok.isObjCAtKeyword(tok::objc_interface) && | 
| Daniel Dunbar | 26e2ab4 | 2008-09-26 04:48:09 +0000 | [diff] [blame] | 984 | !Tok.isObjCAtKeyword(tok::objc_protocol)) { | 
|  | 985 | Diag(Tok, diag::err_objc_unexpected_attr); | 
| Chris Lattner | 5e530bc | 2007-12-27 19:57:00 +0000 | [diff] [blame] | 986 | SkipUntil(tok::semi); // FIXME: better skip? | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 987 | return nullptr; | 
| Chris Lattner | 5e530bc | 2007-12-27 19:57:00 +0000 | [diff] [blame] | 988 | } | 
| John McCall | d5a3632 | 2009-11-03 19:26:08 +0000 | [diff] [blame] | 989 |  | 
| John McCall | 28a6aea | 2009-11-04 02:18:39 +0000 | [diff] [blame] | 990 | DS.abort(); | 
|  | 991 |  | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 992 | const char *PrevSpec = nullptr; | 
| John McCall | 49bfce4 | 2009-08-03 20:12:06 +0000 | [diff] [blame] | 993 | unsigned DiagID; | 
| Erik Verbruggen | 888d52a | 2014-01-15 09:15:43 +0000 | [diff] [blame] | 994 | if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID, | 
|  | 995 | Actions.getASTContext().getPrintingPolicy())) | 
| John McCall | 49bfce4 | 2009-08-03 20:12:06 +0000 | [diff] [blame] | 996 | Diag(AtLoc, DiagID) << PrevSpec; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 997 |  | 
| Daniel Dunbar | 26e2ab4 | 2008-09-26 04:48:09 +0000 | [diff] [blame] | 998 | if (Tok.isObjCAtKeyword(tok::objc_protocol)) | 
| Douglas Gregor | f610267 | 2012-01-01 21:23:57 +0000 | [diff] [blame] | 999 | return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes()); | 
|  | 1000 |  | 
|  | 1001 | return Actions.ConvertDeclToDeclGroup( | 
|  | 1002 | ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes())); | 
| Steve Naroff | 1eb1ad6 | 2007-08-20 21:31:48 +0000 | [diff] [blame] | 1003 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1004 |  | 
| Chris Lattner | 38376f1 | 2008-01-12 07:05:38 +0000 | [diff] [blame] | 1005 | // If the declspec consisted only of 'extern' and we have a string | 
|  | 1006 | // literal following it, this must be a C++ linkage specifier like | 
|  | 1007 | // 'extern "C"'. | 
| Richard Smith | 4ee696d | 2014-02-17 23:25:27 +0000 | [diff] [blame] | 1008 | if (getLangOpts().CPlusPlus && isTokenStringLiteral() && | 
| Chris Lattner | 38376f1 | 2008-01-12 07:05:38 +0000 | [diff] [blame] | 1009 | DS.getStorageClassSpec() == DeclSpec::SCS_extern && | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 1010 | DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) { | 
| Faisal Vali | 421b2d1 | 2017-12-29 05:41:00 +0000 | [diff] [blame] | 1011 | Decl *TheDecl = ParseLinkage(DS, DeclaratorContext::FileContext); | 
| Chris Lattner | 5bbb3c8 | 2009-03-29 16:50:03 +0000 | [diff] [blame] | 1012 | return Actions.ConvertDeclToDeclGroup(TheDecl); | 
|  | 1013 | } | 
| Chris Lattner | 38376f1 | 2008-01-12 07:05:38 +0000 | [diff] [blame] | 1014 |  | 
| Faisal Vali | 421b2d1 | 2017-12-29 05:41:00 +0000 | [diff] [blame] | 1015 | return ParseDeclGroup(DS, DeclaratorContext::FileContext); | 
| Chris Lattner | 70f32b7 | 2006-07-31 05:09:04 +0000 | [diff] [blame] | 1016 | } | 
|  | 1017 |  | 
| Fariborz Jahanian | 26de2e5 | 2009-12-09 21:39:38 +0000 | [diff] [blame] | 1018 | Parser::DeclGroupPtrTy | 
| Alexis Hunt | 6aa9bee | 2012-06-23 05:07:58 +0000 | [diff] [blame] | 1019 | Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributesWithRange &attrs, | 
|  | 1020 | ParsingDeclSpec *DS, | 
| Fariborz Jahanian | 26de2e5 | 2009-12-09 21:39:38 +0000 | [diff] [blame] | 1021 | AccessSpecifier AS) { | 
| Alexis Hunt | 6aa9bee | 2012-06-23 05:07:58 +0000 | [diff] [blame] | 1022 | if (DS) { | 
|  | 1023 | return ParseDeclOrFunctionDefInternal(attrs, *DS, AS); | 
|  | 1024 | } else { | 
|  | 1025 | ParsingDeclSpec PDS(*this); | 
|  | 1026 | // Must temporarily exit the objective-c container scope for | 
|  | 1027 | // parsing c constructs and re-enter objc container scope | 
|  | 1028 | // afterwards. | 
|  | 1029 | ObjCDeclContextSwitch ObjCDC(*this); | 
| Nico Weber | cb7f722 | 2016-09-03 02:41:17 +0000 | [diff] [blame] | 1030 |  | 
| Alexis Hunt | 6aa9bee | 2012-06-23 05:07:58 +0000 | [diff] [blame] | 1031 | return ParseDeclOrFunctionDefInternal(attrs, PDS, AS); | 
|  | 1032 | } | 
| Fariborz Jahanian | 26de2e5 | 2009-12-09 21:39:38 +0000 | [diff] [blame] | 1033 | } | 
|  | 1034 |  | 
| Chris Lattner | fff824f | 2006-08-07 06:31:38 +0000 | [diff] [blame] | 1035 | /// ParseFunctionDefinition - We parsed and verified that the specified | 
|  | 1036 | /// Declarator is well formed.  If this is a K&R-style function, read the | 
|  | 1037 | /// parameters declaration-list, then start the compound-statement. | 
|  | 1038 | /// | 
| Chris Lattner | 94fc806 | 2008-04-05 05:52:15 +0000 | [diff] [blame] | 1039 | ///       function-definition: [C99 6.9.1] | 
|  | 1040 | ///         decl-specs      declarator declaration-list[opt] compound-statement | 
|  | 1041 | /// [C90] function-definition: [C99 6.7.1] - implicit int result | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1042 | /// [C90]   decl-specs[opt] declarator declaration-list[opt] compound-statement | 
| Douglas Gregor | e8381c0 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 1043 | /// [C++] function-definition: [C++ 8.4] | 
| Chris Lattner | efb0f11 | 2009-03-29 17:18:04 +0000 | [diff] [blame] | 1044 | ///         decl-specifier-seq[opt] declarator ctor-initializer[opt] | 
|  | 1045 | ///         function-body | 
| Douglas Gregor | e8381c0 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 1046 | /// [C++] function-definition: [C++ 8.4] | 
| Sebastian Redl | a7b98a7 | 2009-04-26 20:35:05 +0000 | [diff] [blame] | 1047 | ///         decl-specifier-seq[opt] declarator function-try-block | 
| Chris Lattner | fff824f | 2006-08-07 06:31:38 +0000 | [diff] [blame] | 1048 | /// | 
| John McCall | 4887165 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 1049 | Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, | 
| DeLesley Hutchins | 3fc6e4a | 2012-02-16 16:50:43 +0000 | [diff] [blame] | 1050 | const ParsedTemplateInfo &TemplateInfo, | 
|  | 1051 | LateParsedAttrList *LateParsedAttrs) { | 
| Nico Weber | 744cc5b | 2015-01-04 00:47:22 +0000 | [diff] [blame] | 1052 | // Poison SEH identifiers so they are flagged as illegal in function bodies. | 
| John Wiegley | 1c0675e | 2011-04-28 01:08:34 +0000 | [diff] [blame] | 1053 | PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); | 
| Abramo Bagnara | 924a8f3 | 2010-12-10 16:29:40 +0000 | [diff] [blame] | 1054 | const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1055 |  | 
| Chris Lattner | 94fc806 | 2008-04-05 05:52:15 +0000 | [diff] [blame] | 1056 | // If this is C90 and the declspecs were completely missing, fudge in an | 
|  | 1057 | // implicit int.  We do this here because this is the only place where | 
|  | 1058 | // declaration-specifiers are completely optional in the grammar. | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1059 | if (getLangOpts().ImplicitInt && D.getDeclSpec().isEmpty()) { | 
| Chris Lattner | 94fc806 | 2008-04-05 05:52:15 +0000 | [diff] [blame] | 1060 | const char *PrevSpec; | 
| John McCall | 49bfce4 | 2009-08-03 20:12:06 +0000 | [diff] [blame] | 1061 | unsigned DiagID; | 
| Erik Verbruggen | 888d52a | 2014-01-15 09:15:43 +0000 | [diff] [blame] | 1062 | const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy(); | 
| Chris Lattner | fcc390a | 2008-10-20 02:01:34 +0000 | [diff] [blame] | 1063 | D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int, | 
|  | 1064 | D.getIdentifierLoc(), | 
| Erik Verbruggen | 888d52a | 2014-01-15 09:15:43 +0000 | [diff] [blame] | 1065 | PrevSpec, DiagID, | 
|  | 1066 | Policy); | 
| Sebastian Redl | f6591ca | 2009-02-09 18:23:29 +0000 | [diff] [blame] | 1067 | D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin()); | 
| Chris Lattner | 94fc806 | 2008-04-05 05:52:15 +0000 | [diff] [blame] | 1068 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1069 |  | 
| Chris Lattner | fff824f | 2006-08-07 06:31:38 +0000 | [diff] [blame] | 1070 | // If this declaration was formed with a K&R-style identifier list for the | 
|  | 1071 | // arguments, parse declarations for all of the args next. | 
|  | 1072 | // int foo(a,b) int a; float b; {} | 
| Chris Lattner | 1390134 | 2010-07-11 22:42:07 +0000 | [diff] [blame] | 1073 | if (FTI.isKNRPrototype()) | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1074 | ParseKNRParamDeclarations(D); | 
| Chris Lattner | fff824f | 2006-08-07 06:31:38 +0000 | [diff] [blame] | 1075 |  | 
| Douglas Gregor | e8381c0 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 1076 | // We should have either an opening brace or, in a C++ constructor, | 
|  | 1077 | // we may have a colon. | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1078 | if (Tok.isNot(tok::l_brace) && | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1079 | (!getLangOpts().CPlusPlus || | 
| Alexis Hunt | 61ae8d3 | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 1080 | (Tok.isNot(tok::colon) && Tok.isNot(tok::kw_try) && | 
|  | 1081 | Tok.isNot(tok::equal)))) { | 
| Chris Lattner | 0ccd51e | 2006-08-09 05:47:47 +0000 | [diff] [blame] | 1082 | Diag(Tok, diag::err_expected_fn_body); | 
|  | 1083 |  | 
|  | 1084 | // Skip over garbage, until we get to '{'.  Don't eat the '{'. | 
| Alexey Bataev | ee6507d | 2013-11-18 08:17:37 +0000 | [diff] [blame] | 1085 | SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1086 |  | 
| Chris Lattner | 0ccd51e | 2006-08-09 05:47:47 +0000 | [diff] [blame] | 1087 | // If we didn't find the '{', bail out. | 
| Chris Lattner | 0ab032a | 2007-10-09 17:23:58 +0000 | [diff] [blame] | 1088 | if (Tok.isNot(tok::l_brace)) | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 1089 | return nullptr; | 
| Chris Lattner | 0ccd51e | 2006-08-09 05:47:47 +0000 | [diff] [blame] | 1090 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1091 |  | 
| DeLesley Hutchins | 3fc6e4a | 2012-02-16 16:50:43 +0000 | [diff] [blame] | 1092 | // Check to make sure that any normal attributes are allowed to be on | 
|  | 1093 | // a definition.  Late parsed attributes are checked at the end. | 
|  | 1094 | if (Tok.isNot(tok::equal)) { | 
| Erich Keane | e891aa9 | 2018-07-13 15:07:47 +0000 | [diff] [blame] | 1095 | for (const ParsedAttr &AL : D.getAttributes()) | 
| Erich Keane | c480f30 | 2018-07-12 21:09:05 +0000 | [diff] [blame] | 1096 | if (AL.isKnownToGCC() && !AL.isCXX11Attribute()) | 
|  | 1097 | Diag(AL.getLoc(), diag::warn_attribute_on_function_definition) | 
|  | 1098 | << AL.getName(); | 
| DeLesley Hutchins | 3fc6e4a | 2012-02-16 16:50:43 +0000 | [diff] [blame] | 1099 | } | 
|  | 1100 |  | 
| Francois Pichet | 1c229c0 | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 1101 | // In delayed template parsing mode, for function template we consume the | 
|  | 1102 | // tokens and store them for late parsing at the end of the translation unit. | 
| David Majnemer | c85ed7e | 2013-10-23 21:31:20 +0000 | [diff] [blame] | 1103 | if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) && | 
|  | 1104 | TemplateInfo.Kind == ParsedTemplateInfo::Template && | 
| Richard Smith | 8e6002f | 2014-03-12 23:14:33 +0000 | [diff] [blame] | 1105 | Actions.canDelayFunctionBody(D)) { | 
| Benjamin Kramer | cc4c49d | 2012-08-23 23:38:35 +0000 | [diff] [blame] | 1106 | MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams); | 
| Momchil Velikov | 57c681f | 2017-08-10 15:43:06 +0000 | [diff] [blame] | 1107 |  | 
|  | 1108 | ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | | 
|  | 1109 | Scope::CompoundStmtScope); | 
| Francois Pichet | 1c229c0 | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 1110 | Scope *ParentScope = getCurScope()->getParent(); | 
|  | 1111 |  | 
| Douglas Gregor | 5d1b4e3 | 2011-11-07 20:56:01 +0000 | [diff] [blame] | 1112 | D.setFunctionDefinitionKind(FDK_Definition); | 
| Francois Pichet | 1c229c0 | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 1113 | Decl *DP = Actions.HandleDeclarator(ParentScope, D, | 
| Benjamin Kramer | 62b95d8 | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 1114 | TemplateParameterLists); | 
| Francois Pichet | 1c229c0 | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 1115 | D.complete(DP); | 
|  | 1116 | D.getMutableDeclSpec().abort(); | 
|  | 1117 |  | 
| Olivier Goffart | f9e890c | 2016-06-16 21:40:06 +0000 | [diff] [blame] | 1118 | if (SkipFunctionBodies && (!DP || Actions.canSkipFunctionBody(DP)) && | 
|  | 1119 | trySkippingFunctionBody()) { | 
|  | 1120 | BodyScope.Exit(); | 
|  | 1121 | return Actions.ActOnSkippedFunctionBody(DP); | 
|  | 1122 | } | 
|  | 1123 |  | 
| Richard Smith | e40f2ba | 2013-08-07 21:41:30 +0000 | [diff] [blame] | 1124 | CachedTokens Toks; | 
|  | 1125 | LexTemplateFunctionForLateParsing(Toks); | 
| Francois Pichet | 1c229c0 | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 1126 |  | 
| Richard Smith | e40f2ba | 2013-08-07 21:41:30 +0000 | [diff] [blame] | 1127 | if (DP) { | 
| Alp Toker | a2794f9 | 2014-01-22 07:29:52 +0000 | [diff] [blame] | 1128 | FunctionDecl *FnD = DP->getAsFunction(); | 
| Richard Smith | e40f2ba | 2013-08-07 21:41:30 +0000 | [diff] [blame] | 1129 | Actions.CheckForFunctionRedefinition(FnD); | 
|  | 1130 | Actions.MarkAsLateParsedTemplate(FnD, DP, Toks); | 
| Francois Pichet | 1c229c0 | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 1131 | } | 
|  | 1132 | return DP; | 
| Alexey Bataev | 61deb4d | 2016-06-15 11:24:54 +0000 | [diff] [blame] | 1133 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1134 | else if (CurParsedObjCImpl && | 
| Alexey Bataev | 61deb4d | 2016-06-15 11:24:54 +0000 | [diff] [blame] | 1135 | !TemplateInfo.TemplateParams && | 
|  | 1136 | (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) || | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1137 | Tok.is(tok::colon)) && | 
| Alexey Bataev | 61deb4d | 2016-06-15 11:24:54 +0000 | [diff] [blame] | 1138 | Actions.CurContext->isTranslationUnit()) { | 
| Momchil Velikov | 57c681f | 2017-08-10 15:43:06 +0000 | [diff] [blame] | 1139 | ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | | 
|  | 1140 | Scope::CompoundStmtScope); | 
| Fariborz Jahanian | 712bb81 | 2012-08-10 15:54:40 +0000 | [diff] [blame] | 1141 | Scope *ParentScope = getCurScope()->getParent(); | 
| Richard Smith | 8e6002f | 2014-03-12 23:14:33 +0000 | [diff] [blame] | 1142 |  | 
| Fariborz Jahanian | 712bb81 | 2012-08-10 15:54:40 +0000 | [diff] [blame] | 1143 | D.setFunctionDefinitionKind(FDK_Definition); | 
|  | 1144 | Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D, | 
| Benjamin Kramer | cc4c49d | 2012-08-23 23:38:35 +0000 | [diff] [blame] | 1145 | MultiTemplateParamsArg()); | 
| Fariborz Jahanian | 712bb81 | 2012-08-10 15:54:40 +0000 | [diff] [blame] | 1146 | D.complete(FuncDecl); | 
|  | 1147 | D.getMutableDeclSpec().abort(); | 
|  | 1148 | if (FuncDecl) { | 
|  | 1149 | // Consume the tokens and store them for later parsing. | 
|  | 1150 | StashAwayMethodOrFunctionBodyTokens(FuncDecl); | 
|  | 1151 | CurParsedObjCImpl->HasCFunction = true; | 
|  | 1152 | return FuncDecl; | 
|  | 1153 | } | 
| Richard Smith | 8e6002f | 2014-03-12 23:14:33 +0000 | [diff] [blame] | 1154 | // FIXME: Should we really fall through here? | 
| Fariborz Jahanian | 712bb81 | 2012-08-10 15:54:40 +0000 | [diff] [blame] | 1155 | } | 
| Richard Smith | 8e6002f | 2014-03-12 23:14:33 +0000 | [diff] [blame] | 1156 |  | 
| Chris Lattner | a55a2cc | 2007-10-09 17:14:05 +0000 | [diff] [blame] | 1157 | // Enter a scope for the function body. | 
| Momchil Velikov | 57c681f | 2017-08-10 15:43:06 +0000 | [diff] [blame] | 1158 | ParseScope BodyScope(this, Scope::FnScope | Scope::DeclScope | | 
|  | 1159 | Scope::CompoundStmtScope); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1160 |  | 
| Chris Lattner | a55a2cc | 2007-10-09 17:14:05 +0000 | [diff] [blame] | 1161 | // Tell the actions module that we have entered a function definition with the | 
|  | 1162 | // specified Declarator for the function. | 
| Richard Smith | b9fa996 | 2015-08-21 03:04:33 +0000 | [diff] [blame] | 1163 | Sema::SkipBodyInfo SkipBody; | 
|  | 1164 | Decl *Res = Actions.ActOnStartOfFunctionDef(getCurScope(), D, | 
|  | 1165 | TemplateInfo.TemplateParams | 
|  | 1166 | ? *TemplateInfo.TemplateParams | 
|  | 1167 | : MultiTemplateParamsArg(), | 
|  | 1168 | &SkipBody); | 
|  | 1169 |  | 
|  | 1170 | if (SkipBody.ShouldSkip) { | 
|  | 1171 | SkipFunctionBody(); | 
|  | 1172 | return Res; | 
|  | 1173 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1174 |  | 
| John McCall | 28a6aea | 2009-11-04 02:18:39 +0000 | [diff] [blame] | 1175 | // Break out of the ParsingDeclarator context before we parse the body. | 
|  | 1176 | D.complete(Res); | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1177 |  | 
| John McCall | 28a6aea | 2009-11-04 02:18:39 +0000 | [diff] [blame] | 1178 | // Break out of the ParsingDeclSpec context, too.  This const_cast is | 
|  | 1179 | // safe because we're always the sole owner. | 
|  | 1180 | D.getMutableDeclSpec().abort(); | 
|  | 1181 |  | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 1182 | if (TryConsumeToken(tok::equal)) { | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1183 | assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='"); | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 1184 |  | 
| Alexis Hunt | 61ae8d3 | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 1185 | bool Delete = false; | 
|  | 1186 | SourceLocation KWLoc; | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 1187 | if (TryConsumeToken(tok::kw_delete, KWLoc)) { | 
|  | 1188 | Diag(KWLoc, getLangOpts().CPlusPlus11 | 
| Craig Topper | 54a6a68 | 2015-11-14 18:16:08 +0000 | [diff] [blame] | 1189 | ? diag::warn_cxx98_compat_defaulted_deleted_function | 
|  | 1190 | : diag::ext_defaulted_deleted_function) | 
|  | 1191 | << 1 /* deleted */; | 
| Alexis Hunt | 61ae8d3 | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 1192 | Actions.SetDeclDeleted(Res, KWLoc); | 
|  | 1193 | Delete = true; | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 1194 | } else if (TryConsumeToken(tok::kw_default, KWLoc)) { | 
|  | 1195 | Diag(KWLoc, getLangOpts().CPlusPlus11 | 
| Craig Topper | 54a6a68 | 2015-11-14 18:16:08 +0000 | [diff] [blame] | 1196 | ? diag::warn_cxx98_compat_defaulted_deleted_function | 
|  | 1197 | : diag::ext_defaulted_deleted_function) | 
|  | 1198 | << 0 /* defaulted */; | 
| Alexis Hunt | 61ae8d3 | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 1199 | Actions.SetDeclDefaulted(Res, KWLoc); | 
|  | 1200 | } else { | 
|  | 1201 | llvm_unreachable("function definition after = not 'delete' or 'default'"); | 
|  | 1202 | } | 
|  | 1203 |  | 
|  | 1204 | if (Tok.is(tok::comma)) { | 
|  | 1205 | Diag(KWLoc, diag::err_default_delete_in_multiple_declaration) | 
|  | 1206 | << Delete; | 
|  | 1207 | SkipUntil(tok::semi); | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 1208 | } else if (ExpectAndConsume(tok::semi, diag::err_expected_after, | 
|  | 1209 | Delete ? "delete" : "default")) { | 
|  | 1210 | SkipUntil(tok::semi); | 
| Alexis Hunt | 61ae8d3 | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 1211 | } | 
|  | 1212 |  | 
| Benjamin Kramer | 8610cae | 2015-03-12 14:28:47 +0000 | [diff] [blame] | 1213 | Stmt *GeneratedBody = Res ? Res->getBody() : nullptr; | 
|  | 1214 | Actions.ActOnFinishFunctionBody(Res, GeneratedBody, false); | 
| Alexis Hunt | 61ae8d3 | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 1215 | return Res; | 
|  | 1216 | } | 
|  | 1217 |  | 
| Olivier Goffart | f9e890c | 2016-06-16 21:40:06 +0000 | [diff] [blame] | 1218 | if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) && | 
|  | 1219 | trySkippingFunctionBody()) { | 
|  | 1220 | BodyScope.Exit(); | 
|  | 1221 | Actions.ActOnSkippedFunctionBody(Res); | 
|  | 1222 | return Actions.ActOnFinishFunctionBody(Res, nullptr, false); | 
|  | 1223 | } | 
|  | 1224 |  | 
| Sebastian Redl | a7b98a7 | 2009-04-26 20:35:05 +0000 | [diff] [blame] | 1225 | if (Tok.is(tok::kw_try)) | 
| Douglas Gregor | a0ff0c3 | 2011-03-16 17:05:57 +0000 | [diff] [blame] | 1226 | return ParseFunctionTryBlock(Res, BodyScope); | 
| Sebastian Redl | a7b98a7 | 2009-04-26 20:35:05 +0000 | [diff] [blame] | 1227 |  | 
| Douglas Gregor | e8381c0 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 1228 | // If we have a colon, then we're probably parsing a C++ | 
|  | 1229 | // ctor-initializer. | 
| John McCall | bb7b658 | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 1230 | if (Tok.is(tok::colon)) { | 
| Douglas Gregor | e8381c0 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 1231 | ParseConstructorInitializer(Res); | 
| John McCall | bb7b658 | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 1232 |  | 
|  | 1233 | // Recover from error. | 
|  | 1234 | if (!Tok.is(tok::l_brace)) { | 
| Douglas Gregor | a0ff0c3 | 2011-03-16 17:05:57 +0000 | [diff] [blame] | 1235 | BodyScope.Exit(); | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 1236 | Actions.ActOnFinishFunctionBody(Res, nullptr); | 
| John McCall | bb7b658 | 2010-04-10 07:37:23 +0000 | [diff] [blame] | 1237 | return Res; | 
|  | 1238 | } | 
|  | 1239 | } else | 
| Fariborz Jahanian | aee31ac | 2009-07-21 22:36:06 +0000 | [diff] [blame] | 1240 | Actions.ActOnDefaultCtorInitializers(Res); | 
| Douglas Gregor | e8381c0 | 2008-11-05 04:29:56 +0000 | [diff] [blame] | 1241 |  | 
| DeLesley Hutchins | 3fc6e4a | 2012-02-16 16:50:43 +0000 | [diff] [blame] | 1242 | // Late attributes are parsed in the same scope as the function body. | 
|  | 1243 | if (LateParsedAttrs) | 
|  | 1244 | ParseLexedAttributeList(*LateParsedAttrs, Res, false, true); | 
|  | 1245 |  | 
| Douglas Gregor | a0ff0c3 | 2011-03-16 17:05:57 +0000 | [diff] [blame] | 1246 | return ParseFunctionStatementBody(Res, BodyScope); | 
| Chris Lattner | fff824f | 2006-08-07 06:31:38 +0000 | [diff] [blame] | 1247 | } | 
|  | 1248 |  | 
| Richard Smith | b9fa996 | 2015-08-21 03:04:33 +0000 | [diff] [blame] | 1249 | void Parser::SkipFunctionBody() { | 
|  | 1250 | if (Tok.is(tok::equal)) { | 
|  | 1251 | SkipUntil(tok::semi); | 
|  | 1252 | return; | 
|  | 1253 | } | 
|  | 1254 |  | 
|  | 1255 | bool IsFunctionTryBlock = Tok.is(tok::kw_try); | 
|  | 1256 | if (IsFunctionTryBlock) | 
|  | 1257 | ConsumeToken(); | 
|  | 1258 |  | 
|  | 1259 | CachedTokens Skipped; | 
|  | 1260 | if (ConsumeAndStoreFunctionPrologue(Skipped)) | 
|  | 1261 | SkipMalformedDecl(); | 
|  | 1262 | else { | 
|  | 1263 | SkipUntil(tok::r_brace); | 
|  | 1264 | while (IsFunctionTryBlock && Tok.is(tok::kw_catch)) { | 
|  | 1265 | SkipUntil(tok::l_brace); | 
|  | 1266 | SkipUntil(tok::r_brace); | 
|  | 1267 | } | 
|  | 1268 | } | 
|  | 1269 | } | 
|  | 1270 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1271 | /// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides | 
|  | 1272 | /// types for a function with a K&R-style identifier list for arguments. | 
|  | 1273 | void Parser::ParseKNRParamDeclarations(Declarator &D) { | 
|  | 1274 | // We know that the top-level of this declarator is a function. | 
| Abramo Bagnara | 924a8f3 | 2010-12-10 16:29:40 +0000 | [diff] [blame] | 1275 | DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1276 |  | 
| Chris Lattner | aa9c7ae | 2008-04-08 04:40:51 +0000 | [diff] [blame] | 1277 | // Enter function-declaration scope, limiting any declarators to the | 
|  | 1278 | // function prototype scope, including parameter declarators. | 
| Richard Smith | e233fbf | 2013-01-28 22:42:45 +0000 | [diff] [blame] | 1279 | ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope | | 
|  | 1280 | Scope::FunctionDeclarationScope | Scope::DeclScope); | 
| Chris Lattner | aa9c7ae | 2008-04-08 04:40:51 +0000 | [diff] [blame] | 1281 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1282 | // Read all the argument declarations. | 
|  | 1283 | while (isDeclarationSpecifier()) { | 
|  | 1284 | SourceLocation DSStart = Tok.getLocation(); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1285 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1286 | // Parse the common declaration-specifiers piece. | 
| John McCall | 084e83d | 2011-03-24 11:26:52 +0000 | [diff] [blame] | 1287 | DeclSpec DS(AttrFactory); | 
| Faisal Vali | a534f07 | 2018-04-26 00:42:40 +0000 | [diff] [blame] | 1288 | ParseDeclarationSpecifiers(DS); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1289 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1290 | // C99 6.9.1p6: 'each declaration in the declaration list shall have at | 
|  | 1291 | // least one declarator'. | 
|  | 1292 | // NOTE: GCC just makes this an ext-warn.  It's not clear what it does with | 
|  | 1293 | // the declarations though.  It's trivial to ignore them, really hard to do | 
|  | 1294 | // anything else with them. | 
| Alp Toker | 094e521 | 2014-01-05 03:27:11 +0000 | [diff] [blame] | 1295 | if (TryConsumeToken(tok::semi)) { | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1296 | Diag(DSStart, diag::err_declaration_does_not_declare_param); | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1297 | continue; | 
|  | 1298 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1299 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1300 | // C99 6.9.1p6: Declarations shall contain no storage-class specifiers other | 
|  | 1301 | // than register. | 
|  | 1302 | if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified && | 
|  | 1303 | DS.getStorageClassSpec() != DeclSpec::SCS_register) { | 
|  | 1304 | Diag(DS.getStorageClassSpecLoc(), | 
|  | 1305 | diag::err_invalid_storage_class_in_func_decl); | 
|  | 1306 | DS.ClearStorageClassSpecs(); | 
|  | 1307 | } | 
| Richard Smith | b4a9e86 | 2013-04-12 22:46:28 +0000 | [diff] [blame] | 1308 | if (DS.getThreadStorageClassSpec() != DeclSpec::TSCS_unspecified) { | 
|  | 1309 | Diag(DS.getThreadStorageClassSpecLoc(), | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1310 | diag::err_invalid_storage_class_in_func_decl); | 
|  | 1311 | DS.ClearStorageClassSpecs(); | 
|  | 1312 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1313 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1314 | // Parse the first declarator attached to this declspec. | 
| Faisal Vali | 421b2d1 | 2017-12-29 05:41:00 +0000 | [diff] [blame] | 1315 | Declarator ParmDeclarator(DS, DeclaratorContext::KNRTypeListContext); | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1316 | ParseDeclarator(ParmDeclarator); | 
|  | 1317 |  | 
|  | 1318 | // Handle the full declarator list. | 
|  | 1319 | while (1) { | 
|  | 1320 | // If attributes are present, parse them. | 
| John McCall | 53fa714 | 2010-12-24 02:08:15 +0000 | [diff] [blame] | 1321 | MaybeParseGNUAttributes(ParmDeclarator); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1322 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1323 | // Ask the actions module to compute the type for this declarator. | 
| John McCall | 4887165 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 1324 | Decl *Param = | 
| Douglas Gregor | 0be31a2 | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 1325 | Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator); | 
| Manuel Klimek | 2fdbea2 | 2013-08-22 12:12:24 +0000 | [diff] [blame] | 1326 |  | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1327 | if (Param && | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1328 | // A missing identifier has already been diagnosed. | 
|  | 1329 | ParmDeclarator.getIdentifier()) { | 
|  | 1330 |  | 
|  | 1331 | // Scan the argument list looking for the correct param to apply this | 
|  | 1332 | // type. | 
|  | 1333 | for (unsigned i = 0; ; ++i) { | 
|  | 1334 | // C99 6.9.1p6: those declarators shall declare only identifiers from | 
|  | 1335 | // the identifier list. | 
| Alp Toker | c535072 | 2014-02-26 22:27:52 +0000 | [diff] [blame] | 1336 | if (i == FTI.NumParams) { | 
| Chris Lattner | 6d29c10 | 2008-11-18 07:48:38 +0000 | [diff] [blame] | 1337 | Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param) | 
| Chris Lattner | 760d19ad | 2008-11-19 07:51:13 +0000 | [diff] [blame] | 1338 | << ParmDeclarator.getIdentifier(); | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1339 | break; | 
|  | 1340 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1341 |  | 
| Alp Toker | c535072 | 2014-02-26 22:27:52 +0000 | [diff] [blame] | 1342 | if (FTI.Params[i].Ident == ParmDeclarator.getIdentifier()) { | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1343 | // Reject redefinitions of parameters. | 
| Alp Toker | c535072 | 2014-02-26 22:27:52 +0000 | [diff] [blame] | 1344 | if (FTI.Params[i].Param) { | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1345 | Diag(ParmDeclarator.getIdentifierLoc(), | 
| Chris Lattner | 6d29c10 | 2008-11-18 07:48:38 +0000 | [diff] [blame] | 1346 | diag::err_param_redefinition) | 
| Chris Lattner | 760d19ad | 2008-11-19 07:51:13 +0000 | [diff] [blame] | 1347 | << ParmDeclarator.getIdentifier(); | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1348 | } else { | 
| Alp Toker | c535072 | 2014-02-26 22:27:52 +0000 | [diff] [blame] | 1349 | FTI.Params[i].Param = Param; | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1350 | } | 
|  | 1351 | break; | 
|  | 1352 | } | 
|  | 1353 | } | 
|  | 1354 | } | 
|  | 1355 |  | 
|  | 1356 | // If we don't have a comma, it is either the end of the list (a ';') or | 
|  | 1357 | // an error, bail out. | 
| Chris Lattner | 0ab032a | 2007-10-09 17:23:58 +0000 | [diff] [blame] | 1358 | if (Tok.isNot(tok::comma)) | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1359 | break; | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1360 |  | 
| Richard Smith | 8d06f42 | 2012-01-12 23:53:29 +0000 | [diff] [blame] | 1361 | ParmDeclarator.clear(); | 
|  | 1362 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1363 | // Consume the comma. | 
| Richard Smith | 8d06f42 | 2012-01-12 23:53:29 +0000 | [diff] [blame] | 1364 | ParmDeclarator.setCommaLoc(ConsumeToken()); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1365 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1366 | // Parse the next declarator. | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1367 | ParseDeclarator(ParmDeclarator); | 
|  | 1368 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1369 |  | 
| Alp Toker | c090ae7 | 2014-01-05 04:17:27 +0000 | [diff] [blame] | 1370 | // Consume ';' and continue parsing. | 
|  | 1371 | if (!ExpectAndConsumeSemi(diag::err_expected_semi_declaration)) | 
|  | 1372 | continue; | 
|  | 1373 |  | 
|  | 1374 | // Otherwise recover by skipping to next semi or mandatory function body. | 
|  | 1375 | if (SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch)) | 
|  | 1376 | break; | 
|  | 1377 | TryConsumeToken(tok::semi); | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1378 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1379 |  | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1380 | // The actions module must verify that all arguments were declared. | 
| Douglas Gregor | 0be31a2 | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 1381 | Actions.ActOnFinishKNRParamDeclarations(getCurScope(), D, Tok.getLocation()); | 
| Chris Lattner | 5c5fbcc | 2006-12-03 08:41:30 +0000 | [diff] [blame] | 1382 | } | 
|  | 1383 |  | 
|  | 1384 |  | 
| Chris Lattner | 0116c47 | 2006-08-15 06:03:28 +0000 | [diff] [blame] | 1385 | /// ParseAsmStringLiteral - This is just a normal string-literal, but is not | 
|  | 1386 | /// allowed to be a wide string, and is not subject to character translation. | 
|  | 1387 | /// | 
|  | 1388 | /// [GNU] asm-string-literal: | 
|  | 1389 | ///         string-literal | 
|  | 1390 | /// | 
| Craig Topper | 9ad7e26 | 2014-10-31 06:57:07 +0000 | [diff] [blame] | 1391 | ExprResult Parser::ParseAsmStringLiteral() { | 
| David Majnemer | b3e96f7 | 2014-12-11 01:00:48 +0000 | [diff] [blame] | 1392 | if (!isTokenStringLiteral()) { | 
|  | 1393 | Diag(Tok, diag::err_expected_string_literal) | 
|  | 1394 | << /*Source='in...'*/0 << "'asm'"; | 
|  | 1395 | return ExprError(); | 
| Chris Lattner | 0116c47 | 2006-08-15 06:03:28 +0000 | [diff] [blame] | 1396 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1397 |  | 
| David Majnemer | b3e96f7 | 2014-12-11 01:00:48 +0000 | [diff] [blame] | 1398 | ExprResult AsmString(ParseStringLiteralExpression()); | 
|  | 1399 | if (!AsmString.isInvalid()) { | 
|  | 1400 | const auto *SL = cast<StringLiteral>(AsmString.get()); | 
|  | 1401 | if (!SL->isAscii()) { | 
|  | 1402 | Diag(Tok, diag::err_asm_operand_wide_string_literal) | 
|  | 1403 | << SL->isWide() | 
|  | 1404 | << SL->getSourceRange(); | 
|  | 1405 | return ExprError(); | 
|  | 1406 | } | 
|  | 1407 | } | 
|  | 1408 | return AsmString; | 
| Chris Lattner | 0116c47 | 2006-08-15 06:03:28 +0000 | [diff] [blame] | 1409 | } | 
|  | 1410 |  | 
| Chris Lattner | 6d7e634 | 2006-08-15 03:41:14 +0000 | [diff] [blame] | 1411 | /// ParseSimpleAsm | 
|  | 1412 | /// | 
|  | 1413 | /// [GNU] simple-asm-expr: | 
|  | 1414 | ///         'asm' '(' asm-string-literal ')' | 
| Chris Lattner | 6d7e634 | 2006-08-15 03:41:14 +0000 | [diff] [blame] | 1415 | /// | 
| Craig Topper | 9ad7e26 | 2014-10-31 06:57:07 +0000 | [diff] [blame] | 1416 | ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { | 
| Chris Lattner | 0ab032a | 2007-10-09 17:23:58 +0000 | [diff] [blame] | 1417 | assert(Tok.is(tok::kw_asm) && "Not an asm!"); | 
| Anders Carlsson | 5c6c059 | 2008-02-08 00:33:21 +0000 | [diff] [blame] | 1418 | SourceLocation Loc = ConsumeToken(); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1419 |  | 
| John McCall | 9dfb162 | 2010-01-25 22:27:48 +0000 | [diff] [blame] | 1420 | if (Tok.is(tok::kw_volatile)) { | 
| John McCall | 5cb5287 | 2010-01-25 23:12:50 +0000 | [diff] [blame] | 1421 | // Remove from the end of 'asm' to the end of 'volatile'. | 
|  | 1422 | SourceRange RemovalRange(PP.getLocForEndOfToken(Loc), | 
|  | 1423 | PP.getLocForEndOfToken(Tok.getLocation())); | 
|  | 1424 |  | 
|  | 1425 | Diag(Tok, diag::warn_file_asm_volatile) | 
| Douglas Gregor | a771f46 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 1426 | << FixItHint::CreateRemoval(RemovalRange); | 
| John McCall | 9dfb162 | 2010-01-25 22:27:48 +0000 | [diff] [blame] | 1427 | ConsumeToken(); | 
|  | 1428 | } | 
|  | 1429 |  | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 1430 | BalancedDelimiterTracker T(*this, tok::l_paren); | 
|  | 1431 | if (T.consumeOpen()) { | 
| Chris Lattner | 6d29c10 | 2008-11-18 07:48:38 +0000 | [diff] [blame] | 1432 | Diag(Tok, diag::err_expected_lparen_after) << "asm"; | 
| Sebastian Redl | 042ad95 | 2008-12-11 19:30:53 +0000 | [diff] [blame] | 1433 | return ExprError(); | 
| Chris Lattner | 6d7e634 | 2006-08-15 03:41:14 +0000 | [diff] [blame] | 1434 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1435 |  | 
| John McCall | dadc575 | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 1436 | ExprResult Result(ParseAsmStringLiteral()); | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1437 |  | 
| Justin Bogner | ab403f4 | 2013-12-10 21:29:48 +0000 | [diff] [blame] | 1438 | if (!Result.isInvalid()) { | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 1439 | // Close the paren and get the location of the end bracket | 
|  | 1440 | T.consumeClose(); | 
| Sebastian Redl | f6591ca | 2009-02-09 18:23:29 +0000 | [diff] [blame] | 1441 | if (EndLoc) | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 1442 | *EndLoc = T.getCloseLocation(); | 
| Justin Bogner | ab403f4 | 2013-12-10 21:29:48 +0000 | [diff] [blame] | 1443 | } else if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) { | 
|  | 1444 | if (EndLoc) | 
|  | 1445 | *EndLoc = Tok.getLocation(); | 
|  | 1446 | ConsumeParen(); | 
| Sebastian Redl | f6591ca | 2009-02-09 18:23:29 +0000 | [diff] [blame] | 1447 | } | 
| Mike Stump | 01e0765 | 2008-06-19 19:28:49 +0000 | [diff] [blame] | 1448 |  | 
| Benjamin Kramer | 62b95d8 | 2012-08-23 21:35:17 +0000 | [diff] [blame] | 1449 | return Result; | 
| Chris Lattner | 6d7e634 | 2006-08-15 03:41:14 +0000 | [diff] [blame] | 1450 | } | 
| Steve Naroff | b419d3a | 2006-10-27 23:18:49 +0000 | [diff] [blame] | 1451 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1452 | /// Get the TemplateIdAnnotation from the token and put it in the | 
| Argyrios Kyrtzidis | c0c5dd2 | 2011-06-22 06:09:49 +0000 | [diff] [blame] | 1453 | /// cleanup pool so that it gets destroyed when parsing the current top level | 
|  | 1454 | /// declaration is finished. | 
|  | 1455 | TemplateIdAnnotation *Parser::takeTemplateIdAnnotation(const Token &tok) { | 
|  | 1456 | assert(tok.is(tok::annot_template_id) && "Expected template-id token"); | 
|  | 1457 | TemplateIdAnnotation * | 
|  | 1458 | Id = static_cast<TemplateIdAnnotation *>(tok.getAnnotationValue()); | 
| Argyrios Kyrtzidis | c0c5dd2 | 2011-06-22 06:09:49 +0000 | [diff] [blame] | 1459 | return Id; | 
|  | 1460 | } | 
|  | 1461 |  | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1462 | void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) { | 
|  | 1463 | // Push the current token back into the token stream (or revert it if it is | 
|  | 1464 | // cached) and use an annotation scope token for current token. | 
|  | 1465 | if (PP.isBacktrackEnabled()) | 
|  | 1466 | PP.RevertCachedTokens(1); | 
|  | 1467 | else | 
|  | 1468 | PP.EnterToken(Tok); | 
|  | 1469 | Tok.setKind(tok::annot_cxxscope); | 
|  | 1470 | Tok.setAnnotationValue(Actions.SaveNestedNameSpecifierAnnotation(SS)); | 
|  | 1471 | Tok.setAnnotationRange(SS.getRange()); | 
|  | 1472 |  | 
|  | 1473 | // In case the tokens were cached, have Preprocessor replace them | 
|  | 1474 | // with the annotation token.  We don't need to do this if we've | 
|  | 1475 | // just reverted back to a prior state. | 
|  | 1476 | if (IsNewAnnotation) | 
|  | 1477 | PP.AnnotateCachedTokens(Tok); | 
|  | 1478 | } | 
|  | 1479 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1480 | /// Attempt to classify the name at the current token position. This may | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1481 | /// form a type, scope or primary expression annotation, or replace the token | 
|  | 1482 | /// with a typo-corrected keyword. This is only appropriate when the current | 
|  | 1483 | /// name must refer to an entity which has already been declared. | 
|  | 1484 | /// | 
|  | 1485 | /// \param IsAddressOfOperand Must be \c true if the name is preceded by an '&' | 
|  | 1486 | ///        and might possibly have a dependent nested name specifier. | 
|  | 1487 | /// \param CCC Indicates how to perform typo-correction for this name. If NULL, | 
|  | 1488 | ///        no typo correction will be performed. | 
|  | 1489 | Parser::AnnotatedNameKind | 
|  | 1490 | Parser::TryAnnotateName(bool IsAddressOfOperand, | 
| Kaelyn Takata | 89c881b | 2014-10-27 18:07:29 +0000 | [diff] [blame] | 1491 | std::unique_ptr<CorrectionCandidateCallback> CCC) { | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1492 | assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope)); | 
|  | 1493 |  | 
|  | 1494 | const bool EnteringContext = false; | 
|  | 1495 | const bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope); | 
|  | 1496 |  | 
|  | 1497 | CXXScopeSpec SS; | 
|  | 1498 | if (getLangOpts().CPlusPlus && | 
| David Blaikie | efdccaa | 2016-01-15 23:43:34 +0000 | [diff] [blame] | 1499 | ParseOptionalCXXScopeSpecifier(SS, nullptr, EnteringContext)) | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1500 | return ANK_Error; | 
|  | 1501 |  | 
|  | 1502 | if (Tok.isNot(tok::identifier) || SS.isInvalid()) { | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1503 | if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation)) | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1504 | return ANK_Error; | 
|  | 1505 | return ANK_Unresolved; | 
|  | 1506 | } | 
|  | 1507 |  | 
|  | 1508 | IdentifierInfo *Name = Tok.getIdentifierInfo(); | 
|  | 1509 | SourceLocation NameLoc = Tok.getLocation(); | 
|  | 1510 |  | 
|  | 1511 | // FIXME: Move the tentative declaration logic into ClassifyName so we can | 
|  | 1512 | // typo-correct to tentatively-declared identifiers. | 
|  | 1513 | if (isTentativelyDeclared(Name)) { | 
|  | 1514 | // Identifier has been tentatively declared, and thus cannot be resolved as | 
|  | 1515 | // an expression. Fall back to annotating it as a type. | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1516 | if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation)) | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1517 | return ANK_Error; | 
|  | 1518 | return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl; | 
|  | 1519 | } | 
|  | 1520 |  | 
|  | 1521 | Token Next = NextToken(); | 
|  | 1522 |  | 
|  | 1523 | // Look up and classify the identifier. We don't perform any typo-correction | 
|  | 1524 | // after a scope specifier, because in general we can't recover from typos | 
| Alp Toker | b164a34 | 2013-12-17 17:25:19 +0000 | [diff] [blame] | 1525 | // there (eg, after correcting 'A::tempalte B<X>::C' [sic], we would need to | 
|  | 1526 | // jump back into scope specifier parsing). | 
| Kaelyn Takata | 89c881b | 2014-10-27 18:07:29 +0000 | [diff] [blame] | 1527 | Sema::NameClassification Classification = Actions.ClassifyName( | 
|  | 1528 | getCurScope(), SS, Name, NameLoc, Next, IsAddressOfOperand, | 
|  | 1529 | SS.isEmpty() ? std::move(CCC) : nullptr); | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1530 |  | 
|  | 1531 | switch (Classification.getKind()) { | 
|  | 1532 | case Sema::NC_Error: | 
|  | 1533 | return ANK_Error; | 
|  | 1534 |  | 
|  | 1535 | case Sema::NC_Keyword: | 
|  | 1536 | // The identifier was typo-corrected to a keyword. | 
|  | 1537 | Tok.setIdentifierInfo(Name); | 
|  | 1538 | Tok.setKind(Name->getTokenID()); | 
|  | 1539 | PP.TypoCorrectToken(Tok); | 
|  | 1540 | if (SS.isNotEmpty()) | 
|  | 1541 | AnnotateScopeToken(SS, !WasScopeAnnotation); | 
|  | 1542 | // We've "annotated" this as a keyword. | 
|  | 1543 | return ANK_Success; | 
|  | 1544 |  | 
|  | 1545 | case Sema::NC_Unknown: | 
|  | 1546 | // It's not something we know about. Leave it unannotated. | 
|  | 1547 | break; | 
|  | 1548 |  | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1549 | case Sema::NC_Type: { | 
|  | 1550 | SourceLocation BeginLoc = NameLoc; | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1551 | if (SS.isNotEmpty()) | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1552 | BeginLoc = SS.getBeginLoc(); | 
|  | 1553 |  | 
|  | 1554 | /// An Objective-C object type followed by '<' is a specialization of | 
|  | 1555 | /// a parameterized class type or a protocol-qualified type. | 
|  | 1556 | ParsedType Ty = Classification.getType(); | 
| Erik Pilkington | fa98390 | 2018-10-30 20:31:30 +0000 | [diff] [blame] | 1557 | if (getLangOpts().ObjC && NextToken().is(tok::less) && | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1558 | (Ty.get()->isObjCObjectType() || | 
|  | 1559 | Ty.get()->isObjCObjectPointerType())) { | 
|  | 1560 | // Consume the name. | 
|  | 1561 | SourceLocation IdentifierLoc = ConsumeToken(); | 
|  | 1562 | SourceLocation NewEndLoc; | 
|  | 1563 | TypeResult NewType | 
|  | 1564 | = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty, | 
|  | 1565 | /*consumeLastToken=*/false, | 
|  | 1566 | NewEndLoc); | 
|  | 1567 | if (NewType.isUsable()) | 
|  | 1568 | Ty = NewType.get(); | 
| Bruno Cardoso Lopes | 218c874 | 2016-09-13 20:04:35 +0000 | [diff] [blame] | 1569 | else if (Tok.is(tok::eof)) // Nothing to do here, bail out... | 
|  | 1570 | return ANK_Error; | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1571 | } | 
|  | 1572 |  | 
|  | 1573 | Tok.setKind(tok::annot_typename); | 
|  | 1574 | setTypeAnnotation(Tok, Ty); | 
|  | 1575 | Tok.setAnnotationEndLoc(Tok.getLocation()); | 
|  | 1576 | Tok.setLocation(BeginLoc); | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1577 | PP.AnnotateCachedTokens(Tok); | 
|  | 1578 | return ANK_Success; | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1579 | } | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1580 |  | 
|  | 1581 | case Sema::NC_Expression: | 
|  | 1582 | Tok.setKind(tok::annot_primary_expr); | 
|  | 1583 | setExprAnnotation(Tok, Classification.getExpression()); | 
|  | 1584 | Tok.setAnnotationEndLoc(NameLoc); | 
|  | 1585 | if (SS.isNotEmpty()) | 
|  | 1586 | Tok.setLocation(SS.getBeginLoc()); | 
|  | 1587 | PP.AnnotateCachedTokens(Tok); | 
|  | 1588 | return ANK_Success; | 
|  | 1589 |  | 
|  | 1590 | case Sema::NC_TypeTemplate: | 
|  | 1591 | if (Next.isNot(tok::less)) { | 
|  | 1592 | // This may be a type template being used as a template template argument. | 
|  | 1593 | if (SS.isNotEmpty()) | 
|  | 1594 | AnnotateScopeToken(SS, !WasScopeAnnotation); | 
|  | 1595 | return ANK_TemplateName; | 
|  | 1596 | } | 
| Reid Kleckner | 4dc0b1a | 2018-11-01 19:54:45 +0000 | [diff] [blame] | 1597 | LLVM_FALLTHROUGH; | 
| Larisse Voufo | 39a1e50 | 2013-08-06 01:03:05 +0000 | [diff] [blame] | 1598 | case Sema::NC_VarTemplate: | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1599 | case Sema::NC_FunctionTemplate: { | 
| Larisse Voufo | 39a1e50 | 2013-08-06 01:03:05 +0000 | [diff] [blame] | 1600 | // We have a type, variable or function template followed by '<'. | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1601 | ConsumeToken(); | 
|  | 1602 | UnqualifiedId Id; | 
|  | 1603 | Id.setIdentifier(Name, NameLoc); | 
|  | 1604 | if (AnnotateTemplateIdToken( | 
|  | 1605 | TemplateTy::make(Classification.getTemplateName()), | 
|  | 1606 | Classification.getTemplateNameKind(), SS, SourceLocation(), Id)) | 
|  | 1607 | return ANK_Error; | 
|  | 1608 | return ANK_Success; | 
|  | 1609 | } | 
|  | 1610 |  | 
|  | 1611 | case Sema::NC_NestedNameSpecifier: | 
|  | 1612 | llvm_unreachable("already parsed nested name specifier"); | 
|  | 1613 | } | 
|  | 1614 |  | 
|  | 1615 | // Unable to classify the name, but maybe we can annotate a scope specifier. | 
|  | 1616 | if (SS.isNotEmpty()) | 
|  | 1617 | AnnotateScopeToken(SS, !WasScopeAnnotation); | 
|  | 1618 | return ANK_Unresolved; | 
|  | 1619 | } | 
|  | 1620 |  | 
| Alp Toker | 47642d2 | 2013-12-03 06:13:01 +0000 | [diff] [blame] | 1621 | bool Parser::TryKeywordIdentFallback(bool DisableKeyword) { | 
| Nico Weber | 7c3c5be | 2014-09-23 04:09:56 +0000 | [diff] [blame] | 1622 | assert(Tok.isNot(tok::identifier)); | 
| Alp Toker | 47642d2 | 2013-12-03 06:13:01 +0000 | [diff] [blame] | 1623 | Diag(Tok, diag::ext_keyword_as_ident) | 
|  | 1624 | << PP.getSpelling(Tok) | 
|  | 1625 | << DisableKeyword; | 
| Nico Weber | 7c3c5be | 2014-09-23 04:09:56 +0000 | [diff] [blame] | 1626 | if (DisableKeyword) | 
| Richard Smith | 9c25418 | 2015-07-19 21:41:12 +0000 | [diff] [blame] | 1627 | Tok.getIdentifierInfo()->revertTokenIDToIdentifier(); | 
| Alp Toker | 47642d2 | 2013-12-03 06:13:01 +0000 | [diff] [blame] | 1628 | Tok.setKind(tok::identifier); | 
|  | 1629 | return true; | 
|  | 1630 | } | 
|  | 1631 |  | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1632 | /// TryAnnotateTypeOrScopeToken - If the current token position is on a | 
|  | 1633 | /// typename (possibly qualified in C++) or a C++ scope specifier not followed | 
|  | 1634 | /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens | 
|  | 1635 | /// with a single annotation token representing the typename or C++ scope | 
|  | 1636 | /// respectively. | 
|  | 1637 | /// This simplifies handling of C++ scope specifiers and allows efficient | 
|  | 1638 | /// backtracking without the need to re-parse and resolve nested-names and | 
|  | 1639 | /// typenames. | 
| Argyrios Kyrtzidis | 0c4162a | 2008-11-26 21:51:07 +0000 | [diff] [blame] | 1640 | /// It will mainly be called when we expect to treat identifiers as typenames | 
|  | 1641 | /// (if they are typenames). For example, in C we do not expect identifiers | 
|  | 1642 | /// inside expressions to be treated as typenames so it will not be called | 
|  | 1643 | /// for expressions in C. | 
|  | 1644 | /// The benefit for C/ObjC is that a typename will be annotated and | 
| Steve Naroff | 16c8e59 | 2009-01-28 19:39:02 +0000 | [diff] [blame] | 1645 | /// Actions.getTypeName will not be needed to be called again (e.g. getTypeName | 
| Argyrios Kyrtzidis | 0c4162a | 2008-11-26 21:51:07 +0000 | [diff] [blame] | 1646 | /// will not be called twice, once to check whether we have a declaration | 
|  | 1647 | /// specifier, and another one to get the actual type inside | 
| Faisal Vali | a534f07 | 2018-04-26 00:42:40 +0000 | [diff] [blame] | 1648 | /// ParseDeclarationSpecifiers). | 
| Chris Lattner | 9a8968b | 2009-01-04 23:23:14 +0000 | [diff] [blame] | 1649 | /// | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1650 | /// This returns true if an error occurred. | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1651 | /// | 
| Chris Lattner | 45ddec3 | 2009-01-05 00:13:00 +0000 | [diff] [blame] | 1652 | /// Note that this routine emits an error if you call it with ::new or ::delete | 
|  | 1653 | /// as the current tokens, so only call it in contexts where these are invalid. | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1654 | bool Parser::TryAnnotateTypeOrScopeToken() { | 
| Nikola Smiljanic | 6786024 | 2014-09-26 00:28:20 +0000 | [diff] [blame] | 1655 | assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || | 
|  | 1656 | Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) || | 
|  | 1657 | Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) || | 
|  | 1658 | Tok.is(tok::kw___super)) && | 
|  | 1659 | "Cannot be a type or scope token!"); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1660 |  | 
| Douglas Gregor | 333489b | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 1661 | if (Tok.is(tok::kw_typename)) { | 
| David Majnemer | ad01851 | 2013-09-03 22:36:22 +0000 | [diff] [blame] | 1662 | // MSVC lets you do stuff like: | 
|  | 1663 | //   typename typedef T_::D D; | 
|  | 1664 | // | 
|  | 1665 | // We will consume the typedef token here and put it back after we have | 
|  | 1666 | // parsed the first identifier, transforming it into something more like: | 
|  | 1667 | //   typename T_::D typedef D; | 
| Alp Toker | bfa3934 | 2014-01-14 12:51:41 +0000 | [diff] [blame] | 1668 | if (getLangOpts().MSVCCompat && NextToken().is(tok::kw_typedef)) { | 
| David Majnemer | ad01851 | 2013-09-03 22:36:22 +0000 | [diff] [blame] | 1669 | Token TypedefToken; | 
|  | 1670 | PP.Lex(TypedefToken); | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1671 | bool Result = TryAnnotateTypeOrScopeToken(); | 
| David Majnemer | ad01851 | 2013-09-03 22:36:22 +0000 | [diff] [blame] | 1672 | PP.EnterToken(Tok); | 
|  | 1673 | Tok = TypedefToken; | 
|  | 1674 | if (!Result) | 
|  | 1675 | Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename); | 
|  | 1676 | return Result; | 
|  | 1677 | } | 
|  | 1678 |  | 
| Douglas Gregor | 333489b | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 1679 | // Parse a C++ typename-specifier, e.g., "typename T::type". | 
|  | 1680 | // | 
|  | 1681 | //   typename-specifier: | 
|  | 1682 | //     'typename' '::' [opt] nested-name-specifier identifier | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1683 | //     'typename' '::' [opt] nested-name-specifier template [opt] | 
| Douglas Gregor | dce2b62 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 1684 | //            simple-template-id | 
| Douglas Gregor | 333489b | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 1685 | SourceLocation TypenameLoc = ConsumeToken(); | 
|  | 1686 | CXXScopeSpec SS; | 
| David Blaikie | efdccaa | 2016-01-15 23:43:34 +0000 | [diff] [blame] | 1687 | if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, | 
|  | 1688 | /*EnteringContext=*/false, nullptr, | 
|  | 1689 | /*IsTypename*/ true)) | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1690 | return true; | 
|  | 1691 | if (!SS.isSet()) { | 
| Francois Pichet | f5b24e0 | 2012-07-22 15:10:57 +0000 | [diff] [blame] | 1692 | if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) || | 
|  | 1693 | Tok.is(tok::annot_decltype)) { | 
| Richard Smith | b71e732 | 2012-05-14 22:43:34 +0000 | [diff] [blame] | 1694 | // Attempt to recover by skipping the invalid 'typename' | 
| Francois Pichet | f5b24e0 | 2012-07-22 15:10:57 +0000 | [diff] [blame] | 1695 | if (Tok.is(tok::annot_decltype) || | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1696 | (!TryAnnotateTypeOrScopeToken() && Tok.isAnnotation())) { | 
| Richard Smith | b71e732 | 2012-05-14 22:43:34 +0000 | [diff] [blame] | 1697 | unsigned DiagID = diag::err_expected_qualified_after_typename; | 
|  | 1698 | // MS compatibility: MSVC permits using known types with typename. | 
|  | 1699 | // e.g. "typedef typename T* pointer_type" | 
|  | 1700 | if (getLangOpts().MicrosoftExt) | 
|  | 1701 | DiagID = diag::warn_expected_qualified_after_typename; | 
|  | 1702 | Diag(Tok.getLocation(), DiagID); | 
|  | 1703 | return false; | 
|  | 1704 | } | 
|  | 1705 | } | 
| Alex Lorenz | 1be800c5 | 2017-04-19 08:58:56 +0000 | [diff] [blame] | 1706 | if (Tok.isEditorPlaceholder()) | 
|  | 1707 | return true; | 
| Richard Smith | b71e732 | 2012-05-14 22:43:34 +0000 | [diff] [blame] | 1708 |  | 
|  | 1709 | Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename); | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1710 | return true; | 
| Douglas Gregor | 333489b | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 1711 | } | 
|  | 1712 |  | 
|  | 1713 | TypeResult Ty; | 
|  | 1714 | if (Tok.is(tok::identifier)) { | 
|  | 1715 | // FIXME: check whether the next token is '<', first! | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1716 | Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, | 
| Douglas Gregor | f7d7771 | 2010-06-16 22:31:08 +0000 | [diff] [blame] | 1717 | *Tok.getIdentifierInfo(), | 
| Douglas Gregor | 333489b | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 1718 | Tok.getLocation()); | 
| Douglas Gregor | dce2b62 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 1719 | } else if (Tok.is(tok::annot_template_id)) { | 
| Argyrios Kyrtzidis | c0c5dd2 | 2011-06-22 06:09:49 +0000 | [diff] [blame] | 1720 | TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); | 
| Richard Smith | 72bfbd8 | 2013-12-04 00:28:23 +0000 | [diff] [blame] | 1721 | if (TemplateId->Kind != TNK_Type_template && | 
|  | 1722 | TemplateId->Kind != TNK_Dependent_template_name) { | 
| Douglas Gregor | dce2b62 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 1723 | Diag(Tok, diag::err_typename_refers_to_non_type_template) | 
|  | 1724 | << Tok.getAnnotationRange(); | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1725 | return true; | 
| Douglas Gregor | dce2b62 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 1726 | } | 
| Douglas Gregor | 333489b | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 1727 |  | 
| Benjamin Kramer | cc4c49d | 2012-08-23 23:38:35 +0000 | [diff] [blame] | 1728 | ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), | 
| Douglas Gregor | b09518c | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 1729 | TemplateId->NumArgs); | 
| Abramo Bagnara | e0a70b2 | 2012-02-06 22:45:07 +0000 | [diff] [blame] | 1730 |  | 
| Douglas Gregor | b09518c | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 1731 | Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, | 
| Abramo Bagnara | e0a70b2 | 2012-02-06 22:45:07 +0000 | [diff] [blame] | 1732 | TemplateId->TemplateKWLoc, | 
| Douglas Gregor | b09518c | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 1733 | TemplateId->Template, | 
| Richard Smith | 74f0234 | 2017-01-19 21:00:13 +0000 | [diff] [blame] | 1734 | TemplateId->Name, | 
| Douglas Gregor | b09518c | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 1735 | TemplateId->TemplateNameLoc, | 
|  | 1736 | TemplateId->LAngleLoc, | 
| Abramo Bagnara | e0a70b2 | 2012-02-06 22:45:07 +0000 | [diff] [blame] | 1737 | TemplateArgsPtr, | 
| Douglas Gregor | b09518c | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 1738 | TemplateId->RAngleLoc); | 
| Douglas Gregor | dce2b62 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 1739 | } else { | 
|  | 1740 | Diag(Tok, diag::err_expected_type_name_after_typename) | 
|  | 1741 | << SS.getRange(); | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1742 | return true; | 
| Douglas Gregor | dce2b62 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 1743 | } | 
|  | 1744 |  | 
| Sebastian Redl | b0e3e1b | 2010-02-08 19:35:18 +0000 | [diff] [blame] | 1745 | SourceLocation EndLoc = Tok.getLastLoc(); | 
| Douglas Gregor | dce2b62 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 1746 | Tok.setKind(tok::annot_typename); | 
| David Blaikie | efdccaa | 2016-01-15 23:43:34 +0000 | [diff] [blame] | 1747 | setTypeAnnotation(Tok, Ty.isInvalid() ? nullptr : Ty.get()); | 
| Sebastian Redl | b0e3e1b | 2010-02-08 19:35:18 +0000 | [diff] [blame] | 1748 | Tok.setAnnotationEndLoc(EndLoc); | 
| Douglas Gregor | dce2b62 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 1749 | Tok.setLocation(TypenameLoc); | 
|  | 1750 | PP.AnnotateCachedTokens(Tok); | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1751 | return false; | 
| Douglas Gregor | 333489b | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 1752 | } | 
|  | 1753 |  | 
| John McCall | e2ade28 | 2009-12-19 00:35:18 +0000 | [diff] [blame] | 1754 | // Remembers whether the token was originally a scope annotation. | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1755 | bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope); | 
| John McCall | e2ade28 | 2009-12-19 00:35:18 +0000 | [diff] [blame] | 1756 |  | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1757 | CXXScopeSpec SS; | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1758 | if (getLangOpts().CPlusPlus) | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1759 | if (ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext*/false)) | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1760 | return true; | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1761 |  | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1762 | return TryAnnotateTypeOrScopeTokenAfterScopeSpec(SS, !WasScopeAnnotation); | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1763 | } | 
|  | 1764 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 1765 | /// Try to annotate a type or scope token, having already parsed an | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1766 | /// optional scope specifier. \p IsNewScope should be \c true unless the scope | 
|  | 1767 | /// specifier was extracted from an existing tok::annot_cxxscope annotation. | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1768 | bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(CXXScopeSpec &SS, | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1769 | bool IsNewScope) { | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1770 | if (Tok.is(tok::identifier)) { | 
| Chris Lattner | da03008 | 2009-01-05 01:49:50 +0000 | [diff] [blame] | 1771 | // Determine whether the identifier is a type name. | 
| David Blaikie | efdccaa | 2016-01-15 23:43:34 +0000 | [diff] [blame] | 1772 | if (ParsedType Ty = Actions.getTypeName( | 
|  | 1773 | *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS, | 
|  | 1774 | false, NextToken().is(tok::period), nullptr, | 
|  | 1775 | /*IsCtorOrDtorName=*/false, | 
| Richard Smith | 77a9c60 | 2018-02-28 03:02:23 +0000 | [diff] [blame] | 1776 | /*NonTrivialTypeSourceInfo*/true, | 
|  | 1777 | /*IsClassTemplateDeductionContext*/true)) { | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1778 | SourceLocation BeginLoc = Tok.getLocation(); | 
|  | 1779 | if (SS.isNotEmpty()) // it was a C++ qualified type name. | 
|  | 1780 | BeginLoc = SS.getBeginLoc(); | 
|  | 1781 |  | 
|  | 1782 | /// An Objective-C object type followed by '<' is a specialization of | 
|  | 1783 | /// a parameterized class type or a protocol-qualified type. | 
| Erik Pilkington | fa98390 | 2018-10-30 20:31:30 +0000 | [diff] [blame] | 1784 | if (getLangOpts().ObjC && NextToken().is(tok::less) && | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1785 | (Ty.get()->isObjCObjectType() || | 
|  | 1786 | Ty.get()->isObjCObjectPointerType())) { | 
|  | 1787 | // Consume the name. | 
|  | 1788 | SourceLocation IdentifierLoc = ConsumeToken(); | 
|  | 1789 | SourceLocation NewEndLoc; | 
|  | 1790 | TypeResult NewType | 
|  | 1791 | = parseObjCTypeArgsAndProtocolQualifiers(IdentifierLoc, Ty, | 
|  | 1792 | /*consumeLastToken=*/false, | 
|  | 1793 | NewEndLoc); | 
|  | 1794 | if (NewType.isUsable()) | 
|  | 1795 | Ty = NewType.get(); | 
| Bruno Cardoso Lopes | 218c874 | 2016-09-13 20:04:35 +0000 | [diff] [blame] | 1796 | else if (Tok.is(tok::eof)) // Nothing to do here, bail out... | 
|  | 1797 | return false; | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1798 | } | 
|  | 1799 |  | 
| Chris Lattner | da03008 | 2009-01-05 01:49:50 +0000 | [diff] [blame] | 1800 | // This is a typename. Replace the current token in-place with an | 
|  | 1801 | // annotation type token. | 
| Chris Lattner | a8a3f73 | 2009-01-06 05:06:21 +0000 | [diff] [blame] | 1802 | Tok.setKind(tok::annot_typename); | 
| John McCall | ba7bf59 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 1803 | setTypeAnnotation(Tok, Ty); | 
| Chris Lattner | da03008 | 2009-01-05 01:49:50 +0000 | [diff] [blame] | 1804 | Tok.setAnnotationEndLoc(Tok.getLocation()); | 
| Douglas Gregor | 9bda6cf | 2015-07-07 03:58:14 +0000 | [diff] [blame] | 1805 | Tok.setLocation(BeginLoc); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1806 |  | 
| Chris Lattner | da03008 | 2009-01-05 01:49:50 +0000 | [diff] [blame] | 1807 | // In case the tokens were cached, have Preprocessor replace | 
|  | 1808 | // them with the annotation token. | 
|  | 1809 | PP.AnnotateCachedTokens(Tok); | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1810 | return false; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1811 | } | 
| Douglas Gregor | 7f74112 | 2009-02-25 19:37:18 +0000 | [diff] [blame] | 1812 |  | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1813 | if (!getLangOpts().CPlusPlus) { | 
| Chris Lattner | da03008 | 2009-01-05 01:49:50 +0000 | [diff] [blame] | 1814 | // If we're in C, we can't have :: tokens at all (the lexer won't return | 
|  | 1815 | // them).  If the identifier is not a type, then it can't be scope either, | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1816 | // just early exit. | 
| Chris Lattner | da03008 | 2009-01-05 01:49:50 +0000 | [diff] [blame] | 1817 | return false; | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1818 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1819 |  | 
| Douglas Gregor | 7f74112 | 2009-02-25 19:37:18 +0000 | [diff] [blame] | 1820 | // If this is a template-id, annotate with a template-id or type token. | 
| Douglas Gregor | 8bf4205 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1821 | if (NextToken().is(tok::less)) { | 
| Douglas Gregor | dc572a3 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1822 | TemplateTy Template; | 
| Douglas Gregor | 3cf8131 | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 1823 | UnqualifiedId TemplateName; | 
|  | 1824 | TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); | 
| Douglas Gregor | 786123d | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 1825 | bool MemberOfUnknownSpecialization; | 
| Richard Smith | 6232706 | 2017-01-10 22:59:18 +0000 | [diff] [blame] | 1826 | if (TemplateNameKind TNK = Actions.isTemplateName( | 
|  | 1827 | getCurScope(), SS, | 
|  | 1828 | /*hasTemplateKeyword=*/false, TemplateName, | 
|  | 1829 | /*ObjectType=*/nullptr, /*EnteringContext*/false, Template, | 
|  | 1830 | MemberOfUnknownSpecialization)) { | 
| Douglas Gregor | 71395fa | 2009-11-04 00:56:37 +0000 | [diff] [blame] | 1831 | // Consume the identifier. | 
|  | 1832 | ConsumeToken(); | 
| Abramo Bagnara | 7945c98 | 2012-01-27 09:46:47 +0000 | [diff] [blame] | 1833 | if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(), | 
|  | 1834 | TemplateName)) { | 
| Chris Lattner | 5558e9f | 2009-06-26 04:27:47 +0000 | [diff] [blame] | 1835 | // If an unrecoverable error occurred, we need to return true here, | 
|  | 1836 | // because the token stream is in a damaged state.  We may not return | 
|  | 1837 | // a valid identifier. | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1838 | return true; | 
| Chris Lattner | 5558e9f | 2009-06-26 04:27:47 +0000 | [diff] [blame] | 1839 | } | 
| Douglas Gregor | 71395fa | 2009-11-04 00:56:37 +0000 | [diff] [blame] | 1840 | } | 
| Douglas Gregor | 8bf4205 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1841 | } | 
| Douglas Gregor | 55ad91f | 2008-12-18 19:37:40 +0000 | [diff] [blame] | 1842 |  | 
| Douglas Gregor | 7f74112 | 2009-02-25 19:37:18 +0000 | [diff] [blame] | 1843 | // The current token, which is either an identifier or a | 
|  | 1844 | // template-id, is not part of the annotation. Fall through to | 
|  | 1845 | // push that token back into the stream and complete the C++ scope | 
|  | 1846 | // specifier annotation. | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1847 | } | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1848 |  | 
| Douglas Gregor | 7f74112 | 2009-02-25 19:37:18 +0000 | [diff] [blame] | 1849 | if (Tok.is(tok::annot_template_id)) { | 
| Argyrios Kyrtzidis | c0c5dd2 | 2011-06-22 06:09:49 +0000 | [diff] [blame] | 1850 | TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); | 
| Douglas Gregor | b67535d | 2009-03-31 00:43:58 +0000 | [diff] [blame] | 1851 | if (TemplateId->Kind == TNK_Type_template) { | 
| Douglas Gregor | 7f74112 | 2009-02-25 19:37:18 +0000 | [diff] [blame] | 1852 | // A template-id that refers to a type was parsed into a | 
|  | 1853 | // template-id annotation in a context where we weren't allowed | 
|  | 1854 | // to produce a type annotation token. Update the template-id | 
|  | 1855 | // annotation token to a type annotation token now. | 
| Douglas Gregor | e7c2065 | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1856 | AnnotateTemplateIdTokenAsType(); | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1857 | return false; | 
| Richard Smith | ff78338 | 2013-12-04 01:01:51 +0000 | [diff] [blame] | 1858 | } | 
| Douglas Gregor | 7f74112 | 2009-02-25 19:37:18 +0000 | [diff] [blame] | 1859 | } | 
| Douglas Gregor | 55ad91f | 2008-12-18 19:37:40 +0000 | [diff] [blame] | 1860 |  | 
| Chris Lattner | dfa1a45 | 2009-01-04 22:32:19 +0000 | [diff] [blame] | 1861 | if (SS.isEmpty()) | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1862 | return false; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1863 |  | 
| Chris Lattner | dfa1a45 | 2009-01-04 22:32:19 +0000 | [diff] [blame] | 1864 | // A C++ scope specifier that isn't followed by a typename. | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1865 | AnnotateScopeToken(SS, IsNewScope); | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1866 | return false; | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1867 | } | 
|  | 1868 |  | 
|  | 1869 | /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only | 
| Douglas Gregor | 7f74112 | 2009-02-25 19:37:18 +0000 | [diff] [blame] | 1870 | /// annotates C++ scope specifiers and template-ids.  This returns | 
| Richard Smith | 45855df | 2012-05-09 08:23:23 +0000 | [diff] [blame] | 1871 | /// true if there was an error that could not be recovered from. | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1872 | /// | 
| Chris Lattner | 45ddec3 | 2009-01-05 00:13:00 +0000 | [diff] [blame] | 1873 | /// Note that this routine emits an error if you call it with ::new or ::delete | 
|  | 1874 | /// as the current tokens, so only call it in contexts where these are invalid. | 
| Douglas Gregor | e861bac | 2009-08-25 22:51:20 +0000 | [diff] [blame] | 1875 | bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1876 | assert(getLangOpts().CPlusPlus && | 
| Chris Lattner | dfa1a45 | 2009-01-04 22:32:19 +0000 | [diff] [blame] | 1877 | "Call sites of this function should be guarded by checking for C++"); | 
| Douglas Gregor | 8b02cd0 | 2011-04-27 04:48:22 +0000 | [diff] [blame] | 1878 | assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || | 
| David Blaikie | 15a430a | 2011-12-04 05:04:18 +0000 | [diff] [blame] | 1879 | (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) || | 
| Nikola Smiljanic | 6786024 | 2014-09-26 00:28:20 +0000 | [diff] [blame] | 1880 | Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super)) && | 
|  | 1881 | "Cannot be a type or scope token!"); | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1882 |  | 
| Argyrios Kyrtzidis | ace521a | 2008-11-26 21:41:52 +0000 | [diff] [blame] | 1883 | CXXScopeSpec SS; | 
| David Blaikie | efdccaa | 2016-01-15 23:43:34 +0000 | [diff] [blame] | 1884 | if (ParseOptionalCXXScopeSpecifier(SS, nullptr, EnteringContext)) | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1885 | return true; | 
| Jeffrey Yasskin | 4e150f8 | 2010-04-07 23:29:58 +0000 | [diff] [blame] | 1886 | if (SS.isEmpty()) | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1887 | return false; | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1888 |  | 
| Richard Smith | 4f605af | 2012-08-18 00:55:03 +0000 | [diff] [blame] | 1889 | AnnotateScopeToken(SS, true); | 
| John McCall | 1f476a1 | 2010-02-26 08:45:28 +0000 | [diff] [blame] | 1890 | return false; | 
| Argyrios Kyrtzidis | 32a0379 | 2008-11-08 16:45:02 +0000 | [diff] [blame] | 1891 | } | 
| John McCall | 37958aa | 2009-11-03 19:33:12 +0000 | [diff] [blame] | 1892 |  | 
| Richard Trieu | 4972a6d | 2012-01-19 22:01:51 +0000 | [diff] [blame] | 1893 | bool Parser::isTokenEqualOrEqualTypo() { | 
|  | 1894 | tok::TokenKind Kind = Tok.getKind(); | 
|  | 1895 | switch (Kind) { | 
|  | 1896 | default: | 
| Richard Trieu | c64d323 | 2012-01-18 22:54:52 +0000 | [diff] [blame] | 1897 | return false; | 
| Richard Trieu | 4972a6d | 2012-01-19 22:01:51 +0000 | [diff] [blame] | 1898 | case tok::ampequal:            // &= | 
|  | 1899 | case tok::starequal:           // *= | 
|  | 1900 | case tok::plusequal:           // += | 
|  | 1901 | case tok::minusequal:          // -= | 
|  | 1902 | case tok::exclaimequal:        // != | 
|  | 1903 | case tok::slashequal:          // /= | 
|  | 1904 | case tok::percentequal:        // %= | 
|  | 1905 | case tok::lessequal:           // <= | 
|  | 1906 | case tok::lesslessequal:       // <<= | 
|  | 1907 | case tok::greaterequal:        // >= | 
|  | 1908 | case tok::greatergreaterequal: // >>= | 
|  | 1909 | case tok::caretequal:          // ^= | 
|  | 1910 | case tok::pipeequal:           // |= | 
|  | 1911 | case tok::equalequal:          // == | 
|  | 1912 | Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal) | 
| Alp Toker | ec54327 | 2013-12-24 09:48:30 +0000 | [diff] [blame] | 1913 | << Kind | 
|  | 1914 | << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "="); | 
| Galina Kistanova | 27daec6 | 2017-06-03 06:29:16 +0000 | [diff] [blame] | 1915 | LLVM_FALLTHROUGH; | 
| Richard Trieu | 4972a6d | 2012-01-19 22:01:51 +0000 | [diff] [blame] | 1916 | case tok::equal: | 
|  | 1917 | return true; | 
|  | 1918 | } | 
| Argyrios Kyrtzidis | b5c7c51 | 2010-10-08 02:39:23 +0000 | [diff] [blame] | 1919 | } | 
|  | 1920 |  | 
| Argyrios Kyrtzidis | 5cec2ae | 2011-09-04 03:32:15 +0000 | [diff] [blame] | 1921 | SourceLocation Parser::handleUnexpectedCodeCompletionToken() { | 
|  | 1922 | assert(Tok.is(tok::code_completion)); | 
|  | 1923 | PrevTokLocation = Tok.getLocation(); | 
|  | 1924 |  | 
| Douglas Gregor | 0be31a2 | 2010-07-02 17:43:08 +0000 | [diff] [blame] | 1925 | for (Scope *S = getCurScope(); S; S = S->getParent()) { | 
| Douglas Gregor | 6da3db4 | 2010-05-25 05:58:43 +0000 | [diff] [blame] | 1926 | if (S->getFlags() & Scope::FnScope) { | 
| Nico Weber | 744cc5b | 2015-01-04 00:47:22 +0000 | [diff] [blame] | 1927 | Actions.CodeCompleteOrdinaryName(getCurScope(), | 
|  | 1928 | Sema::PCC_RecoveryInFunction); | 
| Argyrios Kyrtzidis | 5cec2ae | 2011-09-04 03:32:15 +0000 | [diff] [blame] | 1929 | cutOffParsing(); | 
|  | 1930 | return PrevTokLocation; | 
| Douglas Gregor | 6da3db4 | 2010-05-25 05:58:43 +0000 | [diff] [blame] | 1931 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1932 |  | 
| Douglas Gregor | 6da3db4 | 2010-05-25 05:58:43 +0000 | [diff] [blame] | 1933 | if (S->getFlags() & Scope::ClassScope) { | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1934 | Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class); | 
| Argyrios Kyrtzidis | 5cec2ae | 2011-09-04 03:32:15 +0000 | [diff] [blame] | 1935 | cutOffParsing(); | 
|  | 1936 | return PrevTokLocation; | 
| Douglas Gregor | 6da3db4 | 2010-05-25 05:58:43 +0000 | [diff] [blame] | 1937 | } | 
|  | 1938 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1939 |  | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1940 | Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace); | 
| Argyrios Kyrtzidis | 5cec2ae | 2011-09-04 03:32:15 +0000 | [diff] [blame] | 1941 | cutOffParsing(); | 
|  | 1942 | return PrevTokLocation; | 
| Douglas Gregor | 6da3db4 | 2010-05-25 05:58:43 +0000 | [diff] [blame] | 1943 | } | 
|  | 1944 |  | 
| Douglas Gregor | 3a7ad25 | 2010-08-24 19:08:16 +0000 | [diff] [blame] | 1945 | // Code-completion pass-through functions | 
|  | 1946 |  | 
|  | 1947 | void Parser::CodeCompleteDirective(bool InConditional) { | 
| Douglas Gregor | ec00a26 | 2010-08-24 22:20:20 +0000 | [diff] [blame] | 1948 | Actions.CodeCompletePreprocessorDirective(InConditional); | 
| Douglas Gregor | 3a7ad25 | 2010-08-24 19:08:16 +0000 | [diff] [blame] | 1949 | } | 
|  | 1950 |  | 
|  | 1951 | void Parser::CodeCompleteInConditionalExclusion() { | 
|  | 1952 | Actions.CodeCompleteInPreprocessorConditionalExclusion(getCurScope()); | 
|  | 1953 | } | 
| Douglas Gregor | 1278510 | 2010-08-24 20:21:13 +0000 | [diff] [blame] | 1954 |  | 
|  | 1955 | void Parser::CodeCompleteMacroName(bool IsDefinition) { | 
| Douglas Gregor | ec00a26 | 2010-08-24 22:20:20 +0000 | [diff] [blame] | 1956 | Actions.CodeCompletePreprocessorMacroName(IsDefinition); | 
|  | 1957 | } | 
|  | 1958 |  | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1959 | void Parser::CodeCompletePreprocessorExpression() { | 
| Douglas Gregor | ec00a26 | 2010-08-24 22:20:20 +0000 | [diff] [blame] | 1960 | Actions.CodeCompletePreprocessorExpression(); | 
|  | 1961 | } | 
|  | 1962 |  | 
|  | 1963 | void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro, | 
|  | 1964 | MacroInfo *MacroInfo, | 
|  | 1965 | unsigned ArgumentIndex) { | 
| Nico Weber | 744cc5b | 2015-01-04 00:47:22 +0000 | [diff] [blame] | 1966 | Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo, | 
| Douglas Gregor | ec00a26 | 2010-08-24 22:20:20 +0000 | [diff] [blame] | 1967 | ArgumentIndex); | 
| Douglas Gregor | 1278510 | 2010-08-24 20:21:13 +0000 | [diff] [blame] | 1968 | } | 
| Douglas Gregor | 1158370 | 2010-08-25 17:04:25 +0000 | [diff] [blame] | 1969 |  | 
| Sam McCall | 3d8051a | 2018-09-18 08:40:41 +0000 | [diff] [blame] | 1970 | void Parser::CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) { | 
|  | 1971 | Actions.CodeCompleteIncludedFile(Dir, IsAngled); | 
|  | 1972 | } | 
|  | 1973 |  | 
| Douglas Gregor | 1158370 | 2010-08-25 17:04:25 +0000 | [diff] [blame] | 1974 | void Parser::CodeCompleteNaturalLanguage() { | 
|  | 1975 | Actions.CodeCompleteNaturalLanguage(); | 
|  | 1976 | } | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 1977 |  | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 1978 | bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) { | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 1979 | assert((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists)) && | 
|  | 1980 | "Expected '__if_exists' or '__if_not_exists'"); | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 1981 | Result.IsIfExists = Tok.is(tok::kw___if_exists); | 
|  | 1982 | Result.KeywordLoc = ConsumeToken(); | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 1983 |  | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 1984 | BalancedDelimiterTracker T(*this, tok::l_paren); | 
|  | 1985 | if (T.consumeOpen()) { | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1986 | Diag(Tok, diag::err_expected_lparen_after) | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 1987 | << (Result.IsIfExists? "__if_exists" : "__if_not_exists"); | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 1988 | return true; | 
|  | 1989 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 1990 |  | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 1991 | // Parse nested-name-specifier. | 
| Nico Rieck | dfff5d2 | 2014-11-24 17:29:35 +0000 | [diff] [blame] | 1992 | if (getLangOpts().CPlusPlus) | 
| David Blaikie | efdccaa | 2016-01-15 23:43:34 +0000 | [diff] [blame] | 1993 | ParseOptionalCXXScopeSpecifier(Result.SS, nullptr, | 
| Nico Rieck | dfff5d2 | 2014-11-24 17:29:35 +0000 | [diff] [blame] | 1994 | /*EnteringContext=*/false); | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 1995 |  | 
|  | 1996 | // Check nested-name specifier. | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 1997 | if (Result.SS.isInvalid()) { | 
|  | 1998 | T.skipToEnd(); | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 1999 | return true; | 
|  | 2000 | } | 
|  | 2001 |  | 
| Abramo Bagnara | 7945c98 | 2012-01-27 09:46:47 +0000 | [diff] [blame] | 2002 | // Parse the unqualified-id. | 
|  | 2003 | SourceLocation TemplateKWLoc; // FIXME: parsed, but unused. | 
| Richard Smith | 3584515 | 2017-02-07 01:37:30 +0000 | [diff] [blame] | 2004 | if (ParseUnqualifiedId( | 
|  | 2005 | Result.SS, /*EnteringContext*/false, /*AllowDestructorName*/true, | 
|  | 2006 | /*AllowConstructorName*/true, /*AllowDeductionGuide*/false, nullptr, | 
| Richard Smith | c08b693 | 2018-04-27 02:00:13 +0000 | [diff] [blame] | 2007 | &TemplateKWLoc, Result.Name)) { | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2008 | T.skipToEnd(); | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2009 | return true; | 
|  | 2010 | } | 
|  | 2011 |  | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2012 | if (T.consumeClose()) | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2013 | return true; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2014 |  | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2015 | // Check if the symbol exists. | 
| Douglas Gregor | 4a2a8f7 | 2011-10-25 03:44:56 +0000 | [diff] [blame] | 2016 | switch (Actions.CheckMicrosoftIfExistsSymbol(getCurScope(), Result.KeywordLoc, | 
| Nico Weber | 744cc5b | 2015-01-04 00:47:22 +0000 | [diff] [blame] | 2017 | Result.IsIfExists, Result.SS, | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2018 | Result.Name)) { | 
|  | 2019 | case Sema::IER_Exists: | 
|  | 2020 | Result.Behavior = Result.IsIfExists ? IEB_Parse : IEB_Skip; | 
|  | 2021 | break; | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2022 |  | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2023 | case Sema::IER_DoesNotExist: | 
|  | 2024 | Result.Behavior = !Result.IsIfExists ? IEB_Parse : IEB_Skip; | 
|  | 2025 | break; | 
|  | 2026 |  | 
|  | 2027 | case Sema::IER_Dependent: | 
|  | 2028 | Result.Behavior = IEB_Dependent; | 
|  | 2029 | break; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2030 |  | 
| Douglas Gregor | 4a2a8f7 | 2011-10-25 03:44:56 +0000 | [diff] [blame] | 2031 | case Sema::IER_Error: | 
|  | 2032 | return true; | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2033 | } | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2034 |  | 
|  | 2035 | return false; | 
|  | 2036 | } | 
|  | 2037 |  | 
| Francois Pichet | 8f981d5 | 2011-05-25 10:19:49 +0000 | [diff] [blame] | 2038 | void Parser::ParseMicrosoftIfExistsExternalDeclaration() { | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2039 | IfExistsCondition Result; | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2040 | if (ParseMicrosoftIfExistsCondition(Result)) | 
|  | 2041 | return; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2042 |  | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2043 | BalancedDelimiterTracker Braces(*this, tok::l_brace); | 
|  | 2044 | if (Braces.consumeOpen()) { | 
| Alp Toker | ec54327 | 2013-12-24 09:48:30 +0000 | [diff] [blame] | 2045 | Diag(Tok, diag::err_expected) << tok::l_brace; | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2046 | return; | 
|  | 2047 | } | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2048 |  | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2049 | switch (Result.Behavior) { | 
|  | 2050 | case IEB_Parse: | 
|  | 2051 | // Parse declarations below. | 
|  | 2052 | break; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2053 |  | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2054 | case IEB_Dependent: | 
|  | 2055 | llvm_unreachable("Cannot have a dependent external declaration"); | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2056 |  | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2057 | case IEB_Skip: | 
|  | 2058 | Braces.skipToEnd(); | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2059 | return; | 
|  | 2060 | } | 
|  | 2061 |  | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2062 | // Parse the declarations. | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 2063 | // FIXME: Support module import within __if_exists? | 
|  | 2064 | while (Tok.isNot(tok::r_brace) && !isEofOrEom()) { | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2065 | ParsedAttributesWithRange attrs(AttrFactory); | 
| Richard Smith | 89645bc | 2013-01-02 12:01:23 +0000 | [diff] [blame] | 2066 | MaybeParseCXX11Attributes(attrs); | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2067 | DeclGroupPtrTy Result = ParseExternalDeclaration(attrs); | 
|  | 2068 | if (Result && !getCurScope()->getParent()) | 
|  | 2069 | Actions.getASTConsumer().HandleTopLevelDecl(Result.get()); | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 2070 | } | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2071 | Braces.consumeClose(); | 
| Francois Pichet | a5b3fcb | 2011-05-07 17:30:27 +0000 | [diff] [blame] | 2072 | } | 
| Douglas Gregor | 0814253 | 2011-08-26 23:56:07 +0000 | [diff] [blame] | 2073 |  | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2074 | /// Parse a C++ Modules TS module declaration, which appears at the beginning | 
|  | 2075 | /// of a module interface, module partition, or module implementation file. | 
|  | 2076 | /// | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 2077 | ///   module-declaration:   [Modules TS + P0273R0 + P0629R0] | 
|  | 2078 | ///     'export'[opt] 'module' 'partition'[opt] | 
|  | 2079 | ///            module-name attribute-specifier-seq[opt] ';' | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2080 | /// | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 2081 | /// Note that 'partition' is a context-sensitive keyword. | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2082 | Parser::DeclGroupPtrTy Parser::ParseModuleDecl() { | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 2083 | SourceLocation StartLoc = Tok.getLocation(); | 
|  | 2084 |  | 
|  | 2085 | Sema::ModuleDeclKind MDK = TryConsumeToken(tok::kw_export) | 
| Richard Smith | d97d35e | 2017-10-10 22:35:27 +0000 | [diff] [blame] | 2086 | ? Sema::ModuleDeclKind::Interface | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 2087 | : Sema::ModuleDeclKind::Implementation; | 
|  | 2088 |  | 
|  | 2089 | assert(Tok.is(tok::kw_module) && "not a module declaration"); | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2090 | SourceLocation ModuleLoc = ConsumeToken(); | 
|  | 2091 |  | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 2092 | if (Tok.is(tok::identifier) && NextToken().is(tok::identifier) && | 
|  | 2093 | Tok.getIdentifierInfo()->isStr("partition")) { | 
|  | 2094 | // If 'partition' is present, this must be a module interface unit. | 
| Richard Smith | d97d35e | 2017-10-10 22:35:27 +0000 | [diff] [blame] | 2095 | if (MDK != Sema::ModuleDeclKind::Interface) | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 2096 | Diag(Tok.getLocation(), diag::err_module_implementation_partition) | 
|  | 2097 | << FixItHint::CreateInsertion(ModuleLoc, "export "); | 
|  | 2098 | MDK = Sema::ModuleDeclKind::Partition; | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2099 | ConsumeToken(); | 
|  | 2100 | } | 
|  | 2101 |  | 
|  | 2102 | SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; | 
|  | 2103 | if (ParseModuleName(ModuleLoc, Path, /*IsImport*/false)) | 
|  | 2104 | return nullptr; | 
|  | 2105 |  | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 2106 | // We don't support any module attributes yet; just parse them and diagnose. | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2107 | ParsedAttributesWithRange Attrs(AttrFactory); | 
|  | 2108 | MaybeParseCXX11Attributes(Attrs); | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2109 | ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_module_attr); | 
|  | 2110 |  | 
|  | 2111 | ExpectAndConsumeSemi(diag::err_module_expected_semi); | 
|  | 2112 |  | 
| Richard Smith | 81328ac | 2017-04-21 22:39:18 +0000 | [diff] [blame] | 2113 | return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path); | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2114 | } | 
|  | 2115 |  | 
| Richard Smith | 49cc1cc | 2016-08-18 21:59:42 +0000 | [diff] [blame] | 2116 | /// Parse a module import declaration. This is essentially the same for | 
|  | 2117 | /// Objective-C and the C++ Modules TS, except for the leading '@' (in ObjC) | 
|  | 2118 | /// and the trailing optional attributes (in C++). | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2119 | /// | 
| Richard Smith | 49cc1cc | 2016-08-18 21:59:42 +0000 | [diff] [blame] | 2120 | /// [ObjC]  @import declaration: | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2121 | ///           '@' 'import' module-name ';' | 
| Richard Smith | 49cc1cc | 2016-08-18 21:59:42 +0000 | [diff] [blame] | 2122 | /// [ModTS] module-import-declaration: | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2123 | ///           'import' module-name attribute-specifier-seq[opt] ';' | 
| Hamza Sood | 81fe14e | 2017-11-21 09:42:42 +0000 | [diff] [blame] | 2124 | Decl *Parser::ParseModuleImport(SourceLocation AtLoc) { | 
| Richard Smith | 49cc1cc | 2016-08-18 21:59:42 +0000 | [diff] [blame] | 2125 | assert((AtLoc.isInvalid() ? Tok.is(tok::kw_import) | 
|  | 2126 | : Tok.isObjCAtKeyword(tok::objc_import)) && | 
| Douglas Gregor | ca97589 | 2011-08-31 18:19:09 +0000 | [diff] [blame] | 2127 | "Improper start to module import"); | 
| Bruno Cardoso Lopes | 03e0d2d | 2018-06-27 20:29:36 +0000 | [diff] [blame] | 2128 | bool IsObjCAtImport = Tok.isObjCAtKeyword(tok::objc_import); | 
| Douglas Gregor | 0814253 | 2011-08-26 23:56:07 +0000 | [diff] [blame] | 2129 | SourceLocation ImportLoc = ConsumeToken(); | 
| Richard Smith | 49cc1cc | 2016-08-18 21:59:42 +0000 | [diff] [blame] | 2130 | SourceLocation StartLoc = AtLoc.isInvalid() ? ImportLoc : AtLoc; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2131 |  | 
| Dmitri Gribenko | f857950 | 2013-01-12 19:30:44 +0000 | [diff] [blame] | 2132 | SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2133 | if (ParseModuleName(ImportLoc, Path, /*IsImport*/true)) | 
|  | 2134 | return nullptr; | 
| Richard Smith | 49cc1cc | 2016-08-18 21:59:42 +0000 | [diff] [blame] | 2135 |  | 
|  | 2136 | ParsedAttributesWithRange Attrs(AttrFactory); | 
|  | 2137 | MaybeParseCXX11Attributes(Attrs); | 
|  | 2138 | // We don't support any module import attributes yet. | 
|  | 2139 | ProhibitCXX11Attributes(Attrs, diag::err_attribute_not_import_attr); | 
| Argyrios Kyrtzidis | dc9fdaf | 2013-05-24 05:44:08 +0000 | [diff] [blame] | 2140 |  | 
|  | 2141 | if (PP.hadModuleLoaderFatalFailure()) { | 
|  | 2142 | // With a fatal failure in the module loader, we abort parsing. | 
|  | 2143 | cutOffParsing(); | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 2144 | return nullptr; | 
| Argyrios Kyrtzidis | dc9fdaf | 2013-05-24 05:44:08 +0000 | [diff] [blame] | 2145 | } | 
|  | 2146 |  | 
| Richard Smith | 49cc1cc | 2016-08-18 21:59:42 +0000 | [diff] [blame] | 2147 | DeclResult Import = Actions.ActOnModuleImport(StartLoc, ImportLoc, Path); | 
| Douglas Gregor | 0814253 | 2011-08-26 23:56:07 +0000 | [diff] [blame] | 2148 | ExpectAndConsumeSemi(diag::err_module_expected_semi); | 
|  | 2149 | if (Import.isInvalid()) | 
| David Blaikie | 0403cb1 | 2016-01-15 23:43:25 +0000 | [diff] [blame] | 2150 | return nullptr; | 
|  | 2151 |  | 
| Bruno Cardoso Lopes | 03e0d2d | 2018-06-27 20:29:36 +0000 | [diff] [blame] | 2152 | // Using '@import' in framework headers requires modules to be enabled so that | 
|  | 2153 | // the header is parseable. Emit a warning to make the user aware. | 
|  | 2154 | if (IsObjCAtImport && AtLoc.isValid()) { | 
|  | 2155 | auto &SrcMgr = PP.getSourceManager(); | 
|  | 2156 | auto *FE = SrcMgr.getFileEntryForID(SrcMgr.getFileID(AtLoc)); | 
|  | 2157 | if (FE && llvm::sys::path::parent_path(FE->getDir()->getName()) | 
|  | 2158 | .endswith(".framework")) | 
|  | 2159 | Diags.Report(AtLoc, diag::warn_atimport_in_framework_header); | 
|  | 2160 | } | 
|  | 2161 |  | 
| Hamza Sood | 81fe14e | 2017-11-21 09:42:42 +0000 | [diff] [blame] | 2162 | return Import.get(); | 
| Douglas Gregor | 0814253 | 2011-08-26 23:56:07 +0000 | [diff] [blame] | 2163 | } | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 2164 |  | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2165 | /// Parse a C++ Modules TS / Objective-C module name (both forms use the same | 
|  | 2166 | /// grammar). | 
|  | 2167 | /// | 
|  | 2168 | ///         module-name: | 
|  | 2169 | ///           module-name-qualifier[opt] identifier | 
|  | 2170 | ///         module-name-qualifier: | 
|  | 2171 | ///           module-name-qualifier[opt] identifier '.' | 
|  | 2172 | bool Parser::ParseModuleName( | 
|  | 2173 | SourceLocation UseLoc, | 
|  | 2174 | SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path, | 
|  | 2175 | bool IsImport) { | 
|  | 2176 | // Parse the module path. | 
|  | 2177 | while (true) { | 
|  | 2178 | if (!Tok.is(tok::identifier)) { | 
|  | 2179 | if (Tok.is(tok::code_completion)) { | 
|  | 2180 | Actions.CodeCompleteModuleImport(UseLoc, Path); | 
|  | 2181 | cutOffParsing(); | 
|  | 2182 | return true; | 
|  | 2183 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2184 |  | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2185 | Diag(Tok, diag::err_module_expected_ident) << IsImport; | 
|  | 2186 | SkipUntil(tok::semi); | 
|  | 2187 | return true; | 
|  | 2188 | } | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2189 |  | 
| Richard Smith | 964cc53 | 2016-08-19 01:43:06 +0000 | [diff] [blame] | 2190 | // Record this part of the module path. | 
|  | 2191 | Path.push_back(std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation())); | 
|  | 2192 | ConsumeToken(); | 
|  | 2193 |  | 
|  | 2194 | if (Tok.isNot(tok::period)) | 
|  | 2195 | return false; | 
|  | 2196 |  | 
|  | 2197 | ConsumeToken(); | 
|  | 2198 | } | 
|  | 2199 | } | 
|  | 2200 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 2201 | /// Try recover parser when module annotation appears where it must not | 
| Serge Pavlov | c4e04a2 | 2015-09-19 05:32:57 +0000 | [diff] [blame] | 2202 | /// be found. | 
|  | 2203 | /// \returns false if the recover was successful and parsing may be continued, or | 
|  | 2204 | /// true if parser must bail out to top level and handle the token there. | 
|  | 2205 | bool Parser::parseMisplacedModuleImport() { | 
|  | 2206 | while (true) { | 
|  | 2207 | switch (Tok.getKind()) { | 
|  | 2208 | case tok::annot_module_end: | 
| Richard Smith | b9d0193 | 2016-12-06 00:12:39 +0000 | [diff] [blame] | 2209 | // If we recovered from a misplaced module begin, we expect to hit a | 
|  | 2210 | // misplaced module end too. Stay in the current context when this | 
|  | 2211 | // happens. | 
|  | 2212 | if (MisplacedModuleBeginCount) { | 
|  | 2213 | --MisplacedModuleBeginCount; | 
|  | 2214 | Actions.ActOnModuleEnd(Tok.getLocation(), | 
|  | 2215 | reinterpret_cast<Module *>( | 
|  | 2216 | Tok.getAnnotationValue())); | 
| Richard Smith | af3b325 | 2017-05-18 19:21:48 +0000 | [diff] [blame] | 2217 | ConsumeAnnotationToken(); | 
| Richard Smith | b9d0193 | 2016-12-06 00:12:39 +0000 | [diff] [blame] | 2218 | continue; | 
|  | 2219 | } | 
| Serge Pavlov | c4e04a2 | 2015-09-19 05:32:57 +0000 | [diff] [blame] | 2220 | // Inform caller that recovery failed, the error must be handled at upper | 
| Richard Smith | b9d0193 | 2016-12-06 00:12:39 +0000 | [diff] [blame] | 2221 | // level. This will generate the desired "missing '}' at end of module" | 
|  | 2222 | // diagnostics on the way out. | 
| Serge Pavlov | c4e04a2 | 2015-09-19 05:32:57 +0000 | [diff] [blame] | 2223 | return true; | 
|  | 2224 | case tok::annot_module_begin: | 
| Richard Smith | b9d0193 | 2016-12-06 00:12:39 +0000 | [diff] [blame] | 2225 | // Recover by entering the module (Sema will diagnose). | 
|  | 2226 | Actions.ActOnModuleBegin(Tok.getLocation(), | 
|  | 2227 | reinterpret_cast<Module *>( | 
|  | 2228 | Tok.getAnnotationValue())); | 
| Richard Smith | af3b325 | 2017-05-18 19:21:48 +0000 | [diff] [blame] | 2229 | ConsumeAnnotationToken(); | 
| Richard Smith | b9d0193 | 2016-12-06 00:12:39 +0000 | [diff] [blame] | 2230 | ++MisplacedModuleBeginCount; | 
|  | 2231 | continue; | 
| Serge Pavlov | c4e04a2 | 2015-09-19 05:32:57 +0000 | [diff] [blame] | 2232 | case tok::annot_module_include: | 
|  | 2233 | // Module import found where it should not be, for instance, inside a | 
|  | 2234 | // namespace. Recover by importing the module. | 
|  | 2235 | Actions.ActOnModuleInclude(Tok.getLocation(), | 
|  | 2236 | reinterpret_cast<Module *>( | 
| Richard Smith | b9d0193 | 2016-12-06 00:12:39 +0000 | [diff] [blame] | 2237 | Tok.getAnnotationValue())); | 
| Richard Smith | af3b325 | 2017-05-18 19:21:48 +0000 | [diff] [blame] | 2238 | ConsumeAnnotationToken(); | 
| Serge Pavlov | c4e04a2 | 2015-09-19 05:32:57 +0000 | [diff] [blame] | 2239 | // If there is another module import, process it. | 
|  | 2240 | continue; | 
|  | 2241 | default: | 
|  | 2242 | return false; | 
|  | 2243 | } | 
|  | 2244 | } | 
|  | 2245 | return false; | 
|  | 2246 | } | 
|  | 2247 |  | 
| Douglas Gregor | 91c25ea | 2012-06-06 21:18:07 +0000 | [diff] [blame] | 2248 | bool BalancedDelimiterTracker::diagnoseOverflow() { | 
| Richard Smith | b3a1452 | 2013-02-22 01:59:51 +0000 | [diff] [blame] | 2249 | P.Diag(P.Tok, diag::err_bracket_depth_exceeded) | 
|  | 2250 | << P.getLangOpts().BracketDepth; | 
|  | 2251 | P.Diag(P.Tok, diag::note_bracket_depth); | 
| Richard Smith | 34f3051 | 2013-11-23 04:06:09 +0000 | [diff] [blame] | 2252 | P.cutOffParsing(); | 
|  | 2253 | return true; | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 2254 | } | 
|  | 2255 |  | 
| Douglas Gregor | 91c25ea | 2012-06-06 21:18:07 +0000 | [diff] [blame] | 2256 | bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID, | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 2257 | const char *Msg, | 
|  | 2258 | tok::TokenKind SkipToTok) { | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 2259 | LOpen = P.Tok.getLocation(); | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 2260 | if (P.ExpectAndConsume(Kind, DiagID, Msg)) { | 
|  | 2261 | if (SkipToTok != tok::unknown) | 
|  | 2262 | P.SkipUntil(SkipToTok, Parser::StopAtSemi); | 
| Douglas Gregor | 0cf55e9 | 2012-03-08 01:00:17 +0000 | [diff] [blame] | 2263 | return true; | 
| Alp Toker | 383d2c4 | 2014-01-01 03:08:43 +0000 | [diff] [blame] | 2264 | } | 
|  | 2265 |  | 
| Jan Korous | e669f3a | 2018-03-16 20:17:28 +0000 | [diff] [blame] | 2266 | if (getDepth() < P.getLangOpts().BracketDepth) | 
| Douglas Gregor | 0cf55e9 | 2012-03-08 01:00:17 +0000 | [diff] [blame] | 2267 | return false; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 2268 |  | 
| Douglas Gregor | 0cf55e9 | 2012-03-08 01:00:17 +0000 | [diff] [blame] | 2269 | return diagnoseOverflow(); | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 2270 | } | 
|  | 2271 |  | 
| Douglas Gregor | 91c25ea | 2012-06-06 21:18:07 +0000 | [diff] [blame] | 2272 | bool BalancedDelimiterTracker::diagnoseMissingClose() { | 
| Douglas Gregor | 0cf55e9 | 2012-03-08 01:00:17 +0000 | [diff] [blame] | 2273 | assert(!P.Tok.is(Close) && "Should have consumed closing delimiter"); | 
| Alp Toker | ec54327 | 2013-12-24 09:48:30 +0000 | [diff] [blame] | 2274 |  | 
| Serge Pavlov | c4e04a2 | 2015-09-19 05:32:57 +0000 | [diff] [blame] | 2275 | if (P.Tok.is(tok::annot_module_end)) | 
|  | 2276 | P.Diag(P.Tok, diag::err_missing_before_module_end) << Close; | 
|  | 2277 | else | 
|  | 2278 | P.Diag(P.Tok, diag::err_expected) << Close; | 
| Alp Toker | ec54327 | 2013-12-24 09:48:30 +0000 | [diff] [blame] | 2279 | P.Diag(LOpen, diag::note_matching) << Kind; | 
| Richard Smith | c2c8bb8 | 2013-10-15 01:34:54 +0000 | [diff] [blame] | 2280 |  | 
|  | 2281 | // If we're not already at some kind of closing bracket, skip to our closing | 
|  | 2282 | // token. | 
|  | 2283 | if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) && | 
|  | 2284 | P.Tok.isNot(tok::r_square) && | 
| David Majnemer | 234b818 | 2015-01-12 03:36:37 +0000 | [diff] [blame] | 2285 | P.SkipUntil(Close, FinalToken, | 
| Alp Toker | d751fa7 | 2013-12-18 19:10:49 +0000 | [diff] [blame] | 2286 | Parser::StopAtSemi | Parser::StopBeforeMatch) && | 
| Richard Smith | c2c8bb8 | 2013-10-15 01:34:54 +0000 | [diff] [blame] | 2287 | P.Tok.is(Close)) | 
| David Blaikie | 0da2fa3 | 2012-11-07 19:08:05 +0000 | [diff] [blame] | 2288 | LClose = P.ConsumeAnyToken(); | 
| Douglas Gregor | e7a8e3b | 2011-10-12 16:37:45 +0000 | [diff] [blame] | 2289 | return true; | 
|  | 2290 | } | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2291 |  | 
| Douglas Gregor | 91c25ea | 2012-06-06 21:18:07 +0000 | [diff] [blame] | 2292 | void BalancedDelimiterTracker::skipToEnd() { | 
| Alp Toker | d751fa7 | 2013-12-18 19:10:49 +0000 | [diff] [blame] | 2293 | P.SkipUntil(Close, Parser::StopBeforeMatch); | 
| Richard Smith | c2c8bb8 | 2013-10-15 01:34:54 +0000 | [diff] [blame] | 2294 | consumeClose(); | 
| Douglas Gregor | 43edb32 | 2011-10-24 22:31:10 +0000 | [diff] [blame] | 2295 | } |