@@ -3469,6 +3469,12 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
34693469
34703470// --- Common definitions
34713471
3472+ #define INHERITED_TUPLE_CLASS_BOILERPLATE (classname, basename ) \
3473+ using basename::basename; \
3474+ classname (basename &&b) : basename(std::move(b)) {} \
3475+ using TupleTrait = std::true_type; \
3476+ BOILERPLATE (classname)
3477+
34723478#define INHERITED_WRAPPER_CLASS_BOILERPLATE (classname, basename ) \
34733479 BOILERPLATE (classname); \
34743480 using basename::basename; \
@@ -4750,6 +4756,33 @@ struct OmpDirectiveSpecification {
47504756 t;
47514757};
47524758
4759+ // OmpBeginDirective and OmpEndDirective are needed for semantic analysis,
4760+ // where some checks are done specifically for either the begin or the end
4761+ // directive. The structure of both is identical, but the diffent types
4762+ // allow to distinguish them in the type-based parse-tree visitor.
4763+ struct OmpBeginDirective : public OmpDirectiveSpecification {
4764+ INHERITED_TUPLE_CLASS_BOILERPLATE (
4765+ OmpBeginDirective, OmpDirectiveSpecification);
4766+ };
4767+
4768+ struct OmpEndDirective : public OmpDirectiveSpecification {
4769+ INHERITED_TUPLE_CLASS_BOILERPLATE (OmpEndDirective, OmpDirectiveSpecification);
4770+ };
4771+
4772+ // Common base class for block-associated constructs.
4773+ struct OmpBlockConstruct {
4774+ TUPLE_CLASS_BOILERPLATE (OmpBlockConstruct);
4775+ const OmpBeginDirective &BeginDir () const {
4776+ return std::get<OmpBeginDirective>(t);
4777+ }
4778+ const std::optional<OmpEndDirective> &EndDir () const {
4779+ return std::get<std::optional<OmpEndDirective>>(t);
4780+ }
4781+
4782+ CharBlock source;
4783+ std::tuple<OmpBeginDirective, Block, std::optional<OmpEndDirective>> t;
4784+ };
4785+
47534786struct OmpMetadirectiveDirective {
47544787 TUPLE_CLASS_BOILERPLATE (OmpMetadirectiveDirective);
47554788 std::tuple<Verbatim, OmpClauseList> t;
@@ -4854,12 +4887,6 @@ struct OpenMPSectionsConstruct {
48544887 t;
48554888};
48564889
4857- // OpenMP directive beginning or ending a block
4858- struct OmpBlockDirective {
4859- WRAPPER_CLASS_BOILERPLATE (OmpBlockDirective, llvm::omp::Directive);
4860- CharBlock source;
4861- };
4862-
48634890struct OmpDeclareVariantDirective {
48644891 TUPLE_CLASS_BOILERPLATE (OmpDeclareVariantDirective);
48654892 CharBlock source;
@@ -4984,12 +5011,9 @@ struct OpenMPExecutableAllocate {
49845011// ALLOCATORS [allocate-clause...]
49855012// block
49865013// [END ALLOCATORS]
4987- struct OpenMPAllocatorsConstruct {
4988- TUPLE_CLASS_BOILERPLATE (OpenMPAllocatorsConstruct);
4989- CharBlock source;
4990- std::tuple<OmpDirectiveSpecification, Block,
4991- std::optional<OmpDirectiveSpecification>>
4992- t;
5014+ struct OpenMPAllocatorsConstruct : public OmpBlockConstruct {
5015+ INHERITED_TUPLE_CLASS_BOILERPLATE (
5016+ OpenMPAllocatorsConstruct, OmpBlockConstruct);
49935017};
49945018
49955019// 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0]
@@ -5003,15 +5027,11 @@ struct OmpMemoryOrderClause {
50035027 CharBlock source;
50045028};
50055029
5006- struct OpenMPAtomicConstruct {
5030+ struct OpenMPAtomicConstruct : public OmpBlockConstruct {
50075031 llvm::omp::Clause GetKind () const ;
50085032 bool IsCapture () const ;
50095033 bool IsCompare () const ;
5010- TUPLE_CLASS_BOILERPLATE (OpenMPAtomicConstruct);
5011- CharBlock source;
5012- std::tuple<OmpDirectiveSpecification, Block,
5013- std::optional<OmpDirectiveSpecification>>
5014- t;
5034+ INHERITED_TUPLE_CLASS_BOILERPLATE (OpenMPAtomicConstruct, OmpBlockConstruct);
50155035
50165036 // Information filled out during semantic checks to avoid duplication
50175037 // of analyses.
@@ -5075,12 +5095,8 @@ struct OpenMPDepobjConstruct {
50755095// nocontext-clause |
50765096// novariants-clause |
50775097// nowait-clause
5078- struct OpenMPDispatchConstruct {
5079- TUPLE_CLASS_BOILERPLATE (OpenMPDispatchConstruct);
5080- CharBlock source;
5081- std::tuple<OmpDirectiveSpecification, Block,
5082- std::optional<OmpDirectiveSpecification>>
5083- t;
5098+ struct OpenMPDispatchConstruct : public OmpBlockConstruct {
5099+ INHERITED_TUPLE_CLASS_BOILERPLATE (OpenMPDispatchConstruct, OmpBlockConstruct);
50845100};
50855101
50865102// [4.5:162-165], [5.0:242-246], [5.1:275-279], [5.2:315-316], [6.0:498-500]
@@ -5135,22 +5151,8 @@ struct OmpEndLoopDirective {
51355151 CharBlock source;
51365152};
51375153
5138- struct OmpBeginBlockDirective {
5139- TUPLE_CLASS_BOILERPLATE (OmpBeginBlockDirective);
5140- std::tuple<OmpBlockDirective, OmpClauseList> t;
5141- CharBlock source;
5142- };
5143-
5144- struct OmpEndBlockDirective {
5145- TUPLE_CLASS_BOILERPLATE (OmpEndBlockDirective);
5146- std::tuple<OmpBlockDirective, OmpClauseList> t;
5147- CharBlock source;
5148- };
5149-
5150- struct OpenMPBlockConstruct {
5151- TUPLE_CLASS_BOILERPLATE (OpenMPBlockConstruct);
5152- std::tuple<OmpBeginBlockDirective, Block, std::optional<OmpEndBlockDirective>>
5153- t;
5154+ struct OpenMPBlockConstruct : public OmpBlockConstruct {
5155+ INHERITED_TUPLE_CLASS_BOILERPLATE (OpenMPBlockConstruct, OmpBlockConstruct);
51545156};
51555157
51565158// OpenMP directives enclosing do loop
0 commit comments