[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
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 461b155..8bee34e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1386,8 +1386,10 @@
InitBuiltinType(BuiltinFnTy, BuiltinType::BuiltinFn);
// Placeholder type for OMP array sections.
- if (LangOpts.OpenMP)
+ if (LangOpts.OpenMP) {
InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection);
+ InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping);
+ }
// C99 6.2.5p11.
FloatComplexTy = getComplexType(FloatTy);
diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index b51164e..a023ed1 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -363,6 +363,15 @@
return D;
}
+ExprDependence clang::computeDependence(OMPArrayShapingExpr *E) {
+ auto D = E->getBase()->getDependence() |
+ toExprDependence(E->getType()->getDependence());
+ for (Expr *Dim: E->getDimensions())
+ if (Dim)
+ D |= Dim->getDependence();
+ return D;
+}
+
/// Compute the type-, value-, and instantiation-dependence of a
/// declaration reference
/// based on the declaration being referenced.
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index f0f22b6..fb63897 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -3398,6 +3398,7 @@
case ParenExprClass:
case ArraySubscriptExprClass:
case OMPArraySectionExprClass:
+ case OMPArrayShapingExprClass:
case MemberExprClass:
case ConditionalOperatorClass:
case BinaryConditionalOperatorClass:
@@ -4569,3 +4570,50 @@
alignof(RecoveryExpr));
return new (Mem) RecoveryExpr(EmptyShell());
}
+
+void OMPArrayShapingExpr::setDimensions(ArrayRef<Expr *> Dims) {
+ assert(
+ NumDims == Dims.size() &&
+ "Preallocated number of dimensions is different from the provided one.");
+ llvm::copy(Dims, getTrailingObjects<Expr *>());
+}
+
+void OMPArrayShapingExpr::setBracketsRanges(ArrayRef<SourceRange> BR) {
+ assert(
+ NumDims == BR.size() &&
+ "Preallocated number of dimensions is different from the provided one.");
+ llvm::copy(BR, getTrailingObjects<SourceRange>());
+}
+
+OMPArrayShapingExpr::OMPArrayShapingExpr(QualType ExprTy, Expr *Op,
+ SourceLocation L, SourceLocation R,
+ ArrayRef<Expr *> Dims)
+ : Expr(OMPArrayShapingExprClass, ExprTy, VK_LValue, OK_Ordinary), LPLoc(L),
+ RPLoc(R), NumDims(Dims.size()) {
+ setBase(Op);
+ setDimensions(Dims);
+ setDependence(computeDependence(this));
+}
+
+OMPArrayShapingExpr *
+OMPArrayShapingExpr::Create(const ASTContext &Context, QualType T, Expr *Op,
+ SourceLocation L, SourceLocation R,
+ ArrayRef<Expr *> Dims,
+ ArrayRef<SourceRange> BracketRanges) {
+ assert(Dims.size() == BracketRanges.size() &&
+ "Different number of dimensions and brackets ranges.");
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Expr *, SourceRange>(Dims.size() + 1, Dims.size()),
+ alignof(OMPArrayShapingExpr));
+ auto *E = new (Mem) OMPArrayShapingExpr(T, Op, L, R, Dims);
+ E->setBracketsRanges(BracketRanges);
+ return E;
+}
+
+OMPArrayShapingExpr *OMPArrayShapingExpr::CreateEmpty(const ASTContext &Context,
+ unsigned NumDims) {
+ void *Mem = Context.Allocate(
+ totalSizeToAlloc<Expr *, SourceRange>(NumDims + 1, NumDims),
+ alignof(OMPArrayShapingExpr));
+ return new (Mem) OMPArrayShapingExpr(EmptyShell(), NumDims);
+}
diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp
index 58e7034..4505626 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -140,6 +140,7 @@
case Expr::MSPropertyRefExprClass:
case Expr::MSPropertySubscriptExprClass:
case Expr::OMPArraySectionExprClass:
+ case Expr::OMPArrayShapingExprClass:
return Cl::CL_LValue;
// C99 6.5.2.5p5 says that compound literals are lvalues.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 53e168a..4a11c84 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14180,6 +14180,7 @@
case Expr::StringLiteralClass:
case Expr::ArraySubscriptExprClass:
case Expr::OMPArraySectionExprClass:
+ case Expr::OMPArrayShapingExprClass:
case Expr::MemberExprClass:
case Expr::CompoundAssignOperatorClass:
case Expr::CompoundLiteralExprClass:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 9c1e6b5..4c05990 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3714,6 +3714,7 @@
case Expr::TypoExprClass: // This should no longer exist in the AST by now.
case Expr::RecoveryExprClass:
case Expr::OMPArraySectionExprClass:
+ case Expr::OMPArrayShapingExprClass:
case Expr::CXXInheritedCtorInitExprClass:
llvm_unreachable("unexpected statement kind");
diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp
index ae6ff04..2bfe977 100644
--- a/clang/lib/AST/NSAPI.cpp
+++ b/clang/lib/AST/NSAPI.cpp
@@ -483,6 +483,7 @@
case BuiltinType::PseudoObject:
case BuiltinType::BuiltinFn:
case BuiltinType::OMPArraySection:
+ case BuiltinType::OMPArrayShaping:
break;
}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 80fdc09..3d03f39 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1350,6 +1350,17 @@
OS << "]";
}
+void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
+ OS << "(";
+ for (Expr *E : Node->getDimensions()) {
+ OS << "[";
+ PrintExpr(E);
+ OS << "]";
+ }
+ OS << ")";
+ PrintExpr(Node->getBase());
+}
+
void StmtPrinter::PrintCallArgs(CallExpr *Call) {
for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 5e87eb3..054276a 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1194,6 +1194,10 @@
VisitExpr(S);
}
+void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) {
+ VisitExpr(S);
+}
+
void StmtProfiler::VisitCallExpr(const CallExpr *S) {
VisitExpr(S);
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 279c0d1..f90eb5c 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2908,6 +2908,8 @@
return "reserve_id_t";
case OMPArraySection:
return "<OpenMP array section type>";
+ case OMPArrayShaping:
+ return "<OpenMP array shaping type>";
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
case Id: \
return #ExtType;
@@ -3914,6 +3916,7 @@
case BuiltinType::BuiltinFn:
case BuiltinType::NullPtr:
case BuiltinType::OMPArraySection:
+ case BuiltinType::OMPArrayShaping:
return false;
}
llvm_unreachable("unknown builtin type");
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 665a86f..dd48ae3 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -404,6 +404,7 @@
#include "clang/Basic/AArch64SVEACLETypes.def"
case BuiltinType::BuiltinFn:
case BuiltinType::OMPArraySection:
+ case BuiltinType::OMPArrayShaping:
return TST_unspecified;
}