aboutsummaryrefslogtreecommitdiff
path: root/lib/Format/Format.cpp
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2013-02-06 14:22:40 +0000
committerDaniel Jasper <djasper@google.com>2013-02-06 14:22:40 +0000
commit8ff690ab478b33e0d830a6203de12d191d94f8ff (patch)
treeaf093e6e11e4cdec73d16e5268f690f720f66113 /lib/Format/Format.cpp
parent6b5ba8be528bf614d5f4477a4cdbd7c3b19714a6 (diff)
Optionally derive formatting information from the input file.
With this patch, clang-format can analyze the input file for two properties: 1. Is "int *a" or "int* a" more common. 2. Are non-C++03 constructs used, e.g. A<A<A>>. With Google-style, clang-format will now use the more common style for (1) and format C++03 compatible, unless it finds C++11 constructs in the input. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174504 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/Format.cpp')
-rw-r--r--lib/Format/Format.cpp57
1 files changed, 50 insertions, 7 deletions
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index bbebec3652..99251f5c85 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -36,9 +36,10 @@ FormatStyle getLLVMStyle() {
FormatStyle LLVMStyle;
LLVMStyle.ColumnLimit = 80;
LLVMStyle.MaxEmptyLinesToKeep = 1;
- LLVMStyle.PointerAndReferenceBindToType = false;
+ LLVMStyle.PointerBindsToType = false;
+ LLVMStyle.DerivePointerBinding = false;
LLVMStyle.AccessModifierOffset = -2;
- LLVMStyle.SplitTemplateClosingGreater = true;
+ LLVMStyle.Standard = FormatStyle::LS_Cpp03;
LLVMStyle.IndentCaseLabels = false;
LLVMStyle.SpacesBeforeTrailingComments = 1;
LLVMStyle.BinPackParameters = true;
@@ -55,9 +56,10 @@ FormatStyle getGoogleStyle() {
FormatStyle GoogleStyle;
GoogleStyle.ColumnLimit = 80;
GoogleStyle.MaxEmptyLinesToKeep = 1;
- GoogleStyle.PointerAndReferenceBindToType = true;
+ GoogleStyle.PointerBindsToType = true;
+ GoogleStyle.DerivePointerBinding = true;
GoogleStyle.AccessModifierOffset = -1;
- GoogleStyle.SplitTemplateClosingGreater = false;
+ GoogleStyle.Standard = FormatStyle::LS_Auto;
GoogleStyle.IndentCaseLabels = true;
GoogleStyle.SpacesBeforeTrailingComments = 2;
GoogleStyle.BinPackParameters = false;
@@ -73,7 +75,8 @@ FormatStyle getGoogleStyle() {
FormatStyle getChromiumStyle() {
FormatStyle ChromiumStyle = getGoogleStyle();
ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
- ChromiumStyle.SplitTemplateClosingGreater = true;
+ ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
+ ChromiumStyle.DerivePointerBinding = false;
return ChromiumStyle;
}
@@ -838,14 +841,54 @@ public:
virtual ~Formatter() {}
+ void deriveLocalStyle() {
+ unsigned CountBoundToVariable = 0;
+ unsigned CountBoundToType = 0;
+ bool HasCpp03IncompatibleFormat = false;
+ for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
+ if (AnnotatedLines[i].First.Children.empty())
+ continue;
+ AnnotatedToken *Tok = &AnnotatedLines[i].First.Children[0];
+ while (!Tok->Children.empty()) {
+ if (Tok->Type == TT_PointerOrReference) {
+ bool SpacesBefore = Tok->FormatTok.WhiteSpaceLength > 0;
+ bool SpacesAfter = Tok->Children[0].FormatTok.WhiteSpaceLength > 0;
+ if (SpacesBefore && !SpacesAfter)
+ ++CountBoundToVariable;
+ else if (!SpacesBefore && SpacesAfter)
+ ++CountBoundToType;
+ }
+
+ if (Tok->Type == TT_TemplateCloser && Tok->Parent->Type ==
+ TT_TemplateCloser && Tok->FormatTok.WhiteSpaceLength == 0)
+ HasCpp03IncompatibleFormat = true;
+ Tok = &Tok->Children[0];
+ }
+ }
+ if (Style.DerivePointerBinding) {
+ if (CountBoundToType > CountBoundToVariable)
+ Style.PointerBindsToType = true;
+ else if (CountBoundToType < CountBoundToVariable)
+ Style.PointerBindsToType = false;
+ }
+ if (Style.Standard == FormatStyle::LS_Auto) {
+ Style.Standard = HasCpp03IncompatibleFormat ? FormatStyle::LS_Cpp11
+ : FormatStyle::LS_Cpp03;
+ }
+ }
+
tooling::Replacements format() {
LexerBasedFormatTokenSource Tokens(Lex, SourceMgr);
UnwrappedLineParser Parser(Diag, Style, Tokens, *this);
StructuralError = Parser.parse();
unsigned PreviousEndOfLineColumn = 0;
+ TokenAnnotator Annotator(Style, SourceMgr, Lex);
+ for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
+ Annotator.annotate(AnnotatedLines[i]);
+ }
+ deriveLocalStyle();
for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
- TokenAnnotator Annotator(Style, SourceMgr, Lex, AnnotatedLines[i]);
- Annotator.annotate();
+ Annotator.calculateFormattingInformation(AnnotatedLines[i]);
}
for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),
E = AnnotatedLines.end();