forked from OSchip/llvm-project
[OPENMP 4.1] Parsing/sema analysis for extended format of 'if' clause.
OpenMP 4.1 added special 'directive-name-modifier' to the 'if' clause. Format of 'if' clause is as follows: ``` if([ directive-name-modifier :] scalar-logical-expression) ``` The restriction rules are also changed. 1. If any 'if' clause on the directive includes a 'directive-name-modifier' then all 'if' clauses on the directive must include a 'directive-name-modifier'. 2. At most one 'if' clause without a 'directive-name-modifier' can appear on the directive. 3. At most one 'if' clause with some particular 'directive-name-modifier' can appear on the directive. 'directive-name-modifier' is important for combined directives and allows to separate conditions in 'if' clause for simple sub-directives in combined directive. This 'directive-name-modifier' identifies the sub-directive to which this 'if' clause must be applied. llvm-svn: 246747
This commit is contained in:
parent
49948af9cd
commit
6b8046addf
|
@ -152,10 +152,10 @@ public:
|
|||
/// \brief This represents 'if' clause in the '#pragma omp ...' directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp parallel if(a > 5)
|
||||
/// #pragma omp parallel if(parallel:a > 5)
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp parallel' has simple 'if'
|
||||
/// clause with condition 'a > 5'.
|
||||
/// In this example directive '#pragma omp parallel' has simple 'if' clause with
|
||||
/// condition 'a > 5' and directive name modifier 'parallel'.
|
||||
///
|
||||
class OMPIfClause : public OMPClause {
|
||||
friend class OMPClauseReader;
|
||||
|
@ -163,37 +163,67 @@ class OMPIfClause : public OMPClause {
|
|||
SourceLocation LParenLoc;
|
||||
/// \brief Condition of the 'if' clause.
|
||||
Stmt *Condition;
|
||||
/// \brief Location of ':' (if any).
|
||||
SourceLocation ColonLoc;
|
||||
/// \brief Directive name modifier for the clause.
|
||||
OpenMPDirectiveKind NameModifier;
|
||||
/// \brief Name modifier location.
|
||||
SourceLocation NameModifierLoc;
|
||||
|
||||
/// \brief Set condition.
|
||||
///
|
||||
void setCondition(Expr *Cond) { Condition = Cond; }
|
||||
/// \brief Set directive name modifier for the clause.
|
||||
///
|
||||
void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; }
|
||||
/// \brief Set location of directive name modifier for the clause.
|
||||
///
|
||||
void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; }
|
||||
/// \brief Set location of ':'.
|
||||
///
|
||||
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
|
||||
|
||||
public:
|
||||
/// \brief Build 'if' clause with condition \a Cond.
|
||||
///
|
||||
/// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
|
||||
/// \param Cond Condition of the clause.
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param LParenLoc Location of '('.
|
||||
/// \param Cond Condition of the clause.
|
||||
/// \param NameModifierLoc Location of directive name modifier.
|
||||
/// \param ColonLoc [OpenMP 4.1] Location of ':'.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
///
|
||||
OMPIfClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation NameModifierLoc, SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
|
||||
Condition(Cond) {}
|
||||
Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier),
|
||||
NameModifierLoc(NameModifierLoc) {}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
OMPIfClause()
|
||||
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
|
||||
LParenLoc(SourceLocation()), Condition(nullptr) {}
|
||||
: OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(),
|
||||
Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown),
|
||||
NameModifierLoc() {}
|
||||
|
||||
/// \brief Sets the location of '('.
|
||||
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
|
||||
/// \brief Returns the location of '('.
|
||||
SourceLocation getLParenLoc() const { return LParenLoc; }
|
||||
|
||||
/// \brief Return the location of ':'.
|
||||
SourceLocation getColonLoc() const { return ColonLoc; }
|
||||
|
||||
/// \brief Returns condition.
|
||||
Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
|
||||
/// \brief Return directive name modifier associated with the clause.
|
||||
OpenMPDirectiveKind getNameModifier() const { return NameModifier; }
|
||||
|
||||
/// \brief Return the location of directive name modifier.
|
||||
SourceLocation getNameModifierLoc() const { return NameModifierLoc; }
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_if;
|
||||
|
|
|
@ -211,4 +211,7 @@ def note_mt_message : Note<"[rewriter] %0">;
|
|||
def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
|
||||
def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
|
||||
|
||||
// OpenMP
|
||||
def err_omp_more_one_clause : Error<
|
||||
"directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier}2">;
|
||||
}
|
||||
|
|
|
@ -987,8 +987,6 @@ def err_omp_expected_punc : Error<
|
|||
"expected ',' or ')' in '%0' %select{clause|directive}1">;
|
||||
def err_omp_unexpected_clause : Error<
|
||||
"unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
|
||||
def err_omp_more_one_clause : Error<
|
||||
"directive '#pragma omp %0' cannot contain more than one '%1' clause">;
|
||||
def err_omp_immediate_directive : Error<
|
||||
"'#pragma omp %0' cannot be an immediate substatement">;
|
||||
def err_omp_expected_identifier_for_critical : Error<
|
||||
|
|
|
@ -7694,6 +7694,14 @@ def err_omp_wrong_linear_modifier_non_reference : Error<
|
|||
"variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">;
|
||||
def err_omp_wrong_simdlen_safelen_values : Error<
|
||||
"the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter">;
|
||||
def err_omp_wrong_if_directive_name_modifier : Error<
|
||||
"directive name modifier '%0' is not allowed for '#pragma omp %1'">;
|
||||
def err_omp_no_more_if_clause : Error<
|
||||
"no more 'if' clause is allowed">;
|
||||
def err_omp_unnamed_if_clause : Error<
|
||||
"expected %select{|one of}0 %1 directive name modifier%select{|s}0">;
|
||||
def note_omp_previous_named_if_clause : Note<
|
||||
"previous clause with directive name modifier specified here">;
|
||||
} // end of OpenMP category
|
||||
|
||||
let CategoryName = "Related Result Type Issue" in {
|
||||
|
|
|
@ -7889,8 +7889,11 @@ public:
|
|||
SourceLocation LParenLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'if' clause.
|
||||
OMPClause *ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
|
||||
OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
|
||||
Expr *Condition, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation NameModifierLoc,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'final' clause.
|
||||
OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc,
|
||||
|
@ -7945,7 +7948,7 @@ public:
|
|||
SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation ArgumentLoc,
|
||||
SourceLocation CommaLoc,
|
||||
SourceLocation DelimLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'schedule' clause.
|
||||
OMPClause *ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind,
|
||||
|
|
|
@ -602,6 +602,8 @@ public:
|
|||
|
||||
void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
|
||||
OS << "if(";
|
||||
if (Node->getNameModifier() != OMPD_unknown)
|
||||
OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
|
||||
Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
|
||||
OS << ")";
|
||||
}
|
||||
|
|
|
@ -288,7 +288,6 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
|
|||
ConsumeToken();
|
||||
|
||||
StmtResult AssociatedStmt;
|
||||
bool CreateDirective = true;
|
||||
if (HasAssociatedStatement) {
|
||||
// The body is a block scope like in Lambdas and Blocks.
|
||||
Sema::CompoundScopeRAII CompoundScope(Actions);
|
||||
|
@ -298,12 +297,10 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
|
|||
AssociatedStmt = ParseStatement();
|
||||
Actions.ActOnFinishOfCompoundStmt();
|
||||
AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
|
||||
CreateDirective = AssociatedStmt.isUsable();
|
||||
}
|
||||
if (CreateDirective)
|
||||
Directive = Actions.ActOnOpenMPExecutableDirective(
|
||||
DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
|
||||
EndLoc);
|
||||
Directive = Actions.ActOnOpenMPExecutableDirective(
|
||||
DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
|
||||
EndLoc);
|
||||
|
||||
// Exit scope.
|
||||
Actions.EndOpenMPDSABlock(Directive.get());
|
||||
|
@ -411,7 +408,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
}
|
||||
|
||||
switch (CKind) {
|
||||
case OMPC_if:
|
||||
case OMPC_final:
|
||||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
|
@ -420,7 +416,6 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
case OMPC_ordered:
|
||||
case OMPC_device:
|
||||
// OpenMP [2.5, Restrictions]
|
||||
// At most one if clause can appear on the directive.
|
||||
// At most one num_threads clause can appear on the directive.
|
||||
// OpenMP [2.8.1, simd construct, Restrictions]
|
||||
// Only one safelen clause can appear on a simd directive.
|
||||
|
@ -432,8 +427,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
// At most one if clause can appear on the directive.
|
||||
// At most one final clause can appear on the directive.
|
||||
if (!FirstClause) {
|
||||
Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
|
||||
<< getOpenMPClauseName(CKind);
|
||||
Diag(Tok, diag::err_omp_more_one_clause)
|
||||
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
|
||||
ErrorFound = true;
|
||||
}
|
||||
|
||||
|
@ -450,8 +445,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
// OpenMP [2.5, parallel Construct, Restrictions]
|
||||
// At most one proc_bind clause can appear on the directive.
|
||||
if (!FirstClause) {
|
||||
Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
|
||||
<< getOpenMPClauseName(CKind);
|
||||
Diag(Tok, diag::err_omp_more_one_clause)
|
||||
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
|
||||
ErrorFound = true;
|
||||
}
|
||||
|
||||
|
@ -461,11 +456,12 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
// OpenMP [2.7.1, Restrictions, p. 3]
|
||||
// Only one schedule clause can appear on a loop directive.
|
||||
if (!FirstClause) {
|
||||
Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
|
||||
<< getOpenMPClauseName(CKind);
|
||||
Diag(Tok, diag::err_omp_more_one_clause)
|
||||
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
|
||||
ErrorFound = true;
|
||||
}
|
||||
|
||||
case OMPC_if:
|
||||
Clause = ParseOpenMPSingleExprWithArgClause(CKind);
|
||||
break;
|
||||
case OMPC_nowait:
|
||||
|
@ -481,8 +477,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
// OpenMP [2.7.1, Restrictions, C/C++, p. 4]
|
||||
// Only one nowait clause can appear on a for directive.
|
||||
if (!FirstClause) {
|
||||
Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
|
||||
<< getOpenMPClauseName(CKind);
|
||||
Diag(Tok, diag::err_omp_more_one_clause)
|
||||
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
|
||||
ErrorFound = true;
|
||||
}
|
||||
|
||||
|
@ -515,12 +511,9 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
return ErrorFound ? nullptr : Clause;
|
||||
}
|
||||
|
||||
/// \brief Parsing of OpenMP clauses with single expressions like 'if',
|
||||
/// 'final', 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
|
||||
/// 'thread_limit' or 'simdlen'.
|
||||
///
|
||||
/// if-clause:
|
||||
/// 'if' '(' expression ')'
|
||||
/// \brief Parsing of OpenMP clauses with single expressions like 'final',
|
||||
/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', 'thread_limit'
|
||||
/// or 'simdlen'.
|
||||
///
|
||||
/// final-clause:
|
||||
/// 'final' '(' expression ')'
|
||||
|
@ -545,8 +538,10 @@ OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
|
|||
getOpenMPClauseName(Kind)))
|
||||
return nullptr;
|
||||
|
||||
SourceLocation ELoc = Tok.getLocation();
|
||||
ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
|
||||
ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
|
||||
Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
|
||||
|
||||
// Parse ')'.
|
||||
T.consumeClose();
|
||||
|
@ -620,9 +615,12 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
|
|||
/// schedule-clause:
|
||||
/// 'schedule' '(' kind [',' expression ] ')'
|
||||
///
|
||||
/// if-clause:
|
||||
/// 'if' '(' [ directive-name-modifier ':' ] expression ')'
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
|
||||
SourceLocation Loc = ConsumeToken();
|
||||
SourceLocation CommaLoc;
|
||||
SourceLocation DelimLoc;
|
||||
// Parse '('.
|
||||
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
|
||||
if (T.expectAndConsume(diag::err_expected_lparen_after,
|
||||
|
@ -630,29 +628,50 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
|
|||
return nullptr;
|
||||
|
||||
ExprResult Val;
|
||||
unsigned Type = getOpenMPSimpleClauseType(
|
||||
Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
|
||||
SourceLocation KLoc = Tok.getLocation();
|
||||
if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
|
||||
Tok.isNot(tok::annot_pragma_openmp_end))
|
||||
ConsumeAnyToken();
|
||||
unsigned Arg;
|
||||
SourceLocation KLoc;
|
||||
if (Kind == OMPC_schedule) {
|
||||
Arg = getOpenMPSimpleClauseType(
|
||||
Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
|
||||
KLoc = Tok.getLocation();
|
||||
if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
|
||||
Tok.isNot(tok::annot_pragma_openmp_end))
|
||||
ConsumeAnyToken();
|
||||
if ((Arg == OMPC_SCHEDULE_static || Arg == OMPC_SCHEDULE_dynamic ||
|
||||
Arg == OMPC_SCHEDULE_guided) &&
|
||||
Tok.is(tok::comma))
|
||||
DelimLoc = ConsumeAnyToken();
|
||||
} else {
|
||||
assert(Kind == OMPC_if);
|
||||
KLoc = Tok.getLocation();
|
||||
Arg = ParseOpenMPDirectiveKind(*this);
|
||||
if (Arg != OMPD_unknown) {
|
||||
ConsumeToken();
|
||||
if (Tok.is(tok::colon))
|
||||
DelimLoc = ConsumeToken();
|
||||
else
|
||||
Diag(Tok, diag::warn_pragma_expected_colon)
|
||||
<< "directive name modifier";
|
||||
}
|
||||
}
|
||||
|
||||
if (Kind == OMPC_schedule &&
|
||||
(Type == OMPC_SCHEDULE_static || Type == OMPC_SCHEDULE_dynamic ||
|
||||
Type == OMPC_SCHEDULE_guided) &&
|
||||
Tok.is(tok::comma)) {
|
||||
CommaLoc = ConsumeAnyToken();
|
||||
bool NeedAnExpression =
|
||||
(Kind == OMPC_schedule && DelimLoc.isValid()) || Kind == OMPC_if;
|
||||
if (NeedAnExpression) {
|
||||
SourceLocation ELoc = Tok.getLocation();
|
||||
ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
|
||||
Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
|
||||
if (Val.isInvalid())
|
||||
return nullptr;
|
||||
Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
|
||||
}
|
||||
|
||||
// Parse ')'.
|
||||
T.consumeClose();
|
||||
|
||||
if (NeedAnExpression && Val.isInvalid())
|
||||
return nullptr;
|
||||
|
||||
return Actions.ActOnOpenMPSingleExprWithArgClause(
|
||||
Kind, Type, Val.get(), Loc, T.getOpenLocation(), KLoc, CommaLoc,
|
||||
Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
|
||||
T.getCloseLocation());
|
||||
}
|
||||
|
||||
|
@ -838,9 +857,9 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
|
|||
const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
|
||||
if (MustHaveTail) {
|
||||
ColonLoc = Tok.getLocation();
|
||||
ConsumeToken();
|
||||
ExprResult Tail =
|
||||
Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
|
||||
SourceLocation ELoc = ConsumeToken();
|
||||
ExprResult Tail = ParseAssignmentExpression();
|
||||
Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
|
||||
if (Tail.isUsable())
|
||||
TailExpr = Tail.get();
|
||||
else
|
||||
|
|
|
@ -1985,6 +1985,82 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
|
||||
ArrayRef<OMPClause *> Clauses,
|
||||
ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
|
||||
bool ErrorFound = false;
|
||||
unsigned NamedModifiersNumber = 0;
|
||||
SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
|
||||
OMPD_unknown + 1);
|
||||
for (const auto *C : Clauses) {
|
||||
if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
|
||||
// At most one if clause without a directive-name-modifier can appear on
|
||||
// the directive.
|
||||
OpenMPDirectiveKind CurNM = IC->getNameModifier();
|
||||
if (FoundNameModifiers[CurNM]) {
|
||||
S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
|
||||
<< getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
|
||||
<< (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
|
||||
ErrorFound = true;
|
||||
} else if (CurNM != OMPD_unknown)
|
||||
++NamedModifiersNumber;
|
||||
FoundNameModifiers[CurNM] = IC;
|
||||
if (CurNM == OMPD_unknown)
|
||||
continue;
|
||||
// Check if the specified name modifier is allowed for the current
|
||||
// directive.
|
||||
// At most one if clause with the particular directive-name-modifier can
|
||||
// appear on the directive.
|
||||
bool MatchFound = false;
|
||||
for (auto NM : AllowedNameModifiers) {
|
||||
if (CurNM == NM) {
|
||||
MatchFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!MatchFound) {
|
||||
S.Diag(IC->getNameModifierLoc(),
|
||||
diag::err_omp_wrong_if_directive_name_modifier)
|
||||
<< getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
|
||||
ErrorFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If any if clause on the directive includes a directive-name-modifier then
|
||||
// all if clauses on the directive must include a directive-name-modifier.
|
||||
if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
|
||||
if (NamedModifiersNumber == AllowedNameModifiers.size()) {
|
||||
S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
|
||||
diag::err_omp_no_more_if_clause);
|
||||
} else {
|
||||
std::string Values;
|
||||
std::string Sep(", ");
|
||||
unsigned AllowedCnt = 0;
|
||||
unsigned TotalAllowedNum =
|
||||
AllowedNameModifiers.size() - NamedModifiersNumber;
|
||||
for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
|
||||
++Cnt) {
|
||||
OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
|
||||
if (!FoundNameModifiers[NM]) {
|
||||
Values += "'";
|
||||
Values += getOpenMPDirectiveName(NM);
|
||||
Values += "'";
|
||||
if (AllowedCnt + 2 == TotalAllowedNum)
|
||||
Values += " or ";
|
||||
else if (AllowedCnt + 1 != TotalAllowedNum)
|
||||
Values += Sep;
|
||||
++AllowedCnt;
|
||||
}
|
||||
}
|
||||
S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
|
||||
diag::err_omp_unnamed_if_clause)
|
||||
<< (TotalAllowedNum > 1) << Values;
|
||||
}
|
||||
ErrorFound = true;
|
||||
}
|
||||
return ErrorFound;
|
||||
}
|
||||
|
||||
StmtResult Sema::ActOnOpenMPExecutableDirective(
|
||||
OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
|
||||
OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
|
||||
|
@ -2021,10 +2097,12 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|||
}
|
||||
}
|
||||
|
||||
llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
|
||||
switch (Kind) {
|
||||
case OMPD_parallel:
|
||||
Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
|
||||
EndLoc);
|
||||
AllowedNameModifiers.push_back(OMPD_parallel);
|
||||
break;
|
||||
case OMPD_simd:
|
||||
Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
|
||||
|
@ -2064,18 +2142,22 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|||
case OMPD_parallel_for:
|
||||
Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
|
||||
EndLoc, VarsWithInheritedDSA);
|
||||
AllowedNameModifiers.push_back(OMPD_parallel);
|
||||
break;
|
||||
case OMPD_parallel_for_simd:
|
||||
Res = ActOnOpenMPParallelForSimdDirective(
|
||||
ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
|
||||
AllowedNameModifiers.push_back(OMPD_parallel);
|
||||
break;
|
||||
case OMPD_parallel_sections:
|
||||
Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
|
||||
StartLoc, EndLoc);
|
||||
AllowedNameModifiers.push_back(OMPD_parallel);
|
||||
break;
|
||||
case OMPD_task:
|
||||
Res =
|
||||
ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
|
||||
AllowedNameModifiers.push_back(OMPD_task);
|
||||
break;
|
||||
case OMPD_taskyield:
|
||||
assert(ClausesWithImplicit.empty() &&
|
||||
|
@ -2124,6 +2206,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|||
case OMPD_target:
|
||||
Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
|
||||
EndLoc);
|
||||
AllowedNameModifiers.push_back(OMPD_target);
|
||||
break;
|
||||
case OMPD_cancellation_point:
|
||||
assert(ClausesWithImplicit.empty() &&
|
||||
|
@ -2142,6 +2225,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|||
case OMPD_target_data:
|
||||
Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
|
||||
EndLoc);
|
||||
AllowedNameModifiers.push_back(OMPD_target_data);
|
||||
break;
|
||||
case OMPD_threadprivate:
|
||||
llvm_unreachable("OpenMP Directive is not allowed");
|
||||
|
@ -2153,8 +2237,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|||
Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
|
||||
<< P.first << P.second->getSourceRange();
|
||||
}
|
||||
if (!VarsWithInheritedDSA.empty())
|
||||
return StmtError();
|
||||
ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
|
||||
|
||||
if (!AllowedNameModifiers.empty())
|
||||
ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
|
||||
ErrorFound;
|
||||
|
||||
if (ErrorFound)
|
||||
return StmtError();
|
||||
|
@ -2165,7 +2252,9 @@ StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
|
|||
Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
CapturedStmt *CS = cast<CapturedStmt>(AStmt);
|
||||
// 1.2.2 OpenMP Language Terminology
|
||||
// Structured block - An executable statement with a single entry at the
|
||||
|
@ -3557,6 +3646,10 @@ StmtResult Sema::ActOnOpenMPSimdDirective(
|
|||
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
OMPLoopDirective::HelperExprs B;
|
||||
// In presence of clause 'collapse' or 'ordered' with number of loops, it will
|
||||
// define the nested loops number.
|
||||
|
@ -3606,6 +3699,10 @@ StmtResult Sema::ActOnOpenMPForDirective(
|
|||
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
OMPLoopDirective::HelperExprs B;
|
||||
// In presence of clause 'collapse' or 'ordered' with number of loops, it will
|
||||
// define the nested loops number.
|
||||
|
@ -3637,6 +3734,10 @@ StmtResult Sema::ActOnOpenMPForSimdDirective(
|
|||
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
OMPLoopDirective::HelperExprs B;
|
||||
// In presence of clause 'collapse' or 'ordered' with number of loops, it will
|
||||
// define the nested loops number.
|
||||
|
@ -3687,7 +3788,10 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
|
|||
Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
auto BaseStmt = AStmt;
|
||||
while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
|
||||
BaseStmt = CS->getCapturedStmt();
|
||||
|
@ -3719,7 +3823,10 @@ StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
|
|||
StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
|
@ -3730,7 +3837,10 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
|
|||
Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
|
@ -3757,7 +3867,10 @@ StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
|
|||
StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
|
@ -3768,7 +3881,10 @@ StmtResult
|
|||
Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
|
||||
Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
|
@ -3780,7 +3896,9 @@ StmtResult Sema::ActOnOpenMPParallelForDirective(
|
|||
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
CapturedStmt *CS = cast<CapturedStmt>(AStmt);
|
||||
// 1.2.2 OpenMP Language Terminology
|
||||
// Structured block - An executable statement with a single entry at the
|
||||
|
@ -3821,7 +3939,9 @@ StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
|
|||
ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
CapturedStmt *CS = cast<CapturedStmt>(AStmt);
|
||||
// 1.2.2 OpenMP Language Terminology
|
||||
// Structured block - An executable statement with a single entry at the
|
||||
|
@ -3877,7 +3997,10 @@ StmtResult
|
|||
Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
|
||||
Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
auto BaseStmt = AStmt;
|
||||
while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
|
||||
BaseStmt = CS->getCapturedStmt();
|
||||
|
@ -3910,7 +4033,9 @@ Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
|
|||
StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
|
||||
Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
CapturedStmt *CS = cast<CapturedStmt>(AStmt);
|
||||
// 1.2.2 OpenMP Language Terminology
|
||||
// Structured block - An executable statement with a single entry at the
|
||||
|
@ -3942,7 +4067,10 @@ StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
|
|||
StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
|
@ -3959,7 +4087,10 @@ StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
|
|||
StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
|
@ -4210,7 +4341,9 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
|
|||
Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
auto CS = cast<CapturedStmt>(AStmt);
|
||||
// 1.2.2 OpenMP Language Terminology
|
||||
// Structured block - An executable statement with a single entry at the
|
||||
|
@ -4631,7 +4764,10 @@ StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
|
|||
Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
// OpenMP [2.16, Nesting of Regions]
|
||||
// If specified, a teams construct must be contained within a target
|
||||
|
@ -4672,6 +4808,11 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
|
|||
Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
|
||||
|
@ -4681,7 +4822,9 @@ StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
|
|||
StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
|
||||
Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
if (!AStmt)
|
||||
return StmtError();
|
||||
|
||||
CapturedStmt *CS = cast<CapturedStmt>(AStmt);
|
||||
// 1.2.2 OpenMP Language Terminology
|
||||
// Structured block - An executable statement with a single entry at the
|
||||
|
@ -4743,9 +4886,6 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
|||
SourceLocation EndLoc) {
|
||||
OMPClause *Res = nullptr;
|
||||
switch (Kind) {
|
||||
case OMPC_if:
|
||||
Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_final:
|
||||
Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
|
@ -4767,6 +4907,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
|||
case OMPC_device:
|
||||
Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_if:
|
||||
case OMPC_default:
|
||||
case OMPC_proc_bind:
|
||||
case OMPC_schedule:
|
||||
|
@ -4796,8 +4937,11 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
|||
return Res;
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
|
||||
OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
|
||||
Expr *Condition, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation NameModifierLoc,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc) {
|
||||
Expr *ValExpr = Condition;
|
||||
if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
|
||||
|
@ -4811,7 +4955,8 @@ OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
|
|||
ValExpr = Val.get();
|
||||
}
|
||||
|
||||
return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc);
|
||||
return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,
|
||||
NameModifierLoc, ColonLoc, EndLoc);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
|
||||
|
@ -5129,16 +5274,20 @@ OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
|
|||
OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
|
||||
OpenMPClauseKind Kind, unsigned Argument, Expr *Expr,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc,
|
||||
SourceLocation ArgumentLoc, SourceLocation CommaLoc,
|
||||
SourceLocation ArgumentLoc, SourceLocation DelimLoc,
|
||||
SourceLocation EndLoc) {
|
||||
OMPClause *Res = nullptr;
|
||||
switch (Kind) {
|
||||
case OMPC_schedule:
|
||||
Res = ActOnOpenMPScheduleClause(
|
||||
static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc,
|
||||
LParenLoc, ArgumentLoc, CommaLoc, EndLoc);
|
||||
LParenLoc, ArgumentLoc, DelimLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_if:
|
||||
Res =
|
||||
ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument), Expr,
|
||||
StartLoc, LParenLoc, ArgumentLoc, DelimLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_final:
|
||||
case OMPC_num_threads:
|
||||
case OMPC_safelen:
|
||||
|
@ -6382,9 +6531,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
|
|||
BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
|
||||
BO_Assign, LHSDRE, ConditionalOp);
|
||||
}
|
||||
if (ReductionOp.isUsable()) {
|
||||
ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
|
||||
}
|
||||
ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
|
||||
}
|
||||
if (ReductionOp.isInvalid())
|
||||
continue;
|
||||
|
@ -6551,6 +6698,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
|
|||
buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
|
||||
ExprResult CalcStep =
|
||||
BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
|
||||
CalcStep = ActOnFinishFullExpr(CalcStep.get());
|
||||
|
||||
// Warn about zero linear step (it would be probably better specified as
|
||||
// making corresponding variables 'const').
|
||||
|
@ -6607,13 +6755,15 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
|
|||
ExprResult Update =
|
||||
BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
|
||||
InitExpr, IV, Step, /* Subtract */ false);
|
||||
Update = SemaRef.ActOnFinishFullExpr(Update.get());
|
||||
Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
|
||||
/*DiscardedValue=*/true);
|
||||
|
||||
// Build final: Var = InitExpr + NumIterations * Step
|
||||
ExprResult Final =
|
||||
BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
|
||||
InitExpr, NumIterations, Step, /* Subtract */ false);
|
||||
Final = SemaRef.ActOnFinishFullExpr(Final.get());
|
||||
Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
|
||||
/*DiscardedValue=*/true);
|
||||
if (!Update.isUsable() || !Final.isUsable()) {
|
||||
Updates.push_back(nullptr);
|
||||
Finals.push_back(nullptr);
|
||||
|
|
|
@ -1355,12 +1355,15 @@ public:
|
|||
///
|
||||
/// By default, performs semantic analysis to build the new OpenMP clause.
|
||||
/// Subclasses may override this routine to provide different behavior.
|
||||
OMPClause *RebuildOMPIfClause(Expr *Condition,
|
||||
SourceLocation StartLoc,
|
||||
OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
|
||||
Expr *Condition, SourceLocation StartLoc,
|
||||
SourceLocation LParenLoc,
|
||||
SourceLocation NameModifierLoc,
|
||||
SourceLocation ColonLoc,
|
||||
SourceLocation EndLoc) {
|
||||
return getSema().ActOnOpenMPIfClause(Condition, StartLoc,
|
||||
LParenLoc, EndLoc);
|
||||
return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc,
|
||||
LParenLoc, NameModifierLoc, ColonLoc,
|
||||
EndLoc);
|
||||
}
|
||||
|
||||
/// \brief Build a new OpenMP 'final' clause.
|
||||
|
@ -7214,8 +7217,9 @@ OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
|
|||
ExprResult Cond = getDerived().TransformExpr(C->getCondition());
|
||||
if (Cond.isInvalid())
|
||||
return nullptr;
|
||||
return getDerived().RebuildOMPIfClause(Cond.get(), C->getLocStart(),
|
||||
C->getLParenLoc(), C->getLocEnd());
|
||||
return getDerived().RebuildOMPIfClause(
|
||||
C->getNameModifier(), Cond.get(), C->getLocStart(), C->getLParenLoc(),
|
||||
C->getNameModifierLoc(), C->getColonLoc(), C->getLocEnd());
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
|
|
|
@ -1812,6 +1812,9 @@ OMPClause *OMPClauseReader::readClause() {
|
|||
}
|
||||
|
||||
void OMPClauseReader::VisitOMPIfClause(OMPIfClause *C) {
|
||||
C->setNameModifier(static_cast<OpenMPDirectiveKind>(Record[Idx++]));
|
||||
C->setNameModifierLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
C->setCondition(Reader->Reader.ReadSubExpr());
|
||||
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
}
|
||||
|
|
|
@ -1728,6 +1728,9 @@ void OMPClauseWriter::writeClause(OMPClause *C) {
|
|||
}
|
||||
|
||||
void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
|
||||
Record.push_back(C->getNameModifier());
|
||||
Writer->Writer.AddSourceLocation(C->getNameModifierLoc(), Record);
|
||||
Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
|
||||
Writer->Writer.AddStmt(C->getCondition());
|
||||
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ T tmain(T argc, S **argv) {
|
|||
// expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
|
||||
#pragma omp for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
#pragma omp for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
|
||||
#pragma omp for schedule (static, S) // expected-error {{'S' does not refer to a value}}
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
// expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
|
@ -76,14 +76,14 @@ int main(int argc, char **argv) {
|
|||
// expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
|
||||
#pragma omp for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
#pragma omp for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
|
||||
#pragma omp for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
// expected-error@+3 {{statement after '#pragma omp for' must be a for loop}}
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
|
||||
#pragma omp for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
|
||||
foo();
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
|
||||
return tmain<int, char, 1, 0>(argc, argv);
|
||||
|
|
|
@ -39,7 +39,7 @@ T tmain(T argc, S **argv) {
|
|||
// expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
|
||||
#pragma omp for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
#pragma omp for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}}
|
||||
#pragma omp for simd schedule (static, S) // expected-error {{'S' does not refer to a value}}
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
// expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
|
@ -76,14 +76,14 @@ int main(int argc, char **argv) {
|
|||
// expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
|
||||
#pragma omp for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
#pragma omp for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for simd' are ignored}}
|
||||
#pragma omp for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
// expected-error@+3 {{statement after '#pragma omp for simd' must be a for loop}}
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
|
||||
#pragma omp for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
|
||||
foo();
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
|
||||
return tmain<int, char, 1, 0>(argc, argv);
|
||||
|
|
|
@ -34,6 +34,20 @@ int tmain(T argc, S **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(argc)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -64,6 +78,20 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause with 'parallel' name modifier}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
return tmain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ T tmain(T argc, S **argv) {
|
|||
// expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
|
||||
#pragma omp parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
#pragma omp parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
|
||||
#pragma omp parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}}
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
// expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
|
@ -76,14 +76,14 @@ int main(int argc, char **argv) {
|
|||
// expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
|
||||
#pragma omp parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
#pragma omp parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
|
||||
#pragma omp parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp parallel for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
// expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}}
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
|
||||
#pragma omp parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
|
||||
foo();
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
|
||||
return tmain<int, char, 1, 0>(argc, argv);
|
||||
|
|
|
@ -34,6 +34,20 @@ int tmain(T argc, S **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(argc)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for simd'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -64,6 +78,20 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel for simd'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp parallel for simd if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
return tmain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ T tmain(T argc, S **argv) {
|
|||
// expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
|
||||
#pragma omp parallel for simd schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
#pragma omp parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
|
||||
#pragma omp parallel for simd schedule (static, S) // expected-error {{'S' does not refer to a value}}
|
||||
for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
|
||||
// expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp parallel for simd schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
|
@ -76,14 +76,14 @@ int main(int argc, char **argv) {
|
|||
// expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
|
||||
#pragma omp parallel for simd schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
#pragma omp parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for simd' are ignored}}
|
||||
#pragma omp parallel for simd schedule (guided, S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
// expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
|
||||
#pragma omp parallel for simd schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
|
||||
// expected-error@+3 {{statement after '#pragma omp parallel for simd' must be a for loop}}
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
|
||||
#pragma omp parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel for simd schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
|
||||
foo();
|
||||
// expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
|
||||
return tmain<int, char, 1, 0>(argc, argv);
|
||||
|
|
|
@ -22,6 +22,13 @@ int tmain(T argc, S **argv) {
|
|||
#pragma omp parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(argc)
|
||||
#pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(parallel : argc)
|
||||
#pragma omp parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel'}}
|
||||
#pragma omp parallel if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}}
|
||||
#pragma omp parallel if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
foo();
|
||||
|
||||
return 0;
|
||||
|
@ -40,6 +47,13 @@ int main(int argc, char **argv) {
|
|||
#pragma omp parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(parallel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp parallel if(parallel : argc)
|
||||
#pragma omp parallel if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel'}}
|
||||
#pragma omp parallel if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause with 'parallel' name modifier}}
|
||||
#pragma omp parallel if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
foo();
|
||||
|
||||
return tmain(argc, argv);
|
||||
|
|
|
@ -55,6 +55,30 @@ int tmain(T argc, S **argv) {
|
|||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc)
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel sections'}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause with 'parallel' name modifier}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -108,6 +132,30 @@ int main(int argc, char **argv) {
|
|||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc)
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp parallel sections'}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause with 'parallel' name modifier}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp parallel sections if(parallel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
|
||||
return tmain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,12 @@ int main(int argc, char **argv) {
|
|||
#pragma omp target data if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause}}
|
||||
#pragma omp target data if (S1) // expected-error {{'S1' does not refer to a value}}
|
||||
#pragma omp target data if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target data if(target data : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target data if(target data : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target data if(target data : argc)
|
||||
#pragma omp target data if(target data : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target data'}}
|
||||
#pragma omp target data if(target data : argc) if (target data:argc) // expected-error {{directive '#pragma omp target data' cannot contain more than one 'if' clause with 'target data' name modifier}}
|
||||
#pragma omp target data if(target data : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
foo();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -22,6 +22,12 @@ int tmain(T argc, S **argv) {
|
|||
#pragma omp target if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if(argc)
|
||||
#pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if(target : argc)
|
||||
#pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}}
|
||||
#pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}}
|
||||
#pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
foo();
|
||||
|
||||
return 0;
|
||||
|
@ -40,6 +46,12 @@ int main(int argc, char **argv) {
|
|||
#pragma omp target if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if(target : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if(target : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp target if(target : argc)
|
||||
#pragma omp target if(target : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target'}}
|
||||
#pragma omp target if(target : argc) if (target:argc) // expected-error {{directive '#pragma omp target' cannot contain more than one 'if' clause with 'target' name modifier}}
|
||||
#pragma omp target if(target : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
foo();
|
||||
|
||||
return tmain(argc, argv);
|
||||
|
|
|
@ -22,6 +22,12 @@ int tmain(T argc, S **argv) {
|
|||
#pragma omp task if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if(argc)
|
||||
#pragma omp task if(task : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if(task : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if(task : argc)
|
||||
#pragma omp task if(task : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp task'}}
|
||||
#pragma omp task if(task : argc) if (task:argc) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause with 'task' name modifier}}
|
||||
#pragma omp task if(task : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
foo();
|
||||
|
||||
return 0;
|
||||
|
@ -40,6 +46,12 @@ int main(int argc, char **argv) {
|
|||
#pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if(task : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if(task : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp task if(task : argc)
|
||||
#pragma omp task if(task : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp task'}}
|
||||
#pragma omp task if(task : argc) if (task:argc) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause with 'task' name modifier}}
|
||||
#pragma omp task if(task : argc) if (argc) // expected-error {{no more 'if' clause is allowed}}
|
||||
foo();
|
||||
|
||||
return tmain(argc, argv);
|
||||
|
|
Loading…
Reference in New Issue