aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-06-12 16:51:40 +0000
committerAnders Carlsson <andersca@mac.com>2009-06-12 16:51:40 +0000
commit5e300d1a8e37f24e71f8cf204b982f20f85cf91a (patch)
tree4ecedfd5067b9578a835d6f0ccb3df0c7bf9b463 /lib/Sema
parent859ba504e754436e1ccf81f50800e5d2ea647447 (diff)
It's an error to use a function declared in a class definition as a default argument before the function has been declared.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73234 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.h8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp15
-rw-r--r--lib/Sema/SemaExpr.cpp12
3 files changed, 30 insertions, 5 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 2df1ae2950..c4b3b2d050 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -412,8 +412,14 @@ public:
SourceLocation EqualLoc,
ExprArg defarg);
virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
- SourceLocation EqualLoc);
+ SourceLocation EqualLoc,
+ SourceLocation ArgLoc);
virtual void ActOnParamDefaultArgumentError(DeclPtrTy param);
+
+ // Contains the locations of the beginning of unparsed default
+ // argument locations.
+ llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
+
virtual void AddInitializerToDecl(DeclPtrTy dcl, FullExprArg init);
void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
void ActOnUninitializedDecl(DeclPtrTy dcl);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b59ac879d1..8f64e78c52 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -108,6 +108,8 @@ void
Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc,
ExprArg defarg) {
ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+ UnparsedDefaultArgLocs.erase(Param);
+
ExprOwningPtr<Expr> DefaultArg(this, defarg.takeAs<Expr>());
QualType ParamType = Param->getType();
@@ -154,16 +156,23 @@ Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc,
/// because we're inside a class definition. Note that this default
/// argument will be parsed later.
void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
- SourceLocation EqualLoc) {
+ SourceLocation EqualLoc,
+ SourceLocation ArgLoc) {
ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
if (Param)
Param->setUnparsedDefaultArg();
+
+ UnparsedDefaultArgLocs[Param] = ArgLoc;
}
/// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
/// the default argument for the parameter param failed.
void Sema::ActOnParamDefaultArgumentError(DeclPtrTy param) {
- cast<ParmVarDecl>(param.getAs<Decl>())->setInvalidDecl();
+ ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+
+ Param->setInvalidDecl();
+
+ UnparsedDefaultArgLocs.erase(Param);
}
/// CheckExtraCXXDefaultArguments - Check for any extra default
@@ -285,7 +294,7 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
// in a semantically valid state.
for (p = 0; p <= LastMissingDefaultArg; ++p) {
ParmVarDecl *Param = FD->getParamDecl(p);
- if (Param->getDefaultArg()) {
+ if (Param->hasDefaultArg()) {
if (!Param->hasUnparsedDefaultArg())
Param->getDefaultArg()->Destroy(Context);
Param->setDefaultArg(0);
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 1abd5fb302..c01c812be6 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2484,9 +2484,19 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
// Pass the argument.
if (PerformCopyInitialization(Arg, ProtoArgType, "passing"))
return true;
- } else
+ } else {
+ if (FDecl->getParamDecl(i)->hasUnparsedDefaultArg()) {
+ Diag (Call->getSourceRange().getBegin(),
+ diag::err_use_of_default_argument_to_function_declared_later) <<
+ FDecl << cast<CXXRecordDecl>(FDecl->getDeclContext())->getDeclName();
+ Diag(UnparsedDefaultArgLocs[FDecl->getParamDecl(i)],
+ diag::note_default_argument_declared_here);
+ }
+
// We already type-checked the argument, so we know it works.
Arg = new (Context) CXXDefaultArgExpr(FDecl->getParamDecl(i));
+ }
+
QualType ArgType = Arg->getType();
Call->setArg(i, Arg);