https://github.com/pfeodrippe updated https://github.com/llvm/llvm-project/pull/169272
>From 58432c222b651a9b7f309790eb7f50ea771138b7 Mon Sep 17 00:00:00 2001 From: Paulo Feodrippe <[email protected]> Date: Sun, 23 Nov 2025 22:34:43 -0500 Subject: [PATCH] [clang][Parser] Allow private type aliases in out-of-line member function return types When parsing qualified type names (e.g., `io_context::impl_type`) at file scope in clang-repl, suppress access checks during type annotation. This allows private member type aliases to be used in return types of out-of-line member function definitions, matching the C++ standard's scoping rules for such declarations. Fixes: Parsing errors in clang-repl when including headers with out-of-line member functions that return private nested types (e.g., ASIO's io_context::impl_type). --- clang/lib/Parse/Parser.cpp | 21 +++++++++++++ .../Interpreter/private-member-access.cpp | 31 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 clang/test/Interpreter/private-member-access.cpp diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index a6fc676f23a51..ac5c90bf7c7ac 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -2020,6 +2020,27 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec( CXXScopeSpec &SS, bool IsNewScope, ImplicitTypenameContext AllowImplicitTypename) { if (Tok.is(tok::identifier)) { + // In incremental/clang-repl mode, suppress access checks for qualified + // type lookups when no delayed diagnostic pool is active. This handles + // the case where we're parsing input like "A::B *A::foo()" where the type + // "A::B" might be a private member type, but if this turns out to be an + // out-of-line member function definition, access should be allowed. + // + // When the declaration is actually parsed (via ParseDeclarationOrFunctionDefinition), + // the ParsingDeclSpec will set up proper delayed diagnostics to handle + // access checking in the correct context. + // + // We only do this in incremental mode because this is where the issue + // manifests - disambiguation happens before ParsingDeclSpec is created. + // In normal compilation, these access checks would be re-triggered during + // actual parsing with delayed diagnostics active. + bool SuppressAccess = getLangOpts().IncrementalExtensions && + SS.isNotEmpty() && + !Actions.DelayedDiagnostics.shouldDelayDiagnostics(); + std::optional<SuppressAccessChecks> SAC; + if (SuppressAccess) + SAC.emplace(*this, true); + // Determine whether the identifier is a type name. if (ParsedType Ty = Actions.getTypeName( *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), &SS, diff --git a/clang/test/Interpreter/private-member-access.cpp b/clang/test/Interpreter/private-member-access.cpp new file mode 100644 index 0000000000000..0d02f09332612 --- /dev/null +++ b/clang/test/Interpreter/private-member-access.cpp @@ -0,0 +1,31 @@ +// RUN: cat %s | clang-repl | FileCheck %s + +extern "C" int printf(const char*, ...); + +struct scheduler { }; +class io_context { using impl_type = scheduler; public: impl_type *get_impl(); }; +io_context::impl_type *io_context::get_impl() { return nullptr; } +printf("Private type alias: passed\n"); +// CHECK: Private type alias: passed + +class Container { struct Node { int data; }; public: Node* create(); }; +Container::Node* Container::create() { return new Node{456}; } +printf("Private nested struct: %d\n", Container().create()->data); +// CHECK: Private nested struct: 456 + +class Status { enum Code { OK = 0 }; public: Code get(); }; +Status::Code Status::get() { return OK; } +printf("Private enum: %d\n", Status().get()); +// CHECK: Private enum: 0 + +template<typename T> class Handler { using ptr = T*; public: ptr get(); }; +template<typename T> typename Handler<T>::ptr Handler<T>::get() { return nullptr; } +printf("Template with private type: passed\n"); +// CHECK: Template with private type: passed + +namespace ns { class C { using val_t = double; public: val_t compute(); }; } +ns::C::val_t ns::C::compute() { return 3.14; } +printf("Namespace qualified: %.2f\n", ns::C().compute()); +// CHECK: Namespace qualified: 3.14 + +%quit _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
