diff options
Diffstat (limited to 'lib/Parse/Parser.cpp')
-rw-r--r-- | lib/Parse/Parser.cpp | 127 |
1 files changed, 54 insertions, 73 deletions
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 37ce157e0812..7ccd2092a2d7 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -510,6 +510,13 @@ namespace { }; } +void Parser::LateTemplateParserCleanupCallback(void *P) { + // While this RAII helper doesn't bracket any actual work, the destructor will + // clean up annotations that were created during ActOnEndOfTranslationUnit + // when incremental processing is enabled. + DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(((Parser *)P)->TemplateIds); +} + /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the /// action tells us to. This returns true if the EOF was encountered. bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) { @@ -542,7 +549,10 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) { case tok::eof: // Late template parsing can begin. if (getLangOpts().DelayedTemplateParsing) - Actions.SetLateTemplateParser(LateTemplateParserCallback, this); + Actions.SetLateTemplateParser(LateTemplateParserCallback, + PP.isIncrementalProcessingEnabled() ? + LateTemplateParserCleanupCallback : nullptr, + this); if (!PP.isIncrementalProcessingEnabled()) Actions.ActOnEndOfTranslationUnit(); //else don't tell Sema that we ended parsing: more input might come. @@ -624,8 +634,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, HandlePragmaOpenCLExtension(); return DeclGroupPtrTy(); case tok::annot_pragma_openmp: - ParseOpenMPDeclarativeDirective(); - return DeclGroupPtrTy(); + return ParseOpenMPDeclarativeDirective(); case tok::annot_pragma_ms_pointers_to_members: HandlePragmaMSPointersToMembers(); return DeclGroupPtrTy(); @@ -697,8 +706,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, // A function definition cannot start with any of these keywords. { SourceLocation DeclEnd; - StmtVector Stmts; - return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs); + return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs); } case tok::kw_static: @@ -708,8 +716,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) << 0; SourceLocation DeclEnd; - StmtVector Stmts; - return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs); + return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs); } goto dont_know; @@ -720,8 +727,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, // Inline namespaces. Allowed as an extension even in C++03. if (NextKind == tok::kw_namespace) { SourceLocation DeclEnd; - StmtVector Stmts; - return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs); + return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs); } // Parse (then ignore) 'inline' prior to a template instantiation. This is @@ -730,8 +736,7 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored) << 1; SourceLocation DeclEnd; - StmtVector Stmts; - return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs); + return ParseDeclaration(Declarator::FileContext, DeclEnd, attrs); } } goto dont_know; @@ -885,7 +890,7 @@ Parser::ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs, return Actions.ConvertDeclToDeclGroup(TheDecl); } - return ParseDeclGroup(DS, Declarator::FileContext, true); + return ParseDeclGroup(DS, Declarator::FileContext); } Parser::DeclGroupPtrTy @@ -922,7 +927,7 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributesWithRange &attrs, Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, LateParsedAttrList *LateParsedAttrs) { - // Poison the SEH identifiers so they are flagged as illegal in function bodies + // Poison SEH identifiers so they are flagged as illegal in function bodies. PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true); const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); @@ -1218,27 +1223,24 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { /// [GNU] asm-string-literal: /// string-literal /// -Parser::ExprResult Parser::ParseAsmStringLiteral() { - switch (Tok.getKind()) { - case tok::string_literal: - break; - case tok::utf8_string_literal: - case tok::utf16_string_literal: - case tok::utf32_string_literal: - case tok::wide_string_literal: { - SourceLocation L = Tok.getLocation(); +ExprResult Parser::ParseAsmStringLiteral() { + if (!isTokenStringLiteral()) { + Diag(Tok, diag::err_expected_string_literal) + << /*Source='in...'*/0 << "'asm'"; + return ExprError(); + } + + ExprResult AsmString(ParseStringLiteralExpression()); + if (!AsmString.isInvalid()) { + const auto *SL = cast<StringLiteral>(AsmString.get()); + if (!SL->isAscii()) { Diag(Tok, diag::err_asm_operand_wide_string_literal) - << (Tok.getKind() == tok::wide_string_literal) - << SourceRange(L, L); + << SL->isWide() + << SL->getSourceRange(); return ExprError(); } - default: - Diag(Tok, diag::err_expected_string_literal) - << /*Source='in...'*/0 << "'asm'"; - return ExprError(); } - - return ParseStringLiteralExpression(); + return AsmString; } /// ParseSimpleAsm @@ -1246,7 +1248,7 @@ Parser::ExprResult Parser::ParseAsmStringLiteral() { /// [GNU] simple-asm-expr: /// 'asm' '(' asm-string-literal ')' /// -Parser::ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { +ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { assert(Tok.is(tok::kw_asm) && "Not an asm!"); SourceLocation Loc = ConsumeToken(); @@ -1321,7 +1323,7 @@ void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) { /// no typo correction will be performed. Parser::AnnotatedNameKind Parser::TryAnnotateName(bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC) { + std::unique_ptr<CorrectionCandidateCallback> CCC) { assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope)); const bool EnteringContext = false; @@ -1359,9 +1361,9 @@ Parser::TryAnnotateName(bool IsAddressOfOperand, // after a scope specifier, because in general we can't recover from typos // there (eg, after correcting 'A::tempalte B<X>::C' [sic], we would need to // jump back into scope specifier parsing). - Sema::NameClassification Classification - = Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next, - IsAddressOfOperand, SS.isEmpty() ? CCC : nullptr); + Sema::NameClassification Classification = Actions.ClassifyName( + getCurScope(), SS, Name, NameLoc, Next, IsAddressOfOperand, + SS.isEmpty() ? std::move(CCC) : nullptr); switch (Classification.getKind()) { case Sema::NC_Error: @@ -1431,34 +1433,16 @@ Parser::TryAnnotateName(bool IsAddressOfOperand, } bool Parser::TryKeywordIdentFallback(bool DisableKeyword) { - assert(!Tok.is(tok::identifier) && !Tok.isAnnotation()); + assert(Tok.isNot(tok::identifier)); Diag(Tok, diag::ext_keyword_as_ident) << PP.getSpelling(Tok) << DisableKeyword; - if (DisableKeyword) { - IdentifierInfo *II = Tok.getIdentifierInfo(); - ContextualKeywords[II] = Tok.getKind(); - II->RevertTokenIDToIdentifier(); - } + if (DisableKeyword) + Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); Tok.setKind(tok::identifier); return true; } -bool Parser::TryIdentKeywordUpgrade() { - assert(Tok.is(tok::identifier)); - const IdentifierInfo *II = Tok.getIdentifierInfo(); - assert(II->hasRevertedTokenIDToIdentifier()); - // If we find that this is in fact the name of a type trait, - // update the token kind in place and parse again to treat it as - // the appropriate kind of type trait. - llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind>::iterator Known = - ContextualKeywords.find(II); - if (Known == ContextualKeywords.end()) - return false; - Tok.setKind(Known->second); - return true; -} - /// TryAnnotateTypeOrScopeToken - If the current token position is on a /// typename (possibly qualified in C++) or a C++ scope specifier not followed /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens @@ -1482,10 +1466,11 @@ bool Parser::TryIdentKeywordUpgrade() { /// Note that this routine emits an error if you call it with ::new or ::delete /// as the current tokens, so only call it in contexts where these are invalid. bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) { - assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) - || Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) - || Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)) - && "Cannot be a type or scope token!"); + assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || + Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope) || + Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id) || + Tok.is(tok::kw___super)) && + "Cannot be a type or scope token!"); if (Tok.is(tok::kw_typename)) { // MSVC lets you do stuff like: @@ -1694,7 +1679,8 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { "Call sites of this function should be guarded by checking for C++"); assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) || - Tok.is(tok::kw_decltype)) && "Cannot be a type or scope token!"); + Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super)) && + "Cannot be a type or scope token!"); CXXScopeSpec SS; if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext)) @@ -1739,7 +1725,8 @@ SourceLocation Parser::handleUnexpectedCodeCompletionToken() { for (Scope *S = getCurScope(); S; S = S->getParent()) { if (S->getFlags() & Scope::FnScope) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_RecoveryInFunction); + Actions.CodeCompleteOrdinaryName(getCurScope(), + Sema::PCC_RecoveryInFunction); cutOffParsing(); return PrevTokLocation; } @@ -1756,13 +1743,6 @@ SourceLocation Parser::handleUnexpectedCodeCompletionToken() { return PrevTokLocation; } -// Anchor the Parser::FieldCallback vtable to this translation unit. -// We use a spurious method instead of the destructor because -// destroying FieldCallbacks can actually be slightly -// performance-sensitive. -void Parser::FieldCallback::_anchor() { -} - // Code-completion pass-through functions void Parser::CodeCompleteDirective(bool InConditional) { @@ -1784,7 +1764,7 @@ void Parser::CodeCompletePreprocessorExpression() { void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo, unsigned ArgumentIndex) { - Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo, + Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo, ArgumentIndex); } @@ -1806,8 +1786,9 @@ bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) { } // Parse nested-name-specifier. - ParseOptionalCXXScopeSpecifier(Result.SS, ParsedType(), - /*EnteringContext=*/false); + if (getLangOpts().CPlusPlus) + ParseOptionalCXXScopeSpecifier(Result.SS, ParsedType(), + /*EnteringContext=*/false); // Check nested-name specifier. if (Result.SS.isInvalid()) { @@ -1828,7 +1809,7 @@ bool Parser::ParseMicrosoftIfExistsCondition(IfExistsCondition& Result) { // Check if the symbol exists. switch (Actions.CheckMicrosoftIfExistsSymbol(getCurScope(), Result.KeywordLoc, - Result.IsIfExists, Result.SS, + Result.IsIfExists, Result.SS, Result.Name)) { case Sema::IER_Exists: Result.Behavior = Result.IsIfExists ? IEB_Parse : IEB_Skip; |