[cfe-commits] r45597 - in /cfe/trunk: Sema/SemaExpr.cpp Sema/SemaExprObjC.cpp clang.xcodeproj/project.pbxproj

Chris Lattner sabre at nondot.org
Fri Jan 4 14:32:31 PST 2008


Author: lattner
Date: Fri Jan  4 16:32:30 2008
New Revision: 45597

URL: http://llvm.org/viewvc/llvm-project?rev=45597&view=rev
Log:
move objc expr sema to its own file.

Added:
    cfe/trunk/Sema/SemaExprObjC.cpp
Modified:
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/clang.xcodeproj/project.pbxproj

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=45597&r1=45596&r2=45597&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Fri Jan  4 16:32:30 2008
@@ -14,15 +14,11 @@
 #include "Sema.h"
 #include "SemaUtil.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"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallString.h"
@@ -2040,93 +2036,6 @@
   return new VAArgExpr(BuiltinLoc, E, T, RPLoc);
 }
 
-// TODO: Move this to SemaObjC.cpp
-Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, 
-                                              ExprTy **Strings,
-                                              unsigned NumStrings) {
-  SourceLocation AtLoc = AtLocs[0];
-  StringLiteral* S = static_cast<StringLiteral *>(Strings[0]);
-  if (NumStrings > 1) {
-    // Concatenate objc strings.
-    StringLiteral* ES = static_cast<StringLiteral *>(Strings[NumStrings-1]);
-    SourceLocation EndLoc = ES->getSourceRange().getEnd();
-    unsigned Length = 0;
-    for (unsigned i = 0; i < NumStrings; i++)
-      Length += static_cast<StringLiteral *>(Strings[i])->getByteLength();
-    char *strBuf = new char [Length];
-    char *p = strBuf;
-    bool isWide = false;
-    for (unsigned i = 0; i < NumStrings; i++) {
-      S = static_cast<StringLiteral *>(Strings[i]);
-      if (S->isWide())
-        isWide = true;
-      memcpy(p, S->getStrData(), S->getByteLength());
-      p += S->getByteLength();
-      delete S;
-    }
-    S = new StringLiteral(strBuf, Length,
-                          isWide, Context.getPointerType(Context.CharTy),
-                          AtLoc, EndLoc);
-  }
-  
-  if (CheckBuiltinCFStringArgument(S))
-    return true;
-  
-  if (Context.getObjcConstantStringInterface().isNull()) {
-    // Initialize the constant string interface lazily. This assumes
-    // the NSConstantString interface is seen in this translation unit.
-    IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
-    ScopedDecl *IFace = LookupScopedDecl(NSIdent, Decl::IDNS_Ordinary, 
-                                         SourceLocation(), TUScope);
-    ObjcInterfaceDecl *strIFace = dyn_cast_or_null<ObjcInterfaceDecl>(IFace);
-    if (!strIFace)
-      return Diag(S->getLocStart(), diag::err_undef_interface,
-                  NSIdent->getName());
-    Context.setObjcConstantStringInterface(strIFace);
-  }
-  QualType t = Context.getObjcConstantStringInterface();
-  t = Context.getPointerType(t);
-  return new ObjCStringLiteral(S, t, AtLoc);
-}
-
-Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
-                                                 SourceLocation EncodeLoc,
-                                                 SourceLocation LParenLoc,
-                                                 TypeTy *Ty,
-                                                 SourceLocation RParenLoc) {
-  QualType EncodedType = QualType::getFromOpaquePtr(Ty);
-
-  QualType t = Context.getPointerType(Context.CharTy);
-  return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
-}
-
-Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
-                                                   SourceLocation AtLoc,
-                                                   SourceLocation SelLoc,
-                                                   SourceLocation LParenLoc,
-                                                   SourceLocation RParenLoc) {
-  QualType t = Context.getObjcSelType();
-  return new ObjCSelectorExpr(t, Sel, AtLoc, RParenLoc);
-}
-
-Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
-                                                   SourceLocation AtLoc,
-                                                   SourceLocation ProtoLoc,
-                                                   SourceLocation LParenLoc,
-                                                   SourceLocation RParenLoc) {
-  ObjcProtocolDecl* PDecl = ObjcProtocols[ProtocolId];
-  if (!PDecl) {
-    Diag(ProtoLoc, diag::err_undeclared_protocol, ProtocolId->getName());
-    return true;
-  }
-  
-  QualType t = Context.getObjcProtoType();
-  if (t.isNull())
-    return true;
-  t = Context.getPointerType(t);
-  return new ObjCProtocolExpr(t, PDecl, AtLoc, RParenLoc);
-}
-
 bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
                                     SourceLocation Loc,
                                     QualType DstType, QualType SrcType,
