Skip to content
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
6 changes: 5 additions & 1 deletion flang/include/flang/Parser/dump-parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ class ParseTreeDumper {
NODE(parser, OmpInitClause)
NODE(OmpInitClause, Modifier)
NODE(parser, OmpInitializerClause)
NODE(parser, OmpInitializerProc)
NODE(parser, OmpInitializerExpression)
NODE(parser, OmpInReductionClause)
NODE(OmpInReductionClause, Modifier)
NODE(parser, OmpInteropPreference)
Expand Down Expand Up @@ -674,6 +674,10 @@ class ParseTreeDumper {
NODE_ENUM(OmpSeverityClause, Severity)
NODE(parser, OmpStepComplexModifier)
NODE(parser, OmpStepSimpleModifier)
NODE(parser, OmpStylizedDeclaration)
NODE(parser, OmpStylizedExpression)
NODE(parser, OmpStylizedInstance)
NODE(OmpStylizedInstance, Instance)
NODE(parser, OmpTaskDependenceType)
NODE_ENUM(OmpTaskDependenceType, Value)
NODE(parser, OmpTaskReductionClause)
Expand Down
22 changes: 22 additions & 0 deletions flang/include/flang/Parser/openmp-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@

namespace Fortran::parser::omp {

template <typename T> constexpr auto addr_if(std::optional<T> &x) {
return x ? &*x : nullptr;
}
template <typename T> constexpr auto addr_if(const std::optional<T> &x) {
return x ? &*x : nullptr;
}

namespace detail {
using D = llvm::omp::Directive;

Expand Down Expand Up @@ -133,9 +140,24 @@ template <typename T> OmpDirectiveName GetOmpDirectiveName(const T &x) {
}

const OmpObjectList *GetOmpObjectList(const OmpClause &clause);

template <typename T>
const T *GetFirstArgument(const OmpDirectiveSpecification &spec) {
for (const OmpArgument &arg : spec.Arguments().v) {
if (auto *t{std::get_if<T>(&arg.u)}) {
return t;
}
}
return nullptr;
}

const BlockConstruct *GetFortranBlockConstruct(
const ExecutionPartConstruct &epc);

const OmpCombinerExpression *GetCombinerExpr(
const OmpReductionSpecifier &rspec);
const OmpInitializerExpression *GetInitializerExpr(const OmpClause &init);

} // namespace Fortran::parser::omp

#endif // FORTRAN_PARSER_OPENMP_UTILS_H
65 changes: 54 additions & 11 deletions flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
#include "provenance.h"
#include "flang/Common/idioms.h"
#include "flang/Common/indirection.h"
#include "flang/Common/reference.h"
#include "flang/Support/Fortran.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Frontend/OpenACC/ACC.h.inc"
#include "llvm/Frontend/OpenMP/OMP.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
Expand Down Expand Up @@ -3504,6 +3506,8 @@ struct OmpDirectiveName {

// type-name list item
struct OmpTypeName {
CharBlock source;
mutable const semantics::DeclTypeSpec *declTypeSpec{nullptr};
UNION_CLASS_BOILERPLATE(OmpTypeName);
std::variant<TypeSpec, DeclarationTypeSpec> u;
};
Expand Down Expand Up @@ -3532,6 +3536,39 @@ struct OmpObjectList {
WRAPPER_CLASS_BOILERPLATE(OmpObjectList, std::list<OmpObject>);
};

struct OmpStylizedDeclaration {
COPY_AND_ASSIGN_BOILERPLATE(OmpStylizedDeclaration);
// Since "Reference" isn't handled by parse-tree-visitor, add EmptyTrait,
// and visit the members by hand when needed.
using EmptyTrait = std::true_type;
common::Reference<const OmpTypeName> type;
EntityDecl var;
};

struct OmpStylizedInstance {
struct Instance {
UNION_CLASS_BOILERPLATE(Instance);
std::variant<AssignmentStmt, CallStmt, common::Indirection<Expr>> u;
};
TUPLE_CLASS_BOILERPLATE(OmpStylizedInstance);
std::tuple<std::list<OmpStylizedDeclaration>, Instance> t;
};

class ParseState;

// Ref: [5.2:76], [6.0:185]
//
struct OmpStylizedExpression {
CharBlock source;
// Pointer to a temporary copy of the ParseState that is used to create
// additional parse subtrees for the stylized expression. This is only
// used internally during parsing and conveys no information to the
// consumers of the AST.
const ParseState *state{nullptr};
WRAPPER_CLASS_BOILERPLATE(
OmpStylizedExpression, std::list<OmpStylizedInstance>);
};

// Ref: [4.5:201-207], [5.0:293-299], [5.1:325-331], [5.2:124]
//
// reduction-identifier ->
Expand All @@ -3549,9 +3586,22 @@ struct OmpReductionIdentifier {
// combiner-expression -> // since 4.5
// assignment-statement |
// function-reference
struct OmpCombinerExpression {
UNION_CLASS_BOILERPLATE(OmpCombinerExpression);
std::variant<AssignmentStmt, FunctionReference> u;
struct OmpCombinerExpression : public OmpStylizedExpression {
INHERITED_WRAPPER_CLASS_BOILERPLATE(
OmpCombinerExpression, OmpStylizedExpression);
static llvm::ArrayRef<CharBlock> Variables();
};

// Ref: [4.5:222:7-8], [5.0:305:28-29], [5.1:337:20-21], [5.2:127:6-8],
// [6.0:242:3-5]
//
// initializer-expression -> // since 4.5
// OMP_PRIV = expression |
// subroutine-name(argument-list)
struct OmpInitializerExpression : public OmpStylizedExpression {
INHERITED_WRAPPER_CLASS_BOILERPLATE(
OmpInitializerExpression, OmpStylizedExpression);
static llvm::ArrayRef<CharBlock> Variables();
};

inline namespace arguments {
Expand Down Expand Up @@ -4552,16 +4602,9 @@ struct OmpInReductionClause {
std::tuple<MODIFIERS(), OmpObjectList> t;
};

// declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list
// : combiner) [initializer-clause]
struct OmpInitializerProc {
TUPLE_CLASS_BOILERPLATE(OmpInitializerProc);
std::tuple<ProcedureDesignator, std::list<ActualArgSpec>> t;
};
// Initialization for declare reduction construct
struct OmpInitializerClause {
UNION_CLASS_BOILERPLATE(OmpInitializerClause);
std::variant<OmpInitializerProc, AssignmentStmt> u;
WRAPPER_CLASS_BOILERPLATE(OmpInitializerClause, OmpInitializerExpression);
};

// Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117]
Expand Down
2 changes: 2 additions & 0 deletions flang/include/flang/Semantics/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,8 @@ class Symbol {
OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
// OpenMP data-copying attribute
OmpCopyIn, OmpCopyPrivate,
// OpenMP special variables
OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
// OpenMP miscellaneous flags
OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned, OmpNontemporal,
OmpAllocate, OmpDeclarativeAllocateDirective,
Expand Down
Loading