[OPENMP50]Parsing/sema support for 'implementation/vendor' context
selector. Added basic parsing/semantic support for 'implementation={vendor(<vendor>)}' context selector. llvm-svn: 372917
This commit is contained in:
parent
45c935bd0b
commit
9ff34745a2
|
@ -3288,18 +3288,51 @@ def OMPDeclareVariant : Attr {
|
|||
let HasCustomParsing = 1;
|
||||
let Documentation = [OMPDeclareVariantDocs];
|
||||
let Args = [
|
||||
ExprArgument<"VariantFuncRef">
|
||||
ExprArgument<"VariantFuncRef">,
|
||||
EnumArgument<"CtxSelectorSet", "CtxSelectorSetType",
|
||||
[ "", "implementation"
|
||||
],
|
||||
[
|
||||
"CtxSetUnknown", "CtxSetImplementation"
|
||||
]>,
|
||||
EnumArgument<"CtxSelector", "CtxSelectorType",
|
||||
[ "", "vendor"
|
||||
],
|
||||
[
|
||||
"CtxUnknown", "CtxVendor"
|
||||
]>,
|
||||
StringArgument<"ImplVendor", 1>
|
||||
];
|
||||
let AdditionalMembers = [{
|
||||
void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy)
|
||||
const {
|
||||
assert(getCtxSelectorSet() != CtxSetUnknown &&
|
||||
getCtxSelector() != CtxUnknown && "Unknown context selector.");
|
||||
if (const Expr *E = getVariantFuncRef()) {
|
||||
OS << "(";
|
||||
E->printPretty(OS, nullptr, Policy);
|
||||
OS << ")";
|
||||
}
|
||||
// TODO: add printing of real context selectors.
|
||||
OS << " match(unknown={})";
|
||||
OS << " match(";
|
||||
switch (getCtxSelectorSet()) {
|
||||
case CtxSetImplementation:
|
||||
OS << "implementation={";
|
||||
switch (getCtxSelector()) {
|
||||
case CtxVendor:
|
||||
OS << "vendor(";
|
||||
OS << getImplVendor();
|
||||
OS << ")";
|
||||
break;
|
||||
case CtxUnknown:
|
||||
llvm_unreachable("Unknown context selector.");
|
||||
}
|
||||
OS << "}";
|
||||
break;
|
||||
case CtxSetUnknown:
|
||||
llvm_unreachable("Unknown context selector set.");
|
||||
}
|
||||
OS << ")";
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -1206,6 +1206,11 @@ def err_omp_declare_variant_no_ctx_selector : Error<
|
|||
"expected context selector in '%0' clause on 'omp declare variant' directive">;
|
||||
def err_omp_declare_variant_equal_expected : Error<
|
||||
"expected '=' after '%0' context selector set name on 'omp declare variant' directive">;
|
||||
def warn_omp_declare_variant_cs_name_expected : Warning<
|
||||
"unknown context selector in '%0' context selector set of 'omp declare variant' directive, ignored">,
|
||||
InGroup<OpenMPClauses>;
|
||||
def err_omp_declare_variant_item_expected : Error<
|
||||
"expected %0 in '%1' context selector of '%2' selector set of 'omp declare variant' directive">;
|
||||
def warn_omp_more_one_device_type_clause : Warning<
|
||||
"more than one 'device_type' clause is specified">,
|
||||
InGroup<OpenMPClauses>;
|
||||
|
|
|
@ -197,6 +197,9 @@
|
|||
#ifndef OPENMP_DECLARE_VARIANT_CLAUSE
|
||||
#define OPENMP_DECLARE_VARIANT_CLAUSE(Name)
|
||||
#endif
|
||||
#ifndef OPENMP_MATCH_KIND
|
||||
#define OPENMP_MATCH_KIND(Name)
|
||||
#endif
|
||||
|
||||
// OpenMP directives.
|
||||
OPENMP_DIRECTIVE(threadprivate)
|
||||
|
@ -965,6 +968,11 @@ OPENMP_DEVICE_TYPE_KIND(any)
|
|||
// Clauses allowed for OpenMP directive 'declare variant'.
|
||||
OPENMP_DECLARE_VARIANT_CLAUSE(match)
|
||||
|
||||
// Context selectors for 'match' clause.
|
||||
// TODO: add other context selectors.
|
||||
OPENMP_MATCH_KIND(implementation)
|
||||
|
||||
#undef OPENMP_MATCH_KIND
|
||||
#undef OPENMP_DECLARE_VARIANT_CLAUSE
|
||||
#undef OPENMP_DEVICE_TYPE_KIND
|
||||
#undef OPENMP_ALLOCATE_CLAUSE
|
||||
|
|
|
@ -2836,9 +2836,11 @@ private:
|
|||
SourceLocation Loc);
|
||||
/// Parses OpenMP context selectors and calls \p Callback for each
|
||||
/// successfully parsed context selector.
|
||||
bool
|
||||
parseOpenMPContextSelectors(SourceLocation Loc,
|
||||
llvm::function_ref<void(SourceRange)> Callback);
|
||||
bool parseOpenMPContextSelectors(
|
||||
SourceLocation Loc,
|
||||
llvm::function_ref<
|
||||
void(SourceRange, const Sema::OpenMPDeclareVariantCtsSelectorData &)>
|
||||
Callback);
|
||||
|
||||
/// Parse clauses for '#pragma omp declare variant'.
|
||||
void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks,
|
||||
|
|
|
@ -9102,6 +9102,20 @@ private:
|
|||
bool MightBeOdrUse);
|
||||
|
||||
public:
|
||||
/// Struct to store the context selectors info for declare variant directive.
|
||||
struct OpenMPDeclareVariantCtsSelectorData {
|
||||
OMPDeclareVariantAttr::CtxSelectorSetType CtxSet =
|
||||
OMPDeclareVariantAttr::CtxSetUnknown;
|
||||
OMPDeclareVariantAttr::CtxSelectorType Ctx =
|
||||
OMPDeclareVariantAttr::CtxUnknown;
|
||||
StringRef ImplVendor;
|
||||
explicit OpenMPDeclareVariantCtsSelectorData() = default;
|
||||
explicit OpenMPDeclareVariantCtsSelectorData(
|
||||
OMPDeclareVariantAttr::CtxSelectorSetType CtxSet,
|
||||
OMPDeclareVariantAttr::CtxSelectorType Ctx, StringRef ImplVendor)
|
||||
: CtxSet(CtxSet), Ctx(Ctx), ImplVendor(ImplVendor) {}
|
||||
};
|
||||
|
||||
/// Checks if the variant/multiversion functions are compatible.
|
||||
bool areMultiversionVariantFunctionsCompatible(
|
||||
const FunctionDecl *OldFD, const FunctionDecl *NewFD,
|
||||
|
@ -9542,10 +9556,9 @@ public:
|
|||
/// \param VariantRef Expression that references the variant function, which
|
||||
/// must be used instead of the original one, specified in \p DG.
|
||||
/// \returns None, if the function/variant function are not compatible with
|
||||
/// the pragma,pair of original function/variant ref expression otherwise.
|
||||
Optional<std::pair<FunctionDecl *, Expr *>>
|
||||
checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef,
|
||||
SourceRange SR);
|
||||
/// the pragma, pair of original function/variant ref expression otherwise.
|
||||
Optional<std::pair<FunctionDecl *, Expr *>> checkOpenMPDeclareVariantFunction(
|
||||
DeclGroupPtrTy DG, Expr *VariantRef, SourceRange SR);
|
||||
|
||||
/// Called on well-formed '\#pragma omp declare variant' after parsing of
|
||||
/// the associated method/function.
|
||||
|
@ -9553,8 +9566,11 @@ public:
|
|||
/// applied to.
|
||||
/// \param VariantRef Expression that references the variant function, which
|
||||
/// must be used instead of the original one, specified in \p DG.
|
||||
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef,
|
||||
SourceRange SR);
|
||||
/// \param Data Set of context-specific data for the specified context
|
||||
/// selector.
|
||||
void ActOnOpenMPDeclareVariantDirective(
|
||||
FunctionDecl *FD, Expr *VariantRef, SourceRange SR,
|
||||
const Sema::OpenMPDeclareVariantCtsSelectorData &Data);
|
||||
|
||||
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
|
||||
Expr *Expr,
|
||||
|
|
|
@ -786,12 +786,72 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
|
|||
LinModifiers, Steps, SourceRange(Loc, EndLoc));
|
||||
}
|
||||
|
||||
/// Parse context selector for 'implementation' selector set:
|
||||
/// 'vendor' '(' <vendor> ')'
|
||||
static void
|
||||
parseImplementationSelector(Parser &P,
|
||||
Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
|
||||
const Token &Tok = P.getCurToken();
|
||||
// Parse inner context selector set name, if any.
|
||||
if (!Tok.is(tok::identifier)) {
|
||||
P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected)
|
||||
<< "implementation";
|
||||
// Skip until either '}', ')', or end of directive.
|
||||
while (!P.SkipUntil(tok::r_brace, tok::r_paren,
|
||||
tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
|
||||
;
|
||||
return;
|
||||
}
|
||||
SmallString<16> Buffer;
|
||||
StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer);
|
||||
OMPDeclareVariantAttr::CtxSelectorType CSKind =
|
||||
OMPDeclareVariantAttr::CtxUnknown;
|
||||
(void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorType(CtxSelectorName,
|
||||
CSKind);
|
||||
(void)P.ConsumeToken();
|
||||
switch (CSKind) {
|
||||
case OMPDeclareVariantAttr::CtxVendor: {
|
||||
// Parse '('.
|
||||
BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
|
||||
(void)T.expectAndConsume(diag::err_expected_lparen_after,
|
||||
CtxSelectorName.data());
|
||||
// Parse <vendor>.
|
||||
StringRef VendorName;
|
||||
if (Tok.is(tok::identifier)) {
|
||||
VendorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
|
||||
(void)P.ConsumeToken();
|
||||
} else {
|
||||
P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_item_expected)
|
||||
<< "vendor identifier" << "vendor" << "implementation";
|
||||
}
|
||||
// Parse ')'.
|
||||
(void)T.consumeClose();
|
||||
if (!VendorName.empty())
|
||||
Data.ImplVendor = VendorName;
|
||||
break;
|
||||
}
|
||||
case OMPDeclareVariantAttr::CtxUnknown:
|
||||
P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected)
|
||||
<< "implementation";
|
||||
// Skip until either '}', ')', or end of directive.
|
||||
while (!P.SkipUntil(tok::r_brace, tok::r_paren,
|
||||
tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
|
||||
;
|
||||
return;
|
||||
}
|
||||
Data.CtxSet = OMPDeclareVariantAttr::CtxSetImplementation;
|
||||
Data.Ctx = CSKind;
|
||||
}
|
||||
|
||||
/// Parses clauses for 'declare variant' directive.
|
||||
/// clause:
|
||||
/// <selector_set_name> '=' '{' <context_selectors> '}'
|
||||
/// [ ',' <selector_set_name> '=' '{' <context_selectors> '}' ]
|
||||
bool Parser::parseOpenMPContextSelectors(
|
||||
SourceLocation Loc, llvm::function_ref<void(SourceRange)> Callback) {
|
||||
SourceLocation Loc,
|
||||
llvm::function_ref<void(SourceRange,
|
||||
const Sema::OpenMPDeclareVariantCtsSelectorData &)>
|
||||
Callback) {
|
||||
do {
|
||||
// Parse inner context selector set name.
|
||||
if (!Tok.is(tok::identifier)) {
|
||||
|
@ -800,30 +860,43 @@ bool Parser::parseOpenMPContextSelectors(
|
|||
return true;
|
||||
}
|
||||
SmallString<16> Buffer;
|
||||
StringRef CtxSelectorName = PP.getSpelling(Tok, Buffer);
|
||||
StringRef CtxSelectorSetName = PP.getSpelling(Tok, Buffer);
|
||||
// Parse '='.
|
||||
(void)ConsumeToken();
|
||||
if (Tok.isNot(tok::equal)) {
|
||||
Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected)
|
||||
<< CtxSelectorName;
|
||||
<< CtxSelectorSetName;
|
||||
return true;
|
||||
}
|
||||
(void)ConsumeToken();
|
||||
// TBD: add parsing of known context selectors.
|
||||
// Unknown selector - just ignore it completely.
|
||||
Sema::OpenMPDeclareVariantCtsSelectorData Data;
|
||||
{
|
||||
// Parse '{'.
|
||||
BalancedDelimiterTracker TBr(*this, tok::l_brace,
|
||||
tok::annot_pragma_openmp_end);
|
||||
if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "="))
|
||||
return true;
|
||||
while (!SkipUntil(tok::r_brace, tok::r_paren,
|
||||
tok::annot_pragma_openmp_end, StopBeforeMatch))
|
||||
;
|
||||
OMPDeclareVariantAttr::CtxSelectorSetType CSSKind =
|
||||
OMPDeclareVariantAttr::CtxSetUnknown;
|
||||
(void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorSetType(
|
||||
CtxSelectorSetName, CSSKind);
|
||||
switch (CSSKind) {
|
||||
case OMPDeclareVariantAttr::CtxSetImplementation:
|
||||
parseImplementationSelector(*this, Data);
|
||||
break;
|
||||
case OMPDeclareVariantAttr::CtxSetUnknown:
|
||||
// Skip until either '}', ')', or end of directive.
|
||||
while (!SkipUntil(tok::r_brace, tok::r_paren,
|
||||
tok::annot_pragma_openmp_end, StopBeforeMatch))
|
||||
;
|
||||
break;
|
||||
}
|
||||
// Parse '}'.
|
||||
(void)TBr.consumeClose();
|
||||
}
|
||||
Callback(SourceRange(Loc, Tok.getLocation()));
|
||||
Callback(SourceRange(Loc, Tok.getLocation()), Data);
|
||||
// Consume ','
|
||||
if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end))
|
||||
(void)ExpectAndConsume(tok::comma);
|
||||
|
@ -888,11 +961,15 @@ void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
|
|||
}
|
||||
|
||||
// Parse inner context selectors.
|
||||
if (!parseOpenMPContextSelectors(Loc, [this, &DeclVarData](SourceRange SR) {
|
||||
if (DeclVarData.hasValue())
|
||||
Actions.ActOnOpenMPDeclareVariantDirective(
|
||||
DeclVarData.getValue().first, DeclVarData.getValue().second, SR);
|
||||
})) {
|
||||
if (!parseOpenMPContextSelectors(
|
||||
Loc, [this, &DeclVarData](
|
||||
SourceRange SR,
|
||||
const Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
|
||||
if (DeclVarData.hasValue())
|
||||
Actions.ActOnOpenMPDeclareVariantDirective(
|
||||
DeclVarData.getValue().first, DeclVarData.getValue().second,
|
||||
SR, Data);
|
||||
})) {
|
||||
// Parse ')'.
|
||||
(void)T.consumeClose();
|
||||
// Need to check for extra tokens.
|
||||
|
|
|
@ -5101,11 +5101,14 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
|
|||
return std::make_pair(FD, cast<Expr>(DRE));
|
||||
}
|
||||
|
||||
void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
|
||||
Expr *VariantRef,
|
||||
SourceRange SR) {
|
||||
auto *NewAttr =
|
||||
OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, SR);
|
||||
void Sema::ActOnOpenMPDeclareVariantDirective(
|
||||
FunctionDecl *FD, Expr *VariantRef, SourceRange SR,
|
||||
const Sema::OpenMPDeclareVariantCtsSelectorData &Data) {
|
||||
if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown ||
|
||||
Data.Ctx == OMPDeclareVariantAttr::CtxUnknown)
|
||||
return;
|
||||
auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
|
||||
Context, VariantRef, Data.CtxSet, Data.Ctx, Data.ImplVendor, SR);
|
||||
FD->addAttr(NewAttr);
|
||||
}
|
||||
|
||||
|
|
|
@ -395,9 +395,11 @@ static void instantiateOMPDeclareVariantAttr(
|
|||
if (!DeclVarData)
|
||||
return;
|
||||
// Instantiate the attribute.
|
||||
Sema::OpenMPDeclareVariantCtsSelectorData Data(
|
||||
Attr.getCtxSelectorSet(), Attr.getCtxSelector(), Attr.getImplVendor());
|
||||
S.ActOnOpenMPDeclareVariantDirective(DeclVarData.getValue().first,
|
||||
DeclVarData.getValue().second,
|
||||
Attr.getRange());
|
||||
Attr.getRange(), Data);
|
||||
}
|
||||
|
||||
static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr(
|
||||
|
|
|
@ -8,10 +8,12 @@ int foo(void);
|
|||
|
||||
#pragma omp declare variant(foo) match(xxx={}, yyy={ccc})
|
||||
#pragma omp declare variant(foo) match(xxx={vvv})
|
||||
#pragma omp declare variant(foo) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(foo) match(implementation={vendor(unknown)})
|
||||
int bar(void);
|
||||
|
||||
// CHECK: int foo();
|
||||
// CHECK-NEXT: #pragma omp declare variant(foo) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foo) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foo) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: int bar();
|
||||
|
|
|
@ -17,20 +17,19 @@ T foofoo() { return T(); }
|
|||
// CHECK-NEXT: return int();
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: int bar();
|
||||
#pragma omp declare variant(foofoo <int>) match(xxx = {})
|
||||
#pragma omp declare variant(foofoo <int>) match(xxx = {vvv})
|
||||
#pragma omp declare variant(foofoo <int>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(foofoo <int>) match(implementation={vendor(unknown)})
|
||||
int bar();
|
||||
|
||||
// CHECK: #pragma omp declare variant(foofoo<T>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<T>) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: template <typename T> T barbar();
|
||||
#pragma omp declare variant(foofoo <T>) match(xxx = {})
|
||||
#pragma omp declare variant(foofoo <T>) match(xxx = {vvv})
|
||||
|
@ -38,16 +37,14 @@ int bar();
|
|||
#pragma omp declare variant(foofoo <T>) match(user = {score(<expr>) : condition(<expr>)}, user = {condition(<expr>)})
|
||||
#pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)})
|
||||
#pragma omp declare variant(foofoo <T>) match(user = {condition(<expr>)})
|
||||
#pragma omp declare variant(foofoo <T>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(foofoo <T>) match(implementation={vendor(unknown)})
|
||||
template <typename T>
|
||||
T barbar();
|
||||
|
||||
// CHECK: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(foofoo<int>) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: template<> int barbar<int>();
|
||||
|
||||
// CHECK-NEXT: int baz() {
|
||||
|
@ -67,15 +64,21 @@ template <class C>
|
|||
void h_ref(C *hp, C *hp2, C *hq, C *lin) {
|
||||
}
|
||||
|
||||
// CHECK: #pragma omp declare variant(h_ref<C>) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(h_ref<C>) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(h_ref<C>) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(h_ref<C>) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: template <class C> void h(C *hp, C *hp2, C *hq, C *lin) {
|
||||
// CHECK-NEXT: }
|
||||
#pragma omp declare variant(h_ref <C>) match(xxx = {})
|
||||
#pragma omp declare variant(h_ref <C>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(h_ref <C>) match(implementation={vendor(unknown)})
|
||||
template <class C>
|
||||
void h(C *hp, C *hp2, C *hq, C *lin) {
|
||||
}
|
||||
|
||||
// CHECK: #pragma omp declare variant(h_ref<float>) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(h_ref<float>) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(h_ref<float>) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(h_ref<float>) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: template<> void h<float>(float *hp, float *hp2, float *hq, float *lin) {
|
||||
// CHECK-NEXT: }
|
||||
|
||||
|
@ -83,6 +86,8 @@ void h(C *hp, C *hp2, C *hq, C *lin) {
|
|||
// CHECK-NEXT: h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
|
||||
// CHECK-NEXT: }
|
||||
#pragma omp declare variant(h_ref <double>) match(xxx = {})
|
||||
#pragma omp declare variant(h_ref <double>) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(h_ref <double>) match(implementation={vendor(unknown)})
|
||||
template <>
|
||||
void h(double *hp, double *hp2, double *hq, double *lin) {
|
||||
h((float *)hp, (float *)hp2, (float *)hq, (float *)lin);
|
||||
|
@ -92,27 +97,39 @@ void h(double *hp, double *hp2, double *hq, double *lin) {
|
|||
int fn();
|
||||
// CHECK: int fn(int);
|
||||
int fn(int);
|
||||
// CHECK: #pragma omp declare variant(fn) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(fn) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(fn) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(fn) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: int overload();
|
||||
#pragma omp declare variant(fn) match(xxx = {})
|
||||
#pragma omp declare variant(fn) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(fn) match(implementation={vendor(unknown)})
|
||||
int overload(void);
|
||||
|
||||
// CHECK: int fn_deduced_variant() {
|
||||
// CHECK-NEXT: return 0;
|
||||
// CHECK-NEXT: }
|
||||
auto fn_deduced_variant() { return 0; }
|
||||
// CHECK: #pragma omp declare variant(fn_deduced_variant) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: int fn_deduced();
|
||||
#pragma omp declare variant(fn_deduced_variant) match(xxx = {})
|
||||
#pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(unknown)})
|
||||
int fn_deduced();
|
||||
|
||||
// CHECK: int fn_deduced_variant1();
|
||||
int fn_deduced_variant1();
|
||||
// CHECK: #pragma omp declare variant(fn_deduced_variant1) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: int fn_deduced1() {
|
||||
// CHECK-NEXT: return 0;
|
||||
// CHECK-NEXT: }
|
||||
#pragma omp declare variant(fn_deduced_variant1) match(xxx = {})
|
||||
#pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(unknown)})
|
||||
auto fn_deduced1() { return 0; }
|
||||
|
||||
// CHECK: struct SpecialFuncs {
|
||||
|
@ -126,8 +143,9 @@ auto fn_deduced1() { return 0; }
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: void bar(int) {
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(unknown={})
|
||||
// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: void foo1() {
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: } s;
|
||||
|
@ -141,16 +159,22 @@ struct SpecialFuncs {
|
|||
void bar(int) {}
|
||||
#pragma omp declare variant(SpecialFuncs::baz) match(xxx = {})
|
||||
#pragma omp declare variant(SpecialFuncs::bar) match(xxx = {})
|
||||
#pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)})
|
||||
void foo1() {}
|
||||
} s;
|
||||
|
||||
// CHECK: static void static_f_variant() {
|
||||
// CHECK-NEXT: }
|
||||
static void static_f_variant() {}
|
||||
// CHECK: #pragma omp declare variant(static_f_variant) match(unknown={})
|
||||
// CHECK: #pragma omp declare variant(static_f_variant) match(implementation={vendor(unknown)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(static_f_variant) match(implementation={vendor(ibm)})
|
||||
// CHECK-NEXT: #pragma omp declare variant(static_f_variant) match(implementation={vendor(llvm)})
|
||||
// CHECK-NEXT: static void static_f() {
|
||||
// CHECK-NEXT: }
|
||||
#pragma omp declare variant(static_f_variant) match(xxx = {})
|
||||
#pragma omp declare variant(static_f_variant) match(implementation={vendor(ibm)}, implementation={vendor(llvm)})
|
||||
#pragma omp declare variant(static_f_variant) match(implementation={vendor(unknown)})
|
||||
static void static_f() {}
|
||||
|
||||
// CHECK: void bazzzz() {
|
||||
|
|
|
@ -26,6 +26,10 @@ int foo(void);
|
|||
#pragma omp declare variant(foo) match(xxx={vvv})
|
||||
#pragma omp declare variant(foo) match(xxx={vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}}
|
||||
#pragma omp declare variant(foo) match(xxx={vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
|
||||
#pragma omp declare variant(foo) match(implementation={xxx}) // expected-warning {{unknown context selector in 'implementation' context selector set of 'omp declare variant' directive, ignored}}
|
||||
#pragma omp declare variant(foo) match(implementation={vendor}) // expected-error {{expected '(' after 'vendor'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp declare variant(foo) match(implementation={vendor(}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp declare variant(foo) match(implementation={vendor()}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}}
|
||||
int bar(void);
|
||||
|
||||
// expected-error@+2 {{'#pragma omp declare variant' can only be applied to functions}}
|
||||
|
@ -89,7 +93,7 @@ void diff_ret(void);
|
|||
void marked(void);
|
||||
void not_marked(void);
|
||||
// expected-note@+1 {{marked as 'declare variant' here}}
|
||||
#pragma omp declare variant(not_marked) match(xxx={})
|
||||
#pragma omp declare variant(not_marked) match(implementation={vendor(unknown)})
|
||||
void marked_variant(void);
|
||||
// expected-warning@+1 {{variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'}}
|
||||
#pragma omp declare variant(marked_variant) match(xxx={})
|
||||
|
|
|
@ -29,6 +29,10 @@ T foofoo();
|
|||
#pragma omp declare variant(foofoo <int>) match(xxx = {vvv})
|
||||
#pragma omp declare variant(foofoo <int>) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}}
|
||||
#pragma omp declare variant(foofoo <int>) match(xxx = {vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}}
|
||||
#pragma omp declare variant(foofoo <int>) match(implementation={xxx}) // expected-warning {{unknown context selector in 'implementation' context selector set of 'omp declare variant' directive, ignored}}
|
||||
#pragma omp declare variant(foofoo <int>) match(implementation={vendor}) // expected-error {{expected '(' after 'vendor'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp declare variant(foofoo <int>) match(implementation={vendor(}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
#pragma omp declare variant(foofoo <int>) match(implementation={vendor()}) // expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}}
|
||||
int bar();
|
||||
|
||||
#pragma omp declare variant // expected-error {{expected '(' after 'declare variant'}}
|
||||
|
|
Loading…
Reference in New Issue