- Add ObjcInterfaceDecl::lookupInstanceMethod(), lookupClassMethod().
- Add ObjcMessageExpr::getSelector(), getClassName(). - Change Sema::getObjCInterfaceDecl() to simply take an IdentifierInfo (no Scope needed). - Remove FIXME for printing ObjCMessageExpr's. llvm-svn: 42543
This commit is contained in:
parent
88ea107fdb
commit
c6814ea670
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 << "]";
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -737,7 +737,6 @@
|
|||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
|
||||
compatibilityVersion = "Xcode 2.4";
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
|
||||
projectDirPath = "";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(); }
|
||||
|
||||
|
|
Loading…
Reference in New Issue