[cfe-commits] r62475 - in /cfe/trunk: Driver/PrintParserCallbacks.cpp include/clang/Parse/Action.h lib/Parse/ParseExpr.cpp lib/Parse/ParseStmt.cpp lib/Sema/Sema.h lib/Sema/SemaChecking.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp

Daniel Dunbar daniel at zuster.org
Wed Jan 21 11:52:12 PST 2009


My performance tester is pointing at this for a 2.5% regression in
syntax only time.  Is this inherent and the price we have to pay for
cleanup, or unexpected?

It would be nice if someone could inspect the code generation for the
smart pointers to see if there is any performance we can reclaim.

 - Daniel

On Sun, Jan 18, 2009 at 4:08 PM, Sebastian Redl
<sebastian.redl at getdesigned.at> wrote:
> Author: cornedbee
> Date: Sun Jan 18 18:08:26 2009
> New Revision: 62475
>
> URL: http://llvm.org/viewvc/llvm-project?rev=62475&view=rev
> Log:
> Convert more expression actions to smart pointers.
> Fix type of logical negation for C++.
>
> Modified:
>    cfe/trunk/Driver/PrintParserCallbacks.cpp
>    cfe/trunk/include/clang/Parse/Action.h
>    cfe/trunk/lib/Parse/ParseExpr.cpp
>    cfe/trunk/lib/Parse/ParseStmt.cpp
>    cfe/trunk/lib/Sema/Sema.h
>    cfe/trunk/lib/Sema/SemaChecking.cpp
>    cfe/trunk/lib/Sema/SemaExpr.cpp
>    cfe/trunk/lib/Sema/SemaOverload.cpp
>
> Modified: cfe/trunk/Driver/PrintParserCallbacks.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/PrintParserCallbacks.cpp?rev=62475&r1=62474&r2=62475&view=diff
>
> ==============================================================================
> --- cfe/trunk/Driver/PrintParserCallbacks.cpp (original)
> +++ cfe/trunk/Driver/PrintParserCallbacks.cpp Sun Jan 18 18:08:26 2009
> @@ -499,50 +499,48 @@
>     }
>
>     // 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 ExprEmpty();
> +    }
> +    virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base,
> +                                                     SourceLocation LLoc,
> +                                                     ExprArg Idx,
> +                                                     SourceLocation RLoc) {
> +      llvm::cout << __FUNCTION__ << "\n";
> +      return ExprEmpty();
> +    }
> +    virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
> +                                                      SourceLocation OpLoc,
> +                                                      tok::TokenKind OpKind,
> +                                                      SourceLocation MemberLoc,
> +                                                      IdentifierInfo &Member) {
>       llvm::cout << __FUNCTION__ << "\n";
> -      return 0;
> -    }
> -    virtual ExprResult ActOnArraySubscriptExpr(Scope *S, ExprTy *Base,
> -                                               SourceLocation LLoc, ExprTy *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) {
> -      llvm::cout << __FUNCTION__ << "\n";
> -      return 0;
> -    }
> -
> -    /// 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,
>
> Modified: cfe/trunk/include/clang/Parse/Action.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=62475&r1=62474&r2=62475&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Action.h (original)
> +++ cfe/trunk/include/clang/Parse/Action.h Sun Jan 18 18:08:26 2009
> @@ -587,46 +587,48 @@
>   }
>
>   // 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;
>
> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=62475&r1=62474&r2=62475&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Sun Jan 18 18:08:26 2009
> @@ -548,8 +548,7 @@
>     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 @@
>     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 @@
>     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 @@
>       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 @@
>       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 @@
>       }
>
>       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 @@
>     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 @@
>     // 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
>
> Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=62475&r1=62474&r2=62475&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseStmt.cpp Sun Jan 18 18:08:26 2009
> @@ -391,8 +391,8 @@
>         }
>
>         // 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;
>
>
> Modified: cfe/trunk/lib/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=62475&r1=62474&r2=62475&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/Sema.h (original)
> +++ cfe/trunk/lib/Sema/Sema.h Sun Jan 18 18:08:26 2009
> @@ -249,6 +249,9 @@
>   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 @@
>
>   /// 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 @@
>   /// 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,
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=62475&r1=62474&r2=62475&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Sun Jan 18 18:08:26 2009
> @@ -24,52 +24,54 @@
>
>  /// 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 @@
>   // 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 @@
>     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 @@
>
>  /// 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 @@
>     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 @@
>     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 @@
>     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 @@
>   }
>
>   // 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;
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=62475&r1=62474&r2=62475&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Jan 18 18:08:26 2009
> @@ -1032,11 +1032,11 @@
>  /// 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 @@
>   }
>
>   // 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 @@
>
>
>
> -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 @@
>   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 @@
>         // 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 @@
>           << 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 @@
>   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 @@
>     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 @@
>               PerformCopyInitialization(RHSExp,
>                                         FnDecl->getParamDecl(0)->getType(),
>                                         "passing"))
> -            return true;
> +            return ExprError();
>         } else {
>           // Convert the arguments.
>           if (PerformCopyInitialization(LHSExp,
> @@ -1228,20 +1233,22 @@
>               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 @@
>                                       "passing") ||
>             PerformCopyInitialization(RHSExp, Best->BuiltinTypes.ParamTypes[1],
>                                       "passing"))
> -          return true;
> +          return ExprError();
>
>         break;
>       }
> @@ -1266,7 +1273,7 @@
>           << "[]"
>           << 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 @@
>   // 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 @@
>     // 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 @@
>   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 @@
>
>     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 @@
>       // (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 @@
>         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 @@
>
>     // 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 @@
>
>     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 @@
>             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 @@
>     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 @@
>  /// 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 @@
>                                      /*SS=*/0,
>                                      /*ForceResolution=*/true);
>         if (Resolved.isInvalid())
> -          return true;
> +          return ExprError();
>         else {
>           delete Fn;
>           Fn = (Expr *)Resolved.release();
> @@ -1769,20 +1787,21 @@
>   // 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 @@
>     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 @@
>
>   // 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 @@
>
>   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 @@
>  }
>
>  // 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 @@
>         // 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 @@
>           << 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 @@
>              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 @@
>       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 @@
>     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".
>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=62475&r1=62474&r2=62475&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Jan 18 18:08:26 2009
> @@ -3436,7 +3436,7 @@
>                               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 @@
>     // 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 @@
>     }
>   }
>
> -  return CheckFunctionCall(Method, TheCall.take());
> +  return CheckFunctionCall(Method, TheCall.take()).release();
>  }
>
>  /// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator->
> @@ -3700,7 +3701,8 @@
>   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
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>



More information about the cfe-commits mailing list