[cfe-commits] r41752 - in /cfe/trunk: AST/ASTContext.cpp AST/Decl.cpp AST/Type.cpp Parse/MinimalAction.cpp Parse/ParseObjc.cpp Parse/Parser.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaType.cpp include/clang/AST/ASTContext.h include/clang/AST/Decl.h include/clang/AST/Type.h include/clang/Parse/Action.h include/clang/Parse/Parser.h test/Sema/cocoa.m

Steve Naroff snaroff at apple.com
Thu Sep 6 14:24:24 PDT 2007


Author: snaroff
Date: Thu Sep  6 16:24:23 2007
New Revision: 41752

URL: http://llvm.org/viewvc/llvm-project?rev=41752&view=rev
Log:

The goal of this commit is to get just enough Sema support to recognize Objective-C classes
as types. That said, the AST nodes ObjcInterfaceDecl, ObjcInterfaceType, and ObjcClassDecl are *very*
preliminary.

The good news is we no longer need -parse-noop (aka MinimalActions) to parse cocoa.m.

Modified:
    cfe/trunk/AST/ASTContext.cpp
    cfe/trunk/AST/Decl.cpp
    cfe/trunk/AST/Type.cpp
    cfe/trunk/Parse/MinimalAction.cpp
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Parse/Parser.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaType.cpp
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/test/Sema/cocoa.m

Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Thu Sep  6 16:24:23 2007
@@ -596,6 +596,16 @@
   return QualType(Decl->TypeForDecl, 0);
 }
 
+/// getObjcInterfaceType - Return the unique reference to the type for the
+/// specified ObjC interface decl.
+QualType ASTContext::getObjcInterfaceType(ObjcInterfaceDecl *Decl) {
+  if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+  
+  Decl->TypeForDecl = new ObjcInterfaceType(Decl);
+  Types.push_back(Decl->TypeForDecl);
+  return QualType(Decl->TypeForDecl, 0);
+}
+
 /// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique
 /// TypeOfExpr AST's (since expression's are never shared). For example,
 /// multiple declarations that refer to "typeof(x)" all contain different

Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Thu Sep  6 16:24:23 2007
@@ -25,6 +25,7 @@
 static unsigned nEnumDecls = 0;
 static unsigned nTypedef = 0;
 static unsigned nFieldDecls = 0;
+static unsigned nInterfaceDecls = 0;
 static bool StatSwitch = false;
 
 bool Decl::CollectingStats(bool enable) {
@@ -101,6 +102,9 @@
     case Enum:
       nEnumDecls++;
       break;
+    case ObjcInterface:
+      nInterfaceDecls++;
+      break;
   }
 }
 

Modified: cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Type.cpp?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/AST/Type.cpp (original)
+++ cfe/trunk/AST/Type.cpp Thu Sep  6 16:24:23 2007
@@ -836,6 +836,12 @@
   InnerString = getDecl()->getIdentifier()->getName() + InnerString;
 }
 
+void ObjcInterfaceType::getAsStringInternal(std::string &InnerString) const {
+  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
+    InnerString = ' ' + InnerString;
+  InnerString = getDecl()->getIdentifier()->getName() + InnerString;
+}
+
 void TagType::getAsStringInternal(std::string &InnerString) const {
   if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
     InnerString = ' ' + InnerString;

Modified: cfe/trunk/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/MinimalAction.cpp?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/Parse/MinimalAction.cpp Thu Sep  6 16:24:23 2007
@@ -68,12 +68,24 @@
   return 0;
 }
 
-/// ParsedObjcClassDeclaration - 
+Action::DeclTy *
+MinimalAction::ObjcStartClassInterface(SourceLocation AtInterafceLoc,
+                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                    IdentifierInfo *SuperName, SourceLocation SuperLoc,
+                    IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+                    AttributeList *AttrList) {
+  TypeNameInfo *TI =
+    new TypeNameInfo(1, ClassName->getFETokenInfo<TypeNameInfo>());
+
+  ClassName->setFETokenInfo(TI);
+  return 0;
+}
+
+/// ObjcClassDeclaration - 
 /// Scope will always be top level file scope. 
 Action::DeclTy *
