[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-10-04 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

@modocache I do need someone to land this for me! Take it away!


Repository:
  rC Clang

https://reviews.llvm.org/D51741



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-10-04 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 updated this revision to Diff 168380.
tks2103 added a comment.

comply with clang-format


Repository:
  rC Clang

https://reviews.llvm.org/D51741

Files:
  lib/Sema/SemaCoroutine.cpp
  test/SemaCXX/coroutine-rvo.cpp


Index: test/SemaCXX/coroutine-rvo.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-rvo.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z 
-fcoroutines-ts -fsyntax-only
+
+namespace std::experimental {
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+
+template 
+struct void_t_imp {
+  using type = void;
+};
+template 
+using void_t = typename void_t_imp::type;
+
+template 
+struct traits_sfinae_base {};
+
+template 
+struct traits_sfinae_base> {
+  using promise_type = typename T::promise_type;
+};
+
+template 
+struct coroutine_traits : public traits_sfinae_base {};
+}
+
+struct suspend_never {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct MoveOnly {
+  MoveOnly() {};
+  MoveOnly(const MoveOnly&) = delete;
+  MoveOnly(MoveOnly&&) noexcept {};
+  ~MoveOnly() {};
+};
+
+template 
+struct task {
+  struct promise_type {
+auto initial_suspend() { return suspend_never{}; }
+auto final_suspend() { return suspend_never{}; }
+auto get_return_object() { return task{}; }
+static void unhandled_exception() {}
+void return_value(T&& value) {}
+  };
+};
+
+task f() {
+  MoveOnly value;
+  co_return value;
+}
+
+int main() {
+  f();
+  return 0;
+}
+
+// expected-no-diagnostics
Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -841,6 +841,19 @@
 E = R.get();
   }
 
+  // Move the return value if we can
+  if (E) {
+auto NRVOCandidate = this->getCopyElisionCandidate(E->getType(), E, 
CES_AsIfByStdMove);
+if (NRVOCandidate) {
+  InitializedEntity Entity =
+  InitializedEntity::InitializeResult(Loc, E->getType(), 
NRVOCandidate);
+  ExprResult MoveResult = this->PerformMoveOrCopyInitialization(
+  Entity, NRVOCandidate, E->getType(), E);
+  if (MoveResult.get())
+E = MoveResult.get();
+}
+  }
+
   // FIXME: If the operand is a reference to a variable that's about to go out
   // of scope, we should treat the operand as an xvalue for this overload
   // resolution.


Index: test/SemaCXX/coroutine-rvo.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-rvo.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z -fcoroutines-ts -fsyntax-only
+
+namespace std::experimental {
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+
+template 
+struct void_t_imp {
+  using type = void;
+};
+template 
+using void_t = typename void_t_imp::type;
+
+template 
+struct traits_sfinae_base {};
+
+template 
+struct traits_sfinae_base> {
+  using promise_type = typename T::promise_type;
+};
+
+template 
+struct coroutine_traits : public traits_sfinae_base {};
+}
+
+struct suspend_never {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct MoveOnly {
+  MoveOnly() {};
+  MoveOnly(const MoveOnly&) = delete;
+  MoveOnly(MoveOnly&&) noexcept {};
+  ~MoveOnly() {};
+};
+
+template 
+struct task {
+  struct promise_type {
+auto initial_suspend() { return suspend_never{}; }
+auto final_suspend() { return suspend_never{}; }
+auto get_return_object() { return task{}; }
+static void unhandled_exception() {}
+void return_value(T&& value) {}
+  };
+};
+
+task f() {
+  MoveOnly value;
+  co_return value;
+}
+
+int main() {
+  f();
+  return 0;
+}
+
+// expected-no-diagnostics
Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -841,6 +841,19 @@
 E = R.get();
   }
 
+  // Move the return value if we can
+  if (E) {
+auto NRVOCandidate = this->getCopyElisionCandidate(E->getType(), E, CES_AsIfByStdMove);
+if (NRVOCandidate) {
+  InitializedEntity Entity =
+  InitializedEntity::InitializeResult(Loc, E->getType(), NRVOCandidate);
+ 

[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-09-25 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

ping @GorNishanov SAVE ME GOR! YOU'RE MY ONLY HOPE!


Repository:
  rC Clang

https://reviews.llvm.org/D51741



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-09-14 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

ping @GorNishanov


Repository:
  rC Clang

https://reviews.llvm.org/D51741



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-09-10 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

ping @GorNishanov


Repository:
  rC Clang

https://reviews.llvm.org/D51741



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-09-06 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 updated this revision to Diff 164265.
tks2103 added a comment.

get NRVOCandidate to determine if we should try to move return var


Repository:
  rC Clang

https://reviews.llvm.org/D51741

Files:
  lib/Sema/SemaCoroutine.cpp
  test/SemaCXX/coroutine-rvo.cpp


Index: test/SemaCXX/coroutine-rvo.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-rvo.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z 
-fcoroutines-ts -fsyntax-only
+
+namespace std::experimental {
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+
+template 
+struct void_t_imp {
+  using type = void;
+};
+template 
+using void_t = typename void_t_imp::type;
+
+template 
+struct traits_sfinae_base {};
+
+template 
+struct traits_sfinae_base> {
+  using promise_type = typename T::promise_type;
+};
+
+template 
+struct coroutine_traits : public traits_sfinae_base {};
+}
+
+struct suspend_never {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct MoveOnly {
+  MoveOnly() {};
+  MoveOnly(const MoveOnly&) = delete;
+  MoveOnly(MoveOnly&&) noexcept {};
+  ~MoveOnly() {};
+};
+
+template 
+struct task {
+  struct promise_type {
+auto initial_suspend() { return suspend_never{}; }
+auto final_suspend() { return suspend_never{}; }
+auto get_return_object() { return task{}; }
+static void unhandled_exception() {}
+void return_value(T&& value) {}
+  };
+};
+
+task f() {
+  MoveOnly value;
+  co_return value;
+}
+
+int main() {
+  f();
+  return 0;
+}
+
+// expected-no-diagnostics
Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -841,6 +841,19 @@
 E = R.get();
   }
 
+  // Move the return value if we can
+  if (E) {
+auto NRVOCandidate = this->getCopyElisionCandidate(E->getType(), E, 
CES_AsIfByStdMove);
+if (NRVOCandidate) {
+  InitializedEntity Entity =
+  InitializedEntity::InitializeResult(Loc, E->getType(), 
NRVOCandidate);
+  ExprResult MoveResult =
+  this->PerformMoveOrCopyInitialization(Entity, NRVOCandidate, 
E->getType(), E);
+  if (MoveResult.get())
+E = MoveResult.get();
+}
+  }
+
   // FIXME: If the operand is a reference to a variable that's about to go out
   // of scope, we should treat the operand as an xvalue for this overload
   // resolution.


Index: test/SemaCXX/coroutine-rvo.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-rvo.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z -fcoroutines-ts -fsyntax-only
+
+namespace std::experimental {
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+
+template 
+struct void_t_imp {
+  using type = void;
+};
+template 
+using void_t = typename void_t_imp::type;
+
+template 
+struct traits_sfinae_base {};
+
+template 
+struct traits_sfinae_base> {
+  using promise_type = typename T::promise_type;
+};
+
+template 
+struct coroutine_traits : public traits_sfinae_base {};
+}
+
+struct suspend_never {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct MoveOnly {
+  MoveOnly() {};
+  MoveOnly(const MoveOnly&) = delete;
+  MoveOnly(MoveOnly&&) noexcept {};
+  ~MoveOnly() {};
+};
+
+template 
+struct task {
+  struct promise_type {
+auto initial_suspend() { return suspend_never{}; }
+auto final_suspend() { return suspend_never{}; }
+auto get_return_object() { return task{}; }
+static void unhandled_exception() {}
+void return_value(T&& value) {}
+  };
+};
+
+task f() {
+  MoveOnly value;
+  co_return value;
+}
+
+int main() {
+  f();
+  return 0;
+}
+
+// expected-no-diagnostics
Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -841,6 +841,19 @@
 E = R.get();
   }
 
+  // Move the return value if we can
+  if (E) {
+auto NRVOCandidate = this->getCopyElisionCandidate(E->getType(), E, CES_AsIfByStdMove);
+if (NRVOCandidate) {
+  InitializedEntity Entity =
+  

[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-09-06 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

also fails 
https://github.com/llvm-mirror/clang/blob/master/test/SemaCXX/coroutines.cpp#L494
 with `address of overloaded function 'g' does not match required type 
''`
also fails 
https://github.com/llvm-mirror/clang/blob/master/test/SemaCXX/coroutines.cpp#L505
 with `address of overloaded function 'g' does not match required type 
''`


Repository:
  rC Clang

https://reviews.llvm.org/D51741



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-09-06 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

currently changes the behavior for a few cases:

something like

  void coro() {
co_return {4};
  }

throws `illegal initializer type 'void'`


Repository:
  rC Clang

https://reviews.llvm.org/D51741



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51741: [coro]Pass rvalue reference for named local variable to return_value

2018-09-06 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 created this revision.
tks2103 added reviewers: modocache, GorNishanov.
Herald added a subscriber: cfe-commits.
tks2103 edited the summary of this revision.

Addressing https://bugs.llvm.org/show_bug.cgi?id=37265.

Implements [class.copy]/33 of coroutines TS

When the criteria for elision of a copy/move operation are met, but not
for an exception-declaration, and the object to be copied is designated by an 
lvalue, or when the
expression in a return or co_return statement is a (possibly parenthesized) 
id-expression that
names an object with automatic storage duration declared in the body or
parameter-declaration-clause of the innermost enclosing function or 
lambda-expression, overload resolution to select
the constructor for the copy or the return_value overload to call is first 
performed as if the object
were designated by an rvalue.


Repository:
  rC Clang

https://reviews.llvm.org/D51741

Files:
  lib/Sema/SemaCoroutine.cpp
  test/SemaCXX/coroutine-rvo.cpp


Index: test/SemaCXX/coroutine-rvo.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-rvo.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z 
-fcoroutines-ts -fsyntax-only
+
+namespace std::experimental {
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+
+template 
+struct void_t_imp {
+  using type = void;
+};
+template 
+using void_t = typename void_t_imp::type;
+
+template 
+struct traits_sfinae_base {};
+
+template 
+struct traits_sfinae_base> {
+  using promise_type = typename T::promise_type;
+};
+
+template 
+struct coroutine_traits : public traits_sfinae_base {};
+}
+
+struct suspend_never {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct MoveOnly {
+  MoveOnly() {};
+  MoveOnly(const MoveOnly&) = delete;
+  MoveOnly(MoveOnly&&) noexcept {};
+  ~MoveOnly() {};
+};
+
+template 
+struct task {
+  struct promise_type {
+auto initial_suspend() { return suspend_never{}; }
+auto final_suspend() { return suspend_never{}; }
+auto get_return_object() { return task{}; }
+static void unhandled_exception() {}
+void return_value(T&& value) {}
+  };
+};
+
+task f() {
+  MoveOnly value;
+  co_return value;
+}
+
+int main() {
+  f();
+  return 0;
+}
+
+// expected-no-diagnostics
Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -841,6 +841,16 @@
 E = R.get();
   }
 
+  // Move the return value if we can
+  if (E) {
+InitializedEntity Entity =
+InitializedEntity::InitializeResult(Loc, E->getType(), false);
+ExprResult MoveResult =
+this->PerformMoveOrCopyInitialization(Entity, nullptr, E->getType(), 
E);
+if (MoveResult.get())
+  E = MoveResult.get();
+  }
+
   // FIXME: If the operand is a reference to a variable that's about to go out
   // of scope, we should treat the operand as an xvalue for this overload
   // resolution.


Index: test/SemaCXX/coroutine-rvo.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-rvo.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z -fcoroutines-ts -fsyntax-only
+
+namespace std::experimental {
+template  struct coroutine_handle {
+  coroutine_handle() = default;
+  static coroutine_handle from_address(void *) noexcept;
+};
+
+template <> struct coroutine_handle {
+  static coroutine_handle from_address(void *) noexcept;
+  coroutine_handle() = default;
+  template 
+  coroutine_handle(coroutine_handle) noexcept;
+};
+
+template 
+struct void_t_imp {
+  using type = void;
+};
+template 
+using void_t = typename void_t_imp::type;
+
+template 
+struct traits_sfinae_base {};
+
+template 
+struct traits_sfinae_base> {
+  using promise_type = typename T::promise_type;
+};
+
+template 
+struct coroutine_traits : public traits_sfinae_base {};
+}
+
+struct suspend_never {
+  bool await_ready() noexcept;
+  void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+  void await_resume() noexcept;
+};
+
+struct MoveOnly {
+  MoveOnly() {};
+  MoveOnly(const MoveOnly&) = delete;
+  MoveOnly(MoveOnly&&) noexcept {};
+  ~MoveOnly() {};
+};
+
+template 
+struct task {
+  struct promise_type {
+auto initial_suspend() { return suspend_never{}; }
+auto final_suspend() { return suspend_never{}; }
+auto get_return_object() { return task{}; }
+static void unhandled_exception() {}
+void return_value(T&& value) {}
+  };
+};
+
+task f() {
+  

[PATCH] D48981: Add caching when looking up coroutine_traits

2018-07-13 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

ping @modocache @GorNishanov


Repository:
  rC Clang

https://reviews.llvm.org/D48981



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49099: Remove qualtype qualifier in coroutine error to prevent assert in debug

2018-07-10 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

@modocache please commit on my behalf please =)


Repository:
  rC Clang

https://reviews.llvm.org/D49099



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49099: Remove qualtype qualifier in coroutine error to prevent assert in debug

2018-07-09 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 created this revision.
tks2103 added reviewers: modocache, GorNishanov.

A forward-declared coroutine_traits should trip an error; we need
a complete type.

Unfortunately, in debug mode only, we trip an assert when attempting
to provide the fully qualified type for the error message.
If you try to compile a program with a forward-declared
coroutine_traits in debug mode, clang will crash.

I've included a test for the behavior and removed the q modifier
on the error message. This prevents the crash in debug mode and
does not change the behavior for the error message on a
forward-declaration of a coroutine_traits type.

Test Plan:
I've included a test for the forward-declaration.


Repository:
  rC Clang

https://reviews.llvm.org/D49099

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  test/SemaCXX/coroutine-traits-undefined-template.cpp


Index: test/SemaCXX/coroutine-traits-undefined-template.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-traits-undefined-template.cpp
@@ -0,0 +1,21 @@
+// test/SemaCXX/coroutine-traits-undefined-template.cpp
+
+// This file contains references to sections of the Coroutines TS, which can be
+// found at http://wg21.link/coroutines.
+
+// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions 
-fexceptions -Wunused-result
+
+namespace std {
+namespace experimental {
+
+template
+struct coroutine_traits {
+  struct promise_type {};
+};
+
+template<> struct coroutine_traits; // expected-note {{forward 
declaration of 'std::experimental::coroutine_traits'}}
+}} // namespace std::experimental
+
+void uses_forward_declaration() {
+  co_return; // expected-error {{this function cannot be a coroutine: missing 
definition of specialization 'coroutine_traits'}}
+}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -9071,7 +9071,7 @@
   "this function cannot be a coroutine: %0 is an incomplete type">;
 def err_coroutine_type_missing_specialization : Error<
   "this function cannot be a coroutine: missing definition of "
-  "specialization %q0">;
+  "specialization %0">;
 def err_coroutine_promise_incompatible_return_functions : Error<
   "the coroutine promise type %0 declares both 'return_value' and 
'return_void'">;
 def err_coroutine_promise_requires_return_function : Error<


Index: test/SemaCXX/coroutine-traits-undefined-template.cpp
===
--- /dev/null
+++ test/SemaCXX/coroutine-traits-undefined-template.cpp
@@ -0,0 +1,21 @@
+// test/SemaCXX/coroutine-traits-undefined-template.cpp
+
+// This file contains references to sections of the Coroutines TS, which can be
+// found at http://wg21.link/coroutines.
+
+// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -Wunused-result
+
+namespace std {
+namespace experimental {
+
+template
+struct coroutine_traits {
+  struct promise_type {};
+};
+
+template<> struct coroutine_traits; // expected-note {{forward declaration of 'std::experimental::coroutine_traits'}}
+}} // namespace std::experimental
+
+void uses_forward_declaration() {
+  co_return; // expected-error {{this function cannot be a coroutine: missing definition of specialization 'coroutine_traits'}}
+}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -9071,7 +9071,7 @@
   "this function cannot be a coroutine: %0 is an incomplete type">;
 def err_coroutine_type_missing_specialization : Error<
   "this function cannot be a coroutine: missing definition of "
-  "specialization %q0">;
+  "specialization %0">;
 def err_coroutine_promise_incompatible_return_functions : Error<
   "the coroutine promise type %0 declares both 'return_value' and 'return_void'">;
 def err_coroutine_promise_requires_return_function : Error<
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48981: Add caching when looking up coroutine_traits

2018-07-09 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 added a comment.

ping @modocache @GorNishanov


Repository:
  rC Clang

https://reviews.llvm.org/D48981



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48981: Add caching when looking up coroutine_traits

2018-07-05 Thread Tanoy Sinha via Phabricator via cfe-commits
tks2103 created this revision.
tks2103 added reviewers: GorNishanov, modocache.

Currently clang looks up the coroutine_traits ClassTemplateDecl
everytime it looks up the promise type. This is unnecessary
as coroutine_traits doesn't change between promise type lookups.

This diff caches the coroutine_traits lookup.

Test Plan:
I added log statements in the new `lookupCoroutineTraits` function
to ensure that `LookupQualifiedName` was only called once even
when multiple coroutines existed in the source file.


Repository:
  rC Clang

https://reviews.llvm.org/D48981

Files:
  include/clang/Sema/Sema.h
  lib/Sema/Sema.cpp
  lib/Sema/SemaCoroutine.cpp


Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -60,20 +60,8 @@
 return QualType();
   }
 
-  LookupResult Result(S, ().get("coroutine_traits"),
-  FuncLoc, Sema::LookupOrdinaryName);
-  if (!S.LookupQualifiedName(Result, StdExp)) {
-S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
-<< "std::experimental::coroutine_traits";
-return QualType();
-  }
-
-  ClassTemplateDecl *CoroTraits = Result.getAsSingle();
+  ClassTemplateDecl *CoroTraits = S.lookupCoroutineTraits(KwLoc, FuncLoc);
   if (!CoroTraits) {
-Result.suppressDiagnostics();
-// We found something weird. Complain about the first thing we found.
-NamedDecl *Found = *Result.begin();
-S.Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
 return QualType();
   }
 
@@ -1538,3 +1526,27 @@
 return StmtError();
   return Res;
 }
+
+ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc,
+   SourceLocation FuncLoc) {
+  if (!StdCoroutineTraitsCache) {
+if (auto StdExp = lookupStdExperimentalNamespace()) {
+  LookupResult Result(*this,
+  ().get("coroutine_traits"),
+  FuncLoc, LookupOrdinaryName);
+  if (!LookupQualifiedName(Result, StdExp)) {
+Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
+<< "std::experimental::coroutine_traits";
+return nullptr;
+  }
+  if (!(StdCoroutineTraitsCache =
+Result.getAsSingle())) {
+Result.suppressDiagnostics();
+NamedDecl *Found = *Result.begin();
+Diag(Found->getLocation(), diag::err_malformed_std_coroutine_traits);
+return nullptr;
+  }
+}
+  }
+  return StdCoroutineTraitsCache;
+}
Index: lib/Sema/Sema.cpp
===
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -131,9 +131,9 @@
   IsBuildingRecoveryCallExpr(false), Cleanup{}, 
