clang-format

基础格式是 LLVM ,4 空格缩进、100 列宽、左花括号不换行,整体风格偏展开、低压缩、低对齐。

函数参数换行时一行一个,二元/三元运算符换行时置于行首,指针和引用符号靠右,const 位置不动,继承和构造函数初始化列表冒号前换行,命名空间内部不缩进,注释自动重排,预处理指令按层缩进,禁止 include 排序和表格对齐,最多保留一个空行,并且不自动增删大括号或分号。

diff 友好,代码结构清晰。

BasedOnStyle: LLVM
Language: Cpp

# =============================================================================
# Basic layout
# =============================================================================

IndentWidth: 4
TabWidth: 4
UseTab: Never
ContinuationIndentWidth: 4
ColumnLimit: 100

# Attach opening braces:
#
# if (...) {
# }
#
# void foo() {
# }
BreakBeforeBraces: Attach


# =============================================================================
# Function calls / parameters
# =============================================================================

# When a (...) list has to wrap:
#
# foo(
#     arg1,
#     arg2
# );
#
# NOTE:
# clang-format 21 cannot distinguish function parentheses from if/while
# parentheses here. clang-format 22+ has more fine-grained options.
AlignAfterOpenBracket: BlockIndent

# Never squeeze multiple wrapped arguments onto the same line.
BinPackArguments: false
BinPackParameters: OnePerLine

AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false

# Don't force every function definition with parameters to wrap if it fits.
BreakFunctionDefinitionParameters: false


# =============================================================================
# Short constructs
# =============================================================================

# Short functions defined inside a class may stay on one line:
#
# int size() const { return size_; }
#
# Ordinary out-of-class functions are still expanded.
AllowShortFunctionsOnASingleLine: InlineOnly

# Do not compress control flow.
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false

# Simple lambdas may stay on one line.
AllowShortLambdasOnASingleLine: Inline

# Empty classes / structs may stay compact.
AllowShortBlocksOnASingleLine: Empty


# =============================================================================
# Templates / concepts
# =============================================================================

# Always:
#
# template <typename T>
# T *cast(...);
BreakTemplateDeclarations: Yes

# Keep template arguments normally compact.
BreakBeforeTemplateCloser: false

# Prefer:
#
# template <typename T>
# requires SomeConcept<T>
# void foo();
BreakBeforeConceptDeclarations: Always


# =============================================================================
# Expressions
# =============================================================================

# Arithmetic:
#
# auto value = first
#     + second
#     + third;
#
# This is your preferred operator-at-start style.
BreakBeforeBinaryOperators: All

# Don't aggressively explode every binary operation merely because one wraps.
BreakBinaryOperations: Never

# Avoid visual column alignment in expressions.
AlignOperands: DontAlign

# Ternary:
#
# auto value = condition
#     ? foo
#     : bar;
BreakBeforeTernaryOperators: true


# =============================================================================
# Pointers / references / qualifiers
# =============================================================================

# Your requested style:
#
# Token *token;
# SourceManager &source;
PointerAlignment: Right
ReferenceAlignment: Right
DerivePointerAlignment: false

# Keep const exactly where the author wrote it.
#
# const Token *
# Token const *
#
# clang-format won't rewrite one into the other.
QualifierAlignment: Leave


# =============================================================================
# Constructor initializer lists
# =============================================================================

# Prefer normal trailing commas:
#
# Foo::Foo()
#     : a_(...),
#       b_(...),
#       c_(...) {
# }
BreakConstructorInitializers: BeforeColon

ConstructorInitializerIndentWidth: 4

# When wrapped, use one initializer per line.
PackConstructorInitializers: Never


# =============================================================================
# Inheritance lists
# =============================================================================

# Prefer:
#
# class Parser
#     : public ParserBase,
#       public DiagnosticConsumer {
# };
BreakInheritanceList: BeforeColon