-MinimalAction::ParsedObjcClassDeclaration(Scope *S,
-                                          IdentifierInfo **IdentList,
-                                          unsigned NumElts) {
+MinimalAction::ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+                                IdentifierInfo **IdentList, unsigned NumElts) {
   for (unsigned i = 0; i != NumElts; ++i) {
     TypeNameInfo *TI =
       new TypeNameInfo(1, IdentList[i]->getFETokenInfo<TypeNameInfo>());

Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Thu Sep  6 16:24:23 2007
@@ -37,7 +37,7 @@
     case tok::objc_protocol:
       return ParseObjCAtProtocolDeclaration(AtLoc);
     case tok::objc_implementation:
-      return ParseObjCAtImplementationDeclaration(AtLoc);
+      return ObjcImpDecl = ParseObjCAtImplementationDeclaration(AtLoc);
     case tok::objc_end:
       return ParseObjCAtEndDeclaration(AtLoc);
     case tok::objc_compatibility_alias:
@@ -80,8 +80,8 @@
   if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
     return 0;
   
-  return Actions.ParsedObjcClassDeclaration(CurScope,
-                                            &ClassNames[0], ClassNames.size());
+  return Actions.ObjcClassDeclaration(CurScope, atLoc,
+                                      &ClassNames[0], ClassNames.size());
 }
 
 ///
@@ -154,8 +154,7 @@
     if (attrList) // categories don't support attributes.
       Diag(Tok, diag::err_objc_no_attributes_on_category);
     
-    llvm::SmallVector<DeclTy*, 64> MethodDecls;
-    ParseObjCInterfaceDeclList(0/*FIXME*/, MethodDecls);
+    ParseObjCInterfaceDeclList(0/*FIXME*/);
 
     // The @ sign was already consumed by ParseObjCInterfaceDeclList().
     if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -169,11 +168,6 @@
   IdentifierInfo *superClassId = 0;
   SourceLocation superClassLoc;
 
-  // FIXME: temporary hack to grok class names (until we have sema support).
-  llvm::SmallVector<IdentifierInfo *, 1> ClassName;
-  ClassName.push_back(nameId);
-  Actions.ParsedObjcClassDeclaration(CurScope, &ClassName[0], 1);
-  
   if (Tok.getKind() == tok::colon) { // a super class is specified.
     ConsumeToken();
     if (Tok.getKind() != tok::identifier) {
@@ -193,12 +187,10 @@
                       superClassId, superClassLoc, &ProtocolRefs[0], 
                       ProtocolRefs.size(), attrList);
             
-  llvm::SmallVector<DeclTy*, 32> IvarDecls;
   if (Tok.getKind() == tok::l_brace)
-    ParseObjCClassInstanceVariables(ClsType, IvarDecls);
+    ParseObjCClassInstanceVariables(ClsType);
 
-  llvm::SmallVector<DeclTy*, 64> MethodDecls;
-  ParseObjCInterfaceDeclList(ClsType, MethodDecls);
+  ParseObjCInterfaceDeclList(ClsType);
 
   // The @ sign was already consumed by ParseObjCInterfaceDeclList().
   if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -213,7 +205,7 @@
 ///     empty
 ///     objc-interface-decl-list objc-property-decl [OBJC2]
 ///     objc-interface-decl-list objc-method-requirement [OBJC2]
-///     objc-interface-decl-list objc-method-proto
+///     objc-interface-decl-list objc-method-proto ';'
 ///     objc-interface-decl-list declaration
 ///     objc-interface-decl-list ';'
 ///
@@ -221,9 +213,7 @@
 ///     @required
 ///     @optional
 ///
-void Parser::ParseObjCInterfaceDeclList(
-  DeclTy *interfaceDecl, llvm::SmallVectorImpl<DeclTy*> &MethodDecls) {
-  DeclTy *IDecl = 0;
+void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl) {
   while (1) {
     if (Tok.getKind() == tok::at) {
       SourceLocation AtLoc = ConsumeToken(); // the "@"
@@ -246,8 +236,10 @@
       }
     }
     if (Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) {
-      IDecl = ParseObjCMethodPrototype(true);
-      MethodDecls.push_back(IDecl);
+      ParseObjCMethodPrototype(interfaceDecl);
+      // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
+      // method definitions.
+      ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
       continue;
     }
     if (Tok.getKind() == tok::semi)
@@ -257,8 +249,7 @@
     else {
       // FIXME: as the name implies, this rule allows function definitions.
       // We could pass a flag or check for functions during semantic analysis.
-      IDecl = ParseDeclarationOrFunctionDefinition();
-      MethodDecls.push_back(IDecl);
+      ParseDeclarationOrFunctionDefinition();
     }
   }
 }
@@ -355,10 +346,9 @@
   }
 }
 
