Index: clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp =================================================================== --- clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp +++ clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp @@ -195,14 +195,10 @@ auto TokenLength = clang::Lexer::MeasureTokenLength(NameLoc, SM, LangOpts); auto CreatePosition = [&SM](SourceLocation Loc) { - auto FileIdAndOffset = SM.getDecomposedLoc(Loc); - auto FileId = FileIdAndOffset.first; - auto Offset = FileIdAndOffset.second; + auto LSPLoc = sourceLocToPosition(SM, Loc); SymbolLocation::Position Pos; - // Position is 0-based while SourceManager is 1-based. - Pos.Line = SM.getLineNumber(FileId, Offset) - 1; - // FIXME: Use UTF-16 code units, not UTF-8 bytes. - Pos.Column = SM.getColumnNumber(FileId, Offset) - 1; + Pos.Line = LSPLoc.line; + Pos.Column = LSPLoc.character; return Pos; }; Index: clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp @@ -689,6 +689,15 @@ IncludeHeader(TestHeaderURI), DefURI(TestFileURI)))); } +TEST_F(SymbolCollectorTest, UTF16Character) { + // ö is 2-bytes. + Annotations Header(/*Header=*/"class [[pörk]] {};"); + runSymbolCollector(Header.code(), /*Main=*/""); + EXPECT_THAT(Symbols, UnorderedElementsAre( + AllOf(QName("pörk"), DeclRange(Header.range())))); +} + + } // namespace } // namespace clangd } // namespace clang