llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.82k stars 11.46k forks source link

Unexpected breaks after 'endl' #38221

Open llvmbot opened 6 years ago

llvmbot commented 6 years ago
Bugzilla Link 38873
Version 6.0
OS Linux
Reporter LLVM Bugzilla Contributor

Extended Description

If ColumnLimit high enough (but not zero) then the statement fits in a single line:

$ echo -e 'void fu(void) {\ncerr << endl << endl << "A" << endl << endl << endl << "B" << endl;\n}' |clang-format -style="{BasedOnStyle: LLVM, ColumnLimit: 200, AlignAfterOpenBracket: DontAlign, AlignOperands: false}" void fu(void) { cerr << endl << endl << "A" << endl << endl << endl << "B" << endl; }

If ColumnLimit does not allow single line, then the line is breaked (wrapped) -- but into too many pieces:

$ echo -e 'void fu(void) {\ncerr << endl << endl << "A" << endl << endl << endl << "B" << endl;\n}' |clang-format -style="{BasedOnStyle: LLVM, ColumnLimit: 60, AlignAfterOpenBracket: DontAlign, AlignOperands: false}"


void fu(void) {
  cerr << endl
       << endl
       << "A" << endl
       << endl
       << endl
       << "B" << endl;
}

After each and every 'endl' a break is introduced. Why? Any rationale or intention?

Moreover, "ColumnLimit: 0" ("infinite limit") is NOT respected! I expected the same behaviour as with "ColumnLimit: 220" (or 20000 or any very high value).

$ echo -e 'void fu(void) {\ncerr << endl << endl << "A" << endl << endl << endl << "B" << endl;\n}' |clang-format -style="{BasedOnStyle: LLVM, ColumnLimit: 0, AlignAfterOpenBracket: DontAlign, AlignOperands: false}"

void fu(void) {
  cerr << endl
       << endl
       << "A" << endl
       << endl
       << endl
       << "B" << endl;
}

Moreover, alignment occurs, despite that alignments are prohibited (each type).

mydeveloperday commented 2 years ago

This is by design for both adjacent strings or after endl in mustBreak()

  if (Current.is(tok::lessless) &&
      ((Previous.is(tok::identifier) && Previous.TokenText == "endl") ||
       (Previous.Tok.isLiteral() && (Previous.TokenText.endswith("\\n\"") ||
                                     Previous.TokenText == "\'\\n\'"))))
    return true;

see some discussion on this here https://reviews.llvm.org/D80950

Any change would have to be a new option

alejandroclaro commented 1 year ago

Here are my two cents on this.

This is really surprising and unexpected when someone starts using to use clang-format, and I think it should be configurable.

Also, the rules of this are in conflict with other configuration parameters and possible guidelines. It does not respect the ContinuationIndentWidth, and AlignOperands configurations.