aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclObjC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDeclObjC.cpp')
-rw-r--r--lib/Sema/SemaDeclObjC.cpp29
1 files changed, 19 insertions, 10 deletions
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index e40e8fedc0..925c0db4e4 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -599,22 +599,31 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
SourceLocation EndProtoLoc) {
ObjCCategoryDecl *CDecl = 0;
ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc);
- if (!CategoryName)
+
+ /// Check that class of this category is already completely declared.
+ if (!IDecl || IDecl->isForwardDecl()) {
+ // Create an invalid ObjCCategoryDecl to serve as context for
+ // the enclosing method declarations. We mark the decl invalid
+ // to make it clear that this isn't a valid AST.
+ CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
+ ClassLoc, CategoryLoc, CategoryName);
+ CDecl->setInvalidDecl();
+ Diag(ClassLoc, diag::err_undef_interface) << ClassName;
+ 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 (!CDecl) {
- CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, ClassLoc,
- CategoryLoc, CategoryName);
+ CDecl = ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc,
+ ClassLoc, CategoryLoc, CategoryName);
// FIXME: PushOnScopeChains?
CurContext->addDecl(CDecl);
- /// Check that class of this category is already completely declared.
- if (!IDecl || IDecl->isForwardDecl()) {
- CDecl->setInvalidDecl();
- Diag(ClassLoc, diag::err_undef_interface) << ClassName;
- return DeclPtrTy::make(CDecl);
- }
-
CDecl->setClassInterface(IDecl);
// Insert first use of class extension to the list of class's categories.
if (!CategoryName)