Skip to content

Commit 92ee602

Browse files
mikerice1969jeanPerier
authored andcommitted
[OPENMP51]Initial parsing/sema for append_args clause for 'declare variant'
Adds initial parsing and sema for the 'append_args' clause. Note that an AST clause is not created as it instead adds its values to the OMPDeclareVariantAttr. Differential Revision: https://reviews.llvm.org/D111854
1 parent 0d6b970 commit 92ee602

File tree

16 files changed

+479
-52
lines changed

16 files changed

+479
-52
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3692,7 +3692,10 @@ def OMPDeclareVariant : InheritableAttr {
36923692
ExprArgument<"VariantFuncRef">,
36933693
OMPTraitInfoArgument<"TraitInfos">,
36943694
VariadicExprArgument<"AdjustArgsNothing">,
3695-
VariadicExprArgument<"AdjustArgsNeedDevicePtr">
3695+
VariadicExprArgument<"AdjustArgsNeedDevicePtr">,
3696+
VariadicEnumArgument<"AppendArgs", "InteropType",
3697+
["target", "targetsync", "target,targetsync"],
3698+
["Target", "TargetSync", "Target_TargetSync"]>
36963699
];
36973700
let AdditionalMembers = [{
36983701
OMPTraitInfo &getTraitInfo() { return *traitInfos; }

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,9 +1359,11 @@ def err_omp_mapper_illegal_identifier : Error<
13591359
"illegal OpenMP user-defined mapper identifier">;
13601360
def err_omp_mapper_expected_declarator : Error<
13611361
"expected declarator on 'omp declare mapper' directive">;
1362+
def err_omp_unexpected_append_op : Error<
1363+
"unexpected operation specified in 'append_args' clause, expected 'interop'">;
13621364
def err_omp_declare_variant_wrong_clause : Error<
1363-
"expected %select{'match'|'match' or 'adjust_args'}0 clause on "
1364-
"'omp declare variant' directive">;
1365+
"expected %select{'match'|'match', 'adjust_args', or 'append_args'}0 clause "
1366+
"on 'omp declare variant' directive">;
13651367
def err_omp_declare_variant_duplicate_nested_trait : Error<
13661368
"nested OpenMP context selector contains duplicated trait '%0'"
13671369
" in selector '%1' and set '%2' with different score">;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10747,9 +10747,14 @@ def err_omp_declare_variant_diff : Error<
1074710747
"function with '#pragma omp declare variant' has a different %select{calling convention"
1074810748
"|return type|constexpr specification|inline specification|storage class|"
1074910749
"linkage}0">;
10750+
def err_omp_declare_variant_prototype_required : Error<
10751+
"function with '#pragma omp declare variant' must have a prototype when "
10752+
"'append_args' is used">;
10753+
def err_omp_interop_type_not_found : Error<
10754+
"'omp_interop_t' must be defined when 'append_args' clause is used; include <omp.h>">;
1075010755
def err_omp_declare_variant_incompat_types : Error<
10751-
"variant in '#pragma omp declare variant' with type %0 is incompatible with type %1"
10752-
>;
10756+
"variant in '#pragma omp declare variant' with type %0 is incompatible with"
10757+
" type %1%select{| with appended arguments}2">;
1075310758
def warn_omp_declare_variant_marked_as_declare_variant : Warning<
1075410759
"variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'"
1075510760
>, InGroup<SourceUsesOpenMP>;
@@ -10818,6 +10823,8 @@ def err_omp_adjust_arg_multiple_clauses : Error<
1081810823
"'adjust_arg' argument %0 used in multiple clauses">;
1081910824
def err_omp_clause_requires_dispatch_construct : Error<
1082010825
"'%0' clause requires 'dispatch' context selector">;
10826+
def err_omp_append_args_with_varargs : Error<
10827+
"'append_args' is not allowed with varargs functions">;
1082110828
} // end of OpenMP category
1082210829

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

clang/include/clang/Parse/Parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3205,6 +3205,10 @@ class Parser : public CodeCompletionHandler {
32053205
/// Parses OpenMP context selectors.
32063206
bool parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI);
32073207

3208+
/// Parse an 'append_args' clause for '#pragma omp declare variant'.
3209+
bool parseOpenMPAppendArgs(
3210+
SmallVectorImpl<OMPDeclareVariantAttr::InteropType> &InterOpTypes);
3211+
32083212
/// Parse a `match` clause for an '#pragma omp declare variant'. Return true
32093213
/// if there was an error.
32103214
bool parseOMPDeclareVariantMatchClause(SourceLocation Loc, OMPTraitInfo &TI,

clang/include/clang/Sema/Sema.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10964,11 +10964,14 @@ class Sema final {
1096410964
/// \param VariantRef Expression that references the variant function, which
1096510965
/// must be used instead of the original one, specified in \p DG.
1096610966
/// \param TI The trait info object representing the match clause.
10967+
/// \param NumAppendArgs The number of omp_interop_t arguments to account for
10968+
/// in checking.
1096710969
/// \returns None, if the function/variant function are not compatible with
1096810970
/// the pragma, pair of original function/variant ref expression otherwise.
1096910971
Optional<std::pair<FunctionDecl *, Expr *>>
1097010972
checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef,
10971-
OMPTraitInfo &TI, SourceRange SR);
10973+
OMPTraitInfo &TI, unsigned NumAppendArgs,
10974+
SourceRange SR);
1097210975

1097310976
/// Called on well-formed '\#pragma omp declare variant' after parsing of
1097410977
/// the associated method/function.
@@ -10977,10 +10980,19 @@ class Sema final {
1097710980
/// \param VariantRef Expression that references the variant function, which
1097810981
/// must be used instead of the original one, specified in \p DG.
1097910982
/// \param TI The context traits associated with the function variant.
10983+
/// \param AdjustArgsNothing The list of 'nothing' arguments.
10984+
/// \param AdjustArgsNeedDevicePtr The list of 'need_device_ptr' arguments.
10985+
/// \param AppendArgs The list of 'append_args' arguments.
10986+
/// \param AdjustArgsLoc The Location of an 'adjust_args' clause.
10987+
/// \param AppendArgsLoc The Location of an 'append_args' clause.
10988+
/// \param SR The SourceRange of the 'declare variant' directive.
1098010989
void ActOnOpenMPDeclareVariantDirective(
1098110990
FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
1098210991
ArrayRef<Expr *> AdjustArgsNothing,
10983-
ArrayRef<Expr *> AdjustArgsNeedDevicePtr, SourceRange SR);
10992+
ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
10993+
ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs,
10994+
SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc,
10995+
SourceRange SR);
1098410996

1098510997
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
1098610998
Expr *Expr,

clang/lib/AST/AttrImpl.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,21 @@ void OMPDeclareVariantAttr::printPrettyPragma(
214214
PrintExprs(adjustArgsNeedDevicePtr_begin(), adjustArgsNeedDevicePtr_end());
215215
OS << ")";
216216
}
217+
218+
auto PrintInteropTypes = [&OS](InteropType *Begin, InteropType *End) {
219+
for (InteropType *I = Begin; I != End; ++I) {
220+
if (I != Begin)
221+
OS << ", ";
222+
OS << "interop(";
223+
OS << ConvertInteropTypeToStr(*I);
224+
OS << ")";
225+
}
226+
};
227+
if (appendArgs_size()) {
228+
OS << " append_args(";
229+
PrintInteropTypes(appendArgs_begin(), appendArgs_end());
230+
OS << ")";
231+
}
217232
}
218233

