[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