From: Sebastian Redl Date: Sun, 11 Jan 2009 00:38:46 +0000 (+0000) Subject: Convert some more actions to smart pointers. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=de307473448fb3cebcb4c10090728300b53bca03;p=clang Convert some more actions to smart pointers. No performance regression in my basic test. Also fixed a type error in ActOnFinishSwitchStmt's arguments (body is a stmt). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62032 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/PrintParserCallbacks.cpp b/Driver/PrintParserCallbacks.cpp index c5d754e73d..7999da01d9 100644 --- a/Driver/PrintParserCallbacks.cpp +++ b/Driver/PrintParserCallbacks.cpp @@ -284,29 +284,32 @@ namespace { llvm::cout << __FUNCTION__ << "\n"; return StmtEmpty(); } - - virtual StmtResult ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, - SourceLocation ColonLoc, StmtTy *SubStmt) { + + virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc, + IdentifierInfo *II, + SourceLocation ColonLoc, + StmtArg SubStmt) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } - - virtual StmtResult ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal, - StmtTy *ThenVal, SourceLocation ElseLoc, - StmtTy *ElseVal) { + + virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, + StmtArg ThenVal,SourceLocation ElseLoc, + StmtArg ElseVal) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } - - virtual StmtResult ActOnStartOfSwitchStmt(ExprTy *Cond) { + + virtual OwningStmtResult ActOnStartOfSwitchStmt(ExprArg Cond) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } - - virtual StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, - StmtTy *Switch, ExprTy *Body) { + + virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, + StmtArg Switch, + StmtArg Body) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return StmtEmpty(); } virtual StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond, diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 257d62f46b..009858959e 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -393,25 +393,27 @@ public: StmtArg SubStmt, Scope *CurScope){ return StmtEmpty(); } - - virtual StmtResult ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, - SourceLocation ColonLoc, StmtTy *SubStmt) { - return 0; + + virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc, + IdentifierInfo *II, + SourceLocation ColonLoc, + StmtArg SubStmt) { + return StmtEmpty(); } - - virtual StmtResult ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal, - StmtTy *ThenVal, SourceLocation ElseLoc, - StmtTy *ElseVal) { - return 0; + + virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, + StmtArg ThenVal, SourceLocation ElseLoc, + StmtArg ElseVal) { + return StmtEmpty(); } - - virtual StmtResult ActOnStartOfSwitchStmt(ExprTy *Cond) { - return 0; + + virtual OwningStmtResult ActOnStartOfSwitchStmt(ExprArg Cond) { + return StmtEmpty(); } - - virtual StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, - StmtTy *Switch, ExprTy *Body) { - return 0; + + virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, + StmtArg Switch, StmtArg Body) { + return StmtEmpty(); } virtual StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond, diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 9f525a5491..d83e98d8d8 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -215,9 +215,9 @@ Parser::OwningStmtResult Parser::ParseLabeledStatement() { if (SubStmt.isInvalid()) SubStmt = Actions.ActOnNullStmt(ColonLoc); - return Owned(Actions.ActOnLabelStmt(IdentTok.getLocation(), - IdentTok.getIdentifierInfo(), - ColonLoc, SubStmt.release())); + return Actions.ActOnLabelStmt(IdentTok.getLocation(), + IdentTok.getIdentifierInfo(), + ColonLoc, move_convert(SubStmt)); } /// ParseCaseStatement @@ -575,8 +575,9 @@ Parser::OwningStmtResult Parser::ParseIfStatement() { if (ElseStmt.isInvalid()) ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc); - return Owned(Actions.ActOnIfStmt(IfLoc, CondExp.release(), ThenStmt.release(), - ElseLoc, ElseStmt.release())); + return Actions.ActOnIfStmt(IfLoc, move_convert(CondExp), + move_convert(ThenStmt), ElseLoc, + move_convert(ElseStmt)); } /// ParseSwitchStatement @@ -619,7 +620,7 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement() { OwningStmtResult Switch(Actions); if (!Cond.isInvalid()) - Switch = Actions.ActOnStartOfSwitchStmt(Cond.release()); + Switch = Actions.ActOnStartOfSwitchStmt(move_convert(Cond)); // C99 6.8.4p3 - In C99, the body of the switch statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this @@ -650,9 +651,9 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement() { if (Cond.isInvalid()) return StmtError(); - - return Owned(Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.release(), - Body.release())); + + return Actions.ActOnFinishSwitchStmt(SwitchLoc, move_convert(Switch), + move_convert(Body)); } /// ParseWhileStatement diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index bd7e0364a7..f699e496cf 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -598,14 +598,16 @@ public: virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, StmtArg SubStmt, Scope *CurScope); - virtual StmtResult ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, - SourceLocation ColonLoc, StmtTy *SubStmt); - virtual StmtResult ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal, - StmtTy *ThenVal, SourceLocation ElseLoc, - StmtTy *ElseVal); - virtual StmtResult ActOnStartOfSwitchStmt(ExprTy *Cond); - virtual StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, - StmtTy *Switch, ExprTy *Body); + virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc, + IdentifierInfo *II, + SourceLocation ColonLoc, + StmtArg SubStmt); + virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, + StmtArg ThenVal, SourceLocation ElseLoc, + StmtArg ElseVal); + virtual OwningStmtResult ActOnStartOfSwitchStmt(ExprArg Cond); + virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, + StmtArg Switch, StmtArg Body); virtual StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ExprTy *Cond, StmtTy *Body); virtual StmtResult ActOnDoStmt(SourceLocation DoLoc, StmtTy *Body, diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 23d3cd5fae..34f9f65cd7 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -169,69 +169,73 @@ Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, return Owned(DS); } -Action::StmtResult +Action::OwningStmtResult Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, - SourceLocation ColonLoc, StmtTy *subStmt) { - Stmt *SubStmt = static_cast(subStmt); + SourceLocation ColonLoc, StmtArg subStmt) { + Stmt *SubStmt = static_cast(subStmt.release()); // Look up the record for this label identifier. LabelStmt *&LabelDecl = LabelMap[II]; - + // If not forward referenced or defined already, just create a new LabelStmt. if (LabelDecl == 0) - return LabelDecl = new LabelStmt(IdentLoc, II, SubStmt); - + return Owned(LabelDecl = new LabelStmt(IdentLoc, II, SubStmt)); + assert(LabelDecl->getID() == II && "Label mismatch!"); - + // Otherwise, this label was either forward reference or multiply defined. If // multiply defined, reject it now. if (LabelDecl->getSubStmt()) { Diag(IdentLoc, diag::err_redefinition_of_label) << LabelDecl->getID(); Diag(LabelDecl->getIdentLoc(), diag::note_previous_definition); - return SubStmt; + return Owned(SubStmt); } - + // Otherwise, this label was forward declared, and we just found its real // definition. Fill in the forward definition and return it. LabelDecl->setIdentLoc(IdentLoc); LabelDecl->setSubStmt(SubStmt); - return LabelDecl; + return Owned(LabelDecl); } -Action::StmtResult -Sema::ActOnIfStmt(SourceLocation IfLoc, ExprTy *CondVal, - StmtTy *ThenVal, SourceLocation ElseLoc, - StmtTy *ElseVal) { - Expr *condExpr = (Expr *)CondVal; - Stmt *thenStmt = (Stmt *)ThenVal; - +Action::OwningStmtResult +Sema::ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, + StmtArg ThenVal, SourceLocation ElseLoc, + StmtArg ElseVal) { + Expr *condExpr = (Expr *)CondVal.release(); + assert(condExpr && "ActOnIfStmt(): missing expression"); - + DefaultFunctionArrayConversion(condExpr); + // Take ownership again until we're past the error checking. + CondVal = condExpr; QualType condType = condExpr->getType(); - + if (getLangOptions().CPlusPlus) { if (CheckCXXBooleanCondition(condExpr)) // C++ 6.4p4 - return true; + return StmtError(); } else if (!condType->isScalarType()) // C99 6.8.4.1p1 - return Diag(IfLoc, diag::err_typecheck_statement_requires_scalar) - << condType << condExpr->getSourceRange(); + return StmtError(Diag(IfLoc, diag::err_typecheck_statement_requires_scalar) + << condType << condExpr->getSourceRange()); + + Stmt *thenStmt = (Stmt *)ThenVal.release(); // Warn if the if block has a null body without an else value. // this helps prevent bugs due to typos, such as // if (condition); // do_stuff(); - if (!ElseVal) { + if (!ElseVal.get()) { if (NullStmt* stmt = dyn_cast(thenStmt)) Diag(stmt->getSemiLoc(), diag::warn_empty_if_body); } - return new IfStmt(IfLoc, condExpr, thenStmt, (Stmt*)ElseVal); + CondVal.release(); + return Owned(new IfStmt(IfLoc, condExpr, thenStmt, (Stmt*)ElseVal.release())); } -Action::StmtResult -Sema::ActOnStartOfSwitchStmt(ExprTy *cond) { - Expr *Cond = static_cast(cond); - +Action::OwningStmtResult +Sema::ActOnStartOfSwitchStmt(ExprArg cond) { + Expr *Cond = static_cast(cond.release()); + if (getLangOptions().CPlusPlus) { // C++ 6.4.2.p2: // The condition shall be of integral type, enumeration type, or of a class @@ -256,10 +260,10 @@ Sema::ActOnStartOfSwitchStmt(ExprTy *cond) { // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr. UsualUnaryConversions(Cond); } - + SwitchStmt *SS = new SwitchStmt(Cond); SwitchStack.push_back(SS); - return SS; + return Owned(SS); } /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have @@ -337,26 +341,26 @@ static bool CmpCaseVals(const std::pair& lhs, return false; } -Action::StmtResult -Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtTy *Switch, - ExprTy *Body) { - Stmt *BodyStmt = (Stmt*)Body; - +Action::OwningStmtResult +Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch, + StmtArg Body) { + Stmt *BodyStmt = (Stmt*)Body.release(); + SwitchStmt *SS = SwitchStack.back(); - assert(SS == (SwitchStmt*)Switch && "switch stack missing push/pop!"); - + assert(SS == (SwitchStmt*)Switch.get() && "switch stack missing push/pop!"); + SS->setBody(BodyStmt, SwitchLoc); SwitchStack.pop_back(); Expr *CondExpr = SS->getCond(); QualType CondType = CondExpr->getType(); - + if (!CondType->isIntegerType()) { // C99 6.8.4.2p1 Diag(SwitchLoc, diag::err_typecheck_statement_requires_integer) << CondType << CondExpr->getSourceRange(); - return true; + return StmtError(); } - + // Get the bitwidth of the switched-on value before promotions. We must // convert the integer case values to this width before comparison. unsigned CondWidth = static_cast(Context.getTypeSize(CondType)); @@ -382,7 +386,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtTy *Switch, if (TheDefaultStmt) { Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined); Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev); - + // FIXME: Remove the default statement from the switch block so that // we'll return a valid AST. This requires recursing down the // AST and finding it, not something we are set up to do right now. For @@ -522,9 +526,10 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtTy *Switch, // FIXME: If the case list was broken is some way, we don't have a good system // to patch it up. Instead, just return the whole substmt as broken. if (CaseListIsErroneous) - return true; - - return SS; + return StmtError(); + + Switch.release(); + return Owned(SS); } Action::StmtResult