219234
#include "clang/AST/AttrImpl.inc"

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
191191
case OMPC_uses_allocators:
192192
case OMPC_affinity:
193193
case OMPC_when:
194+
case OMPC_append_args:
194195
break;
195196
default:
196197
break;
@@ -445,6 +446,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
445446
case OMPC_uses_allocators:
446447
case OMPC_affinity:
447448
case OMPC_when:
449+
case OMPC_append_args:
448450
break;
449451
default:
450452
break;

clang/lib/CodeGen/CGStmtOpenMP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5990,6 +5990,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
59905990
case OMPC_filter:
59915991
case OMPC_when:
59925992
case OMPC_adjust_args:
5993+
case OMPC_append_args:
59935994
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
59945995
}
59955996
}

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 112 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,6 +1404,8 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
14041404
OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
14051405
SmallVector<Expr *, 6> AdjustNothing;
14061406
SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1407+
SmallVector<OMPDeclareVariantAttr::InteropType, 3> AppendArgs;
1408+
SourceLocation AdjustArgsLoc, AppendArgsLoc;
14071409

14081410
// At least one clause is required.
14091411
if (Tok.is(tok::annot_pragma_openmp_end)) {
@@ -1428,6 +1430,7 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
14281430
IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
14291431
break;
14301432
case OMPC_adjust_args: {
1433+
AdjustArgsLoc = Tok.getLocation();
14311434
ConsumeToken();
14321435
Parser::OpenMPVarListDataTy Data;
14331436
SmallVector<Expr *> Vars;
@@ -1440,6 +1443,19 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
14401443
Vars);
14411444
break;
14421445
}
1446+
case OMPC_append_args:
1447+
if (!AppendArgs.empty()) {
1448+
Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1449+
<< getOpenMPDirectiveName(OMPD_declare_variant)
1450+
<< getOpenMPClauseName(CKind) << 0;
1451+
IsError = true;
1452+
}
1453+
if (!IsError) {
1454+
AppendArgsLoc = Tok.getLocation();
1455+
ConsumeToken();
1456+
IsError = parseOpenMPAppendArgs(AppendArgs);
1457+
}
1458+
break;
14431459
default:
14441460
llvm_unreachable("Unexpected clause for declare variant.");
14451461
}
@@ -1458,18 +1474,106 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
14581474

