summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp46
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp5
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp40
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) {
OpenPOWER on IntegriCloud