diff options
Diffstat (limited to 'clang/lib/Parse/Parser.cpp')
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 65 |
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) |
