WhitespaceManager.cpp 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556
  1. //===--- WhitespaceManager.cpp - Format C++ code --------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// This file implements WhitespaceManager class.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13. #include "WhitespaceManager.h"
  14. #include "llvm/ADT/STLExtras.h"
  15. #include "llvm/ADT/SmallVector.h"
  16. #include <algorithm>
  17. namespace clang {
  18. namespace format {
  19. bool WhitespaceManager::Change::IsBeforeInFile::operator()(
  20. const Change &C1, const Change &C2) const {
  21. return SourceMgr.isBeforeInTranslationUnit(
  22. C1.OriginalWhitespaceRange.getBegin(),
  23. C2.OriginalWhitespaceRange.getBegin());
  24. }
  25. WhitespaceManager::Change::Change(const FormatToken &Tok,
  26. bool CreateReplacement,
  27. SourceRange OriginalWhitespaceRange,
  28. int Spaces, unsigned StartOfTokenColumn,
  29. unsigned NewlinesBefore,
  30. StringRef PreviousLinePostfix,
  31. StringRef CurrentLinePrefix, bool IsAligned,
  32. bool ContinuesPPDirective, bool IsInsideToken)
  33. : Tok(&Tok), CreateReplacement(CreateReplacement),
  34. OriginalWhitespaceRange(OriginalWhitespaceRange),
  35. StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore),
  36. PreviousLinePostfix(PreviousLinePostfix),
  37. CurrentLinePrefix(CurrentLinePrefix), IsAligned(IsAligned),
  38. ContinuesPPDirective(ContinuesPPDirective), Spaces(Spaces),
  39. IsInsideToken(IsInsideToken), IsTrailingComment(false), TokenLength(0),
  40. PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0),
  41. StartOfBlockComment(nullptr), IndentationOffset(0), ConditionalsLevel(0) {
  42. }
  43. void WhitespaceManager::replaceWhitespace(FormatToken &Tok, unsigned Newlines,
  44. unsigned Spaces,
  45. unsigned StartOfTokenColumn,
  46. bool IsAligned, bool InPPDirective) {
  47. if (Tok.Finalized)
  48. return;
  49. Tok.setDecision((Newlines > 0) ? FD_Break : FD_Continue);
  50. Changes.push_back(Change(Tok, /*CreateReplacement=*/true, Tok.WhitespaceRange,
  51. Spaces, StartOfTokenColumn, Newlines, "", "",
  52. IsAligned, InPPDirective && !Tok.IsFirst,
  53. /*IsInsideToken=*/false));
  54. }
  55. void WhitespaceManager::addUntouchableToken(const FormatToken &Tok,
  56. bool InPPDirective) {
  57. if (Tok.Finalized)
  58. return;
  59. Changes.push_back(Change(Tok, /*CreateReplacement=*/false,
  60. Tok.WhitespaceRange, /*Spaces=*/0,
  61. Tok.OriginalColumn, Tok.NewlinesBefore, "", "",
  62. /*IsAligned=*/false, InPPDirective && !Tok.IsFirst,
  63. /*IsInsideToken=*/false));
  64. }
  65. llvm::Error
  66. WhitespaceManager::addReplacement(const tooling::Replacement &Replacement) {
  67. return Replaces.add(Replacement);
  68. }
  69. bool WhitespaceManager::inputUsesCRLF(StringRef Text, bool DefaultToCRLF) {
  70. size_t LF = Text.count('\n');
  71. size_t CR = Text.count('\r') * 2;
  72. return LF == CR ? DefaultToCRLF : CR > LF;
  73. }
  74. void WhitespaceManager::replaceWhitespaceInToken(
  75. const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
  76. StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
  77. unsigned Newlines, int Spaces) {
  78. if (Tok.Finalized)
  79. return;
  80. SourceLocation Start = Tok.getStartOfNonWhitespace().getLocWithOffset(Offset);
  81. Changes.push_back(
  82. Change(Tok, /*CreateReplacement=*/true,
  83. SourceRange(Start, Start.getLocWithOffset(ReplaceChars)), Spaces,
  84. std::max(0, Spaces), Newlines, PreviousPostfix, CurrentPrefix,
  85. /*IsAligned=*/true, InPPDirective && !Tok.IsFirst,
  86. /*IsInsideToken=*/true));
  87. }
  88. const tooling::Replacements &WhitespaceManager::generateReplacements() {
  89. if (Changes.empty())
  90. return Replaces;
  91. llvm::sort(Changes, Change::IsBeforeInFile(SourceMgr));
  92. calculateLineBreakInformation();
  93. alignConsecutiveMacros();
  94. alignConsecutiveDeclarations();
  95. alignConsecutiveBitFields();
  96. alignConsecutiveAssignments();
  97. alignChainedConditionals();
  98. alignTrailingComments();
  99. alignEscapedNewlines();
  100. alignArrayInitializers();
  101. generateChanges();
  102. return Replaces;
  103. }
  104. void WhitespaceManager::calculateLineBreakInformation() {
  105. Changes[0].PreviousEndOfTokenColumn = 0;
  106. Change *LastOutsideTokenChange = &Changes[0];
  107. for (unsigned i = 1, e = Changes.size(); i != e; ++i) {
  108. SourceLocation OriginalWhitespaceStart =
  109. Changes[i].OriginalWhitespaceRange.getBegin();
  110. SourceLocation PreviousOriginalWhitespaceEnd =
  111. Changes[i - 1].OriginalWhitespaceRange.getEnd();
  112. unsigned OriginalWhitespaceStartOffset =
  113. SourceMgr.getFileOffset(OriginalWhitespaceStart);
  114. unsigned PreviousOriginalWhitespaceEndOffset =
  115. SourceMgr.getFileOffset(PreviousOriginalWhitespaceEnd);
  116. assert(PreviousOriginalWhitespaceEndOffset <=
  117. OriginalWhitespaceStartOffset);
  118. const char *const PreviousOriginalWhitespaceEndData =
  119. SourceMgr.getCharacterData(PreviousOriginalWhitespaceEnd);
  120. StringRef Text(PreviousOriginalWhitespaceEndData,
  121. SourceMgr.getCharacterData(OriginalWhitespaceStart) -
  122. PreviousOriginalWhitespaceEndData);
  123. // Usually consecutive changes would occur in consecutive tokens. This is
  124. // not the case however when analyzing some preprocessor runs of the
  125. // annotated lines. For example, in this code:
  126. //
  127. // #if A // line 1
  128. // int i = 1;
  129. // #else B // line 2
  130. // int i = 2;
  131. // #endif // line 3
  132. //
  133. // one of the runs will produce the sequence of lines marked with line 1, 2
  134. // and 3. So the two consecutive whitespace changes just before '// line 2'
  135. // and before '#endif // line 3' span multiple lines and tokens:
  136. //
  137. // #else B{change X}[// line 2
  138. // int i = 2;
  139. // ]{change Y}#endif // line 3
  140. //
  141. // For this reason, if the text between consecutive changes spans multiple
  142. // newlines, the token length must be adjusted to the end of the original
  143. // line of the token.
  144. auto NewlinePos = Text.find_first_of('\n');
  145. if (NewlinePos == StringRef::npos) {
  146. Changes[i - 1].TokenLength = OriginalWhitespaceStartOffset -
  147. PreviousOriginalWhitespaceEndOffset +
  148. Changes[i].PreviousLinePostfix.size() +
  149. Changes[i - 1].CurrentLinePrefix.size();
  150. } else {
  151. Changes[i - 1].TokenLength =
  152. NewlinePos + Changes[i - 1].CurrentLinePrefix.size();
  153. }
  154. // If there are multiple changes in this token, sum up all the changes until
  155. // the end of the line.
  156. if (Changes[i - 1].IsInsideToken && Changes[i - 1].NewlinesBefore == 0) {
  157. LastOutsideTokenChange->TokenLength +=
  158. Changes[i - 1].TokenLength + Changes[i - 1].Spaces;
  159. } else {
  160. LastOutsideTokenChange = &Changes[i - 1];
  161. }
  162. Changes[i].PreviousEndOfTokenColumn =
  163. Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength;
  164. Changes[i - 1].IsTrailingComment =
  165. (Changes[i].NewlinesBefore > 0 || Changes[i].Tok->is(tok::eof) ||
  166. (Changes[i].IsInsideToken && Changes[i].Tok->is(tok::comment))) &&
  167. Changes[i - 1].Tok->is(tok::comment) &&
  168. // FIXME: This is a dirty hack. The problem is that
  169. // BreakableLineCommentSection does comment reflow changes and here is
  170. // the aligning of trailing comments. Consider the case where we reflow
  171. // the second line up in this example:
  172. //
  173. // // line 1
  174. // // line 2
  175. //
  176. // That amounts to 2 changes by BreakableLineCommentSection:
  177. // - the first, delimited by (), for the whitespace between the tokens,
  178. // - and second, delimited by [], for the whitespace at the beginning
  179. // of the second token:
  180. //
  181. // // line 1(
  182. // )[// ]line 2
  183. //
  184. // So in the end we have two changes like this:
  185. //
  186. // // line1()[ ]line 2
  187. //
  188. // Note that the OriginalWhitespaceStart of the second change is the
  189. // same as the PreviousOriginalWhitespaceEnd of the first change.
  190. // In this case, the below check ensures that the second change doesn't
  191. // get treated as a trailing comment change here, since this might
  192. // trigger additional whitespace to be wrongly inserted before "line 2"
  193. // by the comment aligner here.
  194. //
  195. // For a proper solution we need a mechanism to say to WhitespaceManager
  196. // that a particular change breaks the current sequence of trailing
  197. // comments.
  198. OriginalWhitespaceStart != PreviousOriginalWhitespaceEnd;
  199. }
  200. // FIXME: The last token is currently not always an eof token; in those
  201. // cases, setting TokenLength of the last token to 0 is wrong.
  202. Changes.back().TokenLength = 0;
  203. Changes.back().IsTrailingComment = Changes.back().Tok->is(tok::comment);
  204. const WhitespaceManager::Change *LastBlockComment = nullptr;
  205. for (auto &Change : Changes) {
  206. // Reset the IsTrailingComment flag for changes inside of trailing comments
  207. // so they don't get realigned later. Comment line breaks however still need
  208. // to be aligned.
  209. if (Change.IsInsideToken && Change.NewlinesBefore == 0)
  210. Change.IsTrailingComment = false;
  211. Change.StartOfBlockComment = nullptr;
  212. Change.IndentationOffset = 0;
  213. if (Change.Tok->is(tok::comment)) {
  214. if (Change.Tok->is(TT_LineComment) || !Change.IsInsideToken) {
  215. LastBlockComment = &Change;
  216. } else if ((Change.StartOfBlockComment = LastBlockComment)) {
  217. Change.IndentationOffset =
  218. Change.StartOfTokenColumn -
  219. Change.StartOfBlockComment->StartOfTokenColumn;
  220. }
  221. } else {
  222. LastBlockComment = nullptr;
  223. }
  224. }
  225. // Compute conditional nesting level
  226. // Level is increased for each conditional, unless this conditional continues
  227. // a chain of conditional, i.e. starts immediately after the colon of another
  228. // conditional.
  229. SmallVector<bool, 16> ScopeStack;
  230. int ConditionalsLevel = 0;
  231. for (auto &Change : Changes) {
  232. for (unsigned i = 0, e = Change.Tok->FakeLParens.size(); i != e; ++i) {
  233. bool isNestedConditional =
  234. Change.Tok->FakeLParens[e - 1 - i] == prec::Conditional &&
  235. !(i == 0 && Change.Tok->Previous &&
  236. Change.Tok->Previous->is(TT_ConditionalExpr) &&
  237. Change.Tok->Previous->is(tok::colon));
  238. if (isNestedConditional)
  239. ++ConditionalsLevel;
  240. ScopeStack.push_back(isNestedConditional);
  241. }
  242. Change.ConditionalsLevel = ConditionalsLevel;
  243. for (unsigned i = Change.Tok->FakeRParens; i > 0 && ScopeStack.size(); --i)
  244. if (ScopeStack.pop_back_val())
  245. --ConditionalsLevel;
  246. }
  247. }
  248. // Align a single sequence of tokens, see AlignTokens below.
  249. // Column - The token for which Matches returns true is moved to this column.
  250. // RightJustify - Whether it is the token's right end or left end that gets
  251. // moved to that column.
  252. template <typename F>
  253. static void
  254. AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
  255. unsigned Column, bool RightJustify, F &&Matches,
  256. SmallVector<WhitespaceManager::Change, 16> &Changes) {
  257. bool FoundMatchOnLine = false;
  258. int Shift = 0;
  259. // ScopeStack keeps track of the current scope depth. It contains indices of
  260. // the first token on each scope.
  261. // We only run the "Matches" function on tokens from the outer-most scope.
  262. // However, we do need to pay special attention to one class of tokens
  263. // that are not in the outer-most scope, and that is function parameters
  264. // which are split across multiple lines, as illustrated by this example:
  265. // double a(int x);
  266. // int b(int y,
  267. // double z);
  268. // In the above example, we need to take special care to ensure that
  269. // 'double z' is indented along with it's owning function 'b'.
  270. // The same holds for calling a function:
  271. // double a = foo(x);
  272. // int b = bar(foo(y),
  273. // foor(z));
  274. // Similar for broken string literals:
  275. // double x = 3.14;
  276. // auto s = "Hello"
  277. // "World";
  278. // Special handling is required for 'nested' ternary operators.
  279. SmallVector<unsigned, 16> ScopeStack;
  280. for (unsigned i = Start; i != End; ++i) {
  281. if (ScopeStack.size() != 0 &&
  282. Changes[i].indentAndNestingLevel() <
  283. Changes[ScopeStack.back()].indentAndNestingLevel()) {
  284. ScopeStack.pop_back();
  285. }
  286. // Compare current token to previous non-comment token to ensure whether
  287. // it is in a deeper scope or not.
  288. unsigned PreviousNonComment = i - 1;
  289. while (PreviousNonComment > Start &&
  290. Changes[PreviousNonComment].Tok->is(tok::comment)) {
  291. --PreviousNonComment;
  292. }
  293. if (i != Start && Changes[i].indentAndNestingLevel() >
  294. Changes[PreviousNonComment].indentAndNestingLevel()) {
  295. ScopeStack.push_back(i);
  296. }
  297. bool InsideNestedScope = ScopeStack.size() != 0;
  298. bool ContinuedStringLiteral = i > Start &&
  299. Changes[i].Tok->is(tok::string_literal) &&
  300. Changes[i - 1].Tok->is(tok::string_literal);
  301. bool SkipMatchCheck = InsideNestedScope || ContinuedStringLiteral;
  302. if (Changes[i].NewlinesBefore > 0 && !SkipMatchCheck) {
  303. Shift = 0;
  304. FoundMatchOnLine = false;
  305. }
  306. // If this is the first matching token to be aligned, remember by how many
  307. // spaces it has to be shifted, so the rest of the changes on the line are
  308. // shifted by the same amount
  309. if (!FoundMatchOnLine && !SkipMatchCheck && Matches(Changes[i])) {
  310. FoundMatchOnLine = true;
  311. Shift = Column - (RightJustify ? Changes[i].TokenLength : 0) -
  312. Changes[i].StartOfTokenColumn;
  313. Changes[i].Spaces += Shift;
  314. // FIXME: This is a workaround that should be removed when we fix
  315. // http://llvm.org/PR53699. An assertion later below verifies this.
  316. if (Changes[i].NewlinesBefore == 0) {
  317. Changes[i].Spaces =
  318. std::max(Changes[i].Spaces,
  319. static_cast<int>(Changes[i].Tok->SpacesRequiredBefore));
  320. }
  321. }
  322. // This is for function parameters that are split across multiple lines,
  323. // as mentioned in the ScopeStack comment.
  324. if (InsideNestedScope && Changes[i].NewlinesBefore > 0) {
  325. unsigned ScopeStart = ScopeStack.back();
  326. auto ShouldShiftBeAdded = [&] {
  327. // Function declaration
  328. if (Changes[ScopeStart - 1].Tok->is(TT_FunctionDeclarationName))
  329. return true;
  330. // Lambda.
  331. if (Changes[ScopeStart - 1].Tok->is(TT_LambdaLBrace))
  332. return false;
  333. // Continued function declaration
  334. if (ScopeStart > Start + 1 &&
  335. Changes[ScopeStart - 2].Tok->is(TT_FunctionDeclarationName)) {
  336. return true;
  337. }
  338. // Continued function call
  339. if (ScopeStart > Start + 1 &&
  340. Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
  341. Changes[ScopeStart - 1].Tok->is(tok::l_paren) &&
  342. Changes[ScopeStart].Tok->isNot(TT_LambdaLSquare)) {
  343. if (Changes[i].Tok->MatchingParen &&
  344. Changes[i].Tok->MatchingParen->is(TT_LambdaLBrace)) {
  345. return false;
  346. }
  347. if (Changes[ScopeStart].NewlinesBefore > 0)
  348. return false;
  349. if (Changes[i].Tok->is(tok::l_brace) &&
  350. Changes[i].Tok->is(BK_BracedInit)) {
  351. return true;
  352. }
  353. return Style.BinPackArguments;
  354. }
  355. // Ternary operator
  356. if (Changes[i].Tok->is(TT_ConditionalExpr))
  357. return true;
  358. // Period Initializer .XXX = 1.
  359. if (Changes[i].Tok->is(TT_DesignatedInitializerPeriod))
  360. return true;
  361. // Continued ternary operator
  362. if (Changes[i].Tok->Previous &&
  363. Changes[i].Tok->Previous->is(TT_ConditionalExpr)) {
  364. return true;
  365. }
  366. // Continued direct-list-initialization using braced list.
  367. if (ScopeStart > Start + 1 &&
  368. Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
  369. Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
  370. Changes[i].Tok->is(tok::l_brace) &&
  371. Changes[i].Tok->is(BK_BracedInit)) {
  372. return true;
  373. }
  374. // Continued braced list.
  375. if (ScopeStart > Start + 1 &&
  376. Changes[ScopeStart - 2].Tok->isNot(tok::identifier) &&
  377. Changes[ScopeStart - 1].Tok->is(tok::l_brace) &&
  378. Changes[i].Tok->isNot(tok::r_brace)) {
  379. for (unsigned OuterScopeStart : llvm::reverse(ScopeStack)) {
  380. // Lambda.
  381. if (OuterScopeStart > Start &&
  382. Changes[OuterScopeStart - 1].Tok->is(TT_LambdaLBrace)) {
  383. return false;
  384. }
  385. }
  386. if (Changes[ScopeStart].NewlinesBefore > 0)
  387. return false;
  388. return true;
  389. }
  390. return false;
  391. };
  392. if (ShouldShiftBeAdded())
  393. Changes[i].Spaces += Shift;
  394. }
  395. if (ContinuedStringLiteral)
  396. Changes[i].Spaces += Shift;
  397. // We should not remove required spaces unless we break the line before.
  398. assert(Shift >= 0 || Changes[i].NewlinesBefore > 0 ||
  399. Changes[i].Spaces >=
  400. static_cast<int>(Changes[i].Tok->SpacesRequiredBefore) ||
  401. Changes[i].Tok->is(tok::eof));
  402. Changes[i].StartOfTokenColumn += Shift;
  403. if (i + 1 != Changes.size())
  404. Changes[i + 1].PreviousEndOfTokenColumn += Shift;
  405. // If PointerAlignment is PAS_Right, keep *s or &s next to the token
  406. if (Style.PointerAlignment == FormatStyle::PAS_Right &&
  407. Changes[i].Spaces != 0) {
  408. for (int Previous = i - 1;
  409. Previous >= 0 &&
  410. Changes[Previous].Tok->getType() == TT_PointerOrReference;
  411. --Previous) {
  412. Changes[Previous + 1].Spaces -= Shift;
  413. Changes[Previous].Spaces += Shift;
  414. Changes[Previous].StartOfTokenColumn += Shift;
  415. }
  416. }
  417. }
  418. }
  419. // Walk through a subset of the changes, starting at StartAt, and find
  420. // sequences of matching tokens to align. To do so, keep track of the lines and
  421. // whether or not a matching token was found on a line. If a matching token is
  422. // found, extend the current sequence. If the current line cannot be part of a
  423. // sequence, e.g. because there is an empty line before it or it contains only
  424. // non-matching tokens, finalize the previous sequence.
  425. // The value returned is the token on which we stopped, either because we
  426. // exhausted all items inside Changes, or because we hit a scope level higher
  427. // than our initial scope.
  428. // This function is recursive. Each invocation processes only the scope level
  429. // equal to the initial level, which is the level of Changes[StartAt].
  430. // If we encounter a scope level greater than the initial level, then we call
  431. // ourselves recursively, thereby avoiding the pollution of the current state
  432. // with the alignment requirements of the nested sub-level. This recursive
  433. // behavior is necessary for aligning function prototypes that have one or more
  434. // arguments.
  435. // If this function encounters a scope level less than the initial level,
  436. // it returns the current position.
  437. // There is a non-obvious subtlety in the recursive behavior: Even though we
  438. // defer processing of nested levels to recursive invocations of this
  439. // function, when it comes time to align a sequence of tokens, we run the
  440. // alignment on the entire sequence, including the nested levels.
  441. // When doing so, most of the nested tokens are skipped, because their
  442. // alignment was already handled by the recursive invocations of this function.
  443. // However, the special exception is that we do NOT skip function parameters
  444. // that are split across multiple lines. See the test case in FormatTest.cpp
  445. // that mentions "split function parameter alignment" for an example of this.
  446. // When the parameter RightJustify is true, the operator will be
  447. // right-justified. It is used to align compound assignments like `+=` and `=`.
  448. // When RightJustify and ACS.PadOperators are true, operators in each block to
  449. // be aligned will be padded on the left to the same length before aligning.
  450. template <typename F>
  451. static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
  452. SmallVector<WhitespaceManager::Change, 16> &Changes,
  453. unsigned StartAt,
  454. const FormatStyle::AlignConsecutiveStyle &ACS = {},
  455. bool RightJustify = false) {
  456. // We arrange each line in 3 parts. The operator to be aligned (the anchor),
  457. // and text to its left and right. In the aligned text the width of each part
  458. // will be the maximum of that over the block that has been aligned. Maximum
  459. // widths of each part so far. When RightJustify is true and ACS.PadOperators
  460. // is false, the part from start of line to the right end of the anchor.
  461. // Otherwise, only the part to the left of the anchor. Including the space
  462. // that exists on its left from the start. Not including the padding added on
  463. // the left to right-justify the anchor.
  464. unsigned WidthLeft = 0;
  465. // The operator to be aligned when RightJustify is true and ACS.PadOperators
  466. // is false. 0 otherwise.
  467. unsigned WidthAnchor = 0;
  468. // Width to the right of the anchor. Plus width of the anchor when
  469. // RightJustify is false.
  470. unsigned WidthRight = 0;
  471. // Line number of the start and the end of the current token sequence.
  472. unsigned StartOfSequence = 0;
  473. unsigned EndOfSequence = 0;
  474. // Measure the scope level (i.e. depth of (), [], {}) of the first token, and
  475. // abort when we hit any token in a higher scope than the starting one.
  476. auto IndentAndNestingLevel = StartAt < Changes.size()
  477. ? Changes[StartAt].indentAndNestingLevel()
  478. : std::tuple<unsigned, unsigned, unsigned>();
  479. // Keep track if the first token has a non-zero indent and nesting level.
  480. // This can happen when aligning the contents of "#else" preprocessor blocks,
  481. // which is done separately.
  482. bool HasInitialIndentAndNesting =
  483. StartAt == 0 &&
  484. IndentAndNestingLevel > std::tuple<unsigned, unsigned, unsigned>();
  485. // Keep track of the number of commas before the matching tokens, we will only
  486. // align a sequence of matching tokens if they are preceded by the same number
  487. // of commas.
  488. unsigned CommasBeforeLastMatch = 0;
  489. unsigned CommasBeforeMatch = 0;
  490. // Whether a matching token has been found on the current line.
  491. bool FoundMatchOnLine = false;
  492. // Whether the current line consists purely of comments.
  493. bool LineIsComment = true;
  494. // Aligns a sequence of matching tokens, on the MinColumn column.
  495. //
  496. // Sequences start from the first matching token to align, and end at the
  497. // first token of the first line that doesn't need to be aligned.
  498. //
  499. // We need to adjust the StartOfTokenColumn of each Change that is on a line
  500. // containing any matching token to be aligned and located after such token.
  501. auto AlignCurrentSequence = [&] {
  502. if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) {
  503. AlignTokenSequence(Style, StartOfSequence, EndOfSequence,
  504. WidthLeft + WidthAnchor, RightJustify, Matches,
  505. Changes);
  506. }
  507. WidthLeft = 0;
  508. WidthAnchor = 0;
  509. WidthRight = 0;
  510. StartOfSequence = 0;
  511. EndOfSequence = 0;
  512. };
  513. unsigned i = StartAt;
  514. for (unsigned e = Changes.size(); i != e; ++i) {
  515. if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel) {
  516. if (!HasInitialIndentAndNesting)
  517. break;
  518. // The contents of preprocessor blocks are aligned separately.
  519. // If the initial preprocessor block is indented or nested (e.g. it's in
  520. // a function), do not align and exit after finishing this scope block.
  521. // Instead, align, and then lower the baseline indent and nesting level
  522. // in order to continue aligning subsequent blocks.
  523. EndOfSequence = i;
  524. AlignCurrentSequence();
  525. IndentAndNestingLevel =
  526. Changes[i].indentAndNestingLevel(); // new baseline
  527. }
  528. if (Changes[i].NewlinesBefore != 0) {
  529. CommasBeforeMatch = 0;
  530. EndOfSequence = i;
  531. // Whether to break the alignment sequence because of an empty line.
  532. bool EmptyLineBreak =
  533. (Changes[i].NewlinesBefore > 1) && !ACS.AcrossEmptyLines;
  534. // Whether to break the alignment sequence because of a line without a
  535. // match.
  536. bool NoMatchBreak =
  537. !FoundMatchOnLine && !(LineIsComment && ACS.AcrossComments);
  538. if (EmptyLineBreak || NoMatchBreak)
  539. AlignCurrentSequence();
  540. // A new line starts, re-initialize line status tracking bools.
  541. // Keep the match state if a string literal is continued on this line.
  542. if (i == 0 || !Changes[i].Tok->is(tok::string_literal) ||
  543. !Changes[i - 1].Tok->is(tok::string_literal)) {
  544. FoundMatchOnLine = false;
  545. }
  546. LineIsComment = true;
  547. }
  548. if (!Changes[i].Tok->is(tok::comment))
  549. LineIsComment = false;
  550. if (Changes[i].Tok->is(tok::comma)) {
  551. ++CommasBeforeMatch;
  552. } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
  553. // Call AlignTokens recursively, skipping over this scope block.
  554. unsigned StoppedAt =
  555. AlignTokens(Style, Matches, Changes, i, ACS, RightJustify);
  556. i = StoppedAt - 1;
  557. continue;
  558. }
  559. if (!Matches(Changes[i]))
  560. continue;
  561. // If there is more than one matching token per line, or if the number of
  562. // preceding commas, do not match anymore, end the sequence.
  563. if (FoundMatchOnLine || CommasBeforeMatch != CommasBeforeLastMatch)
  564. AlignCurrentSequence();
  565. CommasBeforeLastMatch = CommasBeforeMatch;
  566. FoundMatchOnLine = true;
  567. if (StartOfSequence == 0)
  568. StartOfSequence = i;
  569. unsigned ChangeWidthLeft = Changes[i].StartOfTokenColumn;
  570. unsigned ChangeWidthAnchor = 0;
  571. unsigned ChangeWidthRight = 0;
  572. if (RightJustify)
  573. if (ACS.PadOperators)
  574. ChangeWidthAnchor = Changes[i].TokenLength;
  575. else
  576. ChangeWidthLeft += Changes[i].TokenLength;
  577. else
  578. ChangeWidthRight = Changes[i].TokenLength;
  579. for (unsigned j = i + 1; j != e && Changes[j].NewlinesBefore == 0; ++j) {
  580. ChangeWidthRight += Changes[j].Spaces;
  581. // Changes are generally 1:1 with the tokens, but a change could also be
  582. // inside of a token, in which case it's counted more than once: once for
  583. // the whitespace surrounding the token (!IsInsideToken) and once for
  584. // each whitespace change within it (IsInsideToken).
  585. // Therefore, changes inside of a token should only count the space.
  586. if (!Changes[j].IsInsideToken)
  587. ChangeWidthRight += Changes[j].TokenLength;
  588. }
  589. // If we are restricted by the maximum column width, end the sequence.
  590. unsigned NewLeft = std::max(ChangeWidthLeft, WidthLeft);
  591. unsigned NewAnchor = std::max(ChangeWidthAnchor, WidthAnchor);
  592. unsigned NewRight = std::max(ChangeWidthRight, WidthRight);
  593. // `ColumnLimit == 0` means there is no column limit.
  594. if (Style.ColumnLimit != 0 &&
  595. Style.ColumnLimit < NewLeft + NewAnchor + NewRight) {
  596. AlignCurrentSequence();
  597. StartOfSequence = i;
  598. WidthLeft = ChangeWidthLeft;
  599. WidthAnchor = ChangeWidthAnchor;
  600. WidthRight = ChangeWidthRight;
  601. } else {
  602. WidthLeft = NewLeft;
  603. WidthAnchor = NewAnchor;
  604. WidthRight = NewRight;
  605. }
  606. }
  607. EndOfSequence = i;
  608. AlignCurrentSequence();
  609. return i;
  610. }
  611. // Aligns a sequence of matching tokens, on the MinColumn column.
  612. //
  613. // Sequences start from the first matching token to align, and end at the
  614. // first token of the first line that doesn't need to be aligned.
  615. //
  616. // We need to adjust the StartOfTokenColumn of each Change that is on a line
  617. // containing any matching token to be aligned and located after such token.
  618. static void AlignMacroSequence(
  619. unsigned &StartOfSequence, unsigned &EndOfSequence, unsigned &MinColumn,
  620. unsigned &MaxColumn, bool &FoundMatchOnLine,
  621. std::function<bool(const WhitespaceManager::Change &C)> AlignMacrosMatches,
  622. SmallVector<WhitespaceManager::Change, 16> &Changes) {
  623. if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) {
  624. FoundMatchOnLine = false;
  625. int Shift = 0;
  626. for (unsigned I = StartOfSequence; I != EndOfSequence; ++I) {
  627. if (Changes[I].NewlinesBefore > 0) {
  628. Shift = 0;
  629. FoundMatchOnLine = false;
  630. }
  631. // If this is the first matching token to be aligned, remember by how many
  632. // spaces it has to be shifted, so the rest of the changes on the line are
  633. // shifted by the same amount
  634. if (!FoundMatchOnLine && AlignMacrosMatches(Changes[I])) {
  635. FoundMatchOnLine = true;
  636. Shift = MinColumn - Changes[I].StartOfTokenColumn;
  637. Changes[I].Spaces += Shift;
  638. }
  639. assert(Shift >= 0);
  640. Changes[I].StartOfTokenColumn += Shift;
  641. if (I + 1 != Changes.size())
  642. Changes[I + 1].PreviousEndOfTokenColumn += Shift;
  643. }
  644. }
  645. MinColumn = 0;
  646. MaxColumn = UINT_MAX;
  647. StartOfSequence = 0;
  648. EndOfSequence = 0;
  649. }
  650. void WhitespaceManager::alignConsecutiveMacros() {
  651. if (!Style.AlignConsecutiveMacros.Enabled)
  652. return;
  653. auto AlignMacrosMatches = [](const Change &C) {
  654. const FormatToken *Current = C.Tok;
  655. unsigned SpacesRequiredBefore = 1;
  656. if (Current->SpacesRequiredBefore == 0 || !Current->Previous)
  657. return false;
  658. Current = Current->Previous;
  659. // If token is a ")", skip over the parameter list, to the
  660. // token that precedes the "("
  661. if (Current->is(tok::r_paren) && Current->MatchingParen) {
  662. Current = Current->MatchingParen->Previous;
  663. SpacesRequiredBefore = 0;
  664. }
  665. if (!Current || !Current->is(tok::identifier))
  666. return false;
  667. if (!Current->Previous || !Current->Previous->is(tok::pp_define))
  668. return false;
  669. // For a macro function, 0 spaces are required between the
  670. // identifier and the lparen that opens the parameter list.
  671. // For a simple macro, 1 space is required between the
  672. // identifier and the first token of the defined value.
  673. return Current->Next->SpacesRequiredBefore == SpacesRequiredBefore;
  674. };
  675. unsigned MinColumn = 0;
  676. unsigned MaxColumn = UINT_MAX;
  677. // Start and end of the token sequence we're processing.
  678. unsigned StartOfSequence = 0;
  679. unsigned EndOfSequence = 0;
  680. // Whether a matching token has been found on the current line.
  681. bool FoundMatchOnLine = false;
  682. // Whether the current line consists only of comments
  683. bool LineIsComment = true;
  684. unsigned I = 0;
  685. for (unsigned E = Changes.size(); I != E; ++I) {
  686. if (Changes[I].NewlinesBefore != 0) {
  687. EndOfSequence = I;
  688. // Whether to break the alignment sequence because of an empty line.
  689. bool EmptyLineBreak = (Changes[I].NewlinesBefore > 1) &&
  690. !Style.AlignConsecutiveMacros.AcrossEmptyLines;
  691. // Whether to break the alignment sequence because of a line without a
  692. // match.
  693. bool NoMatchBreak =
  694. !FoundMatchOnLine &&
  695. !(LineIsComment && Style.AlignConsecutiveMacros.AcrossComments);
  696. if (EmptyLineBreak || NoMatchBreak) {
  697. AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
  698. FoundMatchOnLine, AlignMacrosMatches, Changes);
  699. }
  700. // A new line starts, re-initialize line status tracking bools.
  701. FoundMatchOnLine = false;
  702. LineIsComment = true;
  703. }
  704. if (!Changes[I].Tok->is(tok::comment))
  705. LineIsComment = false;
  706. if (!AlignMacrosMatches(Changes[I]))
  707. continue;
  708. FoundMatchOnLine = true;
  709. if (StartOfSequence == 0)
  710. StartOfSequence = I;
  711. unsigned ChangeMinColumn = Changes[I].StartOfTokenColumn;
  712. int LineLengthAfter = -Changes[I].Spaces;
  713. for (unsigned j = I; j != E && Changes[j].NewlinesBefore == 0; ++j)
  714. LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength;
  715. unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter;
  716. MinColumn = std::max(MinColumn, ChangeMinColumn);
  717. MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
  718. }
  719. EndOfSequence = I;
  720. AlignMacroSequence(StartOfSequence, EndOfSequence, MinColumn, MaxColumn,
  721. FoundMatchOnLine, AlignMacrosMatches, Changes);
  722. }
  723. void WhitespaceManager::alignConsecutiveAssignments() {
  724. if (!Style.AlignConsecutiveAssignments.Enabled)
  725. return;
  726. AlignTokens(
  727. Style,
  728. [&](const Change &C) {
  729. // Do not align on equal signs that are first on a line.
  730. if (C.NewlinesBefore > 0)
  731. return false;
  732. // Do not align on equal signs that are last on a line.
  733. if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
  734. return false;
  735. // Do not align operator= overloads.
  736. FormatToken *Previous = C.Tok->getPreviousNonComment();
  737. if (Previous && Previous->is(tok::kw_operator))
  738. return false;
  739. return Style.AlignConsecutiveAssignments.AlignCompound
  740. ? C.Tok->getPrecedence() == prec::Assignment
  741. : C.Tok->is(tok::equal);
  742. },
  743. Changes, /*StartAt=*/0, Style.AlignConsecutiveAssignments,
  744. /*RightJustify=*/true);
  745. }
  746. void WhitespaceManager::alignConsecutiveBitFields() {
  747. if (!Style.AlignConsecutiveBitFields.Enabled)
  748. return;
  749. AlignTokens(
  750. Style,
  751. [&](Change const &C) {
  752. // Do not align on ':' that is first on a line.
  753. if (C.NewlinesBefore > 0)
  754. return false;
  755. // Do not align on ':' that is last on a line.
  756. if (&C != &Changes.back() && (&C + 1)->NewlinesBefore > 0)
  757. return false;
  758. return C.Tok->is(TT_BitFieldColon);
  759. },
  760. Changes, /*StartAt=*/0, Style.AlignConsecutiveBitFields);
  761. }
  762. void WhitespaceManager::alignConsecutiveDeclarations() {
  763. if (!Style.AlignConsecutiveDeclarations.Enabled)
  764. return;
  765. AlignTokens(
  766. Style,
  767. [](Change const &C) {
  768. if (C.Tok->is(TT_FunctionDeclarationName))
  769. return true;
  770. if (C.Tok->isNot(TT_StartOfName))
  771. return false;
  772. if (C.Tok->Previous &&
  773. C.Tok->Previous->is(TT_StatementAttributeLikeMacro))
  774. return false;
  775. // Check if there is a subsequent name that starts the same declaration.
  776. for (FormatToken *Next = C.Tok->Next; Next; Next = Next->Next) {
  777. if (Next->is(tok::comment))
  778. continue;
  779. if (Next->is(TT_PointerOrReference))
  780. return false;
  781. if (!Next->Tok.getIdentifierInfo())
  782. break;
  783. if (Next->isOneOf(TT_StartOfName, TT_FunctionDeclarationName,
  784. tok::kw_operator)) {
  785. return false;
  786. }
  787. }
  788. return true;
  789. },
  790. Changes, /*StartAt=*/0, Style.AlignConsecutiveDeclarations);
  791. }
  792. void WhitespaceManager::alignChainedConditionals() {
  793. if (Style.BreakBeforeTernaryOperators) {
  794. AlignTokens(
  795. Style,
  796. [](Change const &C) {
  797. // Align question operators and last colon
  798. return C.Tok->is(TT_ConditionalExpr) &&
  799. ((C.Tok->is(tok::question) && !C.NewlinesBefore) ||
  800. (C.Tok->is(tok::colon) && C.Tok->Next &&
  801. (C.Tok->Next->FakeLParens.size() == 0 ||
  802. C.Tok->Next->FakeLParens.back() != prec::Conditional)));
  803. },
  804. Changes, /*StartAt=*/0);
  805. } else {
  806. static auto AlignWrappedOperand = [](Change const &C) {
  807. FormatToken *Previous = C.Tok->getPreviousNonComment();
  808. return C.NewlinesBefore && Previous && Previous->is(TT_ConditionalExpr) &&
  809. (Previous->is(tok::colon) &&
  810. (C.Tok->FakeLParens.size() == 0 ||
  811. C.Tok->FakeLParens.back() != prec::Conditional));
  812. };
  813. // Ensure we keep alignment of wrapped operands with non-wrapped operands
  814. // Since we actually align the operators, the wrapped operands need the
  815. // extra offset to be properly aligned.
  816. for (Change &C : Changes)
  817. if (AlignWrappedOperand(C))
  818. C.StartOfTokenColumn -= 2;
  819. AlignTokens(
  820. Style,
  821. [this](Change const &C) {
  822. // Align question operators if next operand is not wrapped, as
  823. // well as wrapped operands after question operator or last
  824. // colon in conditional sequence
  825. return (C.Tok->is(TT_ConditionalExpr) && C.Tok->is(tok::question) &&
  826. &C != &Changes.back() && (&C + 1)->NewlinesBefore == 0 &&
  827. !(&C + 1)->IsTrailingComment) ||
  828. AlignWrappedOperand(C);
  829. },
  830. Changes, /*StartAt=*/0);
  831. }
  832. }
  833. void WhitespaceManager::alignTrailingComments() {
  834. unsigned MinColumn = 0;
  835. unsigned MaxColumn = UINT_MAX;
  836. unsigned StartOfSequence = 0;
  837. bool BreakBeforeNext = false;
  838. unsigned Newlines = 0;
  839. unsigned int NewLineThreshold = 1;
  840. if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Always)
  841. NewLineThreshold = Style.AlignTrailingComments.OverEmptyLines + 1;
  842. for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
  843. if (Changes[i].StartOfBlockComment)
  844. continue;
  845. Newlines += Changes[i].NewlinesBefore;
  846. if (!Changes[i].IsTrailingComment)
  847. continue;
  848. if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Leave) {
  849. auto OriginalSpaces =
  850. Changes[i].OriginalWhitespaceRange.getEnd().getRawEncoding() -
  851. Changes[i].OriginalWhitespaceRange.getBegin().getRawEncoding() -
  852. Changes[i].Tok->NewlinesBefore;
  853. unsigned RestoredLineLength = Changes[i].StartOfTokenColumn +
  854. Changes[i].TokenLength + OriginalSpaces;
  855. // If leaving comments makes the line exceed the column limit, give up to
  856. // leave the comments.
  857. if (RestoredLineLength >= Style.ColumnLimit && Style.ColumnLimit != 0)
  858. break;
  859. Changes[i].Spaces = OriginalSpaces;
  860. continue;
  861. }
  862. unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
  863. unsigned ChangeMaxColumn;
  864. if (Style.ColumnLimit == 0)
  865. ChangeMaxColumn = UINT_MAX;
  866. else if (Style.ColumnLimit >= Changes[i].TokenLength)
  867. ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
  868. else
  869. ChangeMaxColumn = ChangeMinColumn;
  870. // If we don't create a replacement for this change, we have to consider
  871. // it to be immovable.
  872. if (!Changes[i].CreateReplacement)
  873. ChangeMaxColumn = ChangeMinColumn;
  874. if (i + 1 != e && Changes[i + 1].ContinuesPPDirective)
  875. ChangeMaxColumn -= 2;
  876. // If this comment follows an } in column 0, it probably documents the
  877. // closing of a namespace and we don't want to align it.
  878. bool FollowsRBraceInColumn0 = i > 0 && Changes[i].NewlinesBefore == 0 &&
  879. Changes[i - 1].Tok->is(tok::r_brace) &&
  880. Changes[i - 1].StartOfTokenColumn == 0;
  881. bool WasAlignedWithStartOfNextLine = false;
  882. if (Changes[i].NewlinesBefore >= 1) { // A comment on its own line.
  883. unsigned CommentColumn = SourceMgr.getSpellingColumnNumber(
  884. Changes[i].OriginalWhitespaceRange.getEnd());
  885. for (unsigned j = i + 1; j != e; ++j) {
  886. if (Changes[j].Tok->is(tok::comment))
  887. continue;
  888. unsigned NextColumn = SourceMgr.getSpellingColumnNumber(
  889. Changes[j].OriginalWhitespaceRange.getEnd());
  890. // The start of the next token was previously aligned with the
  891. // start of this comment.
  892. WasAlignedWithStartOfNextLine =
  893. CommentColumn == NextColumn ||
  894. CommentColumn == NextColumn + Style.IndentWidth;
  895. break;
  896. }
  897. }
  898. if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Never ||
  899. FollowsRBraceInColumn0) {
  900. alignTrailingComments(StartOfSequence, i, MinColumn);
  901. MinColumn = ChangeMinColumn;
  902. MaxColumn = ChangeMinColumn;
  903. StartOfSequence = i;
  904. } else if (BreakBeforeNext || Newlines > NewLineThreshold ||
  905. (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) ||
  906. // Break the comment sequence if the previous line did not end
  907. // in a trailing comment.
  908. (Changes[i].NewlinesBefore == 1 && i > 0 &&
  909. !Changes[i - 1].IsTrailingComment) ||
  910. WasAlignedWithStartOfNextLine) {
  911. alignTrailingComments(StartOfSequence, i, MinColumn);
  912. MinColumn = ChangeMinColumn;
  913. MaxColumn = ChangeMaxColumn;
  914. StartOfSequence = i;
  915. } else {
  916. MinColumn = std::max(MinColumn, ChangeMinColumn);
  917. MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
  918. }
  919. BreakBeforeNext = (i == 0) || (Changes[i].NewlinesBefore > 1) ||
  920. // Never start a sequence with a comment at the beginning
  921. // of the line.
  922. (Changes[i].NewlinesBefore == 1 && StartOfSequence == i);
  923. Newlines = 0;
  924. }
  925. alignTrailingComments(StartOfSequence, Changes.size(), MinColumn);
  926. }
  927. void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
  928. unsigned Column) {
  929. for (unsigned i = Start; i != End; ++i) {
  930. int Shift = 0;
  931. if (Changes[i].IsTrailingComment)
  932. Shift = Column - Changes[i].StartOfTokenColumn;
  933. if (Changes[i].StartOfBlockComment) {
  934. Shift = Changes[i].IndentationOffset +
  935. Changes[i].StartOfBlockComment->StartOfTokenColumn -
  936. Changes[i].StartOfTokenColumn;
  937. }
  938. if (Shift <= 0)
  939. continue;
  940. Changes[i].Spaces += Shift;
  941. if (i + 1 != Changes.size())
  942. Changes[i + 1].PreviousEndOfTokenColumn += Shift;
  943. Changes[i].StartOfTokenColumn += Shift;
  944. }
  945. }
  946. void WhitespaceManager::alignEscapedNewlines() {
  947. if (Style.AlignEscapedNewlines == FormatStyle::ENAS_DontAlign)
  948. return;
  949. bool AlignLeft = Style.AlignEscapedNewlines == FormatStyle::ENAS_Left;
  950. unsigned MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
  951. unsigned StartOfMacro = 0;
  952. for (unsigned i = 1, e = Changes.size(); i < e; ++i) {
  953. Change &C = Changes[i];
  954. if (C.NewlinesBefore > 0) {
  955. if (C.ContinuesPPDirective) {
  956. MaxEndOfLine = std::max(C.PreviousEndOfTokenColumn + 2, MaxEndOfLine);
  957. } else {
  958. alignEscapedNewlines(StartOfMacro + 1, i, MaxEndOfLine);
  959. MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
  960. StartOfMacro = i;
  961. }
  962. }
  963. }
  964. alignEscapedNewlines(StartOfMacro + 1, Changes.size(), MaxEndOfLine);
  965. }
  966. void WhitespaceManager::alignEscapedNewlines(unsigned Start, unsigned End,
  967. unsigned Column) {
  968. for (unsigned i = Start; i < End; ++i) {
  969. Change &C = Changes[i];
  970. if (C.NewlinesBefore > 0) {
  971. assert(C.ContinuesPPDirective);
  972. if (C.PreviousEndOfTokenColumn + 1 > Column)
  973. C.EscapedNewlineColumn = 0;
  974. else
  975. C.EscapedNewlineColumn = Column;
  976. }
  977. }
  978. }
  979. void WhitespaceManager::alignArrayInitializers() {
  980. if (Style.AlignArrayOfStructures == FormatStyle::AIAS_None)
  981. return;
  982. for (unsigned ChangeIndex = 1U, ChangeEnd = Changes.size();
  983. ChangeIndex < ChangeEnd; ++ChangeIndex) {
  984. auto &C = Changes[ChangeIndex];
  985. if (C.Tok->IsArrayInitializer) {
  986. bool FoundComplete = false;
  987. for (unsigned InsideIndex = ChangeIndex + 1; InsideIndex < ChangeEnd;
  988. ++InsideIndex) {
  989. if (Changes[InsideIndex].Tok == C.Tok->MatchingParen) {
  990. alignArrayInitializers(ChangeIndex, InsideIndex + 1);
  991. ChangeIndex = InsideIndex + 1;
  992. FoundComplete = true;
  993. break;
  994. }
  995. }
  996. if (!FoundComplete)
  997. ChangeIndex = ChangeEnd;
  998. }
  999. }
  1000. }
  1001. void WhitespaceManager::alignArrayInitializers(unsigned Start, unsigned End) {
  1002. if (Style.AlignArrayOfStructures == FormatStyle::AIAS_Right)
  1003. alignArrayInitializersRightJustified(getCells(Start, End));
  1004. else if (Style.AlignArrayOfStructures == FormatStyle::AIAS_Left)
  1005. alignArrayInitializersLeftJustified(getCells(Start, End));
  1006. }
  1007. void WhitespaceManager::alignArrayInitializersRightJustified(
  1008. CellDescriptions &&CellDescs) {
  1009. if (!CellDescs.isRectangular())
  1010. return;
  1011. auto &Cells = CellDescs.Cells;
  1012. // Now go through and fixup the spaces.
  1013. auto *CellIter = Cells.begin();
  1014. for (auto i = 0U; i < CellDescs.CellCounts[0]; ++i, ++CellIter) {
  1015. unsigned NetWidth = 0U;
  1016. if (isSplitCell(*CellIter))
  1017. NetWidth = getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
  1018. auto CellWidth = getMaximumCellWidth(CellIter, NetWidth);
  1019. if (Changes[CellIter->Index].Tok->is(tok::r_brace)) {
  1020. // So in here we want to see if there is a brace that falls
  1021. // on a line that was split. If so on that line we make sure that
  1022. // the spaces in front of the brace are enough.
  1023. const auto *Next = CellIter;
  1024. do {
  1025. const FormatToken *Previous = Changes[Next->Index].Tok->Previous;
  1026. if (Previous && Previous->isNot(TT_LineComment)) {
  1027. Changes[Next->Index].Spaces = 0;
  1028. Changes[Next->Index].NewlinesBefore = 0;
  1029. }
  1030. Next = Next->NextColumnElement;
  1031. } while (Next);
  1032. // Unless the array is empty, we need the position of all the
  1033. // immediately adjacent cells
  1034. if (CellIter != Cells.begin()) {
  1035. auto ThisNetWidth =
  1036. getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
  1037. auto MaxNetWidth = getMaximumNetWidth(
  1038. Cells.begin(), CellIter, CellDescs.InitialSpaces,
  1039. CellDescs.CellCounts[0], CellDescs.CellCounts.size());
  1040. if (ThisNetWidth < MaxNetWidth)
  1041. Changes[CellIter->Index].Spaces = (MaxNetWidth - ThisNetWidth);
  1042. auto RowCount = 1U;
  1043. auto Offset = std::distance(Cells.begin(), CellIter);
  1044. for (const auto *Next = CellIter->NextColumnElement; Next != nullptr;
  1045. Next = Next->NextColumnElement) {
  1046. auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
  1047. auto *End = Start + Offset;
  1048. ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
  1049. if (ThisNetWidth < MaxNetWidth)
  1050. Changes[Next->Index].Spaces = (MaxNetWidth - ThisNetWidth);
  1051. ++RowCount;
  1052. }
  1053. }
  1054. } else {
  1055. auto ThisWidth =
  1056. calculateCellWidth(CellIter->Index, CellIter->EndIndex, true) +
  1057. NetWidth;
  1058. if (Changes[CellIter->Index].NewlinesBefore == 0) {
  1059. Changes[CellIter->Index].Spaces = (CellWidth - (ThisWidth + NetWidth));
  1060. Changes[CellIter->Index].Spaces += (i > 0) ? 1 : 0;
  1061. }
  1062. alignToStartOfCell(CellIter->Index, CellIter->EndIndex);
  1063. for (const auto *Next = CellIter->NextColumnElement; Next != nullptr;
  1064. Next = Next->NextColumnElement) {
  1065. ThisWidth =
  1066. calculateCellWidth(Next->Index, Next->EndIndex, true) + NetWidth;
  1067. if (Changes[Next->Index].NewlinesBefore == 0) {
  1068. Changes[Next->Index].Spaces = (CellWidth - ThisWidth);
  1069. Changes[Next->Index].Spaces += (i > 0) ? 1 : 0;
  1070. }
  1071. alignToStartOfCell(Next->Index, Next->EndIndex);
  1072. }
  1073. }
  1074. }
  1075. }
  1076. void WhitespaceManager::alignArrayInitializersLeftJustified(
  1077. CellDescriptions &&CellDescs) {
  1078. if (!CellDescs.isRectangular())
  1079. return;
  1080. auto &Cells = CellDescs.Cells;
  1081. // Now go through and fixup the spaces.
  1082. auto *CellIter = Cells.begin();
  1083. // The first cell needs to be against the left brace.
  1084. if (Changes[CellIter->Index].NewlinesBefore == 0)
  1085. Changes[CellIter->Index].Spaces = 0;
  1086. else
  1087. Changes[CellIter->Index].Spaces = CellDescs.InitialSpaces;
  1088. ++CellIter;
  1089. for (auto i = 1U; i < CellDescs.CellCounts[0]; i++, ++CellIter) {
  1090. auto MaxNetWidth = getMaximumNetWidth(
  1091. Cells.begin(), CellIter, CellDescs.InitialSpaces,
  1092. CellDescs.CellCounts[0], CellDescs.CellCounts.size());
  1093. auto ThisNetWidth =
  1094. getNetWidth(Cells.begin(), CellIter, CellDescs.InitialSpaces);
  1095. if (Changes[CellIter->Index].NewlinesBefore == 0) {
  1096. Changes[CellIter->Index].Spaces =
  1097. MaxNetWidth - ThisNetWidth +
  1098. (Changes[CellIter->Index].Tok->isNot(tok::r_brace) ? 1 : 0);
  1099. }
  1100. auto RowCount = 1U;
  1101. auto Offset = std::distance(Cells.begin(), CellIter);
  1102. for (const auto *Next = CellIter->NextColumnElement; Next != nullptr;
  1103. Next = Next->NextColumnElement) {
  1104. if (RowCount > CellDescs.CellCounts.size())
  1105. break;
  1106. auto *Start = (Cells.begin() + RowCount * CellDescs.CellCounts[0]);
  1107. auto *End = Start + Offset;
  1108. auto ThisNetWidth = getNetWidth(Start, End, CellDescs.InitialSpaces);
  1109. if (Changes[Next->Index].NewlinesBefore == 0) {
  1110. Changes[Next->Index].Spaces =
  1111. MaxNetWidth - ThisNetWidth +
  1112. (Changes[Next->Index].Tok->isNot(tok::r_brace) ? 1 : 0);
  1113. }
  1114. ++RowCount;
  1115. }
  1116. }
  1117. }
  1118. bool WhitespaceManager::isSplitCell(const CellDescription &Cell) {
  1119. if (Cell.HasSplit)
  1120. return true;
  1121. for (const auto *Next = Cell.NextColumnElement; Next != nullptr;
  1122. Next = Next->NextColumnElement) {
  1123. if (Next->HasSplit)
  1124. return true;
  1125. }
  1126. return false;
  1127. }
  1128. WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
  1129. unsigned End) {
  1130. unsigned Depth = 0;
  1131. unsigned Cell = 0;
  1132. SmallVector<unsigned> CellCounts;
  1133. unsigned InitialSpaces = 0;
  1134. unsigned InitialTokenLength = 0;
  1135. unsigned EndSpaces = 0;
  1136. SmallVector<CellDescription> Cells;
  1137. const FormatToken *MatchingParen = nullptr;
  1138. for (unsigned i = Start; i < End; ++i) {
  1139. auto &C = Changes[i];
  1140. if (C.Tok->is(tok::l_brace))
  1141. ++Depth;
  1142. else if (C.Tok->is(tok::r_brace))
  1143. --Depth;
  1144. if (Depth == 2) {
  1145. if (C.Tok->is(tok::l_brace)) {
  1146. Cell = 0;
  1147. MatchingParen = C.Tok->MatchingParen;
  1148. if (InitialSpaces == 0) {
  1149. InitialSpaces = C.Spaces + C.TokenLength;
  1150. InitialTokenLength = C.TokenLength;
  1151. auto j = i - 1;
  1152. for (; Changes[j].NewlinesBefore == 0 && j > Start; --j) {
  1153. InitialSpaces += Changes[j].Spaces + Changes[j].TokenLength;
  1154. InitialTokenLength += Changes[j].TokenLength;
  1155. }
  1156. if (C.NewlinesBefore == 0) {
  1157. InitialSpaces += Changes[j].Spaces + Changes[j].TokenLength;
  1158. InitialTokenLength += Changes[j].TokenLength;
  1159. }
  1160. }
  1161. } else if (C.Tok->is(tok::comma)) {
  1162. if (!Cells.empty())
  1163. Cells.back().EndIndex = i;
  1164. if (C.Tok->getNextNonComment()->isNot(tok::r_brace)) // dangling comma
  1165. ++Cell;
  1166. }
  1167. } else if (Depth == 1) {
  1168. if (C.Tok == MatchingParen) {
  1169. if (!Cells.empty())
  1170. Cells.back().EndIndex = i;
  1171. Cells.push_back(CellDescription{i, ++Cell, i + 1, false, nullptr});
  1172. CellCounts.push_back(C.Tok->Previous->isNot(tok::comma) ? Cell + 1
  1173. : Cell);
  1174. // Go to the next non-comment and ensure there is a break in front
  1175. const auto *NextNonComment = C.Tok->getNextNonComment();
  1176. while (NextNonComment->is(tok::comma))
  1177. NextNonComment = NextNonComment->getNextNonComment();
  1178. auto j = i;
  1179. while (Changes[j].Tok != NextNonComment && j < End)
  1180. ++j;
  1181. if (j < End && Changes[j].NewlinesBefore == 0 &&
  1182. Changes[j].Tok->isNot(tok::r_brace)) {
  1183. Changes[j].NewlinesBefore = 1;
  1184. // Account for the added token lengths
  1185. Changes[j].Spaces = InitialSpaces - InitialTokenLength;
  1186. }
  1187. } else if (C.Tok->is(tok::comment)) {
  1188. // Trailing comments stay at a space past the last token
  1189. C.Spaces = Changes[i - 1].Tok->is(tok::comma) ? 1 : 2;
  1190. } else if (C.Tok->is(tok::l_brace)) {
  1191. // We need to make sure that the ending braces is aligned to the
  1192. // start of our initializer
  1193. auto j = i - 1;
  1194. for (; j > 0 && !Changes[j].Tok->ArrayInitializerLineStart; --j)
  1195. ; // Nothing the loop does the work
  1196. EndSpaces = Changes[j].Spaces;
  1197. }
  1198. } else if (Depth == 0 && C.Tok->is(tok::r_brace)) {
  1199. C.NewlinesBefore = 1;
  1200. C.Spaces = EndSpaces;
  1201. }
  1202. if (C.Tok->StartsColumn) {
  1203. // This gets us past tokens that have been split over multiple
  1204. // lines
  1205. bool HasSplit = false;
  1206. if (Changes[i].NewlinesBefore > 0) {
  1207. // So if we split a line previously and the tail line + this token is
  1208. // less then the column limit we remove the split here and just put
  1209. // the column start at a space past the comma
  1210. //
  1211. // FIXME This if branch covers the cases where the column is not
  1212. // the first column. This leads to weird pathologies like the formatting
  1213. // auto foo = Items{
  1214. // Section{
  1215. // 0, bar(),
  1216. // }
  1217. // };
  1218. // Well if it doesn't lead to that it's indicative that the line
  1219. // breaking should be revisited. Unfortunately alot of other options
  1220. // interact with this
  1221. auto j = i - 1;
  1222. if ((j - 1) > Start && Changes[j].Tok->is(tok::comma) &&
  1223. Changes[j - 1].NewlinesBefore > 0) {
  1224. --j;
  1225. auto LineLimit = Changes[j].Spaces + Changes[j].TokenLength;
  1226. if (LineLimit < Style.ColumnLimit) {
  1227. Changes[i].NewlinesBefore = 0;
  1228. Changes[i].Spaces = 1;
  1229. }
  1230. }
  1231. }
  1232. while (Changes[i].NewlinesBefore > 0 && Changes[i].Tok == C.Tok) {
  1233. Changes[i].Spaces = InitialSpaces;
  1234. ++i;
  1235. HasSplit = true;
  1236. }
  1237. if (Changes[i].Tok != C.Tok)
  1238. --i;
  1239. Cells.push_back(CellDescription{i, Cell, i, HasSplit, nullptr});
  1240. }
  1241. }
  1242. return linkCells({Cells, CellCounts, InitialSpaces});
  1243. }
  1244. unsigned WhitespaceManager::calculateCellWidth(unsigned Start, unsigned End,
  1245. bool WithSpaces) const {
  1246. unsigned CellWidth = 0;
  1247. for (auto i = Start; i < End; i++) {
  1248. if (Changes[i].NewlinesBefore > 0)
  1249. CellWidth = 0;
  1250. CellWidth += Changes[i].TokenLength;
  1251. CellWidth += (WithSpaces ? Changes[i].Spaces : 0);
  1252. }
  1253. return CellWidth;
  1254. }
  1255. void WhitespaceManager::alignToStartOfCell(unsigned Start, unsigned End) {
  1256. if ((End - Start) <= 1)
  1257. return;
  1258. // If the line is broken anywhere in there make sure everything
  1259. // is aligned to the parent
  1260. for (auto i = Start + 1; i < End; i++)
  1261. if (Changes[i].NewlinesBefore > 0)
  1262. Changes[i].Spaces = Changes[Start].Spaces;
  1263. }
  1264. WhitespaceManager::CellDescriptions
  1265. WhitespaceManager::linkCells(CellDescriptions &&CellDesc) {
  1266. auto &Cells = CellDesc.Cells;
  1267. for (auto *CellIter = Cells.begin(); CellIter != Cells.end(); ++CellIter) {
  1268. if (CellIter->NextColumnElement == nullptr &&
  1269. ((CellIter + 1) != Cells.end())) {
  1270. for (auto *NextIter = CellIter + 1; NextIter != Cells.end(); ++NextIter) {
  1271. if (NextIter->Cell == CellIter->Cell) {
  1272. CellIter->NextColumnElement = &(*NextIter);
  1273. break;
  1274. }
  1275. }
  1276. }
  1277. }
  1278. return std::move(CellDesc);
  1279. }
  1280. void WhitespaceManager::generateChanges() {
  1281. for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
  1282. const Change &C = Changes[i];
  1283. if (i > 0 && Changes[i - 1].OriginalWhitespaceRange.getBegin() ==
  1284. C.OriginalWhitespaceRange.getBegin()) {
  1285. // Do not generate two replacements for the same location.
  1286. continue;
  1287. }
  1288. if (C.CreateReplacement) {
  1289. std::string ReplacementText = C.PreviousLinePostfix;
  1290. if (C.ContinuesPPDirective) {
  1291. appendEscapedNewlineText(ReplacementText, C.NewlinesBefore,
  1292. C.PreviousEndOfTokenColumn,
  1293. C.EscapedNewlineColumn);
  1294. } else {
  1295. appendNewlineText(ReplacementText, C.NewlinesBefore);
  1296. }
  1297. // FIXME: This assert should hold if we computed the column correctly.
  1298. // assert((int)C.StartOfTokenColumn >= C.Spaces);
  1299. appendIndentText(
  1300. ReplacementText, C.Tok->IndentLevel, std::max(0, C.Spaces),
  1301. std::max((int)C.StartOfTokenColumn, C.Spaces) - std::max(0, C.Spaces),
  1302. C.IsAligned);
  1303. ReplacementText.append(C.CurrentLinePrefix);
  1304. storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
  1305. }
  1306. }
  1307. }
  1308. void WhitespaceManager::storeReplacement(SourceRange Range, StringRef Text) {
  1309. unsigned WhitespaceLength = SourceMgr.getFileOffset(Range.getEnd()) -
  1310. SourceMgr.getFileOffset(Range.getBegin());
  1311. // Don't create a replacement, if it does not change anything.
  1312. if (StringRef(SourceMgr.getCharacterData(Range.getBegin()),
  1313. WhitespaceLength) == Text) {
  1314. return;
  1315. }
  1316. auto Err = Replaces.add(tooling::Replacement(
  1317. SourceMgr, CharSourceRange::getCharRange(Range), Text));
  1318. // FIXME: better error handling. For now, just print an error message in the
  1319. // release version.
  1320. if (Err) {
  1321. llvm::errs() << llvm::toString(std::move(Err)) << "\n";
  1322. assert(false);
  1323. }
  1324. }
  1325. void WhitespaceManager::appendNewlineText(std::string &Text,
  1326. unsigned Newlines) {
  1327. if (UseCRLF) {
  1328. Text.reserve(Text.size() + 2 * Newlines);
  1329. for (unsigned i = 0; i < Newlines; ++i)
  1330. Text.append("\r\n");
  1331. } else {
  1332. Text.append(Newlines, '\n');
  1333. }
  1334. }
  1335. void WhitespaceManager::appendEscapedNewlineText(
  1336. std::string &Text, unsigned Newlines, unsigned PreviousEndOfTokenColumn,
  1337. unsigned EscapedNewlineColumn) {
  1338. if (Newlines > 0) {
  1339. unsigned Spaces =
  1340. std::max<int>(1, EscapedNewlineColumn - PreviousEndOfTokenColumn - 1);
  1341. for (unsigned i = 0; i < Newlines; ++i) {
  1342. Text.append(Spaces, ' ');
  1343. Text.append(UseCRLF ? "\\\r\n" : "\\\n");
  1344. Spaces = std::max<int>(0, EscapedNewlineColumn - 1);
  1345. }
  1346. }
  1347. }
  1348. void WhitespaceManager::appendIndentText(std::string &Text,
  1349. unsigned IndentLevel, unsigned Spaces,
  1350. unsigned WhitespaceStartColumn,
  1351. bool IsAligned) {
  1352. switch (Style.UseTab) {
  1353. case FormatStyle::UT_Never:
  1354. Text.append(Spaces, ' ');
  1355. break;
  1356. case FormatStyle::UT_Always: {
  1357. if (Style.TabWidth) {
  1358. unsigned FirstTabWidth =
  1359. Style.TabWidth - WhitespaceStartColumn % Style.TabWidth;
  1360. // Insert only spaces when we want to end up before the next tab.
  1361. if (Spaces < FirstTabWidth || Spaces == 1) {
  1362. Text.append(Spaces, ' ');
  1363. break;
  1364. }
  1365. // Align to the next tab.
  1366. Spaces -= FirstTabWidth;
  1367. Text.append("\t");
  1368. Text.append(Spaces / Style.TabWidth, '\t');
  1369. Text.append(Spaces % Style.TabWidth, ' ');
  1370. } else if (Spaces == 1) {
  1371. Text.append(Spaces, ' ');
  1372. }
  1373. break;
  1374. }
  1375. case FormatStyle::UT_ForIndentation:
  1376. if (WhitespaceStartColumn == 0) {
  1377. unsigned Indentation = IndentLevel * Style.IndentWidth;
  1378. Spaces = appendTabIndent(Text, Spaces, Indentation);
  1379. }
  1380. Text.append(Spaces, ' ');
  1381. break;
  1382. case FormatStyle::UT_ForContinuationAndIndentation:
  1383. if (WhitespaceStartColumn == 0)
  1384. Spaces = appendTabIndent(Text, Spaces, Spaces);
  1385. Text.append(Spaces, ' ');
  1386. break;
  1387. case FormatStyle::UT_AlignWithSpaces:
  1388. if (WhitespaceStartColumn == 0) {
  1389. unsigned Indentation =
  1390. IsAligned ? IndentLevel * Style.IndentWidth : Spaces;
  1391. Spaces = appendTabIndent(Text, Spaces, Indentation);
  1392. }
  1393. Text.append(Spaces, ' ');
  1394. break;
  1395. }
  1396. }
  1397. unsigned WhitespaceManager::appendTabIndent(std::string &Text, unsigned Spaces,
  1398. unsigned Indentation) {
  1399. // This happens, e.g. when a line in a block comment is indented less than the
  1400. // first one.
  1401. if (Indentation > Spaces)
  1402. Indentation = Spaces;
  1403. if (Style.TabWidth) {
  1404. unsigned Tabs = Indentation / Style.TabWidth;
  1405. Text.append(Tabs, '\t');
  1406. Spaces -= Tabs * Style.TabWidth;
  1407. }
  1408. return Spaces;
  1409. }
  1410. } // namespace format
  1411. } // namespace clang