Skip to content

[OpenACC][NFC] Implement basic OpenACC Sema infrastructure #81874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3572,7 +3572,21 @@ class Parser : public CodeCompletionHandler {
StmtResult ParseOpenACCDirectiveStmt();

private:
void ParseOpenACCDirective();
/// A struct to hold the information that got parsed by ParseOpenACCDirective,
/// so that the callers of it can use that to construct the appropriate AST
/// nodes.
struct OpenACCDirectiveParseInfo {
OpenACCDirectiveKind DirKind;
SourceLocation StartLoc;
SourceLocation EndLoc;
// TODO OpenACC: Add Clause list here once we have a type for that.
// TODO OpenACC: As we implement support for the Atomic, Routine, Cache, and
// Wait constructs, we likely want to put that information in here as well.
};

/// Parses the OpenACC directive (the entire pragma) including the clause
/// list, but does not produce the main AST node.
OpenACCDirectiveParseInfo ParseOpenACCDirective();
/// Helper that parses an ID Expression based on the language options.
ExprResult ParseOpenACCIDExpression();
/// Parses the variable list for the `cache` construct.
Expand Down
41 changes: 41 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "clang/Basic/DarwinSDKInfo.h"
#include "clang/Basic/ExpressionTraits.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/OpenACCKinds.h"
#include "clang/Basic/OpenCLOptions.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/PragmaKinds.h"
Expand Down Expand Up @@ -12704,6 +12705,46 @@ class Sema final {
OMPClause *ActOnOpenMPXBareClause(SourceLocation StartLoc,
SourceLocation EndLoc);

//===--------------------------------------------------------------------===//
// OpenACC directives and clauses.

/// Called after parsing an OpenACC Clause so that it can be checked.
bool ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
SourceLocation StartLoc);

/// Called after the construct has been parsed, but clauses haven't been
/// parsed. This allows us to diagnose not-implemented, as well as set up any
/// state required for parsing the clauses.
void ActOnOpenACCConstruct(OpenACCDirectiveKind K, SourceLocation StartLoc);

/// Called after the directive, including its clauses, have been parsed and
/// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
/// happen before any associated declarations or statements have been parsed.
/// This function is only called when we are parsing a 'statement' context.
bool ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc);

/// Called after the directive, including its clauses, have been parsed and
/// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES
/// happen before any associated declarations or statements have been parsed.
/// This function is only called when we are parsing a 'Decl' context.
bool ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc);
/// Called when we encounter an associated statement for our construct, this
/// should check legality of the statement as it appertains to this Construct.
StmtResult ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
StmtResult AssocStmt);

/// Called after the directive has been completely parsed, including the
/// declaration group or associated statement.
StmtResult ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc,
SourceLocation EndLoc,
StmtResult AssocStmt);
/// Called after the directive has been completely parsed, including the
/// declaration group or associated statement.
DeclGroupRef ActOnEndOpenACCDeclDirective();

/// The kind of conversion being performed.
enum CheckedConversionKind {
/// An implicit conversion.
Expand Down
46 changes: 38 additions & 8 deletions clang/lib/Parse/ParseOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,11 @@ void SkipUntilEndOfDirective(Parser &P) {
P.ConsumeAnyToken();
}

bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) {
// TODO OpenACC: Implement.
return false;
}

} // namespace

// OpenACC 3.3, section 1.7:
Expand Down Expand Up @@ -745,9 +750,11 @@ bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) {
<< getCurToken().getIdentifierInfo();

// Consume the clause name.
ConsumeToken();
SourceLocation ClauseLoc = ConsumeToken();

return ParseOpenACCClauseParams(DirKind, Kind);
bool Result = ParseOpenACCClauseParams(DirKind, Kind);
getActions().ActOnOpenACCClause(Kind, ClauseLoc);
return Result;
}

bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind,
Expand Down Expand Up @@ -1116,9 +1123,12 @@ void Parser::ParseOpenACCCacheVarList() {
}
}

void Parser::ParseOpenACCDirective() {
Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() {
SourceLocation StartLoc = getCurToken().getLocation();
OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this);

getActions().ActOnOpenACCConstruct(DirKind, StartLoc);

// Once we've parsed the construct/directive name, some have additional
// specifiers that need to be taken care of. Atomic has an 'atomic-clause'
// that needs to be parsed.
Expand Down Expand Up @@ -1175,7 +1185,10 @@ void Parser::ParseOpenACCDirective() {
Diag(getCurToken(), diag::warn_pragma_acc_unimplemented);
assert(Tok.is(tok::annot_pragma_openacc_end) &&
"Didn't parse all OpenACC Clauses");
ConsumeAnnotationToken();
SourceLocation EndLoc = ConsumeAnnotationToken();
assert(EndLoc.isValid());

return OpenACCDirectiveParseInfo{DirKind, StartLoc, EndLoc};
}

// Parse OpenACC directive on a declaration.
Expand All @@ -1185,9 +1198,14 @@ Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() {
ParsingOpenACCDirectiveRAII DirScope(*this);
ConsumeAnnotationToken();

ParseOpenACCDirective();
OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();

if (getActions().ActOnStartOpenACCDeclDirective(DirInfo.DirKind,
DirInfo.StartLoc))
return nullptr;

return nullptr;
// TODO OpenACC: Do whatever decl parsing is required here.
return DeclGroupPtrTy::make(getActions().ActOnEndOpenACCDeclDirective());
}

// Parse OpenACC Directive on a Statement.
Expand All @@ -1197,7 +1215,19 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() {
ParsingOpenACCDirectiveRAII DirScope(*this);
ConsumeAnnotationToken();

ParseOpenACCDirective();
OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
if (getActions().ActOnStartOpenACCDeclDirective(DirInfo.DirKind,
DirInfo.StartLoc))
return StmtError();

StmtResult AssocStmt;

if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section ends up being slightly worse without being able to check the AST kind here, so we need a separate function to check whether we need to parse one. However, this removes the ASTContext function that was troublesome.

ParsingOpenACCDirectiveRAII DirScope(*this, /*Value=*/false);
AssocStmt = getActions().ActOnOpenACCAssociatedStmt(DirInfo.DirKind,
ParseStatement());
}

return StmtEmpty();
return getActions().ActOnEndOpenACCStmtDirective(
DirInfo.DirKind, DirInfo.StartLoc, DirInfo.EndLoc, AssocStmt);
}
1 change: 1 addition & 0 deletions clang/lib/Sema/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ add_clang_library(clangSema
SemaLookup.cpp
SemaModule.cpp
SemaObjCProperty.cpp
SemaOpenACC.cpp
SemaOpenMP.cpp
SemaOverload.cpp
SemaPseudoObject.cpp
Expand Down
47 changes: 47 additions & 0 deletions clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//===--- SemaOpenACC.cpp - Semantic Analysis for OpenACC constructs -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
/// This file implements semantic analysis for OpenACC constructs and
/// clauses.
///
//===----------------------------------------------------------------------===//

#include "clang/Basic/OpenACCKinds.h"
#include "clang/Sema/Sema.h"

using namespace clang;
bool Sema::ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
SourceLocation StartLoc) {
return true;
}
void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K,
SourceLocation StartLoc) {}

bool Sema::ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc) {
return true;
}

StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc,
SourceLocation EndLoc,
StmtResult AssocStmt) {
return StmtEmpty();
}

StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
StmtResult AssocStmt) {
return AssocStmt;
}

bool Sema::ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc) {
return true;
}

DeclGroupRef Sema::ActOnEndOpenACCDeclDirective() { return DeclGroupRef{}; }