diff --git a/Driver/PrintParserCallbacks.cpp b/Driver/PrintParserCallbacks.cpp index c04dbdc3ace3ed092cba58e0186bd495b2adf1c6..126e8ed06ac9ed617191cfd8436d2c0dd5f256cf 100644 --- a/Driver/PrintParserCallbacks.cpp +++ b/Driver/PrintParserCallbacks.cpp @@ -338,31 +338,32 @@ namespace { llvm::cout << __FUNCTION__ << "\n"; return StmtEmpty(); } - virtual StmtResult ActOnGotoStmt(SourceLocation GotoLoc, - SourceLocation LabelLoc, - IdentifierInfo *LabelII) { + virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc, + SourceLocation LabelLoc, + IdentifierInfo *LabelII) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } - virtual StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, - SourceLocation StarLoc, - ExprTy *DestExp) { + virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, + SourceLocation StarLoc, + ExprArg DestExp) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } - virtual StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, - Scope *CurScope) { + virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc, + Scope *CurScope) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } - virtual StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope) { + virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc, + Scope *CurScope) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } - virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, - ExprTy *RetValExp) { + virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc, + ExprArg RetValExp) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple, diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 431be9c90e01da6a3cae51929c8a5785289ad850..f47021ac5fd3eb4eeadd284b38163c78d812558f 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -437,26 +437,27 @@ public: SourceLocation RParenLoc, StmtArg Body) { return StmtEmpty(); } - virtual StmtResult ActOnGotoStmt(SourceLocation GotoLoc, - SourceLocation LabelLoc, - IdentifierInfo *LabelII) { - return 0; + virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc, + SourceLocation LabelLoc, + IdentifierInfo *LabelII) { + return StmtEmpty(); } - virtual StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, - SourceLocation StarLoc, - ExprTy *DestExp) { - return 0; + virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, + SourceLocation StarLoc, + ExprArg DestExp) { + return StmtEmpty(); } - virtual StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, - Scope *CurScope) { - return 0; + virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc, + Scope *CurScope) { + return StmtEmpty(); } - virtual StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope) { - return 0; + virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc, + Scope *CurScope) { + return StmtEmpty(); } - virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, - ExprTy *RetValExp) { - return 0; + virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc, + ExprArg RetValExp) { + return StmtEmpty(); } virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple, diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 1bc78583edae3006011898e57f69c5ebed78596f..9ddd26a8b3ce89dd2c7d4871ad6a45e0cd9a19e7 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -972,7 +972,7 @@ Parser::OwningStmtResult Parser::ParseGotoStatement() { SkipUntil(tok::semi, false, true); return StmtError(); } - Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.release()); + Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, move_convert(R)); } else { Diag(Tok, diag::err_expected_ident); return StmtError(); @@ -989,7 +989,7 @@ Parser::OwningStmtResult Parser::ParseGotoStatement() { /// Parser::OwningStmtResult Parser::ParseContinueStatement() { SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'. - return Owned(Actions.ActOnContinueStmt(ContinueLoc, CurScope)); + return Actions.ActOnContinueStmt(ContinueLoc, CurScope); } /// ParseBreakStatement @@ -1000,7 +1000,7 @@ Parser::OwningStmtResult Parser::ParseContinueStatement() { /// Parser::OwningStmtResult Parser::ParseBreakStatement() { SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'. - return Owned(Actions.ActOnBreakStmt(BreakLoc, CurScope)); + return Actions.ActOnBreakStmt(BreakLoc, CurScope); } /// ParseReturnStatement @@ -1018,7 +1018,7 @@ Parser::OwningStmtResult Parser::ParseReturnStatement() { return StmtError(); } } - return Owned(Actions.ActOnReturnStmt(ReturnLoc, R.release())); + return Actions.ActOnReturnStmt(ReturnLoc, move_convert(R)); } /// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index b4da411cf64a5d92b18cd156dee4efd132057ca8..16c2f2f57efb93b66cf1d9e644dcbb56fcbc14a6 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -884,21 +884,23 @@ public: SourceLocation LParenLoc, StmtArg First, ExprArg Second, SourceLocation RParenLoc, StmtArg Body); - - virtual StmtResult ActOnGotoStmt(SourceLocation GotoLoc, - SourceLocation LabelLoc, - IdentifierInfo *LabelII); - virtual StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, - SourceLocation StarLoc, - ExprTy *DestExp); - virtual StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, - Scope *CurScope); - virtual StmtResult ActOnBreakStmt(SourceLocation GotoLoc, Scope *CurScope); - - virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, - ExprTy *RetValExp); - StmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp); - + + virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc, + SourceLocation LabelLoc, + IdentifierInfo *LabelII); + virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, + SourceLocation StarLoc, + ExprArg DestExp); + virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc, + Scope *CurScope); + virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc, + Scope *CurScope); + + virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc, + ExprArg RetValExp); + OwningStmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc, + Expr *RetValExp); + virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index cb467d41d8b46e80d32d80be79d87dc941009f1c..f143c5bfdccf469ff4d03c27804af4da1008787e 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -670,12 +670,12 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, ForLoc, RParenLoc)); } -Action::StmtResult +Action::OwningStmtResult Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, IdentifierInfo *LabelII) { // If we are in a block, reject all gotos for now. if (CurBlock) - return Diag(GotoLoc, diag::err_goto_in_block); + return StmtError(Diag(GotoLoc, diag::err_goto_in_block)); // Look up the record for this label identifier. LabelStmt *&LabelDecl = LabelMap[LabelII]; @@ -683,47 +683,45 @@ Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, // If we haven't seen this label yet, create a forward reference. if (LabelDecl == 0) LabelDecl = new LabelStmt(LabelLoc, LabelII, 0); - - return new GotoStmt(LabelDecl, GotoLoc, LabelLoc); + + return Owned(new GotoStmt(LabelDecl, GotoLoc, LabelLoc)); } -Action::StmtResult +Action::OwningStmtResult Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc,SourceLocation StarLoc, - ExprTy *DestExp) { + ExprArg DestExp) { // FIXME: Verify that the operand is convertible to void*. - - return new IndirectGotoStmt((Expr*)DestExp); + + return Owned(new IndirectGotoStmt((Expr*)DestExp.release())); } -Action::StmtResult +Action::OwningStmtResult Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) { Scope *S = CurScope->getContinueParent(); if (!S) { // C99 6.8.6.2p1: A break shall appear only in or as a loop body. - Diag(ContinueLoc, diag::err_continue_not_in_loop); - return true; + return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop)); } - - return new ContinueStmt(ContinueLoc); + + return Owned(new ContinueStmt(ContinueLoc)); } -Action::StmtResult +Action::OwningStmtResult Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) { Scope *S = CurScope->getBreakParent(); if (!S) { // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body. - Diag(BreakLoc, diag::err_break_not_in_loop_or_switch); - return true; + return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch)); } - - return new BreakStmt(BreakLoc); + + return Owned(new BreakStmt(BreakLoc)); } /// ActOnBlockReturnStmt - Utility routine to figure out block's return type. /// -Action::StmtResult +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) { @@ -734,9 +732,9 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { CurBlock->ReturnType = RetValExp->getType().getTypePtr(); } else CurBlock->ReturnType = Context.VoidTy.getTypePtr(); - return new ReturnStmt(ReturnLoc, RetValExp); + return Owned(new ReturnStmt(ReturnLoc, RetValExp)); } - + // Otherwise, verify that this result type matches the previous one. We are // pickier with blocks than for normal functions because we don't have GCC // compatibility to worry about here. @@ -746,38 +744,37 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { delete RetValExp; RetValExp = 0; } - return new ReturnStmt(ReturnLoc, RetValExp); + return Owned(new ReturnStmt(ReturnLoc, RetValExp)); } - - if (!RetValExp) { - Diag(ReturnLoc, diag::err_block_return_missing_expr); - return true; - } - + + if (!RetValExp) + return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr)); + // we have a non-void block with an expression, continue checking QualType RetValType = RetValExp->getType(); - + // For now, restrict multiple return statements in a block to have // strict compatible types only. QualType BlockQT = QualType(CurBlock->ReturnType, 0); if (Context.getCanonicalType(BlockQT).getTypePtr() != Context.getCanonicalType(RetValType).getTypePtr()) { + // FIXME: non-localizable string in diagnostic DiagnoseAssignmentResult(Incompatible, ReturnLoc, BlockQT, RetValType, RetValExp, "returning"); - return true; + return StmtError(); } - + if (RetValExp) CheckReturnStackAddr(RetValExp, BlockQT, ReturnLoc); - - return new ReturnStmt(ReturnLoc, (Expr*)RetValExp); + + return Owned(new ReturnStmt(ReturnLoc, RetValExp)); } -Action::StmtResult -Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) { - Expr *RetValExp = static_cast<Expr *>(rex); +Action::OwningStmtResult +Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) { + Expr *RetValExp = static_cast<Expr *>(rex.release()); if (CurBlock) return ActOnBlockReturnStmt(ReturnLoc, RetValExp); - + QualType FnRetType; if (FunctionDecl *FD = getCurFunctionDecl()) FnRetType = FD->getResultType(); @@ -789,7 +786,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) { unsigned D = diag::ext_return_has_expr; if (RetValExp->getType()->isVoidType()) D = diag::ext_return_has_void_expr; - + // return (some void expression); is legal in C++. if (D != diag::ext_return_has_void_expr || !getLangOptions().CPlusPlus) { @@ -799,9 +796,9 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) { << RetValExp->getSourceRange(); } } - return new ReturnStmt(ReturnLoc, RetValExp); + return Owned(new ReturnStmt(ReturnLoc, RetValExp)); } - + if (!RetValExp) { unsigned DiagID = diag::warn_return_missing_expr; // C90 6.6.6.4p4 // C99 6.8.6.4p1 (ext_ since GCC warns) @@ -811,27 +808,27 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) { Diag(ReturnLoc, DiagID) << FD->getIdentifier() << 0/*fn*/; else Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/; - return new ReturnStmt(ReturnLoc, (Expr*)0); + return Owned(new ReturnStmt(ReturnLoc, (Expr*)0)); } - + if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) { // we have a non-void function with an expression, continue checking QualType RetValType = RetValExp->getType(); - + // C99 6.8.6.4p3(136): The return statement is not an assignment. The // overlap restriction of subclause 6.5.16.1 does not apply to the case of - // function return. - + // function return. + // In C++ the return statement is handled via a copy initialization. - // the C version of which boils down to - // CheckSingleAssignmentConstraints. + // the C version of which boils down to CheckSingleAssignmentConstraints. + // FIXME: Leaks RetValExp. if (PerformCopyInitialization(RetValExp, FnRetType, "returning")) - return true; - + return StmtError(); + if (RetValExp) CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc); } - return new ReturnStmt(ReturnLoc, (Expr*)RetValExp); + return Owned(new ReturnStmt(ReturnLoc, RetValExp)); } Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,