Fix the parsing of default arguments for inline member function
authorEli Friedman <eli.friedman@gmail.com>
Wed, 22 Jul 2009 21:45:50 +0000 (21:45 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 22 Jul 2009 21:45:50 +0000 (21:45 +0000)
definitions.

I'm not very familiar with this code, so please review.

llvm-svn: 76796

clang/include/clang/Parse/Parser.h
clang/lib/Parse/ParseCXXInlineMethods.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/test/SemaCXX/default2.cpp

index bebc874..dc6a577 100644 (file)
@@ -1147,6 +1147,8 @@ private:
   void ParseCXXClassMemberDeclaration(AccessSpecifier AS);
   void ParseConstructorInitializer(DeclPtrTy ConstructorDecl);
   MemInitResult ParseMemInitializer(DeclPtrTy ConstructorDecl);
+  void HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
+                                       DeclPtrTy ThisDecl);
 
   //===--------------------------------------------------------------------===//
   // C++ 10: Derived classes [class.derived]
index 613e0e3..8afffe3 100644 (file)
@@ -29,6 +29,8 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
 
   DeclPtrTy FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0);
 
+  HandleMemberFunctionDefaultArgs(D, FnD);
+
   // Consume the tokens and store them for later parsing.
 
   getCurrentClass().MethodDefs.push_back(LexedMethod(FnD));
index b9b2979..930d58d 100644 (file)
@@ -852,6 +852,39 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const
   }
 }
 
+void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
+                                             DeclPtrTy ThisDecl) {
+  // We just declared a member function. If this member function
+  // has any default arguments, we'll need to parse them later.
+  LateParsedMethodDeclaration *LateMethod = 0;
+  DeclaratorChunk::FunctionTypeInfo &FTI 
+    = DeclaratorInfo.getTypeObject(0).Fun;
+  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
+    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
+      if (!LateMethod) {
+        // Push this method onto the stack of late-parsed method
+        // declarations.
+        getCurrentClass().MethodDecls.push_back(
+                                LateParsedMethodDeclaration(ThisDecl));
+        LateMethod = &getCurrentClass().MethodDecls.back();
+
+        // Add all of the parameters prior to this one (they don't
+        // have default arguments).
+        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
+        for (unsigned I = 0; I < ParamIdx; ++I)
+          LateMethod->DefaultArgs.push_back(
+                    LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
+      }
+
+      // Add this parameter to the list of parameters (it or may
+      // not have a default argument).
+      LateMethod->DefaultArgs.push_back(
+        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
+                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
+    }
+  }
+}
+
 /// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
 ///
 ///       member-declaration:
@@ -1047,35 +1080,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
     if (DeclaratorInfo.isFunctionDeclarator() &&
         DeclaratorInfo.getDeclSpec().getStorageClassSpec() 
           != DeclSpec::SCS_typedef) {
-      // We just declared a member function. If this member function
-      // has any default arguments, we'll need to parse them later.
-      LateParsedMethodDeclaration *LateMethod = 0;
-      DeclaratorChunk::FunctionTypeInfo &FTI 
-        = DeclaratorInfo.getTypeObject(0).Fun;
-      for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
-        if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
-          if (!LateMethod) {
-            // Push this method onto the stack of late-parsed method
-            // declarations.
-            getCurrentClass().MethodDecls.push_back(
-                                   LateParsedMethodDeclaration(ThisDecl));
-            LateMethod = &getCurrentClass().MethodDecls.back();
-
-            // Add all of the parameters prior to this one (they don't
-            // have default arguments).
-            LateMethod->DefaultArgs.reserve(FTI.NumArgs);
-            for (unsigned I = 0; I < ParamIdx; ++I)
-              LateMethod->DefaultArgs.push_back(
-                        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
-          }
-
-          // Add this parameter to the list of parameters (it or may
-          // not have a default argument).
-          LateMethod->DefaultArgs.push_back(
-            LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
-                                      FTI.ArgInfo[ParamIdx].DefaultArgTokens));
-        }
-      }
+      HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
     }
 
     // If we don't have a comma, it is either the end of the list (a ';')
index edbd6b3..dc83ac4 100644 (file)
@@ -127,3 +127,9 @@ class C2 {
   static void g(int = f()); // expected-error{{use of default argument to function 'f' that is declared later in class 'C2'}}
   static int f(int = 10); // expected-note{{default argument declared here}}
 };
+
+// Make sure we actually parse the default argument for an inline definition
+class XX {
+  void A(int length = -1 ) {  } 
+  void B() { A(); }
+};