Atlas locates where a behavior is implemented in a C++ codebase by attacking the problem from three angles at once. codebase_search queries a semantic index for meaning, so you can describe what the software does without knowing what the code is called. grep runs a real regex through ripgrep with include and path filters, which is how you separate a declaration in a header from its definition in a translation unit. The lsp tool's findReferences and workspaceSymbol operations walk the symbol graph across your CMake targets. Atlas ships all three because in C++ they answer genuinely different questions.
How do you find where a behavior is implemented in a large C++ codebase?
Describe the behavior to codebase_search. Atlas's semantic index returns candidate declarations even when your words never appear in the source, which is the normal case in C++ where the function that throttles reconnects is called ScheduleBackoff and lives in a .cpp file 3 CMake targets away from where you looked.
C++ codebases defeat naive search in specific ways. The name you would search for does not exist, because the domain concept was abstracted away behind a template or a policy class. The symbol is split: declared in include/net/session.h, defined in src/net/session.cpp, and possibly specialized in a third translation unit. Behavior is dispatched virtually, so the call site names the base class and the code that actually runs is an override in a derived type you have never heard of. Atlas's codebase_search handles the first problem because it indexes meaning, not identifiers, and because Atlas indexes code by AST declarations using tree-sitter rather than blind line windows, the hits it returns are real C++ declarations with file paths and not arbitrary 40-line chunks that straddle a function boundary.
How does grep help when searching a C++ project with headers and translation units?
Atlas's grep tool takes a real regex plus 2 filter types, include and path, and runs it through ripgrep. Filter to headers to find the declaration, filter to translation units to find the definition, and filter to a CMake target's directory to stop a match in a vendored vcpkg dependency from drowning the result.
Semantic search finds the concept; grep pins the symbol. In a C++ repository the difference between those two searches is the whole day. Once codebase_search suggests that ScheduleBackoff is the function you want, grep answers the follow-up questions precisely: where is it declared, where is it defined, who calls it, and does a macro in a config header conditionally compile it out. Include filters restricted to .h and .hpp separate the declarations from the definitions in .cpp files. Path filters keep third-party code pulled in through vcpkg out of the results, which matters because a vendored library will happily contain a hundred functions with the same generic name. Because grep runs through ripgrep, the search across a large tree with a build directory in it stays fast.
What does the lsp tool add over grep in a C++ codebase?
The lsp tool gives Atlas the C++ symbol graph, which grep cannot compute. 2 operations matter most: findReferences returns every callsite of ScheduleBackoff, including calls made through a base-class pointer that no text search would connect, and workspaceSymbol jumps straight to a declaration by name across every CMake target in the project.
Virtual dispatch, overloads, and templates are where text search runs out of road in C++. A text search for ScheduleBackoff finds the calls that spell it; it does not find the call through an ISessionPolicy pointer that resolves to your override at runtime, and it cannot distinguish two overloads with different signatures. The language server can, because it has actually parsed the translation units against the compilation database CMake generates. Atlas's lsp tool exposes that: findReferences to enumerate every callsite before you change a signature, workspaceSymbol to reach a declaration by name without knowing its header. Combined with codebase_search for meaning and grep for exact text, the three tools cover the three distinct questions a C++ developer asks when hunting a behavior, and that is precisely why Atlas ships all three rather than one fuzzy search box.
What happens when Atlas guesses the wrong C++ file path?
Atlas's read tool fails loudly on a bad path. 1 wrong guess returns File not found plus a Did you mean list, so a hallucinated include/net/sesssion.h is caught immediately rather than becoming a silent empty read that the model then reasons over as if the file were empty.
Silent failure is the quiet killer of agent code search, and C++ path structures invite it. Header directories mirror source directories but not exactly. A public include/ tree shadows a private src/ tree with similarly named files. A generated header exists only after a CMake configure step, so it is present in the build tree and absent from the source tree. An agent that reads a nonexistent path and gets back nothing may conclude the file is empty or that the symbol does not exist, and then confidently tell you the behavior is not implemented anywhere. Atlas's read tool refuses that outcome. File not found is an error, and the Did you mean list points at the paths that actually exist, which usually corrects a header versus translation unit mixup on the spot.
How does Atlas report where a C++ behavior lives?
Atlas summarizes the call path back to you with concrete file and line references, for example include/net/session.h declaring the virtual, src/net/tcp_session.cpp overriding it, and 3 callers in src/net/pool.cpp. Concrete references are checkable in a way that a prose summary of a C++ architecture never is.
The deliverable of a search session is a map you can act on, not a paragraph. Atlas gives file and line references for the declaration, the definition, and the callsites, so the next step, whether that is a change, a clang-format pass, or a new GoogleTest case, starts from a known location. Nothing in the search phase modifies your repository: codebase_search, grep, read, and the lsp tool are all read operations, and every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs anyway. When you do move to changing the behavior you found, Atlas computes a unified diff for every file edit and surfaces it for approval before writing, and the verification loop is the ordinary C++ one. Build the CMake target, run GoogleTest via ctest, and apply clang-format to the files you touched.
Step by step
- 01Start atlas in the project root, the directory that holds CMakeLists.txt, so the index covers your headers, translation units, and build targets.
- 02Describe the behavior in plain language to codebase_search; the semantic index returns candidate C++ declarations even when your words do not appear in the source.
- 03Confirm the symbol with grep, using an include filter for .h and .hpp to find the declaration and a second pass over .cpp files to find the definition.
- 04Add a path filter to grep so matches inside vendored vcpkg dependencies and the build directory do not drown the results.
- 05Open the best candidate with read; a wrong path fails loudly with File not found plus a Did you mean list, so a mistyped header is caught immediately.
- 06Run the lsp tool's findReferences operation to enumerate every callsite, including calls made through a base-class pointer that no text search would connect.
- 07Use the lsp tool's workspaceSymbol operation to jump to a declaration by name across CMake targets when you know the symbol but not the header.
- 08Have Atlas summarize the call path with concrete file and line references, then verify any change you make with GoogleTest via ctest and format it with clang-format.
Frequently asked questions
- How do I find which C++ file implements a behavior when I do not know the function name?
- Describe the behavior to Atlas's codebase_search. The semantic index returns candidate declarations even when your words never appear in the source, then grep confirms the exact symbol across headers and translation units and the lsp tool walks the callsites.
- Can an AI agent find every caller of a C++ virtual function?
- Yes, through the language server. Atlas's lsp tool exposes findReferences, which enumerates every callsite including calls made through a base-class pointer. A text search would only find the calls that literally spell the function name.
- How does Atlas search a C++ repo without matching vendored dependencies?
- Atlas's grep tool takes a real regex plus include and path filters and runs through ripgrep. Filter by path to exclude vcpkg-vendored code and the build directory, and by extension to search only .h and .hpp or only .cpp files.
- What happens if Atlas reads a C++ header path that does not exist?
- The read tool fails loudly. A wrong path returns File not found plus a Did you mean list, so a mistyped include/net/session.h is corrected immediately rather than being treated as an empty file the model then reasons over.
- Does Atlas understand the difference between a C++ declaration and a definition?
- Atlas indexes code by AST declarations using tree-sitter, not blind line windows, so a hit in include/net/session.h is a declaration and a hit in src/net/session.cpp is a definition. Grep's include filters let you target either one deliberately.
- Can Atlas change the C++ code once it finds the behavior?
- Yes, but not silently. codebase_search, grep, read, and the lsp tool are read operations, and any edit is permission-gated with a unified diff surfaced for approval before writing. Verify the change with GoogleTest via ctest and format it with clang-format.
- Can Atlas index a C++ codebase without sending it to a third-party server?
- Yes. Atlas can build its code index with local Ollama embeddings, keeping code off third-party servers, and codebase_search, grep, and the lsp tool all work the same way against a locally embedded CMake project.
Try Atlas in your terminal
The terminal-native AI coding agent. Free core, single binary.
Install AtlasRelated guides
Locate Where a Behavior Is Implemented with Atlas in 2026
How to locate where a behavior is implemented with Atlas in 2026: codebase_search for meaning, grep for exact text, and the lsp tool for the symbol graph.
Atlas for C++ in 2026
In 2026, C++ developers adopt Atlas, the terminal-native AI coding agent, to enhance productivity. Atlas offers secure, context-aware assistance for modern C++ projects, integrating with CMake and ensuring code quality
Debug a single failing test in C++ with Atlas (2026)
Debug one failing GoogleTest case in C++ with Atlas in 2026: run it isolated through ctest, walk the call path with lsp, and fix the code rather than the assertion.
Audit a repo with parallel subagents in C++ with Atlas (2026)
Sweep a whole C++ repo for one class of defect in 2026 without blowing your context window. Atlas fans out read-only explore subagents across CMake targets and headers.
Plan a Multi-File Change Before Editing in C++ with Atlas (2026)
Design a C++ change across headers and translation units in 2026 before one line moves: Atlas plan mode denies every edit tool until you approve the plan and switch to build.
Run Atlas Headless in CI for C++ Projects in 2026
In 2026, C++ developers can run Atlas headless in CI pipelines to automate code tasks. Get machine-readable output, integrate with vcpkg and GoogleTest via ctest, and ensure safety.
Rename a symbol across the repo in C++ with Atlas (2026)
How Atlas renames a symbol across a C++ repo in 2026: lsp findReferences for the true reference set, grep for strings and docs, and edit that refuses ambiguous matches.
Refactor a Legacy Module in C++ with Atlas (2026)
How to refactor a legacy C++ module with Atlas in 2026: enumerate callsites with the lsp tool, restructure with apply_patch, and prove behavior with GoogleTest via ctest.