in TokenAnnotator::parseBrace. Left is misleading, because we have a
loop and Left does not move.
Also return early.
Differential Revision: https://reviews.llvm.org/D121558
in TokenAnnotator::parseParens(). Left is misleading since we have a
loop and Left is not adjusted.
Differential Revision: https://reviews.llvm.org/D121557
I have lost count of the number of times this has been reported, but it fundamentally comes down to the fact that the "AlignArrayLeft/Right" function is fundamentally broken for non-square arrays.
As a result, a pointer can end up running off the end of the array structure, I've spent the last 2 weekends trying to rewrite this algorithm but I've struggled to get it aligned correctly.
This is an interim fix, that ignores all array that are non-square and leaves them alone. I think this can allow us to close out most of the crashes (if not all).
I think this can help reduce the number of bugs coming in that are duplicates.
https://github.com/llvm/llvm-project/issues/53748https://github.com/llvm/llvm-project/issues/51767https://github.com/llvm/llvm-project/issues/51277
Reviewed By: curdeius, HazardyKnusperkeks, feg208
Differential Revision: https://reviews.llvm.org/D121069
Before, the code:
```
int Value { get; } = 0;
int Value { init; } = 0;
```
was formatted incoherently:
```
int Value { get; } = 0;
int Value { init; }
= 0;
```
because `init` was not recognised as an accessor specifier.
Reviewed By: MyDeveloperDay, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D121132
Fixes https://github.com/llvm/llvm-project/issues/54147.
When handling `AllowShortFunctionsOnASingleLine`, we were searching for the last line with a smaller level than the current line. The search was incorrect when the first line had the same level as the current one. This led to an unsatisfied assumption about the existence of a brace (non-comment token).
Reviewed By: HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D120902
https://github.com/llvm/llvm-project/issues/53981
Reorder the qualifiers inside the template argument. This should handle the simple cases of
```
<const T>
<T const>
```
But only by relaxing that single letter capital variables are not possible macros
Fixes: #53981
Reviewed By: HazardyKnusperkeks, curdeius
Differential Revision: https://reviews.llvm.org/D120710
Originally filed at crbug.com/1184570.
When the name of a namespace is a macro that takes arguments,
- It fixed the indentation.
- It fixed the namepsace end comments.
Differential Revision: https://reviews.llvm.org/D120931
We have a little problem. TokenAnnotator::resetTokenMetadata() resets
the type, except for a (growing) whitelist. This is because the
TokenAnnotator visits some tokens multiple times. E.g. trying to
identify if a < is an operator less or a template opener. And in some
runs, which are bascially "reverted" the types are reset.
On the other hand, if the parser does already know the type, it should
be able to set it, without it being reset. So we introduce the ability
to set a type and make that final.
Differential Revision: https://reviews.llvm.org/D120511
This change can be seen as code cleanup but motivation is more performance related.
While browsing perf reports captured during Linux build we can notice unusual portion of instructions executed in std::vector<std::string> copy constructor like:
0.59% 0.58% clang-14 clang-14 [.] std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::vector
or even:
1.42% 0.26% clang clang-14 [.] clang::LangOptions::LangOptions
|
--1.16%--clang::LangOptions::LangOptions
|
--0.74%--std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >,
std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::vector
After more digging we can see that relevant LangOptions std::vector members (*Files, ModuleFeatures and NoBuiltinFuncs)
are constructed when Lexer::LangOpts field is initialized on list:
Lexer::Lexer(..., const LangOptions &langOpts, ...)
: ..., LangOpts(langOpts),
Since LangOptions copy constructor is called by Lexer(..., const LangOptions &LangOpts,...) and local Lexer objects are created thousands times
(in Lexer::getRawToken, Preprocessor::EnterSourceFile and more) during single module processing in frontend it makes std::vector copy constructors surprisingly hot.
Unfortunately even though in current Lexer implementation mentioned std::vector members are unused and most of time empty,
no compiler is smart enough to optimize their std::vector copy constructors out (take a look at test assembly): https://godbolt.org/z/hdoxPfMYY even with LTO enabled.
However there is simple way to fix this. Since Lexer doesn't access *Files, ModuleFeatures, NoBuiltinFuncs and any other LangOptions fields (but only LangOptionsBase)
we can simply get rid of redundant copy constructor assembly by changing LangOpts type to more appropriate const LangOptions reference: https://godbolt.org/z/fP7de9176
Additionally we need to store LineComment outside LangOpts because it's written in SkipLineComment function.
Also FormatTokenLexer need to be adjusted a bit to avoid lifetime issues related to passing local LangOpts reference to Lexer.
After this change I can see more than 1% speedup in some of my microbenchmarks when using Clang release binary built with LTO.
For Linux build gains are not so significant but still nice at the level of -0.4%/-0.5% instructions drop.
Differential Revision: https://reviews.llvm.org/D120334
Fixes https://github.com/llvm/llvm-project/issues/53876.
This is a solution for standard C++ casts: const_cast, dynamic_cast, reinterpret_cast, static_cast.
A general approach handling all possible casts is not possible without semantic information.
Consider the code:
```
static_cast<T>(*function_pointer_variable)(arguments);
```
vs.
```
some_return_type<T> (*function_pointer_variable)(parameters);
// Later used as:
function_pointer_variable = &some_function;
return function_pointer_variable(args);
```
In the latter case, it's not a cast but a variable declaration of a pointer to function.
Without knowing what `some_return_type<T>` is (and clang-format does not know it), it's hard to distinguish between the two cases. Theoretically, one could check whether "parameters" are types (not a cast) and "arguments" are value/expressions (a cast), but that might be inefficient (needs lots of lookahead).
Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D120140
Fixes https://github.com/llvm/llvm-project/issues/53962.
Given the config:
```
BasedOnStyle: LLVM
QualifierAlignment: Custom
QualifierOrder: ['constexpr', 'type']
```
The code:
```
template <typename F>
requires std::invocable<F>
constexpr constructor();
```
was incorrectly formatted to:
```
template <typename F>
requires
constexpr std::invocable<F> constructor();
```
because we considered `std::invocable<F> constexpr` as a type, not recognising the requires clause.
This patch avoids moving the qualifier across the boundary of the requires clause (checking `ClosesRequiresClause`).
Reviewed By: HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D120309
Setting a boolean within an if and only using it in the very next if is
a bit confusing. Merge it into one if.
Differential Revision: https://reviews.llvm.org/D120237
In 529aa4b011
by setting the identifier info to nullptr, we started to subtly
interfere with the parts in the beginning of the function,
529aa4b011/clang/lib/Format/UnwrappedLineParser.cpp (L991)
causing the preprocessor nesting to change in some cases. E.g., for the
added regression test, clang-format started incorrectly guessing the
language as C++.
This tries to address this by introducing an internal identifier info
element to use instead.
Reviewed By: curdeius, MyDeveloperDay
Differential Revision: https://reviews.llvm.org/D120315
Adds a new option InsertBraces to insert the optional braces after
if, else, for, while, and do in C++.
Differential Revision: https://reviews.llvm.org/D120217
We can return as early as possible and only calculate IsComparison if we
really need to. Also cache getPrecedence() instead of querying it at
most 4 times.
Differential Revision: https://reviews.llvm.org/D119923
This reverts commit e021987273.
This commit provokes failures in formatting tests of polly.
Cf. https://lab.llvm.org/buildbot/#/builders/205/builds/3320.
That's probably because of `)` being annotated as `CastRParen` instead of `Unknown` before, hence being kept on the same line with the next token.
Fixes https://github.com/llvm/llvm-project/issues/53876.
This is a solution for standard C++ casts: const_cast, dynamic_cast, reinterpret_cast, static_cast.
A general approach handling all possible casts is not possible without semantic information.
Consider the code:
```
static_cast<T>(*function_pointer_variable)(arguments);
```
vs.
```
some_return_type<T> (*function_pointer_variable)(parameters);
// Later used as:
function_pointer_variable = &some_function;
return function_pointer_variable(args);
```
In the latter case, it's not a cast but a variable declaration of a pointer to function.
Without knowing what `some_return_type<T>` is (and clang-format does not know it), it's hard to distinguish between the two cases. Theoretically, one could check whether "parameters" are types (not a cast) and "arguments" are value/expressions (a cast), but that might be inefficient (needs lots of lookahead).
Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D120140
Fixes https://github.com/llvm/llvm-project/issues/24781.
Fixes https://github.com/llvm/llvm-project/issues/38160.
This patch splits `TT_RecordLBrace` for classes/enums/structs/unions (and other records, e.g. interfaces) and uses the brace type to avoid the error-prone scanning for record token.
The mentioned bugs were provoked by the scanning being too limited (and so not considering `const` or `constexpr`, or other qualifiers, on an anonymous struct variable declaration).
Moreover, the proposed solution is more efficient as we parse tokens once only (scanning being parsing too).
Reviewed By: MyDeveloperDay, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D119785
We can now configure the space between requires and the following paren,
seperate for clauses and expressions.
Differential Revision: https://reviews.llvm.org/D113369
Detect requires expressions in more unusable contexts. This is far from
perfect, but currently we have no good metric to decide between a
requires expression and a trailing requires clause.
Differential Revision: https://reviews.llvm.org/D119138
Fixes https://github.com/llvm/llvm-project/issues/53758.
Braces in loops and in `if` statements with leading (block) comments were formatted according to `BraceWrapping.AfterFunction` and not `AllowShortBlocksOnASingleLine`/`AllowShortLoopsOnASingleLine`/`AllowShortIfStatementsOnASingleLine`.
Previously, the code:
```
while (true) {
f();
}
/*comment*/ while (true) {
f();
}
```
was incorrectly formatted to:
```
while (true) {
f();
}
/*comment*/ while (true) { f(); }
```
when using config:
```
BasedOnStyle: LLVM
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: false
AllowShortBlocksOnASingleLine: false
AllowShortLoopsOnASingleLine: false
```
and it was (correctly but by chance) formatted to:
```
while (true) {
f();
}
/*comment*/ while (true) {
f();
}
```
when using enabling brace wrapping after functions:
```
BasedOnStyle: LLVM
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: true
AllowShortBlocksOnASingleLine: false
AllowShortLoopsOnASingleLine: false
```
Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D119649
Fixes https://github.com/llvm/llvm-project/issues/53576.
There was an inconsistency in formatting of delete expressions.
Before:
```
delete (void*)a;
delete[](void*) a;
```
After this patch:
```
delete (void*)a;
delete[] (void*)a;
```
Reviewed By: HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D119117
- Add or remove empty lines surrounding union blocks.
- Fixes https://github.com/llvm/llvm-project/issues/53229, in which
keywords like class and struct in a line ending with left brace or
whose next line is left brace only, will be falsely recognized as
definition line, causing extra empty lines inserted surrounding blocks
with no need to be formatted.
Reviewed By: MyDeveloperDay, curdeius, HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D119067
The l_brace token in a macro definition should not be set to
TT_FunctionLBrace.
This patch could have fixed#42087.
Differential Revision: https://reviews.llvm.org/D118969
The second space in `void foo() &` is always produced by clang-format,
and isn't evidence of any particular style.
Before this patch, it was considered evidence of PAS_Right, because
there is a space before a pointerlike ampersand.
This caused the following code to have "unstable" pointer alignment:
void a() &;
void b() &;
int *x;
PAS_Left, Derive=false would produce 'int* x' with other lines unchanged.
But subsequent formatting with Derive=true would produce 'int *x' again.
Differential Revision: https://reviews.llvm.org/D118921
* Give I[1] and I[-1] a name:
- Easier to understand
- Easier to debug (since you don't go through operator[] everytime)
* TheLine->First != TheLine->Last follows since last is a l brace and
first isn't.
* Factor the check for is(tok::l_brace) out.
* Drop else after return.
Differential Revision: https://reviews.llvm.org/D115060
This commit changes the condition of requiring comment to start with
alphanumeric characters to make no change only for a certain set of
characters, currently horizontal whitespace and punctuation characters,
to support wider set of leading characters unrelated to documentation
generation directives.
Reviewed By: HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D118869
Fixes https://github.com/llvm/llvm-project/issues/31592.
This commits enables lexing of digraphs in C++11 and onwards.
Enabling them in C++03 is error-prone, as it would unconditionally treat sequences like "<:" as digraphs, even if they are followed by a single colon, e.g. "<::" would be treated as "[:" instead of "<" followed by "::". Lexing in C++11 doesn't have this problem as it looks ahead the following token.
The relevant excerpt from Lexer::LexTokenInternal:
```
// C++0x [lex.pptoken]p3:
// Otherwise, if the next three characters are <:: and the subsequent
// character is neither : nor >, the < is treated as a preprocessor
// token by itself and not as the first character of the alternative
// token <:.
```
Also, note that both clang and gcc turn on digraphs by default (-fdigraphs), so clang-format should match this behaviour.
Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D118706
Fixes https://github.com/llvm/llvm-project/issues/52772.
This patch fixes the formatting of the code:
```
auto aaaaaaaaaaaaaaaaaaaaa = {};
auto b = g([] {
return;
});
```
which should be left as is, but before this patch was formatted to:
```
auto aaaaaaaaaaaaaaaaaaaaa = {};
auto b = g([] {
return;
});
```
Reviewed By: MyDeveloperDay, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D115972
Fixes https://github.com/llvm/llvm-project/issues/34626.
Before, the include sorter would break the code:
```
#include <stdio.h>
#include <stdint.h> /* long
comment */
```
and change it into:
```
#include <stdint.h> /* long
#include <stdio.h>
comment */
```
This commit handles only the most basic case of a single block comment on an include line, but does not try to handle all the possible edge cases with multiple comments.
Reviewed By: HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D118627
Fixes https://github.com/llvm/llvm-project/issues/53441.
Expected code:
```
/**/ //
int a; //
```
was before misformatted to:
```
/**/ //
int a; //
```
Because the "remaining length" (after the starting `/*`) of an empty block comment `/**/` was computed to be 0 instead of 2.
Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D118475
SortJavaScriptImports attempts to set its currently parsed token to an
invalid token when it reaches the end of the line. However in doing so,
it used a `FormatToken`, which contains a `Token Tok`. `Token` does not
have a constructor, so its fields start out as uninitialized memory.
`Token::startToken()` initializes all fields. Calling it in
`JavaScriptImportSorter`'s constructor thus fixes the problem.
Differential Revision: https://reviews.llvm.org/D118448
import X = A.B.C;
Previously, these were unhandled and would terminate import sorting.
With this change, aliases sort as their own group, coming last after all
other imports.
Aliases are not sorted within their group, as they may reference each
other, so order is significant.
This reverts commit f750c3d95a. It fixes
the msan issue by not parsing past the end of the line when handling
import aliases.
Differential Revision: https://reviews.llvm.org/D118446
Fixes https://github.com/llvm/llvm-project/issues/53430.
Initially, I had a quick and dirty approach, but it led to a myriad of special cases handling comments (that may add unwrapped lines).
So I added TT_RecordLBrace type annotations and it seems like a much nicer solution.
I think that in the future it will allow us to clean up some convoluted code that detects records.
Reviewed By: MyDeveloperDay, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D118337
Users can define aliases for long symbols using import aliases:
import X = A.B.C;
Previously, these were unhandled and would terminate import sorting.
With this change, aliases sort as their own group, coming last after all
other imports.
Aliases are not sorted within their group, as they may reference each
other, so order is significant.
Revision URI: https://reviews.llvm.org/D118361
- Fixes https://github.com/llvm/llvm-project/issues/53227 that wrongly
indents multiline comments
- Fixes wrong detection of single-line opening braces when used along
with those only opening scopes, causing crashes due to duplicated
replacements on the same token:
void foo()
{
{
int x;
}
}
- Fixes wrong recognition of first line of definition when the line
starts with block comment, causing crashes due to duplicated
replacements on the same token for this leads toward skipping the line
starting with inline block comment:
/*
Some descriptions about function
*/
/*inline*/ void bar() {
}
- Fixes wrong recognition of enum when used as a type name rather than
starting definition block, causing crashes due to duplicated
replacements on the same token since both actions for enum and for
definition blocks were taken place:
void foobar(const enum EnumType e) {
}
- Change to use function keyword for JavaScript instead of comparing
strings
- Resolves formatting conflict with options EmptyLineAfterAccessModifier
and EmptyLineBeforeAccessModifier (prompts with --dry-run (-n) or
--output-replacement-xml but no observable change)
- Recognize long (len>=5) uppercased name taking a single line as return
type and fix the problem of adding newline below it, with adding new
token type FunctionLikeOrFreestandingMacro and marking tokens in
UnwrappedLineParser:
void
afunc(int x) {
return;
}
TYPENAME
func(int x, int y) {
// ...
}
- Remove redundant and repeated initialization
- Do no change to newlines before EOF
Reviewed By: MyDeveloperDay, curdeius, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D117520
LLVM Programmer’s Manual strongly discourages the use of `std::vector<bool>` and suggests `llvm::BitVector` as a possible replacement.
Currently, some users of `std::vector<bool>` cannot switch to `llvm::BitVector` because it doesn't implement the `pop_back()` and `back()` functions.
To enable easy transition of `std::vector<bool>` users, this patch implements `llvm::BitVector::pop_back()` and `llvm::BitVector::back()`.
Reviewed By: dexonsmith
Differential Revision: https://reviews.llvm.org/D117115
This factors out a pattern that comes up from time to time.
Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D117769
Fixes https://github.com/llvm/llvm-project/issues/44601.
This patch handles a bug when parsing a below example code :
```
template <class> class S;
template <class T> bool operator<(S<T> const &x, S<T> const &y) {
return x.i < y.i;
}
template <class T> class S {
int i = 42;
friend bool operator< <>(S const &, S const &);
};
int main() { return S<int>{} < S<int>{}; }
```
which parse `< <>` as `<< >`, not `< <>` in terms of tokens as discussed in discord.
1. Add a condition in `tryMergeLessLess()` considering `operator` keyword and `>`
2. Force to leave a whitespace between `tok::less` and a template opener
3. Add unit test
Reviewed By: MyDeveloperDay, curdeius
Differential Revision: https://reviews.llvm.org/D117398
This style is similar to AlwaysBreak, but places closing brackets on new lines.
For example, if you have a multiline parameter list, clang-format currently only supports breaking per-parameter, but places the closing bracket on the line of the last parameter.
Function(
param1,
param2,
param3);
A style supported by other code styling tools (e.g. rustfmt) is to allow the closing brackets to be placed on their own line, aiding the user in being able to quickly infer the bounds of the block of code.
Function(
param1,
param2,
param3
);
For prior work on a similar feature, see: https://reviews.llvm.org/D33029.
Note: This currently only supports block indentation for closing parentheses.
Differential Revision: https://reviews.llvm.org/D109557
Fixes https://github.com/llvm/llvm-project/issues/24784.
With config:
```
AllowShortFunctionsOnASingleLine: Inline
NamespaceIndentation: All
```
The code:
```
namespace Test
{
void f()
{
return;
}
}
```
was incorrectly formatted to:
```
namespace Test
{
void f() { return; }
}
```
since the function `f` was considered being inside a class/struct/record.
That's because the check was simplistic and only checked for a non-zero indentation level of the line starting `f`.
Reviewed By: MyDeveloperDay, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D117142
https://github.com/llvm/llvm-project/issues/27037
Sorry its taken so long to get to this issue! (got it before it hit its 6th birthday!)
```
void operator delete(void *foo)ATTRIB;
```
(void *foo) is incorrectly determined to be a C-Style Cast resulting in the space being removed after the ) and before the attrib, due to the detection of
```
delete (A* )a;
```
The following was previously unaffected
```
void operator new(void *foo) ATTRIB;
```
Fixes#27037
Reviewed By: curdeius, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D116920
Fixes https://github.com/llvm/llvm-project/issues/52976.
- Make no formatting for macros
- Attach comment with definition headers
- Make no change on use of empty lines at block start/end
- Fix misrecognition of keyword namespace
Differential Revision: https://reviews.llvm.org/D116663
Reviewed By: MyDeveloperDay, HazardyKnusperkeks, curdeius