mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-14 14:56:47 +00:00
[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
This commit is contained in:
parent
01ba2ad9ef
commit
7ac9efb0c3
@ -2176,7 +2176,11 @@ enum CXCursorKind {
|
||||
*/
|
||||
CXCursor_FixedPointLiteral = 149,
|
||||
|
||||
CXCursor_LastExpr = CXCursor_FixedPointLiteral,
|
||||
/** OpenMP 5.0 [2.1.4, Array Shaping].
|
||||
*/
|
||||
CXCursor_OMPArrayShapingExpr = 150,
|
||||
|
||||
CXCursor_LastExpr = CXCursor_OMPArrayShapingExpr,
|
||||
|
||||
/* Statements */
|
||||
CXCursor_FirstStmt = 200,
|
||||
|
@ -970,7 +970,7 @@ public:
|
||||
#include "clang/Basic/OpenCLImageTypes.def"
|
||||
CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy;
|
||||
CanQualType OCLQueueTy, OCLReserveIDTy;
|
||||
CanQualType OMPArraySectionTy;
|
||||
CanQualType OMPArraySectionTy, OMPArrayShapingTy;
|
||||
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
|
||||
CanQualType Id##Ty;
|
||||
#include "clang/Basic/OpenCLExtensionTypes.def"
|
||||
|
@ -313,8 +313,11 @@ PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy)
|
||||
// A placeholder type for OpenMP array sections.
|
||||
PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy)
|
||||
|
||||
// A placeholder type for OpenMP array shaping operation.
|
||||
PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy)
|
||||
|
||||
#ifdef LAST_BUILTIN_TYPE
|
||||
LAST_BUILTIN_TYPE(OMPArraySection)
|
||||
LAST_BUILTIN_TYPE(OMPArrayShaping)
|
||||
#undef LAST_BUILTIN_TYPE
|
||||
#endif
|
||||
|
||||
|
@ -87,6 +87,7 @@ class ParenListExpr;
|
||||
class PseudoObjectExpr;
|
||||
class AtomicExpr;
|
||||
class OMPArraySectionExpr;
|
||||
class OMPArrayShapingExpr;
|
||||
class ObjCArrayLiteral;
|
||||
class ObjCDictionaryLiteral;
|
||||
class ObjCBoxedExpr;
|
||||
@ -172,6 +173,7 @@ ExprDependence computeDependence(PseudoObjectExpr *E);
|
||||
ExprDependence computeDependence(AtomicExpr *E);
|
||||
|
||||
ExprDependence computeDependence(OMPArraySectionExpr *E);
|
||||
ExprDependence computeDependence(OMPArrayShapingExpr *E);
|
||||
|
||||
ExprDependence computeDependence(ObjCArrayLiteral *E);
|
||||
ExprDependence computeDependence(ObjCDictionaryLiteral *E);
|
||||
|
@ -116,6 +116,95 @@ public:
|
||||
return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
|
||||
}
|
||||
};
|
||||
|
||||
/// An explicit cast in C or a C-style cast in C++, which uses the syntax
|
||||
/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f.
|
||||
class OMPArrayShapingExpr final
|
||||
: public Expr,
|
||||
private llvm::TrailingObjects<OMPArrayShapingExpr, Expr *, SourceRange> {
|
||||
friend TrailingObjects;
|
||||
friend class ASTStmtReader;
|
||||
friend class ASTStmtWriter;
|
||||
/// Base node.
|
||||
SourceLocation LPLoc; /// The location of the left paren
|
||||
SourceLocation RPLoc; /// The location of the right paren
|
||||
unsigned NumDims = 0; /// Number of dimensions in the shaping expression.
|
||||
|
||||
/// Construct full expression.
|
||||
OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L,
|
||||
SourceLocation R, ArrayRef<Expr *> Dims);
|
||||
|
||||
/// Construct an empty expression.
|
||||
explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims)
|
||||
: Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {}
|
||||
|
||||
/// Sets the dimensions for the array shaping.
|
||||
void setDimensions(ArrayRef<Expr *> Dims);
|
||||
|
||||
/// Sets the base expression for array shaping operation.
|
||||
void setBase(Expr *Op) { getTrailingObjects<Expr *>()[NumDims] = Op; }
|
||||
|
||||
/// Sets source ranges for the brackets in the array shaping operation.
|
||||
void setBracketsRanges(ArrayRef<SourceRange> BR);
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<Expr *>) const {
|
||||
// Add an extra one for the base expression.
|
||||
return NumDims + 1;
|
||||
}
|
||||
|
||||
unsigned numTrailingObjects(OverloadToken<SourceRange>) const {
|
||||
return NumDims;
|
||||
}
|
||||
|
||||
public:
|
||||
static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T,
|
||||
Expr *Op, SourceLocation L,
|
||||
SourceLocation R, ArrayRef<Expr *> Dims,
|
||||
ArrayRef<SourceRange> BracketRanges);
|
||||
|
||||
static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context,
|
||||
unsigned NumDims);
|
||||
|
||||
SourceLocation getLParenLoc() const { return LPLoc; }
|
||||
void setLParenLoc(SourceLocation L) { LPLoc = L; }
|
||||
|
||||
SourceLocation getRParenLoc() const { return RPLoc; }
|
||||
void setRParenLoc(SourceLocation L) { RPLoc = L; }
|
||||
|
||||
SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; }
|
||||
SourceLocation getEndLoc() const LLVM_READONLY {
|
||||
return getBase()->getEndLoc();
|
||||
}
|
||||
|
||||
/// Fetches the dimensions for array shaping expression.
|
||||
ArrayRef<Expr *> getDimensions() const {
|
||||
return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumDims);
|
||||
}
|
||||
|
||||
/// Fetches source ranges for the brackets os the array shaping expression.
|
||||
ArrayRef<SourceRange> getBracketsRanges() const {
|
||||
return llvm::makeArrayRef(getTrailingObjects<SourceRange>(), NumDims);
|
||||
}
|
||||
|
||||
/// Fetches base expression of array shaping expression.
|
||||
Expr *getBase() { return getTrailingObjects<Expr *>()[NumDims]; }
|
||||
const Expr *getBase() const { return getTrailingObjects<Expr *>()[NumDims]; }
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == OMPArrayShapingExprClass;
|
||||
}
|
||||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
|
||||
return child_range(Begin, Begin + NumDims + 1);
|
||||
}
|
||||
const_child_range children() const {
|
||||
Stmt *const *Begin =
|
||||
reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
|
||||
return const_child_range(Begin, Begin + NumDims + 1);
|
||||
}
|
||||
};
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
@ -2551,6 +2551,7 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
|
||||
DEF_TRAVERSE_STMT(AddrLabelExpr, {})
|
||||
DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
|
||||
DEF_TRAVERSE_STMT(OMPArraySectionExpr, {})
|
||||
DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
|
||||
|
||||
DEF_TRAVERSE_STMT(BlockExpr, {
|
||||
TRY_TO(TraverseDecl(S->getBlockDecl()));
|
||||
|
@ -9685,7 +9685,7 @@ def err_omp_expected_var_name_member_expr : Error<
|
||||
def err_omp_expected_var_name_member_expr_or_array_item : Error<
|
||||
"expected variable name%select{|, data member of current class}0, array element or array section">;
|
||||
def err_omp_expected_addressable_lvalue_or_array_item : Error<
|
||||
"expected addressable lvalue expression, array element or array section%select{| of non 'omp_depend_t' type}0">;
|
||||
"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">;
|
||||
def err_omp_expected_named_var_member_or_array_expression: Error<
|
||||
"expected expression containing only member accesses and/or array sections based on named variables">;
|
||||
def err_omp_bit_fields_forbidden_in_clause : Error<
|
||||
@ -9952,10 +9952,15 @@ def err_omp_declare_mapper_redefinition : Error<
|
||||
def err_omp_invalid_mapper: Error<
|
||||
"cannot find a valid user-defined mapper for type %0 with name %1">;
|
||||
def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">;
|
||||
def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">;
|
||||
def err_omp_typecheck_section_value : Error<
|
||||
"subscripted value is not an array or pointer">;
|
||||
def err_omp_typecheck_section_not_integer : Error<
|
||||
"array section %select{lower bound|length}0 is not an integer">;
|
||||
def err_omp_typecheck_shaping_not_integer : Error<
|
||||
"array shaping operation dimension is not an integer">;
|
||||
def err_omp_shaping_dimension_not_positive : Error<
|
||||
"array shaping dimension is evaluated to a non-positive value %0">;
|
||||
def err_omp_section_function_type : Error<
|
||||
"section of pointer to function type %0">;
|
||||
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<
|
||||
def note_omp_flush_order_clause_here : Note<
|
||||
"memory order clause '%0' is specified here">;
|
||||
def err_omp_non_lvalue_in_map_or_motion_clauses: Error<
|
||||
"expected addressable lvalue in '%0' clause"
|
||||
>;
|
||||
"expected addressable lvalue in '%0' clause">;
|
||||
def err_omp_event_var_expected : Error<
|
||||
"expected variable of the 'omp_event_handle_t' type%select{|, not %1}0">;
|
||||
def warn_nested_declare_variant
|
||||
: Warning<"nesting `omp begin/end declare variant` is not supported yet; "
|
||||
"nested context ignored">,
|
||||
InGroup<SourceUsesOpenMP>;
|
||||
def err_omp_non_pointer_type_array_shaping_base : Error<
|
||||
"expected pointer type expression as a base of an array shaping operation">;
|
||||
} // end of OpenMP category
|
||||
|
||||
let CategoryName = "Related Result Type Issue" in {
|
||||
|
@ -81,6 +81,7 @@ def BinaryConditionalOperator : StmtNode<AbstractConditionalOperator>;
|
||||
def ImplicitCastExpr : StmtNode<CastExpr>;
|
||||
def ExplicitCastExpr : StmtNode<CastExpr, 1>;
|
||||
def CStyleCastExpr : StmtNode<ExplicitCastExpr>;
|
||||
def OMPArrayShapingExpr : StmtNode<Expr>;
|
||||
def CompoundLiteralExpr : StmtNode<Expr>;
|
||||
def ExtVectorElementExpr : StmtNode<Expr>;
|
||||
def InitListExpr : StmtNode<Expr>;
|
||||
|
@ -3010,6 +3010,10 @@ private:
|
||||
DeclarationName &Name,
|
||||
AccessSpecifier AS = AS_none);
|
||||
|
||||
/// Tries to parse cast part of OpenMP array shaping operation:
|
||||
/// '[' expression ']' { '[' expression ']' } ')'.
|
||||
bool tryParseOpenMPArrayShapingCastPart();
|
||||
|
||||
/// Parses simple list of variables.
|
||||
///
|
||||
/// \param Kind Kind of the directive.
|
||||
|
@ -4899,6 +4899,10 @@ public:
|
||||
ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
|
||||
Expr *LowerBound, SourceLocation ColonLoc,
|
||||
Expr *Length, SourceLocation RBLoc);
|
||||
ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc,
|
||||
ArrayRef<Expr *> Dims,
|
||||
ArrayRef<SourceRange> Brackets);
|
||||
|
||||
// This struct is for use by ActOnMemberAccess to allow
|
||||
// BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after
|
||||
|
@ -1016,6 +1016,9 @@ namespace serialization {
|
||||
/// \brief The '_Sat unsigned long _Fract' type
|
||||
PREDEF_TYPE_SAT_ULONG_FRACT_ID = 69,
|
||||
|
||||
/// The placeholder type for OpenMP array shaping operation.
|
||||
PREDEF_TYPE_OMP_ARRAY_SHAPING = 70,
|
||||
|
||||
/// OpenCL image types with auto numeration
|
||||
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
||||
PREDEF_TYPE_##Id##_ID,
|
||||
@ -1868,6 +1871,7 @@ namespace serialization {
|
||||
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE,
|
||||
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE,
|
||||
EXPR_OMP_ARRAY_SECTION,
|
||||
EXPR_OMP_ARRAY_SHAPING,
|
||||
|
||||
// ARC
|
||||
EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
|
||||
|
@ -1386,8 +1386,10 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
|
||||
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);
|
||||
|
@ -363,6 +363,15 @@ ExprDependence clang::computeDependence(OMPArraySectionExpr *E) {
|
||||
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.
|
||||
|
@ -3398,6 +3398,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
|
||||
case ParenExprClass:
|
||||
case ArraySubscriptExprClass:
|
||||
case OMPArraySectionExprClass:
|
||||
case OMPArrayShapingExprClass:
|
||||
case MemberExprClass:
|
||||
case ConditionalOperatorClass:
|
||||
case BinaryConditionalOperatorClass:
|
||||
@ -4569,3 +4570,50 @@ RecoveryExpr *RecoveryExpr::CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs) {
|
||||
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);
|
||||
}
|
||||
|
@ -140,6 +140,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
|
||||
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.
|
||||
|
@ -14180,6 +14180,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
|
||||
case Expr::StringLiteralClass:
|
||||
case Expr::ArraySubscriptExprClass:
|
||||
case Expr::OMPArraySectionExprClass:
|
||||
case Expr::OMPArrayShapingExprClass:
|
||||
case Expr::MemberExprClass:
|
||||
case Expr::CompoundAssignOperatorClass:
|
||||
case Expr::CompoundLiteralExprClass:
|
||||
|
@ -3714,6 +3714,7 @@ recurse:
|
||||
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");
|
||||
|
||||
|
@ -483,6 +483,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
|
||||
case BuiltinType::PseudoObject:
|
||||
case BuiltinType::BuiltinFn:
|
||||
case BuiltinType::OMPArraySection:
|
||||
case BuiltinType::OMPArrayShaping:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1350,6 +1350,17 @@ void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) {
|
||||
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))) {
|
||||
|
@ -1194,6 +1194,10 @@ void StmtProfiler::VisitOMPArraySectionExpr(const OMPArraySectionExpr *S) {
|
||||
VisitExpr(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) {
|
||||
VisitExpr(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitCallExpr(const CallExpr *S) {
|
||||
VisitExpr(S);
|
||||
}
|
||||
|
@ -2908,6 +2908,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
|
||||
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 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
|
||||
case BuiltinType::BuiltinFn:
|
||||
case BuiltinType::NullPtr:
|
||||
case BuiltinType::OMPArraySection:
|
||||
case BuiltinType::OMPArrayShaping:
|
||||
return false;
|
||||
}
|
||||
llvm_unreachable("unknown builtin type");
|
||||
|
@ -404,6 +404,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
|
||||
#include "clang/Basic/AArch64SVEACLETypes.def"
|
||||
case BuiltinType::BuiltinFn:
|
||||
case BuiltinType::OMPArraySection:
|
||||
case BuiltinType::OMPArrayShaping:
|
||||
return TST_unspecified;
|
||||
}
|
||||
|
||||
|
@ -2648,6 +2648,33 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||
return ParsePostfixExpressionSuffix(Res.get());
|
||||
}
|
||||
|
||||
bool Parser::tryParseOpenMPArrayShapingCastPart() {
|
||||
assert(Tok.is(tok::l_square) && "Expected open bracket");
|
||||
bool ErrorFound = true;
|
||||
TentativeParsingAction TPA(*this);
|
||||
do {
|
||||
if (Tok.isNot(tok::l_square))
|
||||
break;
|
||||
// Consume '['
|
||||
ConsumeBracket();
|
||||
// Skip inner expression.
|
||||
while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end,
|
||||
StopAtSemi | StopBeforeMatch))
|
||||
;
|
||||
if (Tok.isNot(tok::r_square))
|
||||
break;
|
||||
// Consume ']'
|
||||
ConsumeBracket();
|
||||
// Found ')' - done.
|
||||
if (Tok.is(tok::r_paren)) {
|
||||
ErrorFound = false;
|
||||
break;
|
||||
}
|
||||
} while (Tok.isNot(tok::annot_pragma_openmp_end));
|
||||
TPA.Revert();
|
||||
return !ErrorFound;
|
||||
}
|
||||
|
||||
/// ParseParenExpression - This parses the unit that starts with a '(' token,
|
||||
/// based on what is allowed by ExprType. The actual thing parsed is returned
|
||||
/// in ExprType. If stopIfCastExpr is true, it will only return the parsed type,
|
||||
@ -2672,6 +2699,8 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
||||
/// '(' '...' fold-operator cast-expression ')'
|
||||
/// '(' cast-expression fold-operator '...'
|
||||
/// fold-operator cast-expression ')'
|
||||
/// [OPENMP] Array shaping operation
|
||||
/// '(' '[' expression ']' { '[' expression ']' } cast-expression
|
||||
/// \endverbatim
|
||||
ExprResult
|
||||
Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
|
||||
@ -2948,6 +2977,38 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
|
||||
Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
|
||||
ArgExprs);
|
||||
}
|
||||
} else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing &&
|
||||
ExprType == CastExpr && Tok.is(tok::l_square) &&
|
||||
tryParseOpenMPArrayShapingCastPart()) {
|
||||
bool ErrorFound = false;
|
||||
SmallVector<Expr *, 4> OMPDimensions;
|
||||
SmallVector<SourceRange, 4> OMPBracketsRanges;
|
||||
do {
|
||||
BalancedDelimiterTracker TS(*this, tok::l_square);
|
||||
TS.consumeOpen();
|
||||
ExprResult NumElements =
|
||||
Actions.CorrectDelayedTyposInExpr(ParseExpression());
|
||||
if (!NumElements.isUsable()) {
|
||||
ErrorFound = true;
|
||||
while (!SkipUntil(tok::r_square, tok::r_paren,
|
||||
StopAtSemi | StopBeforeMatch))
|
||||
;
|
||||
}
|
||||
TS.consumeClose();
|
||||
OMPDimensions.push_back(NumElements.get());
|
||||
OMPBracketsRanges.push_back(TS.getRange());
|
||||
} while (Tok.isNot(tok::r_paren));
|
||||
// Match the ')'.
|
||||
T.consumeClose();
|
||||
RParenLoc = T.getCloseLocation();
|
||||
Result = Actions.CorrectDelayedTyposInExpr(ParseExpression());
|
||||
if (ErrorFound) {
|
||||
Result = ExprError();
|
||||
} else if (!Result.isInvalid()) {
|
||||
Result = Actions.ActOnOMPArrayShapingExpr(
|
||||
Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges);
|
||||
}
|
||||
return Result;
|
||||
} else {
|
||||
InMessageExpressionRAIIObject InMessage(*this, false);
|
||||
|
||||
|
@ -1299,6 +1299,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
|
||||
// Some might be dependent for other reasons.
|
||||
case Expr::ArraySubscriptExprClass:
|
||||
case Expr::OMPArraySectionExprClass:
|
||||
case Expr::OMPArrayShapingExprClass:
|
||||
case Expr::BinaryOperatorClass:
|
||||
case Expr::DependentCoawaitExprClass:
|
||||
case Expr::CompoundAssignOperatorClass:
|
||||
|
@ -4798,6 +4798,75 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc,
|
||||
VK_LValue, OK_Ordinary, ColonLoc, RBLoc);
|
||||
}
|
||||
|
||||
ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc,
|
||||
ArrayRef<Expr *> Dims,
|
||||
ArrayRef<SourceRange> Brackets) {
|
||||
if (Base->getType()->isPlaceholderType()) {
|
||||
ExprResult Result = CheckPlaceholderExpr(Base);
|
||||
if (Result.isInvalid())
|
||||
return ExprError();
|
||||
Base = Result.get();
|
||||
}
|
||||
QualType BaseTy = Base->getType();
|
||||
// Delay analysis of the types/expressions if instantiation/specialization is
|
||||
// required.
|
||||
if (!BaseTy->isPointerType() && Base->isTypeDependent())
|
||||
return OMPArrayShapingExpr::Create(Context, Context.DependentTy, Base,
|
||||
LParenLoc, RParenLoc, Dims, Brackets);
|
||||
if (!BaseTy->isPointerType())
|
||||
return ExprError(Diag(Base->getExprLoc(),
|
||||
diag::err_omp_non_pointer_type_array_shaping_base)
|
||||
<< Base->getSourceRange());
|
||||
SmallVector<Expr *, 4> NewDims;
|
||||
bool ErrorFound = false;
|
||||
for (Expr *Dim : Dims) {
|
||||
if (Dim->getType()->isPlaceholderType()) {
|
||||
ExprResult Result = CheckPlaceholderExpr(Dim);
|
||||
if (Result.isInvalid()) {
|
||||
ErrorFound = true;
|
||||
continue;
|
||||
}
|
||||
Result = DefaultLvalueConversion(Result.get());
|
||||
if (Result.isInvalid()) {
|
||||
ErrorFound = true;
|
||||
continue;
|
||||
}
|
||||
Dim = Result.get();
|
||||
}
|
||||
if (!Dim->isTypeDependent()) {
|
||||
ExprResult Result =
|
||||
PerformOpenMPImplicitIntegerConversion(Dim->getExprLoc(), Dim);
|
||||
if (Result.isInvalid()) {
|
||||
ErrorFound = true;
|
||||
Diag(Dim->getExprLoc(), diag::err_omp_typecheck_shaping_not_integer)
|
||||
<< Dim->getSourceRange();
|
||||
continue;
|
||||
}
|
||||
Dim = Result.get();
|
||||
Expr::EvalResult EvResult;
|
||||
if (!Dim->isValueDependent() && Dim->EvaluateAsInt(EvResult, Context)) {
|
||||
// OpenMP 5.0, [2.1.4 Array Shaping]
|
||||
// Each si is an integral type expression that must evaluate to a
|
||||
// positive integer.
|
||||
llvm::APSInt Value = EvResult.Val.getInt();
|
||||
if (!Value.isStrictlyPositive()) {
|
||||
Diag(Dim->getExprLoc(), diag::err_omp_shaping_dimension_not_positive)
|
||||
<< Value.toString(/*Radix=*/10, /*Signed=*/true)
|
||||
<< Dim->getSourceRange();
|
||||
ErrorFound = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
NewDims.push_back(Dim);
|
||||
}
|
||||
if (ErrorFound)
|
||||
return ExprError();
|
||||
return OMPArrayShapingExpr::Create(Context, Context.OMPArrayShapingTy, Base,
|
||||
LParenLoc, RParenLoc, NewDims, Brackets);
|
||||
}
|
||||
|
||||
ExprResult
|
||||
Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
|
||||
Expr *Idx, SourceLocation RLoc) {
|
||||
@ -5558,6 +5627,7 @@ static bool isPlaceholderToRemoveAsArg(QualType type) {
|
||||
case BuiltinType::BoundMember:
|
||||
case BuiltinType::BuiltinFn:
|
||||
case BuiltinType::OMPArraySection:
|
||||
case BuiltinType::OMPArrayShaping:
|
||||
return true;
|
||||
|
||||
}
|
||||
@ -18433,6 +18503,10 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
|
||||
Diag(E->getBeginLoc(), diag::err_omp_array_section_use);
|
||||
return ExprError();
|
||||
|
||||
// Expressions of unknown type.
|
||||
case BuiltinType::OMPArrayShaping:
|
||||
return ExprError(Diag(E->getBeginLoc(), diag::err_omp_array_shaping_use));
|
||||
|
||||
// Everything else should be impossible.
|
||||
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
|
||||
case BuiltinType::Id:
|
||||
|
@ -15824,7 +15824,8 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
|
||||
(OMPDependTFound &&
|
||||
DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
|
||||
Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
|
||||
<< 1 << RefExpr->getSourceRange();
|
||||
<< (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
|
||||
<< RefExpr->getSourceRange();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -15837,6 +15838,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
|
||||
->isPointerType() &&
|
||||
!ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
|
||||
Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
|
||||
<< (LangOpts.OpenMP >= 50 ? 1 : 0)
|
||||
<< (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
|
||||
continue;
|
||||
}
|
||||
@ -15847,8 +15849,10 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
|
||||
Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
|
||||
RefExpr->IgnoreParenImpCasts());
|
||||
}
|
||||
if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
|
||||
if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
|
||||
!isa<OMPArrayShapingExpr>(SimpleExpr)) {
|
||||
Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
|
||||
<< (LangOpts.OpenMP >= 50 ? 1 : 0)
|
||||
<< (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
|
||||
continue;
|
||||
}
|
||||
|
@ -2379,6 +2379,18 @@ public:
|
||||
ColonLoc, Length, RBracketLoc);
|
||||
}
|
||||
|
||||
/// Build a new array shaping expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
|
||||
SourceLocation RParenLoc,
|
||||
ArrayRef<Expr *> Dims,
|
||||
ArrayRef<SourceRange> BracketsRanges) {
|
||||
return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims,
|
||||
BracketsRanges);
|
||||
}
|
||||
|
||||
/// Build a new call expression.
|
||||
///
|
||||
/// By default, performs semantic analysis to build the new expression.
|
||||
@ -10017,6 +10029,31 @@ TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {
|
||||
Length.get(), E->getRBracketLoc());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
|
||||
ExprResult Base = getDerived().TransformExpr(E->getBase());
|
||||
if (Base.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
SmallVector<Expr *, 4> Dims;
|
||||
bool ErrorFound = false;
|
||||
for (Expr *Dim : E->getDimensions()) {
|
||||
ExprResult DimRes = getDerived().TransformExpr(Dim);
|
||||
if (DimRes.isInvalid()) {
|
||||
ErrorFound = true;
|
||||
continue;
|
||||
}
|
||||
Dims.push_back(DimRes.get());
|
||||
}
|
||||
|
||||
if (ErrorFound)
|
||||
return ExprError();
|
||||
return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
|
||||
E->getRParenLoc(), Dims,
|
||||
E->getBracketsRanges());
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
ExprResult
|
||||
TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
|
||||
|
@ -243,6 +243,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
|
||||
case BuiltinType::OMPArraySection:
|
||||
ID = PREDEF_TYPE_OMP_ARRAY_SECTION;
|
||||
break;
|
||||
case BuiltinType::OMPArrayShaping:
|
||||
ID = PREDEF_TYPE_OMP_ARRAY_SHAPING;
|
||||
break;
|
||||
}
|
||||
|
||||
return TypeIdx(ID);
|
||||
|
@ -6957,6 +6957,9 @@ QualType ASTReader::GetType(TypeID ID) {
|
||||
case PREDEF_TYPE_OMP_ARRAY_SECTION:
|
||||
T = Context.OMPArraySectionTy;
|
||||
break;
|
||||
case PREDEF_TYPE_OMP_ARRAY_SHAPING:
|
||||
T = Context.OMPArraySectionTy;
|
||||
break;
|
||||
#define SVE_TYPE(Name, Id, SingletonId) \
|
||||
case PREDEF_TYPE_##Id##_ID: \
|
||||
T = Context.SingletonId; \
|
||||
|
@ -911,6 +911,22 @@ void ASTStmtReader::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
|
||||
E->setRBracketLoc(readSourceLocation());
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
|
||||
VisitExpr(E);
|
||||
unsigned NumDims = Record.readInt();
|
||||
E->setBase(Record.readSubExpr());
|
||||
SmallVector<Expr *, 4> Dims(NumDims);
|
||||
for (unsigned I = 0; I < NumDims; ++I)
|
||||
Dims[I] = Record.readSubExpr();
|
||||
E->setDimensions(Dims);
|
||||
SmallVector<SourceRange, 4> SRs(NumDims);
|
||||
for (unsigned I = 0; I < NumDims; ++I)
|
||||
SRs[I] = readSourceRange();
|
||||
E->setBracketsRanges(SRs);
|
||||
E->setLParenLoc(readSourceLocation());
|
||||
E->setRParenLoc(readSourceLocation());
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitCallExpr(CallExpr *E) {
|
||||
VisitExpr(E);
|
||||
unsigned NumArgs = Record.readInt();
|
||||
@ -2866,6 +2882,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
||||
S = new (Context) OMPArraySectionExpr(Empty);
|
||||
break;
|
||||
|
||||
case EXPR_OMP_ARRAY_SHAPING:
|
||||
S = OMPArrayShapingExpr::CreateEmpty(
|
||||
Context, Record[ASTStmtReader::NumExprFields]);
|
||||
break;
|
||||
|
||||
case EXPR_CALL:
|
||||
S = CallExpr::CreateEmpty(
|
||||
Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty);
|
||||
|
@ -774,6 +774,19 @@ void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
|
||||
Code = serialization::EXPR_OMP_ARRAY_SECTION;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
|
||||
VisitExpr(E);
|
||||
Record.push_back(E->getDimensions().size());
|
||||
Record.AddStmt(E->getBase());
|
||||
for (Expr *Dim : E->getDimensions())
|
||||
Record.AddStmt(Dim);
|
||||
for (SourceRange SR : E->getBracketsRanges())
|
||||
Record.AddSourceRange(SR);
|
||||
Record.AddSourceLocation(E->getLParenLoc());
|
||||
Record.AddSourceLocation(E->getRParenLoc());
|
||||
Code = serialization::EXPR_OMP_ARRAY_SHAPING;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
|
||||
VisitExpr(E);
|
||||
Record.push_back(E->getNumArgs());
|
||||
|
@ -351,6 +351,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1,
|
||||
case Stmt::CallExprClass:
|
||||
case Stmt::ArraySubscriptExprClass:
|
||||
case Stmt::OMPArraySectionExprClass:
|
||||
case Stmt::OMPArrayShapingExprClass:
|
||||
case Stmt::ImplicitCastExprClass:
|
||||
case Stmt::ParenExprClass:
|
||||
case Stmt::BreakStmtClass:
|
||||
|
@ -1413,6 +1413,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
||||
case Stmt::SubstNonTypeTemplateParmExprClass:
|
||||
case Stmt::CXXNullPtrLiteralExprClass:
|
||||
case Stmt::OMPArraySectionExprClass:
|
||||
case Stmt::OMPArrayShapingExprClass:
|
||||
case Stmt::TypeTraitExprClass: {
|
||||
Bldr.takeNodes(Pred);
|
||||
ExplodedNodeSet preVisit;
|
||||
|
@ -158,7 +158,7 @@ label1 : {
|
||||
#pragma omp depend(out:x) depobj(x) // expected-error {{expected an OpenMP directive}}
|
||||
#pragma omp destroy depobj(x) // expected-error {{expected an OpenMP directive}}
|
||||
#pragma omp update(out) depobj(x) // expected-error {{expected an OpenMP directive}}
|
||||
#pragma omp depobj depend(in:x) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} expected-error {{expected addressable lvalue expression, array element or array section of non 'omp_depend_t' type}}
|
||||
#pragma omp depobj depend(in:x) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} expected-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}}
|
||||
#pragma omp depobj destroy (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}}
|
||||
#pragma omp depobj update(in) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}}
|
||||
return tmain(argc); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
int incomplete[];
|
||||
|
||||
void test() {
|
||||
void test(int *p) {
|
||||
int a;
|
||||
#pragma omp parallel reduction( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-note {{to match this '('}}
|
||||
;
|
||||
@ -16,7 +16,7 @@ void test() {
|
||||
;
|
||||
#pragma omp parallel reduction(inscan, + : a) // expected-error {{'inscan' modifier can be used only in 'omp for', 'omp simd', 'omp for simd', 'omp parallel for', or 'omp parallel for simd' directive}}
|
||||
;
|
||||
#pragma omp parallel reduction(+ : incomplete) // expected-error {{a reduction list item with incomplete type 'int []'}}
|
||||
#pragma omp parallel reduction(+ : incomplete, ([10])p) // expected-error {{a reduction list item with incomplete type 'int []'}} expected-error {{expected variable name, array element or array section}}
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ T tmain(T argc, T *argv) {
|
||||
T arr[argc];
|
||||
omp_depend_t x;
|
||||
omp_event_handle_t evt;
|
||||
#pragma omp task untied depend(in : argc, argv[b:argc], arr[:]) if (task : argc > 0) depend(depobj: x) detach(evt)
|
||||
#pragma omp task untied depend(in : argc, argv[b:argc], arr[:], ([argc][sizeof(T)])argv) if (task : argc > 0) depend(depobj: x) detach(evt)
|
||||
a = 2;
|
||||
#pragma omp task default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) final(S<T>::TS > 0) priority(argc)
|
||||
foo();
|
||||
@ -116,7 +116,7 @@ T tmain(T argc, T *argv) {
|
||||
// CHECK-NEXT: T arr[argc];
|
||||
// CHECK-NEXT: omp_depend_t x;
|
||||
// CHECK-NEXT: omp_event_handle_t evt;
|
||||
// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) depend(depobj : x) detach(evt)
|
||||
// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(T)])argv) if(task: argc > 0) depend(depobj : x) detach(evt)
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<T>::TS > 0) priority(argc)
|
||||
// CHECK-NEXT: foo()
|
||||
@ -130,7 +130,7 @@ T tmain(T argc, T *argv) {
|
||||
// CHECK-NEXT: int arr[argc];
|
||||
// CHECK-NEXT: omp_depend_t x;
|
||||
// CHECK-NEXT: omp_event_handle_t evt;
|
||||
// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) depend(depobj : x) detach(evt)
|
||||
// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(int)])argv) if(task: argc > 0) depend(depobj : x) detach(evt)
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<int>::TS > 0) priority(argc)
|
||||
// CHECK-NEXT: foo()
|
||||
@ -144,7 +144,7 @@ T tmain(T argc, T *argv) {
|
||||
// CHECK-NEXT: long arr[argc];
|
||||
// CHECK-NEXT: omp_depend_t x;
|
||||
// CHECK-NEXT: omp_event_handle_t evt;
|
||||
// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) depend(depobj : x) detach(evt)
|
||||
// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(long)])argv) if(task: argc > 0) depend(depobj : x) detach(evt)
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<long>::TS > 0) priority(argc)
|
||||
// CHECK-NEXT: foo()
|
||||
@ -164,14 +164,14 @@ int main(int argc, char **argv) {
|
||||
#pragma omp threadprivate(a)
|
||||
Enum ee;
|
||||
// CHECK: Enum ee;
|
||||
#pragma omp task untied mergeable depend(out:argv[:a][1], (arr)[0:]) if(task: argc > 0) priority(f) depend(depobj:y)
|
||||
// CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:]) if(task: argc > 0) priority(f) depend(depobj : y)
|
||||
#pragma omp task untied mergeable depend(out:argv[:a][1], (arr)[0:],([argc][10])argv) if(task: argc > 0) priority(f) depend(depobj:y)
|
||||
// CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:],([argc][10])argv) if(task: argc > 0) priority(f) depend(depobj : y)
|
||||
a = 2;
|
||||
// CHECK-NEXT: a = 2;
|
||||
#pragma omp taskgroup task_reduction(min: arr1)
|
||||
#pragma omp task default(none), private(argc, b) firstprivate(argv, evt) if (argc > 0) final(a > 0) depend(inout : a, argv[:argc],arr[:a]) priority(23) in_reduction(min: arr1), detach(evt)
|
||||
#pragma omp task default(none), private(argc, b) firstprivate(argv, evt) if (argc > 0) final(a > 0) depend(inout : a, argv[:argc],arr[:a], ([10][argc])argv) priority(23) in_reduction(min: arr1), detach(evt)
|
||||
// CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1)
|
||||
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv,evt) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a]) priority(23) in_reduction(min: arr1) detach(evt)
|
||||
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv,evt) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a],([10][argc])argv) priority(23) in_reduction(min: arr1) detach(evt)
|
||||
foo();
|
||||
// CHECK-NEXT: foo();
|
||||
#pragma omp taskgroup task_reduction(min: arr1)
|
||||
|
@ -35,14 +35,14 @@ int main(int argc, char **argv, char *env[]) {
|
||||
#pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}}
|
||||
#pragma omp task depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
|
||||
#pragma omp task depend (out: ) // expected-error {{expected expression}}
|
||||
#pragma omp task depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
|
||||
#pragma omp task depend (inout : foobool(argc)), depend (in, argc) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}}
|
||||
#pragma omp task depend (out :S1) // expected-error {{'S1' does not refer to a value}}
|
||||
#pragma omp task depend(in : argv[1][1] = '2')
|
||||
#pragma omp task depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}}
|
||||
#pragma omp task depend (in : vec[1]) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}}
|
||||
#pragma omp task depend (in : argv[0])
|
||||
#pragma omp task depend (in : ) // expected-error {{expected expression}}
|
||||
#pragma omp task depend (in : main)
|
||||
#pragma omp task depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}}
|
||||
#pragma omp task depend(in : a[0]) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}}
|
||||
#pragma omp task depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}}
|
||||
#pragma omp task depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
|
||||
#pragma omp task depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}}
|
||||
@ -62,6 +62,14 @@ int main(int argc, char **argv, char *env[]) {
|
||||
#pragma omp task depend(depobj:argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}}
|
||||
#pragma omp task depend(depobj : argv[ : argc][1 : argc - 1]) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected lvalue expression of 'omp_depend_t' type, not '<OpenMP array section type>'}}
|
||||
#pragma omp task depend(depobj : arr[0]) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}}
|
||||
#pragma omp task depend(in : ([ // expected-error {{expected variable name or 'this' in lambda capture list}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task depend(in : ([] // expected-error {{expected body of lambda expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task depend(in : ([]) // omp45-error {{expected body of lambda expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error 2 {{expected expression}}
|
||||
#pragma omp task depend(in : ([])a // omp45-error {{expected body of lambda expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected expression}}
|
||||
#pragma omp task depend(in : ([])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression}}
|
||||
#pragma omp task depend(in : ([a])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected pointer type expression as a base of an array shaping operation}}
|
||||
#pragma omp task depend(in : ([a])argc) // omp45-error {{expected body of lambda expression}} omp50-error {{expected pointer type expression as a base of an array shaping operation}}
|
||||
#pragma omp task depend(in : ([-1][0])argv) // omp45-error {{expected variable name or 'this' in lambda capture list}} omp45-error {{expected ')'}} omp45-note {{to match this '('}} omp50-error {{array shaping dimension is evaluated to a non-positive value -1}} omp50-error {{array shaping dimension is evaluated to a non-positive value 0}}
|
||||
foo();
|
||||
|
||||
return 0;
|
||||
|
@ -5183,6 +5183,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
|
||||
return cxstring::createRef("ArraySubscriptExpr");
|
||||
case CXCursor_OMPArraySectionExpr:
|
||||
return cxstring::createRef("OMPArraySectionExpr");
|
||||
case CXCursor_OMPArrayShapingExpr:
|
||||
return cxstring::createRef("OMPArrayShapingExpr");
|
||||
case CXCursor_BinaryOperator:
|
||||
return cxstring::createRef("BinaryOperator");
|
||||
case CXCursor_CompoundAssignOperator:
|
||||
|
@ -423,6 +423,10 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
|
||||
K = CXCursor_OMPArraySectionExpr;
|
||||
break;
|
||||
|
||||
case Stmt::OMPArrayShapingExprClass:
|
||||
K = CXCursor_OMPArrayShapingExpr;
|
||||
break;
|
||||
|
||||
case Stmt::BinaryOperatorClass:
|
||||
K = CXCursor_BinaryOperator;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user