[clang-tools-extra] r370768 - [clangd] Move getBeginningOfIdentifier from ClangdUnit to SourceCode. Drop dependencies on ClangdUnit from some headers. NFC

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 3 08:34:47 PDT 2019


Author: sammccall
Date: Tue Sep  3 08:34:47 2019
New Revision: 370768

URL: http://llvm.org/viewvc/llvm-project?rev=370768&view=rev
Log:
[clangd] Move getBeginningOfIdentifier from ClangdUnit to SourceCode. Drop dependencies on ClangdUnit from some headers. NFC

Modified:
    clang-tools-extra/trunk/clangd/ClangdServer.cpp
    clang-tools-extra/trunk/clangd/ClangdServer.h
    clang-tools-extra/trunk/clangd/ClangdUnit.cpp
    clang-tools-extra/trunk/clangd/ClangdUnit.h
    clang-tools-extra/trunk/clangd/CodeComplete.h
    clang-tools-extra/trunk/clangd/Selection.cpp
    clang-tools-extra/trunk/clangd/Selection.h
    clang-tools-extra/trunk/clangd/SourceCode.cpp
    clang-tools-extra/trunk/clangd/SourceCode.h
    clang-tools-extra/trunk/clangd/XRefs.cpp
    clang-tools-extra/trunk/clangd/index/FileIndex.h
    clang-tools-extra/trunk/clangd/refactor/Rename.cpp
    clang-tools-extra/trunk/clangd/refactor/Rename.h
    clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp
    clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp

Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Tue Sep  3 08:34:47 2019
@@ -315,7 +315,7 @@ void ClangdServer::prepareRename(PathRef
       return CB(Changes.takeError());
     }
     SourceLocation Loc = getBeginningOfIdentifier(
-        AST, Pos, AST.getSourceManager().getMainFileID());
+        Pos, AST.getSourceManager(), AST.getASTContext().getLangOpts());
     if (auto Range = getTokenRange(AST.getSourceManager(),
                                    AST.getASTContext().getLangOpts(), Loc))
       return CB(*Range);

Modified: clang-tools-extra/trunk/clangd/ClangdServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.h Tue Sep  3 08:34:47 2019
@@ -11,7 +11,6 @@
 
 #include "../clang-tidy/ClangTidyOptions.h"
 #include "Cancellation.h"
-#include "ClangdUnit.h"
 #include "CodeComplete.h"
 #include "FSProvider.h"
 #include "FormattedString.h"

Modified: clang-tools-extra/trunk/clangd/ClangdUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp Tue Sep  3 08:34:47 2019
@@ -710,39 +710,6 @@ buildAST(PathRef FileName, std::unique_p
       std::move(VFS), Inputs.Index, Inputs.Opts);
 }
 
-SourceLocation getBeginningOfIdentifier(const ParsedAST &Unit,
-                                        const Position &Pos, const FileID FID) {
-  const ASTContext &AST = Unit.getASTContext();
-  const SourceManager &SourceMgr = AST.getSourceManager();
-  auto Offset = positionToOffset(SourceMgr.getBufferData(FID), Pos);
-  if (!Offset) {
-    log("getBeginningOfIdentifier: {0}", Offset.takeError());
-    return SourceLocation();
-  }
-
-  // GetBeginningOfToken(pos) is almost what we want, but does the wrong thing
-  // if the cursor is at the end of the identifier.
-  // Instead, we lex at GetBeginningOfToken(pos - 1). The cases are:
-  //  1) at the beginning of an identifier, we'll be looking at something
-  //  that isn't an identifier.
-  //  2) at the middle or end of an identifier, we get the identifier.
-  //  3) anywhere outside an identifier, we'll get some non-identifier thing.
-  // We can't actually distinguish cases 1 and 3, but returning the original
-  // location is correct for both!
-  SourceLocation InputLoc = SourceMgr.getComposedLoc(FID, *Offset);
-  if (*Offset == 0) // Case 1 or 3.
-    return SourceMgr.getMacroArgExpandedLocation(InputLoc);
-  SourceLocation Before = SourceMgr.getComposedLoc(FID, *Offset - 1);
-
-  Before = Lexer::GetBeginningOfToken(Before, SourceMgr, AST.getLangOpts());
-  Token Tok;
-  if (Before.isValid() &&
-      !Lexer::getRawToken(Before, Tok, SourceMgr, AST.getLangOpts(), false) &&
-      Tok.is(tok::raw_identifier))
-    return SourceMgr.getMacroArgExpandedLocation(Before); // Case 2.
-  return SourceMgr.getMacroArgExpandedLocation(InputLoc); // Case 1 or 3.
-}
-
 } // namespace clangd
 namespace tidy {
 // Force the linker to link in Clang-tidy modules.

Modified: clang-tools-extra/trunk/clangd/ClangdUnit.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.h?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.h Tue Sep  3 08:34:47 2019
@@ -187,11 +187,6 @@ buildAST(PathRef FileName, std::unique_p
          const ParseInputs &Inputs,
          std::shared_ptr<const PreambleData> Preamble);
 
-/// Get the beginning SourceLocation at a specified \p Pos.
-/// May be invalid if Pos is, or if there's no identifier.
-SourceLocation getBeginningOfIdentifier(const ParsedAST &Unit,
-                                        const Position &Pos, const FileID FID);
-
 /// For testing/debugging purposes. Note that this method deserializes all
 /// unserialized Decls, so use with care.
 void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS);

