[cfe-commits] r123913 - in /cfe/trunk: lib/AST/ASTDiagnostic.cpp lib/Parse/ParseTentative.cpp lib/Sema/SemaInit.cpp lib/Sema/SemaType.cpp test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp

Douglas Gregor dgregor at apple.com
Thu Jan 20 08:08:07 PST 2011


Author: dgregor
Date: Thu Jan 20 10:08:06 2011
New Revision: 123913

URL: http://llvm.org/viewvc/llvm-project?rev=123913&view=rev
Log:
Add some tests for reference-collapsing and referencing binding
involving rvalue references, to start scoping out what is and what
isn't implemented. In the process, tweak some standards citations,
type desugaring, and teach the tentative parser about && in
ptr-operator.

Added:
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp   (with props)
    cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp   (with props)
Modified:
    cfe/trunk/lib/AST/ASTDiagnostic.cpp
    cfe/trunk/lib/Parse/ParseTentative.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=123913&r1=123912&r2=123913&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Thu Jan 20 10:08:06 2011
@@ -103,6 +103,9 @@
   } else if (const LValueReferenceType *Ty = QT->getAs<LValueReferenceType>()) {
     QT = Context.getLValueReferenceType(Desugar(Context, Ty->getPointeeType(),
                                                 ShouldAKA));
+  } else if (const RValueReferenceType *Ty = QT->getAs<RValueReferenceType>()) {
+    QT = Context.getRValueReferenceType(Desugar(Context, Ty->getPointeeType(),
+                                                ShouldAKA));
   }
 
   return QC.apply(Context, QT);

Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=123913&r1=123912&r2=123913&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Thu Jan 20 10:08:06 2011
@@ -506,6 +506,7 @@
         return TPResult::Error();
 
     if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
+        Tok.is(tok::ampamp) ||
         (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
       // ptr-operator
       ConsumeToken();
@@ -608,6 +609,7 @@
   case tok::l_square:
   case tok::l_paren:
   case tok::amp:
+  case tok::ampamp:
   case tok::star:
   case tok::plus:
   case tok::plusplus:

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=123913&r1=123912&r2=123913&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Jan 20 10:08:06 2011
@@ -2575,9 +2575,7 @@
 
   //     - Otherwise, the reference shall be an lvalue reference to a 
   //       non-volatile const type (i.e., cv1 shall be const), or the reference
-  //       shall be an rvalue reference and the initializer expression shall 
-  //       be an rvalue or have a function type.
-  // We handled the function type stuff above.
+  //       shall be an rvalue reference.
   if (!((isLValueRef && T1Quals.hasConst() && !T1Quals.hasVolatile()) ||
         (isRValueRef && InitCategory.isRValue()))) {
     if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy)

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=123913&r1=123912&r2=123913&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jan 20 10:08:06 2011
@@ -1001,14 +1001,14 @@
 QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
                                   SourceLocation Loc,
                                   DeclarationName Entity) {
+  // C++0x [dcl.ref]p6:
+  //   If a typedef (7.1.3), a type template-parameter (14.3.1), or a 
+  //   decltype-specifier (7.1.6.2) denotes a type TR that is a reference to a 
+  //   type T, an attempt to create the type "lvalue reference to cv TR" creates 
+  //   the type "lvalue reference to T", while an attempt to create the type 
+  //   "rvalue reference to cv TR" creates the type TR.
   bool LValueRef = SpelledAsLValue || T->getAs<LValueReferenceType>();
 
-  // C++0x [dcl.typedef]p9: If a typedef TD names a type that is a
-  //   reference to a type T, and attempt to create the type "lvalue
-  //   reference to cv TD" creates the type "lvalue reference to T".
-  // We use the qualifiers (restrict or none) of the original reference,
-  // not the new ones. This is consistent with GCC.
-
   // C++ [dcl.ref]p4: There shall be no references to references.
   //
   // According to C++ DR 106, references to references are only
@@ -1020,8 +1020,8 @@
   //
   // Parser::ParseDeclaratorInternal diagnoses the case where
   // references are written directly; here, we handle the
-  // collapsing of references-to-references as described in C++
-  // DR 106 and amended by C++ DR 540.
+  // collapsing of references-to-references as described in C++0x.
+  // DR 106 and 540 introduce reference-collapsing into C++98/03.
 
   // C++ [dcl.ref]p1:
   //   A declarator that specifies the type "reference to cv void"

Added: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp?rev=123913&view=auto
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp (added)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp Thu Jan 20 10:08:06 2011
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Test the C++0x-specific reference initialization rules, e.g., the
+// rules for rvalue references.
+template<typename T> T prvalue();
+template<typename T> T&& xvalue();
+template<typename T> T& lvalue();
+
+struct Base { };
+struct Derived : Base { };
+
+struct HasArray {
+  int array[5];
+};
+
+int f(int);
+
+void test_rvalue_refs() {
+  // If the initializer expression...
+
+  //   - is an xvalue, class prvalue, array prvalue or function lvalue
+  //     and "cv1 T1" is reference-compatible with "cv2 T2", or
+
+  // xvalue case
+  Base&& base0 = xvalue<Base>();
+  Base&& base1 = xvalue<Derived>();
+  int&& int0 = xvalue<int>();
+
+  // class prvalue case
+  Base&& base2 = prvalue<Base>();
+  Base&& base3 = prvalue<Derived>();
+
+  // FIXME: array prvalue case
+  //  int (&&array0)[5] = HasArray().array;
+
+  // function lvalue case
+  int (&&function0)(int) = f;
+}

Propchange: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp?rev=123913&view=auto
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp (added)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp Thu Jan 20 10:08:06 2011
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T, typename U> 
+struct is_same {
+  static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+  static const bool value = true;
+};
+#define JOIN2(X,Y) X##Y
+#define JOIN(X,Y) JOIN2(X,Y)
+#define CHECK_EQUAL_TYPES(T1, T2) \
+  int JOIN(array,__LINE__)[is_same<T1, T2>::value? 1 : -1]
+
+int i; 
+typedef int& LRI; 
+typedef int&& RRI;
+
+typedef LRI& r1; CHECK_EQUAL_TYPES(r1, int&);
+typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&);
+typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&);
+
+typedef RRI& r4; CHECK_EQUAL_TYPES(r4, int&);
+typedef RRI&& r5; CHECK_EQUAL_TYPES(r5, int&&);

Propchange: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list