aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/Parser.cpp')
-rw-r--r--lib/Parse/Parser.cpp127
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;