34 #include "llvm/ADT/STLExtras.h" 35 #include "llvm/ADT/StringRef.h" 36 #include "llvm/Support/Allocator.h" 37 #include "llvm/Support/Debug.h" 38 #include "llvm/Support/Path.h" 39 #include "llvm/Support/Regex.h" 40 #include "llvm/Support/VirtualFileSystem.h" 41 #include "llvm/Support/YAMLTraits.h" 46 #include <unordered_map> 48 #define DEBUG_TYPE "format-formatter" 56 template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageKind> {
58 IO.enumCase(Value,
"Cpp", FormatStyle::LK_Cpp);
59 IO.enumCase(Value,
"Java", FormatStyle::LK_Java);
60 IO.enumCase(Value,
"JavaScript", FormatStyle::LK_JavaScript);
61 IO.enumCase(Value,
"ObjC", FormatStyle::LK_ObjC);
62 IO.enumCase(Value,
"Proto", FormatStyle::LK_Proto);
63 IO.enumCase(Value,
"TableGen", FormatStyle::LK_TableGen);
64 IO.enumCase(Value,
"TextProto", FormatStyle::LK_TextProto);
68 template <>
struct ScalarEnumerationTraits<
FormatStyle::LanguageStandard> {
70 IO.enumCase(Value,
"Cpp03", FormatStyle::LS_Cpp03);
71 IO.enumCase(Value,
"C++03", FormatStyle::LS_Cpp03);
72 IO.enumCase(Value,
"Cpp11", FormatStyle::LS_Cpp11);
73 IO.enumCase(Value,
"C++11", FormatStyle::LS_Cpp11);
74 IO.enumCase(Value,
"Auto", FormatStyle::LS_Auto);
78 template <>
struct ScalarEnumerationTraits<
FormatStyle::UseTabStyle> {
80 IO.enumCase(Value,
"Never", FormatStyle::UT_Never);
81 IO.enumCase(Value,
"false", FormatStyle::UT_Never);
82 IO.enumCase(Value,
"Always", FormatStyle::UT_Always);
83 IO.enumCase(Value,
"true", FormatStyle::UT_Always);
84 IO.enumCase(Value,
"ForIndentation", FormatStyle::UT_ForIndentation);
85 IO.enumCase(Value,
"ForContinuationAndIndentation",
86 FormatStyle::UT_ForContinuationAndIndentation);
90 template <>
struct ScalarEnumerationTraits<
FormatStyle::JavaScriptQuoteStyle> {
92 IO.enumCase(Value,
"Leave", FormatStyle::JSQS_Leave);
93 IO.enumCase(Value,
"Single", FormatStyle::JSQS_Single);
94 IO.enumCase(Value,
"Double", FormatStyle::JSQS_Double);
98 template <>
struct ScalarEnumerationTraits<
FormatStyle::ShortFunctionStyle> {
100 IO.enumCase(Value,
"None", FormatStyle::SFS_None);
101 IO.enumCase(Value,
"false", FormatStyle::SFS_None);
102 IO.enumCase(Value,
"All", FormatStyle::SFS_All);
103 IO.enumCase(Value,
"true", FormatStyle::SFS_All);
104 IO.enumCase(Value,
"Inline", FormatStyle::SFS_Inline);
105 IO.enumCase(Value,
"InlineOnly", FormatStyle::SFS_InlineOnly);
106 IO.enumCase(Value,
"Empty", FormatStyle::SFS_Empty);
110 template <>
struct ScalarEnumerationTraits<
FormatStyle::BinPackStyle> {
112 IO.enumCase(Value,
"Auto", FormatStyle::BPS_Auto);
113 IO.enumCase(Value,
"Always", FormatStyle::BPS_Always);
114 IO.enumCase(Value,
"Never", FormatStyle::BPS_Never);
118 template <>
struct ScalarEnumerationTraits<
FormatStyle::BinaryOperatorStyle> {
120 IO.enumCase(Value,
"All", FormatStyle::BOS_All);
121 IO.enumCase(Value,
"true", FormatStyle::BOS_All);
122 IO.enumCase(Value,
"None", FormatStyle::BOS_None);
123 IO.enumCase(Value,
"false", FormatStyle::BOS_None);
124 IO.enumCase(Value,
"NonAssignment", FormatStyle::BOS_NonAssignment);
128 template <>
struct ScalarEnumerationTraits<
FormatStyle::BraceBreakingStyle> {
130 IO.enumCase(Value,
"Attach", FormatStyle::BS_Attach);
131 IO.enumCase(Value,
"Linux", FormatStyle::BS_Linux);
132 IO.enumCase(Value,
"Mozilla", FormatStyle::BS_Mozilla);
133 IO.enumCase(Value,
"Stroustrup", FormatStyle::BS_Stroustrup);
134 IO.enumCase(Value,
"Allman", FormatStyle::BS_Allman);
135 IO.enumCase(Value,
"GNU", FormatStyle::BS_GNU);
136 IO.enumCase(Value,
"WebKit", FormatStyle::BS_WebKit);
137 IO.enumCase(Value,
"Custom", FormatStyle::BS_Custom);
142 struct ScalarEnumerationTraits<
FormatStyle::BreakConstructorInitializersStyle> {
145 IO.enumCase(Value,
"BeforeColon", FormatStyle::BCIS_BeforeColon);
146 IO.enumCase(Value,
"BeforeComma", FormatStyle::BCIS_BeforeComma);
147 IO.enumCase(Value,
"AfterColon", FormatStyle::BCIS_AfterColon);
152 struct ScalarEnumerationTraits<
FormatStyle::BreakInheritanceListStyle> {
155 IO.enumCase(Value,
"BeforeColon", FormatStyle::BILS_BeforeColon);
156 IO.enumCase(Value,
"BeforeComma", FormatStyle::BILS_BeforeComma);
157 IO.enumCase(Value,
"AfterColon", FormatStyle::BILS_AfterColon);
162 struct ScalarEnumerationTraits<
FormatStyle::PPDirectiveIndentStyle> {
164 IO.enumCase(Value,
"None", FormatStyle::PPDIS_None);
165 IO.enumCase(Value,
"AfterHash", FormatStyle::PPDIS_AfterHash);
170 struct ScalarEnumerationTraits<
FormatStyle::ReturnTypeBreakingStyle> {
172 IO.enumCase(Value,
"None", FormatStyle::RTBS_None);
173 IO.enumCase(Value,
"All", FormatStyle::RTBS_All);
174 IO.enumCase(Value,
"TopLevel", FormatStyle::RTBS_TopLevel);
175 IO.enumCase(Value,
"TopLevelDefinitions",
176 FormatStyle::RTBS_TopLevelDefinitions);
177 IO.enumCase(Value,
"AllDefinitions", FormatStyle::RTBS_AllDefinitions);
182 struct ScalarEnumerationTraits<
FormatStyle::BreakTemplateDeclarationsStyle> {
184 IO.enumCase(Value,
"No", FormatStyle::BTDS_No);
185 IO.enumCase(Value,
"MultiLine", FormatStyle::BTDS_MultiLine);
186 IO.enumCase(Value,
"Yes", FormatStyle::BTDS_Yes);
189 IO.enumCase(Value,
"false", FormatStyle::BTDS_MultiLine);
190 IO.enumCase(Value,
"true", FormatStyle::BTDS_Yes);
195 struct ScalarEnumerationTraits<
FormatStyle::DefinitionReturnTypeBreakingStyle> {
198 IO.enumCase(Value,
"None", FormatStyle::DRTBS_None);
199 IO.enumCase(Value,
"All", FormatStyle::DRTBS_All);
200 IO.enumCase(Value,
"TopLevel", FormatStyle::DRTBS_TopLevel);
203 IO.enumCase(Value,
"false", FormatStyle::DRTBS_None);
204 IO.enumCase(Value,
"true", FormatStyle::DRTBS_All);
209 struct ScalarEnumerationTraits<
FormatStyle::NamespaceIndentationKind> {
211 FormatStyle::NamespaceIndentationKind &
Value) {
212 IO.enumCase(Value,
"None", FormatStyle::NI_None);
213 IO.enumCase(Value,
"Inner", FormatStyle::NI_Inner);
214 IO.enumCase(Value,
"All", FormatStyle::NI_All);
218 template <>
struct ScalarEnumerationTraits<
FormatStyle::BracketAlignmentStyle> {
220 IO.enumCase(Value,
"Align", FormatStyle::BAS_Align);
221 IO.enumCase(Value,
"DontAlign", FormatStyle::BAS_DontAlign);
222 IO.enumCase(Value,
"AlwaysBreak", FormatStyle::BAS_AlwaysBreak);
225 IO.enumCase(Value,
"true", FormatStyle::BAS_Align);
226 IO.enumCase(Value,
"false", FormatStyle::BAS_DontAlign);
231 struct ScalarEnumerationTraits<
FormatStyle::EscapedNewlineAlignmentStyle> {
233 FormatStyle::EscapedNewlineAlignmentStyle &
Value) {
234 IO.enumCase(Value,
"DontAlign", FormatStyle::ENAS_DontAlign);
235 IO.enumCase(Value,
"Left", FormatStyle::ENAS_Left);
236 IO.enumCase(Value,
"Right", FormatStyle::ENAS_Right);
239 IO.enumCase(Value,
"true", FormatStyle::ENAS_Left);
240 IO.enumCase(Value,
"false", FormatStyle::ENAS_Right);
244 template <>
struct ScalarEnumerationTraits<
FormatStyle::PointerAlignmentStyle> {
246 IO.enumCase(Value,
"Middle", FormatStyle::PAS_Middle);
247 IO.enumCase(Value,
"Left", FormatStyle::PAS_Left);
248 IO.enumCase(Value,
"Right", FormatStyle::PAS_Right);
251 IO.enumCase(Value,
"true", FormatStyle::PAS_Left);
252 IO.enumCase(Value,
"false", FormatStyle::PAS_Right);
257 struct ScalarEnumerationTraits<
FormatStyle::SpaceBeforeParensOptions> {
259 FormatStyle::SpaceBeforeParensOptions &
Value) {
260 IO.enumCase(Value,
"Never", FormatStyle::SBPO_Never);
261 IO.enumCase(Value,
"ControlStatements",
262 FormatStyle::SBPO_ControlStatements);
263 IO.enumCase(Value,
"Always", FormatStyle::SBPO_Always);
266 IO.enumCase(Value,
"false", FormatStyle::SBPO_Never);
267 IO.enumCase(Value,
"true", FormatStyle::SBPO_ControlStatements);
274 IO.mapOptional(
"Language", Style.
Language);
276 if (IO.outputting()) {
277 StringRef StylesArray[] = {
"LLVM",
"Google",
"Chromium",
278 "Mozilla",
"WebKit",
"GNU"};
280 for (
size_t i = 0, e = Styles.size(); i < e; ++i) {
281 StringRef StyleName(Styles[i]);
284 Style == PredefinedStyle) {
285 IO.mapOptional(
"# BasedOnStyle", StyleName);
290 StringRef BasedOnStyle;
291 IO.mapOptional(
"BasedOnStyle", BasedOnStyle);
292 if (!BasedOnStyle.empty()) {
293 FormatStyle::LanguageKind OldLanguage = Style.
Language;
294 FormatStyle::LanguageKind Language =
297 IO.setError(Twine(
"Unknown value for BasedOnStyle: ", BasedOnStyle));
305 if (!IO.outputting()) {
308 IO.mapOptional(
"IndentFunctionDeclarationAfterType",
311 IO.mapOptional(
"SpaceAfterControlStatementKeyword",
317 IO.mapOptional(
"AlignConsecutiveAssignments",
319 IO.mapOptional(
"AlignConsecutiveDeclarations",
324 IO.mapOptional(
"AllowAllParametersOfDeclarationOnNextLine",
326 IO.mapOptional(
"AllowShortBlocksOnASingleLine",
328 IO.mapOptional(
"AllowShortCaseLabelsOnASingleLine",
330 IO.mapOptional(
"AllowShortFunctionsOnASingleLine",
332 IO.mapOptional(
"AllowShortIfStatementsOnASingleLine",
334 IO.mapOptional(
"AllowShortLoopsOnASingleLine",
336 IO.mapOptional(
"AlwaysBreakAfterDefinitionReturnType",
338 IO.mapOptional(
"AlwaysBreakAfterReturnType",
348 FormatStyle::DRTBS_TopLevel)
350 FormatStyle::RTBS_TopLevelDefinitions;
353 IO.mapOptional(
"AlwaysBreakBeforeMultilineStrings",
355 IO.mapOptional(
"AlwaysBreakTemplateDeclarations",
360 IO.mapOptional(
"BreakBeforeBinaryOperators",
364 bool BreakBeforeInheritanceComma =
false;
365 IO.mapOptional(
"BreakBeforeInheritanceComma",
366 BreakBeforeInheritanceComma);
367 IO.mapOptional(
"BreakInheritanceList",
372 if (BreakBeforeInheritanceComma &&
376 IO.mapOptional(
"BreakBeforeTernaryOperators",
379 bool BreakConstructorInitializersBeforeComma =
false;
380 IO.mapOptional(
"BreakConstructorInitializersBeforeComma",
381 BreakConstructorInitializersBeforeComma);
382 IO.mapOptional(
"BreakConstructorInitializers",
387 if (BreakConstructorInitializersBeforeComma &&
391 IO.mapOptional(
"BreakAfterJavaFieldAnnotations",
397 IO.mapOptional(
"ConstructorInitializerAllOnOneLineOrOnePerLine",
399 IO.mapOptional(
"ConstructorInitializerIndentWidth",
405 IO.mapOptional(
"ExperimentalAutoDetectBinPacking",
415 IO.mapOptional(
"IndentWrappedFunctionNames",
420 IO.mapOptional(
"KeepEmptyLinesAtTheStartOfBlocks",
429 IO.mapOptional(
"ObjCSpaceBeforeProtocolList",
432 IO.mapOptional(
"PenaltyBreakBeforeFirstCallParameter",
435 IO.mapOptional(
"PenaltyBreakFirstLessLess",
438 IO.mapOptional(
"PenaltyBreakTemplateDeclaration",
441 IO.mapOptional(
"PenaltyReturnTypeOnItsOwnLine",
449 IO.mapOptional(
"SpaceAfterTemplateKeyword",
451 IO.mapOptional(
"SpaceBeforeAssignmentOperators",
453 IO.mapOptional(
"SpaceBeforeCpp11BracedList",
455 IO.mapOptional(
"SpaceBeforeCtorInitializerColon",
457 IO.mapOptional(
"SpaceBeforeInheritanceColon",
460 IO.mapOptional(
"SpaceBeforeRangeBasedForLoopColon",
463 IO.mapOptional(
"SpacesBeforeTrailingComments",
466 IO.mapOptional(
"SpacesInContainerLiterals",
468 IO.mapOptional(
"SpacesInCStyleCastParentheses",
472 IO.mapOptional(
"Standard", Style.
Standard);
474 IO.mapOptional(
"TabWidth", Style.
TabWidth);
475 IO.mapOptional(
"UseTab", Style.
UseTab);
479 template <>
struct MappingTraits<
FormatStyle::BraceWrappingFlags> {
480 static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) {
481 IO.mapOptional(
"AfterClass", Wrapping.AfterClass);
482 IO.mapOptional(
"AfterControlStatement", Wrapping.AfterControlStatement);
483 IO.mapOptional(
"AfterEnum", Wrapping.AfterEnum);
484 IO.mapOptional(
"AfterFunction", Wrapping.AfterFunction);
485 IO.mapOptional(
"AfterNamespace", Wrapping.AfterNamespace);
486 IO.mapOptional(
"AfterObjCDeclaration", Wrapping.AfterObjCDeclaration);
487 IO.mapOptional(
"AfterStruct", Wrapping.AfterStruct);
488 IO.mapOptional(
"AfterUnion", Wrapping.AfterUnion);
489 IO.mapOptional(
"AfterExternBlock", Wrapping.AfterExternBlock);
490 IO.mapOptional(
"BeforeCatch", Wrapping.BeforeCatch);
491 IO.mapOptional(
"BeforeElse", Wrapping.BeforeElse);
492 IO.mapOptional(
"IndentBraces", Wrapping.IndentBraces);
493 IO.mapOptional(
"SplitEmptyFunction", Wrapping.SplitEmptyFunction);
494 IO.mapOptional(
"SplitEmptyRecord", Wrapping.SplitEmptyRecord);
495 IO.mapOptional(
"SplitEmptyNamespace", Wrapping.SplitEmptyNamespace);
500 static void mapping(IO &IO, FormatStyle::RawStringFormat &Format) {
501 IO.mapOptional(
"Language", Format.Language);
502 IO.mapOptional(
"Delimiters", Format.Delimiters);
503 IO.mapOptional(
"EnclosingFunctions", Format.EnclosingFunctions);
504 IO.mapOptional(
"CanonicalDelimiter", Format.CanonicalDelimiter);
505 IO.mapOptional(
"BasedOnStyle", Format.BasedOnStyle);
514 template <>
struct DocumentListTraits<
std::vector<FormatStyle>> {
515 static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
520 if (Index >= Seq.size()) {
521 assert(Index == Seq.size());
523 if (!Seq.empty() && Seq[0].Language == FormatStyle::LK_None) {
526 Template = *((
const FormatStyle *)IO.getContext());
527 Template.
Language = FormatStyle::LK_None;
529 Seq.resize(Index + 1, Template);
549 return llvm::make_error<llvm::StringError>(Message,
550 llvm::inconvertibleErrorCode());
553 const char *ParseErrorCategory::name() const noexcept {
554 return "clang-format.parse_error";
557 std::string ParseErrorCategory::message(
int EV)
const {
558 switch (static_cast<ParseError>(EV)) {
559 case ParseError::Success:
562 return "Invalid argument";
563 case ParseError::Unsuitable:
566 llvm_unreachable(
"unexpected parse error");
574 false,
false,
false,
false,
false,
575 false,
false,
true,
true,
true};
577 case FormatStyle::BS_Linux:
582 case FormatStyle::BS_Mozilla:
592 case FormatStyle::BS_Stroustrup:
597 case FormatStyle::BS_Allman:
609 case FormatStyle::BS_GNU:
610 Expanded.
BraceWrapping = {
true,
true,
true,
true,
true,
true,
true,
true,
611 true,
true,
true,
true,
true,
true,
true};
613 case FormatStyle::BS_WebKit:
624 LLVMStyle.
Language = FormatStyle::LK_Cpp;
647 LLVMStyle.
BraceWrapping = {
false,
false,
false,
false,
false,
648 false,
false,
false,
false,
false,
649 false,
false,
true,
true,
true};
668 {
"^\"(llvm|llvm-c|clang|clang-c)/", 2},
669 {
"^(<|\"(gtest|gmock|isl|json)/)", 3},
689 LLVMStyle.
Standard = FormatStyle::LS_Cpp11;
690 LLVMStyle.
UseTab = FormatStyle::UT_Never;
726 if (Language == FormatStyle::LK_TextProto) {
728 GoogleStyle.
Language = FormatStyle::LK_TextProto;
745 {
"^<ext/.*\\.h>", 2}, {
"^<.*\\.h>", 1}, {
"^<.*", 2}, {
".*", 3}};
772 FormatStyle::LK_TextProto,
784 "PARSE_PARTIAL_TEXT_PROTO",
788 "ParseTextProtoOrDie",
795 GoogleStyle.
Standard = FormatStyle::LS_Auto;
800 if (Language == FormatStyle::LK_Java) {
811 }
else if (Language == FormatStyle::LK_JavaScript) {
825 }
else if (Language == FormatStyle::LK_Proto) {
836 }
else if (Language == FormatStyle::LK_ObjC) {
846 if (Language == FormatStyle::LK_Java) {
859 "com.google.android.apps.chrome",
865 }
else if (Language == FormatStyle::LK_JavaScript) {
875 if (Language == FormatStyle::LK_ObjC)
878 return ChromiumStyle;
887 FormatStyle::DRTBS_TopLevel;
939 Style.
Standard = FormatStyle::LS_Cpp03;
953 if (Name.equals_lower(
"llvm")) {
955 }
else if (Name.equals_lower(
"chromium")) {
957 }
else if (Name.equals_lower(
"mozilla")) {
959 }
else if (Name.equals_lower(
"google")) {
961 }
else if (Name.equals_lower(
"webkit")) {
963 }
else if (Name.equals_lower(
"gnu")) {
965 }
else if (Name.equals_lower(
"none")) {
978 assert(Language != FormatStyle::LK_None);
979 if (Text.trim().empty())
981 Style->StyleSet.
Clear();
982 std::vector<FormatStyle> Styles;
983 llvm::yaml::Input Input(Text);
988 Input.setContext(Style);
991 return Input.error();
993 for (
unsigned i = 0; i < Styles.size(); ++i) {
995 if (Styles[i].Language == FormatStyle::LK_None && i != 0)
998 for (
unsigned j = 0; j < i; ++j) {
999 if (Styles[i].Language == Styles[j].Language) {
1000 LLVM_DEBUG(llvm::dbgs()
1001 <<
"Duplicate languages in the config file on positions " 1002 << j <<
" and " << i <<
"\n");
1011 bool LanguageFound =
false;
1012 for (
int i = Styles.size() - 1; i >= 0; --i) {
1013 if (Styles[i].Language != FormatStyle::LK_None)
1014 StyleSet.
Add(Styles[i]);
1015 if (Styles[i].Language == Language)
1016 LanguageFound =
true;
1018 if (!LanguageFound) {
1019 if (Styles.empty() || Styles[0].Language != FormatStyle::LK_None)
1023 StyleSet.
Add(std::move(DefaultStyle));
1025 *Style = *StyleSet.
Get(Language);
1031 llvm::raw_string_ostream Stream(Text);
1032 llvm::yaml::Output Output(Stream);
1036 Output << NonConstStyle;
1037 return Stream.str();
1044 auto It = Styles->find(Language);
1045 if (It == Styles->end())
1048 Style.StyleSet = *
this;
1053 assert(Style.
Language != LK_None &&
1054 "Cannot add a style for LK_None to a StyleSet");
1056 !Style.StyleSet.Styles &&
1057 "Cannot add a style associated with an existing StyleSet to a StyleSet");
1059 Styles = std::make_shared<MapType>();
1060 (*Styles)[Style.
Language] = std::move(Style);
1063 void FormatStyle::FormatStyleSet::Clear() {
1069 return StyleSet.Get(Language);
1079 std::pair<tooling::Replacements, unsigned>
1083 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1085 requoteJSStringLiteral(AnnotatedLines, Result);
1095 requoteJSStringLiteral(
Line->Children, Result);
1096 if (!
Line->Affected)
1099 FormatTok = FormatTok->Next) {
1100 StringRef Input = FormatTok->TokenText;
1101 if (FormatTok->Finalized || !FormatTok->isStringLiteral() ||
1105 !Input.startswith(
"\"")) ||
1107 !Input.startswith(
"\'")))
1114 StringRef ReplacementText) {
1124 Replace(Start, 1, IsSingle ?
"'" :
"\"");
1125 Replace(FormatTok->Tok.getEndLoc().getLocWithOffset(-1), 1,
1126 IsSingle ?
"'" :
"\"");
1129 bool Escaped =
false;
1130 for (
size_t i = 1; i < Input.size() - 1; i++) {
1133 if (!Escaped && i + 1 < Input.size() &&
1134 ((IsSingle && Input[i + 1] ==
'"') ||
1135 (!IsSingle && Input[i + 1] ==
'\''))) {
1145 if (!Escaped && IsSingle == (Input[i] ==
'\'')) {
1167 std::pair<tooling::Replacements, unsigned>
1172 deriveLocalStyle(AnnotatedLines);
1173 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1174 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1184 BinPackInconclusiveFunctions);
1189 .format(AnnotatedLines,
false,
1195 for (
const auto &R : Whitespaces.generateReplacements())
1197 return std::make_pair(Result, 0);
1198 return std::make_pair(Result, Penalty);
1202 static bool inputUsesCRLF(StringRef
Text) {
1203 return Text.count(
'\r') * 2 > Text.count(
'\n');
1209 if (hasCpp03IncompatibleFormat(
Line->Children))
1215 if (
Tok->
is(TT_TemplateCloser) &&
1225 int AlignmentDiff = 0;
1227 AlignmentDiff += countVariableAlignments(
Line->Children);
1229 if (!
Tok->
is(TT_PointerOrReference))
1235 if (SpaceBefore && !SpaceAfter)
1237 if (!SpaceBefore && SpaceAfter)
1241 return AlignmentDiff;
1246 bool HasBinPackedFunction =
false;
1247 bool HasOnePerLineFunction =
false;
1248 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1249 if (!AnnotatedLines[i]->
First->Next)
1254 HasBinPackedFunction =
true;
1256 HasOnePerLineFunction =
true;
1263 ? FormatStyle::PAS_Left
1264 : FormatStyle::PAS_Right;
1265 if (Style.
Standard == FormatStyle::LS_Auto)
1266 Style.
Standard = hasCpp03IncompatibleFormat(AnnotatedLines)
1267 ? FormatStyle::LS_Cpp11
1268 : FormatStyle::LS_Cpp03;
1269 BinPackInconclusiveFunctions =
1270 HasBinPackedFunction || !HasOnePerLineFunction;
1273 bool BinPackInconclusiveFunctions;
1286 std::pair<tooling::Replacements, unsigned>
1297 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
1299 checkEmptyNamespace(AnnotatedLines);
1301 for (
auto &
Line : AnnotatedLines) {
1302 if (
Line->Affected) {
1303 cleanupRight(
Line->First, tok::comma, tok::comma);
1304 cleanupRight(
Line->First, TT_CtorInitializerColon, tok::comma);
1305 cleanupRight(
Line->First, tok::l_paren, tok::comma);
1306 cleanupLeft(
Line->First, tok::comma, tok::r_paren);
1307 cleanupLeft(
Line->First, TT_CtorInitializerComma, tok::l_brace);
1308 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::l_brace);
1309 cleanupLeft(
Line->First, TT_CtorInitializerColon, tok::equal);
1313 return {generateFixes(), 0};
1327 std::set<unsigned> DeletedLines;
1328 for (
unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
1329 auto &Line = *AnnotatedLines[i];
1331 checkEmptyNamespace(AnnotatedLines, i, i, DeletedLines);
1335 for (
auto Line : DeletedLines) {
1349 unsigned CurrentLine,
unsigned &
NewLine,
1350 std::set<unsigned> &DeletedLines) {
1351 unsigned InitLine = CurrentLine,
End = AnnotatedLines.size();
1356 if (!AnnotatedLines[++CurrentLine]->startsWith(tok::l_brace)) {
1357 NewLine = CurrentLine;
1360 }
else if (!AnnotatedLines[CurrentLine]->endsWith(tok::l_brace)) {
1363 while (++CurrentLine < End) {
1364 if (AnnotatedLines[CurrentLine]->startsWith(tok::r_brace))
1367 if (AnnotatedLines[CurrentLine]->startsWithNamespace()) {
1368 if (!checkEmptyNamespace(AnnotatedLines, CurrentLine, NewLine,
1375 if (containsOnlyComments(*AnnotatedLines[CurrentLine]))
1380 NewLine = CurrentLine;
1384 NewLine = CurrentLine;
1385 if (CurrentLine >= End)
1389 if (!AffectedRangeMgr.affectsCharSourceRange(CharSourceRange::getCharRange(
1390 AnnotatedLines[InitLine]->First->Tok.getLocation(),
1391 AnnotatedLines[CurrentLine]->Last->Tok.getEndLoc())))
1394 for (
unsigned i = InitLine; i <= CurrentLine; ++i) {
1395 DeletedLines.insert(i);
1405 template <
typename LeftKind,
typename RightKind>
1406 void cleanupPair(
FormatToken *Start, LeftKind LK, RightKind RK,
1410 if (!Res->is(tok::comment) &&
1411 DeletedTokens.find(Res) == DeletedTokens.end())
1415 for (
auto *Left = Start; Left;) {
1416 auto *Right = NextNotDeleted(*Left);
1419 if (Left->is(LK) && Right->is(RK)) {
1420 deleteToken(DeleteLeft ? Left : Right);
1432 template <
typename LeftKind,
typename RightKind>
1433 void cleanupLeft(
FormatToken *Start, LeftKind LK, RightKind RK) {
1434 cleanupPair(Start, LK, RK,
true);
1437 template <
typename LeftKind,
typename RightKind>
1438 void cleanupRight(
FormatToken *Start, LeftKind LK, RightKind RK) {
1439 cleanupPair(Start, LK, RK,
false);
1445 DeletedTokens.insert(Tok);
1450 std::vector<FormatToken *> Tokens;
1451 std::copy(DeletedTokens.begin(), DeletedTokens.end(),
1452 std::back_inserter(Tokens));
1458 while (Idx < Tokens.size()) {
1459 unsigned St = Idx,
End = Idx;
1460 while ((End + 1) < Tokens.size() &&
1461 Tokens[
End]->Next == Tokens[End + 1]) {
1464 auto SR = CharSourceRange::getCharRange(Tokens[St]->Tok.getLocation(),
1472 assert(
false &&
"Fixes must not conflict!");
1483 struct FormatTokenLess {
1494 std::set<FormatToken *, FormatTokenLess> DeletedTokens;
1497 class ObjCHeaderStyleGuesser :
public TokenAnalyzer {
1500 : TokenAnalyzer(Env, Style), IsObjC(
false) {}
1502 std::pair<tooling::Replacements, unsigned>
1503 analyze(TokenAnnotator &Annotator,
1504 SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1505 FormatTokenLexer &Tokens)
override {
1506 assert(Style.
Language == FormatStyle::LK_Cpp);
1507 IsObjC = guessIsObjC(Env.getSourceManager(), AnnotatedLines,
1508 Tokens.getKeywords());
1509 tooling::Replacements Result;
1513 bool isObjC() {
return IsObjC; }
1517 guessIsObjC(
const SourceManager &SourceManager,
1518 const SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,
1519 const AdditionalKeywords &Keywords) {
1521 static constexpr llvm::StringLiteral FoundationIdentifiers[] = {
1536 "NSAffineTransform",
1538 "NSAttributedString",
1555 "NSInvocationOperation",
1559 "NSMutableAttributedString",
1560 "NSMutableCharacterSet",
1562 "NSMutableDictionary",
1563 "NSMutableIndexSet",
1564 "NSMutableOrderedSet",
1568 "NSNumberFormatter",
1572 "NSOperationQueuePriority",
1576 "NSQualityOfService",
1579 "NSRegularExpression",
1594 for (
auto Line : AnnotatedLines) {
1595 for (
const FormatToken *FormatTok =
Line->First; FormatTok;
1596 FormatTok = FormatTok->Next) {
1597 if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
1598 (FormatTok->Tok.getObjCKeywordID() != tok::objc_not_keyword ||
1599 FormatTok->isOneOf(tok::numeric_constant, tok::l_square,
1601 (FormatTok->Tok.isAnyIdentifier() &&
1602 std::binary_search(std::begin(FoundationIdentifiers),
1603 std::end(FoundationIdentifiers),
1604 FormatTok->TokenText)) ||
1605 FormatTok->is(TT_ObjCStringLiteral) ||
1606 FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS,
1607 TT_ObjCBlockLBrace, TT_ObjCBlockLParen,
1608 TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr,
1609 TT_ObjCMethodSpecifier, TT_ObjCProperty)) {
1610 LLVM_DEBUG(llvm::dbgs()
1611 <<
"Detected ObjC at location " 1612 << FormatTok->Tok.getLocation().printToString(
1614 <<
" token: " << FormatTok->TokenText <<
" token type: " 1618 if (guessIsObjC(SourceManager,
Line->Children, Keywords))
1628 struct IncludeDirective {
1635 struct JavaImportDirective {
1648 for (
auto Range : Ranges) {
1649 if (Range.getOffset() < End &&
1650 Range.getOffset() + Range.getLength() > Start)
1663 static std::pair<unsigned, unsigned>
1667 unsigned OffsetToEOL = 0;
1668 for (
int i = 0, e = Includes.size(); i != e; ++i) {
1669 unsigned Start = Includes[Indices[i]].Offset;
1670 unsigned End = Start + Includes[Indices[i]].Text.size();
1671 if (!(Cursor >= Start && Cursor < End))
1673 CursorIndex = Indices[i];
1674 OffsetToEOL = End -
Cursor;
1677 while (--i >= 0 && Includes[CursorIndex].
Text == Includes[Indices[i]].
Text)
1681 return std::make_pair(CursorIndex, OffsetToEOL);
1695 unsigned IncludesBeginOffset = Includes.front().Offset;
1696 unsigned IncludesEndOffset =
1697 Includes.back().Offset + Includes.back().Text.size();
1698 unsigned IncludesBlockSize = IncludesEndOffset - IncludesBeginOffset;
1699 if (!
affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
1702 for (
unsigned i = 0, e = Includes.size(); i != e; ++i)
1703 Indices.push_back(i);
1705 Indices.begin(), Indices.end(), [&](
unsigned LHSI,
unsigned RHSI) {
1707 std::tie(Includes[RHSI].Category, Includes[RHSI].Filename);
1711 unsigned CursorIndex;
1713 unsigned CursorToEOLOffset;
1715 std::tie(CursorIndex, CursorToEOLOffset) =
1719 Indices.erase(std::unique(Indices.begin(), Indices.end(),
1720 [&](
unsigned LHSI,
unsigned RHSI) {
1721 return Includes[LHSI].Text == Includes[RHSI].Text;
1725 int CurrentCategory = Includes.front().Category;
1729 if (Indices.size() == Includes.size() &&
1730 std::is_sorted(Indices.begin(), Indices.end()) &&
1735 for (
unsigned Index : Indices) {
1736 if (!result.empty()) {
1739 tooling::IncludeStyle::IBS_Regroup &&
1740 CurrentCategory != Includes[Index].Category)
1743 result += Includes[Index].Text;
1744 if (Cursor && CursorIndex == Index)
1745 *Cursor = IncludesBeginOffset + result.size() - CursorToEOLOffset;
1746 CurrentCategory = Includes[Index].Category;
1750 FileName, Includes.front().Offset, IncludesBlockSize, result));
1761 const char CppIncludeRegexPattern[] =
1762 R
"(^[\t\ ]*#[\t\ ]*(import|include)[^"<]*(["<][^">]*[">]))"; 1772 unsigned SearchFrom = 0;
1773 llvm::Regex IncludeRegex(CppIncludeRegexPattern);
1785 bool FirstIncludeBlock =
true;
1786 bool MainIncludeFound =
false;
1787 bool FormattingOff =
false;
1790 auto Pos = Code.find(
'\n', SearchFrom);
1792 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
1794 StringRef Trimmed = Line.trim();
1795 if (Trimmed ==
"// clang-format off")
1796 FormattingOff =
true;
1797 else if (Trimmed ==
"// clang-format on")
1798 FormattingOff =
false;
1800 const bool EmptyLineSkipped =
1804 tooling::IncludeStyle::IBS_Regroup);
1806 if (!FormattingOff && !Line.endswith(
"\\")) {
1807 if (IncludeRegex.match(Line, &Matches)) {
1808 StringRef IncludeName = Matches[2];
1811 !MainIncludeFound && FirstIncludeBlock);
1813 MainIncludeFound =
true;
1814 IncludesInBlock.push_back({IncludeName,
Line, Prev, Category});
1815 }
else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
1818 IncludesInBlock.clear();
1819 FirstIncludeBlock =
false;
1823 if (Pos == StringRef::npos || Pos + 1 == Code.size())
1825 SearchFrom = Pos + 1;
1827 if (!IncludesInBlock.empty())
1828 sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, Cursor);
1835 StringRef ImportIdentifier) {
1836 unsigned LongestMatchIndex =
UINT_MAX;
1837 unsigned LongestMatchLength = 0;
1840 if (ImportIdentifier.startswith(GroupPrefix) &&
1841 GroupPrefix.length() > LongestMatchLength) {
1842 LongestMatchIndex = I;
1843 LongestMatchLength = GroupPrefix.length();
1846 return LongestMatchIndex;
1858 unsigned ImportsBeginOffset = Imports.front().Offset;
1859 unsigned ImportsEndOffset =
1860 Imports.back().Offset + Imports.back().Text.size();
1861 unsigned ImportsBlockSize = ImportsEndOffset - ImportsBeginOffset;
1862 if (!
affectsRange(Ranges, ImportsBeginOffset, ImportsEndOffset))
1866 for (
unsigned i = 0, e = Imports.size(); i != e; ++i) {
1867 Indices.push_back(i);
1868 JavaImportGroups.push_back(
1871 llvm::sort(Indices.begin(), Indices.end(), [&](
unsigned LHSI,
unsigned RHSI) {
1873 return std::make_tuple(!Imports[LHSI].
IsStatic, JavaImportGroups[LHSI],
1875 std::make_tuple(!Imports[RHSI].IsStatic, JavaImportGroups[RHSI],
1876 Imports[RHSI].Identifier);
1880 Indices.erase(std::unique(Indices.begin(), Indices.end(),
1881 [&](
unsigned LHSI,
unsigned RHSI) {
1882 return Imports[LHSI].Text == Imports[RHSI].Text;
1886 bool CurrentIsStatic = Imports[Indices.front()].IsStatic;
1887 unsigned CurrentImportGroup = JavaImportGroups[Indices.front()];
1890 for (
unsigned Index : Indices) {
1891 if (!result.empty()) {
1893 if (CurrentIsStatic != Imports[Index].
IsStatic ||
1894 CurrentImportGroup != JavaImportGroups[Index])
1898 result += CommentLine;
1901 result += Imports[Index].Text;
1902 CurrentIsStatic = Imports[Index].IsStatic;
1903 CurrentImportGroup = JavaImportGroups[Index];
1907 ImportsBlockSize, result));
1918 const char JavaImportRegexPattern[] =
1919 "^[\t ]*import[\t ]*(static[\t ]*)?([^\t ]*)[\t ]*;";
1928 unsigned SearchFrom = 0;
1929 llvm::Regex ImportRegex(JavaImportRegexPattern);
1934 bool FormattingOff =
false;
1937 auto Pos = Code.find(
'\n', SearchFrom);
1939 Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev);
1941 StringRef Trimmed = Line.trim();
1942 if (Trimmed ==
"// clang-format off")
1943 FormattingOff =
true;
1944 else if (Trimmed ==
"// clang-format on")
1945 FormattingOff =
false;
1947 if (ImportRegex.match(Line, &Matches)) {
1948 if (FormattingOff) {
1953 StringRef Static = Matches[1];
1956 if (Static.contains(
"static")) {
1960 AssociatedCommentLines.clear();
1961 }
else if (Trimmed.size() > 0 && !ImportsInBlock.empty()) {
1963 AssociatedCommentLines.push_back(Line);
1966 if (Pos == StringRef::npos || Pos + 1 == Code.size())
1968 SearchFrom = Pos + 1;
1970 if (!ImportsInBlock.empty())
1979 return Code.size() > 188 && Code[0] == 0x47 && Code[188] == 0x47;
1982 bool isLikelyXml(StringRef Code) {
return Code.ltrim().startswith(
"<"); }
1986 StringRef FileName,
unsigned *
Cursor) {
1992 if (Style.
Language == FormatStyle::LanguageKind::LK_JavaScript &&
1995 if (Style.
Language == FormatStyle::LanguageKind::LK_JavaScript)
1997 if (Style.
Language == FormatStyle::LanguageKind::LK_Java)
2003 template <
typename T>
2008 if (Replaces.
empty())
2013 return NewCode.takeError();
2015 StringRef FileName = Replaces.
begin()->getFilePath();
2018 ProcessFunc(Style, *NewCode, ChangedRanges, FileName);
2020 return Replaces.
merge(FormatReplaces);
2029 std::vector<tooling::Range> Ranges,
2033 auto SortedReplaces =
2035 if (!SortedReplaces)
2036 return SortedReplaces.takeError();
2041 std::vector<tooling::Range> Ranges,
2043 return reformat(Style, Code, Ranges, FileName);
2052 llvm::Regex(CppIncludeRegexPattern)
2068 std::set<llvm::StringRef> HeadersToDelete;
2070 for (
const auto &R : Replaces) {
2071 if (isHeaderInsertion(R)) {
2074 llvm::consumeError(HeaderInsertions.
add(R));
2075 }
else if (isHeaderDeletion(R)) {
2076 HeadersToDelete.insert(R.getReplacementText());
2077 }
else if (R.getOffset() ==
UINT_MAX) {
2078 llvm::errs() <<
"Insertions other than header #include insertion are " 2080 << R.getReplacementText() <<
"\n";
2082 llvm::consumeError(Result.
add(R));
2085 if (HeaderInsertions.
empty() && HeadersToDelete.empty())
2089 StringRef FileName = Replaces.begin()->getFilePath();
2092 for (
const auto &Header : HeadersToDelete) {
2094 Includes.
remove(Header.trim(
"\"<>"), Header.startswith(
"<"));
2095 for (
const auto &R : Replaces) {
2096 auto Err = Result.
add(R);
2099 llvm::errs() <<
"Failed to add header deletion replacement for " 2106 llvm::Regex IncludeRegex = llvm::Regex(CppIncludeRegexPattern);
2108 for (
const auto &R : HeaderInsertions) {
2109 auto IncludeDirective = R.getReplacementText();
2110 bool Matched = IncludeRegex.match(IncludeDirective, &Matches);
2111 assert(Matched &&
"Header insertion replacement must have replacement text " 2114 auto IncludeName = Matches[2];
2116 Includes.
insert(IncludeName.trim(
"\"<>"), IncludeName.startswith(
"<"));
2118 auto Err = Result.
add(*Replace);
2120 llvm::consumeError(std::move(Err));
2139 std::vector<tooling::Range> Ranges,
2141 return cleanup(Style, Code, Ranges, FileName);
2145 fixCppIncludeInsertions(Code, Replaces, Style);
2149 namespace internal {
2150 std::pair<tooling::Replacements, unsigned>
2153 unsigned NextStartColumn,
unsigned LastStartColumn, StringRef FileName,
2163 typedef std::function<std::pair<tooling::Replacements, unsigned>(
2168 if (Style.
Language == FormatStyle::LK_Cpp) {
2180 if (Style.
Language == FormatStyle::LK_JavaScript &&
2183 return JavaScriptRequoter(Env, Expanded).process();
2187 return Formatter(Env, Expanded, Status).process();
2191 llvm::make_unique<Environment>(Code, FileName, Ranges, FirstStartColumn,
2192 NextStartColumn, LastStartColumn);
2195 unsigned Penalty = 0;
2196 for (
size_t I = 0, E = Passes.size(); I < E; ++I) {
2197 std::pair<tooling::Replacements, unsigned> PassFixes = Passes[I](*Env);
2199 CurrentCode ? StringRef(*CurrentCode) : Code, PassFixes.first);
2201 Fixes = Fixes.
merge(PassFixes.first);
2202 Penalty += PassFixes.second;
2204 CurrentCode = std::move(*NewCode);
2205 Env = llvm::make_unique<Environment>(
2206 *CurrentCode, FileName,
2208 FirstStartColumn, NextStartColumn, LastStartColumn);
2213 return {Fixes, Penalty};
2224 0, FileName, Status)
2230 StringRef FileName) {
2232 if (Style.
Language != FormatStyle::LK_Cpp)
2234 return Cleaner(
Environment(Code, FileName, Ranges), Style).process().first;
2239 StringRef FileName,
bool *IncompleteFormat) {
2241 auto Result =
reformat(Style, Code, Ranges, FileName, &Status);
2243 *IncompleteFormat =
true;
2250 StringRef FileName) {
2259 StringRef FileName) {
2267 LangOpts.CPlusPlus = 1;
2268 LangOpts.CPlusPlus11 = Style.
Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
2269 LangOpts.CPlusPlus14 = Style.
Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
2270 LangOpts.CPlusPlus17 = Style.
Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
2271 LangOpts.CPlusPlus2a = Style.
Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
2272 LangOpts.LineComment = 1;
2273 bool AlternativeOperators = Style.
isCpp();
2274 LangOpts.CXXOperatorNames = AlternativeOperators ? 1 : 0;
2277 LangOpts.MicrosoftExt = 1;
2278 LangOpts.DeclSpecKeyword = 1;
2283 "Coding style, currently supports:\n" 2284 " LLVM, Google, Chromium, Mozilla, WebKit.\n" 2285 "Use -style=file to load style configuration from\n" 2286 ".clang-format file located in one of the parent\n" 2287 "directories of the source file (or current\n" 2288 "directory for stdin).\n" 2289 "Use -style=\"{key: value, ...}\" to set specific\n" 2290 "parameters, e.g.:\n" 2291 " -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
2294 if (FileName.endswith(
".java"))
2295 return FormatStyle::LK_Java;
2296 if (FileName.endswith_lower(
".js") || FileName.endswith_lower(
".ts"))
2297 return FormatStyle::LK_JavaScript;
2298 if (FileName.endswith(
".m") || FileName.endswith(
".mm"))
2299 return FormatStyle::LK_ObjC;
2300 if (FileName.endswith_lower(
".proto") ||
2301 FileName.endswith_lower(
".protodevel"))
2302 return FormatStyle::LK_Proto;
2303 if (FileName.endswith_lower(
".textpb") ||
2304 FileName.endswith_lower(
".pb.txt") ||
2305 FileName.endswith_lower(
".textproto") ||
2306 FileName.endswith_lower(
".asciipb"))
2307 return FormatStyle::LK_TextProto;
2308 if (FileName.endswith_lower(
".td"))
2309 return FormatStyle::LK_TableGen;
2310 return FormatStyle::LK_Cpp;
2315 if (GuessedLanguage == FormatStyle::LK_Cpp) {
2316 auto Extension = llvm::sys::path::extension(FileName);
2319 if (Extension.empty() || Extension ==
".h") {
2320 auto NonEmptyFileName = FileName.empty() ?
"guess.h" : FileName;
2324 if (Guesser.isObjC())
2325 return FormatStyle::LK_ObjC;
2328 return GuessedLanguage;
2336 StringRef FallbackStyleName,
2338 llvm::vfs::FileSystem *FS) {
2340 FS = llvm::vfs::getRealFileSystem().get();
2349 if (StyleName.startswith(
"{")) {
2356 if (!StyleName.equals_lower(
"file")) {
2365 if (std::error_code EC = FS->makeAbsolute(Path))
2368 for (StringRef Directory = Path; !Directory.empty();
2369 Directory = llvm::sys::path::parent_path(Directory)) {
2371 auto Status = FS->status(Directory);
2373 Status->getType() != llvm::sys::fs::file_type::directory_file) {
2379 llvm::sys::path::append(ConfigFile,
".clang-format");
2380 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
2382 Status = FS->status(ConfigFile.str());
2383 bool FoundConfigFile =
2384 Status && (Status->getType() == llvm::sys::fs::file_type::regular_file);
2385 if (!FoundConfigFile) {
2387 ConfigFile = Directory;
2388 llvm::sys::path::append(ConfigFile,
"_clang-format");
2389 LLVM_DEBUG(llvm::dbgs() <<
"Trying " << ConfigFile <<
"...\n");
2390 Status = FS->status(ConfigFile.str());
2391 FoundConfigFile = Status && (Status->getType() ==
2392 llvm::sys::fs::file_type::regular_file);
2395 if (FoundConfigFile) {
2396 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
Text =
2397 FS->getBufferForFile(ConfigFile.str());
2398 if (std::error_code EC = Text.getError())
2400 if (std::error_code ec =
2402 if (ec == ParseError::Unsuitable) {
2403 if (!UnsuitableConfigFiles.empty())
2404 UnsuitableConfigFiles.append(
", ");
2405 UnsuitableConfigFiles.append(ConfigFile);
2411 LLVM_DEBUG(llvm::dbgs()
2412 <<
"Using configuration file " << ConfigFile <<
"\n");
2416 if (!UnsuitableConfigFiles.empty())
2419 UnsuitableConfigFiles);
2420 return FallbackStyle;
SourceLocation getLocWithOffset(int Offset) const
Return a source location with the specified offset from this SourceLocation.
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Defines the SourceManager interface.
AffectedRangeManager class manages affected ranges in the code.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file implements a token annotator, i.e.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Defines the Diagnostic-related interfaces.
WhitespaceManager class manages whitespace around tokens and their replacements.
const AnnotatedLine * Line
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
SourceLocation getEnd() const
Encodes a location in the source.
This file contains the declaration of the UnwrappedLineParser, which turns a stream of tokens into Un...
Dataflow Directional Tag Classes.
This file implements a sorter for JavaScript ES6 imports.
This file declares an abstract TokenAnalyzer, and associated helper classes.
This file implements an indenter that manages the indentation of continuations.
This file declares UsingDeclarationsSorter, a TokenAnalyzer that sorts consecutive using declarations...
SourceLocation getBegin() const
This class handles loading and caching of source files into memory.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
SourceLocation getEndLoc() const