aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp6
-rw-r--r--lib/AST/ASTImporter.cpp2
-rw-r--r--lib/AST/DeclObjC.cpp21
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp2
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp1
-rw-r--r--lib/Sema/SemaCodeComplete.cpp11
-rw-r--r--lib/Sema/SemaDeclObjC.cpp48
-rw-r--r--lib/Sema/SemaObjCProperty.cpp8
8 files changed, 55 insertions, 44 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index bb62e9efd5..80bda841fe 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -868,7 +868,8 @@ void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
// Find ivars declared in class extension.
- if (const ObjCCategoryDecl *CDecl = OI->getClassExtension()) {
+ for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
+ CDecl = CDecl->getNextClassExtension()) {
for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
E = CDecl->ivar_end(); I != E; ++I) {
Ivars.push_back(*I);
@@ -933,7 +934,8 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) {
unsigned count = 0;
// Count ivars declared in class extension.
- if (const ObjCCategoryDecl *CDecl = OI->getClassExtension())
+ for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
+ CDecl = CDecl->getNextClassExtension())
count += CDecl->ivar_size();
// Count ivar defined in this class's implementation. This
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 370dbc54a2..e1c2abd251 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -2636,6 +2636,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
LexicalDC->addDecl(ToProperty);
ToProperty->setPropertyAttributes(D->getPropertyAttributes());
+ ToProperty->setPropertyAttributesAsWritten(
+ D->getPropertyAttributesAsWritten());
ToProperty->setGetterName(Importer.Import(D->getGetterName()));
ToProperty->setSetterName(Importer.Import(D->getSetterName()));
ToProperty->setGetterMethodDecl(
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 335e89bada..adb0e7d083 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -223,17 +223,24 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
}
-/// getClassExtension - Find class extension of the given class.
-// FIXME. can speed it up, if need be.
-ObjCCategoryDecl* ObjCInterfaceDecl::getClassExtension() const {
- const ObjCInterfaceDecl* ClassDecl = this;
- for (ObjCCategoryDecl *CDecl = ClassDecl->getCategoryList(); CDecl;
+/// getFirstClassExtension - Find first class extension of the given class.
+ObjCCategoryDecl* ObjCInterfaceDecl::getFirstClassExtension() const {
+ for (ObjCCategoryDecl *CDecl = getCategoryList(); CDecl;
CDecl = CDecl->getNextClassCategory())
if (CDecl->IsClassExtension())
return CDecl;
return 0;
}
+/// getNextClassCategory - Find next class extension in list of categories.
+const ObjCCategoryDecl* ObjCCategoryDecl::getNextClassExtension() const {
+ for (const ObjCCategoryDecl *CDecl = getNextClassCategory(); CDecl;
+ CDecl = CDecl->getNextClassCategory())
+ if (CDecl->IsClassExtension())
+ return CDecl;
+ return 0;
+}
+
ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
ObjCInterfaceDecl *&clsDeclared) {
ObjCInterfaceDecl* ClassDecl = this;
@@ -242,11 +249,13 @@ ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
clsDeclared = ClassDecl;
return I;
}
- if (const ObjCCategoryDecl *CDecl = ClassDecl->getClassExtension())
+ for (const ObjCCategoryDecl *CDecl = ClassDecl->getFirstClassExtension();
+ CDecl; CDecl = CDecl->getNextClassExtension()) {
if (ObjCIvarDecl *I = CDecl->getIvarDecl(ID)) {
clsDeclared = ClassDecl;
return I;
}
+ }
ClassDecl = ClassDecl->getSuperClass();
}
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index b8046578ae..f723baefef 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -444,6 +444,8 @@ void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// FIXME: stable encoding
D->setPropertyAttributes(
(ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
+ D->setPropertyAttributesAsWritten(
+ (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);
// FIXME: stable encoding
D->setPropertyImplementation(
(ObjCPropertyDecl::PropertyControl)Record[Idx++]);
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 05414d5fc7..9cc7b4833d 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -425,6 +425,7 @@ void PCHDeclWriter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
// FIXME: stable encoding
Record.push_back((unsigned)D->getPropertyAttributes());
+ Record.push_back((unsigned)D->getPropertyAttributesAsWritten());
// FIXME: stable encoding
Record.push_back((unsigned)D->getPropertyImplementation());
Writer.AddDeclarationName(D->getGetterName(), Record);
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index f730a3a9ea..2877d52b08 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -3929,14 +3929,11 @@ static void FindImplementableMethods(ASTContext &Context,
// Add methods from any class extensions (but not from categories;
// those should go into category implementations).
- for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
- Cat = Cat->getNextClassCategory()) {
- if (!Cat->IsClassExtension())
- continue;
-
- FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
+ for (const ObjCCategoryDecl *Cat = IFace->getFirstClassExtension(); Cat;
+ Cat = Cat->getNextClassExtension())
+ FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat),
+ WantInstanceMethods, ReturnType,
IsInImplementation, KnownMethods);
- }
}
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 5a2765c25b..21aeb59a08 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -414,7 +414,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
unsigned NumProtoRefs,
const SourceLocation *ProtoLocs,
SourceLocation EndProtoLoc) {
- ObjCCategoryDecl *CDecl = 0;
+ ObjCCategoryDecl *CDecl;
ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
/// Check that class of this category is already completely declared.
@@ -429,28 +429,21 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
return DeclPtrTy::make(CDecl);
}
- if (!CategoryName) {
- // Class extensions require a special treatment. Use an existing one.
- // Note that 'getClassExtension()' can return NULL.
- CDecl = IDecl->getClassExtension();
- if (IDecl->getImplementation()) {
- Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
- Diag(IDecl->getImplementation()->getLocation(),
- diag::note_implementation_declared);
- }
+ if (!CategoryName && IDecl->getImplementation()) {
+ Diag(ClassLoc, diag::err_class_extension_after_impl) << ClassName;
+ Diag(IDecl->getImplementation()->getLocation(),
+ diag::note_implementation_declared);
}
- if (!CDecl) {
- CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
- ClassLoc, CategoryLoc, CategoryName);
- // FIXME: PushOnScopeChains?
- CurContext->addDecl(CDecl);
+ CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
+ ClassLoc, CategoryLoc, CategoryName);
+ // FIXME: PushOnScopeChains?
+ CurContext->addDecl(CDecl);
- CDecl->setClassInterface(IDecl);
- // Insert first use of class extension to the list of class's categories.
- if (!CategoryName)
- CDecl->insertNextClassCategory();
- }
+ CDecl->setClassInterface(IDecl);
+ // Insert class extension to the list of class's categories.
+ if (!CategoryName)
+ CDecl->insertNextClassCategory();
// If the interface is deprecated, warn about it.
(void)DiagnoseUseOfDecl(IDecl, ClassLoc);
@@ -969,13 +962,11 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
InsMap, ClsMap, I);
// Check class extensions (unnamed categories)
- for (ObjCCategoryDecl *Categories = I->getCategoryList();
- Categories; Categories = Categories->getNextClassCategory()) {
- if (Categories->IsClassExtension()) {
- ImplMethodsVsClassMethods(S, IMPDecl, Categories, IncompleteImpl);
- break;
- }
- }
+ for (const ObjCCategoryDecl *Categories = I->getFirstClassExtension();
+ Categories; Categories = Categories->getNextClassExtension())
+ ImplMethodsVsClassMethods(S, IMPDecl,
+ const_cast<ObjCCategoryDecl*>(Categories),
+ IncompleteImpl);
} else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
// For extended class, unimplemented methods in its protocols will
// be reported in the primary class.
@@ -1821,7 +1812,8 @@ void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
}
// Find ivars to construct/destruct in class extension.
- if (const ObjCCategoryDecl *CDecl = OI->getClassExtension()) {
+ for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
+ CDecl = CDecl->getNextClassExtension()) {
for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
E = CDecl->ivar_end(); I != E; ++I) {
ObjCIvarDecl *Iv = (*I);
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index f25ba640d6..a27d2a8a2f 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -123,6 +123,10 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
CreatePropertyDecl(S, CCPrimary, AtLoc,
FD, GetterSel, SetterSel, isAssign, isReadWrite,
Attributes, T, MethodImplKind, DC);
+ // Mark written attribute as having no attribute because
+ // this is not a user-written property declaration in primary
+ // class.
+ PDecl->setPropertyAttributesAsWritten(ObjCPropertyDecl::OBJC_PR_noattr);
// A case of continuation class adding a new property in the class. This
// is not what it was meant for. However, gcc supports it and so should we.
@@ -134,7 +138,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
// The property 'PIDecl's readonly attribute will be over-ridden
// with continuation class's readwrite property attribute!
- unsigned PIkind = PIDecl->getPropertyAttributes();
+ unsigned PIkind = PIDecl->getPropertyAttributesAsWritten();
if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
unsigned retainCopyNonatomic =
(ObjCPropertyDecl::OBJC_PR_retain |
@@ -266,6 +270,8 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
if (Attributes & ObjCDeclSpec::DQ_PR_nonatomic)
PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_nonatomic);
+ PDecl->setPropertyAttributesAsWritten(PDecl->getPropertyAttributes());
+
if (MethodImplKind == tok::objc_required)
PDecl->setPropertyImplementation(ObjCPropertyDecl::Required);
else if (MethodImplKind == tok::objc_optional)