зеркало из https://github.com/microsoft/clang-1.git
Switch 'super' from being a weird cast thing to being a predefined expr node.
Patch by David Chisnall with objc rewriter and stmtdumper updates from me. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@52580 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
cf719b7829
Коммит
0d17f6f7b1
|
@ -1848,31 +1848,14 @@ ObjCInterfaceDecl *RewriteObjC::isSuperReceiver(Expr *recExpr) {
|
|||
// check if we are sending a message to 'super'
|
||||
if (!CurMethodDecl || !CurMethodDecl->isInstance()) return 0;
|
||||
|
||||
CastExpr *CE = dyn_cast<CastExpr>(recExpr);
|
||||
if (!CE) return 0;
|
||||
|
||||
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr());
|
||||
if (!DRE) return 0;
|
||||
|
||||
ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl());
|
||||
if (!PVD) return 0;
|
||||
|
||||
if (strcmp(PVD->getName(), "self") != 0)
|
||||
return 0;
|
||||
|
||||
// is this id<P1..> type?
|
||||
if (CE->getType()->isObjCQualifiedIdType())
|
||||
return 0;
|
||||
const PointerType *PT = CE->getType()->getAsPointerType();
|
||||
if (!PT) return 0;
|
||||
|
||||
ObjCInterfaceType *IT = dyn_cast<ObjCInterfaceType>(PT->getPointeeType());
|
||||
if (!IT) return 0;
|
||||
|
||||
if (IT->getDecl() != CurMethodDecl->getClassInterface()->getSuperClass())
|
||||
return 0;
|
||||
|
||||
return IT->getDecl();
|
||||
if (PreDefinedExpr *PDE = dyn_cast<PreDefinedExpr>(recExpr))
|
||||
if (PDE->getIdentType() == PreDefinedExpr::ObjCSuper) {
|
||||
const PointerType *PT = PDE->getType()->getAsPointerType();
|
||||
assert(PT);
|
||||
ObjCInterfaceType *IT = cast<ObjCInterfaceType>(PT->getPointeeType());
|
||||
return IT->getDecl();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
|
||||
|
|
|
@ -222,7 +222,10 @@ public:
|
|||
enum IdentType {
|
||||
Func,
|
||||
Function,
|
||||
PrettyFunction
|
||||
PrettyFunction,
|
||||
ObjCSelf, // self
|
||||
ObjCCmd, // _cmd
|
||||
ObjCSuper // super
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -311,17 +311,13 @@ void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
|
|||
void StmtDumper::VisitPreDefinedExpr(PreDefinedExpr *Node) {
|
||||
DumpExpr(Node);
|
||||
switch (Node->getIdentType()) {
|
||||
default:
|
||||
assert(0 && "unknown case");
|
||||
case PreDefinedExpr::Func:
|
||||
fprintf(F, " __func__");
|
||||
break;
|
||||
case PreDefinedExpr::Function:
|
||||
fprintf(F, " __FUNCTION__");
|
||||
break;
|
||||
case PreDefinedExpr::PrettyFunction:
|
||||
fprintf(F, " __PRETTY_FUNCTION__");
|
||||
break;
|
||||
default: assert(0 && "unknown case");
|
||||
case PreDefinedExpr::Func: fprintf(F, " __func__"); break;
|
||||
case PreDefinedExpr::Function: fprintf(F, " __FUNCTION__"); break;
|
||||
case PreDefinedExpr::PrettyFunction: fprintf(F, " __PRETTY_FUNCTION__");break;
|
||||
case PreDefinedExpr::ObjCSelf: fprintf(F, "self"); break;
|
||||
case PreDefinedExpr::ObjCCmd: fprintf(F, "_cmd"); break;
|
||||
case PreDefinedExpr::ObjCSuper: fprintf(F, "super"); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -509,6 +509,9 @@ void StmtPrinter::VisitPreDefinedExpr(PreDefinedExpr *Node) {
|
|||
case PreDefinedExpr::PrettyFunction:
|
||||
OS << "__PRETTY_FUNCTION__";
|
||||
break;
|
||||
case PreDefinedExpr::ObjCSuper:
|
||||
OS << "super";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -149,14 +149,10 @@ Sema::ExprResult Sema::ActOnClassMessage(
|
|||
return Diag(lbrac, diag::error_no_super_class,
|
||||
CurMethodDecl->getClassInterface()->getName());
|
||||
if (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);
|
||||
ExprResult ReceiverExpr = new PreDefinedExpr(SourceLocation(), superTy,
|
||||
PreDefinedExpr::ObjCSuper);
|
||||
// We are really in an instance method, redirect.
|
||||
return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac,
|
||||
Args, NumArgs);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: clang -rewrite-objc %s -o=-
|
||||
// RUN: clang -rewrite-objc %s -o - | grep objc_msgSendSuper | grep MainMethod
|
||||
|
||||
@interface SUPER
|
||||
- (int) MainMethod;
|
||||
|
|
Загрузка…
Ссылка в новой задаче