-Add support for cv-qualifiers after function declarators.
-Add withConst/withVolatile/withRestrict methods to QualType class, that return the QualType plus the respective qualifier.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58120 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 27133d6..6bcb90b 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1213,6 +1213,8 @@
 ///         direct-declarator '(' identifier-list[opt] ')'
 /// [GNU]   direct-declarator '(' parameter-forward-declarations
 ///                    parameter-type-list[opt] ')'
+/// [C++]   direct-declarator '(' parameter-declaration-clause ')'
+///                    cv-qualifier-seq[opt] exception-specification[opt]
 ///
 void Parser::ParseDirectDeclarator(Declarator &D) {
   // Parse the first direct-declarator seen.
@@ -1371,6 +1373,9 @@
 ///           '=' 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]"(TODO).
+///
 void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
                                      AttributeList *AttrList,
                                      bool RequiresArg) {
@@ -1383,20 +1388,29 @@
       Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
       delete AttrList;
     }
-    
+
+    ConsumeParen();  // Eat the closing ')'.
+
+    // cv-qualifier-seq[opt].
+    DeclSpec DS;
+    if (getLang().CPlusPlus) {
+      ParseTypeQualifierListOpt(DS);
+      // FIXME: Parse exception-specification[opt].
+    }
+
     // Remember that we parsed a function type, and remember the attributes.
     // int() -> no prototype, no '...'.
-    D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/ false,
+    D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
                                                /*variadic*/ false,
-                                               /*arglist*/ 0, 0, LParenLoc));
-    
-    ConsumeParen();  // Eat the closing ')'.
+                                               /*arglist*/ 0, 0,
+                                               DS.getTypeQualifiers(),
+                                               LParenLoc));
     return;
   } 
   
   // Alternatively, this parameter list may be an identifier list form for a
   // K&R-style function:  void foo(a,b,c)
-  if (Tok.is(tok::identifier) &&
+  if (!getLang().CPlusPlus && Tok.is(tok::identifier) &&
       // K&R identifier lists can't have typedefs as identifiers, per
       // C99 6.7.5.3p11.
       !Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) {
@@ -1508,13 +1522,21 @@
   // Leave prototype scope.
   ExitScope();
   
+  // If we have the closing ')', eat it.
+  MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+  // cv-qualifier-seq[opt].
+  DeclSpec DS;
+  if (getLang().CPlusPlus) {
+    ParseTypeQualifierListOpt(DS);
+    // FIXME: Parse exception-specification[opt].
+  }
+
   // Remember that we parsed a function type, and remember the attributes.
   D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
                                              &ParamInfo[0], ParamInfo.size(),
+                                             DS.getTypeQualifiers(),
                                              LParenLoc));
-  
-  // If we have the closing ')', eat it and we're done.
-  MatchRHSPunctuation(tok::r_paren, LParenLoc);
 }
 
 /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
@@ -1581,7 +1603,7 @@
   // has no prototype.
   D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
                                              &ParamInfo[0], ParamInfo.size(),
-                                             LParenLoc));
+                                             /*TypeQuals*/0, LParenLoc));
   
   // If we have the closing ')', eat it and we're done.
   MatchRHSPunctuation(tok::r_paren, LParenLoc);