Modified: clang-tools-extra/trunk/clangd/CodeComplete.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.h?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.h (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.h Tue Sep  3 08:34:47 2019
@@ -15,7 +15,6 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
 
-#include "ClangdUnit.h"
 #include "Headers.h"
 #include "Logger.h"
 #include "Path.h"
@@ -36,6 +35,7 @@
 namespace clang {
 class NamedDecl;
 namespace clangd {
+struct PreambleData;
 
 struct CodeCompleteOptions {
   /// Returns options that can be passed to clang's completion engine.

Modified: clang-tools-extra/trunk/clangd/Selection.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Selection.cpp?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Selection.cpp (original)
+++ clang-tools-extra/trunk/clangd/Selection.cpp Tue Sep  3 08:34:47 2019
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "Selection.h"
-#include "ClangdUnit.h"
 #include "Logger.h"
 #include "SourceCode.h"
 #include "clang/AST/ASTTypeTraits.h"
@@ -17,6 +16,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TokenKinds.h"
+#include "clang/Lex/Lexer.h"
 #include "clang/Tooling/Syntax/Tokens.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/raw_ostream.h"

Modified: clang-tools-extra/trunk/clangd/Selection.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Selection.h?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Selection.h (original)
+++ clang-tools-extra/trunk/clangd/Selection.h Tue Sep  3 08:34:47 2019
@@ -40,7 +40,6 @@
 
 namespace clang {
 namespace clangd {
-class ParsedAST;
 
 // A selection can partially or completely cover several AST nodes.
 // The SelectionTree contains nodes that are covered, and their parents.

Modified: clang-tools-extra/trunk/clangd/SourceCode.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SourceCode.cpp?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/SourceCode.cpp (original)
+++ clang-tools-extra/trunk/clangd/SourceCode.cpp Tue Sep  3 08:34:47 2019
@@ -229,6 +229,39 @@ llvm::Optional<Range> getTokenRange(cons
   return halfOpenToRange(SM, CharSourceRange::getCharRange(TokLoc, End));
 }
 
+SourceLocation getBeginningOfIdentifier(const Position &Pos,
+                                        const SourceManager &SM,
+                                        const LangOptions &LangOpts) {
+  FileID FID = SM.getMainFileID();
+  auto Offset = positionToOffset(SM.getBufferData(FID), Pos);
+  if (!Offset) {
+    log("getBeginningOfIdentifier: {0}", Offset.takeError());
+    return SourceLocation();
+  }
+
+  // GetBeginningOfToken(pos) is almost what we want, but does the wrong thing
+  // if the cursor is at the end of the identifier.
+  // Instead, we lex at GetBeginningOfToken(pos - 1). The cases are:
+  //  1) at the beginning of an identifier, we'll be looking at something
+  //  that isn't an identifier.
+  //  2) at the middle or end of an identifier, we get the identifier.
+  //  3) anywhere outside an identifier, we'll get some non-identifier thing.
+  // We can't actually distinguish cases 1 and 3, but returning the original
+  // location is correct for both!
+  SourceLocation InputLoc = SM.getComposedLoc(FID, *Offset);
+  if (*Offset == 0) // Case 1 or 3.
+    return SM.getMacroArgExpandedLocation(InputLoc);
+  SourceLocation Before = SM.getComposedLoc(FID, *Offset - 1);
+
+  Before = Lexer::GetBeginningOfToken(Before, SM, LangOpts);
+  Token Tok;
+  if (Before.isValid() &&
+      !Lexer::getRawToken(Before, Tok, SM, LangOpts, false) &&
+      Tok.is(tok::raw_identifier))
+    return SM.getMacroArgExpandedLocation(Before); // Case 2.
+  return SM.getMacroArgExpandedLocation(InputLoc); // Case 1 or 3.
+}
+
 bool isValidFileRange(const SourceManager &Mgr, SourceRange R) {
   if (!R.getBegin().isValid() || !R.getEnd().isValid())
     return false;

Modified: clang-tools-extra/trunk/clangd/SourceCode.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SourceCode.h?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/SourceCode.h (original)
+++ clang-tools-extra/trunk/clangd/SourceCode.h Tue Sep  3 08:34:47 2019
@@ -75,6 +75,13 @@ llvm::Optional<Range> getTokenRange(cons
 llvm::Expected<SourceLocation> sourceLocationInMainFile(const SourceManager &SM,
                                                         Position P);
 
+/// Get the beginning SourceLocation at a specified \p Pos in the main file.
+/// May be invalid if Pos is, or if there's no identifier.
+/// FIXME: this returns the macro-expansion location, but it shouldn't.
+SourceLocation getBeginningOfIdentifier(const Position &Pos,
+                                        const SourceManager &SM,
+                                        const LangOptions &LangOpts);
+
 /// Returns true iff \p Loc is inside the main file. This function handles
 /// file & macro locations. For macro locations, returns iff the macro is being
 /// expanded inside the main file.

Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Tue Sep  3 08:34:47 2019
@@ -254,8 +254,8 @@ std::vector<LocatedSymbol> locateSymbolA
     }
   }
 
-  SourceLocation SourceLocationBeg =
-      getBeginningOfIdentifier(AST, Pos, SM.getMainFileID());
+  SourceLocation SourceLocationBeg = getBeginningOfIdentifier(
+      Pos, AST.getSourceManager(), AST.getASTContext().getLangOpts());
 
   // Macros are simple: there's no declaration/definition distinction.
   // As a consequence, there's no need to look them up in the index either.
@@ -408,10 +408,10 @@ std::vector<DocumentHighlight> findDocum
                                                       Position Pos) {
   const SourceManager &SM = AST.getSourceManager();
   // FIXME: show references to macro within file?
-  auto References =
-      findRefs(getDeclAtPosition(
-                   AST, getBeginningOfIdentifier(AST, Pos, SM.getMainFileID())),
-               AST);
+  auto References = findRefs(
+      getDeclAtPosition(AST, getBeginningOfIdentifier(
+                                 Pos, SM, AST.getASTContext().getLangOpts())),
+      AST);
 
   // FIXME: we may get multiple DocumentHighlights with the same location and
   // different kinds, deduplicate them.
@@ -876,7 +876,7 @@ llvm::Optional<HoverInfo> getHover(Parse
                                    const SymbolIndex *Index) {
   llvm::Optional<HoverInfo> HI;
   SourceLocation SourceLocationBeg = getBeginningOfIdentifier(
-      AST, Pos, AST.getSourceManager().getMainFileID());
+      Pos, AST.getSourceManager(), AST.getASTContext().getLangOpts());
 
   if (auto M = locateMacroAt(SourceLocationBeg, AST.getPreprocessor())) {
     HI = getHoverContents(*M, AST);
@@ -918,7 +918,8 @@ std::vector<Location> findReferences(Par
     elog("Failed to get a path for the main file, so no references");
     return Results;
   }
-  auto Loc = getBeginningOfIdentifier(AST, Pos, SM.getMainFileID());
+  auto Loc =
+      getBeginningOfIdentifier(Pos, SM, AST.getASTContext().getLangOpts());
   // TODO: should we handle macros, too?
   auto Decls = getDeclAtPosition(AST, Loc);
 
@@ -974,8 +975,8 @@ std::vector<Location> findReferences(Par
 
 std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) {
   const SourceManager &SM = AST.getSourceManager();
-
-  auto Loc = getBeginningOfIdentifier(AST, Pos, SM.getMainFileID());
+  auto Loc =
+      getBeginningOfIdentifier(Pos, SM, AST.getASTContext().getLangOpts());
 
   std::vector<SymbolDetails> Results;
 
@@ -1146,7 +1147,7 @@ static void fillSuperTypes(const CXXReco
 
 const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos) {
   SourceLocation SourceLocationBeg = getBeginningOfIdentifier(
-      AST, Pos, AST.getSourceManager().getMainFileID());
+      Pos, AST.getSourceManager(), AST.getASTContext().getLangOpts());
   auto Decls = getDeclAtPosition(AST, SourceLocationBeg);
   if (Decls.empty())
     return nullptr;

Modified: clang-tools-extra/trunk/clangd/index/FileIndex.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileIndex.h?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/FileIndex.h (original)
+++ clang-tools-extra/trunk/clangd/index/FileIndex.h Tue Sep  3 08:34:47 2019
@@ -15,10 +15,10 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
 
-#include "ClangdUnit.h"
 #include "Index.h"
 #include "MemIndex.h"
 #include "Merge.h"
+#include "Path.h"
 #include "index/CanonicalIncludes.h"
 #include "index/Symbol.h"
 #include "clang/Lex/Preprocessor.h"
@@ -26,6 +26,7 @@
 
 namespace clang {
 namespace clangd {
+class ParsedAST;
 
 /// Select between in-memory index implementations, which have tradeoffs.
 enum class IndexType {

Modified: clang-tools-extra/trunk/clangd/refactor/Rename.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/Rename.cpp?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/refactor/Rename.cpp (original)
+++ clang-tools-extra/trunk/clangd/refactor/Rename.cpp Tue Sep  3 08:34:47 2019
@@ -8,7 +8,9 @@
 
 #include "refactor/Rename.h"
 #include "AST.h"
+#include "ClangdUnit.h"
 #include "Logger.h"
+#include "SourceCode.h"
 #include "index/SymbolCollector.h"
 #include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
 #include "clang/Tooling/Refactoring/Rename/USRFinder.h"
@@ -151,8 +153,8 @@ findOccurrencesWithinFile(ParsedAST &AST
 llvm::Expected<tooling::Replacements>
 renameWithinFile(ParsedAST &AST, llvm::StringRef File, Position Pos,
                  llvm::StringRef NewName, const SymbolIndex *Index) {
-  SourceLocation SourceLocationBeg = clangd::getBeginningOfIdentifier(
-      AST, Pos, AST.getSourceManager().getMainFileID());
+  SourceLocation SourceLocationBeg = getBeginningOfIdentifier(
+      Pos, AST.getSourceManager(), AST.getASTContext().getLangOpts());
   // FIXME: renaming macros is not supported yet, the macro-handling code should
   // be moved to rename tooling library.
   if (locateMacroAt(SourceLocationBeg, AST.getPreprocessor()))

Modified: clang-tools-extra/trunk/clangd/refactor/Rename.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/Rename.h?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/refactor/Rename.h (original)
+++ clang-tools-extra/trunk/clangd/refactor/Rename.h Tue Sep  3 08:34:47 2019
@@ -9,12 +9,14 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
 
-#include "ClangdUnit.h"
+#include "Protocol.h"
 #include "clang/Tooling/Core/Replacement.h"
 #include "llvm/Support/Error.h"
 
 namespace clang {
 namespace clangd {
+class ParsedAST;
+class SymbolIndex;
 
 /// Renames all occurrences of the symbol at \p Pos to \p NewName.
 /// Occurrences outside the current file are not modified.

Modified: clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp Tue Sep  3 08:34:47 2019
@@ -30,45 +30,6 @@ using ::testing::ElementsAre;
 using ::testing::ElementsAreArray;
 using ::testing::AllOf;
 
-TEST(ClangdUnitTest, GetBeginningOfIdentifier) {
-  std::string Preamble = R"cpp(
-struct Bar { int func(); };
-#define MACRO(X) void f() { X; }
-Bar* bar;
-  )cpp";
-  // First ^ is the expected beginning, last is the search position.
-  for (std::string Text : std::vector<std::string>{
-           "int ^f^oo();", // inside identifier
-           "int ^foo();",  // beginning of identifier
-           "int ^foo^();", // end of identifier
-           "int foo(^);",  // non-identifier
-           "^int foo();",  // beginning of file (can't back up)
-           "int ^f0^0();", // after a digit (lexing at N-1 is wrong)
-           "int ^λλ^λ();", // UTF-8 handled properly when backing up
-
-           // identifier in macro arg
-           "MACRO(bar->^func())",  // beginning of identifier
-           "MACRO(bar->^fun^c())", // inside identifier
-           "MACRO(bar->^func^())", // end of identifier
-           "MACRO(^bar->func())",  // begin identifier
-           "MACRO(^bar^->func())", // end identifier
-           "^MACRO(bar->func())",  // beginning of macro name
-           "^MAC^RO(bar->func())", // inside macro name
-           "^MACRO^(bar->func())", // end of macro name
-       }) {
-    std::string WithPreamble = Preamble + Text;
-    Annotations TestCase(WithPreamble);
-    auto AST = TestTU::withCode(TestCase.code()).build();
-    const auto &SourceMgr = AST.getSourceManager();
-    SourceLocation Actual = getBeginningOfIdentifier(
-        AST, TestCase.points().back(), SourceMgr.getMainFileID());
-    Position ActualPos = offsetToPosition(
-        TestCase.code(),
-        SourceMgr.getFileOffset(SourceMgr.getSpellingLoc(Actual)));
-    EXPECT_EQ(TestCase.points().front(), ActualPos) << Text;
-  }
-}
-
 MATCHER_P(DeclNamed, Name, "") {
   if (NamedDecl *ND = dyn_cast<NamedDecl>(arg))
     if (ND->getName() == Name)

Modified: clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp?rev=370768&r1=370767&r2=370768&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp Tue Sep  3 08:34:47 2019
@@ -312,6 +312,45 @@ TEST(SourceCodeTests, SourceLocationInMa
   }
 }
 
+TEST(ClangdUnitTest, GetBeginningOfIdentifier) {
+  std::string Preamble = R"cpp(
+struct Bar { int func(); };
+#define MACRO(X) void f() { X; }
+Bar* bar;
+  )cpp";
+  // First ^ is the expected beginning, last is the search position.
+  for (std::string Text : std::vector<std::string>{
+           "int ^f^oo();", // inside identifier
+           "int ^foo();",  // beginning of identifier
+           "int ^foo^();", // end of identifier
+           "int foo(^);",  // non-identifier
+           "^int foo();",  // beginning of file (can't back up)
+           "int ^f0^0();", // after a digit (lexing at N-1 is wrong)
+           "int ^λλ^λ();", // UTF-8 handled properly when backing up
+
+           // identifier in macro arg
+           "MACRO(bar->^func())",  // beginning of identifier
+           "MACRO(bar->^fun^c())", // inside identifier
+           "MACRO(bar->^func^())", // end of identifier
+           "MACRO(^bar->func())",  // begin identifier
+           "MACRO(^bar^->func())", // end identifier
+           "^MACRO(bar->func())",  // beginning of macro name
+           "^MAC^RO(bar->func())", // inside macro name
+           "^MACRO^(bar->func())", // end of macro name
+       }) {
+    std::string WithPreamble = Preamble + Text;
+    Annotations TestCase(WithPreamble);
+    auto AST = TestTU::withCode(TestCase.code()).build();
+    const auto &SourceMgr = AST.getSourceManager();
+    SourceLocation Actual = getBeginningOfIdentifier(
+        TestCase.points().back(), SourceMgr, AST.getASTContext().getLangOpts());
+    Position ActualPos = offsetToPosition(
+        TestCase.code(),
+        SourceMgr.getFileOffset(SourceMgr.getSpellingLoc(Actual)));
+    EXPECT_EQ(TestCase.points().front(), ActualPos) << Text;
+  }
+}
+
 TEST(SourceCodeTests, CollectIdentifiers) {
   auto Style = format::getLLVMStyle();
   auto IDs = collectIdentifiers(R"cpp(
@@ -417,8 +456,8 @@ TEST(SourceCodeTests, GetMacros) {
    )cpp");
   TestTU TU = TestTU::withCode(Code.code());
   auto AST = TU.build();
-  auto Loc = getBeginningOfIdentifier(AST, Code.point(),
-                                      AST.getSourceManager().getMainFileID());
+  auto Loc = getBeginningOfIdentifier(Code.point(), AST.getSourceManager(),
+                                      AST.getASTContext().getLangOpts());
   auto Result = locateMacroAt(Loc, AST.getPreprocessor());
   ASSERT_TRUE(Result);
   EXPECT_THAT(*Result, MacroName("MACRO"));




More information about the cfe-commits mailing list