Skip to content

Commit 7ac9efb

Browse files
committed
[OPENMP50]Add basic support for array-shaping operation.
Summary: Added basic representation and parsing/sema handling of array-shaping operations. Array shaping expression is an expression of form ([s0]..[sn])base, where s0, ..., sn must be a positive integer, base - a pointer. This expression is a kind of cast operation that converts pointer expression into an array-like kind of expression. Reviewers: rjmccall, rsmith, jdoerfert Subscribers: guansong, arphaman, cfe-commits, caomhin, kkwli0 Tags: #clang Differential Revision: https://reviews.llvm.org/D74144
1 parent 01ba2ad commit 7ac9efb

39 files changed

+456
-23
lines changed

clang/include/clang-c/Index.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2176,7 +2176,11 @@ enum CXCursorKind {
21762176
*/
21772177
CXCursor_FixedPointLiteral = 149,
21782178

2179-
CXCursor_LastExpr = CXCursor_FixedPointLiteral,
2179+
/** OpenMP 5.0 [2.1.4, Array Shaping].
2180+
*/
2181+
CXCursor_OMPArrayShapingExpr = 150,
2182+
2183+
CXCursor_LastExpr = CXCursor_OMPArrayShapingExpr,
21802184

21812185
/* Statements */
21822186
CXCursor_FirstStmt = 200,

clang/include/clang/AST/ASTContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
970970
#include "clang/Basic/OpenCLImageTypes.def"
971971
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
972972
CanQualType OCLQueueTy, OCLReserveIDTy;
973-
CanQualType OMPArraySectionTy;
973+
CanQualType OMPArraySectionTy, OMPArrayShapingTy;
974974
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
975975
CanQualType Id##Ty;
976976
#include "clang/Basic/OpenCLExtensionTypes.def"

clang/include/clang/AST/BuiltinTypes.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,11 @@ PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
313313
// A placeholder type for OpenMP array sections.
314314
PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy)
315315

316+
// A placeholder type for OpenMP array shaping operation.
317+
PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy)
318+
316319
#ifdef LAST_BUILTIN_TYPE
317-
LAST_BUILTIN_TYPE(OMPArraySection)
320+
LAST_BUILTIN_TYPE(OMPArrayShaping)
318321
#undef LAST_BUILTIN_TYPE
319322
#endif
320323

clang/include/clang/AST/ComputeDependence.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class ParenListExpr;
8787
class PseudoObjectExpr;
8888
class AtomicExpr;
8989
class OMPArraySectionExpr;
90+
class OMPArrayShapingExpr;
9091
class ObjCArrayLiteral;
9192
class ObjCDictionaryLiteral;
9293
class ObjCBoxedExpr;
@@ -172,6 +173,7 @@ ExprDependence computeDependence(PseudoObjectExpr *E);
172173
ExprDependence computeDependence(AtomicExpr *E);
173174

174175
ExprDependence computeDependence(OMPArraySectionExpr *E);
176+
ExprDependence computeDependence(OMPArrayShapingExpr *E);
175177

176178
ExprDependence computeDependence(ObjCArrayLiteral *E);
177179
ExprDependence computeDependence(ObjCDictionaryLiteral *E);

