]> granicus.if.org Git - clang/commitdiff
[coroutines] Better handling of placeholder types.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 20 Nov 2015 22:57:24 +0000 (22:57 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 20 Nov 2015 22:57:24 +0000 (22:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@253731 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCoroutine.cpp
test/SemaCXX/coroutines.cpp

index 471fab90e8042e3cc1af91fdf89c46e96a67fa18..8d91e43f41ee98fd1c64d390f55d39c6634afe1a 100644 (file)
@@ -209,6 +209,12 @@ static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, SourceLocation Loc,
 }
 
 ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
+  if (E->getType()->isPlaceholderType()) {
+    ExprResult R = CheckPlaceholderExpr(E);
+    if (R.isInvalid()) return ExprError();
+    E = R.get();
+  }
+
   ExprResult Awaitable = buildOperatorCoawaitCall(*this, S, Loc, E);
   if (Awaitable.isInvalid())
     return ExprError();
@@ -219,18 +225,18 @@ ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
   if (!Coroutine)
     return ExprError();
 
-  if (E->getType()->isDependentType()) {
-    Expr *Res = new (Context) CoawaitExpr(Loc, Context.DependentTy, E);
-    Coroutine->CoroutineStmts.push_back(Res);
-    return Res;
-  }
-
   if (E->getType()->isPlaceholderType()) {
     ExprResult R = CheckPlaceholderExpr(E);
     if (R.isInvalid()) return ExprError();
     E = R.get();
   }
 
+  if (E->getType()->isDependentType()) {
+    Expr *Res = new (Context) CoawaitExpr(Loc, Context.DependentTy, E);
+    Coroutine->CoroutineStmts.push_back(Res);
+    return Res;
+  }
+
   // FIXME: If E is a prvalue, create a temporary.
   // FIXME: If E is an xvalue, convert to lvalue.
 
@@ -261,6 +267,12 @@ static ExprResult buildYieldValueCall(Sema &S, FunctionScopeInfo *Coroutine,
 }
 
 ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
+  if (E->getType()->isPlaceholderType()) {
+    ExprResult R = CheckPlaceholderExpr(E);
+    if (R.isInvalid()) return ExprError();
+    E = R.get();
+  }
+
   auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
   if (!Coroutine)
     return ExprError();
@@ -282,6 +294,12 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
   if (!Coroutine)
     return ExprError();
 
+  if (E->getType()->isPlaceholderType()) {
+    ExprResult R = CheckPlaceholderExpr(E);
+    if (R.isInvalid()) return ExprError();
+    E = R.get();
+  }
+
   // FIXME: Build await_* calls.
   Expr *Res = new (Context) CoyieldExpr(Loc, Context.VoidTy, E);
   Coroutine->CoroutineStmts.push_back(Res);
@@ -292,6 +310,12 @@ StmtResult Sema::ActOnCoreturnStmt(SourceLocation Loc, Expr *E) {
   return BuildCoreturnStmt(Loc, E);
 }
 StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) {
+  if (E && E->getType()->isPlaceholderType()) {
+    ExprResult R = CheckPlaceholderExpr(E);
+    if (R.isInvalid()) return StmtError();
+    E = R.get();
+  }
+
   auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");
   if (!Coroutine)
     return StmtError();
index 15536d83074040696101bf345e83745f68140c0f..53226f7af21a34014ab43c167c318274b3e3af2a 100644 (file)
@@ -140,3 +140,18 @@ namespace dependent_operator_co_await_lookup {
   template void await_template(outer); // expected-note {{instantiation}}
   template void await_template_2(outer);
 }
+
+namespace placeholder {
+  awaitable f(), f(int); // expected-note 2{{possible target}}
+  int g(), g(int); // expected-note 4{{possible target}}
+  void x() {
+    co_await f; // expected-error {{reference to overloaded function}}
+  }
+  void y() {
+    co_yield g; // expected-error {{reference to overloaded function}}
+  }
+  void z() {
+    co_await a;
+    co_return g; // expected-error {{reference to overloaded function}}
+  }
+}