diff options
author | Daniel Jasper <djasper@google.com> | 2013-02-06 14:22:40 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2013-02-06 14:22:40 +0000 |
commit | 8ff690ab478b33e0d830a6203de12d191d94f8ff (patch) | |
tree | af093e6e11e4cdec73d16e5268f690f720f66113 /lib/Format/Format.cpp | |
parent | 6b5ba8be528bf614d5f4477a4cdbd7c3b19714a6 (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.cpp | 57 |
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(); |