diff options
| -rw-r--r-- | clang/Driver/PrintParserCallbacks.cpp | 62 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Action.h | 56 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 24 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 61 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 99 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 348 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 14 | 
8 files changed, 353 insertions, 315 deletions
diff --git a/clang/Driver/PrintParserCallbacks.cpp b/clang/Driver/PrintParserCallbacks.cpp index 18a4a24c80b..7fc99a4da42 100644 --- a/clang/Driver/PrintParserCallbacks.cpp +++ b/clang/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/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 1b47f0a0d9b..7ca2ea1cb01 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/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/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index c8c521d6aaf..08cb0dd5ce0 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/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/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 681b27f4648..f7014991bf8 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/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/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index b2c8aca966a..40c9a99c7b2 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index ff9d75302f7..9a60861bc28 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 880c840fd4c..be87ee9c496 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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) -             << 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". diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 170ef1b59c1..61c22d43bef 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -3436,7 +3436,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,                                RParenLoc))      return true; -  return CheckFunctionCall(Method, TheCall.take()); +  return CheckFunctionCall(Method, TheCall.take()).release();  }  /// BuildCallToObjectOfClassType - Build a call to an object of class @@ -3548,11 +3548,12 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,      // object parameter to a function pointer. Perform the conversion      // on the object argument, then let ActOnCallExpr finish the job.      // FIXME: Represent the user-defined conversion in the AST! -    ImpCastExprToType(Object,  +    ImpCastExprToType(Object,                        Conv->getConversionType().getNonReferenceType(),                        Conv->getConversionType()->isReferenceType()); -    return ActOnCallExpr(S, (ExprTy*)Object, LParenLoc, (ExprTy**)Args, NumArgs, -                         CommaLocs, RParenLoc); +    return ActOnCallExpr(S, ExprArg(*this, Object), LParenLoc, +                         MultiExprArg(*this, (ExprTy**)Args, NumArgs), +                         CommaLocs, RParenLoc).release();    }    // We found an overloaded operator(). Build a CXXOperatorCallExpr @@ -3630,7 +3631,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,      }    } -  return CheckFunctionCall(Method, TheCall.take()); +  return CheckFunctionCall(Method, TheCall.take()).release();  }  /// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator-> @@ -3700,7 +3701,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,    Base = new CXXOperatorCallExpr(FnExpr, &Base, 1,                                    Method->getResultType().getNonReferenceType(),                                   OpLoc); -  return ActOnMemberReferenceExpr(S, Base, OpLoc, tok::arrow, MemberLoc, Member); +  return ActOnMemberReferenceExpr(S, ExprArg(*this, Base), OpLoc, tok::arrow, +                                  MemberLoc, Member).release();  }  /// FixOverloadedFunctionReference - E is an expression that refers to  | 

