зеркало из https://github.com/microsoft/clang-1.git
- 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). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42842 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a31f030d5c
Коммит
3b950178e2
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче