diff options
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1da0dfe..2e8ddc8 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -188,15 +188,37 @@ static void instantiateDependentAnnotationAttr( const AnnotateAttr *Attr, Decl *New) { EnterExpressionEvaluationContext Unevaluated( S, Sema::ExpressionEvaluationContext::ConstantEvaluated); + + // If the attribute has delayed arguments it will have to instantiate those + // and handle them as new arguments for the attribute. + bool HasDelayedArgs = Attr->delayedArgs_size(); + + ArrayRef<Expr *> ArgsToInstantiate = + HasDelayedArgs + ? ArrayRef<Expr *>{Attr->delayedArgs_begin(), Attr->delayedArgs_end()} + : ArrayRef<Expr *>{Attr->args_begin(), Attr->args_end()}; + SmallVector<Expr *, 4> Args; - Args.reserve(Attr->args_size()); - for (auto *E : Attr->args()) { - ExprResult Result = S.SubstExpr(E, TemplateArgs); - if (!Result.isUsable()) + if (S.SubstExprs(ArgsToInstantiate, + /*IsCall=*/false, TemplateArgs, Args)) + return; + + StringRef Str = Attr->getAnnotation(); + if (HasDelayedArgs) { + if (Args.size() < 1) { + S.Diag(Attr->getLoc(), diag::err_attribute_too_few_arguments) + << Attr << 1; return; - Args.push_back(Result.get()); + } + + if (!S.checkStringLiteralArgumentAttr(*Attr, Args[0], Str)) + return; + + llvm::SmallVector<Expr *, 4> ActualArgs; + ActualArgs.insert(ActualArgs.begin(), Args.begin() + 1, Args.end()); + std::swap(Args, ActualArgs); } - S.AddAnnotationAttr(New, *Attr, Attr->getAnnotation(), Args); + S.AddAnnotationAttr(New, *Attr, Str, Args); } static Expr *instantiateDependentFunctionAttrCondition( |