]> granicus.if.org Git - clang/commitdiff
[coroutines] Tweak diagnostics to always use fully-qualified name for std::coroutine_...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 19 Nov 2015 02:36:35 +0000 (02:36 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 19 Nov 2015 02:36:35 +0000 (02:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@253535 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaCoroutine.cpp
test/SemaCXX/coroutines.cpp

index 61f365377034a2bc54727e64a6446f5563215386..03bea29627cfeb1686200e2410df1d84fe7757aa 100644 (file)
@@ -7971,14 +7971,14 @@ def ext_coroutine_without_co_await_co_yield : ExtWarn<
 def err_implied_std_coroutine_traits_not_found : Error<
   "you need to include <coroutine> before defining a coroutine">;
 def err_malformed_std_coroutine_traits : Error<
-  "std::coroutine_traits must be a class template">;
+  "'std::coroutine_traits' must be a class template">;
 def err_implied_std_coroutine_traits_promise_type_not_found : Error<
-  "this function cannot be a coroutine: %0 has no member named 'promise_type'">;
+  "this function cannot be a coroutine: %q0 has no member named 'promise_type'">;
 def err_implied_std_coroutine_traits_promise_type_not_class : Error<
   "this function cannot be a coroutine: %0 is not a class">;
 def err_coroutine_traits_missing_specialization : Error<
   "this function cannot be a coroutine: missing definition of "
-  "specialization %0">;
+  "specialization %q0">;
 }
 
 let CategoryName = "Documentation Issue" in {
index a2a79001f0d88f6c52a714c89e6bd47424abe890..210f30e2a4ee32aaba0ff1d424241acb0643e5fc 100644 (file)
@@ -82,6 +82,12 @@ static QualType lookupPromiseType(Sema &S, const FunctionProtoType *FnType,
   // The promise type is required to be a class type.
   QualType PromiseType = S.Context.getTypeDeclType(Promise);
   if (!PromiseType->getAsCXXRecordDecl()) {
+    // Use the fully-qualified name of the type.
+    auto *NNS = NestedNameSpecifier::Create(S.Context, nullptr, Std);
+    NNS = NestedNameSpecifier::Create(S.Context, NNS, false,
+                                      CoroTrait.getTypePtr());
+    PromiseType = S.Context.getElaboratedType(ETK_None, NNS, PromiseType);
+
     S.Diag(Loc, diag::err_implied_std_coroutine_traits_promise_type_not_class)
       << PromiseType;
     return QualType();
index 3e18187295dcb58967d3f6c2e87d7d5cb8628909..c82302c3c0708063657d0547aa572471b49bc9ae 100644 (file)
@@ -21,7 +21,12 @@ void no_specialization() {
 template<typename ...T> struct std::coroutine_traits<int, T...> {};
 
 int no_promise_type() {
-  co_await a; // expected-error {{this function cannot be a coroutine: 'coroutine_traits<int>' has no member named 'promise_type'}}
+  co_await a; // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<int>' has no member named 'promise_type'}}
+}
+
+template<> struct std::coroutine_traits<double, double> { typedef int promise_type; };
+double bad_promise_type(double) {
+  co_await a; // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
 }
 
 struct promise; // expected-note {{forward declaration}}