@@ -2163,192 +2072,3 @@
   return isInvalid;
 }
 
-bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
-                                     ObjcMethodDecl *Method) {
-  bool anyIncompatibleArgs = false;
-  
-  for (unsigned i = 0; i < NumArgs; i++) {
-    Expr *argExpr = Args[i];
-    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
-    
-    QualType lhsType = Method->getParamDecl(i)->getType();
-    QualType rhsType = argExpr->getType();
-
-    // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8]. 
-    if (const ArrayType *ary = lhsType->getAsArrayType())
-      lhsType = Context.getPointerType(ary->getElementType());
-    else if (lhsType->isFunctionType())
-      lhsType = Context.getPointerType(lhsType);
-
-    AssignConvertType Result = CheckSingleAssignmentConstraints(lhsType,
-                                                                argExpr);
-    if (Args[i] != argExpr) // The expression was converted.
-      Args[i] = argExpr; // Make sure we store the converted expression.
-    
-    anyIncompatibleArgs |= 
-      DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
-                               argExpr, "sending");
-  }
-  return anyIncompatibleArgs;
-}
-
-// ActOnClassMessage - used for both unary and keyword messages.
-// ArgExprs is optional - if it is present, the number of expressions
-// is obtained from Sel.getNumArgs().
-Sema::ExprResult Sema::ActOnClassMessage(
-  Scope *S,
-  IdentifierInfo *receiverName, Selector Sel,
-  SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs)
-{
-  assert(receiverName && "missing receiver class name");
-
-  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
-  ObjcInterfaceDecl* ClassDecl = 0;
-  if (!strcmp(receiverName->getName(), "super") && CurMethodDecl) {
-    ClassDecl = CurMethodDecl->getClassInterface()->getSuperClass();
-    if (ClassDecl && CurMethodDecl->isInstance()) {
-      // Synthesize a cast to the super class. This hack allows us to loosely
-      // represent super without creating a special expression node.
-      IdentifierInfo &II = Context.Idents.get("self");
-      ExprResult ReceiverExpr = ActOnIdentifierExpr(S, lbrac, II, false);
-      QualType superTy = Context.getObjcInterfaceType(ClassDecl);
-      superTy = Context.getPointerType(superTy);
-      ReceiverExpr = ActOnCastExpr(SourceLocation(), superTy.getAsOpaquePtr(),
-                                   SourceLocation(), ReceiverExpr.Val);
-      // We are really in an instance method, redirect.
-      return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac,
-                                  Args, NumArgs);
-    }
-    // We are sending a message to 'super' within a class method. Do nothing,
-    // the receiver will pass through as 'super' (how convenient:-).
-  } else
-    ClassDecl = getObjCInterfaceDecl(receiverName);
-  
-  // FIXME: can ClassDecl ever be null?
-  ObjcMethodDecl *Method = ClassDecl->lookupClassMethod(Sel);
-  QualType returnType;
-  
-  // Before we give up, check if the selector is an instance method.
-  if (!Method)
-    Method = ClassDecl->lookupInstanceMethod(Sel);
-  if (!Method) {
-    Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(),
-         SourceRange(lbrac, rbrac));
-    returnType = Context.getObjcIdType();
-  } else {
-    returnType = Method->getResultType();
-    if (Sel.getNumArgs()) {
-      if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
-        return true;
-    }
-  }
-  return new ObjCMessageExpr(receiverName, Sel, returnType, Method,
-                             lbrac, rbrac, ArgExprs, NumArgs);
-}
-
-// ActOnInstanceMessage - used for both unary and keyword messages.
-// ArgExprs is optional - if it is present, the number of expressions
-// is obtained from Sel.getNumArgs().
-Sema::ExprResult Sema::ActOnInstanceMessage(
-  ExprTy *receiver, Selector Sel,
-  SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs) 
-{
-  assert(receiver && "missing receiver expression");
-  
-  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
-  Expr *RExpr = static_cast<Expr *>(receiver);
-  QualType receiverType = RExpr->getType();
-  QualType returnType;
-  ObjcMethodDecl *Method = 0;
-  
-  if (receiverType == Context.getObjcIdType() ||
-      receiverType == Context.getObjcClassType()) {
-    Method = InstanceMethodPool[Sel].Method;
-	if (!Method)
-	  Method = FactoryMethodPool[Sel].Method;
-    if (!Method) {
-      Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
-           SourceRange(lbrac, rbrac));
-      returnType = Context.getObjcIdType();
-    } else {
-      returnType = Method->getResultType();
-      if (Sel.getNumArgs())
-        if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
-          return true;
-    }
-  } else {
-    bool receiverIsQualId = dyn_cast<ObjcQualifiedIdType>(receiverType) != 0;
-    // FIXME (snaroff): checking in this code from Patrick. Needs to be
-    // revisited. how do we get the ClassDecl from the receiver expression?
-    if (!receiverIsQualId)
-      while (receiverType->isPointerType()) {
-        PointerType *pointerType =
-          static_cast<PointerType*>(receiverType.getTypePtr());
-        receiverType = pointerType->getPointeeType();
-      }
-    ObjcInterfaceDecl* ClassDecl = 0;
-    if (ObjcQualifiedInterfaceType *QIT = 
-        dyn_cast<ObjcQualifiedInterfaceType>(receiverType)) {
-      ClassDecl = QIT->getDecl();
-      Method = ClassDecl->lookupInstanceMethod(Sel);
-      if (!Method) {
-        // search protocols
-        for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
-          ObjcProtocolDecl *PDecl = QIT->getProtocols(i);
-          if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
-            break;
-        }
-      }
-      if (!Method)
-        Diag(lbrac, diag::warn_method_not_found_in_protocol, 
-             std::string("-"), Sel.getName(),
-             SourceRange(lbrac, rbrac));
-    }
-    else if (ObjcQualifiedIdType *QIT = 
-             dyn_cast<ObjcQualifiedIdType>(receiverType)) {
-      // search protocols
-      for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
-        ObjcProtocolDecl *PDecl = QIT->getProtocols(i);
-        if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
-          break;
-      }
-      if (!Method)
-        Diag(lbrac, diag::warn_method_not_found_in_protocol, 
-             std::string("-"), Sel.getName(),
-             SourceRange(lbrac, rbrac));
-    }
-    else {
-      assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) &&
-             "bad receiver type");
-      ClassDecl = static_cast<ObjcInterfaceType*>(
-                    receiverType.getTypePtr())->getDecl();
-      // FIXME: consider using InstanceMethodPool, since it will be faster
-      // than the following method (which can do *many* linear searches). The
-      // idea is to add class info to InstanceMethodPool...
-      Method = ClassDecl->lookupInstanceMethod(Sel);
-    }
-    if (!Method) {
-      // If we have an implementation in scope, check "private" methods.
-      if (ClassDecl)
-        if (ObjcImplementationDecl *ImpDecl = 
-            ObjcImplementations[ClassDecl->getIdentifier()])
-          Method = ImpDecl->getInstanceMethod(Sel);
-	  // If we still haven't found a method, look in the global pool. This
-	  // behavior isn't very desirable, however we need it for GCC compatibility.
-	  if (!Method)
-	    Method = InstanceMethodPool[Sel].Method;
-    }
-    if (!Method) {
-      Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
-           SourceRange(lbrac, rbrac));
-      returnType = Context.getObjcIdType();
-    } else {
-      returnType = Method->getResultType();
-      if (Sel.getNumArgs())
-        if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
-          return true;
-    }
-  }
-  return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac, 
-                             ArgExprs, NumArgs);
-}

