ios/tools/forward_declarations/README.md
This guide documents the Automated Forward Declarations Optimization & Compiler Self-Healing workflow for Chrome for iOS. It is designed to guide future engineering agents and human developers in optimizing C++ and Objective-C++ headers, decoupling interface dependencies, and resolving compilation issues automatically.
C++ #include and Objective-C #import statements in header files (.h) create tight compile-time coupling. When a header file is modified, all files transitively including it must be recompiled.
By replacing full header imports with lightweight C++ forward declarations (class / struct) and Objective-C forward declarations (@class / @protocol), we:
.mm and .cc files where they belong.Located in ios/tools/forward_declarations/, the optimization toolchain consists of:
check_forward_declarations.py:
--git option) to identify header files with optimization opportunities.fix_forward_declarations.py:
#import lines and inserting appropriate forward declaration blocks. Supports individual files, full recursive directory walking, or Git modified files (--git option)..mm/.cc) and test (_unittest.mm) files to satisfy compiler usage.forward_declarations_lib.py:
core_header_mapping.json configuration file.self_heal_branch.py:
chrome, ios_chrome_unittests) recursively, parses Clang compiler diagnostics, resolves incomplete type errors via intelligent symbol caching, and automatically allowlists GN/DEPS include boundary violations.Follow this systematic workflow to optimize any folder under //ios/chrome/:
Always isolate your optimization work inside a clean Git branch.
git checkout -b fwd-decl-<feature-name>-pilot
Run the scanner on your target subdirectory (e.g., ios/chrome/browser/enterprise) or on files modified in your git branch to see recommended optimizations:
# Scan a specific directory
python3 ios/tools/forward_declarations/check_forward_declarations.py ios/chrome/browser/enterprise
# Or scan files modified in your branch compared to origin/main automatically
python3 ios/tools/forward_declarations/check_forward_declarations.py --git
Apply the scan recommendations to auto-replace header imports with forward declarations and move imports into implementation files:
# Fix a specific directory
python3 ios/tools/forward_declarations/fix_forward_declarations.py ios/chrome/browser/enterprise
# Or fix files modified in your branch compared to origin/main automatically
python3 ios/tools/forward_declarations/fix_forward_declarations.py --git
This will stage initial changes across your header and source files.
Create an initial commit containing the basic layout transformations:
git add -A
git commit -m "[ios] Optimize forward-declarations in <feature> (pilot)"
Because header decoupling can lead to missing transitive includes inside downstream files, launch the Self-Healing compiler loop to automatically diagnose and patch compilation failures:
python3 ios/tools/forward_declarations/self_heal_branch.py fwd-decl-<feature-name>-pilot out/Debug-iphonesimulator --targets chrome ios_chrome_unittests
buildtools/checkdeps/checkdeps.py to identify illegal includes, automatically allowlisting them inside local DEPS files.gn check to detect missing target dependencies.core_header_mapping.json or efficient repository scanning, inserts the import into the implementation file, and auto-commits the healing step onto the branch!Format the code and run unit tests to ensure everything is 100% pristine:
# Apply clang-format to all touched lines
git cl format
git add -u
git commit --amend --no-edit
# Run affected unit tests
python3 ios/tools/run_cl_tests.py
Finally, upload the optimized CL to Gerrit for review:
GIT_EDITOR=true git cl upload
When modifying the script logic or performing manual interventions, pay attention to these core rules:
std::unique_ptr<Type> or absl::variant<Type>) require the full C++ type definition rather than just a forward declaration. If Clang throws an incomplete type failure inside a constructor/destructor, import the header inside the .mm file rather than trying to forward declare it in the .h.DEPS Allowlist Boundaries:
Under Chromium's architecture, directories restrict imports to enforce clean layers. If you move an import to an implementation file and checkdeps raises an Illegal include error, add the correct import pattern (+path/to/header.h) to the directory's local DEPS file.#import and DEPS lines sorted alphabetically. Our style healer heal_spacing dynamically maintains this formatting.namespace enterprise_idle { class IdleService; }). Ensure adjacent duplicate namespaces are merged into a single block for maximum readability.