[clang] 6c274ba - [clang-repl] Disambiguate declarations with private typedefs

Jonas Hahnfeld via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 23 02:30:30 PDT 2023


Author: Jonas Hahnfeld
Date: 2023-08-23T11:29:26+02:00
New Revision: 6c274ba4108b07358ebd4e8d607c72d6db8c8100

URL: https://github.com/llvm/llvm-project/commit/6c274ba4108b07358ebd4e8d607c72d6db8c8100
DIFF: https://github.com/llvm/llvm-project/commit/6c274ba4108b07358ebd4e8d607c72d6db8c8100.diff

LOG: [clang-repl] Disambiguate declarations with private typedefs

Member functions and static variable definitions may use typedefs that
are private in the global context, but fine in the class context.

Differential Revision: https://reviews.llvm.org/D157838

Added: 
    

Modified: 
    clang/lib/Parse/ParseTentative.cpp
    clang/test/Interpreter/disambiguate-decl-stmt.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index 66433705250010..45e73226d706b8 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -83,6 +83,17 @@ bool Parser::isCXXDeclarationStatement(
                                       isDeductionGuide,
                                       DeclSpec::FriendSpecified::No))
             return true;
+        } else if (SS.isNotEmpty()) {
+          // If the scope is not empty, it could alternatively be something like
+          // a typedef or using declaration. That declaration might be private
+          // in the global context, which would be diagnosed by calling into
+          // isCXXSimpleDeclaration, but may actually be fine in the context of
+          // member functions and static variable definitions. Check if the next
+          // token is also an identifier and assume a declaration.
+          // We cannot check if the scopes match because the declarations could
+          // involve namespaces and friend declarations.
+          if (NextToken().is(tok::identifier))
+            return true;
         }
         break;
       }

diff  --git a/clang/test/Interpreter/disambiguate-decl-stmt.cpp b/clang/test/Interpreter/disambiguate-decl-stmt.cpp
index cbc456da6eb512..a49d7013c540ac 100644
--- a/clang/test/Interpreter/disambiguate-decl-stmt.cpp
+++ b/clang/test/Interpreter/disambiguate-decl-stmt.cpp
@@ -1,8 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -fincremental-extensions -std=c++20 %s
 // RUN: %clang_cc1 -fsyntax-only -DMS -fms-extensions -verify -fincremental-extensions -std=c++20 %s
 
-// expected-no-diagnostics
-
 extern "C" int printf(const char*,...);
 
 // Decls which are hard to disambiguate
@@ -47,6 +45,37 @@ ANestedDtor::A1::A2::~A2() { printf("Dtor A::A1::A2::~A2\n"); }
 
 // Ctors
 
+// Private typedefs / using declarations
+class PrivateUsingMember { using T = int; T f(); };
+PrivateUsingMember::T PrivateUsingMember::f() { return 0; }
+
+class PrivateUsingVar { using T = int; static T i; };
+PrivateUsingVar::T PrivateUsingVar::i = 42;
+
+// The same with namespaces
+namespace PrivateUsingNamespace { class Member { using T = int; T f(); }; }
+PrivateUsingNamespace::Member::T PrivateUsingNamespace::Member::f() { return 0; }
+
+namespace PrivateUsingNamespace { class Var { using T = int; static T i; }; }
+PrivateUsingNamespace::Var::T PrivateUsingNamespace::Var::i = 42;
+
+// The same with friend declarations
+class PrivateUsingFriendMember;
+class PrivateUsingFriendVar;
+class PrivateUsingFriend { friend class PrivateUsingFriendMember; friend class PrivateUsingFriendVar; using T = int; };
+class PrivateUsingFriendMember { PrivateUsingFriend::T f(); };
+PrivateUsingFriend::T PrivateUsingFriendMember::f() { return 0; }
+
+class PrivateUsingFriendVar { static PrivateUsingFriend::T i; };
+PrivateUsingFriend::T PrivateUsingFriendVar::i = 42;
+
+// The following should still diagnose (inspired by PR13642)
+// FIXME: Should not be diagnosed twice!
+class PR13642 { class Inner { public: static int i; }; };
+// expected-note at -1 2 {{implicitly declared private here}}
+PR13642::Inner::i = 5;
+// expected-error at -1 2 {{'Inner' is a private member of 'PR13642'}}
+
 // Deduction guide
 template<typename T> struct A { A(); A(T); };
 A() -> A<int>;


        


More information about the cfe-commits mailing list