]> granicus.if.org Git - clang/commitdiff
Early support for declaring ivars in class extensions. wip.
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 22 Feb 2010 23:04:20 +0000 (23:04 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 22 Feb 2010 23:04:20 +0000 (23:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96819 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Parse/Parser.h
lib/Parse/ParseObjc.cpp
lib/Sema/SemaDecl.cpp

index 7c75f2fc7bf3b1c4a990bb20390167b9af799526..919397b52c00a3f3e12e99dee8b17cbdd9788905 100644 (file)
@@ -1490,6 +1490,8 @@ def err_forward_ref_enum : Error<
   "ISO C++ forbids forward references to 'enum' types">;
 def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
 def err_duplicate_member : Error<"duplicate member %0">;
+def err_misplaced_ivar : Error<"ivar may be placed in a class extension "
+                               "in non-fragile-abi2 mode only">;
 def ext_enum_value_not_int : Extension<
   "ISO C restricts enumerator values to range of 'int' (%0 is too "
   "%select{small|large}1)">;
index d21fc1f59f4e9c3089514defcd20fbcc70a0605e..a29e47f1ab16f9acc6b5ebf1936b44da40be0640 100644 (file)
@@ -849,6 +849,7 @@ private:
   DeclPtrTy ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
                                           AttributeList *prefixAttrs = 0);
   void ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
+                                       tok::ObjCKeywordKind visibility,
                                        SourceLocation atLoc);
   bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &P,
                                    llvm::SmallVectorImpl<SourceLocation> &PLocs,
index 4bf183c4c0eb32ad60079680d4ba2698027ac245..7ab0e71dc2356639db1b3294a134a9ac93c150b7 100644 (file)
@@ -188,7 +188,10 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
                                           ProtocolRefs.size(),
                                           ProtocolLocs.data(),
                                           EndProtoLoc);
-
+    if (Tok.is(tok::l_brace))
+      ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
+                                      atLoc);
+    
     ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
     return CategoryType;
   }
@@ -229,7 +232,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
                                      EndProtoLoc, attrList);
 
   if (Tok.is(tok::l_brace))
-    ParseObjCClassInstanceVariables(ClsType, atLoc);
+    ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
 
   ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
   return ClsType;
@@ -965,6 +968,7 @@ ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols,
 ///     struct-declaration
 ///
 void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
+                                             tok::ObjCKeywordKind visibility,
                                              SourceLocation atLoc) {
   assert(Tok.is(tok::l_brace) && "expected {");
   llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
@@ -973,7 +977,6 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,
 
   SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
 
-  tok::ObjCKeywordKind visibility = tok::objc_protected;
   // While we still have something to read, read the instance variables.
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
     // Each iteration of this loop reads one objc-instance-variable-decl.
@@ -1228,7 +1231,8 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
                                   superClassId, superClassLoc);
 
   if (Tok.is(tok::l_brace)) // we have ivars
-    ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc);
+    ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, 
+                                    tok::objc_protected, atLoc);
   ObjCImpDecl = ImplClsType;
   PendingObjCImpDecl.push_back(ObjCImpDecl);
   
index c59e8bad6678cebfe9178344a403c0534c1c963b..0be3841ad5a8ad9b35b2e429a31e7faa3c8356a7 100644 (file)
@@ -5682,6 +5682,19 @@ void Sema::ActOnFields(Scope* S,
         // Only it is in implementation's lexical context.
         ClsFields[I]->setLexicalDeclContext(IMPDecl);
       CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac);
+    } else if (ObjCCategoryDecl *CDecl = 
+                dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
+      if (!LangOpts.ObjCNonFragileABI2 || !CDecl->IsClassExtension())
+        Diag(LBrac, diag::err_misplaced_ivar);
+      else {
+        // FIXME. Class extension does not have a LocEnd field.
+        // CDecl->setLocEnd(RBrac);
+        // Add ivar's to class extension's DeclContext.
+        for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
+          ClsFields[i]->setLexicalDeclContext(CDecl);
+          CDecl->addDecl(ClsFields[i]);
+        }
+      }
     }
   }