From: Sebastian Redl Date: Mon, 19 Jan 2009 00:08:26 +0000 (+0000) Subject: Convert more expression actions to smart pointers. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0eb23307222bda7ad95d968eac4e1ab30864b213;p=clang Convert more expression actions to smart pointers. Fix type of logical negation for C++. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62475 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/PrintParserCallbacks.cpp b/Driver/PrintParserCallbacks.cpp index 18a4a24c80..7fc99a4da4 100644 --- a/Driver/PrintParserCallbacks.cpp +++ b/Driver/PrintParserCallbacks.cpp @@ -499,50 +499,48 @@ namespace { } // Postfix Expressions. - virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Kind, ExprTy *Input) { + virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Kind, + ExprArg Input) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - virtual ExprResult ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, - SourceLocation LLoc, ExprTy *Idx, - SourceLocation RLoc) { + virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base, + SourceLocation LLoc, + ExprArg Idx, + SourceLocation RLoc) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - virtual ExprResult ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - SourceLocation MemberLoc, - IdentifierInfo &Member) { + virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + SourceLocation MemberLoc, + IdentifierInfo &Member) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - - /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. - /// This provides the location of the left/right parens and a list of comma - /// locations. There are guaranteed to be one fewer commas than arguments, - /// unless there are zero arguments. - virtual ExprResult ActOnCallExpr(Scope *S, ExprTy *Fn, - SourceLocation LParenLoc, - ExprTy **Args, unsigned NumArgs, - SourceLocation *CommaLocs, - SourceLocation RParenLoc) { + + virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn, + SourceLocation LParenLoc, + MultiExprArg Args, + SourceLocation *CommaLocs, + SourceLocation RParenLoc) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - + // Unary Operators. 'Tok' is the token for the operator. - virtual ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Op, ExprTy *Input) { + virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Op, ExprArg Input) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } - virtual ExprResult - ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, - void *TyOrEx, const SourceRange &ArgRange) { + virtual OwningExprResult + ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, + void *TyOrEx, const SourceRange &ArgRange) { llvm::cout << __FUNCTION__ << "\n"; - return 0; + return ExprEmpty(); } virtual ExprResult ActOnCompoundLiteral(SourceLocation LParen, TypeTy *Ty, diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 1b47f0a0d9..7ca2ea1cb0 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -587,46 +587,48 @@ public: } // Postfix Expressions. - virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Kind, ExprTy *Input) { - return 0; + virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Kind, + ExprArg Input) { + return ExprEmpty(); } - virtual ExprResult ActOnArraySubscriptExpr(Scope *S, - ExprTy *Base, SourceLocation LLoc, - ExprTy *Idx, SourceLocation RLoc) { - return 0; + virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base, + SourceLocation LLoc, + ExprArg Idx, + SourceLocation RLoc) { + return ExprEmpty(); } - virtual ExprResult ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - SourceLocation MemberLoc, - IdentifierInfo &Member) { - return 0; + virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + SourceLocation MemberLoc, + IdentifierInfo &Member) { + return ExprEmpty(); } - + /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. /// This provides the location of the left/right parens and a list of comma /// locations. There are guaranteed to be one fewer commas than arguments, /// unless there are zero arguments. - virtual ExprResult ActOnCallExpr(Scope *S, ExprTy *Fn, - SourceLocation LParenLoc, - ExprTy **Args, unsigned NumArgs, - SourceLocation *CommaLocs, - SourceLocation RParenLoc) { - return 0; + virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn, + SourceLocation LParenLoc, + MultiExprArg Args, + SourceLocation *CommaLocs, + SourceLocation RParenLoc) { + return ExprEmpty(); } - + // Unary Operators. 'Tok' is the token for the operator. - virtual ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Op, ExprTy *Input) { - return 0; + virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Op, ExprArg Input) { + return ExprEmpty(); } - virtual ExprResult + virtual OwningExprResult ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, void *TyOrEx, const SourceRange &ArgRange) { - return 0; + return ExprEmpty(); } - + virtual ExprResult ActOnCompoundLiteral(SourceLocation LParen, TypeTy *Ty, SourceLocation RParen, ExprTy *Op) { return 0; diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index c8c521d6aa..08cb0dd5ce 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -548,8 +548,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression) { SourceLocation SavedLoc = ConsumeToken(); Res = ParseCastExpression(true); if (!Res.isInvalid()) - Res = Owned(Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, - Res.release())); + Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move_arg(Res)); return move(Res); } case tok::amp: // unary-expression: '&' cast-expression @@ -563,7 +562,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression) { SourceLocation SavedLoc = ConsumeToken(); Res = ParseCastExpression(false); if (!Res.isInvalid()) - Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.release()); + Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move_arg(Res)); return move(Res); } @@ -573,7 +572,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression) { SourceLocation SavedLoc = ConsumeToken(); Res = ParseCastExpression(false); if (!Res.isInvalid()) - Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, Res.release()); + Res = Actions.ActOnUnaryOp(CurScope, SavedLoc, SavedKind, move_arg(Res)); return move(Res); } case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression @@ -736,8 +735,8 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { SourceLocation RLoc = Tok.getLocation(); if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) { - LHS = Actions.ActOnArraySubscriptExpr(CurScope, LHS.release(), Loc, - Idx.release(), RLoc); + LHS = Actions.ActOnArraySubscriptExpr(CurScope, move_arg(LHS), Loc, + move_arg(Idx), RLoc); } else LHS = ExprError(); @@ -763,9 +762,8 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { if (!LHS.isInvalid() && Tok.is(tok::r_paren)) { assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&& "Unexpected number of commas!"); - LHS = Actions.ActOnCallExpr(CurScope, LHS.release(), Loc, - ArgExprs.take(), - ArgExprs.size(), &CommaLocs[0], + LHS = Actions.ActOnCallExpr(CurScope, move_arg(LHS), Loc, + move_arg(ArgExprs), &CommaLocs[0], Tok.getLocation()); } @@ -783,7 +781,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { } if (!LHS.isInvalid()) { - LHS = Actions.ActOnMemberReferenceExpr(CurScope, LHS.release(), OpLoc, + LHS = Actions.ActOnMemberReferenceExpr(CurScope, move_arg(LHS), OpLoc, OpKind, Tok.getLocation(), *Tok.getIdentifierInfo()); } @@ -794,7 +792,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { case tok::minusminus: // postfix-expression: postfix-expression '--' if (!LHS.isInvalid()) { LHS = Actions.ActOnPostfixUnaryOp(CurScope, Tok.getLocation(), - Tok.getKind(), LHS.release()); + Tok.getKind(), move_arg(LHS)); } ConsumeToken(); break; @@ -834,10 +832,10 @@ Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() { // If ParseParenExpression parsed a '(typename)' sequence only, the this is // sizeof/alignof a type. Otherwise, it is sizeof/alignof an expression. if (ExprType == CastExpr) - return Owned(Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(), + return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(), OpTok.is(tok::kw_sizeof), /*isType=*/true, CastTy, - SourceRange(LParenLoc, RParenLoc))); + SourceRange(LParenLoc, RParenLoc)); // If this is a parenthesized expression, it is the start of a // unary-expression, but doesn't include any postfix pieces. Parse these diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 681b27f464..f7014991bf 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -391,8 +391,8 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { } // Add the __extension__ node to the AST. - Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__, - Res.release()); + Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__, + move_arg(Res)); if (Res.isInvalid()) continue; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index b2c8aca966..40c9a99c7b 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -249,6 +249,9 @@ public: virtual void DeleteStmt(StmtTy *S); OwningExprResult Owned(Expr* E) { return OwningExprResult(*this, E); } + OwningExprResult Owned(ExprResult R) { + return R.isInvalid ? ExprError() : OwningExprResult(*this, R.Val); + } OwningStmtResult Owned(Stmt* S) { return OwningStmtResult(*this, S); } virtual void ActOnEndOfTranslationUnit(); @@ -980,44 +983,47 @@ public: /// ActOnStringLiteral - The specified tokens were lexed as pasted string /// fragments (e.g. "foo" "bar" L"baz"). - virtual OwningExprResult ActOnStringLiteral(const Token *Toks, unsigned NumToks); + virtual OwningExprResult ActOnStringLiteral(const Token *Toks, + unsigned NumToks); // Binary/Unary Operators. 'Tok' is the token for the operator. - virtual ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Op, ExprTy *Input); - virtual ExprResult + virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Op, ExprArg Input); + virtual OwningExprResult ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, void *TyOrEx, const SourceRange &ArgRange); bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc, const SourceRange &R, bool isSizeof); - - virtual ExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Kind, ExprTy *Input); - - virtual ExprResult ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, - SourceLocation LLoc, ExprTy *Idx, - SourceLocation RLoc); - virtual ExprResult ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, - SourceLocation OpLoc, - tok::TokenKind OpKind, - SourceLocation MemberLoc, - IdentifierInfo &Member); - bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, + + virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Kind, + ExprArg Input); + + virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base, + SourceLocation LLoc, + ExprArg Idx, + SourceLocation RLoc); + virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base, + SourceLocation OpLoc, + tok::TokenKind OpKind, + SourceLocation MemberLoc, + IdentifierInfo &Member); + bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, FunctionDecl *FDecl, const FunctionTypeProto *Proto, Expr **Args, unsigned NumArgs, SourceLocation RParenLoc); - + /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. /// This provides the location of the left/right parens and a list of comma /// locations. - virtual ExprResult ActOnCallExpr(Scope *S, ExprTy *Fn, - SourceLocation LParenLoc, - ExprTy **Args, unsigned NumArgs, - SourceLocation *CommaLocs, - SourceLocation RParenLoc); - + virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn, + SourceLocation LParenLoc, + MultiExprArg Args, + SourceLocation *CommaLocs, + SourceLocation RParenLoc); + virtual ExprResult ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, SourceLocation RParenLoc, ExprTy *Op); @@ -1782,16 +1788,17 @@ public: /// Returns false on success. bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, QualType FieldTy, const Expr *BitWidth); - + //===--------------------------------------------------------------------===// // Extra semantic analysis beyond the C type system private: - Action::ExprResult CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall); + Action::OwningExprResult CheckFunctionCall(FunctionDecl *FDecl, + CallExpr *TheCall); bool CheckBuiltinCFStringArgument(Expr* Arg); bool SemaBuiltinVAStart(CallExpr *TheCall); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); bool SemaBuiltinStackAddress(CallExpr *TheCall); - Action::ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall); + Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall); bool SemaBuiltinPrefetch(CallExpr *TheCall); bool SemaBuiltinObjectSize(CallExpr *TheCall); bool SemaCheckStringLiteral(Expr *E, CallExpr *TheCall, bool HasVAListArg, diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index ff9d75302f..9a60861bc2 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -24,52 +24,54 @@ using namespace clang; /// CheckFunctionCall - Check a direct function call for various correctness /// and safety properties not strictly enforced by the C type system. -Action::ExprResult -Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCallRaw) { - llvm::OwningPtr TheCall(TheCallRaw); +Action::OwningExprResult +Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { + OwningExprResult TheCallResult(Owned(TheCall)); // Get the IdentifierInfo* for the called function. IdentifierInfo *FnInfo = FDecl->getIdentifier(); // None of the checks below are needed for functions that don't have // simple names (e.g., C++ conversion functions). if (!FnInfo) - return TheCall.take(); + return move(TheCallResult); switch (FnInfo->getBuiltinID()) { case Builtin::BI__builtin___CFStringMakeConstantString: assert(TheCall->getNumArgs() == 1 && "Wrong # arguments to builtin CFStringMakeConstantString"); if (CheckBuiltinCFStringArgument(TheCall->getArg(0))) - return true; - return TheCall.take(); + return ExprError(); + return move(TheCallResult); case Builtin::BI__builtin_stdarg_start: case Builtin::BI__builtin_va_start: - if (SemaBuiltinVAStart(TheCall.get())) - return true; - return TheCall.take(); + if (SemaBuiltinVAStart(TheCall)) + return ExprError(); + return move(TheCallResult); case Builtin::BI__builtin_isgreater: case Builtin::BI__builtin_isgreaterequal: case Builtin::BI__builtin_isless: case Builtin::BI__builtin_islessequal: case Builtin::BI__builtin_islessgreater: case Builtin::BI__builtin_isunordered: - if (SemaBuiltinUnorderedCompare(TheCall.get())) - return true; - return TheCall.take(); + if (SemaBuiltinUnorderedCompare(TheCall)) + return ExprError(); + return move(TheCallResult); case Builtin::BI__builtin_return_address: case Builtin::BI__builtin_frame_address: - if (SemaBuiltinStackAddress(TheCall.get())) - return true; - return TheCall.take(); + if (SemaBuiltinStackAddress(TheCall)) + return ExprError(); + return move(TheCallResult); case Builtin::BI__builtin_shufflevector: - return SemaBuiltinShuffleVector(TheCall.get()); + return SemaBuiltinShuffleVector(TheCall); + // TheCall will be freed by the smart pointer here, but that's fine, since + // SemaBuiltinShuffleVector guts it, but then doesn't release it. case Builtin::BI__builtin_prefetch: - if (SemaBuiltinPrefetch(TheCall.get())) - return true; - return TheCall.take(); + if (SemaBuiltinPrefetch(TheCall)) + return ExprError(); + return move(TheCallResult); case Builtin::BI__builtin_object_size: - if (SemaBuiltinObjectSize(TheCall.get())) - return true; + if (SemaBuiltinObjectSize(TheCall)) + return ExprError(); } // FIXME: This mechanism should be abstracted to be less fragile and @@ -79,15 +81,15 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCallRaw) { // Search the KnownFunctionIDs for the identifier. unsigned i = 0, e = id_num_known_functions; for (; i != e; ++i) { if (KnownFunctionIDs[i] == FnInfo) break; } - if (i == e) return TheCall.take(); - + if (i == e) return move(TheCallResult); + // Printf checking. if (i <= id_vprintf) { // Retrieve the index of the format string parameter and determine // if the function is passed a va_arg argument. unsigned format_idx = 0; bool HasVAListArg = false; - + switch (i) { default: assert(false && "No format string argument index."); case id_NSLog: format_idx = 0; break; @@ -106,11 +108,11 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCallRaw) { case id_vsprintf_chk: format_idx = 3; HasVAListArg = true; break; case id_vprintf: format_idx = 0; HasVAListArg = true; break; } - - CheckPrintfArguments(TheCall.get(), HasVAListArg, format_idx); + + CheckPrintfArguments(TheCall, HasVAListArg, format_idx); } - - return TheCall.take(); + + return move(TheCallResult); } /// CheckBuiltinCFStringArgument - Checks that the argument to the builtin @@ -250,10 +252,11 @@ bool Sema::SemaBuiltinStackAddress(CallExpr *TheCall) { /// SemaBuiltinShuffleVector - Handle __builtin_shufflevector. // This is declared to take (...), so we have to check everything. -Action::ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { +Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { if (TheCall->getNumArgs() < 3) - return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) - << 0 /*function call*/ << TheCall->getSourceRange(); + return ExprError(Diag(TheCall->getLocEnd(), + diag::err_typecheck_call_too_few_args) + << 0 /*function call*/ << TheCall->getSourceRange()); QualType FAType = TheCall->getArg(0)->getType(); QualType SAType = TheCall->getArg(1)->getType(); @@ -262,7 +265,7 @@ Action::ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { Diag(TheCall->getLocStart(), diag::err_shufflevector_non_vector) << SourceRange(TheCall->getArg(0)->getLocStart(), TheCall->getArg(1)->getLocEnd()); - return true; + return ExprError(); } if (Context.getCanonicalType(FAType).getUnqualifiedType() != @@ -270,29 +273,31 @@ Action::ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector) << SourceRange(TheCall->getArg(0)->getLocStart(), TheCall->getArg(1)->getLocEnd()); - return true; + return ExprError(); } unsigned numElements = FAType->getAsVectorType()->getNumElements(); if (TheCall->getNumArgs() != numElements+2) { if (TheCall->getNumArgs() < numElements+2) - return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) - << 0 /*function call*/ << TheCall->getSourceRange(); - return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_many_args) - << 0 /*function call*/ << TheCall->getSourceRange(); + return ExprError(Diag(TheCall->getLocEnd(), + diag::err_typecheck_call_too_few_args) + << 0 /*function call*/ << TheCall->getSourceRange()); + return ExprError(Diag(TheCall->getLocEnd(), + diag::err_typecheck_call_too_many_args) + << 0 /*function call*/ << TheCall->getSourceRange()); } for (unsigned i = 2; i < TheCall->getNumArgs(); i++) { llvm::APSInt Result(32); if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context)) - return Diag(TheCall->getLocStart(), + return ExprError(Diag(TheCall->getLocStart(), diag::err_shufflevector_nonconstant_argument) - << TheCall->getArg(i)->getSourceRange(); - + << TheCall->getArg(i)->getSourceRange()); + if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2) - return Diag(TheCall->getLocStart(), + return ExprError(Diag(TheCall->getLocStart(), diag::err_shufflevector_argument_too_large) - << TheCall->getArg(i)->getSourceRange(); + << TheCall->getArg(i)->getSourceRange()); } llvm::SmallVector exprs; @@ -302,9 +307,9 @@ Action::ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { TheCall->setArg(i, 0); } - return new ShuffleVectorExpr(exprs.begin(), numElements+2, FAType, - TheCall->getCallee()->getLocStart(), - TheCall->getRParenLoc()); + return Owned(new ShuffleVectorExpr(exprs.begin(), numElements+2, FAType, + TheCall->getCallee()->getLocStart(), + TheCall->getRParenLoc())); } /// SemaBuiltinPrefetch - Handle __builtin_prefetch. @@ -1030,12 +1035,12 @@ void Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) { } // Check for comparisons with builtin types. - if (EmitWarning) + if (EmitWarning) if (CallExpr* CL = dyn_cast(LeftExprSansParen)) if (isCallBuiltin(CL)) EmitWarning = false; - if (EmitWarning) + if (EmitWarning) if (CallExpr* CR = dyn_cast(RightExprSansParen)) if (isCallBuiltin(CR)) EmitWarning = false; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 880c840fd4..be87ee9c49 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1032,11 +1032,11 @@ bool Sema::CheckSizeOfAlignOfOperand(QualType exprType, /// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and /// the same for @c alignof and @c __alignof /// Note that the ArgRange is invalid if isType is false. -Action::ExprResult +Action::OwningExprResult Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, void *TyOrEx, const SourceRange &ArgRange) { // If error parsing type, ignore. - if (TyOrEx == 0) return true; + if (TyOrEx == 0) return ExprError(); QualType ArgTy; SourceRange Range; @@ -1051,12 +1051,14 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, } // Verify that the operand is valid. + // FIXME: This might leak the expression. if (CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, isSizeof)) - return true; + return ExprError(); // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t. - return new SizeOfAlignOfExpr(isSizeof, isType, TyOrEx, Context.getSizeType(), - OpLoc, Range.getEnd()); + return Owned(new SizeOfAlignOfExpr(isSizeof, isType, TyOrEx, + Context.getSizeType(), OpLoc, + Range.getEnd())); } QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc) { @@ -1077,10 +1079,10 @@ QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc) { -Action::ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Kind, - ExprTy *Input) { - Expr *Arg = (Expr *)Input; +Action::OwningExprResult +Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Kind, ExprArg Input) { + Expr *Arg = (Expr *)Input.get(); UnaryOperator::Opcode Opc; switch (Kind) { @@ -1088,11 +1090,11 @@ Action::ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, case tok::plusplus: Opc = UnaryOperator::PostInc; break; case tok::minusminus: Opc = UnaryOperator::PostDec; break; } - + if (getLangOptions().CPlusPlus && (Arg->getType()->isRecordType() || Arg->getType()->isEnumeralType())) { // Which overloaded operator? - OverloadedOperatorKind OverOp = + OverloadedOperatorKind OverOp = (Opc == UnaryOperator::PostInc)? OO_PlusPlus : OO_MinusMinus; // C++ [over.inc]p1: @@ -1129,36 +1131,37 @@ Action::ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, // Convert the arguments. if (CXXMethodDecl *Method = dyn_cast(FnDecl)) { if (PerformObjectArgumentInitialization(Arg, Method)) - return true; + return ExprError(); } else { // Convert the arguments. - if (PerformCopyInitialization(Arg, + if (PerformCopyInitialization(Arg, FnDecl->getParamDecl(0)->getType(), "passing")) - return true; + return ExprError(); } // Determine the result type - QualType ResultTy + QualType ResultTy = FnDecl->getType()->getAsFunctionType()->getResultType(); ResultTy = ResultTy.getNonReferenceType(); - + // Build the actual expression node. - Expr *FnExpr = new DeclRefExpr(FnDecl, FnDecl->getType(), + Expr *FnExpr = new DeclRefExpr(FnDecl, FnDecl->getType(), SourceLocation()); UsualUnaryConversions(FnExpr); - return new CXXOperatorCallExpr(FnExpr, Args, 2, ResultTy, OpLoc); + Input.release(); + return Owned(new CXXOperatorCallExpr(FnExpr, Args, 2, ResultTy, OpLoc)); } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in // operator node. if (PerformCopyInitialization(Arg, Best->BuiltinTypes.ParamTypes[0], "passing")) - return true; + return ExprError(); break; - } + } } case OR_No_Viable_Function: @@ -1171,7 +1174,7 @@ Action::ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, << UnaryOperator::getOpcodeStr(Opc) << Arg->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); - return true; + return ExprError(); } // Either we found no viable overloaded operator or we matched a @@ -1182,17 +1185,19 @@ Action::ExprResult Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, QualType result = CheckIncrementDecrementOperand(Arg, OpLoc, Opc == UnaryOperator::PostInc); if (result.isNull()) - return true; - return new UnaryOperator(Arg, Opc, result, OpLoc); + return ExprError(); + Input.release(); + return Owned(new UnaryOperator(Arg, Opc, result, OpLoc)); } -Action::ExprResult Sema:: -ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, - ExprTy *Idx, SourceLocation RLoc) { - Expr *LHSExp = static_cast(Base), *RHSExp = static_cast(Idx); +Action::OwningExprResult +Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, + ExprArg Idx, SourceLocation RLoc) { + Expr *LHSExp = static_cast(Base.get()), + *RHSExp = static_cast(Idx.get()); if (getLangOptions().CPlusPlus && - (LHSExp->getType()->isRecordType() || + (LHSExp->getType()->isRecordType() || LHSExp->getType()->isEnumeralType() || RHSExp->getType()->isRecordType() || RHSExp->getType()->isEnumeralType())) { @@ -1201,7 +1206,7 @@ ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, OverloadCandidateSet CandidateSet; Expr *Args[2] = { LHSExp, RHSExp }; AddOperatorCandidates(OO_Subscript, S, Args, 2, CandidateSet); - + // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (BestViableFunction(CandidateSet, Best)) { @@ -1219,7 +1224,7 @@ ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, PerformCopyInitialization(RHSExp, FnDecl->getParamDecl(0)->getType(), "passing")) - return true; + return ExprError(); } else { // Convert the arguments. if (PerformCopyInitialization(LHSExp, @@ -1228,20 +1233,22 @@ ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, PerformCopyInitialization(RHSExp, FnDecl->getParamDecl(1)->getType(), "passing")) - return true; + return ExprError(); } // Determine the result type - QualType ResultTy + QualType ResultTy = FnDecl->getType()->getAsFunctionType()->getResultType(); ResultTy = ResultTy.getNonReferenceType(); - + // Build the actual expression node. Expr *FnExpr = new DeclRefExpr(FnDecl, FnDecl->getType(), SourceLocation()); UsualUnaryConversions(FnExpr); - return new CXXOperatorCallExpr(FnExpr, Args, 2, ResultTy, LLoc); + Base.release(); + Idx.release(); + return Owned(new CXXOperatorCallExpr(FnExpr, Args, 2, ResultTy, LLoc)); } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in @@ -1250,7 +1257,7 @@ ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, "passing") || PerformCopyInitialization(RHSExp, Best->BuiltinTypes.ParamTypes[1], "passing")) - return true; + return ExprError(); break; } @@ -1266,7 +1273,7 @@ ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, << "[]" << LHSExp->getSourceRange() << RHSExp->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); - return true; + return ExprError(); } // Either we found no viable overloaded operator or we matched a @@ -1277,7 +1284,7 @@ ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, // Perform default conversions. DefaultFunctionArrayConversion(LHSExp); DefaultFunctionArrayConversion(RHSExp); - + QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType(); // C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent @@ -1304,24 +1311,26 @@ ActOnArraySubscriptExpr(Scope *S, ExprTy *Base, SourceLocation LLoc, // FIXME: need to deal with const... ResultType = VTy->getElementType(); } else { - return Diag(LHSExp->getLocStart(), diag::err_typecheck_subscript_value) - << RHSExp->getSourceRange(); - } + return ExprError(Diag(LHSExp->getLocStart(), + diag::err_typecheck_subscript_value) << RHSExp->getSourceRange()); + } // C99 6.5.2.1p1 if (!IndexExpr->getType()->isIntegerType()) - return Diag(IndexExpr->getLocStart(), diag::err_typecheck_subscript) - << IndexExpr->getSourceRange(); + return ExprError(Diag(IndexExpr->getLocStart(), + diag::err_typecheck_subscript) << IndexExpr->getSourceRange()); // C99 6.5.2.1p1: "shall have type "pointer to *object* type". In practice, // the following check catches trying to index a pointer to a function (e.g. // void (*)(int)) and pointers to incomplete types. Functions are not // objects in C99. if (!ResultType->isObjectType()) - return Diag(BaseExpr->getLocStart(), + return ExprError(Diag(BaseExpr->getLocStart(), diag::err_typecheck_subscript_not_object) - << BaseExpr->getType() << BaseExpr->getSourceRange(); + << BaseExpr->getType() << BaseExpr->getSourceRange()); - return new ArraySubscriptExpr(LHSExp, RHSExp, ResultType, RLoc); + Base.release(); + Idx.release(); + return Owned(new ArraySubscriptExpr(LHSExp, RHSExp, ResultType, RLoc)); } QualType Sema:: @@ -1426,42 +1435,44 @@ static IdentifierInfo *constructSetterName(IdentifierTable &Idents, return &Idents.get(&SelectorName[0], &SelectorName[SelectorName.size()]); } -Action::ExprResult Sema:: -ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, - tok::TokenKind OpKind, SourceLocation MemberLoc, - IdentifierInfo &Member) { - Expr *BaseExpr = static_cast(Base); +Action::OwningExprResult +Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, + tok::TokenKind OpKind, SourceLocation MemberLoc, + IdentifierInfo &Member) { + Expr *BaseExpr = static_cast(Base.release()); assert(BaseExpr && "no record expression"); // Perform default conversions. DefaultFunctionArrayConversion(BaseExpr); - + QualType BaseType = BaseExpr->getType(); assert(!BaseType.isNull() && "no type for member expression"); - + // Get the type being accessed in BaseType. If this is an arrow, the BaseExpr // must have pointer type, and the accessed type is the pointee. if (OpKind == tok::arrow) { if (const PointerType *PT = BaseType->getAsPointerType()) BaseType = PT->getPointeeType(); else if (getLangOptions().CPlusPlus && BaseType->isRecordType()) - return BuildOverloadedArrowExpr(S, BaseExpr, OpLoc, MemberLoc, Member); + return Owned(BuildOverloadedArrowExpr(S, BaseExpr, OpLoc, + MemberLoc, Member)); else - return Diag(MemberLoc, diag::err_typecheck_member_reference_arrow) - << BaseType << BaseExpr->getSourceRange(); + return ExprError(Diag(MemberLoc, + diag::err_typecheck_member_reference_arrow) + << BaseType << BaseExpr->getSourceRange()); } - + // Handle field access to simple records. This also handles access to fields // of the ObjC 'id' struct. if (const RecordType *RTy = BaseType->getAsRecordType()) { RecordDecl *RDecl = RTy->getDecl(); if (RTy->isIncompleteType()) - return Diag(OpLoc, diag::err_typecheck_incomplete_tag) - << RDecl->getDeclName() << BaseExpr->getSourceRange(); + return ExprError(Diag(OpLoc, diag::err_typecheck_incomplete_tag) + << RDecl->getDeclName() << BaseExpr->getSourceRange()); // The record definition is complete, now make sure the member is valid. // FIXME: Qualified name lookup for C++ is a bit more complicated // than this. - LookupResult Result + LookupResult Result = LookupQualifiedName(RDecl, DeclarationName(&Member), LookupCriteria(LookupCriteria::Member, /*RedeclarationOnly=*/false, @@ -1469,12 +1480,13 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, Decl *MemberDecl = 0; if (!Result) - return Diag(MemberLoc, diag::err_typecheck_no_member) - << &Member << BaseExpr->getSourceRange(); - else if (Result.isAmbiguous()) - return DiagnoseAmbiguousLookup(Result, DeclarationName(&Member), - MemberLoc, BaseExpr->getSourceRange()); - else + return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member) + << &Member << BaseExpr->getSourceRange()); + else if (Result.isAmbiguous()) { + DiagnoseAmbiguousLookup(Result, DeclarationName(&Member), + MemberLoc, BaseExpr->getSourceRange()); + return ExprError(); + } else MemberDecl = Result; if (FieldDecl *FD = dyn_cast(MemberDecl)) { @@ -1482,8 +1494,7 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, // (C++ [class.union]). if (cast(FD->getDeclContext())->isAnonymousStructOrUnion()) return BuildAnonymousStructUnionMemberReference(MemberLoc, FD, - BaseExpr, OpLoc) - .release(); + BaseExpr, OpLoc); // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref] // FIXME: Handle address space modifiers @@ -1498,47 +1509,49 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, MemberType = MemberType.getQualifiedType(combinedQualifiers); } - return new MemberExpr(BaseExpr, OpKind == tok::arrow, FD, - MemberLoc, MemberType); + return Owned(new MemberExpr(BaseExpr, OpKind == tok::arrow, FD, + MemberLoc, MemberType)); } else if (CXXClassVarDecl *Var = dyn_cast(MemberDecl)) - return new MemberExpr(BaseExpr, OpKind == tok::arrow, Var, MemberLoc, - Var->getType().getNonReferenceType()); + return Owned(new MemberExpr(BaseExpr, OpKind == tok::arrow, + Var, MemberLoc, + Var->getType().getNonReferenceType())); else if (FunctionDecl *MemberFn = dyn_cast(MemberDecl)) - return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberFn, MemberLoc, - MemberFn->getType()); - else if (OverloadedFunctionDecl *Ovl + return Owned(new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberFn, + MemberLoc, MemberFn->getType())); + else if (OverloadedFunctionDecl *Ovl = dyn_cast(MemberDecl)) - return new MemberExpr(BaseExpr, OpKind == tok::arrow, Ovl, MemberLoc, - Context.OverloadTy); + return Owned(new MemberExpr(BaseExpr, OpKind == tok::arrow, Ovl, + MemberLoc, Context.OverloadTy)); else if (EnumConstantDecl *Enum = dyn_cast(MemberDecl)) - return new MemberExpr(BaseExpr, OpKind == tok::arrow, Enum, MemberLoc, - Enum->getType()); + return Owned(new MemberExpr(BaseExpr, OpKind == tok::arrow, Enum, + MemberLoc, Enum->getType())); else if (isa(MemberDecl)) - return Diag(MemberLoc, diag::err_typecheck_member_reference_type) - << DeclarationName(&Member) << int(OpKind == tok::arrow); + return ExprError(Diag(MemberLoc,diag::err_typecheck_member_reference_type) + << DeclarationName(&Member) << int(OpKind == tok::arrow)); // We found a declaration kind that we didn't expect. This is a // generic error message that tells the user that she can't refer // to this member with '.' or '->'. - return Diag(MemberLoc, diag::err_typecheck_member_reference_unknown) - << DeclarationName(&Member) << int(OpKind == tok::arrow); + return ExprError(Diag(MemberLoc, + diag::err_typecheck_member_reference_unknown) + << DeclarationName(&Member) << int(OpKind == tok::arrow)); } - + // Handle access to Objective-C instance variables, such as "Obj->ivar" and // (*Obj).ivar. if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) { if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member)) { - ObjCIvarRefExpr *MRef= new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, - BaseExpr, + ObjCIvarRefExpr *MRef= new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, + BaseExpr, OpKind == tok::arrow); Context.setFieldDecl(IFTy->getDecl(), IV, MRef); - return MRef; + return Owned(MRef); } - return Diag(MemberLoc, diag::err_typecheck_member_reference_ivar) - << IFTy->getDecl()->getDeclName() << &Member - << BaseExpr->getSourceRange(); + return ExprError(Diag(MemberLoc, diag::err_typecheck_member_reference_ivar) + << IFTy->getDecl()->getDeclName() << &Member + << BaseExpr->getSourceRange()); } - + // Handle Objective-C property access, which is "Obj.property" where Obj is a // pointer to a (potentially qualified) interface type. const PointerType *PTy; @@ -1549,13 +1562,15 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, // Search for a declared property first. if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member)) - return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr); - + return Owned(new ObjCPropertyRefExpr(PD, PD->getType(), + MemberLoc, BaseExpr)); + // Check protocols on qualified interfaces. for (ObjCInterfaceType::qual_iterator I = IFTy->qual_begin(), E = IFTy->qual_end(); I != E; ++I) if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) - return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr); + return Owned(new ObjCPropertyRefExpr(PD, PD->getType(), + MemberLoc, BaseExpr)); // If that failed, look for an "implicit" property by seeing if the nullary // selector is implemented. @@ -1565,7 +1580,7 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); - + // If this reference is in an @implementation, check for 'private' methods. if (!Getter) if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) @@ -1604,14 +1619,14 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel); } } - - // FIXME: we must check that the setter has property type. - return new ObjCKVCRefExpr(Getter, Getter->getResultType(), Setter, - MemberLoc, BaseExpr); + + // FIXME: we must check that the setter has property type. + return Owned(new ObjCKVCRefExpr(Getter, Getter->getResultType(), Setter, + MemberLoc, BaseExpr)); } - - return Diag(MemberLoc, diag::err_property_not_found) << - &Member << BaseType; + + return ExprError(Diag(MemberLoc, diag::err_property_not_found) + << &Member << BaseType); } // Handle properties on qualified "id" protocols. const ObjCQualifiedIdType *QIdTy; @@ -1620,28 +1635,30 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(), E = QIdTy->qual_end(); I != E; ++I) { if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) - return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr); + return Owned(new ObjCPropertyRefExpr(PD, PD->getType(), + MemberLoc, BaseExpr)); // Also must look for a getter name which uses property syntax. Selector Sel = PP.getSelectorTable().getNullarySelector(&Member); if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) { - return new ObjCMessageExpr(BaseExpr, Sel, OMD->getResultType(), OMD, - OpLoc, MemberLoc, NULL, 0); + return Owned(new ObjCMessageExpr(BaseExpr, Sel, OMD->getResultType(), + OMD, OpLoc, MemberLoc, NULL, 0)); } } - - return Diag(MemberLoc, diag::err_property_not_found) << - &Member << BaseType; - } + + return ExprError(Diag(MemberLoc, diag::err_property_not_found) + << &Member << BaseType); + } // Handle 'field access' to vectors, such as 'V.xx'. if (BaseType->isExtVectorType() && OpKind == tok::period) { QualType ret = CheckExtVectorComponent(BaseType, OpLoc, Member, MemberLoc); if (ret.isNull()) - return true; - return new ExtVectorElementExpr(ret, BaseExpr, Member, MemberLoc); + return ExprError(); + return Owned(new ExtVectorElementExpr(ret, BaseExpr, Member, MemberLoc)); } - - return Diag(MemberLoc, diag::err_typecheck_member_reference_struct_union) - << BaseType << BaseExpr->getSourceRange(); + + return ExprError(Diag(MemberLoc, + diag::err_typecheck_member_reference_struct_union) + << BaseType << BaseExpr->getSourceRange()); } /// ConvertArgumentsForCall - Converts the arguments specified in @@ -1728,12 +1745,13 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. /// This provides the location of the left/right parens and a list of comma /// locations. -Action::ExprResult -Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc, - ExprTy **args, unsigned NumArgs, +Action::OwningExprResult +Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, + MultiExprArg args, SourceLocation *CommaLocs, SourceLocation RParenLoc) { - Expr *Fn = static_cast(fn); - Expr **Args = reinterpret_cast(args); + unsigned NumArgs = args.size(); + Expr *Fn = static_cast(fn.release()); + Expr **Args = reinterpret_cast(args.release()); assert(Fn && "no function call expression"); FunctionDecl *FDecl = NULL; OverloadedFunctionDecl *Ovl = NULL; @@ -1755,7 +1773,7 @@ Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc, /*SS=*/0, /*ForceResolution=*/true); if (Resolved.isInvalid()) - return true; + return ExprError(); else { delete Fn; Fn = (Expr *)Resolved.release(); @@ -1769,20 +1787,21 @@ Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc, // FIXME: Will need to cache the results of name lookup (including // ADL) in Fn. if (Dependent) - return new CallExpr(Fn, Args, NumArgs, Context.DependentTy, RParenLoc); + return Owned(new CallExpr(Fn, Args, NumArgs, + Context.DependentTy, RParenLoc)); // Determine whether this is a call to an object (C++ [over.call.object]). if (getLangOptions().CPlusPlus && Fn->getType()->isRecordType()) - return BuildCallToObjectOfClassType(S, Fn, LParenLoc, Args, NumArgs, - CommaLocs, RParenLoc); + return Owned(BuildCallToObjectOfClassType(S, Fn, LParenLoc, Args, NumArgs, + CommaLocs, RParenLoc)); // Determine whether this is a call to a member function. if (getLangOptions().CPlusPlus) { if (MemberExpr *MemExpr = dyn_cast(Fn->IgnoreParens())) if (isa(MemExpr->getMemberDecl()) || isa(MemExpr->getMemberDecl())) - return BuildCallToMemberFunction(S, Fn, LParenLoc, Args, NumArgs, - CommaLocs, RParenLoc); + return Owned(BuildCallToMemberFunction(S, Fn, LParenLoc, Args, NumArgs, + CommaLocs, RParenLoc)); } // If we're directly calling a function or a set of overloaded @@ -1792,17 +1811,17 @@ Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc, DRExpr = dyn_cast(IcExpr->getSubExpr()); else DRExpr = dyn_cast(Fn); - + if (DRExpr) { FDecl = dyn_cast(DRExpr->getDecl()); Ovl = dyn_cast(DRExpr->getDecl()); } if (Ovl) { - FDecl = ResolveOverloadedCallFn(Fn, Ovl, LParenLoc, Args, NumArgs, CommaLocs, - RParenLoc); + FDecl = ResolveOverloadedCallFn(Fn, Ovl, LParenLoc, Args, NumArgs, + CommaLocs, RParenLoc); if (!FDecl) - return true; + return ExprError(); // Update Fn to refer to the actual function selected. Expr *NewFn = 0; @@ -1822,36 +1841,38 @@ Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc, // Make the call expr early, before semantic checks. This guarantees cleanup // of arguments and function on error. + // FIXME: Except that llvm::OwningPtr uses delete, when it really must be + // Destroy(), or nothing gets cleaned up. llvm::OwningPtr TheCall(new CallExpr(Fn, Args, NumArgs, Context.BoolTy, RParenLoc)); - + const FunctionType *FuncT; if (!Fn->getType()->isBlockPointerType()) { // C99 6.5.2.2p1 - "The expression that denotes the called function shall // have type pointer to function". const PointerType *PT = Fn->getType()->getAsPointerType(); if (PT == 0) - return Diag(LParenLoc, diag::err_typecheck_call_not_function) - << Fn->getType() << Fn->getSourceRange(); + return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) + << Fn->getType() << Fn->getSourceRange()); FuncT = PT->getPointeeType()->getAsFunctionType(); } else { // This is a block call. FuncT = Fn->getType()->getAsBlockPointerType()->getPointeeType()-> getAsFunctionType(); } if (FuncT == 0) - return Diag(LParenLoc, diag::err_typecheck_call_not_function) - << Fn->getType() << Fn->getSourceRange(); - + return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function) + << Fn->getType() << Fn->getSourceRange()); + // We know the result type of the call, set it. TheCall->setType(FuncT->getResultType().getNonReferenceType()); - + if (const FunctionTypeProto *Proto = dyn_cast(FuncT)) { if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs, RParenLoc)) - return true; + return ExprError(); } else { assert(isa(FuncT) && "Unknown FunctionType!"); - + // Promote the arguments (C99 6.5.2.2p6). for (unsigned i = 0; i != NumArgs; i++) { Expr *Arg = Args[i]; @@ -1862,14 +1883,14 @@ Sema::ActOnCallExpr(Scope *S, ExprTy *fn, SourceLocation LParenLoc, if (CXXMethodDecl *Method = dyn_cast_or_null(FDecl)) if (!Method->isStatic()) - return Diag(LParenLoc, diag::err_member_call_without_object) - << Fn->getSourceRange(); + return ExprError(Diag(LParenLoc, diag::err_member_call_without_object) + << Fn->getSourceRange()); // Do special checking on direct calls to functions. if (FDecl) return CheckFunctionCall(FDecl, TheCall.take()); - return TheCall.take(); + return Owned(TheCall.take()); } Action::ExprResult Sema:: @@ -3614,9 +3635,10 @@ Action::ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc, } // Unary Operators. 'Tok' is the token for the operator. -Action::ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, - tok::TokenKind Op, ExprTy *input) { - Expr *Input = (Expr*)input; +Action::OwningExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, + tok::TokenKind Op, ExprArg input) { + // FIXME: Input is modified later, but smart pointer not reassigned. + Expr *Input = (Expr*)input.get(); UnaryOperator::Opcode Opc = ConvertTokenKindToUnaryOpcode(Op); if (getLangOptions().CPlusPlus && @@ -3655,36 +3677,38 @@ Action::ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, // Convert the arguments. if (CXXMethodDecl *Method = dyn_cast(FnDecl)) { if (PerformObjectArgumentInitialization(Input, Method)) - return true; + return ExprError(); } else { // Convert the arguments. if (PerformCopyInitialization(Input, FnDecl->getParamDecl(0)->getType(), "passing")) - return true; + return ExprError(); } // Determine the result type - QualType ResultTy + QualType ResultTy = FnDecl->getType()->getAsFunctionType()->getResultType(); ResultTy = ResultTy.getNonReferenceType(); - + // Build the actual expression node. Expr *FnExpr = new DeclRefExpr(FnDecl, FnDecl->getType(), SourceLocation()); UsualUnaryConversions(FnExpr); - return new CXXOperatorCallExpr(FnExpr, &Input, 1, ResultTy, OpLoc); + input.release(); + return Owned(new CXXOperatorCallExpr(FnExpr, &Input, 1, + ResultTy, OpLoc)); } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in // operator node. if (PerformImplicitConversion(Input, Best->BuiltinTypes.ParamTypes[0], Best->Conversions[0], "passing")) - return true; + return ExprError(); break; - } + } } case OR_No_Viable_Function: @@ -3697,12 +3721,12 @@ Action::ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, << UnaryOperator::getOpcodeStr(Opc) << Input->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); - return true; + return ExprError(); } // Either we found no viable overloaded operator or we matched a // built-in operator. In either case, fall through to trying to - // build a built-in operation. + // build a built-in operation. } QualType resultType; @@ -3735,8 +3759,8 @@ Action::ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, resultType->isPointerType()) break; - return Diag(OpLoc, diag::err_typecheck_unary_expr) - << resultType << Input->getSourceRange(); + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input->getSourceRange()); case UnaryOperator::Not: // bitwise complement UsualUnaryConversions(Input); resultType = Input->getType(); @@ -3746,18 +3770,19 @@ Action::ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, Diag(OpLoc, diag::ext_integer_complement_complex) << resultType << Input->getSourceRange(); else if (!resultType->isIntegerType()) - return Diag(OpLoc, diag::err_typecheck_unary_expr) - << resultType << Input->getSourceRange(); + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input->getSourceRange()); break; case UnaryOperator::LNot: // logical negation // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5). DefaultFunctionArrayConversion(Input); resultType = Input->getType(); if (!resultType->isScalarType()) // C99 6.5.3.3p1 - return Diag(OpLoc, diag::err_typecheck_unary_expr) - << resultType << Input->getSourceRange(); + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input->getSourceRange()); // LNot always has type int. C99 6.5.3.3p5. - resultType = Context.IntTy; + // In C++, it's bool. C++ 5.3.1p8 + resultType = getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy; break; case UnaryOperator::Real: case UnaryOperator::Imag: @@ -3768,8 +3793,9 @@ Action::ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, break; } if (resultType.isNull()) - return true; - return new UnaryOperator(Input, Opc, resultType, OpLoc); + return ExprError(); + input.release(); + return Owned(new UnaryOperator(Input, Opc, resultType, OpLoc)); } /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo". diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 170ef1b59c..61c22d43be 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -3436,7 +3436,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, RParenLoc)) return true; - return CheckFunctionCall(Method, TheCall.take()); + return CheckFunctionCall(Method, TheCall.take()).release(); } /// BuildCallToObjectOfClassType - Build a call to an object of class @@ -3548,11 +3548,12 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, // object parameter to a function pointer. Perform the conversion // on the object argument, then let ActOnCallExpr finish the job. // FIXME: Represent the user-defined conversion in the AST! - ImpCastExprToType(Object, + ImpCastExprToType(Object, Conv->getConversionType().getNonReferenceType(), Conv->getConversionType()->isReferenceType()); - return ActOnCallExpr(S, (ExprTy*)Object, LParenLoc, (ExprTy**)Args, NumArgs, - CommaLocs, RParenLoc); + return ActOnCallExpr(S, ExprArg(*this, Object), LParenLoc, + MultiExprArg(*this, (ExprTy**)Args, NumArgs), + CommaLocs, RParenLoc).release(); } // We found an overloaded operator(). Build a CXXOperatorCallExpr @@ -3630,7 +3631,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, } } - return CheckFunctionCall(Method, TheCall.take()); + return CheckFunctionCall(Method, TheCall.take()).release(); } /// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator-> @@ -3700,7 +3701,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, Base = new CXXOperatorCallExpr(FnExpr, &Base, 1, Method->getResultType().getNonReferenceType(), OpLoc); - return ActOnMemberReferenceExpr(S, Base, OpLoc, tok::arrow, MemberLoc, Member); + return ActOnMemberReferenceExpr(S, ExprArg(*this, Base), OpLoc, tok::arrow, + MemberLoc, Member).release(); } /// FixOverloadedFunctionReference - E is an expression that refers to