[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