]> granicus.if.org Git - clang/commitdiff
- Add ObjcInterfaceDecl::lookupInstanceMethod(), lookupClassMethod().
authorSteve Naroff <snaroff@apple.com>
Tue, 2 Oct 2007 20:01:56 +0000 (20:01 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 2 Oct 2007 20:01:56 +0000 (20:01 +0000)
- Add ObjcMessageExpr::getSelector(), getClassName().
- Change Sema::getObjCInterfaceDecl() to simply take an IdentifierInfo (no Scope needed).
- Remove FIXME for printing ObjCMessageExpr's.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42543 91177308-0d34-0410-b5e6-96231b3b80d8

AST/Decl.cpp
AST/StmtPrinter.cpp
Sema/Sema.h
Sema/SemaDecl.cpp
Sema/SemaExpr.cpp
clang.xcodeproj/project.pbxproj
include/clang/AST/DeclObjC.h
include/clang/AST/Expr.h

index d23f3cb6f3496eaea57cf2a62f4dffd565304b02..9e02607cf38c11c263c6e8662e9acaec14de1033 100644 (file)
@@ -408,4 +408,36 @@ void ObjcImplementationDecl::ObjcAddImplMethods(ObjcMethodDecl **insMethods,
   }
 }
 
+// FIXME: look through categories...
+ObjcMethodDecl *ObjcInterfaceDecl::lookupInstanceMethod(Selector &Sel) {
+  ObjcInterfaceDecl* ClassDecl = this;
+  while (ClassDecl != NULL) {
+    ObjcMethodDecl **methods = ClassDecl->getInsMethods();
+    int methodCount = ClassDecl->getNumInsMethods();
+    for (int i = 0; i < methodCount; ++i) {
+      if (methods[i]->getSelector() == Sel) {
+        return methods[i];
+      }
+    }
+    ClassDecl = ClassDecl->getSuperClass();
+  }
+  return NULL;
+}
+
+// FIXME: look through categories...
+ObjcMethodDecl *ObjcInterfaceDecl::lookupClassMethod(Selector &Sel) {
+  ObjcInterfaceDecl* ClassDecl = this;
+  while (ClassDecl != NULL) {
+    ObjcMethodDecl **methods = ClassDecl->getClsMethods();
+    int methodCount = ClassDecl->getNumClsMethods();
+    for (int i = 0; i < methodCount; ++i) {
+      if (methods[i]->getSelector() == Sel) {
+        return methods[i];
+      }
+    }
+    ClassDecl = ClassDecl->getSuperClass();
+  }
+  return NULL;
+}
+
 
index f878ca8137282e4114397502c500ec029e192467..a25d8eee4a70be64226d2762f3e2377efbdcaf16 100644 (file)
@@ -614,10 +614,17 @@ void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
 
 void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
   OS << "[";
-  PrintExpr(Mess->getReceiver());
-  for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
-    // FIXME: get/print keyword...
-    PrintExpr(Mess->getArg(i));
+  Expr *receiver = Mess->getReceiver();
+  if (receiver) PrintExpr(receiver);
+  else OS << Mess->getClassName()->getName();
+  Selector &selector = Mess->getSelector();
+  if (selector.isUnarySelector()) {
+    OS << " " << selector.getIdentifierInfoForSlot(0)->getName();
+  } else {
+    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
+      OS << " " << selector.getIdentifierInfoForSlot(i)->getName() << ":";
+      PrintExpr(Mess->getArg(i));
+    }
   }
   OS << "]";
 }
index 74f79d4f3f1766d9f747fd57f94b211b3779bb24..a965f7f7257f593609a298679fe8fbf9b3f34921 100644 (file)
@@ -187,8 +187,7 @@ private:
                                     Scope *FnBodyScope);
   ScopedDecl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI, 
                                SourceLocation IdLoc, Scope *S);  
-  ObjcInterfaceDecl *getObjCInterfaceDecl(Scope *S, 
-                      IdentifierInfo *Id, SourceLocation IdLoc);
+  ObjcInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
   ObjcProtocolDecl *getObjCProtocolDecl(Scope *S, 
                       IdentifierInfo *Id, SourceLocation IdLoc);
   ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S);
@@ -436,7 +435,7 @@ public:
   // is obtained from Sel.getNumArgs().
   virtual ExprResult ActOnClassMessage(
     IdentifierInfo *receivingClassName, Selector Sel,
-    SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs);
+     SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs);
 
   // ActOnInstanceMessage - used for both unary and keyword messages.
   // ArgExprs is optional - if it is present, the number of expressions
