Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,49 +47,59 @@ C/C++ Pro combines the blazing index and AST completion speed of LLVM's **`clang
- **Boost C++ Libraries** (`C:\local\boost_*`, `/usr/include/boost`)
- **SDL2 / SDL3**
- **vcpkg** and **Node-API** (`node-addon-api`, `nan`) includes
- Detailed documentation: [Compiler & Toolchain Setup Wiki](https://github.com/CinderLuna/c-cpp-pro/wiki/Compiler-Toolchain-Setup).

### 3. Visual Studio Solution & Project Integration
- **Solution Formats**: First-class support for traditional `.sln` and the modern XML-based `.slnx` solution formats.
- **Project Parsing**: Extracts include directories, preprocessor definitions, language standards, and forced includes from `.vcxproj` files across all configurations (Debug/Release, x64/x86/ARM64).
- **Compilation Database Generation**: Generates a unified `compile_commands.json` covering all C++ source files in the active solution.
- **MSBuild Task Provider**: Generates build, rebuild, clean, and per-project tasks automatically accessible via VS Code's Task runner.
- Detailed documentation: [Visual Studio Solution Support Wiki](https://github.com/CinderLuna/c-cpp-pro/wiki/Visual-Studio-Solution-Support).

### 4. Integrated DAP Debugging & Run Controller
### 4. Static CMake Intelligence
- **In-Memory CMake Parsing**: Tokenizes and parses `CMakeLists.txt` files and `.cmake` modules statically without invoking CMake CLI binaries.
- **Transitive Include Resolution**: Models `target_include_directories`, `target_compile_definitions`, and `target_link_libraries` transitive property propagation.
- **Compilation Database Generation**: Synthesizes `compile_commands.json` on-demand with isolated target private includes and per-file C/C++ language standards.
- Detailed documentation: [Static CMake Integration Wiki](https://github.com/CinderLuna/c-cpp-pro/wiki/Static-CMake-Integration).

### 5. Integrated DAP Debugging & Run Controller
- **Zero-Setup Debugging**: Seamlessly hooks into `lldb-dap`, GDB (`--interpreter=dap`), or MSVC for native C/C++ debugging.
- **Automatic Launch Generation**: Pre-configured launch configurations with dynamic workspace variable resolution (`${fileBasenameNoExtension}`, `${workspaceFolder}`).
- **Interactive Process Picker**: Select running processes to attach with cross-platform PID and name resolution.
- **Evaluatable Expression Provider**: Evaluate nested member accesses (`a->b.c`), indexed arrays (`arr[i]`), and pointers when hovering during debug breaks.
- **Run & Debug Editor Title Actions**: One-click play and debug buttons in the editor title bar with automated Visual Studio Developer Shell (`vcvarsall`) environment injection on Windows.
- Detailed documentation: [Debugging Guide Wiki](https://github.com/CinderLuna/c-cpp-pro/wiki/Debugging-Guide).

### 5. Type & Memory Layout Inspector
### 6. Type & Memory Layout Inspector
- Inspect struct and class memory layouts directly inside the editor (`c-cpp-pro.inspectMemoryLayout`).
- Visualize field byte offsets, member sizes, struct alignment, and wasted memory from padding holes.
- Visual indicators for 64-byte CPU cache line boundaries to optimize data structures for cache locality.
- Detailed documentation: [Memory Layout Inspector Wiki](https://github.com/CinderLuna/c-cpp-pro/wiki/Memory-Layout-Inspector).

### 6. Include Tree & Build Bottleneck Visualizer
### 7. Include Tree & Build Bottleneck Visualizer
- **Header Dependency Hierarchy**: Analyze `#include` trees, detect circular inclusion cycles, and receive optimization tips for heavy headers (`c-cpp-pro.analyzeIncludes`).
- **Clang `-ftime-trace` Profiling**: Inspect Chrome tracing JSON files to pinpoint slow template instantiations and expensive header parse times (`c-cpp-pro.visualizeTimeTrace`).

### 7. Modern C++ Test Explorer
### 8. Modern C++ Test Explorer
- Native VS Code Test Explorer integration for modern C++ testing frameworks.
- Automatically discovers tests, suites, and scenarios for:
- **GoogleTest** (`TEST`, `TEST_F`, `TEST_P`)
- **Catch2** (`TEST_CASE`, `SCENARIO`)
- **doctest** (`TEST_CASE`)
- **Boost.Test** (`BOOST_AUTO_TEST_CASE`)

### 8. Macro Expansion & Compile-Time Evaluation
### 9. Macro Expansion & Compile-Time Evaluation
- **Step-by-Step Macro Expansion**: Preview complex object-like and function-like macro expansions directly at cursor position (`c-cpp-pro.expandMacro`).
- **`constexpr` Evaluation**: Preview compile-time evaluations and constant folding results (`c-cpp-pro.evaluateConstexpr`).

### 9. Inline Disassembly & Compiler Explorer
### 10. Inline Disassembly & Compiler Explorer
- Open inline assembly output alongside your C++ code (`c-cpp-pro.viewDisassembly`).
- Filter compiler directives, labels, and comments with customizable optimization flags (`-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz`).

### 10. Semantic Symbol Hierarchy Graphs
### 11. Semantic Symbol Hierarchy Graphs
- Generate Mermaid diagrams visualizing class inheritance and symbol relationships (`c-cpp-pro.showTypeHierarchy`).

### 11. Configuration Editor & Multi-Target Profiles
### 12. Configuration Editor & Multi-Target Profiles
- Modern graphical Webview editor (`c-cpp-pro.openSettings`) to configure include paths, preprocessor defines, compiler paths, and C/C++ language standards.
- Supports `.vscode/c_cpp_properties.json` and Linux/RTOS Kconfig (`.config`) files.
- Visual Studio Developer Environment switcher (`c-cpp-pro.setVsDeveloperEnvironment`) to quickly initialize compiler environments.
Expand Down
2 changes: 1 addition & 1 deletion crates/c-cpp-pro-native/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "c-cpp-pro-native"
version = "0.4.0"
version = "0.4.2"
edition = "2021"

[lib]
Expand Down
84 changes: 34 additions & 50 deletions crates/c-cpp-pro-native/src/cmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ pub fn parse_cmake_file_internal(

for cmd in commands {
match cmd.name.as_str() {
"set" => {
if cmd.args.len() >= 2 {
"set"
if cmd.args.len() >= 2 => {
let var_name = cmd.args[0].clone();
let val_joined = cmd.args[1..].join(" ");
let resolved_val = resolve_variables(&val_joined, &variables);
Expand All @@ -309,37 +309,34 @@ pub fn parse_cmake_file_internal(
}
}
}
}
"include_directories" => {
for arg in &cmd.args {
add_include(arg, &variables, &current_dir, None, &mut result);
}
}
"target_include_directories" => {
if cmd.args.len() >= 2 {
"target_include_directories"
if cmd.args.len() >= 2 => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "custom", &mut result.targets);
for arg in &cmd.args[1..] {
add_include(arg, &variables, &current_dir, Some(target_idx), &mut result);
}
}
}
"add_definitions" => {
for arg in &cmd.args {
add_define(arg, &variables, None, &mut result);
}
}
"target_compile_definitions" => {
if cmd.args.len() >= 2 {
"target_compile_definitions"
if cmd.args.len() >= 2 => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "custom", &mut result.targets);
for arg in &cmd.args[1..] {
add_define(arg, &variables, Some(target_idx), &mut result);
}
}
}
"add_executable" => {
if !cmd.args.is_empty() {
"add_executable"
if !cmd.args.is_empty() => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "executable", &mut result.targets);
result.targets[target_idx].target_type = "executable".to_string();
Expand All @@ -363,9 +360,8 @@ pub fn parse_cmake_file_internal(
}
}
}
}
"add_library" => {
if !cmd.args.is_empty() {
"add_library"
if !cmd.args.is_empty() => {
let target_name = &cmd.args[0];
let mut target_type = "library".to_string();
let mut src_start = 1;
Expand Down Expand Up @@ -415,9 +411,8 @@ pub fn parse_cmake_file_internal(
}
}
}
}
"target_sources" => {
if cmd.args.len() >= 2 {
"target_sources"
if cmd.args.len() >= 2 => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "custom", &mut result.targets);
for s in &cmd.args[1..] {
Expand All @@ -430,9 +425,8 @@ pub fn parse_cmake_file_internal(
result.targets[target_idx].source_files.push(full);
}
}
}
"target_link_libraries" => {
if cmd.args.len() >= 2 {
"target_link_libraries"
if cmd.args.len() >= 2 => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "custom", &mut result.targets);
for arg in &cmd.args[1..] {
Expand All @@ -459,9 +453,8 @@ pub fn parse_cmake_file_internal(
}
}
}
}
"add_subdirectory" => {
if !cmd.args.is_empty() {
"add_subdirectory"
if !cmd.args.is_empty() => {
let sub_name = resolve_variables(&cmd.args[0], &variables);
result.subdirectories.push(sub_name.clone());

Expand Down Expand Up @@ -527,9 +520,8 @@ pub fn parse_cmake_file_internal(
}
}
}
}
"include" => {
if !cmd.args.is_empty() {
"include"
if !cmd.args.is_empty() => {
let file_arg = resolve_variables(&cmd.args[0], &variables);
let candidates = vec![
resolve_path(&current_dir, &file_arg),
Expand Down Expand Up @@ -565,7 +557,6 @@ pub fn parse_cmake_file_internal(
}
}
}
}
_ => {}
}
}
Expand All @@ -580,7 +571,7 @@ pub fn parse_cmake_file_internal(
}

pub fn resolve_linked_target_properties(
targets: &mut Vec<CMakeTargetInfoNative>,
targets: &mut [CMakeTargetInfoNative],
global_includes: &mut Vec<String>,
global_defs: &mut Vec<String>,
) {
Expand All @@ -596,7 +587,7 @@ pub fn resolve_linked_target_properties(
None => continue,
};
for dep_name in deps {
if let Some(dep_idx) = targets.iter().position(|t| &t.name == &dep_name) {
if let Some(dep_idx) = targets.iter().position(|t| t.name == dep_name) {
let dep_incs = targets[dep_idx].include_directories.clone();
let dep_defs = targets[dep_idx].compile_definitions.clone();

Expand Down Expand Up @@ -748,8 +739,8 @@ pub fn parse_cmake_content_native(

for cmd in commands {
match cmd.name.as_str() {
"set" => {
if cmd.args.len() >= 2 {
"set"
if cmd.args.len() >= 2 => {
let var_name = cmd.args[0].clone();
let val_joined = cmd.args[1..].join(" ");
let resolved_val = resolve_variables(&val_joined, &variables);
Expand All @@ -767,37 +758,34 @@ pub fn parse_cmake_content_native(
}
}
}
}
"include_directories" => {
for arg in &cmd.args {
add_include(arg, &variables, &current_dir, None, &mut result);
}
}
"target_include_directories" => {
if cmd.args.len() >= 2 {
"target_include_directories"
if cmd.args.len() >= 2 => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "custom", &mut result.targets);
for arg in &cmd.args[1..] {
add_include(arg, &variables, &current_dir, Some(target_idx), &mut result);
}
}
}
"add_definitions" => {
for arg in &cmd.args {
add_define(arg, &variables, None, &mut result);
}
}
"target_compile_definitions" => {
if cmd.args.len() >= 2 {
"target_compile_definitions"
if cmd.args.len() >= 2 => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "custom", &mut result.targets);
for arg in &cmd.args[1..] {
add_define(arg, &variables, Some(target_idx), &mut result);
}
}
}
"add_executable" => {
if !cmd.args.is_empty() {
"add_executable"
if !cmd.args.is_empty() => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "executable", &mut result.targets);
result.targets[target_idx].target_type = "executable".to_string();
Expand All @@ -821,9 +809,8 @@ pub fn parse_cmake_content_native(
}
}
}
}
"add_library" => {
if !cmd.args.is_empty() {
"add_library"
if !cmd.args.is_empty() => {
let target_name = &cmd.args[0];
let mut target_type = "library".to_string();
let mut src_start = 1;
Expand Down Expand Up @@ -873,9 +860,8 @@ pub fn parse_cmake_content_native(
}
}
}
}
"target_sources" => {
if cmd.args.len() >= 2 {
"target_sources"
if cmd.args.len() >= 2 => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "custom", &mut result.targets);
for s in &cmd.args[1..] {
Expand All @@ -888,9 +874,8 @@ pub fn parse_cmake_content_native(
result.targets[target_idx].source_files.push(full);
}
}
}
"target_link_libraries" => {
if cmd.args.len() >= 2 {
"target_link_libraries"
if cmd.args.len() >= 2 => {
let target_name = &cmd.args[0];
let target_idx = get_or_create_target(target_name, "custom", &mut result.targets);
for arg in &cmd.args[1..] {
Expand All @@ -917,7 +902,6 @@ pub fn parse_cmake_content_native(
}
}
}
}
_ => {}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/c-cpp-pro-native/src/memory_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ pub fn calculate_struct_layout_native(
let is_packed = opts.is_packed.unwrap_or(false);
let pack_max = opts
.max_pack_alignment
.unwrap_or_else(|| if is_packed { 1 } else { 8 });
.unwrap_or(if is_packed { 1 } else { 8 });
let data_model = opts
.data_model
.as_deref()
Expand Down
2 changes: 1 addition & 1 deletion crates/c-cpp-pro-native/src/solution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ pub fn parse_vcxproj_content_native(
continue;
}
if trimmed.starts_with('\"') && trimmed.ends_with('\"') && trimmed.len() >= 2 {
trimmed = &trimmed[1..trimmed.len() - 1].trim();
trimmed = trimmed[1..trimmed.len() - 1].trim();
}
let expanded = trimmed
.replace("$(ProjectDir)", &(normalize_slash(&project_dir) + "/"))
Expand Down
Loading
Loading