@@ -3469,6 +3469,12 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
3469
3469
3470
3470
// --- Common definitions
3471
3471
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
+
3472
3478
#define INHERITED_WRAPPER_CLASS_BOILERPLATE (classname, basename ) \
3473
3479
BOILERPLATE (classname); \
3474
3480
using basename::basename; \
@@ -4750,6 +4756,33 @@ struct OmpDirectiveSpecification {
4750
4756
t;
4751
4757
};
4752
4758
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
+
4753
4786
struct OmpMetadirectiveDirective {
4754
4787
TUPLE_CLASS_BOILERPLATE (OmpMetadirectiveDirective);
4755
4788
std::tuple<Verbatim, OmpClauseList> t;
@@ -4854,12 +4887,6 @@ struct OpenMPSectionsConstruct {
4854
4887
t;
4855
4888
};
4856
4889
4857
- // OpenMP directive beginning or ending a block
4858
- struct OmpBlockDirective {
4859
- WRAPPER_CLASS_BOILERPLATE (OmpBlockDirective, llvm::omp::Directive);
4860
- CharBlock source;
4861
- };
4862
-
4863
4890
struct OmpDeclareVariantDirective {
4864
4891
TUPLE_CLASS_BOILERPLATE (OmpDeclareVariantDirective);
4865
4892
CharBlock source;
@@ -4984,12 +5011,9 @@ struct OpenMPExecutableAllocate {
4984
5011
// ALLOCATORS [allocate-clause...]
4985
5012
// block
4986
5013
// [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);
4993
5017
};
4994
5018
4995
5019
// 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0]
@@ -5003,15 +5027,11 @@ struct OmpMemoryOrderClause {
5003
5027
CharBlock source;
5004
5028
};
5005
5029
5006
- struct OpenMPAtomicConstruct {
5030
+ struct OpenMPAtomicConstruct : public OmpBlockConstruct {
5007
5031
llvm::omp::Clause GetKind () const ;
5008
5032
bool IsCapture () const ;
5009
5033
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);
5015
5035
5016
5036
// Information filled out during semantic checks to avoid duplication
5017
5037
// of analyses.
@@ -5075,12 +5095,8 @@ struct OpenMPDepobjConstruct {
5075
5095
// nocontext-clause |
5076
5096
// novariants-clause |
5077
5097
// 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);
5084
5100
};
5085
5101
5086
5102
// [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 {
5135
5151
CharBlock source;
5136
5152
};
5137
5153
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);
5154
5156
};
5155
5157
5156
5158
// OpenMP directives enclosing do loop
0 commit comments