[PATCH] D62954: [Syntax] Add a helper to find expansion by its first spelled token
Ilya Biryukov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 6 07:24:52 PDT 2019
ilya-biryukov created this revision.
ilya-biryukov added a reviewer: sammccall.
Herald added a subscriber: kadircet.
Herald added a project: clang.
Used in clangd for a code tweak that expands a macro.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D62954
Files:
clang/include/clang/Tooling/Syntax/Tokens.h
clang/lib/Tooling/Syntax/Tokens.cpp
Index: clang/lib/Tooling/Syntax/Tokens.cpp
===================================================================
--- clang/lib/Tooling/Syntax/Tokens.cpp
+++ clang/lib/Tooling/Syntax/Tokens.cpp
@@ -200,6 +200,32 @@
: LastSpelled + 1);
}
+llvm::Optional<TokenBuffer::Expansion>
+TokenBuffer::findExpansion(const syntax::Token *Spelled) const {
+ assert(Spelled);
+ assert(Spelled->location().isFileID() && "not a spelled token");
+ auto FileIt = Files.find(SourceMgr->getFileID(Spelled->location()));
+ assert(FileIt != Files.end());
+
+ auto &File = FileIt->second;
+ assert(File.SpelledTokens.data() <= Spelled &&
+ Spelled < (File.SpelledTokens.data() + File.SpelledTokens.size()));
+
+ unsigned SpelledIndex = Spelled - File.SpelledTokens.data();
+ auto M = llvm::bsearch(File.Mappings, [&](const Mapping &M) {
+ return SpelledIndex <= M.BeginSpelled;
+ });
+ if (M == File.Mappings.end() || M->BeginSpelled != SpelledIndex)
+ return llvm::None;
+
+ Expansion E;
+ E.Spelled = llvm::makeArrayRef(File.SpelledTokens.data() + M->BeginSpelled,
+ File.SpelledTokens.data() + M->EndSpelled);
+ E.Expanded = llvm::makeArrayRef(ExpandedTokens.data() + M->BeginExpanded,
+ ExpandedTokens.data() + M->EndExpanded);
+ return E;
+}
+
std::vector<syntax::Token> syntax::tokenize(FileID FID, const SourceManager &SM,
const LangOptions &LO) {
std::vector<syntax::Token> Tokens;
Index: clang/include/clang/Tooling/Syntax/Tokens.h
===================================================================
--- clang/include/clang/Tooling/Syntax/Tokens.h
+++ clang/include/clang/Tooling/Syntax/Tokens.h
@@ -200,6 +200,21 @@
llvm::Optional<llvm::ArrayRef<syntax::Token>>
spelledForExpanded(llvm::ArrayRef<syntax::Token> Expanded) const;
+ /// An expansion produced by the preprocessor, includes macro expansions and
+ /// macro directives. Preprocessor always maps a non-empty range of spelled
+ /// tokens to a (possibly empty) range of expanded tokens.
+ /// Here is a few examples of expansions:
+ /// #pragme once // Expansion from "#pragma once" to an empty range.
+ /// #define FOO 1 2 3 // Expansion from "#define FOO 1" to an empty range.
+ /// FOO // Expansion from "FOO" to "1 2 3".
+ struct Expansion {
+ llvm::ArrayRef<syntax::Token> Spelled;
+ llvm::ArrayRef<syntax::Token> Expanded;
+ };
+ /// If \p Spelled starts a mapping (e.g. if it's a macro name) return the
+ /// subrange of expanded tokens that the macro expands to.
+ llvm::Optional<Expansion> findExpansion(const syntax::Token *Spelled) const;
+
/// Lexed tokens of a file before preprocessing. E.g. for the following input
/// #define DECL(name) int name = 10
/// DECL(a);
@@ -292,6 +307,7 @@
/// finished, i.e. after running Execute().
LLVM_NODISCARD TokenBuffer consume() &&;
+
private:
/// Maps from a start location to an end location of each mapping.
/// 1. range from '#' to the last token in the line for PP directives,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62954.203356.patch
Type: text/x-patch
Size: 3129 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190606/5d6281b7/attachment.bin>
More information about the cfe-commits
mailing list