aaronpuchert updated this revision to Diff 246862.
aaronpuchert added a comment.

Rebase on top of D66437 <https://reviews.llvm.org/D66437>.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67112/new/

https://reviews.llvm.org/D67112

Files:
  clang/include/clang/AST/OperationKinds.def
  clang/include/clang/Sema/Initialization.h
  clang/lib/Sema/SemaInit.cpp
  clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4-ast.cpp

Index: clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4-ast.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4-ast.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++17 -ast-dump %s | FileCheck %s
+
+void f() noexcept;
+// CHECK: VarDecl {{.*}} fp 'void (&)()' cinit
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void ()':'void ()' lvalue <NoOp>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'void () noexcept' lvalue Function {{.*}} 'f' 'void () noexcept'
+void (&fp)() = f;
+
+struct X {
+  typedef void (&fp)() noexcept;
+  operator fp();
+} x;
+
+// CHECK: VarDecl {{.*}} xp 'void (&)()' cinit
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void ()':'void ()' lvalue <NoOp>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void () noexcept':'void () noexcept' lvalue <UserDefinedConversion>
+void (&xp)() = x;
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -3417,6 +3417,7 @@
   case SK_QualificationConversionRValue:
   case SK_QualificationConversionXValue:
   case SK_QualificationConversionLValue:
+  case SK_FunctionReferenceConversion:
   case SK_AtomicConversion:
   case SK_ListInitialization:
   case SK_UnwrapInitList:
@@ -3594,6 +3595,13 @@
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddFunctionReferenceConversionStep(QualType Ty) {
+  Step S;
+  S.Kind = SK_FunctionReferenceConversion;
+  S.Type = Ty;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::AddAtomicConversionStep(QualType Ty) {
   Step S;
   S.Kind = SK_AtomicConversion;
@@ -4627,7 +4635,7 @@
   else if (RefConv & Sema::ReferenceConversions::ObjC)
     Sequence.AddObjCObjectConversionStep(cv1T1);
   else if (RefConv & Sema::ReferenceConversions::Function)
-    Sequence.AddQualificationConversionStep(cv1T1, VK);
+    Sequence.AddFunctionReferenceConversionStep(cv1T1);
   else if (RefConv & Sema::ReferenceConversions::Qualification) {
     if (!S.Context.hasSameType(cv1T4, cv1T1))
       Sequence.AddQualificationConversionStep(cv1T1, VK);
@@ -4725,12 +4733,12 @@
           Sequence.AddDerivedToBaseCastStep(cv1T1, VK_LValue);
         else
           Sequence.AddObjCObjectConversionStep(cv1T1);
-      } else if (RefConv & (Sema::ReferenceConversions::Qualification |
-                            Sema::ReferenceConversions::Function)) {
+      } else if (RefConv & Sema::ReferenceConversions::Qualification) {
         // Perform a (possibly multi-level) qualification conversion.
-        // FIXME: Should we use a different step kind for function conversions?
         Sequence.AddQualificationConversionStep(cv1T1,
                                                 Initializer->getValueKind());
+      } else if (RefConv & Sema::ReferenceConversions::Function) {
+        Sequence.AddFunctionReferenceConversionStep(cv1T1);
       }
 
       // We only create a temporary here when binding a reference to a
@@ -7897,6 +7905,7 @@
   case SK_QualificationConversionLValue:
   case SK_QualificationConversionXValue:
   case SK_QualificationConversionRValue:
+  case SK_FunctionReferenceConversion:
   case SK_AtomicConversion:
   case SK_ConversionSequence:
   case SK_ConversionSequenceNoNarrowing:
@@ -8162,6 +8171,13 @@
       break;
     }
 
+    case SK_FunctionReferenceConversion:
+      assert(CurInit.get()->isLValue() &&
+             "function reference should be lvalue");
+      CurInit =
+          S.ImpCastExprToType(CurInit.get(), Step->Type, CK_NoOp, VK_LValue);
+      break;
+
     case SK_AtomicConversion: {
       assert(CurInit.get()->isRValue() && "cannot convert glvalue to atomic");
       CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
@@ -9398,6 +9414,10 @@
       OS << "qualification conversion (lvalue)";
       break;
 
+    case SK_FunctionReferenceConversion:
+      OS << "function reference conversion";
+      break;
+
     case SK_AtomicConversion:
       OS << "non-atomic-to-atomic conversion";
       break;
Index: clang/include/clang/Sema/Initialization.h
===================================================================
--- clang/include/clang/Sema/Initialization.h
+++ clang/include/clang/Sema/Initialization.h
@@ -818,6 +818,9 @@
     /// Perform a qualification conversion, producing an lvalue.
     SK_QualificationConversionLValue,
 
+    /// Perform a function reference conversion, see [dcl.init.ref]p4.
+    SK_FunctionReferenceConversion,
+
     /// Perform a conversion adding _Atomic to a type.
     SK_AtomicConversion,
 
@@ -1263,6 +1266,10 @@
   void AddQualificationConversionStep(QualType Ty,
                                      ExprValueKind Category);
 
+  /// Add a new step that performs a function reference conversion to the
+  /// given type.
+  void AddFunctionReferenceConversionStep(QualType Ty);
+
   /// Add a new step that performs conversion from non-atomic to atomic
   /// type.
   void AddAtomicConversionStep(QualType Ty);
Index: clang/include/clang/AST/OperationKinds.def
===================================================================
--- clang/include/clang/AST/OperationKinds.def
+++ clang/include/clang/AST/OperationKinds.def
@@ -77,9 +77,10 @@
 CAST_OPERATION(LValueToRValue)
 
 /// CK_NoOp - A conversion which does not affect the type other than
-/// (possibly) adding qualifiers.
+/// (possibly) adding qualifiers or removing noexcept.
 ///   int    -> int
 ///   char** -> const char * const *
+///   void () noexcept -> void ()
 CAST_OPERATION(NoOp)
 
 /// CK_BaseToDerived - A conversion from a C++ class pointer/reference
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D67112: [Sema] Add i... Aaron Puchert via Phabricator via cfe-commits

Reply via email to