# =============================================================================
# Classes / access modifiers
# =============================================================================

# class Foo {
# public:
#     ...
#
# private:
#     ...
# };
AccessModifierOffset: -4

# Keep access sections visually separated when they form distinct blocks.
EmptyLineBeforeAccessModifier: LogicalBlock
EmptyLineAfterAccessModifier: Never


# =============================================================================
# switch
# =============================================================================

# switch (...) {
# case Foo:
#     ...
# case Bar:
#     ...
# }
IndentCaseLabels: false

# Don't add another indentation level merely because a case has statements.
IndentCaseBlocks: false


# =============================================================================
# Namespaces
# =============================================================================

# namespace foo {
#
# class Bar {
# };
#
# } // namespace foo
NamespaceIndentation: None
FixNamespaceComments: true
CompactNamespaces: false


# =============================================================================
# Includes
# =============================================================================

# clang-format must not touch include ordering.
SortIncludes:
  Enabled: false

# Since sorting is disabled, also don't merge/regroup include blocks.
IncludeBlocks: Preserve


# =============================================================================
# Braced initialization
# =============================================================================

# Prefer:
#
# SourceLocation loc{file, offset};
#
# std::vector<int> values{
#     ...
# };
Cpp11BracedListStyle: true
SpaceBeforeCpp11BracedList: false

# clang-format 21 option:
# don't suddenly bin-pack giant initializer lists with >= 20 items.
BinPackLongBracedList: false


# =============================================================================
# Comments
# =============================================================================

# Wrap long comments to ColumnLimit.
ReflowComments: Always

# Enforce normal:
#
# // comment
#
# instead of:
#
# //comment
SpacesInLineCommentPrefix:
  Minimum: 1
  Maximum: 1


# =============================================================================
# Preprocessor
# =============================================================================

# #if FOO
# #  if BAR
# #    define BAZ
# #  endif
# #endif
IndentPPDirectives: AfterHash

# Two spaces per nested PP level looks substantially better than 4 here.
PPIndentWidth: 2

# Align multiline macro backslashes:
#
# #define FOO(x) \
#     something  \
#     something
AlignEscapedNewlines: Left


# =============================================================================
# Empty lines
# =============================================================================

MaxEmptyLinesToKeep: 1

KeepEmptyLines:
  AtEndOfFile: false
  AtStartOfBlock: false
  AtStartOfFile: false


# =============================================================================
# Alignment
# =============================================================================

# Avoid table-like alignment and noisy diffs.
AlignConsecutiveAssignments: None
AlignConsecutiveDeclarations: None
AlignConsecutiveBitFields: None
AlignConsecutiveMacros: None

AlignTrailingComments:
  Kind: Never


# =============================================================================
# Spaces
# =============================================================================

SpaceBeforeParens: ControlStatements
SpacesInParens: Never
SpacesInSquareBrackets: false
SpaceBeforeAssignmentOperators: true

SpaceBeforeCaseColon: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true


# =============================================================================
# Return type / declaration breaking
# =============================================================================

# Strongly discourage:
#
# VeryLongReturnType
# foo();
#
# This is a preference, not an absolute prohibition.
PenaltyReturnTypeOnItsOwnLine: 1000


# =============================================================================
# Formatter must not rewrite program structure
# =============================================================================

InsertBraces: false
RemoveBracesLLVM: false
RemoveSemicolon: false

大概样式

template <typename T>
class Parser
    : public ParserBase,
      public DiagnosticConsumer {
public:
    Parser(
        SourceManager &source_manager,
        DiagnosticEngine &diagnostics
    );

    T *parse(
        const Token &token,
        ParseOptions options
    );

    bool eof() const { return current_ == end_; }

private:
    SourceManager &source_manager_;
    DiagnosticEngine &diagnostics_;
};

