Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. One small documentation nit, but I'm fine with you fixing it then committing (no need for another round of review). Thanks! Comment at: include/clang/Basic/AttrDocs.td:2189 @@ +2188,3 @@ + +The deprecated attribute can have two optional string arguments. The first +one is the message to display when emitting the warning; the second one "When spelled as ``__attribute__((deprecated))``, the deprecated attribute can..." "Otherwise, when spelled as ``[[gnu::deprecated]]`` or ``[[deprecated]]``, the attribute can have one optional string argument which is the message to display when emitting the warning." http://reviews.llvm.org/D17865 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
This revision was automatically updated to reflect the committed changes. Closed by commit rL263652: Add an optional string argument to DeprecatedAttr for Fix-It. (authored by mren). Changed prior to commit: http://reviews.llvm.org/D17865?vs=50682&id=50844#toc Repository: rL LLVM http://reviews.llvm.org/D17865 Files: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/lib/Lex/PPMacroExpansion.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/SemaCXX/attr-deprecated-replacement-error.cpp cfe/trunk/test/SemaCXX/attr-deprecated-replacement-fixit.cpp cfe/trunk/test/SemaCXX/cxx11-attr-print.cpp cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Index: cfe/trunk/lib/Lex/PPMacroExpansion.cpp === --- cfe/trunk/lib/Lex/PPMacroExpansion.cpp +++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp @@ -1079,6 +1079,7 @@ .Case("attribute_cf_returns_retained", true) .Case("attribute_cf_returns_on_parameters", true) .Case("attribute_deprecated_with_message", true) + .Case("attribute_deprecated_with_replacement", true) .Case("attribute_ext_vector_type", true) .Case("attribute_ns_returns_not_retained", true) .Case("attribute_ns_returns_retained", true) Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp === --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp @@ -5136,12 +5136,27 @@ } } + // Handle the cases where the attribute has a text message. + StringRef Str, Replacement; + if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0) && + !S.checkStringLiteralArgumentAttr(Attr, 0, Str)) +return; + + // Only support a single optional message for Declspec and CXX11. + if (Attr.isDeclspecAttribute() || Attr.isCXX11Attribute()) +checkAttributeAtMostNumArgs(S, Attr, 1); + else if (Attr.isArgExpr(1) && Attr.getArgAsExpr(1) && + !S.checkStringLiteralArgumentAttr(Attr, 1, Replacement)) +return; + if (!S.getLangOpts().CPlusPlus14) if (Attr.isCXX11Attribute() && !(Attr.hasScope() && Attr.getScopeName()->isStr("gnu"))) S.Diag(Attr.getLoc(), diag::ext_cxx14_attr) << Attr.getName(); - handleAttrWithMessage(S, D, Attr); + D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str, + Replacement, + Attr.getAttributeSpellingListIndex())); } static void handleNoSanitizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { @@ -6209,18 +6224,35 @@ break; } + CharSourceRange UseRange; + StringRef Replacement; + if (K == Sema::AD_Deprecation) { +if (auto attr = D->getAttr()) + Replacement = attr->getReplacement(); + +if (!Replacement.empty()) + UseRange = + CharSourceRange::getCharRange(Loc, S.getLocForEndOfToken(Loc)); + } + if (!Message.empty()) { -S.Diag(Loc, diag_message) << D << Message; +S.Diag(Loc, diag_message) << D << Message + << (UseRange.isValid() ? + FixItHint::CreateReplacement(UseRange, Replacement) : FixItHint()); if (ObjCProperty) S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) << ObjCProperty->getDeclName() << property_note_select; } else if (!UnknownObjCClass) { -S.Diag(Loc, diag) << D; +S.Diag(Loc, diag) << D + << (UseRange.isValid() ? + FixItHint::CreateReplacement(UseRange, Replacement) : FixItHint()); if (ObjCProperty) S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute) << ObjCProperty->getDeclName() << property_note_select; } else { -S.Diag(Loc, diag_fwdclass_message) << D; +S.Diag(Loc, diag_fwdclass_message) << D + << (UseRange.isValid() ? + FixItHint::CreateReplacement(UseRange, Replacement) : FixItHint()); S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class); } Index: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp === --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp @@ -,6 +,15 @@ << " OS << \""; } +static void writeDeprecatedAttrValue(raw_ostream &OS, std::string &Variety) { + OS << "\\\"\" << getMessage() << \"\\\"\";\n"; + // Only GNU deprecated has an optional fixit argument at the second position. + if (Variety == "GNU") + OS << "if (!getReplacement().empty()) OS << \", \\\"\"" + " << getReplacement() << \"\\\"\";\n"; + OS << "OS << \""; +} + static void writeGetSpellingFunction(Record &R, raw_ostream &OS) { std::vector Spellings = GetFlattenedSpellings(R); @@ -1224,6 +1233,8 @@ OS << "("; if (Spelling == "availability") { writeAvailabilityValue(OS); +} else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") { +
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
manmanren updated this revision to Diff 50682. http://reviews.llvm.org/D17865 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/Lex/PPMacroExpansion.cpp lib/Sema/SemaDeclAttr.cpp test/SemaCXX/attr-deprecated-replacement-error.cpp test/SemaCXX/attr-deprecated-replacement-fixit.cpp test/SemaCXX/cxx11-attr-print.cpp utils/TableGen/ClangAttrEmitter.cpp Index: test/SemaCXX/attr-deprecated-replacement-fixit.cpp === --- /dev/null +++ test/SemaCXX/attr-deprecated-replacement-fixit.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: cp %s %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fixit %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -Werror %t + +#if !__has_feature(attribute_deprecated_with_replacement) +#error "Missing __has_feature" +#endif + +void f_8(int) __attribute__((deprecated("message", "new8"))); // expected-note {{'f_8' has been explicitly marked deprecated here}} +void new8(int); +void test() { + f_8(0); // expected-warning{{'f_8' is deprecated}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new8" +} Index: test/SemaCXX/attr-deprecated-replacement-error.cpp === --- /dev/null +++ test/SemaCXX/attr-deprecated-replacement-error.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only -std=c++11 -fms-extensions %s + +#if !__has_feature(attribute_deprecated_with_replacement) +#error "Missing __has_feature" +#endif + +int a1 [[deprecated("warning", "fixit")]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +int a2 [[deprecated("warning", 1)]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +int b1 [[gnu::deprecated("warning", "fixit")]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +int b2 [[gnu::deprecated("warning", 1)]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +__declspec(deprecated("warning", "fixit")) int c1; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +__declspec(deprecated("warning", 1)) int c2; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +int d1 __attribute__((deprecated("warning", "fixit"))); +int d2 __attribute__((deprecated("warning", 1))); // expected-error{{'deprecated' attribute requires a string}} Index: utils/TableGen/ClangAttrEmitter.cpp === --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -,6 +,15 @@ << " OS << \""; } +static void writeDeprecatedAttrValue(raw_ostream &OS, std::string &Variety) { + OS << "\\\"\" << getMessage() << \"\\\"\";\n"; + // Only GNU deprecated has an optional fixit argument at the second position. + if (Variety == "GNU") + OS << "if (!getReplacement().empty()) OS << \", \\\"\"" + " << getReplacement() << \"\\\"\";\n"; + OS << "OS << \""; +} + static void writeGetSpellingFunction(Record &R, raw_ostream &OS) { std::vector Spellings = GetFlattenedSpellings(R); @@ -1224,6 +1233,8 @@ OS << "("; if (Spelling == "availability") { writeAvailabilityValue(OS); +} else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") { +writeDeprecatedAttrValue(OS, Variety); } else { unsigned index = 0; for (const auto &arg : Args) { Index: test/SemaCXX/cxx11-attr-print.cpp === --- test/SemaCXX/cxx11-attr-print.cpp +++ test/SemaCXX/cxx11-attr-print.cpp @@ -16,6 +16,15 @@ // CHECK: int b {{\[}}[gnu::deprecated("warning")]]; int b [[gnu::deprecated("warning")]]; +// CHECK: __declspec(deprecated("warning")) +__declspec(deprecated("warning")) int c; + +// CHECK: int d {{\[}}[deprecated("warning")]]; +int d [[deprecated("warning")]]; + +// CHECK: __attribute__((deprecated("warning", "fixit"))); +int e __attribute__((deprecated("warning", "fixit"))); + // CHECK: int cxx11_alignas alignas(4); alignas(4) int cxx11_alignas; Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5127,12 +5127,27 @@ } } + // Handle the cases where the attribute has a text message. + StringRef Str, Replacement; + if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0) && + !S.checkStringLiteralArgumentAttr(Attr, 0, Str)) +return; + + // Only support a single optional message for Declspec and CXX11. + if (Attr.isDeclspecAttribute() || Attr.isCXX11Attribute()) +checkAttributeAtMostNumArgs(S, Attr, 1); + else if (Attr.isArgExpr(1) && Attr.getArgAsExpr(1) && +
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
aaron.ballman added a comment. In http://reviews.llvm.org/D17865#374939, @manmanren wrote: > In http://reviews.llvm.org/D17865#374659, @aaron.ballman wrote: > > > Aside from the missing attribute documentation, looks good to me. > > > Hi Aaron, > > Which document are you referring to? "include/clang/Basic/AttrDocs.td"? Yes, AttrDocs.td that you then reference in to Attr.td. > We don't have a section for DeprecatedAttr, should I start one? Yes, please! We used to get away with relying on GCC to document the attribute, so now that we're adding Clang-specific behavior, we should bite the bullet and document the attribute properly. :-) Thanks! http://reviews.llvm.org/D17865 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
manmanren added a comment. In http://reviews.llvm.org/D17865#374659, @aaron.ballman wrote: > Aside from the missing attribute documentation, looks good to me. Hi Aaron, Which document are you referring to? "include/clang/Basic/AttrDocs.td"? We don't have a section for DeprecatedAttr, should I start one? Cheers, Manman http://reviews.llvm.org/D17865 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
aaron.ballman added a comment. Aside from the missing attribute documentation, looks good to me. http://reviews.llvm.org/D17865 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
manmanren marked 3 inline comments as done. manmanren added a comment. Upload patch to address review comments. Thanks, Manman http://reviews.llvm.org/D17865 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
manmanren updated this revision to Diff 50502. http://reviews.llvm.org/D17865 Files: include/clang/Basic/Attr.td lib/Lex/PPMacroExpansion.cpp lib/Sema/SemaDeclAttr.cpp test/SemaCXX/attr-deprecated-replacement-error.cpp test/SemaCXX/attr-deprecated-replacement-fixit.cpp test/SemaCXX/cxx11-attr-print.cpp utils/TableGen/ClangAttrEmitter.cpp Index: test/SemaCXX/attr-deprecated-replacement-fixit.cpp === --- /dev/null +++ test/SemaCXX/attr-deprecated-replacement-fixit.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: cp %s %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fixit %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -Werror %t + +#if !__has_feature(attribute_deprecated_with_replacement) +#error "Missing __has_feature" +#endif + +void f_8(int) __attribute__((deprecated("message", "new8"))); // expected-note {{'f_8' has been explicitly marked deprecated here}} +void new8(int); +void test() { + f_8(0); // expected-warning{{'f_8' is deprecated}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new8" +} Index: test/SemaCXX/attr-deprecated-replacement-error.cpp === --- /dev/null +++ test/SemaCXX/attr-deprecated-replacement-error.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only -std=c++11 -fms-extensions %s + +#if !__has_feature(attribute_deprecated_with_replacement) +#error "Missing __has_feature" +#endif + +int a1 [[deprecated("warning", "fixit")]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +int a2 [[deprecated("warning", 1)]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +int b1 [[gnu::deprecated("warning", "fixit")]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +int b2 [[gnu::deprecated("warning", 1)]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +__declspec(deprecated("warning", "fixit")) int c1; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +__declspec(deprecated("warning", 1)) int c2; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +int d1 __attribute__((deprecated("warning", "fixit"))); +int d2 __attribute__((deprecated("warning", 1))); // expected-error{{'deprecated' attribute requires a string}} Index: utils/TableGen/ClangAttrEmitter.cpp === --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -,6 +,15 @@ << " OS << \""; } +static void writeDeprecatedAttrValue(raw_ostream &OS, std::string &Variety) { + OS << "\\\"\" << getMessage() << \"\\\"\";\n"; + // Only GNU deprecated has an optional fixit argument at the second position. + if (Variety == "GNU") + OS << "if (!getReplacement().empty()) OS << \", \\\"\"" + " << getReplacement() << \"\\\"\";\n"; + OS << "OS << \""; +} + static void writeGetSpellingFunction(Record &R, raw_ostream &OS) { std::vector Spellings = GetFlattenedSpellings(R); @@ -1224,6 +1233,8 @@ OS << "("; if (Spelling == "availability") { writeAvailabilityValue(OS); +} else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") { +writeDeprecatedAttrValue(OS, Variety); } else { unsigned index = 0; for (const auto &arg : Args) { Index: test/SemaCXX/cxx11-attr-print.cpp === --- test/SemaCXX/cxx11-attr-print.cpp +++ test/SemaCXX/cxx11-attr-print.cpp @@ -16,6 +16,15 @@ // CHECK: int b {{\[}}[gnu::deprecated("warning")]]; int b [[gnu::deprecated("warning")]]; +// CHECK: __declspec(deprecated("warning")) +__declspec(deprecated("warning")) int c; + +// CHECK: int d {{\[}}[deprecated("warning")]]; +int d [[deprecated("warning")]]; + +// CHECK: __attribute__((deprecated("warning", "fixit"))); +int e __attribute__((deprecated("warning", "fixit"))); + // CHECK: int cxx11_alignas alignas(4); alignas(4) int cxx11_alignas; Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5127,12 +5127,27 @@ } } + // Handle the cases where the attribute has a text message. + StringRef Str, Replacement; + if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0) && + !S.checkStringLiteralArgumentAttr(Attr, 0, Str)) +return; + + // Only support a single optional message for Declspec and CXX11. + if (Attr.isDeclspecAttribute() || Attr.isCXX11Attribute()) +checkAttributeAtMostNumArgs(S, Attr, 1); + else if (Attr.isArgExpr(1) && Attr.getArgAsExpr(1) && + !S.checkStringLiteralArgu
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
aaron.ballman added inline comments. Comment at: include/clang/Basic/Attr.td:726 @@ +725,3 @@ + let Args = [StringArgument<"Message", 1>, + // An optional string argument that enables us to provide a Fix-It. + StringArgument<"Replacement", 1>]; The formatting here is a bit strange. Comment at: lib/Sema/SemaDeclAttr.cpp:5143 @@ +5142,3 @@ + + D->addAttr(::new (S.Context) DeprecatedAttr(Attr.getRange(), S.Context, Str, + Replacement, This should move back down below the extension warning (the effect is the same, but logically we want to warn before attaching). Comment at: utils/TableGen/ClangAttrEmitter.cpp:1234 @@ +1233,3 @@ +if ((Spelling == "deprecated" || Spelling == "gnu::deprecated") && +Variety != "GNU" && index == 1) + continue; manmanren wrote: > This does not look pretty. Maybe we can implement a function > writeDeprecatedValue that can skip the second argument if it is empty? I wouldn't be opposed to that approach; we already do it for `writeAvailabilityValue()`, so another one for deprecated wouldn't be that horrible. http://reviews.llvm.org/D17865 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
manmanren added inline comments. Comment at: utils/TableGen/ClangAttrEmitter.cpp:1234 @@ +1233,3 @@ +if ((Spelling == "deprecated" || Spelling == "gnu::deprecated") && +Variety != "GNU" && index == 1) + continue; This does not look pretty. Maybe we can implement a function writeDeprecatedValue that can skip the second argument if it is empty? http://reviews.llvm.org/D17865 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D17865: Add an optional string argument to DeprecatedAttr for Fix-It.
manmanren retitled this revision from "Add replacement = "xxx" to DeprecatedAttr." to "Add an optional string argument to DeprecatedAttr for Fix-It.". manmanren updated this revision to Diff 50374. http://reviews.llvm.org/D17865 Files: include/clang/Basic/Attr.td lib/Lex/PPMacroExpansion.cpp lib/Sema/SemaDeclAttr.cpp test/SemaCXX/attr-deprecated-replacement-error.cpp test/SemaCXX/attr-deprecated-replacement-fixit.cpp test/SemaCXX/cxx11-attr-print.cpp utils/TableGen/ClangAttrEmitter.cpp Index: utils/TableGen/ClangAttrEmitter.cpp === --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -1228,6 +1228,11 @@ unsigned index = 0; for (const auto &arg : Args) { if (arg->isFake()) continue; +// Only GNU deprecated has an optional fixit argument at the second +// position. +if ((Spelling == "deprecated" || Spelling == "gnu::deprecated") && +Variety != "GNU" && index == 1) + continue; if (index++) OS << ", "; arg->writeValue(OS); } Index: test/SemaCXX/cxx11-attr-print.cpp === --- test/SemaCXX/cxx11-attr-print.cpp +++ test/SemaCXX/cxx11-attr-print.cpp @@ -10,12 +10,18 @@ // CHECK: int z {{\[}}[gnu::aligned(4)]]; int z [[gnu::aligned(4)]]; -// CHECK: __attribute__((deprecated("warning"))); +// CHECK: __attribute__((deprecated("warning", ""))); int a __attribute__((deprecated("warning"))); // CHECK: int b {{\[}}[gnu::deprecated("warning")]]; int b [[gnu::deprecated("warning")]]; +// CHECK: __attribute__((deprecated("", ""))); +int c __attribute__((deprecated)); + +// CHECK: int d {{\[}}[deprecated("warning")]]; +int d [[deprecated("warning")]]; + // CHECK: int cxx11_alignas alignas(4); alignas(4) int cxx11_alignas; Index: test/SemaCXX/attr-deprecated-replacement-fixit.cpp === --- test/SemaCXX/attr-deprecated-replacement-fixit.cpp +++ test/SemaCXX/attr-deprecated-replacement-fixit.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: cp %s %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fixit %t +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -Werror %t + +#if !__has_feature(attribute_deprecated_with_replacement) +#error "Missing __has_feature" +#endif + +void f_8(int) __attribute__((deprecated("message", "new8"))); // expected-note {{'f_8' has been explicitly marked deprecated here}} +void new8(int); +void test() { + f_8(0); // expected-warning{{'f_8' is deprecated}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:6}:"new8" +} Index: test/SemaCXX/attr-deprecated-replacement-error.cpp === --- test/SemaCXX/attr-deprecated-replacement-error.cpp +++ test/SemaCXX/attr-deprecated-replacement-error.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -verify -fsyntax-only -std=c++11 -fms-extensions %s + +#if !__has_feature(attribute_deprecated_with_replacement) +#error "Missing __has_feature" +#endif + +int a1 [[deprecated("warning", "fixit")]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +int a2 [[deprecated("warning", 1)]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +int b1 [[gnu::deprecated("warning", "fixit")]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +int b2 [[gnu::deprecated("warning", 1)]]; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +__declspec(deprecated("warning", "fixit")) int c1; // expected-error{{'deprecated' attribute takes no more than 1 argument}} +__declspec(deprecated("warning", 1)) int c2; // expected-error{{'deprecated' attribute takes no more than 1 argument}} + +int d1 __attribute__((deprecated("warning", "fixit"))); +int d2 __attribute__((deprecated("warning", 1))); // expected-error{{'deprecated' attribute requires a string}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5127,12 +5127,27 @@ } } + // Handle the cases where the attribute has a text message. + StringRef Str, Replacement; + if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0) && + !S.checkStringLiteralArgumentAttr(Attr, 0, Str)) +return; + + // Only support a single optional message for Declspec and CXX11. + if (Attr.isDeclspecAttribute() || Attr.isCXX11Attribute()) +checkAttributeAtMostNumArgs(S, Attr, 1); + else if (Attr.isArgExpr(1) && Attr.getArgAsExpr(1) && + !S.checkStringLiteralArgumentAttr(Attr, 1, Replacement)) +return; + + D->addAttr(::new (S.Context) DeprecatedAt