diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 15 |
3 files changed, 21 insertions, 11 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index bb9fa4b7988..23bab230097 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -102,7 +102,7 @@ struct BlockSemaInfo { /// 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 diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7e827834047..de568193119 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1129,10 +1129,13 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // 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 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *BlockScope) { BSI->PrevBlockInfo = CurBlock; CurBlock = BSI; - BSI->ReturnType = 0; + BSI->ReturnType = QualType(); BSI->TheScope = BlockScope; BSI->hasBlockDeclRefExprs = false; BSI->SavedFunctionNeedsScopeChecking = CurFunctionNeedsScopeChecking; @@ -5206,7 +5209,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { 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 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, 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) diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 7797e270f5f..914839cbf79 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -748,16 +748,23 @@ Action::OwningStmtResult 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) |