-///   objc-methodproto:
+///   objc-method-proto:
 ///     objc-instance-method objc-method-decl objc-method-attributes[opt] 
-///       ';'[opt]
-///     objc-class-method objc-method-decl objc-method-attributes[opt] ';'[opt]
+///     objc-class-method objc-method-decl objc-method-attributes[opt]
 ///
 ///   objc-instance-method: '-'
 ///   objc-class-method: '+'
@@ -366,19 +356,25 @@
 ///   objc-method-attributes:         [OBJC2]
 ///     __attribute__((deprecated))
 ///
-Parser::DeclTy *Parser::ParseObjCMethodPrototype(bool decl) {
+Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *CDecl) {
   assert((Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) && 
          "expected +/-");
 
   tok::TokenKind methodType = Tok.getKind();  
   SourceLocation methodLoc = ConsumeToken();
   
-  // FIXME: deal with "context sensitive" protocol qualifiers in prototypes
   DeclTy *MDecl = ParseObjCMethodDecl(methodType, methodLoc);
+
+  AttributeList *methodAttrs = 0;
+  // If attributes exist after the method, parse them.
+  if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
+    methodAttrs = ParseAttributes();
+
+  if (CDecl)
+    Actions.ObjcAddMethod(CDecl, MDecl, methodAttrs);
   
-  if (decl)
-    // Consume the ';'.
-    ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
+  // Since this rule is used for both method declarations and definitions,
+  // the caller is responsible for consuming the ';'.
   return MDecl;
 }
 
@@ -546,24 +542,13 @@
       Declarator ParmDecl(DS, Declarator::PrototypeContext);
       ParseDeclarator(ParmDecl);
     }
-    AttributeList *methodAttrs = 0;
-    // If attributes exist after the method, parse them.
-    if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
-      methodAttrs = ParseAttributes();
-
     // FIXME: Add support for optional parmameter list...
     return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, 
-                                              &KeyInfo[0], KeyInfo.size(),
-                                              methodAttrs);
+                                              &KeyInfo[0], KeyInfo.size());
   } else if (!selIdent) {
     Diag(Tok, diag::err_expected_ident); // missing selector name.
   }
-  AttributeList *methodAttrs = 0;
-  // If attributes exist after the method, parse them.
-  if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
-    methodAttrs = ParseAttributes();
-  return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent,
-                                            methodAttrs);
+  return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent);
 }
 
 ///   objc-protocol-refs:
@@ -612,9 +597,9 @@
 ///   objc-instance-variable-decl:
 ///     struct-declaration 
 ///
-void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
-                              llvm::SmallVectorImpl<DeclTy*> &IvarDecls) {
+void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl) {
   assert(Tok.getKind() == tok::l_brace && "expected {");
+  llvm::SmallVector<DeclTy*, 16> IvarDecls;
   
   SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
   
@@ -648,7 +633,10 @@
       }
     }
     ParseStructDeclaration(interfaceDecl, IvarDecls);
