11#include "clang/Basic/IdentifierTable.h"
12#include "clang/Basic/TokenKinds.h"
13#include "llvm/ADT/StringMap.h"
14#include "llvm/Support/Threading.h"
21namespace tok = clang::tok;
25 std::optional<ParsedFunction> result(std::nullopt);
86 if (!
Peek().isOneOf(kinds...))
104std::optional<ParsedFunction>
109 if (expect_return_type) {
141std::optional<ParsedFunction>
154 if (expect_return_type) {
179 if (maybe_inner_function_name)
184 before_inner_function_pos.
Remove();
185 return maybe_inner_function_name;
207 auto maybe_inner_function_ptr_name =
ParseFuncPtr(
false);
208 if (maybe_inner_function_ptr_name)
213 return maybe_inner_function_ptr_name;
237 int template_counter = 1;
238 bool can_open_template =
false;
240 tok::TokenKind kind =
Peek().getKind();
242 case tok::greatergreater:
243 template_counter -= 2;
244 can_open_template =
false;
249 can_open_template =
false;
258 if (can_open_template)
260 can_open_template =
false;
263 case tok::kw_operator:
266 can_open_template =
true;
268 case tok::raw_identifier:
269 can_open_template =
true;
277 can_open_template =
true;
279 can_open_template =
false;
286 can_open_template =
false;
289 can_open_template =
false;
295 if (template_counter != 0) {
308 Peek().getRawIdentifier() ==
"abi")
317 while (
ConsumeToken(tok::raw_identifier, tok::comma, tok::period,
318 tok::numeric_constant))
333 constexpr llvm::StringLiteral g_anonymous(
"anonymous");
335 Peek().getRawIdentifier() == g_anonymous) {
357 constexpr llvm::StringLiteral g_lambda(
"lambda");
359 Peek().getRawIdentifier() == g_lambda) {
375 tok::TokenKind right) {
383 tok::TokenKind kind =
Peek().getKind();
386 else if (kind == left)
391 assert(counter >= 0);
408 const auto &token =
Peek();
419 if (token.getKind() == tok::lessless) {
425 if (n_token.getKind() != tok::l_paren && n_token.getKind() != tok::less) {
426 clang::Token tmp_tok;
427 tmp_tok.startToken();
428 tmp_tok.setLength(1);
429 tmp_tok.setLocation(token.getLocation().getLocWithOffset(1));
430 tmp_tok.setKind(tok::less);
440 switch (token.getKind()) {
453#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
457#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemberOnly)
458#include "clang/Basic/OperatorKinds.def"
459#undef OVERLOADED_OPERATOR
460#undef OVERLOADED_OPERATOR_MULTI
491 while (
ConsumeToken(tok::kw_const, tok::kw_volatile, tok::amp, tok::ampamp))
497 bool continue_parsing =
true;
502 switch (
Peek().getKind()) {
505 case tok::kw___int64:
506 case tok::kw___int128:
508 case tok::kw_unsigned:
515 case tok::kw___float128:
516 case tok::kw_wchar_t:
518 case tok::kw_char16_t:
519 case tok::kw_char32_t:
524 continue_parsing =
false;
539 while (
ConsumeToken(tok::star, tok::amp, tok::ampamp, tok::kw_const,
571std::optional<CPlusPlusNameParser::ParsedNameRanges>
583 State state = State::Beginning;
584 bool continue_parsing =
true;
585 std::optional<size_t> last_coloncolon_position;
588 const auto &token =
Peek();
589 switch (token.getKind()) {
590 case tok::raw_identifier:
591 if (state != State::Beginning && state != State::AfterTwoColons) {
592 continue_parsing =
false;
596 state = State::AfterIdentifier;
598 case tok::l_square: {
606 const bool valid_state =
607 state == State::AfterIdentifier || state == State::AfterOperator;
609 continue_parsing =
false;
615 if (state == State::Beginning || state == State::AfterTwoColons) {
618 state = State::AfterIdentifier;
624 if (state != State::AfterIdentifier && state != State::AfterTemplate &&
625 state != State::AfterOperator) {
626 continue_parsing =
false;
632 continue_parsing =
false;
640 continue_parsing =
false;
643 l_paren_position.
Remove();
644 last_coloncolon_position = coloncolon_position;
645 state = State::AfterTwoColons;
649 if (state == State::Beginning || state == State::AfterTwoColons) {
651 state = State::AfterIdentifier;
655 continue_parsing =
false;
657 case tok::coloncolon:
658 if (state != State::Beginning && state != State::AfterIdentifier &&
659 state != State::AfterTemplate) {
660 continue_parsing =
false;
665 state = State::AfterTwoColons;
668 if (state != State::AfterIdentifier && state != State::AfterOperator) {
669 continue_parsing =
false;
673 continue_parsing =
false;
676 state = State::AfterTemplate;
678 case tok::kw_operator:
679 if (state != State::Beginning && state != State::AfterTwoColons) {
680 continue_parsing =
false;
684 continue_parsing =
false;
687 state = State::AfterOperator;
690 if (state != State::Beginning && state != State::AfterTwoColons) {
691 continue_parsing =
false;
696 state = State::AfterIdentifier;
699 continue_parsing =
false;
703 continue_parsing =
false;
708 if (state == State::AfterIdentifier || state == State::AfterOperator ||
709 state == State::AfterTemplate) {
711 if (last_coloncolon_position) {
729 return llvm::StringRef();
735 clang::SourceLocation start_loc = first_token.getLocation();
736 clang::SourceLocation end_loc = last_token.getLocation();
737 unsigned start_pos = start_loc.getRawEncoding();
738 unsigned end_pos = end_loc.getRawEncoding() + last_token.getLength();
739 return m_text.take_front(end_pos).drop_front(start_pos);
743 static clang::LangOptions g_options;
744 static llvm::once_flag g_once_flag;
745 llvm::call_once(g_once_flag, []() {
746 g_options.LineComment =
true;
747 g_options.C99 =
true;
748 g_options.C11 =
true;
749 g_options.CPlusPlus =
true;
750 g_options.CPlusPlus11 =
true;
751 g_options.CPlusPlus14 =
true;
752 g_options.CPlusPlus17 =
true;
753 g_options.CPlusPlus20 =
true;
759 static llvm::StringMap<tok::TokenKind> g_map{
760#define KEYWORD(Name, Flags) {llvm::StringRef(#Name), tok::kw_##Name},
761#include "clang/Basic/TokenKinds.def"
774 for (lexer.LexFromRawLexer(token); !token.is(clang::tok::eof);
775 lexer.LexFromRawLexer(token)) {
776 if (token.is(clang::tok::raw_identifier)) {
777 auto it = kw_map.find(token.getRawIdentifier());
778 if (it != kw_map.end()) {
779 token.setKind(it->getValue());
static const clang::LangOptions & GetLangOptions()
static const llvm::StringMap< tok::TokenKind > & GetKeywordsMap()
size_t GetSavedPosition()
size_t m_next_token_index
void SkipFunctionQualifiers()
std::optional< ParsedNameRanges > ParseFullNameImpl()
bool ConsumeToken(clang::tok::TokenKind kind)
bool ConsumeBuiltinType()
bool ConsumeAnonymousNamespace()
std::optional< ParsedFunction > ParseFunctionImpl(bool expect_return_type)
std::optional< ParsedFunction > ParseAsFunctionDefinition()
size_t GetCurrentPosition()
std::optional< ParsedName > ParseAsFullName()
bool ConsumeAbiTag()
Consumes ABI tags enclosed within '[abi:' ... ']'.
bool ConsumePtrsAndRefs()
bool ConsumeBrackets(clang::tok::TokenKind left, clang::tok::TokenKind right)
llvm::StringRef GetTextForRange(const Range &range)
bool ConsumeTemplateArgs()
std::optional< ParsedFunction > ParseFuncPtr(bool expect_return_type)
void SkipTypeQualifiers()
llvm::SmallVector< clang::Token, 30 > m_tokens
A class that represents a running process on the host machine.
llvm::StringRef qualifiers
llvm::StringRef arguments
llvm::StringRef return_type