index 7b5aba390bc7e0bff7bccec6be3be24cc619d963..ed8591ddca017b75064154762653b4ce34831af4 100644 (file)
@@ -80,11 +80,18 @@ void Sema::PopScope(SourceLocation Loc, Scope *S) {
 
 /// getObjcInterfaceDecl - Look up a for a class declaration in the scope.
 /// return 0 if one not found.
-ObjcInterfaceDecl *Sema::getObjCInterfaceDecl(Scope *S,
-                                                     IdentifierInfo *Id, 
-                                             SourceLocation IdLoc) {
-  ScopedDecl *IdDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary, 
-                                       IdLoc, S);
+ObjcInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
+
+  // Scan up the scope chain looking for a decl that matches this identifier
+  // that is in the appropriate namespace.  This search should not take long, as
+  // shadowing of names is uncommon, and deep shadowing is extremely uncommon.
+  ScopedDecl *IdDecl = NULL;
+  for (ScopedDecl *D = Id->getFETokenInfo<ScopedDecl>(); D; D = D->getNext()) {
+    if (D->getIdentifierNamespace() == Decl::IDNS_Ordinary) {
+      IdDecl = D;
+      break;
+    }
+  }
   if (IdDecl && !isa<ObjcInterfaceDecl>(IdDecl))
     IdDecl = 0;
   return cast_or_null<ObjcInterfaceDecl>(static_cast<Decl*>(IdDecl));
@@ -905,7 +912,7 @@ Sema::DeclTy *Sema::ObjcStartClassInterface(Scope* S,
     Diag(PrevDecl->getLocation(), diag::err_previous_definition);
   }
   
-  ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(S, ClassName, ClassLoc);
+  ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(ClassName);
   if (IDecl) {
     // Class already seen. Is it a forward declaration?
     if (!IDecl->getIsForwardDecl())
@@ -936,7 +943,7 @@ Sema::DeclTy *Sema::ObjcStartClassInterface(Scope* S,
     }
     else {
       // Check that super class is previously defined
-      SuperClassEntry = getObjCInterfaceDecl(S, SuperName, SuperLoc); 
+      SuperClassEntry = getObjCInterfaceDecl(SuperName); 
                               
       if (!SuperClassEntry || SuperClassEntry->getIsForwardDecl()) {
         Diag(AtInterfaceLoc, diag::err_undef_superclass, SuperName->getName(),
@@ -1030,7 +1037,7 @@ Sema::DeclTy *Sema::ObjcStartCatInterface(Scope* S,
                       IdentifierInfo *CategoryName, SourceLocation CategoryLoc,
                       IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) {
   ObjcCategoryDecl *CDecl;
-  ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(S, ClassName, ClassLoc);
+  ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(ClassName);
   CDecl = new ObjcCategoryDecl(AtInterfaceLoc, NumProtoRefs);
   CDecl->setClassInterface(IDecl);
 
@@ -1075,7 +1082,7 @@ Sema::DeclTy *Sema::ObjcStartCategoryImplementation(Scope* S,
                       SourceLocation AtCatImplLoc,
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *CatName, SourceLocation CatLoc) {
-  ObjcInterfaceDecl *IDecl = getObjCInterfaceDecl(S, ClassName, ClassLoc);
+  ObjcInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
   ObjcCategoryImplDecl *CDecl = new ObjcCategoryImplDecl(AtCatImplLoc, 
                                                          ClassName, IDecl,
                                                          CatName);
@@ -1103,7 +1110,7 @@ Sema::DeclTy *Sema::ObjcStartClassImplementation(Scope *S,
   }
   else {
     // Is there an interface declaration of this class; if not, warn!
-    IDecl = getObjCInterfaceDecl(S, ClassName, ClassLoc); 
+    IDecl = getObjCInterfaceDecl(ClassName); 
     if (!IDecl)
       Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName());
   }
@@ -1121,7 +1128,7 @@ Sema::DeclTy *Sema::ObjcStartClassImplementation(Scope *S,
       Diag(PrevDecl->getLocation(), diag::err_previous_definition);
     }
     else {
-      SDecl = getObjCInterfaceDecl(S, SuperClassname, SuperClassLoc); 
+      SDecl = getObjCInterfaceDecl(SuperClassname); 
       if (!SDecl)
         Diag(SuperClassLoc, diag::err_undef_superclass, 
              SuperClassname->getName(), ClassName->getName());
@@ -1330,7 +1337,7 @@ Sema::ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
 
   for (unsigned i = 0; i != NumElts; ++i) {
     ObjcInterfaceDecl *IDecl;
-    IDecl = getObjCInterfaceDecl(S, IdentList[i], AtClassLoc); 
+    IDecl = getObjCInterfaceDecl(IdentList[i]); 
     if (!IDecl)  {// Already seen?
       IDecl = new ObjcInterfaceDecl(SourceLocation(), 0, IdentList[i], true);
       // Chain & install the interface decl into the identifier.
@@ -1655,8 +1662,7 @@ void Sema::ActOnFields(Scope* S,
        cast<ObjcImplementationDecl>(static_cast<Decl*>(RecDecl));
       assert(IMPDecl && "ActOnFields - missing ObjcImplementationDecl");
       IMPDecl->ObjcAddInstanceVariablesToClassImpl(ClsFields, RecFields.size());
-      ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(S, 
-                                  IMPDecl->getIdentifier(), RecLoc);
+      ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(IMPDecl->getIdentifier());
       if (IDecl)
         ActOnImpleIvarVsClassIvars(static_cast<DeclTy*>(IDecl), 
           reinterpret_cast<DeclTy**>(&RecFields[0]), RecFields.size());
@@ -1705,8 +1711,7 @@ void Sema::ObjcAddMethodsToClass(Scope* S, DeclTy *ClassDecl,
                                                static_cast<Decl*>(ClassDecl));
     ImplClass->ObjcAddImplMethods(&insMethods[0], insMethods.size(),
                                  &clsMethods[0], clsMethods.size());
-    ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(S, 
-                                ImplClass->getIdentifier(), SourceLocation());
+    ObjcInterfaceDecl* IDecl = getObjCInterfaceDecl(ImplClass->getIdentifier());
     if (IDecl)
       ImplMethodsVsClassMethods(ImplClass, IDecl);
   }
index 0041805dfb1e38562eade1cea6dbee3a26169fb7..29f422c04ab5fbf06bde867a048e14728e5cd4e4 100644 (file)
@@ -14,6 +14,7 @@
 #include "Sema.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/Parse/DeclSpec.h" 
 #include "clang/Lex/Preprocessor.h"
@@ -1875,14 +1876,18 @@ Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
 // ArgExprs is optional - if it is present, the number of expressions
 // is obtained from Sel.getNumArgs().
 Sema::ExprResult Sema::ActOnClassMessage(
-  IdentifierInfo *receivingClassName, Selector Sel,
+  IdentifierInfo *receiverName, Selector Sel,
   SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args)
 {
-  assert(receivingClassName && "missing receiver class name");
+  assert(receiverName && "missing receiver class name");
 
+  ObjcInterfaceDecl* ClassDecl = getObjCInterfaceDecl(receiverName);
+  ObjcMethodDecl *Method = ClassDecl->lookupClassMethod(Sel);
+  assert(Method && "missing method declaration");
+  QualType retType = Method->getMethodType();
+  // Expr *RExpr = global reference to the class symbol...
   Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
-  return new ObjCMessageExpr(receivingClassName, Sel, 
-                             Context.IntTy/*FIXME*/, lbrac, rbrac, ArgExprs);
+  return new ObjCMessageExpr(receiverName, Sel, retType, lbrac, rbrac, ArgExprs);
 }
 
 // ActOnInstanceMessage - used for both unary and keyword messages.
@@ -1895,7 +1900,19 @@ Sema::ExprResult Sema::ActOnInstanceMessage(
   assert(receiver && "missing receiver expression");
   
   Expr *RExpr = static_cast<Expr *>(receiver);
+  // FIXME (snaroff): checking in this code from Patrick. Needs to be revisited.
+  // how do we get the ClassDecl from the receiver expression?
+  QualType receiverType = RExpr->getType();
+  while (receiverType->isPointerType()) {
+    PointerType *pointerType = static_cast<PointerType*>(receiverType.getTypePtr());
+    receiverType = pointerType->getPointeeType();
+  }
+  assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) && "bad receiver type");
+  ObjcInterfaceDecl* ClassDecl = static_cast<ObjcInterfaceType*>(
+                                   receiverType.getTypePtr())->getDecl();
+  ObjcMethodDecl *Method = ClassDecl->lookupInstanceMethod(Sel);
+  assert(Method && "missing method declaration");
+  QualType returnType = Method->getMethodType();
   Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
-  return new ObjCMessageExpr(RExpr, Sel,
-                             Context.IntTy/*FIXME*/, lbrac, rbrac, ArgExprs);
+  return new ObjCMessageExpr(RExpr, Sel, returnType, lbrac, rbrac, ArgExprs);
 }
index 6389e5fbc4b52a5bf259edca2edaf14c4c7a7ad6..314ed3ea3cf698d8d382b2bd0ea6ae5b1523a2b3 100644 (file)
                08FB7793FE84155DC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
-                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
                        projectDirPath = "";
index 615bf454de8793b59c3b9d3e0503cd3f21b8e5df..6099e56d7c7714ab66eb9ec1f2599be6d55f39b6 100644 (file)
@@ -127,6 +127,8 @@ public:
   void setListCategories(ObjcCategoryDecl *category) { 
          ListCategories = category; 
   }
+  ObjcMethodDecl *lookupInstanceMethod(Selector &Sel);
+  ObjcMethodDecl *lookupClassMethod(Selector &Sel);
   
   static bool classof(const Decl *D) {
     return D->getKind() == ObjcInterface;
index 0a0e685f804d577c3ebbeaad9ede7a93c6414091..d260cb71930c359afb8d8ffb6d1426c1ae469887 100644 (file)
@@ -1100,6 +1100,12 @@ public:
   const Expr *getReceiver() const { return SubExprs[RECEIVER]; }
   Expr *getReceiver() { return SubExprs[RECEIVER]; }
   
+  const Selector &getSelector() const { return SelName; }
+  Selector &getSelector() { return SelName; }
+  
+  const IdentifierInfo *getClassName() const { return ClassName; }
+  IdentifierInfo *getClassName() { return ClassName; }
+  
   /// getNumArgs - Return the number of actual arguments to this call.
   unsigned getNumArgs() const { return SelName.getNumArgs(); }