Skip to content

style: apply automated formatting baseline with clang-format#2638

Open
DevGeniusCode wants to merge 6 commits into
TheSuperHackers:mainfrom
DevGeniusCode:clang/step1-whitespace
Open

style: apply automated formatting baseline with clang-format#2638
DevGeniusCode wants to merge 6 commits into
TheSuperHackers:mainfrom
DevGeniusCode:clang/step1-whitespace

Conversation

@DevGeniusCode
Copy link
Copy Markdown

@DevGeniusCode DevGeniusCode commented Apr 20, 2026

Prerequisites: Please Merge First

This PR is the final step of the formatting baseline. It depends on two preliminary structural PRs that must be merged first to ensure a clean, 100% automated formatting pass without breaking VC6 compilation:

  1. refactor: Fix pre-C++11 nested template parsing #2760 - Handle nested templates to prevent >> merging in C++98.
  2. refactor: Eliminate macro-split assignments #2641 - Eliminates macro-split assignments for clean AST parsing.

Objective

This PR introduces a minimalist, non-destructive .clang-format baseline. To make this easy to review and discuss, I have scoped the formatting only to the .\Core\GameEngine directory.

The "Do No Harm" Approach

The primary goal of this configuration is to avoid the "destructive" behavior of standard formatters.

  • ColumnLimit: 0: Automatic line wrapping is completely disabled. Clang-format will respect our manual line breaks and will not pack or split arguments unexpectedly.

What is being formatted?

To establish a consistent baseline, the formatter enforces a few core rules:

  1. Tabs & Indentation: Enforces Tabs for indentation with a width of 2.
  2. Braces (Allman Style): Standardizes to the Allman style (braces on new lines).
    Why this change was made -now-: clang-format fundamentally requires a brace style to function; it cannot simply "ignore" braces even on a pure whitespace pass. Since running the tool was inevitably going to touch braces and affect line counts anyway, I decided to "go all in" and establish a fully consistent style across the board, rather than trying to fight the tool to maintain an inconsistent legacy mix.
  3. Pointers: Enforces Left-aligned pointers (e.g., void* ptr).
  4. Trailing Comments: Vertical alignment is disabled (AlignTrailingComments: false) with a fixed 5-space offset. This prevents "diff pollution" (the ripple effect where adding one long function name forces all surrounding comments to shift).
  5. Escaped Newlines: Macro line continuations (\) are left-aligned (AlignEscapedNewlines: DontAlign) with a single space. This eliminates the "mixed whitespace" anti-pattern and ensures macros render perfectly straight in GitHub and all IDEs, regardless of the user's tab width setting.

Legacy / VC6 Compatibility

A lot of effort went into making sure this doesn't break our legacy support:

  • Zero Manual Overrides: Because the structural blockers (nested templates and macro splits) are handled in the prerequisite PRs, this configuration successfully parses and formats the legacy codebase automatically. We use Standard: c++20 to correctly parse modern syntax while maintaining VC6 compatibility structurally.
  • Macro Handling: I added custom rules (AttributeMacros and Macros) to safely parse our CPP_11 enum macros without breaking the formatting tree.
  • Short Blocks: Kept AllowShortBlocksOnASingleLine: Always so macros and empty stubs aren't vertically bloated.

Future Phases (Minimizing the Initial Diff)

Please note that several settings in this baseline (such as SortIncludes: false, AllowShortFunctionsOnASingleLine: All, and AllowShortBlocksOnASingleLine: Always) are intentionally included purely to minimize the initial diff and avoid overwhelming changes.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 20, 2026

Greptile Summary

This PR applies an automated clang-format baseline across the Core/GameEngine directory (369 files), standardising Allman braces, left-aligned pointers, and tab indentation. The formatter configuration is intentionally conservative (ColumnLimit: 0, SortIncludes: false, etc.) to minimise the diff size.

  • /* */ comment injection: Because Standard: c++20 is still in the config (the promised c++03 change is deferred), the formatter collapses > > template brackets and inserts /* */ empty comments as separators in 30+ typedef declarations, member variables, and class inheritance lists (e.g., std::map<…, std::less<T> /* */>). These are persistent code changes, not whitespace-only.
  • AlignConsecutiveDeclarations absent: The formatter strips the column-aligned struct member declarations required by the team's style guide; adding AlignConsecutiveDeclarations: Consecutive to the config would preserve that alignment on future runs.
  • Indentation of #ifdef-enclosed code: IndentPPDirectives: BeforeHash correctly indents nested directives but leaves the code between them at column 0, producing a visual mismatch in heavily conditional files like GameMemory.cpp.