template <typename T>
T *Parser<T>::parse(
    const Token &token,
    ParseOptions options
) {
    if (token.isIdentifier()
        && options.allow_identifier
        && source_manager_.isValid(token.location())) {
        return parseIdentifier(token);
    }

    auto text = source_manager_
        .getBuffer(token.location())
        .substr(token.offset());

    auto value = firstLongExpression
        + secondLongExpression
        + thirdLongExpression;

    switch (token.kind()) {
    case TokenKind::Identifier:
        return parseIdentifier(token);

    case TokenKind::Integer: {
        auto integer = parseInteger(token);
        return convert(integer);
    }

    default:
        return nullptr;
    }
}

clang-tidy

命令接近rust风格,开了部分静态检查,能const就const

---
Checks: >
  -*,

  clang-analyzer-*,

  bugprone-*,
  -bugprone-easily-swappable-parameters,

  performance-*,

  cppcoreguidelines-init-variables,
  cppcoreguidelines-owning-memory,
  cppcoreguidelines-pro-type-const-cast,
  cppcoreguidelines-pro-type-cstyle-cast,
  cppcoreguidelines-pro-type-reinterpret-cast,
  cppcoreguidelines-slicing,
  cppcoreguidelines-special-member-functions,
  cppcoreguidelines-use-enum-class,
  cppcoreguidelines-virtual-class-destructor,

  google-build-using-namespace,
  google-explicit-constructor,

  modernize-avoid-c-arrays,
  modernize-use-equals-default,
  modernize-use-equals-delete,
  modernize-use-nullptr,
  modernize-use-override,
  modernize-use-using,

  misc-const-correctness,
  misc-include-cleaner,
  misc-static-assert,

  readability-convert-member-functions-to-static,
  readability-else-after-return,
  readability-function-cognitive-complexity,
  readability-identifier-naming,
  readability-make-member-function-const,
  readability-redundant-access-specifiers,
  readability-redundant-casting,
  readability-redundant-control-flow,
  readability-redundant-declaration,
  readability-redundant-function-ptr-dereference,
  readability-redundant-inline-specifier,
  readability-redundant-member-init,
  readability-redundant-smartptr-get,
  readability-redundant-string-cstr,
  readability-redundant-string-init,
  readability-static-accessed-through-instance

WarningsAsErrors: ''

HeaderFileExtensions:
  - h
  - hh
  - hpp
  - hxx
  - inc

ImplementationFileExtensions:
  - c
  - cc
  - cpp
  - cxx

FormatStyle: file

