]> granicus.if.org Git - clang/commitdiff
Rvalue references for *this: parse ref-qualifiers.
authorDouglas Gregor <dgregor@apple.com>
Wed, 26 Jan 2011 03:43:54 +0000 (03:43 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 26 Jan 2011 03:43:54 +0000 (03:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124276 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/DeclSpec.h
lib/Parse/ParseDecl.cpp
lib/Parse/ParseExpr.cpp
lib/Sema/DeclSpec.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaType.cpp
test/CXX/dcl.decl/p4-0x.cpp [new file with mode: 0644]

index 65c95dc4c68a2e0a62ce56165e138c7e35a8a33a..59962ae3b70b31e53231903db5e4f5c9ed80e323 100644 (file)
@@ -898,6 +898,10 @@ struct DeclaratorChunk {
     /// contains the location of the ellipsis.
     unsigned isVariadic : 1;
 
+    /// \brief Whether the ref-qualifier (if any) is an lvalue reference.
+    /// Otherwise, it's an rvalue reference.
+    unsigned RefQualifierIsLValueRef : 1;
+    
     /// The type qualifiers: const/volatile/restrict.
     /// The qualifier bitmask values are the same as in QualType.
     unsigned TypeQuals : 3;
@@ -922,6 +926,11 @@ struct DeclaratorChunk {
     /// the function has one.
     unsigned NumExceptions;
 
+    /// \brief The location of the ref-qualifier, if any.
+    ///
+    /// If this is an invalid location, there is no ref-qualifier.
+    unsigned RefQualifierLoc;
+    
     /// ThrowLoc - When hasExceptionSpec is true, the location of the throw
     /// keyword introducing the spec.
     unsigned ThrowLoc;
@@ -970,6 +979,15 @@ struct DeclaratorChunk {
     SourceLocation getThrowLoc() const {
       return SourceLocation::getFromRawEncoding(ThrowLoc);
     }
+    
+    /// \brief Retrieve the location of the ref-qualifier, if any.
+    SourceLocation getRefQualifierLoc() const {
+      return SourceLocation::getFromRawEncoding(RefQualifierLoc);
+    }
+    
+    /// \brief Determine whether this function declaration contains a 
+    /// ref-qualifier.
+    bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); }
   };
 
   struct BlockPointerTypeInfo : TypeInfoCommon {
@@ -1084,7 +1102,10 @@ struct DeclaratorChunk {
                                      bool hasProto, bool isVariadic,
                                      SourceLocation EllipsisLoc,
                                      ParamInfo *ArgInfo, unsigned NumArgs,
-                                     unsigned TypeQuals, bool hasExceptionSpec,
+                                     unsigned TypeQuals, 
+                                     bool RefQualifierIsLvalueRef,
+                                     SourceLocation RefQualifierLoc,
+                                     bool hasExceptionSpec,
                                      SourceLocation ThrowLoc,
                                      bool hasAnyExceptionSpec,
                                      ParsedType *Exceptions,
index f4a79077a925df4ec302f11375ae0b59818b10f4..29f9921217d968baf5be95813eae07e1579cb0b8 100644 (file)
@@ -3064,8 +3064,8 @@ void Parser::ParseParenDeclarator(Declarator &D) {
 ///           '=' assignment-expression
 /// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
 ///
-/// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]"
-/// and "exception-specification[opt]".
+/// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]",
+/// C++0x "ref-qualifier[opt]" and "exception-specification[opt]".
 ///
 void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
                                      ParsedAttributes &attrs,
@@ -3085,6 +3085,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
 
     // cv-qualifier-seq[opt].
     DeclSpec DS;
+    SourceLocation RefQualifierLoc;
+    bool RefQualifierIsLValueRef = true;
     bool hasExceptionSpec = false;
     SourceLocation ThrowLoc;
     bool hasAnyExceptionSpec = false;
@@ -3097,6 +3099,16 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
       if (!DS.getSourceRange().getEnd().isInvalid())
         EndLoc = DS.getSourceRange().getEnd();
 
+      // Parse ref-qualifier[opt]
+      if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
+        if (!getLang().CPlusPlus0x)
+          Diag(Tok, diag::ext_rvalue_reference);
+        
+        RefQualifierIsLValueRef = Tok.is(tok::amp);
+        RefQualifierLoc = ConsumeToken();
+        EndLoc = RefQualifierLoc;
+      }
+      
       // Parse exception-specification[opt].
       if (Tok.is(tok::kw_throw)) {
         hasExceptionSpec = true;
@@ -3121,6 +3133,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
                                                SourceLocation(),
                                                /*arglist*/ 0, 0,
                                                DS.getTypeQualifiers(),
+                                               RefQualifierIsLValueRef,
+                                               RefQualifierLoc,
                                                hasExceptionSpec, ThrowLoc,
                                                hasAnyExceptionSpec,
                                                Exceptions.data(),
@@ -3320,6 +3334,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
   SourceLocation EndLoc = RParenLoc;
 
   DeclSpec DS;
+  SourceLocation RefQualifierLoc;
+  bool RefQualifierIsLValueRef = true;
   bool hasExceptionSpec = false;
   SourceLocation ThrowLoc;
   bool hasAnyExceptionSpec = false;
@@ -3334,6 +3350,16 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
       if (!DS.getSourceRange().getEnd().isInvalid())
         EndLoc = DS.getSourceRange().getEnd();
 
+    // Parse ref-qualifier[opt]
+    if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
+      if (!getLang().CPlusPlus0x)
+        Diag(Tok, diag::ext_rvalue_reference);
+      
+      RefQualifierIsLValueRef = Tok.is(tok::amp);
+      RefQualifierLoc = ConsumeToken();
+      EndLoc = RefQualifierLoc;
+    }
+
     // Parse exception-specification[opt].
     if (Tok.is(tok::kw_throw)) {
       hasExceptionSpec = true;
@@ -3362,6 +3388,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
                                              EllipsisLoc,
                                              ParamInfo.data(), ParamInfo.size(),
                                              DS.getTypeQualifiers(),
+                                             RefQualifierIsLValueRef,
+                                             RefQualifierLoc,
                                              hasExceptionSpec, ThrowLoc,
                                              hasAnyExceptionSpec,
                                              Exceptions.data(),
@@ -3443,6 +3471,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
                                              SourceLocation(),
                                              &ParamInfo[0], ParamInfo.size(),
                                              /*TypeQuals*/0,
+                                             true, SourceLocation(),
                                              /*exception*/false,
                                              SourceLocation(), false, 0, 0, 0,
                                              LParenLoc, RLoc, D),
index acbf3a5a927490956fe72642cf52e71bb978a7f5..67351f7e2fc92b6d7543bf905ce71a5b4703335a 100644 (file)
@@ -1859,6 +1859,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
                                                        true, false,
                                                        SourceLocation(),
                                                        0, 0, 0,
+                                                       true, SourceLocation(),
                                                        false, SourceLocation(),
                                                        false, 0, 0, 0,
                                                        CaretLoc, CaretLoc,
index 4152c5740a93d7f2414479799fed2bc7872476bd..8a35ab70923f904b3af1ae15cbe2805a17469b37 100644 (file)
@@ -52,6 +52,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
                                              ParamInfo *ArgInfo,
                                              unsigned NumArgs,
                                              unsigned TypeQuals,
+                                             bool RefQualifierIsLvalueRef,
+                                             SourceLocation RefQualifierLoc,
                                              bool hasExceptionSpec,
                                              SourceLocation ThrowLoc,
                                              bool hasAnyExceptionSpec,
@@ -74,6 +76,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
   I.Fun.TypeQuals        = TypeQuals;
   I.Fun.NumArgs          = NumArgs;
   I.Fun.ArgInfo          = 0;
+  I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
+  I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
   I.Fun.hasExceptionSpec = hasExceptionSpec;
   I.Fun.ThrowLoc         = ThrowLoc.getRawEncoding();
   I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
index 39d198be392139f363793c9b81d40320d8e399ff..1c487b8113ad7b74311f03bace9ee98396cd3e81 100644 (file)
@@ -5539,7 +5539,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
   Declarator D(DS, Declarator::BlockContext);
   D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
                                              false, false, SourceLocation(), 0,
-                                             0, 0, false, SourceLocation(),
+                                             0, 0, true, SourceLocation(),
+                                             false, SourceLocation(),
                                              false, 0,0,0, Loc, Loc, D),
                 SourceLocation());
   D.SetIdentifier(&II, Loc);
index 8ca1e008238b2ede585ebc5d6ab9a1afc48c9e10..b663f58f0328f5a2a6dd0a3a459fe32d75ef3be8 100644 (file)
@@ -520,6 +520,7 @@ static void maybeSynthesizeBlockSignature(TypeProcessingState &state,
                              /*variadic*/ false, SourceLocation(),
                              /*args*/ 0, 0,
                              /*type quals*/ 0,
+                             /*ref-qualifier*/true, SourceLocation(),
                              /*EH*/ false, SourceLocation(), false, 0, 0, 0,
                              /*parens*/ loc, loc,
                              declarator));
diff --git a/test/CXX/dcl.decl/p4-0x.cpp b/test/CXX/dcl.decl/p4-0x.cpp
new file mode 100644 (file)
index 0000000..9fa2ea1
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct X {
+  void f() &;
+  void g() &&;
+};
+
+void (X::*pmf)() & = &X::f;