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);
76 if (isVerticalWhitespace(*SM.getCharacterData(Loc))) {
80 const tok::TokenKind TokKind =
getTokenKind(Loc, SM, LangOpts);
81 if (TokKind != tok::comment) {
86 const SourceLocation TokEndLoc =
87 Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts);
88 const SourceRange TokRange(Loc, TokEndLoc);
89 const StringRef Comment = Lexer::getSourceText(
90 CharSourceRange::getTokenRange(TokRange), SM, LangOpts);
91 if (Comment.starts_with(
"/*") && Comment.contains(
'\n')) {
104 const LangOptions &LangOpts,
105 const SourceManager &SM,
106 SourceLocation StartLoc,
107 SourceLocation EndLocHint) {
117 if (!S || isa<CompoundStmt>(S)) {
124 const SourceLocation StmtBeginLoc = S->getBeginLoc();
125 if (isa<NullStmt>(S) && StmtBeginLoc.isValid() &&
126 getTokenKind(StmtBeginLoc, SM, LangOpts) == tok::l_brace)
129 if (StartLoc.isInvalid())
132 const Stmt *InnerS = S;
133 while (
const auto *AS = dyn_cast<AttributedStmt>(InnerS))
134 InnerS = AS->getSubStmt();
136 SourceLocation InsertLoc = StartLoc;
139 InnerS->getBeginLoc(), SM, LangOpts,
true)) {
140 InsertLoc = Tok->getLocation();
147 StartLoc = Lexer::makeFileCharRange(CharSourceRange::getCharRange(
148 InsertLoc, InnerS->getBeginLoc()),
151 if (StartLoc.isInvalid())
153 StartLoc = Lexer::getLocForEndOfToken(StartLoc, 0, SM, LangOpts);
156 SourceLocation EndLoc;
157 StringRef ClosingInsertion;
158 if (EndLocHint.isValid()) {
160 ClosingInsertion =
"} ";
162 const SourceLocation StmtEndLoc = S->getEndLoc();
163 if (StmtEndLoc.isMacroID() && SM.isMacroBodyExpansion(StmtEndLoc) &&
164 !Lexer::isAtEndOfMacroExpansion(StmtEndLoc, SM, LangOpts)) {
169 ClosingInsertion =
"\n}";
172 assert(StartLoc.isValid());
180 if (Lexer::makeFileCharRange(
181 CharSourceRange::getTokenRange(SourceRange(
182 SM.getSpellingLoc(StartLoc), SM.getSpellingLoc(EndLoc))),
186 return {StartLoc, EndLoc, ClosingInsertion};
std::optional< Token > getPreviousToken(SourceLocation Location, const SourceManager &SM, const LangOptions &LangOpts, bool SkipComments)
Returns previous token or std::nullopt if not found.
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.