Author: 张之阳
Date: 2026-03-12T16:56:43Z
New Revision: 519a25c977b249471293cb8940b515224f59ec72

URL: 
https://github.com/llvm/llvm-project/commit/519a25c977b249471293cb8940b515224f59ec72
DIFF: 
https://github.com/llvm/llvm-project/commit/519a25c977b249471293cb8940b515224f59ec72.diff

LOG: [clang] Fix alias declaration fix-it location for token-split '>>' 
(#184555)

Fixes #184425

When parsing an alias declaration like:

```c++
using A = X<int>>;
```

clang splits `>>` into two `>` tokens while parsing templates. In this
token-split case, `Lexer::getLocForEndOfToken` was advancing past the
already-correct expansion end location, which moved the fix-it insertion
point too far right (at `;` instead of before the second `>`).

This patch detects token-split expansion ranges and returns the
expansion end location directly after `isAtEndOfMacroExpansion`,
avoiding the extra token-length advance.

Also adds a regression test in
`clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp` that checks the
fix-it insertion location is `{4:17-4:17}` for the example above.

Local validation:
- `tools/clang/lib/Lex/CMakeFiles/obj.clangLex.dir/Lexer.cpp.o` builds
successfully
- full `clang` build/test still in progress

Added: 
    clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Lex/Lexer.cpp
    clang/test/Parser/cxx0x-decl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d9d0fd6308d95..85b3f3e6e3f41 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -282,6 +282,10 @@ Improvements to Clang's diagnostics
 - Added a missing space to the FixIt for the ``implicit-int`` group of 
diagnostics and 
   made sure that only one such diagnostic and FixIt is emitted per declaration 
group. (#GH179354)
 
+- Fixed the Fix-It insertion point for ``expected ';' after alias declaration``
+  when parsing alias declarations involving a token-split ``>>`` sequence
+  (for example, ``using A = X<int>>;``). (#GH184425)
+
 - The ``-Wloop-analysis`` warning has been extended to catch more cases of
   variable modification inside lambda expressions (#GH132038).
 

diff  --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 13f6bb525c716..10246552bb13d 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -862,8 +862,16 @@ SourceLocation Lexer::getLocForEndOfToken(SourceLocation 
Loc, unsigned Offset,
     return {};
 
   if (Loc.isMacroID()) {
+    // Token split (for example, splitting '>>' into two '>' tokens) is
+    // represented in SourceManager as an ExpansionInfo (see
+    // createForTokenSplit), so these locations are MacroIDs even when no user
+    // macro is involved. For split expansions, the expansion end is already
+    // the correct insertion point.
+    const FileID LocFileID = SM.getFileID(Loc);
     if (Offset > 0 || !isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
       return {}; // Points inside the macro expansion.
+    if (!SM.getSLocEntry(LocFileID).getExpansion().isExpansionTokenRange())
+      return Loc;
   }
 
   unsigned Len = Lexer::MeasureTokenLength(Loc, SM, LangOpts);

diff  --git a/clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp 
b/clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp
new file mode 100644
index 0000000000000..fc683431a958a
--- /dev/null
+++ b/clang/test/Parser/cxx-alias-decl-split-angle-fixit.cpp
@@ -0,0 +1,7 @@
+// RUN: not %clang_cc1 -fsyntax-only -std=c++11 -fdiagnostics-parseable-fixits 
%s 2>&1 | FileCheck %s
+
+template <typename> struct X {};
+using A = X<int>>;
+
+// CHECK: error: expected ';' after alias declaration
+// CHECK: fix-it:"{{.*}}":{4:17-4:17}:";"

diff  --git a/clang/test/Parser/cxx0x-decl.cpp 
b/clang/test/Parser/cxx0x-decl.cpp
index 69a8d8a46557d..14643d7812641 100644
--- a/clang/test/Parser/cxx0x-decl.cpp
+++ b/clang/test/Parser/cxx0x-decl.cpp
@@ -190,8 +190,6 @@ namespace AliasDeclEndLocation {
     ;
   using D = AliasDeclEndLocation::A<int
     > // expected-error {{expected ';' after alias declaration}}
-  // FIXME: After splitting this >> into two > tokens, we incorrectly determine
-  // the end of the template-id to be after the *second* '>'.
   using E = AliasDeclEndLocation::A<int>>;
 #define GGG >>>
   using F = AliasDeclEndLocation::A<int GGG;


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to