[cfe-commits] r154939 - in /cfe/trunk: lib/Rewrite/RewriteModernObjC.cpp test/Rewriter/rewrite-modern-extern-c-func-decl.mm

Fariborz Jahanian fjahanian at apple.com
Tue Apr 17 11:40:53 PDT 2012


Author: fjahanian
Date: Tue Apr 17 13:40:53 2012
New Revision: 154939

URL: http://llvm.org/viewvc/llvm-project?rev=154939&view=rev
Log:
objective-c modern translation. Correct rewriting of
block meta-data of block literals declared inside
of extern "C" functions.
// rdar://1131490

Added:
    cfe/trunk/test/Rewriter/rewrite-modern-extern-c-func-decl.mm
Modified:
    cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp

Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=154939&r1=154938&r2=154939&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Tue Apr 17 13:40:53 2012
@@ -304,7 +304,6 @@
     void RewriteFunctionDecl(FunctionDecl *FD);
     void RewriteBlockPointerType(std::string& Str, QualType Type);
     void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
-    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
     void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
     void RewriteTypeOfDecl(VarDecl *VD);
     void RewriteObjCQualifiedInterfaceTypes(Expr *E);
@@ -2246,30 +2245,6 @@
   }
 }
 
-
-void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
-  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
-  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
-  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
-  if (!proto)
-    return;
-  QualType Type = proto->getResultType();
-  std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
-  FdStr += " ";
-  FdStr += FD->getName();
-  FdStr +=  "(";
-  unsigned numArgs = proto->getNumArgs();
-  for (unsigned i = 0; i < numArgs; i++) {
-    QualType ArgType = proto->getArgType(i);
-    RewriteBlockPointerType(FdStr, ArgType);
-    if (i+1 < numArgs)
-      FdStr += ", ";
-  }
-  FdStr +=  ");\n";
-  InsertText(FunLocStart, FdStr);
-  CurFunctionDeclToDeclareForBlock = 0;
-}
-
 // SynthSuperContructorFunctionDecl - id __rw_objc_super(id obj, id super);
 void RewriteModernObjC::SynthSuperContructorFunctionDecl() {
   if (SuperContructorFunctionDecl)
@@ -4008,11 +3983,25 @@
   return S;
 }
 
+/// getFunctionSourceLocation - returns start location of a function
+/// definition. Complication arises when function has declared as
+/// extern "C" or extern "C" {...}
+static SourceLocation getFunctionSourceLocation (FunctionDecl *FD) {
+  if (!FD->isExternC() || FD->isMain())
+    return FD->getTypeSpecStartLoc();
+  const DeclContext *DC = FD->getDeclContext();
+  if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
+    SourceLocation BodyRBrace = LSD->getRBraceLoc();
+    // if it is extern "C" {...}, return function decl's own location.
+    if (BodyRBrace.isValid())
+      return FD->getTypeSpecStartLoc();
+    return LSD->getExternLoc();
+  }
+  return FD->getTypeSpecStartLoc();
+}
+
 void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
                                           StringRef FunName) {
-  // Insert declaration for the function in which block literal is used.
-  if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
-    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
   bool RewriteSC = (GlobalVarDecl &&
                     !Blocks.empty() &&
                     GlobalVarDecl->getStorageClass() == SC_Static &&
@@ -4121,7 +4110,7 @@
 }
 
 void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
-  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  SourceLocation FunLocStart = getFunctionSourceLocation(FD);
   StringRef FuncName = FD->getName();
 
   SynthesizeBlockLiterals(FunLocStart, FuncName);
@@ -4731,10 +4720,6 @@
 ///
 ///
 void RewriteModernObjC::RewriteByRefVar(VarDecl *ND) {
-  // Insert declaration for the function in which block literal is
-  // used.
-  if (CurFunctionDeclToDeclareForBlock)
-    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
   int flag = 0;
   int isa = 0;
   SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
@@ -4773,7 +4758,7 @@
   // Insert this type in global scope. It is needed by helper function.
   SourceLocation FunLocStart;
   if (CurFunctionDef)
-     FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
+     FunLocStart = getFunctionSourceLocation(CurFunctionDef);
   else {
     assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
     FunLocStart = CurMethodDef->getLocStart();

Added: cfe/trunk/test/Rewriter/rewrite-modern-extern-c-func-decl.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-modern-extern-c-func-decl.mm?rev=154939&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-modern-extern-c-func-decl.mm (added)
+++ cfe/trunk/test/Rewriter/rewrite-modern-extern-c-func-decl.mm Tue Apr 17 13:40:53 2012
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o %t-rw.cpp %s
+// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -Wno-attributes -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// rdar://11131490
+
+extern "C" __declspec(dllexport) void BreakTheRewriter(void) {
+        __block int aBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                aBlockVariable = 42;
+        };
+        aBlockVariable++;
+        void (^bBlocks)(void) = ^ {
+                aBlockVariable = 43;
+        };
+        void (^c)(void) = ^ {
+                aBlockVariable = 44;
+        };
+
+}
+__declspec(dllexport) extern "C" void AnotherBreakTheRewriter(int *p1, double d) {
+
+        __block int bBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                bBlockVariable = 42;
+        };
+        bBlockVariable++;
+        void (^bBlocks)(void) = ^ {
+                bBlockVariable = 43;
+        };
+        void (^c)(void) = ^ {
+                bBlockVariable = 44;
+        };
+
+}
+
+int
+
+__declspec (dllexport)
+
+main (int argc, char *argv[])
+{
+        __block int bBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                bBlockVariable = 42;
+        };
+}





More information about the cfe-commits mailing list