Added: cfe/trunk/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExprObjC.cpp?rev=45597&view=auto

==============================================================================
--- cfe/trunk/Sema/SemaExprObjC.cpp (added)
+++ cfe/trunk/Sema/SemaExprObjC.cpp Fri Jan  4 16:32:30 2008
@@ -0,0 +1,295 @@
+//===--- SemaExprObjC.cpp - Semantic Analysis for ObjC Expressions --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for Objective-C expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Sema.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+using namespace clang;
+
+Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, 
+                                              ExprTy **Strings,
+                                              unsigned NumStrings) {
+  SourceLocation AtLoc = AtLocs[0];
+  StringLiteral* S = static_cast<StringLiteral *>(Strings[0]);
+  if (NumStrings > 1) {
+    // Concatenate objc strings.
+    StringLiteral* ES = static_cast<StringLiteral *>(Strings[NumStrings-1]);
+    SourceLocation EndLoc = ES->getSourceRange().getEnd();
+    unsigned Length = 0;
+    for (unsigned i = 0; i < NumStrings; i++)
+      Length += static_cast<StringLiteral *>(Strings[i])->getByteLength();
+    char *strBuf = new char [Length];
+    char *p = strBuf;
+    bool isWide = false;
+    for (unsigned i = 0; i < NumStrings; i++) {
+      S = static_cast<StringLiteral *>(Strings[i]);
+      if (S->isWide())
+        isWide = true;
+      memcpy(p, S->getStrData(), S->getByteLength());
+      p += S->getByteLength();
+      delete S;
+    }
+    S = new StringLiteral(strBuf, Length,
+                          isWide, Context.getPointerType(Context.CharTy),
+                          AtLoc, EndLoc);
+  }
+  
+  if (CheckBuiltinCFStringArgument(S))
+    return true;
+  
+  if (Context.getObjcConstantStringInterface().isNull()) {
+    // Initialize the constant string interface lazily. This assumes
+    // the NSConstantString interface is seen in this translation unit.
+    IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
+    ScopedDecl *IFace = LookupScopedDecl(NSIdent, Decl::IDNS_Ordinary, 
+                                         SourceLocation(), TUScope);
+    ObjcInterfaceDecl *strIFace = dyn_cast_or_null<ObjcInterfaceDecl>(IFace);
+    if (!strIFace)
+      return Diag(S->getLocStart(), diag::err_undef_interface,
+                  NSIdent->getName());
+    Context.setObjcConstantStringInterface(strIFace);
+  }
+  QualType t = Context.getObjcConstantStringInterface();
+  t = Context.getPointerType(t);
+  return new ObjCStringLiteral(S, t, AtLoc);
+}
+
+Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
+                                                 SourceLocation EncodeLoc,
+                                                 SourceLocation LParenLoc,
+                                                 TypeTy *Ty,
+                                                 SourceLocation RParenLoc) {
+  QualType EncodedType = QualType::getFromOpaquePtr(Ty);
+
+  QualType t = Context.getPointerType(Context.CharTy);
+  return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
+}
+
+Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
+                                                   SourceLocation AtLoc,
+                                                   SourceLocation SelLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation RParenLoc) {
+  QualType t = Context.getObjcSelType();
+  return new ObjCSelectorExpr(t, Sel, AtLoc, RParenLoc);
+}
+
+Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
+                                                   SourceLocation AtLoc,
+                                                   SourceLocation ProtoLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation RParenLoc) {
+  ObjcProtocolDecl* PDecl = ObjcProtocols[ProtocolId];
+  if (!PDecl) {
+    Diag(ProtoLoc, diag::err_undeclared_protocol, ProtocolId->getName());
+    return true;
+  }
+  
+  QualType t = Context.getObjcProtoType();
+  if (t.isNull())
+    return true;
+  t = Context.getPointerType(t);
+  return new ObjCProtocolExpr(t, PDecl, AtLoc, RParenLoc);
+}
+
+bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
+                                     ObjcMethodDecl *Method) {
+  bool anyIncompatibleArgs = false;
+  
+  for (unsigned i = 0; i < NumArgs; i++) {
+    Expr *argExpr = Args[i];
+    assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
+    
+    QualType lhsType = Method->getParamDecl(i)->getType();
+    QualType rhsType = argExpr->getType();
+
+    // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8]. 
+    if (const ArrayType *ary = lhsType->getAsArrayType())
+      lhsType = Context.getPointerType(ary->getElementType());
+    else if (lhsType->isFunctionType())
+      lhsType = Context.getPointerType(lhsType);
+
+    AssignConvertType Result = CheckSingleAssignmentConstraints(lhsType,
+                                                                argExpr);
+    if (Args[i] != argExpr) // The expression was converted.
+      Args[i] = argExpr; // Make sure we store the converted expression.
+    
+    anyIncompatibleArgs |= 
+      DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
+                               argExpr, "sending");
+  }
+  return anyIncompatibleArgs;
+}
+
+// ActOnClassMessage - used for both unary and keyword messages.
+// ArgExprs is optional - if it is present, the number of expressions
+// is obtained from Sel.getNumArgs().
+Sema::ExprResult Sema::ActOnClassMessage(
+  Scope *S,
+  IdentifierInfo *receiverName, Selector Sel,
+  SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs)
+{
+  assert(receiverName && "missing receiver class name");
+
+  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
+  ObjcInterfaceDecl* ClassDecl = 0;
+  if (!strcmp(receiverName->getName(), "super") && CurMethodDecl) {
+    ClassDecl = CurMethodDecl->getClassInterface()->getSuperClass();
+    if (ClassDecl && CurMethodDecl->isInstance()) {
+      // Synthesize a cast to the super class. This hack allows us to loosely
+      // represent super without creating a special expression node.
+      IdentifierInfo &II = Context.Idents.get("self");
+      ExprResult ReceiverExpr = ActOnIdentifierExpr(S, lbrac, II, false);
+      QualType superTy = Context.getObjcInterfaceType(ClassDecl);
+      superTy = Context.getPointerType(superTy);
+      ReceiverExpr = ActOnCastExpr(SourceLocation(), superTy.getAsOpaquePtr(),
+                                   SourceLocation(), ReceiverExpr.Val);
+      // We are really in an instance method, redirect.
+      return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac,
+                                  Args, NumArgs);
+    }
+    // We are sending a message to 'super' within a class method. Do nothing,
+    // the receiver will pass through as 'super' (how convenient:-).
+  } else
+    ClassDecl = getObjCInterfaceDecl(receiverName);
+  
+  // FIXME: can ClassDecl ever be null?
+  ObjcMethodDecl *Method = ClassDecl->lookupClassMethod(Sel);
+  QualType returnType;
+  
+  // Before we give up, check if the selector is an instance method.
+  if (!Method)
+    Method = ClassDecl->lookupInstanceMethod(Sel);
+  if (!Method) {
+    Diag(lbrac, diag::warn_method_not_found, std::string("+"), Sel.getName(),
+         SourceRange(lbrac, rbrac));
+    returnType = Context.getObjcIdType();
+  } else {
+    returnType = Method->getResultType();
+    if (Sel.getNumArgs()) {
+      if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
+        return true;
+    }
+  }
+  return new ObjCMessageExpr(receiverName, Sel, returnType, Method,
+                             lbrac, rbrac, ArgExprs, NumArgs);
+}
+
+// ActOnInstanceMessage - used for both unary and keyword messages.
+// ArgExprs is optional - if it is present, the number of expressions
+// is obtained from Sel.getNumArgs().
+Sema::ExprResult Sema::ActOnInstanceMessage(
+  ExprTy *receiver, Selector Sel,
+  SourceLocation lbrac, SourceLocation rbrac, ExprTy **Args, unsigned NumArgs) 
+{
+  assert(receiver && "missing receiver expression");
+  
+  Expr **ArgExprs = reinterpret_cast<Expr **>(Args);
+  Expr *RExpr = static_cast<Expr *>(receiver);
+  QualType receiverType = RExpr->getType();
+  QualType returnType;
+  ObjcMethodDecl *Method = 0;
+  
+  if (receiverType == Context.getObjcIdType() ||
+      receiverType == Context.getObjcClassType()) {
+    Method = InstanceMethodPool[Sel].Method;
+	if (!Method)
+	  Method = FactoryMethodPool[Sel].Method;
+    if (!Method) {
+      Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
+           SourceRange(lbrac, rbrac));
+      returnType = Context.getObjcIdType();
+    } else {
+      returnType = Method->getResultType();
+      if (Sel.getNumArgs())
+        if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
+          return true;
+    }
+  } else {
+    bool receiverIsQualId = dyn_cast<ObjcQualifiedIdType>(receiverType) != 0;
+    // FIXME (snaroff): checking in this code from Patrick. Needs to be
+    // revisited. how do we get the ClassDecl from the receiver expression?
+    if (!receiverIsQualId)
+      while (receiverType->isPointerType()) {
+        PointerType *pointerType =
+          static_cast<PointerType*>(receiverType.getTypePtr());
+        receiverType = pointerType->getPointeeType();
+      }
+    ObjcInterfaceDecl* ClassDecl = 0;
+    if (ObjcQualifiedInterfaceType *QIT = 
+        dyn_cast<ObjcQualifiedInterfaceType>(receiverType)) {
+      ClassDecl = QIT->getDecl();
+      Method = ClassDecl->lookupInstanceMethod(Sel);
+      if (!Method) {
+        // search protocols
+        for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
+          ObjcProtocolDecl *PDecl = QIT->getProtocols(i);
+          if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
+            break;
+        }
+      }
+      if (!Method)
+        Diag(lbrac, diag::warn_method_not_found_in_protocol, 
+             std::string("-"), Sel.getName(),
+             SourceRange(lbrac, rbrac));
+    }
+    else if (ObjcQualifiedIdType *QIT = 
+             dyn_cast<ObjcQualifiedIdType>(receiverType)) {
+      // search protocols
+      for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
+        ObjcProtocolDecl *PDecl = QIT->getProtocols(i);
+        if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
+          break;
+      }
+      if (!Method)
+        Diag(lbrac, diag::warn_method_not_found_in_protocol, 
+             std::string("-"), Sel.getName(),
+             SourceRange(lbrac, rbrac));
+    }
+    else {
+      assert(ObjcInterfaceType::classof(receiverType.getTypePtr()) &&
+             "bad receiver type");
+      ClassDecl = static_cast<ObjcInterfaceType*>(
+                    receiverType.getTypePtr())->getDecl();
+      // FIXME: consider using InstanceMethodPool, since it will be faster
+      // than the following method (which can do *many* linear searches). The
+      // idea is to add class info to InstanceMethodPool...
+      Method = ClassDecl->lookupInstanceMethod(Sel);
+    }
+    if (!Method) {
+      // If we have an implementation in scope, check "private" methods.
+      if (ClassDecl)
+        if (ObjcImplementationDecl *ImpDecl = 
+            ObjcImplementations[ClassDecl->getIdentifier()])
+          Method = ImpDecl->getInstanceMethod(Sel);
+	  // If we still haven't found a method, look in the global pool. This
+	  // behavior isn't very desirable, however we need it for GCC
+          // compatibility.
+	  if (!Method)
+	    Method = InstanceMethodPool[Sel].Method;
+    }
+    if (!Method) {
+      Diag(lbrac, diag::warn_method_not_found, std::string("-"), Sel.getName(),
+           SourceRange(lbrac, rbrac));
+      returnType = Context.getObjcIdType();
+    } else {
+      returnType = Method->getResultType();
+      if (Sel.getNumArgs())
+        if (CheckMessageArgumentTypes(ArgExprs, Sel.getNumArgs(), Method))
+          return true;
+    }
+  }
+  return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac, 
+                             ArgExprs, NumArgs);
+}

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=45597&r1=45596&r2=45597&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Fri Jan  4 16:32:30 2008
@@ -68,6 +68,7 @@
 		DE46BF280AE0A82D00CC047C /* TargetInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE46BF270AE0A82D00CC047C /* TargetInfo.h */; };
 		DE4772FA0C10EAE5002239E8 /* CGStmt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4772F90C10EAE5002239E8 /* CGStmt.cpp */; };
 		DE4772FC0C10EAEC002239E8 /* CGExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */; };
