]> granicus.if.org Git - clang/commitdiff
[PCH] Do not crash if a class extension in a chained PCH introduces/redeclares a...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 14 Nov 2011 04:52:29 +0000 (04:52 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 14 Nov 2011 04:52:29 +0000 (04:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144520 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTMutationListener.h
include/clang/Serialization/ASTWriter.h
lib/Sema/SemaObjCProperty.cpp
lib/Serialization/ASTWriter.cpp
test/PCH/chain-categories2.m

index 03b658cd4742677d6bafffef702401bedae33043..86a93153b9050efc6cc65b5ac94d2ab2453fd8b9 100644 (file)
@@ -25,6 +25,7 @@ namespace clang {
   class ObjCCategoryDecl;
   class ObjCInterfaceDecl;
   class ObjCContainerDecl;
+  class ObjCPropertyDecl;
 
 /// \brief An abstract interface that should be implemented by listeners
 /// that want to be notified when an AST entity gets modified after its
@@ -65,6 +66,18 @@ public:
   /// \brief A objc interface or protocol forward reference was completed.
   virtual void CompletedObjCForwardRef(const ObjCContainerDecl *D) {}
 
+  /// \brief A objc class extension redeclared or introduced a property.
+  ///
+  /// \param Prop the property in the class extension
+  ///
+  /// \param OrigProp the property from the original interface that was declared
+  /// or null if the property was introduced.
+  ///
+  /// \param ClassExt the class extension.
+  virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+                                            const ObjCPropertyDecl *OrigProp,
+                                            const ObjCCategoryDecl *ClassExt) {}
+
   /// \brief The attributes list of a declaration was updated.
   virtual void UpdatedAttributeList(const Decl *D) {}
 };
index 3c8ef2b1ab0ed4ba80266e4d83b7f2cb55f3ef33..5d97c1815b3dcd4636f4c566359d3b04177b0d9f 100644 (file)
@@ -661,6 +661,9 @@ public:
   virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
                                             const ObjCInterfaceDecl *IFD);
   virtual void CompletedObjCForwardRef(const ObjCContainerDecl *D);
+  virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+                                            const ObjCPropertyDecl *OrigProp,
+                                            const ObjCCategoryDecl *ClassExt);
   virtual void UpdatedAttributeList(const Decl *D);
 };
 
index 4933f001c4e3afc72116321f023739359daaff4f..90d2d93431537b47b36faf414e26ca443746b911 100644 (file)
@@ -17,6 +17,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ASTMutationListener.h"
 #include "llvm/ADT/DenseSet.h"
 
 using namespace clang;
@@ -271,6 +272,8 @@ Sema::HandlePropertyInClassExtension(Scope *S,
     // Make sure setter/getters are declared here.
     ProcessPropertyDecl(PDecl, CCPrimary, /* redeclaredProperty = */ 0,
                         /* lexicalDC = */ CDecl);
+    if (ASTMutationListener *L = Context.getASTMutationListener())
+      L->AddedObjCPropertyInClassExtension(PDecl, /*OrigProp=*/0, CDecl);
     return PDecl;
   }
   if (PIDecl->getType().getCanonicalType() 
@@ -343,6 +346,8 @@ Sema::HandlePropertyInClassExtension(Scope *S,
   *isOverridingProperty = true;
   // Make sure setter decl is synthesized, and added to primary class's list.
   ProcessPropertyDecl(PIDecl, CCPrimary, PDecl, CDecl);
+  if (ASTMutationListener *L = Context.getASTMutationListener())
+    L->AddedObjCPropertyInClassExtension(PDecl, PIDecl, CDecl);
   return 0;
 }
 
index 8f79fa4c49243eb7d04a7fc0e2dd5ee90978038d..4fa3cf87564e2b06ba2a01804494de87c8298ec5 100644 (file)
@@ -4130,6 +4130,20 @@ void ASTWriter::CompletedObjCForwardRef(const ObjCContainerDecl *D) {
   RewriteDecl(D);
 }
 
+void ASTWriter::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+                                          const ObjCPropertyDecl *OrigProp,
+                                          const ObjCCategoryDecl *ClassExt) {
+  const ObjCInterfaceDecl *D = ClassExt->getClassInterface();
+  if (!D)
+    return;
+
+  assert(!WritingAST && "Already writing the AST!");
+  if (!D->isFromASTFile())
+    return; // Declaration not imported from PCH.
+
+  RewriteDecl(D);
+}
+
 void ASTWriter::UpdatedAttributeList(const Decl *D) {
   assert(!WritingAST && "Already writing the AST!");
   if (!D->isFromASTFile())
index dcff3d4af049337621c8644aab8d1a07e682ce61..6b9708566cb1c6ba2e5868da255539d33c1adc0e 100644 (file)
 
 @class I;
 
+@interface I2
+@property (readonly) id prop1;
+@end
+
 //===----------------------------------------------------------------------===//
 #elif !defined(HEADER2)
 #define HEADER2
 @interface I(Cat2)
 @end
 
+@interface I2()
+@property (readwrite,assign) id prop1;
+@property (copy) id prop2;
+@end
+
 //===----------------------------------------------------------------------===//
 #else
 //===----------------------------------------------------------------------===//
@@ -40,5 +49,9 @@ void f(I* i) {
   [i meth]; // expected-warning {{not found}}
 }
 
+@implementation I2
+@synthesize prop1, prop2;
+@end
+
 //===----------------------------------------------------------------------===//
 #endif