-
+    for (unsigned i = 0; i < IvarDecls.size(); i++) 
+      Actions.ObjcAddInstanceVariable(interfaceDecl, IvarDecls[i], visibility);
+    IvarDecls.clear();
+    
     if (Tok.getKind() == tok::semi) {
       ConsumeToken();
     } else if (Tok.getKind() == tok::r_brace) {
@@ -671,14 +659,14 @@
 ///   objc-protocol-definition:
 ///     @protocol identifier 
 ///       objc-protocol-refs[opt] 
-///       objc-methodprotolist 
+///       objc-interface-decl-list 
 ///     @end
 ///
 ///   objc-protocol-forward-reference:
 ///     @protocol identifier-list ';'
 ///
 ///   "@protocol identifier ;" should be resolved as "@protocol
-///   identifier-list ;": objc-methodprotolist may not start with a
+///   identifier-list ;": objc-interface-decl-list may not start with a
 ///   semicolon in the first alternative if objc-protocol-refs are omitted.
 
 Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) {
@@ -727,8 +715,7 @@
     if (ParseObjCProtocolReferences(ProtocolRefs))
       return 0;
   }
-  llvm::SmallVector<DeclTy*, 64> MethodDecls;
-  ParseObjCInterfaceDeclList(0/*FIXME*/, MethodDecls);
+  ParseObjCInterfaceDeclList(0/*FIXME*/);
 
   // The @ sign was already consumed by ParseObjCInterfaceDeclList().
   if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -794,9 +781,8 @@
     }
     ConsumeToken(); // Consume super class name
   }
-  llvm::SmallVector<DeclTy*, 32> IvarDecls;
   if (Tok.getKind() == tok::l_brace)
-    ParseObjCClassInstanceVariables(0/*FIXME*/, IvarDecls); // we have ivars
+    ParseObjCClassInstanceVariables(0/*FIXME*/); // we have ivars
   
   return 0;
 }
@@ -895,12 +881,12 @@
   return 0;
 }
 
-///   objc-method-def: objc-methodproto ';'[opt] '{' body '}'
+///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
 ///
 void Parser::ParseObjCInstanceMethodDefinition() {
   assert(Tok.getKind() == tok::minus &&
          "ParseObjCInstanceMethodDefinition(): Expected '-'");
-  ParseObjCMethodPrototype(false);
+  ParseObjCMethodPrototype(ObjcImpDecl);
   // parse optional ';'
   if (Tok.getKind() == tok::semi)
     ConsumeToken();
@@ -913,12 +899,12 @@
   StmtResult FnBody = ParseCompoundStatementBody();
 }
 
-///   objc-method-def: objc-methodproto ';'[opt] '{' body '}'
+///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
 ///
 void Parser::ParseObjCClassMethodDefinition() {
   assert(Tok.getKind() == tok::plus &&
          "ParseObjCClassMethodDefinition(): Expected '+'");
-  ParseObjCMethodPrototype(false);
+  ParseObjCMethodPrototype(ObjcImpDecl);
   // parse optional ';'
   if (Tok.getKind() == tok::semi)
     ConsumeToken();

Modified: cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/Parser.cpp?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Thu Sep  6 16:24:23 2007
@@ -22,6 +22,7 @@
   CurScope = 0;
   NumCachedScopes = 0;
   ParenCount = BracketCount = BraceCount = 0;
+  ObjcImpDecl = 0;
 }
 
 ///  Out-of-line virtual destructor to provide home for Action class.

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Thu Sep  6 16:24:23 2007
@@ -347,6 +347,17 @@
                                                TypeTy *Ty,
                                                SourceLocation RParenLoc);
   
