Skip to content

Conversation

@Guo-Shiyu
Copy link
Contributor

@Guo-Shiyu Guo-Shiyu commented Nov 16, 2025

Summary by CodeRabbit

  • New Features

    • Added support for embed directives and __has_embed queries, tracking embedded file references with associated file metadata and source locations.
  • Tests

    • Extended the test suite with new cases and helpers to validate embed directive parsing, metadata extraction, and has_embed detection.

@coderabbitai
Copy link

coderabbitai bot commented Nov 16, 2025

Walkthrough

Adds support for embed directives to the directive tracking model: two new structs (Embed, HasEmbed) and two preprocessor callbacks (EmbedDirective, HasEmbed) record embed metadata; several container insertions use push_back instead of emplace_back; tests extended to validate embeds.

Changes

Cohort / File(s) Summary
Header Structure Definitions
include/Compiler/Directive.h
Adds Embed and HasEmbed structs (filename, file ref, is_angled, loc) and adds std::vector<Embed> embeds; and std::vector<HasEmbed> has_embeds; to Directive.
Callback Implementation & Container Refactoring
src/Compiler/Directive.cpp
Implements DirectiveCollector::HasEmbed(...) and DirectiveCollector::EmbedDirective(...) to record embed metadata; replaces multiple emplace_back(...) calls with push_back({...}) for macro, include, pragma, and has-include collections.
Test Suite Extensions
tests/unit/Compiler/Directive.cpp
Adds embeds and has_embeds vectors to test state; adds expect_embed / expect_has_embed helpers and new test cases verifying embed and __has_embed parsing and recorded metadata.

Sequence Diagram(s)

sequenceDiagram
  participant PP as Preprocessor
  participant DC as DirectiveCollector
  participant DB as Directive (storage)

  rect rgb(240,248,255)
  PP->>DC: InclusionDirective(location, filename, is_angled, file)
  DC->>DB: push_back Include { ... }
  end

  rect rgb(245,255,240)
  PP->>DC: HasEmbed(location, filename, is_angled, file)
  DC->>DB: push_back HasEmbed { file_name, file, is_angled, loc }
  end

  rect rgb(255,250,240)
  PP->>DC: EmbedDirective(location, filename, is_angled, file, Params)
  DC->>DB: push_back Embed { file_name, file, is_angled, loc }
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Inspect HasEmbed / EmbedDirective callback signatures and ensure parameter types and constness match Clang PP API.
  • Confirm push_back({...}) uses aggregate/init-list types that preserve prior construction semantics and avoid slicing or extra copies.
  • Review tests for correct location decomposition and file-ref handling.

Poem

🐰 I hopped through headers, plugins, and tests,
I caught embeds in tidy little nests,
With callbacks keen and vectors grown,
Each filename shelved, each loc now known,
A frolic, brief — the code feels blessed.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding collection of embed and has_embed directives in PPCallbacks.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/Compiler/Directive.cpp (1)

60-60: Consider consistent use of push_back for imports (line 149).

The change from emplace_back to push_back with brace initialization is cleaner and more readable. However, line 149 (in the moduleImport callback) still uses emplace_back() for imports, creating an inconsistency with the other changes in this PR.

For consistency, consider updating line 149:

-        auto& import = directives[fid].imports.emplace_back();
+        Import import;
         import.location = import_location;
         for(auto name: names) {
             import.name += name.getIdentifierInfo()->getName();
             import.name_locations.emplace_back(name.getLoc());
         }
+        directives[fid].imports.push_back(std::move(import));

Or keep the current style if post-construction mutation is preferred for imports.

Also applies to: 108-108, 167-170, 189-189

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d07bad and 5912501.