CheckOptions:

  # ===========================================================================
  # Cognitive complexity
  # ===========================================================================

  # Parser / Sema naturally contain fairly complex control flow.
  # Default is 25; we deliberately relax this to 40.
  readability-function-cognitive-complexity.Threshold: 40

  # One top-level diagnostic is enough. Don't emit a warning for every
  # individual if / loop contributing to the score.
  readability-function-cognitive-complexity.DescribeBasicIncrements: false

  # Macro internals should not distort normal function complexity.
  readability-function-cognitive-complexity.IgnoreMacros: true


  # ===========================================================================
  # Naming: types
  # ===========================================================================

  readability-identifier-naming.ClassCase: CamelCase
  readability-identifier-naming.StructCase: CamelCase
  readability-identifier-naming.UnionCase: CamelCase
  readability-identifier-naming.EnumCase: CamelCase
  readability-identifier-naming.TypeAliasCase: CamelCase
  readability-identifier-naming.TypedefCase: CamelCase

  # template <typename NodeT>
  readability-identifier-naming.TemplateParameterCase: CamelCase

  # concept ASTNode = ...
  readability-identifier-naming.ConceptCase: CamelCase


  # ===========================================================================
  # Naming: namespaces / functions
  # ===========================================================================

  # namespace sema
  # namespace source
  readability-identifier-naming.NamespaceCase: lower_case
  readability-identifier-naming.InlineNamespaceCase: lower_case

  # parse_expression()
  readability-identifier-naming.FunctionCase: lower_case
  readability-identifier-naming.MethodCase: lower_case

  # Keep constexpr methods consistent with ordinary methods.
  readability-identifier-naming.ConstexprMethodCase: lower_case


  # ===========================================================================
  # Naming: variables / parameters
  # ===========================================================================

  # auto source_location = ...
  readability-identifier-naming.LocalVariableCase: lower_case

  # void parse_expression(const Token &current_token)
  readability-identifier-naming.ParameterCase: lower_case

  # Local const is still ordinary snake_case:
  #
  # const auto token_count = tokens.size();
  readability-identifier-naming.LocalConstantCase: lower_case

  # constexpr is a compile-time property, not an ALL_CAPS naming category:
  #
  # constexpr std::size_t default_buffer_size = 4096;
  readability-identifier-naming.ConstexprVariableCase: lower_case


  # ===========================================================================
  # Naming: data members
  # ===========================================================================

  # class Parser {
  # private:
  #     SourceManager &source_manager_;
  # };
  readability-identifier-naming.PrivateMemberCase: lower_case
  readability-identifier-naming.PrivateMemberSuffix: _

  # struct BinaryExpr {
  #     Expr *lhs;
  #     Expr *rhs;
  # };
  readability-identifier-naming.PublicMemberCase: lower_case

  # Protected follows the encapsulated member style.
  readability-identifier-naming.ProtectedMemberCase: lower_case
  readability-identifier-naming.ProtectedMemberSuffix: _


  # ===========================================================================
  # Naming: constants
  # ===========================================================================

  # Real named const objects at namespace / static scope:
  #
  # const int MAX_RETRY_COUNT = 3;
  readability-identifier-naming.GlobalConstantCase: UPPER_CASE
  readability-identifier-naming.StaticConstantCase: UPPER_CASE

  # constexpr has a more specific rule above, therefore remains snake_case.


  # ===========================================================================
  # Naming: enums / macros / globals
  # ===========================================================================

  # enum class TokenKind {
  #     Identifier,
  #     IntegerLiteral,
  #     LeftParen,
  # };
  readability-identifier-naming.EnumConstantCase: CamelCase

  # #define STC_ASSERT(...)
  readability-identifier-naming.MacroDefinitionCase: UPPER_CASE

  # Rare globals remain plain snake_case.
  readability-identifier-naming.GlobalVariableCase: lower_case

  # You don't currently use static mutable members enough to justify s_foo.
  readability-identifier-naming.StaticVariableCase: lower_case


  # ===========================================================================
  # Const correctness
  # ===========================================================================

  # You explicitly wanted const suggestions for locals, references, pointers
  # and pointees where clang-tidy can prove them.
  misc-const-correctness.AnalyzeValues: true
  misc-const-correctness.AnalyzeReferences: true
  misc-const-correctness.AnalyzePointers: true

  # Also inspect whether the pointed-to object can be const.
  misc-const-correctness.WarnPointersAsValues: true
  misc-const-correctness.TransformPointersAsValues: true


  # ===========================================================================
  # Includes
  # ===========================================================================

  # Report both:
  #
  #   1. symbols used without their owning header
  #   2. includes which are not actually used
  #
  # Do not run clang-tidy --fix blindly if you only want diagnostics.
  misc-include-cleaner.UnusedIncludes: true
  misc-include-cleaner.MissingIncludes: true
  misc-include-cleaner.DeduplicateFindings: true


  # ===========================================================================
  # bugprone
  # ===========================================================================

  # assert(foo()) can be dangerous if foo() has effects. Be strict.
  bugprone-assert-side-effect.CheckFunctionCalls: true

  # We deliberately disabled easily-swappable-parameters above because it
  # tends to produce design/style noise in parser/compiler APIs.


  # ===========================================================================
  # Special members / ownership
  # ===========================================================================

  # Rule-of-five style diagnostics.
  cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor: true

...