forked from OSchip/llvm-project
[PCH] Do not crash if a class extension in a chained PCH introduces/redeclares a property.
llvm-svn: 144520
This commit is contained in:
parent
09c1b3d858
commit
846e61a363
|
@ -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) {}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
|
||||
@class I;
|
||||
|
||||
@interface I2
|
||||
@property (readonly) id prop1;
|
||||
@end
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
#elif !defined(HEADER2)
|
||||
#define HEADER2
|
||||
|
@ -32,6 +36,11 @@
|
|||
@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
|
||||
|
|
Loading…
Reference in New Issue