aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Driver/PrintParserCallbacks.cpp62
-rw-r--r--include/clang/Parse/Action.h56
-rw-r--r--lib/Parse/ParseExpr.cpp24
-rw-r--r--lib/Parse/ParseStmt.cpp4
-rw-r--r--lib/Sema/Sema.h61
-rw-r--r--lib/Sema/SemaChecking.cpp99
-rw-r--r--lib/Sema/SemaExpr.cpp348
-rw-r--r--lib/Sema/SemaOverload.cpp14
8 files changed, 353 insertions, 315 deletions
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<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