LateTemplateParser(nullptr),
   LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), 
IdResolver(pp),
   StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr),
-  CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr), NSNumberDecl(nullptr),
-  NSValueDecl(nullptr), NSStringDecl(nullptr),
-  StringWithUTF8StringMethod(nullptr),
+  StdCoroutineTraitsCache(nullptr), CXXTypeInfoDecl(nullptr),
+  MSVCGuidDecl(nullptr), NSNumberDecl(nullptr), NSValueDecl(nullptr),
+  NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr),
   ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr),
   ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr),
   DictionaryWithObjectsMethod(nullptr), GlobalNewDeleteDeclared(false),
Index: include/clang/Sema/Sema.h
===
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -824,6 +824,10 @@
   /// \.
   ClassTemplateDecl *StdInitializerList;
 
+  /// The C++ "std::coroutine_traits" template, which is defined in
+  /// \
+  ClassTemplateDecl *StdCoroutineTraitsCache;
+
   /// The C++ "type_info" declaration, which is defined in \.
   RecordDecl *CXXTypeInfoDecl;
 
@@ -8572,6 +8576,8 @@
   bool buildCoroutineParameterMoves(SourceLocation Loc);
   VarDecl *buildCoroutinePromise(SourceLocation Loc);
   void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *);
+  ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc,
+   SourceLocation FuncLoc);
 
   
//======//
   // OpenCL extensions.


Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -60,20 +60,8 @@
 return QualType();
   }
 
-  LookupResult Result(S, ().get("coroutine_traits"),
-  FuncLoc, Sema::LookupOrdinaryName);
-  if (!S.LookupQualifiedName(Result, StdExp)) {
-S.Diag(KwLoc, diag::err_implied_coroutine_type_not_found)
-<< "std::experimental::coroutine_traits";
-return QualType();
-  }
-