- Make sure default return/argument types (for methods) default to "id".

- Cache the "id" type in Sema...initialize ObjcIdType and TUScope (oops).
- Fix ActOnInstanceMessage to allow for "id" type receivers...still work to do (next).

llvm-svn: 42842
This commit is contained in:
Steve Naroff 2007-10-10 21:53:07 +00:00
parent d2b8ce4259
commit 7f549f1897
5 changed files with 53 additions and 23 deletions

View File

@ -23,6 +23,20 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
TUScope = S;
}
QualType Sema::GetObjcIdType() {
assert(TUScope && "GetObjcIdType(): Top-level scope is null");
if (ObjcIdType.isNull()) {
IdentifierInfo *IdIdent = &Context.Idents.get("id");
ScopedDecl *IdDecl = LookupScopedDecl(IdIdent, Decl::IDNS_Ordinary,
SourceLocation(), TUScope);
TypedefDecl *IdTypedef = dyn_cast_or_null<TypedefDecl>(IdDecl);
assert(IdTypedef && "GetObjcIdType(): Couldn't find 'id' type");
ObjcIdType = Context.getTypedefType(IdTypedef);
}
return ObjcIdType;
}
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup)
: PP(pp), Context(ctxt), CurFunctionDecl(0), LastInGroupList(prevInGroup) {
@ -40,6 +54,9 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup)
KnownFunctionIDs[ id_vfprintf ] = &IT.get("vfprintf");
KnownFunctionIDs[ id_vsprintf ] = &IT.get("vsprintf");
KnownFunctionIDs[ id_vprintf ] = &IT.get("vprintf");
TUScope = 0;
ObjcIdType = QualType();
}
void Sema::DeleteExpr(ExprTy *E) {

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "clang/AST/Type.h"
#include <vector>
#include <string>
@ -117,6 +118,9 @@ class Sema : public Action {
/// to lookup file scope declarations in the "ordinary" C decl namespace.
/// For example, user-defined classes, built-in "id" type, etc.
Scope *TUScope;
/// ObjcIdType - built-in type for "id".
QualType ObjcIdType;
public:
Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup);
@ -251,6 +255,9 @@ private:
/// true, or false, accordingly.
bool MatchTwoMethodDeclarations(const ObjcMethodDecl *Method,
const ObjcMethodDecl *PrevMethod);
/// GetObjcIdType - Getter for the build-in "id" type.
QualType GetObjcIdType();
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks: SemaStmt.cpp.

View File

@ -1774,23 +1774,23 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(SourceLocation MethodLoc,
for (unsigned i = 0; i < Sel.getNumArgs(); i++) {
// FIXME: arg->AttrList must be stored too!
QualType argType;
if (ArgTypes[i])
argType = QualType::getFromOpaquePtr(ArgTypes[i]);
else
argType = GetObjcIdType();
ParmVarDecl* Param = new ParmVarDecl(SourceLocation(/*FIXME*/), ArgNames[i],
QualType::getFromOpaquePtr(ArgTypes[i]),
VarDecl::None, 0);
argType, VarDecl::None, 0);
Params.push_back(Param);
}
QualType resultDeclType;
if (ReturnType)
resultDeclType = QualType::getFromOpaquePtr(ReturnType);
else { // get the type for "id".
IdentifierInfo *IdIdent = &Context.Idents.get("id");
ScopedDecl *IdDecl = LookupScopedDecl(IdIdent, Decl::IDNS_Ordinary,
SourceLocation(), TUScope);
TypedefDecl *IdTypedef = dyn_cast_or_null<TypedefDecl>(IdDecl);
assert(IdTypedef && "ActOnMethodDeclaration(): Couldn't find 'id' type");
resultDeclType = IdTypedef->getUnderlyingType();
}
else // get the type for "id".
resultDeclType = GetObjcIdType();
ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, Sel,
resultDeclType, 0, -1, AttrList,
MethodType == tok::minus,

View File

@ -1900,19 +1900,25 @@ 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();
QualType returnType;
if (receiverType == GetObjcIdType()) {
returnType = Context.IntTy; // FIXME:just a placeholder
} else {
// FIXME (snaroff): checking in this code from Patrick. Needs to be revisited.
// how do we get the ClassDecl from the receiver expression?
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");
returnType = Method->getMethodType();
}
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, returnType, lbrac, rbrac, ArgExprs);
}

View File

@ -37,7 +37,7 @@ struct D {
@end
int main() {
// id xx = [[Car alloc] init];
id xx = [[Car alloc] init];
// [xx method:4];
[xx method:4];
}