+  // Objective-C declarations.
+  virtual DeclTy *ObjcStartClassInterface(SourceLocation AtInterafceLoc,
+                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                    IdentifierInfo *SuperName, SourceLocation SuperLoc,
+                    IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+                    AttributeList *AttrList);
+                    
+  virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+                                       IdentifierInfo **IdentList,
+                                       unsigned NumElts);
+
 private:
   // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
   // functions and arrays to their respective pointers (C99 6.3.2.1). 

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Thu Sep  6 16:24:23 2007
@@ -26,7 +26,11 @@
 using namespace clang;
 
 Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
-  return dyn_cast_or_null<TypedefDecl>(II.getFETokenInfo<Decl>());
+  Decl *IIDecl = II.getFETokenInfo<Decl>();
+  if (dyn_cast_or_null<TypedefDecl>(IIDecl) || 
+      dyn_cast_or_null<ObjcInterfaceDecl>(IIDecl))
+    return IIDecl;
+  return 0;
 }
 
 void Sema::PopScope(SourceLocation Loc, Scope *S) {
@@ -835,6 +839,45 @@
   return NewTD;
 }
 
+Sema::DeclTy *Sema::ObjcStartClassInterface(SourceLocation AtInterfaceLoc,
+                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                    IdentifierInfo *SuperName, SourceLocation SuperLoc,
+                    IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+                    AttributeList *AttrList) {
+  assert(ClassName && "Missing class identifier");
+  ObjcInterfaceDecl *IDecl;
+    
+  IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, ClassName);
+  
+  // Chain & install the interface decl into the identifier.
+  IDecl->setNext(ClassName->getFETokenInfo<Decl>());
+  ClassName->setFETokenInfo(IDecl);
+  return IDecl;
+}
+
+/// ObjcClassDeclaration - 
+/// Scope will always be top level file scope. 
+Action::DeclTy *
+Sema::ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+                           IdentifierInfo **IdentList, unsigned NumElts) {
+  ObjcClassDecl *CDecl = new ObjcClassDecl(AtClassLoc, NumElts);
+
+  for (unsigned i = 0; i != NumElts; ++i) {
+    ObjcInterfaceDecl *IDecl;
+      
+    IDecl = new ObjcInterfaceDecl(SourceLocation(), IdentList[i], true);
+    // Chain & install the interface decl into the identifier.
+    IDecl->setNext(IdentList[i]->getFETokenInfo<Decl>());
+    IdentList[i]->setFETokenInfo(IDecl);
+    
+    // Remember that this needs to be removed when the scope is popped.
+    S->AddDecl(IdentList[i]);
+    
+    CDecl->setInterfaceDecl((int)i, IDecl);
+  }
+  return CDecl;
+}
+
 
 /// ParseTag - This is invoked when we see 'struct foo' or 'struct {'.  In the
 /// former case, Name will be non-null.  In the later case, Name will be null.

Modified: cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaType.cpp?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/trunk/Sema/SemaType.cpp Thu Sep  6 16:24:23 2007
@@ -102,6 +102,10 @@
     assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
            DS.getTypeSpecSign() == 0 &&
            "Can't handle qualifiers on typedef names yet!");
+    // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so
+    // we have this "hack" for now... 
+    if (isa<ObjcInterfaceDecl>(D))
+      return Ctx.getObjcInterfaceType(cast<ObjcInterfaceDecl>(D));
     // TypeQuals handled by caller.
     return Ctx.getTypedefType(cast<TypedefDecl>(D));
   }

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Sep  6 16:24:23 2007
@@ -109,6 +109,7 @@
   /// getTypedefType - Return the unique reference to the type for the
   /// specified typename decl.
   QualType getTypedefType(TypedefDecl *Decl);
+  QualType getObjcInterfaceType(ObjcInterfaceDecl *Decl);
 
   /// getTypeOfType - GCC extension.
   QualType getTypeOfExpr(Expr *e);

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Thu Sep  6 16:24:23 2007
@@ -34,7 +34,7 @@
     // Concrete sub-classes of ValueDecl
     Function, BlockVariable, FileVariable, ParmVariable, EnumConstant,
     // Concrete sub-classes of TypeDecl