14591475
Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
14601476
Actions.checkOpenMPDeclareVariantFunction(
1461-
Ptr, AssociatedFunction.get(), TI,
1477+
Ptr, AssociatedFunction.get(), TI, AppendArgs.size(),
14621478
SourceRange(Loc, Tok.getLocation()));
14631479

14641480
if (DeclVarData && !TI.Sets.empty())
14651481
Actions.ActOnOpenMPDeclareVariantDirective(
14661482
DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1467-
AdjustNeedDevicePtr, SourceRange(Loc, Tok.getLocation()));
1483+
AdjustNeedDevicePtr, AppendArgs, AdjustArgsLoc, AppendArgsLoc,
1484+
SourceRange(Loc, Tok.getLocation()));
14681485

14691486
// Skip the last annot_pragma_openmp_end.
14701487
(void)ConsumeAnnotationToken();
14711488
}
14721489

1490+
/// Parse a list of interop-types. These are 'target' and 'targetsync'. Both
1491+
/// are allowed but duplication of either is not meaningful.
1492+
static Optional<OMPDeclareVariantAttr::InteropType>
1493+
parseInteropTypeList(Parser &P) {
1494+
const Token &Tok = P.getCurToken();
1495+
bool HasError = false;
1496+
bool IsTarget = false;
1497+
bool IsTargetSync = false;
1498+
1499+
while (Tok.is(tok::identifier)) {
1500+
if (Tok.getIdentifierInfo()->isStr("target")) {
1501+
// OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
1502+
// Each interop-type may be specified on an action-clause at most
1503+
// once.
1504+
if (IsTarget)
1505+
P.Diag(Tok, diag::warn_omp_more_one_interop_type) << "target";
1506+
IsTarget = true;
1507+
} else if (Tok.getIdentifierInfo()->isStr("targetsync")) {
1508+
if (IsTargetSync)
1509+
P.Diag(Tok, diag::warn_omp_more_one_interop_type) << "targetsync";
1510+
IsTargetSync = true;
1511+
} else {
1512+
HasError = true;
1513+
P.Diag(Tok, diag::err_omp_expected_interop_type);
1514+
}
1515+
P.ConsumeToken();
1516+
1517+
if (!Tok.is(tok::comma))
1518+
break;
1519+
P.ConsumeToken();
1520+
}
1521+
if (HasError)
1522+
return None;
1523+
1524+
if (!IsTarget && !IsTargetSync) {
1525+
P.Diag(Tok, diag::err_omp_expected_interop_type);
1526+
return None;
1527+
}
1528+
1529+
// As of OpenMP 5.1,there are two interop-types, "target" and
1530+
// "targetsync". Either or both are allowed for a single interop.
1531+
if (IsTarget && IsTargetSync)
1532+
return OMPDeclareVariantAttr::Target_TargetSync;
1533+
if (IsTarget)
1534+
return OMPDeclareVariantAttr::Target;
1535+
return OMPDeclareVariantAttr::TargetSync;
1536+
}
1537+
1538+
bool Parser::parseOpenMPAppendArgs(
1539+
SmallVectorImpl<OMPDeclareVariantAttr::InteropType> &InterOpTypes) {
1540+
bool HasError = false;
1541+
// Parse '('.
1542+
BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1543+
if (T.expectAndConsume(diag::err_expected_lparen_after,
1544+
getOpenMPClauseName(OMPC_append_args).data()))
1545+
return true;
1546+
1547+
// Parse the list of append-ops, each is;
1548+
// interop(interop-type[,interop-type]...)
1549+
while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr("interop")) {
1550+
ConsumeToken();
1551+
BalancedDelimiterTracker IT(*this, tok::l_paren,
1552+
tok::annot_pragma_openmp_end);
1553+
if (IT.expectAndConsume(diag::err_expected_lparen_after, "interop"))
1554+
return true;
1555+
1556+
// Parse the interop-types.
1557+
if (Optional<OMPDeclareVariantAttr::InteropType> IType =
1558+
parseInteropTypeList(*this))
1559+
InterOpTypes.push_back(IType.getValue());
1560+
else
1561+
HasError = true;
1562+
1563+
IT.consumeClose();
1564+
if (Tok.is(tok::comma))
1565+
ConsumeToken();
1566+
}
1567+
if (!HasError && InterOpTypes.empty()) {
1568+
HasError = true;
1569+
Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1570+
SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1571+
StopBeforeMatch);
1572+
}
1573+
HasError = T.consumeClose() || HasError;
1574+
return HasError;
1575+
}
1576+
14731577
bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
14741578
OMPTraitInfo &TI,
14751579
OMPTraitInfo *ParentTI) {
@@ -3342,36 +3446,15 @@ OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
33423446
}
33433447

