diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 19 | ||||
-rw-r--r-- | test/SemaCXX/decltype-overloaded-functions.cpp | 12 |
5 files changed, 39 insertions, 3 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 2af10b22fb..8d56b57c08 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -398,6 +398,10 @@ def err_init_reference_member_uninitialized : Error< def note_uninit_reference_member : Note< "uninitialized reference member is here">; +// C++0x decltype +def err_cannot_determine_declared_type_of_overloaded_function : Error< + "can't determine the declared type of an overloaded function">; + // C++0x auto def err_auto_variable_cannot_appear_in_own_initializer : Error< "variable %0 declared with 'auto' type cannot appear in its own initializer">; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index a53e420db3..cbd4f58d48 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -406,6 +406,9 @@ public: QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T); + QualType BuildTypeofExprType(Expr *E); + QualType BuildDecltypeType(Expr *E); + //===--------------------------------------------------------------------===// // Symbol table / Decl tracking callbacks: SemaDecl.cpp. // diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index aed348966a..f05323b511 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -530,7 +530,7 @@ TemplateTypeInstantiator::InstantiateTypeOfExprType( if (E.isInvalid()) return QualType(); - return SemaRef.Context.getTypeOfExprType(E.takeAs<Expr>()); + return SemaRef.BuildTypeofExprType(E.takeAs<Expr>()); } QualType @@ -555,7 +555,7 @@ TemplateTypeInstantiator::InstantiateDecltypeType(const DecltypeType *T) const { if (E.isInvalid()) return QualType(); - return SemaRef.Context.getDecltypeType(E.takeAs<Expr>()); + return SemaRef.BuildDecltypeType(E.takeAs<Expr>()); } QualType diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 1c67daece0..c0b4e9fbec 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -242,7 +242,11 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS, Expr *E = static_cast<Expr *>(DS.getTypeRep()); assert(E && "Didn't get an expression for decltype?"); // TypeQuals handled by caller. - Result = Context.getDecltypeType(E); + Result = BuildDecltypeType(E); + if (Result.isNull()) { + Result = Context.IntTy; + isInvalid = true; + } break; } case DeclSpec::TST_auto: { @@ -1463,3 +1467,16 @@ QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) { = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); return Context.getQualifiedNameType(NNS, T); } + +QualType Sema::BuildTypeofExprType(Expr *E) { + return Context.getTypeOfExprType(E); +} + +QualType Sema::BuildDecltypeType(Expr *E) { + if (E->getType() == Context.OverloadTy) { + Diag(E->getLocStart(), + diag::err_cannot_determine_declared_type_of_overloaded_function); + return QualType(); + } + return Context.getDecltypeType(E); +} diff --git a/test/SemaCXX/decltype-overloaded-functions.cpp b/test/SemaCXX/decltype-overloaded-functions.cpp new file mode 100644 index 0000000000..4c5349b858 --- /dev/null +++ b/test/SemaCXX/decltype-overloaded-functions.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -fsyntax-only -verify %s -std=c++0x + +void f(); +void f(int); +decltype(f) a; // expected-error{{can't determine the declared type of an overloaded function}} + +template<typename T> struct S { + decltype(T::f) * f; // expected-error{{can't determine the declared type of an overloaded function}} +}; + +struct K { void f(); void f(int); }; +S<K> b; // expected-note{{in instantiation of template class 'struct S<struct K>' requested here}} |