@@ -3682,20 +3682,68 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
36823682 RD->addAttr (::new (S.Context ) TransparentUnionAttr (S.Context , AL));
36833683}
36843684
3685+ void Sema::AddAnnotationAttr (Decl *D, const AttributeCommonInfo &CI,
3686+ StringRef Str, MutableArrayRef<Expr *> Args) {
3687+ auto *Attr = AnnotateAttr::Create (Context, Str, Args.data (), Args.size (), CI);
3688+ llvm::SmallVector<PartialDiagnosticAt, 8 > Notes;
3689+ for (unsigned Idx = 1 ; Idx < Attr->args_size (); Idx++) {
3690+ Expr *&E = Attr->args_begin ()[Idx];
3691+ assert (E && " error are handled before" );
3692+ if (E->isValueDependent () || E->isTypeDependent ())
3693+ continue ;
3694+
3695+ if (E->getType ()->isArrayType ())
3696+ E = ImpCastExprToType (E, Context.getPointerType (E->getType ()),
3697+ clang::CK_ArrayToPointerDecay)
3698+ .get ();
3699+ if (E->getType ()->isFunctionType ())
3700+ E = ImplicitCastExpr::Create (Context,
3701+ Context.getPointerType (E->getType ()),
3702+ clang::CK_FunctionToPointerDecay, E, nullptr ,
3703+ VK_RValue, FPOptionsOverride ());
3704+ if (E->isLValue ())
3705+ E = ImplicitCastExpr::Create (Context, E->getType ().getNonReferenceType (),
3706+ clang::CK_LValueToRValue, E, nullptr ,
3707+ VK_RValue, FPOptionsOverride ());
3708+
3709+ Expr::EvalResult Eval;
3710+ Notes.clear ();
3711+ Eval.Diag = &Notes;
3712+
3713+ bool Result =
3714+ E->EvaluateAsConstantExpr (Eval, Context);
3715+
3716+ // / Result means the expression can be folded to a constant.
3717+ // / Note.empty() means the expression is a valid constant expression in the
3718+ // / current language mode.
3719+ if (!Result || !Notes.empty ()) {
3720+ Diag (E->getBeginLoc (), diag::err_attribute_argument_n_type)
3721+ << CI << Idx << AANT_ArgumentConstantExpr;
3722+ for (auto &Note : Notes)
3723+ Diag (Note.first , Note.second );
3724+ return ;
3725+ }
3726+ assert (Eval.Val .hasValue ());
3727+ E = ConstantExpr::Create (Context, E, Eval.Val );
3728+ }
3729+ D->addAttr (Attr);
3730+ }
3731+
36853732static void handleAnnotateAttr (Sema &S, Decl *D, const ParsedAttr &AL) {
3686- // Make sure that there is a string literal as the annotation's single
3733+ // Make sure that there is a string literal as the annotation's first
36873734 // argument.
36883735 StringRef Str;
36893736 if (!S.checkStringLiteralArgumentAttr (AL, 0 , Str))
36903737 return ;
36913738
3692- // Don't duplicate annotations that are already set.
3693- for (const auto *I : D->specific_attrs <AnnotateAttr>()) {
3694- if (I->getAnnotation () == Str)
3695- return ;
3739+ llvm::SmallVector<Expr *, 4 > Args;
3740+ Args.reserve (AL.getNumArgs ());
3741+ for (unsigned Idx = 0 ; Idx < AL.getNumArgs (); Idx++) {
3742+ assert (!AL.isArgIdent (Idx));
3743+ Args.push_back (AL.getArgAsExpr (Idx));
36963744 }
36973745
3698- D-> addAttr (:: new (S. Context ) AnnotateAttr (S. Context , AL, Str) );
3746+ S. AddAnnotationAttr (D , AL, Str, Args );
36993747}
37003748
37013749static void handleAlignValueAttr (Sema &S, Decl *D, const ParsedAttr &AL) {
0 commit comments