Index: test/Sema/deprecated.c =================================================================== --- test/Sema/deprecated.c (revision 0) +++ test/Sema/deprecated.c (revision 0) @@ -0,0 +1,25 @@ +// RUN: clang %s -verify -fsyntax-only + +int f() __attribute__((deprecated)); +void g() __attribute__((deprecated)); +void g(); + +void z() __attribute__((bogusattr)); // expected-warning {{'bogusattr' attribute ignored}} + +extern int var __attribute__((deprecated)); + +int a() { + int (*ptr)() = f; // expected-warning {{'f' is deprecated}} + f(); // expected-warning {{'f' is deprecated}} + + // test if attributes propagate to functions + g(); // expected-warning {{'g' is deprecated}} + + return var; // expected-warning {{'var' is deprecated}} +} + +// test if attributes propagate to variables +extern int var; +int w() { + return var; // expected-warning {{'var' is deprecated}} +} Index: include/clang/Basic/DiagnosticKinds.def =================================================================== --- include/clang/Basic/DiagnosticKinds.def (revision 47752) +++ include/clang/Basic/DiagnosticKinds.def (working copy) @@ -617,6 +617,8 @@ "unexpected type name '%0': expected expression") DIAG(err_undeclared_var_use, ERROR, "use of undeclared identifier '%0'") +DIAG(warn_deprecated, WARNING, + "'%0' is deprecated") DIAG(err_redefinition, ERROR, "redefinition of '%0'") DIAG(err_static_non_static, ERROR, Index: include/clang/AST/Attr.h =================================================================== --- include/clang/AST/Attr.h (revision 47752) +++ include/clang/AST/Attr.h (working copy) @@ -26,7 +26,8 @@ Aligned, Packed, Annotate, - NoReturn + NoReturn, + Deprecated }; private: @@ -107,6 +108,16 @@ static bool classof(const NoReturnAttr *A) { return true; } }; +class DeprecatedAttr : public Attr { +public: + DeprecatedAttr() : Attr(Deprecated) {} + + // Implement isa/cast/dyncast/etc. + + static bool classof(const Attr *A) { return A->getKind() == Deprecated; } + static bool classof(const DeprecatedAttr *A) { return true; } +}; + } // end namespace clang #endif Index: include/clang/Parse/AttributeList.h =================================================================== --- include/clang/Parse/AttributeList.h (revision 47752) +++ include/clang/Parse/AttributeList.h (working copy) @@ -49,7 +49,8 @@ AT_aligned, AT_packed, AT_annotate, - AT_noreturn + AT_noreturn, + AT_deprecated }; IdentifierInfo *getName() const { return AttrName; } Index: Sema/SemaExpr.cpp =================================================================== --- Sema/SemaExpr.cpp (revision 47752) +++ Sema/SemaExpr.cpp (working copy) @@ -100,6 +100,12 @@ } } if (ValueDecl *VD = dyn_cast(D)) { + + // check if referencing an identifier with __attribute__((deprecated)) + if (VD->getAttr()) { + Diag(Loc, diag::warn_deprecated, VD->getName()); + } + // Only create DeclRefExpr's for valid Decl's. if (VD->isInvalidDecl()) return true; Index: Sema/SemaDecl.cpp =================================================================== --- Sema/SemaDecl.cpp (revision 47752) +++ Sema/SemaDecl.cpp (working copy) @@ -255,6 +255,8 @@ Diag(OldD->getLocation(), diag::err_previous_definition); return New; } + + // FIXME: propagate old Attrs to the New decl QualType OldQType = Old->getCanonicalType(); QualType NewQType = New->getCanonicalType(); @@ -1778,6 +1780,9 @@ vDecl->setType(newType); } break; + case AttributeList::AT_deprecated: + New->addAttr(new DeprecatedAttr()); + break; case AttributeList::AT_aligned: HandleAlignedAttribute(New, Attr); break; @@ -1791,7 +1796,7 @@ HandleNoReturnAttribute(New, Attr); break; default: - // FIXME: add other attributes... + Diag(Attr->getLoc(), diag::warn_attribute_ignored, Attr->getName()->getName()); break; } } Index: Parse/AttributeList.cpp =================================================================== --- Parse/AttributeList.cpp (revision 47752) +++ Parse/AttributeList.cpp (working copy) @@ -61,7 +61,10 @@ if (!memcmp(Str, "annotate", 8)) return AT_annotate; if (!memcmp(Str, "noreturn", 8)) return AT_noreturn; break; - case 11: + case 10: + if (!memcmp(Str, "deprecated", 10)) return AT_deprecated; + break; + case 11: if (!memcmp(Str, "vector_size", 11)) return AT_vector_size; break; case 13: