11#include "clang/Frontend/CompilerInstance.h"
12#include "clang/Lex/Preprocessor.h"
13#include "llvm/Support/ConvertUTF.h"
20 bool HonorLineBreaks =
true) {
21 const char *CurPtr = Buffer.begin();
36 SmallVector<BidiChar> BidiContexts;
43 while (CurPtr < Buffer.end()) {
44 unsigned char C = *CurPtr;
48 (
C == 0xA ||
C == 0xD || (0x1C <=
C &&
C <= 0x1E) ||
C == 0x85);
49 bool IsSegmentSep = (
C == 0x9 ||
C == 0xB ||
C == 0x1F);
50 if (IsParagrapSep || IsSegmentSep)
54 llvm::UTF32 CodePoint = 0;
55 llvm::ConversionResult Result = llvm::convertUTF8Sequence(
56 (
const llvm::UTF8 **)&CurPtr, (
const llvm::UTF8 *)Buffer.end(),
57 &CodePoint, llvm::strictConversion);
60 if (Result != llvm::conversionOK) {
66 if (CodePoint == RLO || CodePoint == RLE || CodePoint == LRO ||
68 BidiContexts.push_back(PDF);
70 else if (CodePoint == PDF) {
71 if (!BidiContexts.empty() && BidiContexts.back() == PDF)
72 BidiContexts.pop_back();
75 else if (CodePoint == RLI || CodePoint == LRI || CodePoint == FSI)
76 BidiContexts.push_back(PDI);
78 else if (CodePoint == PDI) {
79 auto R = llvm::find(llvm::reverse(BidiContexts), PDI);
80 if (R != BidiContexts.rend())
81 BidiContexts.resize(BidiContexts.rend() - R - 1);
84 else if (CodePoint == PS)
87 return !BidiContexts.empty();
91 :
public CommentHandler {
99 Lexer::getSourceText(CharSourceRange::getCharRange(
Range),
100 PP.getSourceManager(), PP.getLangOpts());
105 "comment contains misleading bidirectional Unicode characters");
121 const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
122 PP->addCommentHandler(Handler.get());
126 const ast_matchers::MatchFinder::MatchResult &Result) {
127 if (
const auto *SL = Result.Nodes.getNodeAs<StringLiteral>(
"strlit")) {
128 StringRef Literal = SL->getBytes();
130 diag(SL->getBeginLoc(),
"string literal contains misleading "
131 "bidirectional Unicode characters");
136 ast_matchers::MatchFinder *Finder) {
137 Finder->addMatcher(ast_matchers::stringLiteral().bind(
"strlit"),
this);
llvm::SmallString< 256U > Name
CharSourceRange Range
SourceRange for the file name.
static bool containsMisleadingBidi(StringRef Buffer, bool HonorLineBreaks=true)
MisleadingBidirectionalHandler(MisleadingBidirectionalCheck &Check)
bool HandleComment(Preprocessor &PP, SourceRange Range) override
Base class for all clang-tidy checks.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
MisleadingBidirectionalCheck(StringRef Name, ClangTidyContext *Context)
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override
Override this to register PPCallbacks in the preprocessor.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
~MisleadingBidirectionalCheck()
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//