clang/include/clang/AST/ExprOpenMP.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,95 @@ class OMPArraySectionExpr : public Expr {
116116
return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
117117
}
118118
};
119+
120+
/// An explicit cast in C or a C-style cast in C++, which uses the syntax
121+
/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f.
122+
class OMPArrayShapingExpr final
123+
: public Expr,
124+
private llvm::TrailingObjects<OMPArrayShapingExpr, Expr *, SourceRange> {
125+
friend TrailingObjects;
126+
friend class ASTStmtReader;
127+
friend class ASTStmtWriter;
128+
/// Base node.
129+
SourceLocation LPLoc; /// The location of the left paren
130+
SourceLocation RPLoc; /// The location of the right paren
131+
unsigned NumDims = 0; /// Number of dimensions in the shaping expression.
132+
133+
/// Construct full expression.
134+
OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L,
135+
SourceLocation R, ArrayRef<Expr *> Dims);
136+
137+
/// Construct an empty expression.
138+
explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims)
139+
: Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {}
140+
141+
/// Sets the dimensions for the array shaping.
142+
void setDimensions(ArrayRef<Expr *> Dims);
143+
144+
/// Sets the base expression for array shaping operation.
145+
void setBase(Expr *Op) { getTrailingObjects<Expr *>()[NumDims] = Op; }
146+
147+
/// Sets source ranges for the brackets in the array shaping operation.
148+
void setBracketsRanges(ArrayRef<SourceRange> BR);
149+
150+
unsigned numTrailingObjects(OverloadToken<Expr *>) const {
151+
// Add an extra one for the base expression.
152+
return NumDims + 1;
153+
}
154+
155+
unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
156+
return NumDims;
157+
}
158+
159+
public:
160+
static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T,
161+
Expr *Op, SourceLocation L,
162+
SourceLocation R, ArrayRef<Expr *> Dims,
163+
ArrayRef<SourceRange> BracketRanges);
164+
165+
static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context,
166+
unsigned NumDims);
167+
168+
SourceLocation getLParenLoc() const { return LPLoc; }
169+
void setLParenLoc(SourceLocation L) { LPLoc = L; }
170+
171+
SourceLocation getRParenLoc() const { return RPLoc; }
172+
void setRParenLoc(SourceLocation L) { RPLoc = L; }
173+
174+
SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
175+
SourceLocation getEndLoc() const LLVM_READONLY {
176+
return getBase()->getEndLoc();
177+
}
178+
179+
/// Fetches the dimensions for array shaping expression.
180+
ArrayRef<Expr *> getDimensions() const {
181+
return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumDims);
182+
}
183+
184+
/// Fetches source ranges for the brackets os the array shaping expression.
185+
ArrayRef<SourceRange> getBracketsRanges() const {
186+
return llvm::makeArrayRef(getTrailingObjects<SourceRange>(), NumDims);
187+
}
188+
189+
/// Fetches base expression of array shaping expression.
190+
Expr *getBase() { return getTrailingObjects<Expr *>()[NumDims]; }
191+
const Expr *getBase() const { return getTrailingObjects<Expr *>()[NumDims]; }
192+
193+
static bool classof(const Stmt *T) {
194+
return T->getStmtClass() == OMPArrayShapingExprClass;
195+
}
196+
197+
// Iterators
198+
child_range children() {
199+
Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
200+
return child_range(Begin, Begin + NumDims + 1);
201+
}
202+
const_child_range children() const {
203+
Stmt *const *Begin =
204+
reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
205+
return const_child_range(Begin, Begin + NumDims + 1);
206+
}
207+
};
119208
} // end namespace clang
120209

121210
#endif

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2551,6 +2551,7 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
25512551
DEF_TRAVERSE_STMT(AddrLabelExpr, {})
25522552
DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
25532553
DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
2554+
DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
25542555

