From 4bf74fdd907432d3ff9c6db5f24515a710882449 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 15 Feb 2009 22:43:40 +0000 Subject: [PATCH] Refactor the deprecated and unavailable checks into a new DiagnoseUseOfDeprecatedDecl method. This ensures that they are treated consistently. This gets us 'unavailable' support on a few new types of decls, and makes sure we consistently silence deprecated when the caller is also deprecated. llvm-svn: 64612 --- clang/include/clang/AST/DeclBase.h | 1 + clang/lib/Sema/Sema.h | 13 ++++++- clang/lib/Sema/SemaDecl.cpp | 5 +-- clang/lib/Sema/SemaExpr.cpp | 61 +++++++++++++++++------------- clang/lib/Sema/SemaExprObjC.cpp | 32 ++++------------ 5 files changed, 58 insertions(+), 54 deletions(-) diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 30d994b9df4c..89ef3b86c818 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -177,6 +177,7 @@ public: void setAccess(AccessSpecifier AS) { Access = AS; } AccessSpecifier getAccess() const { return AccessSpecifier(Access); } + bool hasAttrs() const { return HasAttrs; } void addAttr(Attr *attr); const Attr *getAttrs() const; void swapAttrs(Decl *D); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 7c2d3b67ad6d..362d8dc02de5 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -275,7 +275,7 @@ public: // virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc, Scope *S, const CXXScopeSpec *SS); - virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) { + virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup){ return ActOnDeclarator(S, D, LastInGroup, false); } DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup, @@ -1046,6 +1046,15 @@ public: //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. + /// DiagnoseUseOfDeprecatedDecl - If the specified decl is deprecated or + // unavailable, emit the corresponding diagnostics. + inline void DiagnoseUseOfDeprecatedDecl(NamedDecl *D, SourceLocation Loc) { + if (D->hasAttrs()) + DiagnoseUseOfDeprecatedDeclImpl(D, Loc); + } + void DiagnoseUseOfDeprecatedDeclImpl(NamedDecl *D, SourceLocation Loc); + + // Primary Expressions. virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc, IdentifierInfo &II, @@ -1218,6 +1227,8 @@ public: virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body, Scope *CurScope); + //===---------------------------- C++ Features --------------------------===// + // Act on C++ namespaces virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc, IdentifierInfo *Ident, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 37e1f54f7f0e..a80507ae4e66 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -28,7 +28,6 @@ #include "llvm/ADT/STLExtras.h" #include #include - using namespace clang; /// \brief If the identifier refers to a type name within this scope, @@ -78,8 +77,8 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) { if (MD->isOutOfLineDefinition()) return MD->getLexicalDeclContext(); - // A C++ inline method is parsed *after* the topmost class it was declared in - // is fully parsed (it's "complete"). + // A C++ inline method is parsed *after* the topmost class it was declared + // in is fully parsed (it's "complete"). // The parsing of a C++ inline method happens at the declaration context of // the topmost (non-nested) class it is lexically declared in. assert(isa(MD->getParent()) && "C++ method not in Record."); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 43ed22a48b95..3143fc7aa1fa 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -26,6 +26,25 @@ #include "clang/Parse/Scope.h" using namespace clang; + +/// DiagnoseUseOfDeprecatedDeclImpl - If the specified decl is deprecated or +// unavailable, emit the corresponding diagnostics. +void Sema::DiagnoseUseOfDeprecatedDeclImpl(NamedDecl *D, SourceLocation Loc) { + // See if the decl is deprecated. + if (D->getAttr()) { + // If this reference happens *in* a deprecated function or method, don't + // warn. Implementing deprecated stuff requires referencing depreated + // stuff. + NamedDecl *ND = getCurFunctionOrMethodDecl(); + if (ND == 0 || !ND->getAttr()) + Diag(Loc, diag::warn_deprecated) << D->getDeclName(); + } + + // See if hte decl is unavailable. + if (D->getAttr()) + Diag(Loc, diag::warn_unavailable) << D->getDeclName(); +} + //===----------------------------------------------------------------------===// // Standard Promotions and Conversions //===----------------------------------------------------------------------===// @@ -89,9 +108,7 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) { // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but // will warn if the resulting type is not a POD type. -void Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) - -{ +void Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) { DefaultArgumentPromotion(Expr); if (!Expr->getType()->isPODType()) { @@ -145,10 +162,14 @@ QualType Sema::UsualArithmeticConversionsType(QualType lhs, QualType rhs) { // lhs == rhs check. Also, for conversion purposes, we ignore any // qualifiers. For example, "const float" and "float" are // equivalent. - if (lhs->isPromotableIntegerType()) lhs = Context.IntTy; - else lhs = lhs.getUnqualifiedType(); - if (rhs->isPromotableIntegerType()) rhs = Context.IntTy; - else rhs = rhs.getUnqualifiedType(); + if (lhs->isPromotableIntegerType()) + lhs = Context.IntTy; + else + lhs = lhs.getUnqualifiedType(); + if (rhs->isPromotableIntegerType()) + rhs = Context.IntTy; + else + rhs = rhs.getUnqualifiedType(); // If both types are identical, no conversion is needed. if (lhs == rhs) @@ -223,14 +244,10 @@ QualType Sema::UsualArithmeticConversionsType(QualType lhs, QualType rhs) { // We have two real floating types, float/complex combos were handled above. // Convert the smaller operand to the bigger result. int result = Context.getFloatingTypeOrder(lhs, rhs); - - if (result > 0) { // convert the rhs + if (result > 0) // convert the rhs return lhs; - } - if (result < 0) { // convert the lhs - return rhs; - } - assert(0 && "Sema::UsualArithmeticConversionsType(): illegal float comparison"); + assert(result < 0 && "illegal float comparison"); + return rhs; // convert the lhs } if (lhs->isComplexIntegerType() || rhs->isComplexIntegerType()) { // Handle GCC complex int extension. @@ -239,10 +256,8 @@ QualType Sema::UsualArithmeticConversionsType(QualType lhs, QualType rhs) { if (lhsComplexInt && rhsComplexInt) { if (Context.getIntegerTypeOrder(lhsComplexInt->getElementType(), - rhsComplexInt->getElementType()) >= 0) { - // convert the rhs - return lhs; - } + rhsComplexInt->getElementType()) >= 0) + return lhs; // convert the rhs return rhs; } else if (lhsComplexInt && rhs->isIntegerType()) { // convert the rhs to the lhs complex type. @@ -753,14 +768,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, ValueDecl *VD = cast(D); // Check if referencing an identifier with __attribute__((deprecated)). - if (VD->getAttr()) { - // If this reference happens *in* a deprecated function or method, don't - // warn. Implementing deprecated stuff requires referencing depreated - // stuff. - NamedDecl *ND = getCurFunctionOrMethodDecl(); - if (ND == 0 || !ND->getAttr()) - Diag(Loc, diag::warn_deprecated) << VD->getDeclName(); - } + DiagnoseUseOfDeprecatedDecl(VD, Loc); if (VarDecl *Var = dyn_cast(VD)) { if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) { @@ -1510,6 +1518,7 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc, return VT; // should never get here (a typedef type should always be found). } + /// constructSetterName - Return the setter name for the given /// identifier, i.e. "set" + Name where the initial character of Name /// has been capitalized. diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index aca1cc6e80fd..3e9948277236 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -268,12 +268,8 @@ Sema::ExprResult Sema::ActOnClassMessage( if (!Method) Method = ClassDecl->lookupInstanceMethod(Sel); - if (Method) { - if (Method->getAttr()) - Diag(receiverLoc, diag::warn_deprecated) << Method->getDeclName(); - if (Method->getAttr()) - Diag(receiverLoc, diag::warn_unavailable) << Method->getDeclName(); - } + if (Method) + DiagnoseUseOfDeprecatedDecl(Method, receiverLoc); if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, true, lbrac, rbrac, returnType)) @@ -320,12 +316,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, Method = SuperDecl->lookupInstanceMethod(Sel); } - if (Method) { - if (Method->getAttr()) - Diag(receiverLoc, diag::warn_deprecated) << Method->getDeclName(); - if (Method->getAttr()) - Diag(receiverLoc, diag::warn_unavailable) << Method->getDeclName(); - } + if (Method) + DiagnoseUseOfDeprecatedDecl(Method, receiverLoc); if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false, lbrac, rbrac, returnType)) @@ -358,12 +350,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, ObjCImplementations[ClassDecl->getIdentifier()]) Method = ImpDecl->getClassMethod(Sel); - if (Method) { - if (Method->getAttr()) - Diag(receiverLoc, diag::warn_deprecated) << Method->getDeclName(); - if (Method->getAttr()) - Diag(receiverLoc, diag::warn_unavailable) << Method->getDeclName(); - } + if (Method) + DiagnoseUseOfDeprecatedDecl(Method, receiverLoc); } if (!Method) Method = FactoryMethodPool[Sel].Method; @@ -415,12 +403,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel, Diag(lbrac, diag::warn_method_not_found_in_protocol) << Sel << SourceRange(lbrac, rbrac); - if (Method) { - if (Method->getAttr()) - Diag(receiverLoc, diag::warn_deprecated) << Method->getDeclName(); - if (Method->getAttr()) - Diag(receiverLoc, diag::warn_unavailable) << Method->getDeclName(); - } + if (Method) + DiagnoseUseOfDeprecatedDecl(Method, receiverLoc); } else { Diag(lbrac, diag::error_bad_receiver_type) << RExpr->getType() << RExpr->getSourceRange();