[cfe-commits] r126828 - in /cfe/trunk: include/clang/AST/Attr.h include/clang/Basic/Attr.td include/clang/Basic/AttrKinds.h include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclObjC.cpp

John McCall rjmccall at apple.com
Tue Mar 1 20:00:57 PST 2011


Author: rjmccall
Date: Tue Mar  1 22:00:57 2011
New Revision: 126828

URL: http://llvm.org/viewvc/llvm-project?rev=126828&view=rev
Log:
Support a new InheritableAttr subclass, InheritableParamAttr, which is
used for attributes that are okay to inherit when written on a parameter.
Dependent on LLVM r126827.


Modified:
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/AttrKinds.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=126828&r1=126827&r2=126828&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Tue Mar  1 22:00:57 2011
@@ -120,6 +120,19 @@
   static bool classof(const InheritableAttr *) { return true; }
 };
 
+class InheritableParamAttr : public InheritableAttr {
+protected:
+  InheritableParamAttr(attr::Kind AK, SourceLocation L)
+    : InheritableAttr(AK, L) {}
+
+public:
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) {
+    return A->getKind() <= attr::LAST_INHERITABLE_PARAM;
+  }
+  static bool classof(const InheritableParamAttr *) { return true; }
+};
+
 #include "clang/AST/Attrs.inc"
 
 /// AttrVec - A vector of Attr, which is how they are stored on the AST.

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=126828&r1=126827&r2=126828&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Tue Mar  1 22:00:57 2011
@@ -89,8 +89,13 @@
   code AdditionalMembers = [{}];
 }
 
+/// An inheritable attribute is inherited by later redeclarations.
 class InheritableAttr : Attr;
 
+/// An inheritable parameter attribute is inherited by later
+/// redeclarations, even when it's written on a parameter.
+class InheritableParamAttr : InheritableAttr;
+
 //
 // Attributes begin here
 //
@@ -134,7 +139,7 @@
   let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
 }
 
-def CarriesDependency : InheritableAttr {
+def CarriesDependency : InheritableParamAttr {
   let Spellings = ["carries_dependency"];
   let Subjects = [ParmVar, Function];
   let Namespaces = ["", "std"];
@@ -154,7 +159,7 @@
   let Subjects = [ObjCMethod, Function];
 }
 
-def CFConsumed : InheritableAttr {
+def CFConsumed : InheritableParamAttr {
   let Spellings = ["cf_consumed"];
   let Subjects = [ParmVar];
 }
@@ -355,7 +360,7 @@
   let Subjects = [ObjCMethod];
 }
 
-def NSConsumed : InheritableAttr {
+def NSConsumed : InheritableParamAttr {
   let Spellings = ["ns_consumed"];
   let Subjects = [ParmVar];
 }

Modified: cfe/trunk/include/clang/Basic/AttrKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrKinds.h?rev=126828&r1=126827&r2=126828&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/AttrKinds.h (original)
+++ cfe/trunk/include/clang/Basic/AttrKinds.h Tue Mar  1 22:00:57 2011
@@ -22,6 +22,7 @@
 enum Kind {
 #define ATTR(X) X,
 #define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
+#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
 #include "clang/Basic/AttrList.inc"
   NUM_ATTRS
 };

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=126828&r1=126827&r2=126828&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Mar  1 22:00:57 2011
@@ -1068,6 +1068,7 @@
   void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls);
   bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
   bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
+  void mergeObjCMethodDecls(ObjCMethodDecl *New, const ObjCMethodDecl *Old);
   void MergeVarDeclTypes(VarDecl *New, VarDecl *Old);
   void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
   bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=126828&r1=126827&r2=126828&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Mar  1 22:00:57 2011
@@ -1054,23 +1054,58 @@
   return false;
 }
 