25552556
DEF_TRAVERSE_STMT(BlockExpr, {
25562557
TRY_TO(TraverseDecl(S->getBlockDecl()));

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9685,7 +9685,7 @@ def err_omp_expected_var_name_member_expr : Error<
96859685
def err_omp_expected_var_name_member_expr_or_array_item : Error<
96869686
"expected variable name%select{|, data member of current class}0, array element or array section">;
96879687
def err_omp_expected_addressable_lvalue_or_array_item : Error<
9688-
"expected addressable lvalue expression, array element or array section%select{| of non 'omp_depend_t' type}0">;
9688+
"expected addressable lvalue expression, array element%select{ or array section|, array section or array shaping expression}0%select{| of non 'omp_depend_t' type}1">;
96899689
def err_omp_expected_named_var_member_or_array_expression: Error<
96909690
"expected expression containing only member accesses and/or array sections based on named variables">;
96919691
def err_omp_bit_fields_forbidden_in_clause : Error<
@@ -9952,10 +9952,15 @@ def err_omp_declare_mapper_redefinition : Error<
99529952
def err_omp_invalid_mapper: Error<
99539953
"cannot find a valid user-defined mapper for type %0 with name %1">;
99549954
def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">;
9955+
def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">;
99559956
def err_omp_typecheck_section_value : Error<
99569957
"subscripted value is not an array or pointer">;
99579958
def err_omp_typecheck_section_not_integer : Error<
99589959
"array section %select{lower bound|length}0 is not an integer">;
9960+
def err_omp_typecheck_shaping_not_integer : Error<
9961+
"array shaping operation dimension is not an integer">;
9962+
def err_omp_shaping_dimension_not_positive : Error<
9963+
"array shaping dimension is evaluated to a non-positive value %0">;
99599964
def err_omp_section_function_type : Error<
99609965
"section of pointer to function type %0">;
99619966
def warn_omp_section_is_char : Warning<"array section %select{lower bound|length}0 is of type 'char'">,
@@ -10190,14 +10195,15 @@ def err_omp_flush_order_clause_and_list : Error<
1019010195
def note_omp_flush_order_clause_here : Note<
1019110196
"memory order clause '%0' is specified here">;
1019210197
def err_omp_non_lvalue_in_map_or_motion_clauses: Error<
10193-
"expected addressable lvalue in '%0' clause"
10194-
>;
10198+
"expected addressable lvalue in '%0' clause">;
1019510199
def err_omp_event_var_expected : Error<
1019610200
"expected variable of the 'omp_event_handle_t' type%select{|, not %1}0">;
1019710201
def warn_nested_declare_variant
1019810202
: Warning<"nesting `omp begin/end declare variant` is not supported yet; "
1019910203
"nested context ignored">,
1020010204
InGroup<SourceUsesOpenMP>;
10205+
def err_omp_non_pointer_type_array_shaping_base : Error<
10206+
"expected pointer type expression as a base of an array shaping operation">;
1020110207
} // end of OpenMP category
1020210208

1020310209
let CategoryName = "Related Result Type Issue" in {

clang/include/clang/Basic/StmtNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def BinaryConditionalOperator : StmtNode<AbstractConditionalOperator>;
8181
def ImplicitCastExpr : StmtNode<CastExpr>;
8282
def ExplicitCastExpr : StmtNode<CastExpr, 1>;
8383
def CStyleCastExpr : StmtNode<ExplicitCastExpr>;
84+
def OMPArrayShapingExpr : StmtNode<Expr>;
8485
def CompoundLiteralExpr : StmtNode<Expr>;
8586
def ExtVectorElementExpr : StmtNode<Expr>;
8687
def InitListExpr : StmtNode<Expr>;

clang/include/clang/Parse/Parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3010,6 +3010,10 @@ class Parser : public CodeCompletionHandler {
30103010
DeclarationName &Name,
30113011
AccessSpecifier AS = AS_none);
30123012

3013+
/// Tries to parse cast part of OpenMP array shaping operation:
3014+
/// '[' expression ']' { '[' expression ']' } ')'.
3015+
bool tryParseOpenMPArrayShapingCastPart();
3016+
30133017
/// Parses simple list of variables.
30143018
///
30153019
/// \param Kind Kind of the directive.

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4899,6 +4899,10 @@ class Sema final {
48994899
ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
49004900
Expr *LowerBound, SourceLocation ColonLoc,
49014901
Expr *Length, SourceLocation RBLoc);
4902+
ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
4903+
SourceLocation RParenLoc,
4904+
ArrayRef<Expr *> Dims,
4905+
ArrayRef<SourceRange> Brackets);
49024906

49034907
// This struct is for use by ActOnMemberAccess to allow
49044908
// BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after

0 commit comments

Comments
 (0)