diff options
author | John McCall <rjmccall@apple.com> | 2011-06-15 23:02:42 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-06-15 23:02:42 +0000 |
commit | f85e193739c953358c865005855253af4f68a497 (patch) | |
tree | e242284beb7fd2b88a2f3ce08644585497d5910d /lib/Sema/SemaStmt.cpp | |
parent | 204e13395d83524e9a557c3f3fd6df2e2f353b9d (diff) |
Automatic Reference Counting.
Language-design credit goes to a lot of people, but I particularly want
to single out Blaine Garst and Patrick Beard for their contributions.
Compiler implementation credit goes to Argyrios, Doug, Fariborz, and myself,
in no particular order.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133103 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index d7c0a543ee..18e5f7e3a4 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -66,8 +66,29 @@ void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) { // If we have an invalid decl, just return. if (DG.isNull() || !DG.isSingleDecl()) return; + VarDecl *var = cast<VarDecl>(DG.getSingleDecl()); + // suppress any potential 'unused variable' warning. - DG.getSingleDecl()->setUsed(); + var->setUsed(); + + // In ARC, we don't want to lifetime for the iteration + // variable of a fast enumeration loop. Rather than actually + // trying to catch that during declaration processing, we + // remove the consequences here. + if (getLangOptions().ObjCAutoRefCount) { + SplitQualType split = var->getType().split(); + + // Inferred lifetime will show up as a local qualifier because + // explicit lifetime would have shown up as an AttributedType + // instead. + if (split.second.hasObjCLifetime()) { + // Change the qualification to 'const __unsafe_unretained'. + split.second.setObjCLifetime(Qualifiers::OCL_ExplicitNone); + split.second.addConst(); + var->setType(Context.getQualifiedType(split.first, split.second)); + var->setInit(0); + } + } } void Sema::DiagnoseUnusedExprResult(const Stmt *S) { @@ -114,6 +135,10 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { } } } else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) { + if (getLangOptions().ObjCAutoRefCount && ME->isDelegateInitCall()) { + Diag(Loc, diag::err_arc_unused_init_message) << R1; + return; + } const ObjCMethodDecl *MD = ME->getMethodDecl(); if (MD && MD->getAttr<WarnUnusedResultAttr>()) { Diag(Loc, diag::warn_unused_call) << R1 << R2 << "warn_unused_result"; @@ -951,14 +976,13 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, return StmtError(Diag((*DS->decl_begin())->getLocation(), diag::err_toomany_element_decls)); - Decl *D = DS->getSingleDecl(); - FirstType = cast<ValueDecl>(D)->getType(); + VarDecl *D = cast<VarDecl>(DS->getSingleDecl()); + FirstType = D->getType(); // C99 6.8.5p3: The declaration part of a 'for' statement shall only // declare identifiers for objects having storage class 'auto' or // 'register'. - VarDecl *VD = cast<VarDecl>(D); - if (VD->isLocalVarDecl() && !VD->hasLocalStorage()) - return StmtError(Diag(VD->getLocation(), + if (!D->hasLocalStorage()) + return StmtError(Diag(D->getLocation(), diag::err_non_variable_decl_in_for)); } else { Expr *FirstE = cast<Expr>(First); @@ -1047,6 +1071,13 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, Decl->setTypeSourceInfo(InitTSI); Decl->setType(InitTSI->getType()); + // In ARC, infer lifetime. + // FIXME: ARC may want to turn this into 'const __unsafe_unretained' if + // we're doing the equivalent of fast iteration. + if (SemaRef.getLangOptions().ObjCAutoRefCount && + SemaRef.inferObjCARCLifetime(Decl)) + Decl->setInvalidDecl(); + SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false, /*TypeMayContainAuto=*/false); SemaRef.FinalizeDeclaration(Decl); @@ -1797,7 +1828,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { if (getLangOptions().CPlusPlus && FnRetType->isRecordType() && !CurContext->isDependentContext()) FunctionScopes.back()->Returns.push_back(Result); - + return Owned(Result); } @@ -2179,6 +2210,12 @@ Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, HandlerBlock)); } +StmtResult +Sema::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) { + getCurFunction()->setHasBranchProtectedScope(); + return Owned(new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body)); +} + namespace { class TypeWithHandler { |