diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 46 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseOpenMP.cpp | 40 |
3 files changed, 85 insertions, 6 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index aa314da8e5b..f8b5fec4380 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -223,6 +223,7 @@ Parser::LateParsedDeclaration::~LateParsedDeclaration() {} void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {} void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {} void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {} +void Parser::LateParsedDeclaration::ParseLexedPragmas() {} Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C) : Self(P), Class(C) {} @@ -243,6 +244,10 @@ void Parser::LateParsedClass::ParseLexedMethodDefs() { Self->ParseLexedMethodDefs(*Class); } +void Parser::LateParsedClass::ParseLexedPragmas() { + Self->ParseLexedPragmas(*Class); +} + void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() { Self->ParseLexedMethodDeclaration(*this); } @@ -255,6 +260,10 @@ void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() { Self->ParseLexedMemberInitializer(*this); } +void Parser::LateParsedPragma::ParseLexedPragmas() { + Self->ParseLexedPragma(*this); +} + /// ParseLexedMethodDeclarations - We finished parsing the member /// specification of a top (non-nested) C++ class. Now go over the /// stack of method declarations with some parts for which parsing was @@ -651,6 +660,43 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { ConsumeAnyToken(); } +void Parser::ParseLexedPragmas(ParsingClass &Class) { + bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope; + ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, + HasTemplateScope); + TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); + if (HasTemplateScope) { + Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate); + ++CurTemplateDepthTracker; + } + bool HasClassScope = !Class.TopLevelClass; + ParseScope ClassScope(this, Scope::ClassScope | Scope::DeclScope, + HasClassScope); + + for (LateParsedDeclaration *LPD : Class.LateParsedDeclarations) + LPD->ParseLexedPragmas(); +} + +void Parser::ParseLexedPragma(LateParsedPragma &LP) { + PP.EnterToken(Tok, /*IsReinject=*/true); + PP.EnterTokenStream(LP.toks(), /*DisableMacroExpansion=*/true, + /*IsReinject=*/true); + + // Consume the previously pushed token. + ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); + assert(Tok.isAnnotation() && "Expected annotation token."); + switch (Tok.getKind()) { + case tok::annot_pragma_openmp: { + AccessSpecifier AS = LP.getAccessSpecifier(); + ParsedAttributesWithRange Attrs(AttrFactory); + (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs); + break; + } + default: + llvm_unreachable("Unexpected token."); + } +} + /// ConsumeAndStoreUntil - Consume and store the token at the passed token /// container until the token 'T' is reached (which gets /// consumed/stored too, if ConsumeFinalToken). diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index fe409327bfb..ca2497ef612 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3136,8 +3136,8 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas( } case tok::annot_pragma_openmp: - return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, AccessAttrs, TagType, - TagDecl); + return ParseOpenMPDeclarativeDirectiveWithExtDecl( + AS, AccessAttrs, /*Delayed=*/true, TagType, TagDecl); default: if (tok::isPragmaAnnotation(Tok.getKind())) { @@ -3355,6 +3355,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // declarations and the lexed inline method definitions, along with any // delayed attributes. SourceLocation SavedPrevTokLocation = PrevTokLocation; + ParseLexedPragmas(getCurrentClass()); ParseLexedAttributes(getCurrentClass()); ParseLexedMethodDeclarations(getCurrentClass()); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index aaef4cd36d3..31ae3af70b7 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1336,14 +1336,45 @@ void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind, /// annot_pragma_openmp_end /// Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( - AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, + AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed, DeclSpec::TST TagType, Decl *Tag) { assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); - SourceLocation Loc = ConsumeAnnotationToken(); - OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this); + SourceLocation Loc; + OpenMPDirectiveKind DKind; + if (Delayed) { + TentativeParsingAction TPA(*this); + Loc = ConsumeAnnotationToken(); + DKind = parseOpenMPDirectiveKind(*this); + if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) { + // Need to delay parsing until completion of the parent class. + TPA.Revert(); + CachedTokens Toks; + unsigned Cnt = 1; + Toks.push_back(Tok); + while (Cnt && Tok.isNot(tok::eof)) { + (void)ConsumeAnyToken(); + if (Tok.is(tok::annot_pragma_openmp)) + ++Cnt; + else if (Tok.is(tok::annot_pragma_openmp_end)) + --Cnt; + Toks.push_back(Tok); + } + // Skip last annot_pragma_openmp_end. + if (Cnt == 0) + (void)ConsumeAnyToken(); + auto *LP = new LateParsedPragma(this, AS); + LP->takeToks(Toks); + getCurrentClass().LateParsedDeclarations.push_back(LP); + return nullptr; + } + TPA.Commit(); + } else { + Loc = ConsumeAnnotationToken(); + DKind = parseOpenMPDirectiveKind(*this); + } switch (DKind) { case OMPD_threadprivate: { @@ -1495,7 +1526,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( DeclGroupPtrTy Ptr; if (Tok.is(tok::annot_pragma_openmp)) { - Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag); + Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed, + TagType, Tag); } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) { // Here we expect to see some function declaration. if (AS == AS_none) { |