diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 24 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 61 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 99 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 348 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 14 |
6 files changed, 294 insertions, 256 deletions
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<CallExpr> 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<Expr*, 32> 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<CallExpr>(LeftExprSansParen)) if (isCallBuiltin(CL)) EmitWarning = false; - if (EmitWarning) + if (EmitWarning) if (CallExpr* CR = dyn_cast<CallExpr>(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<CXXMethodDecl>(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<Expr*>(Base), *RHSExp = static_cast<Expr*>(Idx); +Action::OwningExprResult +Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, + ExprArg Idx, SourceLocation RLoc) { + Expr *LHSExp = static_cast<Expr*>(Base.get()), + *RHSExp = static_cast<Expr*>(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<Expr *>(Base); +Action::OwningExprResult +Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc, + tok::TokenKind OpKind, SourceLocation MemberLoc, + IdentifierInfo &Member) { + Expr *BaseExpr = static_cast<Expr *>(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<FieldDecl>(MemberDecl)) { @@ -1482,8 +1494,7 @@ ActOnMemberReferenceExpr(Scope *S, ExprTy *Base, SourceLocation OpLoc, // (C++ [class.union]). if (cast<RecordDecl>(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<CXXClassVarDecl>(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<FunctionDecl>(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<OverloadedFunctionDecl>(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<EnumConstantDecl>(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<TypeDecl>(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) - |