r229852 - FIX PR 18432, default args, friends & late-parsed members.

Nathan Sidwell nathan at acm.org
Thu Feb 19 06:03:22 PST 2015


Author: nathan
Date: Thu Feb 19 08:03:22 2015
New Revision: 229852

URL: http://llvm.org/viewvc/llvm-project?rev=229852&view=rev
Log:
FIX PR 18432, default args, friends & late-parsed members.

Sema::MergeCXXFunctionDecl: propagate hasUnparsedDefaultArg to new decl.

Parser::HandleMemberFunctionDeclDelays: check hasUnparsedDefaultArg
flag.

Parser::ParseLexedMethodDeclaration: handle inherited unparsed default
arg case.

Modified:
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=229852&r1=229851&r2=229852&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Thu Feb 19 08:03:22 2015
@@ -306,8 +306,9 @@ void Parser::ParseLexedMethodDeclaration
   ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope |
                             Scope::FunctionDeclarationScope | Scope::DeclScope);
   for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
-    auto Param = LM.DefaultArgs[I].Param;
+    auto Param = cast<ParmVarDecl>(LM.DefaultArgs[I].Param);
     // Introduce the parameter into scope.
+    bool HasUnparsed = Param->hasUnparsedDefaultArg();
     Actions.ActOnDelayedCXXMethodParameter(getCurScope(), Param);
     if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
       // Mark the end of the default argument so that we know when to stop when
@@ -371,6 +372,16 @@ void Parser::ParseLexedMethodDeclaration
 
       delete Toks;
       LM.DefaultArgs[I].Toks = nullptr;
+    } else if (HasUnparsed) {
+      assert(Param->hasInheritedDefaultArg());
+      FunctionDecl *Old = cast<FunctionDecl>(LM.Method)->getPreviousDecl();
+      ParmVarDecl *OldParam = Old->getParamDecl(I);
+      assert (!OldParam->hasUnparsedDefaultArg());
+      if (OldParam->hasUninstantiatedDefaultArg())
+        Param->setUninstantiatedDefaultArg(
+                                      Param->getUninstantiatedDefaultArg());
+      else
+        Param->setDefaultArg(OldParam->getInit());
     }
   }
 

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=229852&r1=229851&r2=229852&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Feb 19 08:03:22 2015
@@ -1896,13 +1896,16 @@ void Parser::HandleMemberFunctionDeclDel
   // late parse
   bool NeedLateParse = FTI.getExceptionSpecType() == EST_Unparsed;
 
-  if (!NeedLateParse)
+  if (!NeedLateParse) {
     // Look ahead to see if there are any default args
-    for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx)
-      if (FTI.Params[ParamIdx].DefaultArgTokens) {
+    for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) {
+      auto Param = cast<ParmVarDecl>(FTI.Params[ParamIdx].Param);
+      if (Param->hasUnparsedDefaultArg()) {
         NeedLateParse = true;
         break;
       }
+    }
+  }
 
   if (NeedLateParse) {
     // Push this method onto the stack of late-parsed method

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=229852&r1=229851&r2=229852&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Feb 19 08:03:22 2015
@@ -521,7 +521,9 @@ bool Sema::MergeCXXFunctionDecl(Function
       // It's important to use getInit() here;  getDefaultArg()
       // strips off any top-level ExprWithCleanups.
       NewParam->setHasInheritedDefaultArg();
-      if (OldParam->hasUninstantiatedDefaultArg())
+      if (OldParam->hasUnparsedDefaultArg())
+        NewParam->setUnparsedDefaultArg();
+      else if (OldParam->hasUninstantiatedDefaultArg())
         NewParam->setUninstantiatedDefaultArg(
                                       OldParam->getUninstantiatedDefaultArg());
       else

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp?rev=229852&r1=229851&r2=229852&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp Thu Feb 19 08:03:22 2015
@@ -54,3 +54,22 @@ namespace N1 {
     f2(6); // okay
   }
 }
+
+
+namespace PR18432 {
+
+struct A {
+  struct B {
+    static void Foo (int = 0);
+  };
+  
+  // should not hide default args
+  friend void B::Foo (int);
+};
+
+void Test ()
+{
+  A::B::Foo ();
+}
+
+} // namespace





More information about the cfe-commits mailing list