feat(callgraph): C/C++ explicit type inference engines#673
Merged
shivasurya merged 1 commit intomainfrom May 3, 2026
Merged
Conversation
SafeDep Report SummaryNo dependency changes detected. Nothing to scan. This report is generated by SafeDep Github App |
Code Pathfinder Security ScanNo security issues detected.
Powered by Code Pathfinder |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #673 +/- ##
==========================================
+ Coverage 85.18% 85.26% +0.07%
==========================================
Files 180 182 +2
Lines 26237 26399 +162
==========================================
+ Hits 22351 22508 +157
- Misses 3024 3028 +4
- Partials 862 863 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This was referenced May 2, 2026
Owner
Author
This was referenced May 3, 2026
Owner
Author
Merge activity
|
Add CTypeInferenceEngine and CppTypeInferenceEngine under the
resolution package. The engines index types that appear verbatim in
C/C++ source — function return types, variable declarations, class
method return types, and class field types — with Confidence=1.0 and
Source="declaration". No inference, deduction, or propagation; later
phases layer those on top.
Highlights:
- Function-scoped variable bindings track reassignment history; the
latest binding wins on lookup.
- C++ engine embeds the C engine by value so callers can use
ExtractReturnType / GetScope / GetVariable uniformly.
- C++ `auto` is recognised by exact match and stored with
Confidence=0.0, Source="unresolved_auto" so resolvers skip it
until Phase 2 deduces a concrete type.
- Thread-safe via two RWMutex pairs on the C engine and two
additional pairs for class-method and class-field maps; verified
under `go test -race`.
Sets up the typed receiver lookups consumed by PR-07 (C call graph)
and PR-08 (C++ call graph).
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
47d63d3 to
1fc411c
Compare
shivasurya
added a commit
that referenced
this pull request
May 3, 2026
## Summary
Adds `BuildCCallGraph` — a four-pass algorithm that produces a `*core.CallGraph` for C projects, ready to merge into the unified graph alongside Python/Go.
| Pass | Purpose |
|---|---|
| 1 | Index every C `function_definition` under `\"<relpath>::<name>\"` and ensure the FQN is also in `registry.FunctionIndex` |
| 2 | Register explicit return types (skipping `void`) and emit `ParameterSymbol` entries for every named parameter |
| 3 | Walk parser-emitted edges (`function_definition → call_expression`) to extract one `CallSiteInternal` per call — no second AST traversal |
| 4 | Resolve targets in a definition-preferring order, then emit edges and `CallSite` records |
### Resolution order (Pass 4)
1. **Same-file definition** — common case (helper in same `.c`); deterministic and independent of include state.
2. **Global definition** — scan `registry.FunctionIndex[name]` for an FQN whose call-graph entry is a definition. Handles cross-`.c` calls.
3. **Same-file declaration** — accept a forward declaration when no definition exists project-wide.
4. **Declaration reachable through `#include`** — last resort so externs handed off to another translation unit still surface as edges.
Calls that don't match any source produce a `CallSite{Resolved: false, FailureReason: \"external_or_unresolved\"}` — stdlib calls (`printf`, `malloc`) and unknown function pointers remain visible to rule writers without polluting the edge set.
### Design notes
- **Edges from the parser**: every `parseCCallExpression` adds an edge from the enclosing function to the call node. The builder walks `OutgoingEdges` of each indexed function instead of doing byte-range containment, keeping Pass 3 deterministic and trivially testable.
- **Definition vs declaration**: the parser sets `Metadata[\"is_declaration\"]=true` on prototype/extern decls. `isDeclaration()` reads that key with a typed assertion so non-declaration nodes (no metadata) fall through correctly.
- **Recursion**: self-edges (`process → process`) are emitted as-is; the call graph already deduplicates via `AddEdge`.
- **Static functions**: same FQN-by-file mechanism — file-scope statics in different `.c` files map to disjoint FQNs.
- **Unique FunctionIndex entries**: Pass 1 dedupes against the registry's existing `FunctionIndex` so calling `BuildCCallGraph` after `BuildCModuleRegistry` is idempotent.
## Test plan
- [x] `go build ./...`
- [x] `go test ./...` — full suite green
- [x] `go vet ./...`
- [x] `golangci-lint run ./graph/callgraph/builder/` — 0 issues
- [x] Coverage on `c_builder.go` lines: ~89.6%
- [x] Spec scenarios covered:
- Single-file `main()` → `add()` edge
- Cross-file `.c` definition preferred over `.h` declaration
- Header declaration via `#include` fallback
- `printf` (stdlib) recorded as `Resolved:false` with failure reason
- Recursive self-call
- Same name in two `.c` files (file-scope statics)
- Type engine populated; `void` returns dropped
- Parameters indexed (anonymous params skipped)
- Declarations skipped from Pass 2 type extraction
- Merges cleanly into an empty unified graph
- Non-C nodes ignored (mixed-language safety)
- Anonymous / missing-file functions filtered
- Empty-target call_expression produces no edge and no recorded site
- Cross-`.c` global lookup works without an `#include`
- Same-file forward declaration accepted when no definition exists
## Stacked on
`shiva/cpp-type-inference` (#673)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Summary
Adds the explicit type-tracking foundation for C/C++ call-graph resolution.
graph/callgraph/resolution/c_types.go—CTypeInferenceEngine,CFunctionScope,CVariableBinding. Tracks return types and per-function variable scopes drawn directly from source declarations.graph/callgraph/resolution/cpp_types.go—CppTypeInferenceEngineembeds the C engine and adds class method / class field indices, plusautohandling.TypeInfo contract
declarationunresolved_autoauto x = ...placeholders awaiting Phase 2 deductionDesign notes
CppTypeInferenceEngineembedsCTypeInferenceEngineby value, so every C-engine method (ExtractReturnType,GetScope,GetVariable, etc.) is callable on the C++ engine. The embeddedRegistryfield aliases the C++ registry'sCModuleRegistryfacet so updates propagate.GetVariablereturns the latest.GetAllBindingsexposes the history for future flow analysis.autodetection: exact equality on\"auto\". Modifiers likeauto*andauto&are concrete types and keep full confidence — they survive the override branch and route through the C engine unchanged.GetReturnType != nil).sync.RWMutexinstances guardScopes,ReturnTypes,ClassMethods,ClassFields. Snapshot accessors (GetAllReturnTypes,GetAllScopes) return defensive copies.ExtractVariableTypecreates the scope on first use; callers do not need to callAddScopebefore the first variable.Test plan
go build ./...go test ./...— full suite green (25 packages)go test -race ./graph/callgraph/resolution/...— cleango vet ./...golangci-lint run ./graph/callgraph/resolution/— 0 issuesc_types.go100%,cpp_types.go100%autozero-confidence,auto*/auto&exact-match, complex C types (pointer/const/struct), complex C++ types (templates / refs / nested templates).Stacked on
shiva/cpp-module-registry(#672)