17#include "clang/AST/ASTContext.h"
18#include "clang/Basic/CharInfo.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Lex/Lexer.h"
24BraceInsertionHints::operator bool()
const {
return DiagnosticPos.isValid(); }
27 return OpeningBracePos.isValid() && ClosingBracePos.isValid();
31 const SourceManager &SourceMgr)
const {
32 return SourceMgr.getSpellingLineNumber(ClosingBracePos) -
33 SourceMgr.getSpellingLineNumber(OpeningBracePos);
37 return OpeningBracePos.isValid()
38 ? FixItHint::CreateInsertion(OpeningBracePos,
" {")
43 return ClosingBracePos.isValid()
44 ? FixItHint::CreateInsertion(ClosingBracePos, ClosingBrace)
48static tok::TokenKind
getTokenKind(SourceLocation Loc,
const SourceManager &SM,
49 const LangOptions &LangOpts) {
51 const SourceLocation Beginning =
52 Lexer::GetBeginningOfToken(Loc, SM, LangOpts);
53 const bool Invalid = Lexer::getRawToken(Beginning, Tok, SM, LangOpts);
54 assert(!Invalid &&
"Expected a valid token.");
57 return tok::NUM_TOKENS;
63 const LangOptions &LangOpts) {
69 Loc = Loc.getLocWithOffset(1);
72 assert(Loc.isValid());
73 while (isHorizontalWhitespace(*SM.getCharacterData(Loc))) {
74 Loc = Loc.getLocWithOffset(1);
77 if (isVerticalWhitespace(*SM.getCharacterData(Loc))) {
81 const tok::TokenKind TokKind =
getTokenKind(Loc, SM, LangOpts);
82 if (TokKind != tok::comment) {
87 const SourceLocation TokEndLoc =
88 Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts);
89 const SourceRange TokRange(Loc, TokEndLoc);
90 const StringRef Comment = Lexer::getSourceText(
91 CharSourceRange::getTokenRange(TokRange), SM, LangOpts);
92 if (Comment.starts_with(
"/*") && Comment.contains(
'\n')) {
105 const LangOptions &LangOpts,
106 const SourceManager &SM,
107 SourceLocation StartLoc,
108 SourceLocation EndLocHint) {
116 if (!S || isa<CompoundStmt>(S)) {
123 const SourceLocation StmtBeginLoc = S->getBeginLoc();
124 if (isa<NullStmt>(S) && StmtBeginLoc.isValid() &&
125 getTokenKind(StmtBeginLoc, SM, LangOpts) == tok::l_brace)
128 if (StartLoc.isInvalid())
134 StartLoc = Lexer::makeFileCharRange(
135 CharSourceRange::getCharRange(StartLoc, S->getBeginLoc()), SM,
138 if (StartLoc.isInvalid())
140 StartLoc = Lexer::getLocForEndOfToken(StartLoc, 0, SM, LangOpts);
143 SourceLocation EndLoc;
144 StringRef ClosingInsertion;
145 if (EndLocHint.isValid()) {
147 ClosingInsertion =
"} ";
150 ClosingInsertion =
"\n}";
153 assert(StartLoc.isValid());
161 if (Lexer::makeFileCharRange(
162 CharSourceRange::getTokenRange(SourceRange(
163 SM.getSpellingLoc(StartLoc), SM.getSpellingLoc(EndLoc))),
167 return {StartLoc, EndLoc, ClosingInsertion};
This file provides utilities to put braces around a statement.
SourceLocation getUnifiedEndLoc(const Stmt &S, const SourceManager &SM, const LangOptions &LangOpts)
Stmt->getEndLoc does not always behave the same way depending on Token type.
static SourceLocation findEndLocation(const Stmt &S, const SourceManager &SM, const LangOptions &LangOpts)
BraceInsertionHints getBraceInsertionsHints(const Stmt *const S, const LangOptions &LangOpts, const SourceManager &SM, SourceLocation StartLoc, SourceLocation EndLocHint)
Create fix-it hints for braces that wrap the given statement when applied.
static tok::TokenKind getTokenKind(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
A provider of fix-it hints to insert opening and closing braces.
SourceLocation DiagnosticPos
The position of a potential diagnostic.
FixItHint closingBraceFixIt() const
Fix-it to insert a closing brace.
bool offersFixIts() const
Indicates whether the hint provides fix-its to insert braces.
unsigned resultingCompoundLineExtent(const SourceManager &SourceMgr) const
The number of lines between the inserted opening brace and its closing counterpart.
FixItHint openingBraceFixIt() const
Fix-it to insert an opening brace.