-    Typedef, Struct, Union, Class, Enum, 
+    Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass,
     // Concrete sub-class of Decl
     Field
   };
@@ -503,6 +503,47 @@
   static bool classof(const RecordDecl *D) { return true; }
 };
 
+class ObjcInterfaceDecl : public TypeDecl {
+  /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
+  FieldDecl **Ivars;   // Null if not defined.
+  int NumIvars;   // -1 if not defined.
+  
+  bool isForwardDecl; // declared with @class.
+public:
+  ObjcInterfaceDecl(SourceLocation L, IdentifierInfo *Id, bool FD = false)
+    : TypeDecl(ObjcInterface, L, Id, 0), Ivars(0), NumIvars(-1), 
+      isForwardDecl(FD) { }
+     
+  void addInstanceVariable(FieldDecl ivar);
+  
+  static bool classof(const Decl *D) {
+    return D->getKind() == ObjcInterface;
+  }
+  static bool classof(const ObjcInterfaceDecl *D) { return true; }
+};
+
+class ObjcClassDecl : public TypeDecl {
+  ObjcInterfaceDecl **ForwardDecls;   // Null if not defined.
+  int NumForwardDecls;               // -1 if not defined.
+public:
+  ObjcClassDecl(SourceLocation L, unsigned nElts)
+    : TypeDecl(ObjcClass, L, 0, 0) { 
+    if (nElts) {
+      ForwardDecls = new ObjcInterfaceDecl*[nElts];
+      bzero(ForwardDecls, nElts*sizeof(ObjcInterfaceDecl*));
+    }
+    NumForwardDecls = nElts;
+  }
+  void setInterfaceDecl(int idx, ObjcInterfaceDecl *OID) {
+    assert((idx < NumForwardDecls) && "index out of range");
+    ForwardDecls[idx] = OID;
+  }
+  static bool classof(const Decl *D) {
+    return D->getKind() == ObjcClass;
+  }
+  static bool classof(const ObjcClassDecl *D) { return true; }
+};
+
 }  // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Sep  6 16:24:23 2007
@@ -31,6 +31,7 @@
   class TagDecl;
   class RecordDecl;
   class EnumDecl;
+  class ObjcInterfaceDecl;
   class Expr;
   class SourceLocation;
   class PointerType;
@@ -203,6 +204,7 @@
     Vector, OCUVector,
     FunctionNoProto, FunctionProto,
     TypeName, Tagged, 
+    ObjcInterface,
     TypeOfExp, TypeOfTyp // GNU typeof extension.
   };
 private:
@@ -810,6 +812,23 @@
   static bool classof(const TagType *) { return true; }
 };
 
+class ObjcInterfaceType : public Type {
+  ObjcInterfaceDecl *Decl;
+  ObjcInterfaceType(ObjcInterfaceDecl *D) : 
+    Type(ObjcInterface, QualType()), Decl(D) { }
+  friend class ASTContext;  // ASTContext creates these.
+public:
+  
+  ObjcInterfaceDecl *getDecl() const { return Decl; }
+  
+  virtual void getAsStringInternal(std::string &InnerString) const;
+
+  static bool classof(const Type *T) { 
+    return T->getTypeClass() == ObjcInterface; 
+  }
+  static bool classof(const ObjcInterfaceType *) { return true; }
+};
+
 /// RecordType - This is a helper class that allows the use of isa/cast/dyncast
 /// to detect TagType objects of structs/unions/classes.
 class RecordType : public TagType {

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Sep  6 16:24:23 2007
@@ -136,9 +136,9 @@
     return 0;
   }
   
-  virtual DeclTy *ParsedObjcClassDeclaration(Scope *S,
-                                             IdentifierInfo **IdentList,
-                                             unsigned NumElts) {
+  virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+                                       IdentifierInfo **IdentList,
+                                       unsigned NumElts) {
     return 0;
   }
 
@@ -440,25 +440,30 @@
                     AttributeList *AttrList) {
     return 0;
   }
