aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Parse/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/Parser.cpp')
-rw-r--r--clang/lib/Parse/Parser.cpp65
1 files changed, 53 insertions, 12 deletions
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index b1ccbeb99e58..1baeb2aeb021 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -13,8 +13,8 @@
#include "clang/Parse/Parser.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ASTLambda.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/FileManager.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/RAIIObjectsForParser.h"
@@ -22,6 +22,7 @@
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/TimeProfiler.h"
using namespace clang;
@@ -317,6 +318,13 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
return false;
ConsumeAnnotationToken();
break;
+ case tok::annot_pragma_openacc:
+ case tok::annot_pragma_openacc_end:
+ // Stop before an OpenACC pragma boundary.
+ if (OpenACCDirectiveParsing)
+ return false;
+ ConsumeAnnotationToken();
+ break;
case tok::annot_module_begin:
case tok::annot_module_end:
case tok::annot_module_include:
@@ -615,6 +623,11 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
Sema::ModuleImportState &ImportState) {
DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
+ // Skip over the EOF token, flagging end of previous input for incremental
+ // processing
+ if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))
+ ConsumeToken();
+
Result = nullptr;
switch (Tok.getKind()) {
case tok::annot_pragma_unused:
@@ -845,6 +858,8 @@ Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
AccessSpecifier AS = AS_none;
return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
}
+ case tok::annot_pragma_openacc:
+ return ParseOpenACCDirectiveDecl();
case tok::annot_pragma_ms_pointers_to_members:
HandlePragmaMSPointersToMembers();
return nullptr;
@@ -923,9 +938,16 @@ Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
/*IsInstanceMethod=*/std::nullopt,
/*ReturnType=*/nullptr);
}
- Actions.CodeCompleteOrdinaryName(
- getCurScope(),
- CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
+
+ Sema::ParserCompletionContext PCC;
+ if (CurParsedObjCImpl) {
+ PCC = Sema::PCC_ObjCImplementation;
+ } else if (PP.isIncrementalProcessingEnabled()) {
+ PCC = Sema::PCC_TopLevelOrExpression;
+ } else {
+ PCC = Sema::PCC_Namespace;
+ };
+ Actions.CodeCompleteOrdinaryName(getCurScope(), PCC);
return nullptr;
case tok::kw_import: {
Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
@@ -1031,7 +1053,7 @@ Parser::ParseExternalDeclaration(ParsedAttributes &Attrs,
ConsumeToken();
return nullptr;
}
- if (PP.isIncrementalProcessingEnabled() &&
+ if (getLangOpts().IncrementalExtensions &&
!isDeclarationStatement(/*DisambiguatingWithExpression=*/true))
return ParseTopLevelStmtDecl();
@@ -1157,6 +1179,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
getCurScope(), AS_none, DS, ParsedAttributesView::none(), AnonRecord);
DS.complete(TheDecl);
+ Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
if (AnonRecord) {
Decl* decls[] = {AnonRecord, TheDecl};
return Actions.BuildDeclaratorGroup(decls);
@@ -1164,6 +1187,9 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
return Actions.ConvertDeclToDeclGroup(TheDecl);
}
+ if (DS.hasTagDefinition())
+ Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl());
+
// ObjC2 allows prefix attributes on class interfaces and protocols.
// FIXME: This still needs better diagnostics. We should only accept
// attributes here, no types, etc.
@@ -1213,6 +1239,13 @@ Parser::DeclGroupPtrTy Parser::ParseDeclOrFunctionDefInternal(
Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition(
ParsedAttributes &Attrs, ParsedAttributes &DeclSpecAttrs,
ParsingDeclSpec *DS, AccessSpecifier AS) {
+ // Add an enclosing time trace scope for a bunch of small scopes with
+ // "EvaluateAsConstExpr".
+ llvm::TimeTraceScope TimeScope("ParseDeclarationOrFunctionDefinition", [&]() {
+ return Tok.getLocation().printToString(
+ Actions.getASTContext().getSourceManager());
+ });
+
if (DS) {
return ParseDeclOrFunctionDefInternal(Attrs, DeclSpecAttrs, *DS, AS);
} else {
@@ -1243,6 +1276,10 @@ Parser::DeclGroupPtrTy Parser::ParseDeclarationOrFunctionDefinition(
Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
const ParsedTemplateInfo &TemplateInfo,
LateParsedAttrList *LateParsedAttrs) {
+ llvm::TimeTraceScope TimeScope("ParseFunctionDefinition", [&]() {
+ return Actions.GetNameForDeclarator(D).getName().getAsString();
+ });
+
// Poison SEH identifiers so they are flagged as illegal in function bodies.
PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);
const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
@@ -1433,12 +1470,12 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
// With abbreviated function templates - we need to explicitly add depth to
// account for the implicit template parameter list induced by the template.
- if (auto *Template = dyn_cast_or_null<FunctionTemplateDecl>(Res))
- if (Template->isAbbreviated() &&
- Template->getTemplateParameters()->getParam(0)->isImplicit())
- // First template parameter is implicit - meaning no explicit template
- // parameter list was specified.
- CurTemplateDepthTracker.addDepth(1);
+ if (const auto *Template = dyn_cast_if_present<FunctionTemplateDecl>(Res);
+ Template && Template->isAbbreviated() &&
+ Template->getTemplateParameters()->getParam(0)->isImplicit())
+ // First template parameter is implicit - meaning no explicit template
+ // parameter list was specified.
+ CurTemplateDepthTracker.addDepth(1);
if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) &&
trySkippingFunctionBody()) {
@@ -2107,7 +2144,7 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(
}
if (!getLangOpts().CPlusPlus) {
- // If we're in C, the only place we can have :: tokens is C2x
+ // If we're in C, the only place we can have :: tokens is C23
// attribute which is parsed elsewhere. If the identifier is not a type,
// then it can't be scope either, just early exit.
return false;
@@ -2548,6 +2585,10 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc,
SeenError = false;
break;
case Sema::ModuleImportState::FirstDecl:
+ // If we found an import decl as the first declaration, we must be not in
+ // a C++20 module unit or we are in an invalid state.
+ ImportState = Sema::ModuleImportState::NotACXX20Module;
+ [[fallthrough]];
case Sema::ModuleImportState::NotACXX20Module:
// We can only import a partition within a module purview.
if (IsPartition)