diff options
| author | Anders Carlsson <andersca@mac.com> | 2009-09-08 01:48:42 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2009-09-08 01:48:42 +0000 |
| commit | 6816affaa4fdbaa16ad9167ac87e6071c80b75a6 (patch) | |
| tree | 9472c1d8180b3533708cd912e094eafcabb8d72e /clang/lib | |
| parent | f4a0f0f03306f65c7a898621a40be9373fbe1bfb (diff) | |
| download | bcm5719-llvm-6816affaa4fdbaa16ad9167ac87e6071c80b75a6.tar.gz bcm5719-llvm-6816affaa4fdbaa16ad9167ac87e6071c80b75a6.zip | |
Handle variadic constructors better. Share code between BuildCXXConstructExpr and BuildCXXTemporaryObjectExpr.
llvm-svn: 81181
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 84 |
2 files changed, 61 insertions, 26 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 12cafe83c56..a040a0f169e 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -3287,7 +3287,8 @@ public: enum VariadicCallType { VariadicFunction, VariadicBlock, - VariadicMethod + VariadicMethod, + VariadicConstructor }; // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8c5384b471c..c37ff10941c 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2834,6 +2834,60 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, Elidable, move(ExprArgs)); } +static bool +CheckConstructArgumentTypes(Sema &SemaRef, SourceLocation ConstructLoc, + CXXConstructExpr *E) { + CXXConstructorDecl *Ctor = E->getConstructor(); + const FunctionProtoType *Proto = Ctor->getType()->getAsFunctionProtoType(); + + unsigned NumArgs = E->getNumArgs(); + unsigned NumArgsInProto = Proto->getNumArgs(); + unsigned NumRequiredArgs = Ctor->getMinRequiredArguments(); + + for (unsigned i = 0; i != NumArgsInProto; ++i) { + QualType ProtoArgType = Proto->getArgType(i); + + Expr *Arg; + + if (i < NumRequiredArgs) { + Arg = E->getArg(i); + + // Pass the argument. + // FIXME: Do this. + } else { + // Build a default argument. + ParmVarDecl *Param = Ctor->getParamDecl(i); + + Sema::OwningExprResult ArgExpr = + SemaRef.BuildCXXDefaultArgExpr(ConstructLoc, Ctor, Param); + if (ArgExpr.isInvalid()) + return true; + + Arg = ArgExpr.takeAs<Expr>(); + } + + E->setArg(i, Arg); + } + + // If this is a variadic call, handle args passed through "...". + if (Proto->isVariadic()) { + bool Invalid = false; + + // Promote the arguments (C99 6.5.2.2p7). + for (unsigned i = NumArgsInProto; i != NumArgs; i++) { + Expr *Arg = E->getArg(i); + Invalid |= + SemaRef.DefaultVariadicArgumentPromotion(Arg, + Sema::VariadicConstructor); + E->setArg(i, Arg); + } + + return Invalid; + } + + return false; +} + /// BuildCXXConstructExpr - Creates a complete call to a constructor, /// including handling of its default argument expressions. Sema::OwningExprResult @@ -2850,19 +2904,10 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, Elidable, Exprs, NumExprs)); - // Default arguments must be added to constructor call expression. - FunctionDecl *FDecl = cast<FunctionDecl>(Constructor); - unsigned NumArgsInProto = FDecl->param_size(); - for (unsigned j = NumExprs; j != NumArgsInProto; j++) { - ParmVarDecl *Param = FDecl->getParamDecl(j); - - OwningExprResult ArgExpr = - BuildCXXDefaultArgExpr(ConstructLoc, FDecl, Param); - if (ArgExpr.isInvalid()) - return ExprError(); + + if (CheckConstructArgumentTypes(*this, ConstructLoc, Temp.get())) + return ExprError(); - Temp->setArg(j, ArgExpr.takeAs<Expr>()); - } return move(Temp); } @@ -2879,20 +2924,9 @@ Sema::BuildCXXTemporaryObjectExpr(CXXConstructorDecl *Constructor, ExprOwningPtr<CXXTemporaryObjectExpr> Temp(this, E); - // Default arguments must be added to constructor call expression. - FunctionDecl *FDecl = cast<FunctionDecl>(Constructor); - unsigned NumArgsInProto = FDecl->param_size(); - for (unsigned j = Args.size(); j != NumArgsInProto; j++) { - ParmVarDecl *Param = FDecl->getParamDecl(j); - - OwningExprResult ArgExpr = BuildCXXDefaultArgExpr(TyBeginLoc, FDecl, Param); - if (ArgExpr.isInvalid()) - return ExprError(); - - Temp->setArg(j, ArgExpr.takeAs<Expr>()); - } + if (CheckConstructArgumentTypes(*this, TyBeginLoc, Temp.get())) + return ExprError(); - Args.release(); return move(Temp); } |