33443448
// Parse the interop-types.
3345-
bool HasError = false;
3346-
while (Tok.is(tok::identifier)) {
3347-
if (PP.getSpelling(Tok) == "target") {
3348-
// OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
3349-
// Each interop-type may be specified on an action-clause at most
3350-
// once.
3351-
if (IsTarget)
3352-
Diag(Tok, diag::warn_omp_more_one_interop_type) << "target";
3353-
IsTarget = true;
3354-
} else if (PP.getSpelling(Tok) == "targetsync") {
3355-
if (IsTargetSync)
3356-
Diag(Tok, diag::warn_omp_more_one_interop_type) << "targetsync";
3357-
IsTargetSync = true;
3358-
} else {
3359-
HasError = true;
3360-
Diag(Tok, diag::err_omp_expected_interop_type);
3361-
}
3362-
ConsumeToken();
3363-
3364-
if (!Tok.is(tok::comma))
3365-
break;
3366-
ConsumeToken();
3449+
if (Optional<OMPDeclareVariantAttr::InteropType> IType =
3450+
parseInteropTypeList(*this)) {
3451+
IsTarget = IType != OMPDeclareVariantAttr::TargetSync;
3452+
IsTargetSync = IType != OMPDeclareVariantAttr::Target;
3453+
if (Tok.isNot(tok::colon))
3454+
Diag(Tok, diag::warn_pragma_expected_colon) << "interop types";
33673455
}
3368-
if (!HasError && !IsTarget && !IsTargetSync)
3369-
Diag(Tok, diag::err_omp_expected_interop_type);
3370-
33713456
if (Tok.is(tok::colon))
33723457
ConsumeToken();
3373-
else if (IsTarget || IsTargetSync)
3374-
Diag(Tok, diag::warn_pragma_expected_colon) << "interop types";
33753458
}
33763459

33773460
// Parse the variable.

0 commit comments

Comments
 (0)