[cfe-commits] r73795 - in /cfe/trunk: include/clang/AST/Expr.h lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaStmt.cpp test/Sema/block-return.c

Fariborz Jahanian fjahanian at apple.com
Fri Jun 19 16:37:08 PDT 2009


Author: fjahanian
Date: Fri Jun 19 18:37:08 2009
New Revision: 73795

URL: http://llvm.org/viewvc/llvm-project?rev=73795&view=rev
Log:
Use QualType to represent block's implicit return type as
to not lose its 'const/volatile' qualifier.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/Sema/block-return.c

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=73795&r1=73794&r2=73795&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Jun 19 18:37:08 2009
@@ -2463,10 +2463,13 @@
 class BlockDeclRefExpr : public Expr {
   ValueDecl *D; 
   SourceLocation Loc;
-  bool IsByRef;
+  bool IsByRef : 1;
+  bool ConstQualAdded : 1;
 public:
-  BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef) : 
-       Expr(BlockDeclRefExprClass, t), D(d), Loc(l), IsByRef(ByRef) {}
+  BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef, 
+                   bool constAdded = false) :
+       Expr(BlockDeclRefExprClass, t), D(d), Loc(l), IsByRef(ByRef),
+                                       ConstQualAdded(constAdded) {}
 
   // \brief Build an empty reference to a declared variable in a
   // block.
@@ -2484,6 +2487,9 @@
   
   bool isByRef() const { return IsByRef; }
   void setByRef(bool BR) { IsByRef = BR; }
+  
+  bool isConstQualAdded() const { return ConstQualAdded; }
+  void setConstQualAdded(bool C) { ConstQualAdded = C; }
 
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == BlockDeclRefExprClass; 

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=73795&r1=73794&r2=73795&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Jun 19 18:37:08 2009
@@ -102,7 +102,7 @@
   
   /// ReturnType - This will get set to block result type, by looking at
   /// return types, if any, in the block body.
-  Type *ReturnType;
+  QualType ReturnType;
   
   /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
   /// it (which acts like the label decl in some ways).  Forward referenced

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=73795&r1=73794&r2=73795&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jun 19 18:37:08 2009
@@ -1129,10 +1129,13 @@
     // The BlocksAttr indicates the variable is bound by-reference.
     if (VD->getAttr<BlocksAttr>(Context))
       return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true));
-
+    // This is to record that a 'const' was actually synthesize and added.
+    bool constAdded = !ExprTy.isConstQualified();
     // Variable will be bound by-copy, make it const within the closure.
+    
     ExprTy.addConst();
-    return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false));
+    return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false, 
+                                                constAdded));
   }
   // If this reference is not in a block or if the referenced variable is
   // within the block, create a normal DeclRefExpr.
@@ -5111,7 +5114,7 @@
   BSI->PrevBlockInfo = CurBlock;
   CurBlock = BSI;
 
-  BSI->ReturnType = 0;
+  BSI->ReturnType = QualType();
   BSI->TheScope = BlockScope;
   BSI->hasBlockDeclRefExprs = false;
   BSI->SavedFunctionNeedsScopeChecking = CurFunctionNeedsScopeChecking;
@@ -5206,7 +5209,7 @@
     Diag(ParamInfo.getSourceRange().getBegin(),
          diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy;
   } else if (!RetTy->isDependentType())
-    CurBlock->ReturnType = RetTy.getTypePtr();
+    CurBlock->ReturnType = RetTy;
 }
 
 /// ActOnBlockError - If there is an error parsing a block, this callback
@@ -5240,8 +5243,8 @@
   CurBlock = CurBlock->PrevBlockInfo;
 
   QualType RetTy = Context.VoidTy;
-  if (BSI->ReturnType)
-    RetTy = QualType(BSI->ReturnType, 0);
+  if (!BSI->ReturnType.isNull())
+    RetTy = BSI->ReturnType;
 
   llvm::SmallVector<QualType, 8> ArgTypes;
   for (unsigned i = 0, e = BSI->Params.size(); i != e; ++i)

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=73795&r1=73794&r2=73795&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Jun 19 18:37:08 2009
@@ -748,16 +748,23 @@
 Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   // If this is the first return we've seen in the block, infer the type of
   // the block from it.
-  if (CurBlock->ReturnType == 0) {
+  if (CurBlock->ReturnType.isNull()) {
     if (RetValExp) {
       // Don't call UsualUnaryConversions(), since we don't want to do
       // integer promotions here.
       DefaultFunctionArrayConversion(RetValExp);
-      CurBlock->ReturnType = RetValExp->getType().getTypePtr();
+      CurBlock->ReturnType = RetValExp->getType();
+      if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(RetValExp)) {
+        // We have to remove a 'const' added to copied-in variable which was
+        // part of the implementation spec. and not the actual qualifier for
+        // the variable.
+        if (CDRE->isConstQualAdded())
+           CurBlock->ReturnType.removeConst();
+      }
     } else
-      CurBlock->ReturnType = Context.VoidTy.getTypePtr();
+      CurBlock->ReturnType = Context.VoidTy;
   }
-  QualType FnRetType = QualType(CurBlock->ReturnType, 0);
+  QualType FnRetType = CurBlock->ReturnType;
 
   if (CurBlock->TheDecl->hasAttr<NoReturnAttr>(Context)) {
     Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)

Modified: cfe/trunk/test/Sema/block-return.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-return.c?rev=73795&r1=73794&r2=73795&view=diff

==============================================================================
--- cfe/trunk/test/Sema/block-return.c (original)
+++ cfe/trunk/test/Sema/block-return.c Fri Jun 19 18:37:08 2009
@@ -102,3 +102,27 @@
   b(1);
   int (^c)(void) __attribute__((noreturn)) = ^ __attribute__((noreturn)) { return 100; }; // expected-error {{block declared 'noreturn' should not return}}
 }
+
+
+void foo7()
+{
+ const int (^BB) (void) = ^{ const int i = 1; return i; }; // OK 
+ const int (^CC) (void)  = ^const int{ const int i = 1; return i; }; // OK
+
+  int i;
+  int (^FF) (void)  = ^{ return i; }; // OK
+  int (^EE) (void)  = ^{ return i+1; }; // OK
+
+  __block int j;
+  int (^JJ) (void)  = ^{ return j; }; // OK
+  int (^KK) (void)  = ^{ return j+1; }; // OK
+
+  __block const int k;
+  const int cint = 100;
+
+  int (^MM) (void)  = ^{ return k; }; // expected-error {{incompatible block pointer types initializing 'int const (^)(void)', expected 'int (^)(void)'}}
+  int (^NN) (void)  = ^{ return cint; }; // expected-error {{incompatible block pointer types initializing 'int const (^)(void)', expected 'int (^)(void)'}}
+
+}
+
+





More information about the cfe-commits mailing list