diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index f5ff5bc3f2..3ee266a110 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -263,6 +263,7 @@ namespace { void RewriteFunctionDecl(FunctionDecl *FD); void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); + void RewriteTypeOfDecl(VarDecl *VD); void RewriteObjCQualifiedInterfaceTypes(Expr *E); bool needToScanForQualifiers(QualType T); ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr); @@ -2143,6 +2144,44 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) { } } +void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) { + QualType QT = ND->getType(); + const Type* TypePtr = QT->getAs(); + if (!isa(TypePtr)) + return; + while (isa(TypePtr)) { + const TypeOfExprType *TypeOfExprTypePtr = cast(TypePtr); + QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType(); + TypePtr = QT->getAs(); + } + // FIXME. This will not work for multiple declarators; as in: + // __typeof__(a) b,c,d; + std::string TypeAsString(QT.getAsString()); + SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); + const char *startBuf = SM->getCharacterData(DeclLoc); + if (ND->getInit()) { + std::string Name(ND->getNameAsString()); + TypeAsString += " " + Name + " = "; + Expr *E = ND->getInit(); + SourceLocation startLoc; + if (const CStyleCastExpr *ECE = dyn_cast(E)) + startLoc = ECE->getLParenLoc(); + else + startLoc = E->getLocStart(); + startLoc = SM->getInstantiationLoc(startLoc); + const char *endBuf = SM->getCharacterData(startLoc); + ReplaceText(DeclLoc, endBuf-startBuf-1, + TypeAsString.c_str(), TypeAsString.size()); + } + else { + SourceLocation X = ND->getLocEnd(); + X = SM->getInstantiationLoc(X); + const char *endBuf = SM->getCharacterData(X); + ReplaceText(DeclLoc, endBuf-startBuf-1, + TypeAsString.c_str(), TypeAsString.size()); + } +} + // SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str); void RewriteObjC::SynthSelGetUidFunctionDecl() { IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName"); @@ -5059,7 +5098,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { RewriteBlockPointerDecl(ND); else if (ND->getType()->isFunctionPointerType()) CheckFunctionPointerDecl(ND->getType(), ND); - if (VarDecl *VD = dyn_cast(SD)) + if (VarDecl *VD = dyn_cast(SD)) { if (VD->hasAttr()) { static unsigned uniqueByrefDeclCount = 0; assert(!BlockByRefDeclNo.count(ND) && @@ -5067,6 +5106,9 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { BlockByRefDeclNo[ND] = uniqueByrefDeclCount++; RewriteByRefVar(VD); } + else + RewriteTypeOfDecl(VD); + } } if (TypedefDecl *TD = dyn_cast(SD)) { if (isTopLevelBlockPointerType(TD->getUnderlyingType())) diff --git a/test/Rewriter/rewrite-typeof.mm b/test/Rewriter/rewrite-typeof.mm index 9c282b298d..b859ac3d68 100644 --- a/test/Rewriter/rewrite-typeof.mm +++ b/test/Rewriter/rewrite-typeof.mm @@ -21,3 +21,19 @@ int main() { // CHECK-LP: ((void (^)(void))_Block_copy((const void *)(b))) +// radar 7628153 +void f() { + int a; + __typeof__(a) aVal = a; + char *a1t = (char *)@encode(__typeof__(a)); + __typeof__(aVal) bVal; + char *a2t = (char *)@encode(__typeof__(bVal)); + __typeof__(bVal) cVal = bVal; + char *a3t = (char *)@encode(__typeof__(cVal)); + +} + + +// CHECK-LP: int aVal = a; + +// CHECK-LP: int bVal;