diff options
| author | Anders Carlsson <andersca@mac.com> | 2009-08-25 03:49:14 +0000 | 
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2009-08-25 03:49:14 +0000 | 
| commit | 355933d0962e86cc496a99e2f719d10544578aff (patch) | |
| tree | 6779841a35d58cfb0293a04b5a839dcf68d04505 | |
| parent | 94ec649b335f1f9022dac1f6e4af2344d41788c2 (diff) | |
| download | bcm5719-llvm-355933d0962e86cc496a99e2f719d10544578aff.tar.gz bcm5719-llvm-355933d0962e86cc496a99e2f719d10544578aff.zip  | |
Factor building of CXXDefaultArgExpr expressions out into a separate function.
llvm-svn: 79974
| -rw-r--r-- | clang/lib/Sema/Sema.h | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 111 | 
2 files changed, 65 insertions, 52 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 31c2aafd6ca..96ea4204f0c 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1763,6 +1763,12 @@ public:                                bool Elidable,                                Expr **Exprs, unsigned NumExprs); +  /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating +  /// the default expr if needed. +  OwningExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc, +                                          FunctionDecl *FD, +                                          ParmVarDecl *Param); +      /// FinalizeVarWithDestructor - Prepare for calling destructor on the    /// constructed variable.    void FinalizeVarWithDestructor(VarDecl *VD, QualType DeclInitType); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 013273cd8c0..4fc9db034b1 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2429,6 +2429,57 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,    return ExprError();  } +Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, +                                                    FunctionDecl *FD, +                                                    ParmVarDecl *Param) { +  if (Param->hasUnparsedDefaultArg()) { +    Diag (CallLoc, +          diag::err_use_of_default_argument_to_function_declared_later) << +      FD << cast<CXXRecordDecl>(FD->getDeclContext())->getDeclName(); +    Diag(UnparsedDefaultArgLocs[Param],  +          diag::note_default_argument_declared_here); +  } else { +    if (Param->hasUninstantiatedDefaultArg()) { +      Expr *UninstExpr = Param->getUninstantiatedDefaultArg(); + +      // Instantiate the expression. +      const TemplateArgumentList &ArgList = getTemplateInstantiationArgs(FD); +       +      // FIXME: We should really make a new InstantiatingTemplate ctor +      // that has a better message - right now we're just piggy-backing  +      // off the "default template argument" error message. +      InstantiatingTemplate Inst(*this, CallLoc, FD->getPrimaryTemplate(), +                                 ArgList.getFlatArgumentList(), +                                 ArgList.flat_size()); + +      OwningExprResult Result = InstantiateExpr(UninstExpr, ArgList); +      if (Result.isInvalid())  +        return ExprError(); +       +      if (SetParamDefaultArgument(Param, move(Result),  +                                  /*FIXME:EqualLoc*/ +                                  UninstExpr->getSourceRange().getBegin())) +        return ExprError(); +    } +     +    Expr *DefaultExpr = Param->getDefaultArg(); +     +    // If the default expression creates temporaries, we need to +    // push them to the current stack of expression temporaries so they'll +    // be properly destroyed. +    if (CXXExprWithTemporaries *E  +          = dyn_cast_or_null<CXXExprWithTemporaries>(DefaultExpr)) { +      assert(!E->shouldDestroyTemporaries() &&  +             "Can't destroy temporaries in a default argument expr!"); +      for (unsigned I = 0, N = E->getNumTemporaries(); I != N; ++I) +        ExprTemporaries.push_back(E->getTemporary(I)); +    } +  } + +  // We already type-checked the argument, so we know it works. +  return Owned(CXXDefaultArgExpr::Create(Context, Param)); +} +  /// ConvertArgumentsForCall - Converts the arguments specified in  /// Args/NumArgs to the parameter types of the function FDecl with  /// function prototype Proto. Call is the call expression itself, and @@ -2493,60 +2544,16 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,          return true;      } else {        ParmVarDecl *Param = FDecl->getParamDecl(i); -      if (Param->hasUnparsedDefaultArg()) { -        Diag (Call->getSourceRange().getBegin(), -              diag::err_use_of_default_argument_to_function_declared_later) << -        FDecl << cast<CXXRecordDecl>(FDecl->getDeclContext())->getDeclName(); -        Diag(UnparsedDefaultArgLocs[Param],  -              diag::note_default_argument_declared_here); -      } else { -        if (Param->hasUninstantiatedDefaultArg()) { -          Expr *UninstExpr = Param->getUninstantiatedDefaultArg(); - -          // Instantiate the expression. -          const TemplateArgumentList &ArgList =  -            getTemplateInstantiationArgs(FDecl); -           -          // FIXME: We should really make a new InstantiatingTemplate ctor -          // that has a better message - right now we're just piggy-backing  -          // off the "default template argument" error message. -          InstantiatingTemplate Inst(*this, Call->getSourceRange().getBegin(), -                                     FDecl->getPrimaryTemplate(), -                                     ArgList.getFlatArgumentList(), -                                     ArgList.flat_size()); - -          OwningExprResult Result -            = InstantiateExpr(UninstExpr,  -                              getTemplateInstantiationArgs(FDecl)); -          if (Result.isInvalid())  -            return true; -           -          if (SetParamDefaultArgument(Param, move(Result),  -                                      /*FIXME:EqualLoc*/ -                                      UninstExpr->getSourceRange().getBegin())) -            return true; -        } -         -        Expr *DefaultExpr = Param->getDefaultArg(); -         -        // If the default expression creates temporaries, we need to -        // push them to the current stack of expression temporaries so they'll -        // be properly destroyed. -        if (CXXExprWithTemporaries *E  -              = dyn_cast_or_null<CXXExprWithTemporaries>(DefaultExpr)) { -          assert(!E->shouldDestroyTemporaries() &&  -                 "Can't destroy temporaries in a default argument expr!"); -          for (unsigned I = 0, N = E->getNumTemporaries(); I != N; ++I) -            ExprTemporaries.push_back(E->getTemporary(I)); -        } -      } -   -      // We already type-checked the argument, so we know it works. -      Arg = CXXDefaultArgExpr::Create(Context, Param); +      +      OwningExprResult ArgExpr =  +        BuildCXXDefaultArgExpr(Call->getSourceRange().getBegin(), +                               FDecl, Param); +      if (ArgExpr.isInvalid()) +        return true; +       +      Arg = ArgExpr.takeAs<Expr>();      } -    QualType ArgType = Arg->getType(); -      Call->setArg(i, Arg);    }  | 

