forked from OSchip/llvm-project
Convert more expression actions to smart pointers.
Fix type of logical negation for C++. llvm-svn: 62475
This commit is contained in:
parent
e1c01e4e2b
commit
c215cfc3e1
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
<< 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<Expr *>(fn);
|
||||
Expr **Args = reinterpret_cast<Expr**>(args);
|
||||
unsigned NumArgs = args.size();
|
||||
Expr *Fn = static_cast<Expr *>(fn.release());
|
||||
Expr **Args = reinterpret_cast<Expr**>(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<MemberExpr>(Fn->IgnoreParens()))
|
||||
if (isa<OverloadedFunctionDecl>(MemExpr->getMemberDecl()) ||
|
||||
isa<CXXMethodDecl>(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<DeclRefExpr>(IcExpr->getSubExpr());
|
||||
else
|
||||
DRExpr = dyn_cast<DeclRefExpr>(Fn);
|
||||
|
||||
|
||||
if (DRExpr) {
|
||||
FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
|
||||
Ovl = dyn_cast<OverloadedFunctionDecl>(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<CallExpr> 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<FunctionTypeProto>(FuncT)) {
|
||||
if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs,
|
||||
RParenLoc))
|
||||
return true;
|
||||
return ExprError();
|
||||
} else {
|
||||
assert(isa<FunctionTypeNoProto>(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<CXXMethodDecl>(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<CXXMethodDecl>(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".
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue