diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2019-09-17 17:36:49 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2019-09-17 17:36:49 +0000 |
commit | de1444208cc8ad20b90f1d8dd2394dc2ab64a217 (patch) | |
tree | 80dcb2ca96f0000337315bf0b7dda5d10eaf6818 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 20204588ea38f51a99c62beea362106795dd0e19 (diff) | |
download | clang-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.cpp | 49 |
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( |