<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/55731>55731</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang-format] `AlignAfterOpenBracket: BlockIndent` produces inconsistent/bad formatting
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
H-G-Hristov
</td>
</tr>
</table>
<pre>
![Screen Shot 2022-05-27 at 14 30 32](https://user-images.githubusercontent.com/47526411/170691651-0c00a93e-02ca-413a-b450-99666e5da194.png)
My `.clang-format` file looks like:
```yml
---
BasedOnStyle: Google
Standard: c++20
IndentWidth: 4
ColumnLimit: 120
AccessModifierOffset: -4
AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: Right
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortLambdasOnASingleLine: Empty
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterEnum: true
AfterFunction: true
AfterStruct: true
AfterUnion: true
BeforeLambdaBody: true
SplitEmptyFunction: false
BreakBeforeBraces: Custom
BreakConstructorInitializers: BeforeComma
IncludeCategories:
# Third party headers
- Regex: '^<(boost|bzip|fmt|grpc|gsl|gtest|gmock|isl|json|openssl|tl|toml\+\+|proto|zlib)/'
Priority: 3
SortPriority: 0
CaseSensitive: true
# This library headers
- Regex: '^<(nblib)'
Priority: 4
SortPriority: 0
CaseSensitive: true
# This library headers
- Regex: '^"(nblib)'
Priority: 5
SortPriority: 0
CaseSensitive: true
# C system headers
- Regex: '^<.+\.h>$'
Priority: 1
SortPriority: 0
CaseSensitive: true
# C++ standard library headers
- Regex: '^<.+'
Priority: 2
SortPriority: 0
CaseSensitive: true
# Other headers
- Regex: '^".*'
Priority: 6
SortPriority: 0
CaseSensitive: true
IndentPPDirectives: AfterHash
PackConstructorInitializers: Never
# Different ways to arrange specifiers and qualifiers (e.g. const/volatile).
QualifierAlignment: Left
# Specifies the use of empty lines to separate definition blocks, including classes, structs, enums, and functions.
SeparateDefinitionBlocks: Always
# Add namespace comment after short namespaces
ShortNamespaceLines: 0
...
```
The result looks like:
```C++
#pragma once
#include <memory>
#include <optional>
#include <nblib/types/IForwardIterator.hpp>
#include <nblib/utilities/IFileSystem.hpp>
#include <nblib/utilities/Logging.hpp>
#include "nblib/data/hardware/IStorage.hpp"
namespace nblib::data {
#if defined(__APPLE__)
class ISystemProfiler;
#endif // defined(__APPLE__)
} // namespace nblib::data
namespace nblib::utilities {
#if defined(__linux__)
class IProcessSpawner;
#endif // defined(__linux__)
} // namespace nblib::utilities
namespace nblib::data {
using LogicalVolumeIteratorBase = nblib::types::IForwardIterator<IStorage::LogicalVolumeInfo>;
class Storage : public IStorage
{
public:
Storage();
#if defined(__APPLE__)
explicit Storage(std::unique_ptr<ISystemProfiler> systemProfiler);
#endif
#if defined(__linux__)
explicit Storage(std::unique_ptr<::nblib::utilities::IProcessSpawner> processSpawner);
#endif
public:
std::vector<LogicalVolumeInfo> GetLogicalVolumes() const noexcept override;
std::vector<LogicalVolumeInfo> GetNonSystemLogicalVolumes() const noexcept override;
std::vector<LogicalVolumeInfo> GetInternalNonRemovableLogicalVolumes() const noexcept override;
std::vector<std::string> GetPhysicalDiskDriveNames() const noexcept override;
std::vector<std::string> GetInternalNonRemovablePhysicalDiskDriveNames() const noexcept override;
std::vector<OpticalDiscDriveInfo> GetOpticalDiscDrives() const noexcept override;
std::vector<std::string> GetFloppyDiskDriveNames() const noexcept override;
std::optional<PhysicalDiskDriveInfo> GetPhysicalDiskDriveInfo(const std::string& deviceName
) const noexcept override;
std::optional<LogicalVolumeInfo> GetLogicalVolumeInfo(const std::string& deviceName) const noexcept override;
private:
template <typename Iterator>
std::optional<LogicalVolumeInfo> GetLogicalVolumeInfo(Iterator&& iterator, const std::string& deviceName)
const noexcept;
private:
#if defined(__APPLE__)
std::unique_ptr<ISystemProfiler> m_systemProfiler;
#endif // __APPLE__
#if defined(__linux__)
std::unique_ptr<::nblib::utilities::IProcessSpawner> m_processSpawner;
#endif // __linux__
};
template <typename IteratorT>
std::optional<IStorage::LogicalVolumeInfo> Storage::GetLogicalVolumeInfo(
IteratorT&& iterator, const std::string& deviceName
) const noexcept
{
static_assert(std::is_base_of_v<LogicalVolumeIteratorBase, IteratorT>);
try {
LogicalVolumeInfo volumeInfo{};
while (iterator.GetNext(volumeInfo)) {
if (volumeInfo.deviceName == deviceName) {
return volumeInfo;
}
}
return {};
} catch (const std::exception& e) {
UCLOG_ERROR << "Unable to get logical volume info: " << e.what();
return {};
}
}
} // namespace nblib::data
```
I would expect something like:
```C++
#pragma once
#include <memory>
#include <optional>
#include <nblib/types/IForwardIterator.hpp>
#include <nblib/utilities/IFileSystem.hpp>
#include <nblib/utilities/Logging.hpp>
#include "nblib/data/hardware/IStorage.hpp"
namespace nblib::data {
#if defined(__APPLE__)
class ISystemProfiler;
#endif // defined(__APPLE__)
} // namespace nblib::data
namespace nblib::utilities {
#if defined(__linux__)
class IProcessSpawner;
#endif // defined(__linux__)
} // namespace nblib::utilities
namespace nblib::data {
using LogicalVolumeIteratorBase = nblib::types::IForwardIterator<IStorage::LogicalVolumeInfo>;
class Storage : public IStorage
{
public:
Storage();
#if defined(__APPLE__)
explicit Storage(std::unique_ptr<ISystemProfiler> systemProfiler);
#endif
#if defined(__linux__)
explicit Storage(std::unique_ptr<::nblib::utilities::IProcessSpawner> processSpawner);
#endif
public:
std::vector<LogicalVolumeInfo> GetLogicalVolumes() const noexcept override;
std::vector<LogicalVolumeInfo> GetNonSystemLogicalVolumes() const noexcept override;
std::vector<LogicalVolumeInfo> GetInternalNonRemovableLogicalVolumes() const noexcept override;
std::vector<std::string> GetPhysicalDiskDriveNames() const noexcept override;
std::vector<std::string> GetInternalNonRemovablePhysicalDiskDriveNames() const noexcept override;
std::vector<OpticalDiscDriveInfo> GetOpticalDiscDrives() const noexcept override;
std::vector<std::string> GetFloppyDiskDriveNames() const noexcept override;
std::optional<PhysicalDiskDriveInfo> GetPhysicalDiskDriveInfo(
const std::string& deviceName
) const noexcept override;
std::optional<LogicalVolumeInfo> GetLogicalVolumeInfo(const std::string& deviceName) const noexcept override;
private:
template <typename Iterator>
std::optional<LogicalVolumeInfo> GetLogicalVolumeInfo(
Iterator&& iterator, const std::string& deviceName
) const noexcept;
private:
#if defined(__APPLE__)
std::unique_ptr<ISystemProfiler> m_systemProfiler;
#endif // __APPLE__
#if defined(__linux__)
std::unique_ptr<::nblib::utilities::IProcessSpawner> m_processSpawner;
#endif // __linux__
};
template <typename IteratorT>
std::optional<IStorage::LogicalVolumeInfo> Storage::GetLogicalVolumeInfo(
IteratorT&& iterator, const std::string& deviceName
) const noexcept
{
static_assert(std::is_base_of_v<LogicalVolumeIteratorBase, IteratorT>);
try {
LogicalVolumeInfo volumeInfo{};
while (iterator.GetNext(volumeInfo)) {
if (volumeInfo.deviceName == deviceName) {
return volumeInfo;
}
}
return {};
} catch (const std::exception& e) {
UCLOG_ERROR << "Unable to get logical volume info: " << e.what();
return {};
}
}
} // namespace nblib::data
```
If a function declaration cannot fit on a single line it should preferably be broken after the opening and closing bracket always.
```C++
...
// Fits on a single line:
void myFunc2(int param) const noexcept;
// Doesn't fit on a single line:
void myFunc2(
long long veryLongParametrName
) const noexcept;
void myFunc3(
int param1,
int param2,
) const noexcept;
// What about trailing return types?
auto myFunc3(
int param1,
int param2,
) const noexcept -> std::vector<of_very_long_type>;
auto myFunc3(
int param1,
int param2,
) const noexcept
-> std::vector<of_very_long_type>;
...
```
I love this new option but it needs work for braces `{}` and brackets `()`, etc.
References:
- Request: https://github.com/llvm/llvm-project/issues/53190
- Patch: https://reviews.llvm.org/D109557
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztGltv4jj319AXCxQSLuWhD1zamUrdabfMfPOInMQBb5M4azu0zK_fc-yEJMC0MNOuPq2oKgi-nPs1Or4IN1ctZ9Zyxi232-pP5oFkLCXzldDEdVy37fTb7pBQTbo94jnEc1v9Wcu9XGmdqZYHt27gP1dMtnlCl0x1llyvch9XApFqlupOIBI40xv23UGv24XH7tAZjLqDfrftBI5DRx5rO25A272uR9t-r--0R6PBYMD6Ie2Oep0sXbbcUUGl-fxjQ1oDpxPENF22IyETquE3iXjMSCzEkyIxf2JIXu0SnLD_myS2K-122z5MqGLhfTrXmxhvkU9CLOHJ7M01TUMqQ1wPWu4E_l3Hbt2mIfD3nYd6hbs9uzoVcZ6kdzzhGle75elxEDCl_hAhjziT91GkmDnQLu6NY75Mx5GGvYylE0mDJ3tgEovgyeKqn5SSbu6juZZ5oHPJUBvkkS9X20OxeAY9Sn2d5om6T8dzngJXdzw1PEY0Vmz36E2eBpqLdP_4dZLpze7xO5r4IX318ISnD8DJWC7zBBhQO6iL7QcqacKA9b19EAP7LmmWAYKtQgkxcprGVJkLIAPW2EGWD26UDB7ctLI8uPUtPXBpwsD2mBXCBDxpd3-exVwbWdTRNrhj9MlCMYwaZqa50uAx1YEp6MNQJuRtyjWnMf9RSMrenYokoaVJBnEesinVbCkkNxBLclquR76uuAxJRqXekBWjIcIpttvkkS3ZC4Kt_lrusNW_bnlT8HlfCKVbw6n_g2fwFSX4YymzAL9UjJ-amRPLBCwWvrlZ_UsB48OpAKtWZkGbDwFu2J-iR9nP4TSTQgv4_hFzHz0eY8uwJI-QB8mBJb2pUehVu3Owx50TTrU7BQ-fA34Q35rZ7bqmCtFg3PAllafLJvVLml8nuPd_QLDrnkBw_x0JnhK1UZolp0m3Y02kAzEWaO-9RXD3PQm28Z6oIgf8mnkYBt6g2n1Hqu_1isnTDAJIHL9F4uBdSLR57OFhxiUL8ICJYybGfqZqZQ9hSngl6n1haybLqsUjMx5FTAJU8kw3imhBKOTGdMmIylhgsq0ioEDydw5A7E_wANZZdkiAWCDQrEVMNZQP4BEdC_nP8rDJtpi7EPUdi3SFeV7AB6QrRqDmISIiDAM-WErKDC2KQbSFcExCFnFkRKTEx4yuWu6UcBOvIbeRAJMZM4uWb_PIMHfjA9Ifldm5IHFegJ5tIU8sYJRojMKoSB2HIUkhx6oM8gywnSBHhKLcicJcXu0Wt0yG_1IuYmo3gAtFdzqdnbKqXmt9BXFASZLH-oh6rPCyLa2ZpMuEEpEGrHHe9ay0GAGnSlgi5AZDwoFNkaEwaFxtHzhURMAbvclQ7De3N0I-g5PfgkgoWF1nlWU_gV9ezcFkQO7FdTCfuYlvJ968E8slWEDz1t5d1y3vhlRT-FoBrUAvQ9xzoBeqbwPCdesgKp3b66ADb4wQSGs42cUVWSNlIbjHYjF-eLi7Xiy2tbexUHJreXyQAstt2fIqxbEUaluMKtgTvAqq-BzOtqd_SuebzGxF-TZH4JT5yz5HwAuW5vOMPqfHcrQL6kiOKr3_io5yhZEC7IUHNP4f9hmstFZsYcDAZnUQ1rLN465xgymWRmMPNIGmkUBT9BrYrbSKWwRjQZYDsoBsIRUyKG7Z3VoBSsrLIEEUnHeiASIE9gJFdcB1DZTSYSHclP-ds0WmLXs7dnpdVB_blToFhapPM5-T6LFLB03BamjXCq9J1lx5g94D4t5SsmaBVfohNZNPTDfWldWPTY4kFewlYJkmArKu5CHb0dtpiL6I1CrmX8N4m4LNQzIAzI-QNNbUh0b1vZFvVyB3m07VoH5YbRTimXH1NJNQ7Jh0-mHoDnH6YSTcQ461cAMDtybx3a2P4_gmFlm2eS_eqrJhuie2GnuH99xLi3GXUHcAMWTNA0NchfT3STzKlU8g7WiCMuAZqs5GpAGHzmKscoEwTDuY0kiVbK7fj5UtUHeADPDtzyk5jsuKFPxrsvwGp8elqKPzUbJQR9ZSFaKTE9S7ZaNkkR1ZJ1WElEXRjlxftZavW3M5ZCpvVy2kceInVlTJp0L7awZViGDXeXZqIasJaDGDBbZ5UtfrBK4WPpRvCxEt1nveUKvvkKSGlPZqKOOKckMaePFvTwZkXYkDDtdUVF55XuHrdKCzlEgH0zd7QdJrl_EV0mgfIf6BSTTOdiqxYamK1Woz_hyEgn-S6VymdZp3qTUxFbhoLG4XmssFtAN8Y_0eUB2syH7QtHrFl7hgAIfJ_Ta9u_-0uH58vH8kxsmm2Ld9SzER47uAJcN-2Gii4IVww8wYz5VXWOd5RfXBGvkoDiqv-8Ve61BHf0ueRR6HWO9CSiZKJEyvsBs5d_bnzv7c2Z87-3Nnf-7sz539ubP_L3b2jeLr3Ob_G21-s979zab_FXWcO_5zx3_u-M8d_7nj3-v4I0K3IwegNmgSwCjwOaBpKjSJoDaGX5QoM_xnRh7AmXCcAN8UZJJFYEZ-vCE-I74UTywtBg5wWgLHwbDnwcGGIBam__Ht0COhZnih0-Dm4DsFYL8aRKhFecP0Dddqj8BGOlsLHpLETOfhTBRPNY7G0eSVNGHg72KaCabASIaHZfIayqaSY4EvVPADUvLmDh6KwUh5YhprIvJ2EW0Z7UKAObzj1ndel0ftmJHGd7BlQn2Ra4hMFJIM8FOYb9G33myv0Byc5MOoJG3THO6VnBh2QcALFPUCadpviT-ettqt3yLz9UmcW7CnNYQinBVM2TOxiZX4oBww1ZSxUJFnIZ9IJKTxP3zbAiBsnBk4xj8Lv7Q7NkrhAwQuHTS875GZSaygNndqP3H8DGoRZYaomsPjdmC8mBKP43X51Ybi4y8QBfzkSuXmhVrf646cEuIDhu19eBISDHtWHYTRERKy982s64z6_WK87SK88sKRN6IXmuuYXbX6k8YgeX-GbB41jQ3iASLDHIXGU9QvVzjyDih9GhILUIP9X-QyvvoNtvtDr3uxuhp0meN0B5eXbuQGge-5tEdHA98Zht2hHwb0IqY-ixWyBGxc8Csc4Xf67rDbBcn1Opeh16f9fnDpXkaX3UvW6jksAQ_dyupCXhka_HypYDMGdipBXkAdA0JhrIQPDrIS8upz-1P7s4SjYn1hSL4y9P4DefClUA">