diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2020-01-07 13:39:18 -0500 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2020-01-07 13:44:10 -0500 |
commit | c972f6fd7919b737f4c991d27249b9a947011c8e (patch) | |
tree | 8dfd577cbf77d42d61bf0f052644f597fbf53089 /clang/lib/Parse/ParseCXXInlineMethods.cpp | |
parent | 16f47cf607c7193e888de4c1774c46367a5bedf4 (diff) | |
download | bcm5719-llvm-c972f6fd7919b737f4c991d27249b9a947011c8e.tar.gz bcm5719-llvm-c972f6fd7919b737f4c991d27249b9a947011c8e.zip |
[OPENMP]Allow using of members in standalone declaration pragmas.
If standalone OpenMP declaration pragma, like declare mapper or declare
reduction, is declared in the class context, it may reference a member
(data or function) in its internal expressions/statements. So, the
parsing of such pragmas must be dalayed just like the parsing of the
member initializers/definitions before the completion of the class
declaration.
Diffstat (limited to 'clang/lib/Parse/ParseCXXInlineMethods.cpp')
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 46 |
1 files changed, 46 insertions, 0 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). |