+		DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */; };
 		DE5932D10AD60FF400BC794C /* clang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5932CD0AD60FF400BC794C /* clang.cpp */; };
 		DE5932D20AD60FF400BC794C /* clang.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE5932CE0AD60FF400BC794C /* clang.h */; };
 		DE5932D30AD60FF400BC794C /* PrintParserCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5932CF0AD60FF400BC794C /* PrintParserCallbacks.cpp */; };
@@ -299,6 +300,7 @@
 		DE46BF270AE0A82D00CC047C /* TargetInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TargetInfo.h; sourceTree = "<group>"; };
 		DE4772F90C10EAE5002239E8 /* CGStmt.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGStmt.cpp; path = CodeGen/CGStmt.cpp; sourceTree = "<group>"; };
 		DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CGExpr.cpp; path = CodeGen/CGExpr.cpp; sourceTree = "<group>"; };
+		DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SemaExprObjC.cpp; path = Sema/SemaExprObjC.cpp; sourceTree = "<group>"; };
 		DE53370B0CE2D96F00D9A028 /* RewriteRope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RewriteRope.h; path = clang/Rewrite/RewriteRope.h; sourceTree = "<group>"; };
 		DE5932CD0AD60FF400BC794C /* clang.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = clang.cpp; path = Driver/clang.cpp; sourceTree = "<group>"; };
 		DE5932CE0AD60FF400BC794C /* clang.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = clang.h; path = Driver/clang.h; sourceTree = "<group>"; };
@@ -547,6 +549,7 @@
 				DE704B250D0FBEBE009C7762 /* SemaDeclObjC.cpp */,
 				DE67E7100C020ED400F66BC5 /* SemaExpr.cpp */,
 				DE67E70E0C020ECF00F66BC5 /* SemaExprCXX.cpp */,
+				DE47999B0D2EBE1A00706D2D /* SemaExprObjC.cpp */,
 				DE67E70C0C020ECA00F66BC5 /* SemaStmt.cpp */,
 				DE67E70A0C020EC500F66BC5 /* SemaType.cpp */,
 			);
@@ -893,6 +896,7 @@
 				DE704DD20D1668A4009C7762 /* HeaderMap.cpp in Sources */,
 				35BB2D7D0D19951A00944DB5 /* TranslationUnit.cpp in Sources */,
 				35BB2D7F0D19954000944DB5 /* ASTConsumer.cpp in Sources */,
+				DE47999C0D2EBE1A00706D2D /* SemaExprObjC.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};





More information about the cfe-commits mailing list