Confidence Score: 3/5

The formatting changes themselves are safe, but the formatter is actively injecting /* */ empty comments into template type declarations throughout the codebase — a non-whitespace code modification that should not be merged until Standard: c++20 is corrected.

The bulk of the 369-file diff is benign whitespace and brace style normalisation. However, the unresolved Standard: c++20 setting causes the formatter to insert /* */ comments into 30+ template typedef and inheritance declarations. These are permanent, non-trivial source changes that contradict the PR's 'do no harm' objective and will confuse code search, static analysis, and reviewers. The issue is systemic across many files, not isolated to one location.

.clang-format is the root of both issues; Core/GameEngine/Source/Common/System/GameMemory.cpp and any file with nested template typedefs (e.g., Generals/Code/GameEngine/Include/Common/Player.h) show the /* */ injection most visibly.

Important Files Changed

Filename Overview
.clang-format New clang-format baseline config; Standard: c++20 (not yet changed to c++03 as promised) causes /* */ insertion into template declarations; missing AlignConsecutiveDeclarations conflicts with team style rule.
Core/GameEngine/Source/Common/System/GameMemory.cpp Automated whitespace/brace reformatting; /* */ injected into UsedNPeakMap typedef; IndentPPDirectives: BeforeHash causes #ifdef directives to indent while their enclosed code stays at column 0.
Core/GameEngine/Include/Common/AsciiString.h Formatting-only changes; column-aligned struct member declarations (m_refCount, m_numCharsAllocated) are un-aligned by the formatter.
Core/GameEngine/Include/Common/GameCommon.h Formatting-only changes; CPP_11(: Int) macro invocations gain a space before the colon (CPP_11( : Int)); code inside #if blocks is de-indented to column 0.
Generals/Code/GameEngine/Include/Common/Player.h Formatting-only changes; /* */ injected into PlayerRelationMapType typedef template closing brackets.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Source Files\n369 .cpp/.h"] --> B["clang-format\nwith .clang-format config"]
    B --> C{"Standard: c++20\nstill active"}
    C -->|"template closing brackets\n> > found"| D["Insert /* */ separator\nbetween > and >"]
    C -->|"normal formatting"| E["Apply Allman braces\nLeft pointer alignment\nTab indentation"]
    D --> F["Typedef declarations\ne.g. std::map< /* */>\nClass inheritance lists"]
    E --> G["AlignConsecutiveDeclarations\nnot set → removes column alignment"]
    E --> H["IndentPPDirectives: BeforeHash\n→ #ifdef indented, code at col 0"]
    F --> I["Formatted output\nwith embedded /* */ comments"]
    G --> I
    H --> I
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
.clang-format:63-64
**`/* */` injected into hundreds of template type declarations**

Because `Standard: c++20` is still active, the formatter merges `> >` into `>>` in template closing brackets — then inserts a `/* */` empty comment as a separator to keep the code compiling (e.g., `std::map<const char*, UsedNPeak, std::less<const char*> /* */> UsedNPeakMap`). This appears in 30+ typedef declarations, member variable types, and class inheritance lists throughout the codebase. While C++-valid, it permanently embeds empty comments into semantic code, contradicting the PR's stated "do no harm" goal. This is a direct consequence of `Standard: c++20` not yet having been changed to `c++03` as acknowledged in the previous review thread.

### Issue 2 of 2
.clang-format:38-39
The formatter is removing column-aligned struct member declarations that the team's style guide explicitly requires to be aligned. Without `AlignConsecutiveDeclarations`, every future formatter run will strip any manual alignment added by developers (e.g., `m_refCount` / `m_numCharsAllocated` in `AsciiStringData`), creating a permanent conflict between the formatter and the team's alignment rule.

```suggestion
AlignTrailingComments: false
SpacesBeforeTrailingComments: 4
AlignConsecutiveDeclarations: Consecutive
```

Reviews (5): Last reviewed commit: "style: format multi-line macros with una..." | Re-trigger Greptile

Comment thread .clang-format
Comment thread .clang-format
Copy link
Copy Markdown

