diff --git a/clang/include/clang/Tooling/Syntax/Tokens.h b/clang/include/clang/Tooling/Syntax/Tokens.h index a210815d49f9d..fc0fabb40658c 100644 --- a/clang/include/clang/Tooling/Syntax/Tokens.h +++ b/clang/include/clang/Tooling/Syntax/Tokens.h @@ -317,10 +317,15 @@ class TokenBuffer { /// This always returns 0-2 tokens. llvm::ArrayRef spelledTokensTouching(SourceLocation Loc, const syntax::TokenBuffer &Tokens); +llvm::ArrayRef +spelledTokensTouching(SourceLocation Loc, llvm::ArrayRef Tokens); /// The identifier token that overlaps or touches a spelling location Loc. /// If there is none, returns nullptr. const syntax::Token * +spelledIdentifierTouching(SourceLocation Loc, + llvm::ArrayRef Tokens); +const syntax::Token * spelledIdentifierTouching(SourceLocation Loc, const syntax::TokenBuffer &Tokens); diff --git a/clang/lib/Tooling/Syntax/Tokens.cpp b/clang/lib/Tooling/Syntax/Tokens.cpp index dca491e26dde8..9f51ab787ad1a 100644 --- a/clang/lib/Tooling/Syntax/Tokens.cpp +++ b/clang/lib/Tooling/Syntax/Tokens.cpp @@ -254,24 +254,30 @@ TokenBuffer::expansionStartingAt(const syntax::Token *Spelled) const { ExpandedTokens.data() + M->EndExpanded); return E; } - llvm::ArrayRef syntax::spelledTokensTouching(SourceLocation Loc, - const syntax::TokenBuffer &Tokens) { + llvm::ArrayRef Tokens) { assert(Loc.isFileID()); - llvm::ArrayRef All = - Tokens.spelledTokens(Tokens.sourceManager().getFileID(Loc)); + auto *Right = llvm::partition_point( - All, [&](const syntax::Token &Tok) { return Tok.location() < Loc; }); - bool AcceptRight = Right != All.end() && Right->location() <= Loc; - bool AcceptLeft = Right != All.begin() && (Right - 1)->endLocation() >= Loc; + Tokens, [&](const syntax::Token &Tok) { return Tok.location() < Loc; }); + bool AcceptRight = Right != Tokens.end() && Right->location() <= Loc; + bool AcceptLeft = + Right != Tokens.begin() && (Right - 1)->endLocation() >= Loc; return llvm::makeArrayRef(Right - (AcceptLeft ? 1 : 0), Right + (AcceptRight ? 1 : 0)); } +llvm::ArrayRef +syntax::spelledTokensTouching(SourceLocation Loc, + const syntax::TokenBuffer &Tokens) { + return spelledTokensTouching( + Loc, Tokens.spelledTokens(Tokens.sourceManager().getFileID(Loc))); +} + const syntax::Token * syntax::spelledIdentifierTouching(SourceLocation Loc, - const syntax::TokenBuffer &Tokens) { + llvm::ArrayRef Tokens) { for (const syntax::Token &Tok : spelledTokensTouching(Loc, Tokens)) { if (Tok.kind() == tok::identifier) return &Tok; @@ -279,6 +285,13 @@ syntax::spelledIdentifierTouching(SourceLocation Loc, return nullptr; } +const syntax::Token * +syntax::spelledIdentifierTouching(SourceLocation Loc, + const syntax::TokenBuffer &Tokens) { + return spelledIdentifierTouching( + Loc, Tokens.spelledTokens(Tokens.sourceManager().getFileID(Loc))); +} + std::vector TokenBuffer::macroExpansions(FileID FID) const { auto FileIt = Files.find(FID);