diff options
author | Krystian Stasiowski <sdkrystian@gmail.com> | 2024-07-29 14:01:00 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-29 14:01:00 -0400 |
commit | 708a9a06cba66bc8f739b05646e7d3be9247feee (patch) | |
tree | b22b5d17e04e01c5d040c55ea7c95c8c93638c9f /clang/lib/Lex/Preprocessor.cpp | |
parent | c66d25d1429fbf49c97ee9cd0195246642178cb7 (diff) | |
download | llvm-708a9a06cba66bc8f739b05646e7d3be9247feee.zip llvm-708a9a06cba66bc8f739b05646e7d3be9247feee.tar.gz llvm-708a9a06cba66bc8f739b05646e7d3be9247feee.tar.bz2 |
[Clang][Parse] Fix ambiguity with nested-name-specifiers that may declarative (#96364)
Consider the following:
```
template<typename T>
struct A { };
template<typename T>
int A<T>::B::* f(); // error: no member named 'B' in 'A<T>'
```
Although this is clearly valid, clang rejects it because the
_nested-name-specifier_ `A<T>::` is parsed as-if it was declarative,
meaning, we parse it as-if it was the _nested-name-specifier_ in a
redeclaration/specialization. However, we don't (and can't) know whether
the _nested-name-specifier_ is declarative until we see the '`*`' token,
but at that point we have already complained that `A` has no member
named `B`! This patch addresses this bug by adding support for _fully_
unannotated _and_ unbounded tentative parsing, which allows for us to
parse past tokens without having to cache them until we reach a point
where we can guarantee to be past the construct we are disambiguating.
I don't know where the approach taken here is ideal -- alternatives are
welcome. However, the performance impact (as measured by
llvm-compile-time-tracker (https://llvm-compile-time-tracker.com/?config=Overview&stat=instructions%3Au&remote=sdkrystian)
is quite minimal (0.09%, which I plan to further improve).
Diffstat (limited to 'clang/lib/Lex/Preprocessor.cpp')
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 63e27e6..f0b4593 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -170,7 +170,7 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts, } Preprocessor::~Preprocessor() { - assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!"); + assert(!isBacktrackEnabled() && "EnableBacktrack/Backtrack imbalance!"); IncludeMacroStack.clear(); |