📒 Files selected for processing (3)
  • include/Compiler/Directive.h (1 hunks)
  • src/Compiler/Directive.cpp (4 hunks)
  • tests/unit/Compiler/Directive.cpp (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/Compiler/Directive.cpp (3)
src/Feature/FoldingRange.cpp (2)
  • directive (246-252)
  • directive (246-246)
src/Feature/SemanticToken.cpp (4)
  • def (36-48)
  • def (36-38)
  • location (92-115)
  • location (92-92)
src/Compiler/CompilationUnit.cpp (2)
  • directives (313-315)
  • directives (313-313)
🪛 GitHub Actions: format
tests/unit/Compiler/Directive.cpp

[error] 1-1: Trailing whitespace check failed. Files were modified by this hook during pre-commit run (hook: trailing-whitespace). Re-run pre-commit to apply fixes.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: build (windows-2025, releasedbg)
  • GitHub Check: build (ubuntu-24.04, debug)
  • GitHub Check: build (ubuntu-24.04, releasedbg)
  • GitHub Check: build (ubuntu-24.04, Debug, clang-20, clang++-20)
  • GitHub Check: build (windows-2025, RelWithDebInfo, clang, clang++)
  • GitHub Check: build (macos-15, Debug, clang, clang++)
🔇 Additional comments (8)
include/Compiler/Directive.h (3)

130-145: LGTM! Well-designed structure following existing patterns.

The Embed struct follows the same design pattern as Include and HasInclude, with appropriate fields for tracking embed directives. The TODO comment noting that parameters aren't stored yet is reasonable for future enhancement.


147-159: LGTM! Consistent design with Embed.

The HasEmbed struct appropriately mirrors the Embed struct with the key difference being the location semantics (tracking __has_embed token vs # token).


168-169: LGTM! Appropriate additions to Directive.

The new embeds and has_embeds vectors follow the established pattern of the existing directive collections.

tests/unit/Compiler/Directive.cpp (3)

14-15: LGTM! Test vectors properly integrated.

The new embeds and has_embeds vectors are correctly added to the test suite and populated from the directives, following the existing pattern.

Also applies to: 29-30


58-75: LGTM! Well-designed test helpers.

The expect_embed and expect_has_embed helpers properly verify location offsets, file metadata, and filenames. The optional exists parameter in expect_has_embed is appropriate for testing non-existent files.


190-207: LGTM! Comprehensive test coverage.

The HasEmbed test properly validates both existing and non-existing file scenarios, correctly expecting __has_embed to be called in both cases with appropriate exists flag verification.

src/Compiler/Directive.cpp (2)

80-91: LGTM! Proper implementation of embed directive tracking.

The EmbedDirective callback correctly captures embed metadata. The unused Params parameter is intentional per the TODO comment in the header file.


68-78: Clarify the intended C++ standard for #embed support.

The web search reveals an important distinction: #embed is a C23 feature, not C++23, and Clang's experimental #embed support was added for C then reverted. Using the -std=c++23 flag alone will not enable #embed by default—it is a C23 feature and proposed for C++26/C++2c.

Verify:

  • What compiler flags are actually used when testing this code
  • Whether experimental #embed support needs to be explicitly enabled
  • If the code is intended to work with C++23 specifically or if it's preparatory for future standards

Without knowing the actual test configuration, it's unclear whether the HasEmbed callback will be invoked.

Comment on lines 150 to 188
test("Embed") = [&] {
run(R"cpp(
#[bytes10.bin]
0123456789
#[bytes5.bin]
ABCDE
#[main.cpp]
const char e0 = {
$(0)#embed "bytes10.bin"
};
const char e1 = {
$(1)#embed "bytes10.bin"
};
const char e2 = {
$(2)#embed "bytes5.bin"
};
const char e3 = {
$(3)#embed "bytes5.bin"
};
const char e4 = {
$(4)#embed "non-existed.bin"
};
)cpp");

// e4 will not be processed by clang::PPCallbacks::EmbedDirective(), so there is only 4
// embeds.
expect(that % embeds.size() == 4);
expect_embed(0, "0", "bytes10.bin");
expect_embed(1, "1", "bytes10.bin");
expect_embed(2, "2", "bytes5.bin");
expect_embed(3, "3", "bytes5.bin");
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix trailing whitespace on line 176.

The test logic is sound and correctly expects 4 embeds (excluding the non-existent file), but line 176 has trailing whitespace that's causing the pipeline failure.

Apply this diff to fix:

-$(4)#embed "non-existed.bin" 
+$(4)#embed "non-existed.bin"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
test("Embed") = [&] {
run(R"cpp(
#[bytes10.bin]
0123456789
#[bytes5.bin]
ABCDE
#[main.cpp]
const char e0 = {
$(0)#embed "bytes10.bin"
};
const char e1 = {
$(1)#embed "bytes10.bin"
};
const char e2 = {
$(2)#embed "bytes5.bin"
};
const char e3 = {
$(3)#embed "bytes5.bin"
};
const char e4 = {
$(4)#embed "non-existed.bin"
};
)cpp");
// e4 will not be processed by clang::PPCallbacks::EmbedDirective(), so there is only 4
// embeds.
expect(that % embeds.size() == 4);
expect_embed(0, "0", "bytes10.bin");
expect_embed(1, "1", "bytes10.bin");
expect_embed(2, "2", "bytes5.bin");
expect_embed(3, "3", "bytes5.bin");
};
test("Embed") = [&] {
run(R"cpp(
#[bytes10.bin]
0123456789
#[bytes5.bin]
ABCDE
#[main.cpp]
const char e0 = {
$(0)#embed "bytes10.bin"
};
const char e1 = {
$(1)#embed "bytes10.bin"
};
const char e2 = {
$(2)#embed "bytes5.bin"
};
const char e3 = {
$(3)#embed "bytes5.bin"
};
const char e4 = {
$(4)#embed "non-existed.bin"
};
)cpp");
// e4 will not be processed by clang::PPCallbacks::EmbedDirective(), so there is only 4
// embeds.
expect(that % embeds.size() == 4);
expect_embed(0, "0", "bytes10.bin");
expect_embed(1, "1", "bytes10.bin");
expect_embed(2, "2", "bytes5.bin");
expect_embed(3, "3", "bytes5.bin");
};
🤖 Prompt for AI Agents
In tests/unit/Compiler/Directive.cpp around lines 150 to 188, there is trailing
whitespace on line 176 causing the pipeline failure; remove the trailing spaces
at the end of line 176 so the file has no trailing whitespace on that line
(ensure line ends immediately after the last character), then save and run
tests.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
tests/unit/Compiler/Directive.cpp (1)

150-188: Verify that the trailing whitespace issue from the previous review is resolved.

The test logic is sound and correctly expects 4 embeds (since the non-existent file in e4 won't trigger the callback). However, a previous review flagged trailing whitespace on line 176 that was causing a pipeline failure.

Please confirm that the trailing whitespace has been removed from line 176.

🧹 Nitpick comments (1)
src/Compiler/Directive.cpp (1)

80-91: Consider documenting the unused Params parameter.

The callback correctly records embed metadata. However, the Params parameter (which contains embed directive parameters like limit, offset, etc.) is currently unused. If this is intentional for the initial implementation, consider adding a comment to clarify whether these parameters might be used in future enhancements.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5912501 and 89693c3.

📒 Files selected for processing (3)
  • include/Compiler/Directive.h (1 hunks)
  • src/Compiler/Directive.cpp (4 hunks)
  • tests/unit/Compiler/Directive.cpp (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • include/Compiler/Directive.h
🧰 Additional context used
🧬 Code graph analysis (1)
src/Compiler/Directive.cpp (2)
src/Feature/FoldingRange.cpp (2)
  • directive (246-252)
  • directive (246-246)
src/Compiler/CompilationUnit.cpp (2)
  • directives (313-315)
  • directives (313-313)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: build (windows-2025, RelWithDebInfo, clang, clang++)
  • GitHub Check: build (windows-2025, releasedbg)
  • GitHub Check: build (ubuntu-24.04, Debug, clang-20, clang++-20)
  • GitHub Check: build (ubuntu-24.04, debug)
  • GitHub Check: build (ubuntu-24.04, releasedbg)
🔇 Additional comments (5)
tests/unit/Compiler/Directive.cpp (3)

14-15: LGTM! Clean test infrastructure for embeds.

The new vectors follow the established pattern for includes and other directives.

Also applies to: 29-30


58-75: LGTM! Validation helpers follow existing patterns.

The expect_embed and expect_has_embed functions correctly validate location offsets and file metadata, consistent with the existing expect_include and expect_has_inl helpers.


190-207: LGTM! HasEmbed test correctly validates both existing and non-existent files.

The test properly validates the __has_embed directive with both positive (existing file) and negative (non-existent file) cases.

src/Compiler/Directive.cpp (2)

68-78: LGTM! HasEmbed callback correctly records embed metadata.

The implementation follows the same pattern as the HasInclude callback and properly captures all necessary metadata.


60-60: Minor stylistic refactor: emplace_back → push_back.

The changes from emplace_back(Type{...}) to push_back({...}) are stylistically cleaner and equally performant with modern C++ compilers. While unrelated to the embed feature, this is a reasonable code cleanup included in the PR.

Also applies to: 108-108, 167-170, 189-193

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.

1 participant