-/// MergeDeclAttributes - append attributes from the Old decl to the New one.
-static void MergeDeclAttributes(Decl *New, Decl *Old, ASTContext &C) {
-  if (!Old->hasAttrs())
+/// mergeDeclAttributes - Copy attributes from the Old decl to the New one.
+static void mergeDeclAttributes(Decl *newDecl, const Decl *oldDecl,
+                                ASTContext &C) {
+  if (!oldDecl->hasAttrs())
     return;
+
+  bool foundAny = newDecl->hasAttrs();
+
   // Ensure that any moving of objects within the allocated map is done before
   // we process them.
-  if (!New->hasAttrs())
-    New->setAttrs(AttrVec());
+  if (!foundAny) newDecl->setAttrs(AttrVec());
+
   for (specific_attr_iterator<InheritableAttr>
-       i = Old->specific_attr_begin<InheritableAttr>(),
-       e = Old->specific_attr_end<InheritableAttr>(); i != e; ++i) {
-    if (!DeclHasAttr(New, *i)) {
-      InheritableAttr *NewAttr = cast<InheritableAttr>((*i)->clone(C));
-      NewAttr->setInherited(true);
-      New->addAttr(NewAttr);
+       i = oldDecl->specific_attr_begin<InheritableAttr>(),
+       e = oldDecl->specific_attr_end<InheritableAttr>(); i != e; ++i) {
+    if (!DeclHasAttr(newDecl, *i)) {
+      InheritableAttr *newAttr = cast<InheritableAttr>((*i)->clone(C));
+      newAttr->setInherited(true);
+      newDecl->addAttr(newAttr);
+      foundAny = true;
+    }
+  }
+
+  if (!foundAny) newDecl->dropAttrs();
+}
+
+/// mergeParamDeclAttributes - Copy attributes from the old parameter
+/// to the new one.
+static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
+                                     const ParmVarDecl *oldDecl,
+                                     ASTContext &C) {
+  if (!oldDecl->hasAttrs())
+    return;
+
+  bool foundAny = newDecl->hasAttrs();
+
+  // Ensure that any moving of objects within the allocated map is
+  // done before we process them.
+  if (!foundAny) newDecl->setAttrs(AttrVec());
+
+  for (specific_attr_iterator<InheritableParamAttr>
+       i = oldDecl->specific_attr_begin<InheritableParamAttr>(),
+       e = oldDecl->specific_attr_end<InheritableParamAttr>(); i != e; ++i) {
+    if (!DeclHasAttr(newDecl, *i)) {
+      InheritableAttr *newAttr = cast<InheritableParamAttr>((*i)->clone(C));
+      newAttr->setInherited(true);
+      newDecl->addAttr(newAttr);
+      foundAny = true;
     }
   }
+
+  if (!foundAny) newDecl->dropAttrs();
 }
 
 namespace {
@@ -1471,7 +1506,7 @@
 /// \returns false
 bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
   // Merge the attributes
-  MergeDeclAttributes(New, Old, Context);
+  mergeDeclAttributes(New, Old, Context);
 
   // Merge the storage class.
   if (Old->getStorageClass() != SC_Extern &&
@@ -1486,12 +1521,31 @@
   if (Old->isDeleted())
     New->setDeleted();
 
+  // Merge attributes from the parameters.  These can mismatch with K&R
+  // declarations.
+  if (New->getNumParams() == Old->getNumParams())
+    for (unsigned i = 0, e = New->getNumParams(); i != e; ++i)
+      mergeParamDeclAttributes(New->getParamDecl(i), Old->getParamDecl(i),
+                               Context);
+
   if (getLangOptions().CPlusPlus)
     return MergeCXXFunctionDecl(New, Old);
 
   return false;
 }
 
+void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,
+                                const ObjCMethodDecl *oldMethod) {
+  // Merge the attributes.
+  mergeDeclAttributes(newMethod, oldMethod, Context);
+
+  // Merge attributes from the parameters.
+  for (ObjCMethodDecl::param_iterator oi = oldMethod->param_begin(),
+         ni = newMethod->param_begin(), ne = newMethod->param_end();
+       ni != ne; ++ni, ++oi)
+    mergeParamDeclAttributes(*ni, *oi, Context);    
+}
+
 /// MergeVarDecl - We parsed a variable 'New' which has the same name and scope
 /// as a previous declaration 'Old'.  Figure out how to merge their types,
 /// emitting diagnostics as appropriate.
@@ -1585,7 +1639,7 @@
     New->setInvalidDecl();
   }
   
-  MergeDeclAttributes(New, Old, Context);
+  mergeDeclAttributes(New, Old, Context);
 
   // Merge the types.
   MergeVarDeclTypes(New, Old);

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=126828&r1=126827&r2=126828&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Tue Mar  1 22:00:57 2011
@@ -1888,16 +1888,9 @@
     Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
   }
 
-  // If the interface declared this method, and it was deprecated there,
-  // mark it deprecated here.
+  // Merge information down from the interface declaration if we have one.
   if (InterfaceMD)
-   if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>()) {
-    StringLiteral *SE = StringLiteral::CreateEmpty(Context, 1);
-    ObjCMethod->addAttr(::new (Context) 
-                        DeprecatedAttr(DA->getLocation(),
-                                       Context, 
-                                       SE->getString()));
-   }
+    mergeObjCMethodDecls(ObjCMethod, InterfaceMD);
 
   return ObjCMethod;
 }





More information about the cfe-commits mailing list