]> granicus.if.org Git - clang/commitdiff
Provide rewriting suppport for use of __typeof__
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 10 Feb 2010 18:54:22 +0000 (18:54 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 10 Feb 2010 18:54:22 +0000 (18:54 +0000)
in a declaration statement. Fixes radar 7628153.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95788 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Frontend/RewriteObjC.cpp
test/Rewriter/rewrite-typeof.mm

index f5ff5bc3f228809b0a4a424d195331cb48316a4e..3ee266a110fc11a025fb981bf3def31e9d99f0b1 100644 (file)
@@ -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<Type>();
+  if (!isa<TypeOfExprType>(TypePtr))
+    return;
+  while (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    TypePtr = QT->getAs<Type>();
+  }
+  // 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<CStyleCastExpr>(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<VarDecl>(SD)) 
+        if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
           if (VD->hasAttr<BlocksAttr>()) {
             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<TypedefDecl>(SD)) {
         if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
index 9c282b298d453b30a662f58be4c34b12514774b9..b859ac3d684c78e790be0b33e2411bb295ed2113 100644 (file)
@@ -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;