summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-09-17 17:36:49 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-09-17 17:36:49 +0000
commitde1444208cc8ad20b90f1d8dd2394dc2ab64a217 (patch)
tree80dcb2ca96f0000337315bf0b7dda5d10eaf6818 /lib/Sema/SemaTemplateInstantiateDecl.cpp
parent20204588ea38f51a99c62beea362106795dd0e19 (diff)
downloadclang-de1444208cc8ad20b90f1d8dd2394dc2ab64a217.tar.gz
[OPENMP5.0]Introduce attribute for declare variant directive.
Added attribute for declare variant directive. It will allow to handle declare variant directive at the codegen and will allow to add extra checks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372147 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 7521cadb9b..6585917925 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -348,6 +348,50 @@ static void instantiateOMPDeclareSimdDeclAttr(
Attr.getRange());
}
+/// Instantiation of 'declare variant' attribute and its arguments.
+static void instantiateOMPDeclareVariantAttr(
+ Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
+ const OMPDeclareVariantAttr &Attr, Decl *New) {
+ // Allow 'this' in clauses with varlists.
+ if (auto *FTD = dyn_cast<FunctionTemplateDecl>(New))
+ New = FTD->getTemplatedDecl();
+ auto *FD = cast<FunctionDecl>(New);
+ auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(FD->getDeclContext());
+
+ auto &&SubstExpr = [FD, ThisContext, &S, &TemplateArgs](Expr *E) {
+ if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
+ if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
+ Sema::ContextRAII SavedContext(S, FD);
+ LocalInstantiationScope Local(S);
+ if (FD->getNumParams() > PVD->getFunctionScopeIndex())
+ Local.InstantiatedLocal(
+ PVD, FD->getParamDecl(PVD->getFunctionScopeIndex()));
+ return S.SubstExpr(E, TemplateArgs);
+ }
+ Sema::CXXThisScopeRAII ThisScope(S, ThisContext, Qualifiers(),
+ FD->isCXXInstanceMember());
+ return S.SubstExpr(E, TemplateArgs);
+ };
+
+ // Substitute a single OpenMP clause, which is a potentially-evaluated
+ // full-expression.
+ auto &&Subst = [&SubstExpr, &S](Expr *E) {
+ EnterExpressionEvaluationContext Evaluated(
+ S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
+ ExprResult Res = SubstExpr(E);
+ if (Res.isInvalid())
+ return Res;
+ return S.ActOnFinishFullExpr(Res.get(), false);
+ };
+
+ ExprResult VariantFuncRef;
+ if (Expr *E = Attr.getVariantFuncRef())
+ VariantFuncRef = Subst(E);
+
+ (void)S.ActOnOpenMPDeclareVariantDirective(
+ S.ConvertDeclToDeclGroup(New), VariantFuncRef.get(), Attr.getRange());
+}
+
static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const AMDGPUFlatWorkGroupSizeAttr &Attr, Decl *New) {
@@ -505,6 +549,11 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
continue;
}
+ if (const auto *OMPAttr = dyn_cast<OMPDeclareVariantAttr>(TmplAttr)) {
+ instantiateOMPDeclareVariantAttr(*this, TemplateArgs, *OMPAttr, New);
+ continue;
+ }
+
if (const auto *AMDGPUFlatWorkGroupSize =
dyn_cast<AMDGPUFlatWorkGroupSizeAttr>(TmplAttr)) {
instantiateDependentAMDGPUFlatWorkGroupSizeAttr(