-  virtual void ObjCContinueClassInterface(SourceLocation InterfaceLoc) {
+  virtual void ObjcAddInstanceVariable(DeclTy *ClassDec, DeclTy *Ivars, 
+                                       tok::ObjCKeywordKind visibility) {
     return;
   }
-  virtual void ObjCStartCategoryInterface() {
-    return;
-  }
-  virtual void ObjCFinishInterface() {
+  virtual void ObjcAddMethod(DeclTy *ClassDec, DeclTy *Meth, 
+                             AttributeList *AttrList) {
     return;
   }
   virtual DeclTy *ObjcBuildMethodDeclaration(
     SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
-    ObjcKeywordInfo *Keywords, unsigned NumKeywords, AttributeList *attrs) {
+    ObjcKeywordInfo *Keywords, unsigned NumKeywords) {
     return 0;
   }
   virtual DeclTy *ObjcBuildMethodDeclaration(
     SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
-    IdentifierInfo *SelectorName, AttributeList *attrs) {
+    IdentifierInfo *SelectorName) {
     return 0;
   }
+  virtual void ObjCStartCategoryInterface() { // FIXME
+    return;
+  }
+  virtual void ObjCFinishInterface() {
+    return;
+  }
     
   //===----------------------- Obj-C Expressions --------------------------===//
   virtual ExprResult ParseObjCStringLiteral(ExprTy *string) {
@@ -496,10 +501,15 @@
   /// they are removed from the IdentifierInfo::FETokenInfo field.
   virtual void PopScope(SourceLocation Loc, Scope *S);
   
-  virtual DeclTy *ParsedObjcClassDeclaration(Scope *S,
-                                             IdentifierInfo **IdentList,
-                                             unsigned NumElts);
+  virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+                                       IdentifierInfo **IdentList,
+                                       unsigned NumElts);
   
+  virtual DeclTy *ObjcStartClassInterface(SourceLocation AtInterafceLoc,
+                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
+                    IdentifierInfo *SuperName, SourceLocation SuperLoc,
+                    IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+                    AttributeList *AttrList);
 };
 
 }  // end namespace clang

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Sep  6 16:24:23 2007
@@ -253,17 +253,17 @@
   void ParseSimpleAsm();
   void ParseAsmStringLiteral();
 
-  // Objective-C External Declarations 
+  // Objective-C External Declarations
   DeclTy *ParseObjCAtDirectives(); 
   DeclTy *ParseObjCAtClassDeclaration(SourceLocation atLoc);
   DeclTy *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc, 
                                           AttributeList *prefixAttrs = 0);
-  void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
-                              llvm::SmallVectorImpl<DeclTy*> &IvarDecls);
+  void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl);
   bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<IdentifierInfo*> &);
-  void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
-                                  llvm::SmallVectorImpl<DeclTy*> &MethodDecls);
+  void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl);
   DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
+  
+  DeclTy *ObjcImpDecl;
   DeclTy *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
   DeclTy *ParseObjCAtEndDeclaration(SourceLocation atLoc);
   DeclTy *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
@@ -288,7 +288,7 @@
 
   TypeTy *ParseObjCTypeName();
   void ParseObjCMethodRequirement();
-  DeclTy *ParseObjCMethodPrototype(bool decl);
+  DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat);
   DeclTy *ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
   void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
   void ParseObjCPropertyDecl(DeclTy *interfaceDecl);

Modified: cfe/trunk/test/Sema/cocoa.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/cocoa.m?rev=41752&r1=41751&r2=41752&view=diff

==============================================================================
--- cfe/trunk/test/Sema/cocoa.m (original)
+++ cfe/trunk/test/Sema/cocoa.m Thu Sep  6 16:24:23 2007
@@ -1,4 +1,4 @@
-// RUN: clang %s -parse-noop -arch ppc
+// RUN: clang %s -arch ppc
 #ifdef __APPLE__
 #include <Cocoa/Cocoa.h>
 #endif





More information about the cfe-commits mailing list