1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
//===--- Token.cpp - Tokens and token streams in the pseudoparser ---------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "clang-pseudo/Token.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
namespace clang {
namespace pseudo {
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Token &T) {
OS << llvm::formatv("{0} {1}:{2} ", clang::tok::getTokenName(T.Kind), T.Line,
T.Indent);
OS << '"';
llvm::printEscapedString(T.text(), OS);
OS << '"';
if (T.Flags)
OS << llvm::format(" flags=%x", T.Flags);
return OS;
}
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const TokenStream &TS) {
OS << "Index Kind Line Text\n";
for (const auto &T : TS.tokens()) {
OS << llvm::format("%5d: %16s %4d:%-2d ", TS.index(T),
clang::tok::getTokenName(T.Kind), T.Line, T.Indent);
OS << '"';
llvm::printEscapedString(T.text(), OS);
OS << '"';
if (T.Flags)
OS << llvm::format(" flags=%x", T.Flags);
OS << '\n';
}
return OS;
}
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Token::Range &R) {
OS << llvm::formatv("[{0},{1})", R.Begin, R.End);
return OS;
}
TokenStream::TokenStream(std::shared_ptr<void> Payload)
: Payload(std::move(Payload)) {
Storage.emplace_back();
Storage.back().Kind = clang::tok::eof;
}
void TokenStream::finalize() {
assert(!isFinalized());
unsigned LastLine = Storage.back().Line;
Storage.emplace_back();
Storage.back().Kind = tok::eof;
Storage.back().Line = LastLine + 1;
Tokens = Storage;
Tokens = Tokens.drop_front().drop_back();
}
bool TokenStream::isFinalized() const {
assert(!Storage.empty() && Storage.front().Kind == tok::eof);
if (Storage.size() == 1)
return false;
return Storage.back().Kind == tok::eof;
}
void TokenStream::print(llvm::raw_ostream &OS) const {
bool FirstToken = true;
unsigned LastLine = -1;
StringRef LastText;
for (const auto &T : tokens()) {
StringRef Text = T.text();
if (FirstToken) {
FirstToken = false;
} else if (T.Line == LastLine) {
if (LastText.data() + LastText.size() != Text.data())
OS << ' ';
} else {
OS << '\n';
OS.indent(T.Indent);
}
OS << Text;
LastLine = T.Line;
LastText = Text;
}
if (!FirstToken)
OS << '\n';
}
clang::LangOptions genericLangOpts(clang::Language Lang,
clang::LangStandard::Kind Standard) {
clang::LangOptions Opts;
std::vector<std::string> UnusedIncludes;
LangOptions::setLangDefaults(Opts, Lang, llvm::Triple(), UnusedIncludes,
Standard);
// Some options are "on by default", but e.g. at the driver level.
if (Opts.CPlusPlus)
Opts.CXXOperatorNames = true;
if (Opts.CPlusPlus20)
Opts.Coroutines = true;
// Some options are off by default, but define keywords we want to tolerate.
if (Opts.CPlusPlus)
Opts.MicrosoftExt = true; // kw__try, kw__finally
Opts.DeclSpecKeyword = true; // __declspec
Opts.WChar = true;
return Opts;
}
TokenStream stripComments(const TokenStream &Input) {
TokenStream Out(Input.getPayload());
for (const Token &T : Input.tokens()) {
if (T.Kind == tok::comment)
continue;
Out.push(T);
}
Out.finalize();
return Out;
}
} // namespace pseudo
} // namespace clang
|