@Skyaero42 Skyaero42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First initial impression.

Generic comment:

Tabs & Indentation: Enforces Tabs for indentation with a width of 2.

This is an incorrect description. Indentation width of tabs is determined by the IDE. VS defaults to 2.

Comment thread Core/GameEngine/Include/Common/AudioEventRTS.h Outdated
Comment thread Core/GameEngine/Include/Common/ArchiveFileSystem.h Outdated
Comment thread Core/GameEngine/Include/Common/AudioSettings.h Outdated
Comment thread Core/GameEngine/Include/Common/CRCDebug.h
Comment thread Core/GameEngine/Source/Common/CRCDebug.cpp
@DevGeniusCode DevGeniusCode force-pushed the clang/step1-whitespace branch from a9d279e to 9ddb58a Compare April 20, 2026 16:36
Comment thread .clang-format
@DevGeniusCode
Copy link
Copy Markdown
Author

DevGeniusCode commented Apr 21, 2026

There are still a few formatting improvements I haven’t addressed in this pass, such as consecutive assignment alignment.

Current (Before):

AudioAffect_Music = 0x01,
AudioAffect_Sound = 0x02,
AudioAffect_Sound3D = 0x04,
AudioAffect_All = (Music | Sound | Sound3D),

Target (After):

AudioAffect_Music   = 0x01,
AudioAffect_Sound   = 0x02,
AudioAffect_Sound3D = 0x04,
AudioAffect_All     = (Music | Sound | Sound3D),

If there is interest, I can implement it

Comment thread Core/GameEngine/Include/Common/Debug.h
@DevGeniusCode DevGeniusCode changed the title Proposal: Minimalist Code Formatting Baseline (Scoped to Core\GameEngine) Proposal: Minimalist Code Formatting Baseline using clang-format (Scoped to Core\GameEngine) Apr 21, 2026
@xezon
Copy link
Copy Markdown

xezon commented Apr 21, 2026

AudioAffect_Music = 0x01,
AudioAffect_Sound = 0x02,
AudioAffect_Sound3D = 0x04,
AudioAffect_All = (Music | Sound | Sound3D),

This is good.

Copy link
Copy Markdown

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does look promising.

Comment thread Core/GameEngine/Include/Common/ArchiveFile.h Outdated
Comment thread Core/GameEngine/Include/Common/FileSystem.h Outdated
Comment thread Core/GameEngine/Include/Common/FileSystem.h Outdated
Comment thread Core/GameEngine/Source/Common/System/ArchiveFileSystem.cpp Outdated
Comment thread Core/GameEngine/Source/GameClient/GUI/HeaderTemplate.cpp Outdated
@DevGeniusCode DevGeniusCode changed the title Proposal: Minimalist Code Formatting Baseline using clang-format (Scoped to Core\GameEngine) Proposal: Minimalist Code Formatting Baseline using clang-format (Scoped to Core\GameEngine) Apr 22, 2026
@DevGeniusCode
Copy link
Copy Markdown
Author

Updated

Comment thread .clang-format
@DevGeniusCode DevGeniusCode changed the title Proposal: Minimalist Code Formatting Baseline using clang-format (Scoped to Core\GameEngine) style: apply automated formatting baseline with clang-format Apr 22, 2026
@xezon

This comment was marked as resolved.

Copy link
Copy Markdown

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very promising again. I like the minimal formatting on this first pass. Just a few more things to polish.

Comment thread Core/GameEngine/Include/Common/Debug.h Outdated
Comment thread Core/GameEngine/Include/Common/Debug.h
Comment thread Core/GameEngine/Source/Common/Audio/GameAudio.cpp Outdated
if you define MEMORYPOOL_INTENSE_VERIFY, we do intensive verifications after
nearly every memory operation. this is OFF by default, since it slows down
things a lot, but is worth turning on for really obscure memory corruption issues.
*/
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The block macros are indented with 2 spaces instead of tabs. In the github page they will show with different indent width.

*/
* Closes the current file if it is open.
* Must call LocalFile::close() for each successful LocalFile::open() call.
*/
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also strange that here the block comment has only 1 leading space.

@DevGeniusCode DevGeniusCode force-pushed the clang/step1-whitespace branch from 14366de to e19a3a9 Compare May 30, 2026 16:25
@DevGeniusCode
Copy link
Copy Markdown
Author

Updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants