### Using AnnotateAttribute with Macros Source: https://github.com/xoofx/cppast.net/blob/main/doc/attributes.md Demonstrates how to use the AnnotateAttribute with macros, specifically by defining a UUID macro and then using it within the __cppast macro. This example shows that macros work well within the meta attribute state, allowing dynamic information injection. ```C++ #if !defined(__cppast) #define __cppast(...) #endif #define UUID() 12345 __cppast(id=UUID(), desc="a function with macro") void TestFunc() { } ``` -------------------------------- ### CMake Project Setup for CppAst.NET Source: https://github.com/xoofx/cppast.net/blob/main/CMakeLists.txt Configures the CMake build system for the CppAst.NET project. It sets the minimum required CMake version, defines the project name and language, and specifies C# compiler flags and .NET target framework. It also includes the source directory. ```cmake cmake_minimum_required(VERSION 3.22) project(CppAst.NET CSharp) set(CMAKE_CSharp_FLAGS "${CMAKE_CSharp_FLAGS} /langversion:latest") set(CMAKE_DOTNET_TARGET_FRAMEWORK net8.0) set(CMAKE_DOTNET_SDK "Microsoft.NET.Sdk") add_subdirectory(src) ``` -------------------------------- ### Configure CppAst for Windows MSVC Source: https://github.com/xoofx/cppast.net/blob/main/doc/readme.md Shows how to configure CppAst to parse Windows headers with MSVC compiler compatibility. This simplifies setup for Windows-specific C++ code. Requires the CppAst library. ```C# var options = new CppParserOptions().ConfigureForWindowsMsvc(); ``` -------------------------------- ### AnnotateAttribute Support for Multiple Attributes Source: https://github.com/xoofx/cppast.net/blob/main/doc/attributes.md Illustrates that CppAst.Net supports multiple attributes on a single object, including the AnnotateAttribute. This example shows how to apply different attributes like 'id', 'name', and 'desc' to a float variable. ```C++ __cppast(id = 1) __cppast(name = "x") __cppast(desc = "?? ?") float x; ``` -------------------------------- ### C++ Class Definition and Reflection Registration Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md Demonstrates a standard C++ class definition and its corresponding manual reflection registration code. This pattern highlights the complexity that automated code generation tools like CppAst.Net aim to solve. ```cpp class Vector3 { public: double x; double y; double z; public: Vector3() : x(0.0), y(0.0), z(0.0) {} Vector3(double _x, double _y, double _z) : x(_x), y(_y), z(_z) {} double DotProduct(const Vector3& vec) const; }; ``` ```cpp __register_type("Vector3") .constructor() .constructor() .property("x", &Vector3::x) .property("y", &Vector3::y) .property("z", &Vector3::z) .function("DotProduct", &Vector3::DotProduct); ; ``` -------------------------------- ### Working with C++ Functions and Methods using CppAst.NET Source: https://context7.com/xoofx/cppast.net/llms.txt Illustrates how to parse and extract information about C++ functions and methods. This includes details about parameters, return types, calling conventions, and various function qualifiers. ```csharp using CppAst; var compilation = CppParser.Parse(@" int add(int a, int b); void processData(const char* data, int length = 0); static inline double calculate(double x, double y); extern "C" void cFunction(); "); foreach (var func in compilation.Functions) { Console.WriteLine($"Function: {func.Name}"); Console.WriteLine($" Return type: {func.ReturnType}"); Console.WriteLine($" Linkage: {func.LinkageKind}"); Console.WriteLine($" Storage: {func.StorageQualifier}"); Console.WriteLine($" Calling convention: {func.CallingConvention}"); // Access parameters Console.WriteLine($" Parameters ({func.Parameters.Count}):"); foreach (var param in func.Parameters) { Console.Write($" {param.Type} {param.Name}"); if (param.InitExpression != null) Console.Write($" = {param.InitExpression}"); Console.WriteLine(); } Console.WriteLine($" Default param count: {func.DefaultParamCount}"); } ``` -------------------------------- ### Parsing C++ Preprocessor Macros Source: https://context7.com/xoofx/cppast.net/llms.txt Demonstrates how to parse preprocessor macros by enabling the ParseMacros option. It retrieves macro parameters, values, and token counts. ```csharp using CppAst; var options = new CppParserOptions { ParseMacros = true }; var compilation = CppParser.Parse(@" #define VERSION 100 #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define DEBUG_LOG(msg) printf(\"DEBUG: %s\n\", msg) #define EMPTY_MACRO ", options); foreach (var macro in compilation.Macros) { Console.WriteLine($"Macro: {macro.Name}"); if (macro.Parameters != null) { Console.WriteLine($" Parameters: ({string.Join(", ", macro.Parameters)})"); } Console.WriteLine($" Value: {macro.Value}"); Console.WriteLine($" Tokens: {macro.Tokens.Count}"); } ``` -------------------------------- ### Configure CppAst Parser Options Source: https://github.com/xoofx/cppast.net/blob/main/doc/readme.md Illustrates how to configure CppAst parser options, such as defining preprocessor macros. This is useful for controlling the parsing behavior based on specific C++ compiler flags. Requires the CppAst library. ```C# var options = new CppParserOptions() { // Pass the defines -DMYDEFINE to the C++ parser Defines = { "MYDEFINE" } }; var compilation = CppParser.ParseFile("...", options); ``` -------------------------------- ### C# .NET Project Configuration for CppAst.Net Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md This XML configuration for a C# .NET project file (`.csproj`) includes the necessary settings to use CppAst.Net. It specifies the target framework, enables the workaround for native DLL resolution using `RuntimeIdentifier`, and adds the CppAst NuGet package dependency. ```xml Exe netcoreapp3.1 $(NETCoreSdkRuntimeIdentifier) ``` -------------------------------- ### AttributeKind.CxxSystemAttribute Implementation Source: https://github.com/xoofx/cppast.net/blob/main/doc/attributes.md Demonstrates the implementation of a function to handle system and annotate attributes using ClangSharp. It shows how to parse various attributes directly from the cursor's AST. ```APIDOC ## Private Method ParseSystemAndAnnotateAttributeInCursor ### Description This method handles various attributes that ClangSharp supports, including system attributes like `visibility` and `aligned`, as well as `AnnotateAttr`. It efficiently parses these attributes directly from the libclang AST, avoiding costly token-level parsing. ### Method ```cs private List ParseSystemAndAnnotateAttributeInCursor(CXCursor cursor) ``` ### Parameters * **cursor** (CXCursor) - The current cursor being visited. ### Request Body *None* ### Response * **List** - A list of parsed C++ attributes. ### Response Example ```cs // Example usage within a visitor pattern: customer.VisitChildren((argCursor, parentCursor, clientData) => { // ... attribute parsing logic ... return CXChildVisitResult.CXChildVisit_Continue; }, new CXClientData((IntPtr)0)); ``` ### Notes This method leverages `ClangSharp`'s ability to access `libclang`'s Abstract Syntax Tree (AST), providing high performance for attribute parsing. The `AnnotateAttr` is highlighted as a key component for high-performance meta attribute usage. ``` -------------------------------- ### Search C++ Elements by Name Source: https://context7.com/xoofx/cppast.net/llms.txt Demonstrates how to locate C++ classes, functions, and namespaces within a parsed compilation using simple names, fully qualified names, or specific container scopes. ```csharp using CppAst; var compilation = CppParser.Parse(@" namespace math { struct Vector3 { float x, y, z; }; float dot(Vector3 a, Vector3 b); } struct Point { int x; int y; }; void globalFunction(); "); var point = compilation.FindByName("Point"); var vector3 = compilation.FindByFullName("math::Vector3"); var dotFunc = compilation.FindByFullName("math::dot"); var mathNs = compilation.FindByName("math"); var vecInMath = compilation.FindByName(mathNs, "Vector3"); var overloads = compilation.FindListByName(compilation, "globalFunction"); ``` -------------------------------- ### Configure Parser Behavior with CppParserOptions Source: https://context7.com/xoofx/cppast.net/llms.txt Allows configuration of CppAst.NET's parsing behavior through the CppParserOptions class. Options include setting preprocessor defines, include paths, target platform, and toggling features like macro and comment parsing. This enables fine-grained control over how C/C++ code is processed. ```csharp using CppAst; // Create parser options with custom configuration var options = new CppParserOptions { // Add preprocessor defines Defines = { "MY_DEFINE", "VERSION=2", "DEBUG=1" }, // Add include folders for header resolution IncludeFolders = { "include", "third_party/include" }, // Add system include folders SystemIncludeFolders = { "/usr/include" }, // Enable macro parsing (disabled by default) ParseMacros = true, // Enable comment parsing (enabled by default) ParseComments = true, // Skip system include headers from output ParseSystemIncludes = false, // Configure target platform TargetCpu = CppTargetCpu.X86_64, TargetSystem = "linux", TargetVendor = "pc" }; var compilation = CppParser.Parse(@" #ifdef MY_DEFINE struct EnabledStruct { int x; }; #endif ", options); Console.WriteLine($"Structs found: {compilation.Classes.Count}"); // Output: 1 ``` -------------------------------- ### Configure .NET Project for CppAst.Net Native DLLs Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md This XML snippet is a workaround for the common issue of missing native `libclang.dll` or `libclang.so` files when using CppAst.Net (which relies on ClangSharp) in .NET projects. By setting the `RuntimeIdentifier`, it helps ensure the correct native libraries are resolved at runtime, preventing `DLLNotFoundException` errors. ```xml $(NETCoreSdkRuntimeIdentifier) ``` -------------------------------- ### C# AST Traversal using libclang Callbacks Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md Demonstrates a C# function that recursively visits AST children using libclang's callback mechanism. This approach can be inconvenient for tools requiring repeated AST access. ```cs private static void PrintASTByCursor(CXCursor cursor, int level, List saveList) { bool needPrintChild = true; saveList.Add(GetOneCursorDetails(cursor, level, out needPrintChild)); unsafe { PrintCursorInfo cursorInfo = new PrintCursorInfo(); cursorInfo.Level = level + 1; cursorInfo.SaveList = saveList; GCHandle cursorInfoHandle = GCHandle.Alloc(cursorInfo); cursor.VisitChildren(VisitorForPrint, new CXClientData((IntPtr)cursorInfoHandle)); } } ``` -------------------------------- ### Access System Attributes with CppAst.NET Source: https://context7.com/xoofx/cppast.net/llms.txt Demonstrates how to parse and inspect C++ system-level attributes such as dllexport, visibility, and deprecated using CppParser. ```csharp using CppAst; var options = new CppParserOptions(); options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64); var compilation = CppParser.Parse(@" __declspec(dllexport) void exportedFunc(); __declspec(dllimport) extern int importedVar; [[deprecated("Use newFunc instead")]] void oldFunc(); [[noreturn]] void terminateApp(); ", options); foreach (var func in compilation.Functions) { Console.WriteLine($"Function: {func.Name}"); foreach (var attr in func.Attributes) { Console.WriteLine($" Attribute: {attr.Name} ({attr.Kind})"); if (!string.IsNullOrEmpty(attr.Arguments)) Console.WriteLine($" Arguments: {attr.Arguments}"); } } ``` -------------------------------- ### Working with the C++ Type System Source: https://context7.com/xoofx/cppast.net/llms.txt Details how to inspect and traverse complex C++ types including pointers, references, arrays, and function signatures. ```APIDOC ## GET /CppCompilation/Parameters/TypeInfo ### Description Inspects the type metadata of a function parameter, including canonical types and specific type kinds. ### Method GET ### Endpoint /CppCompilation/Parameters/{paramId}/Type ### Parameters #### Path Parameters - **paramId** (string) - Required - The ID of the parameter to inspect. ### Response #### Success Response (200) - **TypeKind** (Enum) - The category of the type (Pointer, Array, Function, etc.). - **CanonicalType** (Type) - The underlying base type. - **Details** (Object) - Specific properties based on type kind (e.g., ElementType for pointers, Size for arrays). ``` -------------------------------- ### Parsing C++ Fields and Variables Source: https://context7.com/xoofx/cppast.net/llms.txt Demonstrates how to parse global variables and class/struct fields. It shows how to access storage qualifiers, initialization values, bit field widths, and visibility modifiers. ```csharp using CppAst; var compilation = CppParser.Parse(@" const int GLOBAL_CONST = 42; static int globalStatic = 100; struct Data { int x = 0; const double pi = 3.14159; unsigned int flags : 8; // bit field }; "); // Global fields/variables foreach (var field in compilation.Fields) { Console.WriteLine($"Global: {field.Type} {field.Name}"); Console.WriteLine($" Storage: {field.StorageQualifier}"); if (field.InitValue != null) Console.WriteLine($" Init value: {field.InitValue}"); } // Class/struct fields foreach (var cls in compilation.Classes) { foreach (var field in cls.Fields) { Console.WriteLine($"Field: {field.Type} {field.Name}"); Console.WriteLine($" Visibility: {field.Visibility}"); Console.WriteLine($" Offset: {field.Offset} bytes"); if (field.IsBitField) Console.WriteLine($" Bit field width: {field.BitFieldWidth}"); if (field.InitExpression != null) Console.WriteLine($" Init expression: {field.InitExpression}"); } } ``` -------------------------------- ### Parsing System Attributes Source: https://context7.com/xoofx/cppast.net/llms.txt Demonstrates how to parse and access C++ system-level attributes like dllexport, deprecated, and noreturn using CppParser. ```APIDOC ## POST /CppParser/Parse/Attributes ### Description Parses C++ source code to extract system-level attributes attached to functions or variables. ### Method POST ### Endpoint /CppParser/Parse ### Parameters #### Request Body - **sourceCode** (string) - Required - The C++ header content to parse. - **options** (CppParserOptions) - Optional - Configuration for target architecture and compiler settings. ### Request Example { "sourceCode": "[[deprecated]] void oldFunc();", "options": { "TargetCpu": "X86_64" } } ### Response #### Success Response (200) - **Attributes** (List) - A collection of attribute objects containing Name, Kind, and Arguments. ``` -------------------------------- ### Parse C++ Code with CppParser Source: https://github.com/xoofx/cppast.net/blob/main/readme.md Demonstrates how to parse a C++ string using CppParser.Parse and iterate through the resulting AST components like enums, functions, and structs. ```csharp // Parse a C++ files var compilation = CppParser.Parse(@" enum MyEnum { MyEnum_0, MyEnum_1 }; void function0(int a, int b); struct MyStruct { int field0; int field1;}; typedef MyStruct* MyStructPtr; " ); // Print diagnostic messages foreach (var message in compilation.Diagnostics.Messages) Console.WriteLine(message); // Print All enums foreach (var cppEnum in compilation.Enums) Console.WriteLine(cppEnum); // Print All functions foreach (var cppFunction in compilation.Functions) Console.WriteLine(cppFunction); // Print All classes, structs foreach (var cppClass in compilation.Classes) Console.WriteLine(cppClass); // Print All typedefs foreach (var cppTypedef in compilation.Typedefs) Console.WriteLine(cppTypedef); ``` -------------------------------- ### Parse C++ Code with CppAst Source: https://github.com/xoofx/cppast.net/blob/main/doc/readme.md Demonstrates how to parse C++ code using CppAst. It shows how to iterate through parsed structs and their fields. This requires the CppAst library. ```C# var compilation = CppParser.Parse("..."); // Print all structs with all fields foreach(var cppStruct in compilation.Classes) { // Skip non struct if (cppStruct.ClassKind != CppClassKind.Struct) continue; Console.WriteLine($"struct {cppStruct.Name}"); // Print all fields foreach(var cppField in cppStruct.Fields) Console.WriteLine($" {cppField}"); Console.WriteLine("}"); } ``` -------------------------------- ### Configure Runtime Identifier for CppAst.NET Source: https://github.com/xoofx/cppast.net/blob/main/readme.md Configures the .NET project file to include the necessary RuntimeIdentifier, which is a required workaround for libclang integration. ```xml $(NETCoreSdkRuntimeIdentifier) ``` -------------------------------- ### Working with C++ Structs, Classes, and Unions using CppAst.NET Source: https://context7.com/xoofx/cppast.net/llms.txt Demonstrates how to parse and interact with C++ class, struct, and union types using CppAst.NET. It covers accessing members like fields, methods, constructors, destructors, base types, and template information. ```csharp using CppAst; var compilation = CppParser.Parse(@" class BaseClass { public: virtual void virtualMethod() = 0; }; class MyClass : public BaseClass { public: MyClass(); ~MyClass(); int publicField; void publicMethod(int param); static void staticMethod(); private: double privateField; }; struct MyStruct { float x, y, z; }; union MyUnion { int intValue; float floatValue; }; "); foreach (var cppClass in compilation.Classes) { // Determine class kind (Class, Struct, Union) Console.WriteLine($"{cppClass.ClassKind}: {cppClass.Name}"); // Check for base types foreach (var baseType in cppClass.BaseTypes) Console.WriteLine($" Inherits from: {baseType.Type}"); // Access fields foreach (var field in cppClass.Fields) Console.WriteLine($" Field: {field.Type} {field.Name} (visibility: {field.Visibility})"); // Access constructors foreach (var ctor in cppClass.Constructors) Console.WriteLine($" Constructor: {ctor}"); // Access destructors foreach (var dtor in cppClass.Destructors) Console.WriteLine($" Destructor: {dtor}"); // Access methods foreach (var method in cppClass.Functions) { Console.WriteLine($" Method: {method.Name}"); Console.WriteLine($" Return: {method.ReturnType}"); Console.WriteLine($" Virtual: {method.IsVirtual}, Pure: {method.IsPureVirtual}"); Console.WriteLine($" Static: {method.IsStatic}, Const: {method.IsConst}"); } // Get size information Console.WriteLine($" SizeOf: {cppClass.SizeOf}, AlignOf: {cppClass.AlignOf}"); } ``` -------------------------------- ### Parse and Inspect C++ Templates Source: https://context7.com/xoofx/cppast.net/llms.txt Shows how to extract template parameters, specialization arguments, and template kinds from parsed C++ code using CppAst.NET. ```csharp using CppAst; var compilation = CppParser.Parse(@" template struct Pair {}; template struct Pair {}; Pair instance; "); foreach (var cls in compilation.Classes) { Console.WriteLine($"Class: {cls.Name}, Kind: {cls.TemplateKind}"); foreach (var param in cls.TemplateParameters) Console.WriteLine($"Param: {param}"); foreach (var arg in cls.TemplateSpecializedArguments) Console.WriteLine($"Arg: {arg.ArgString}"); } ``` -------------------------------- ### Define Export API Macros (C++) Source: https://github.com/xoofx/cppast.net/blob/main/doc/attributes.md This C++ code defines macros for exporting API symbols, adapting to different build environments (Windows vs. others) using preprocessor directives. It's a common pattern for managing cross-platform symbol visibility. ```cpp #ifdef WIN32 #define EXPORT_API __declspec(dllexport) #else #define EXPORT_API __attribute__((visibility("default"))) #endif ``` -------------------------------- ### Inject and Access Custom Metadata Source: https://context7.com/xoofx/cppast.net/llms.txt Explains how to use the __cppast() macro to inject custom attributes into C++ code and retrieve them programmatically via the CppAst API. ```csharp using CppAst; var compilation = CppParser.Parse(@" #define __cppast(...) __cppast(msgid = 1001) struct Message { __cppast(id = 1) int messageType; }; "); foreach (var cls in compilation.Classes) { foreach (var attr in cls.Attributes) { if (attr.Kind == AttributeKind.AnnotateAttribute) Console.WriteLine(attr.Arguments); } } ``` -------------------------------- ### Accessing Source Location Information Source: https://context7.com/xoofx/cppast.net/llms.txt Explains how to retrieve file, line, and column information for parsed C++ elements using the Span property. ```APIDOC ## GET /CppCompilation/Elements/Location ### Description Retrieves the source code position (file, line, column) for a specific C++ declaration. ### Method GET ### Endpoint /CppCompilation/Elements/{elementId}/Span ### Parameters #### Path Parameters - **elementId** (string) - Required - The unique identifier of the parsed class or function. ### Response #### Success Response (200) - **Start** (Location) - The starting file, line, and column. - **End** (Location) - The ending file, line, and column. ``` -------------------------------- ### Inspect C++ Type System Source: https://context7.com/xoofx/cppast.net/llms.txt Illustrates how to navigate complex C++ types including pointers, references, arrays, and function pointers using the CppAst type system. ```csharp using CppAst; var compilation = CppParser.Parse(@" void processTypes( int value, int* pointer, int& reference, const int* constPointer, int array[10], void (*callback)(int, int) ); "); var func = compilation.Functions[0]; foreach (var param in func.Parameters) { Console.WriteLine($"Parameter: {param.Name}"); Console.WriteLine($" Type: {param.Type}"); Console.WriteLine($" Type kind: {param.Type.TypeKind}"); var canonical = param.Type.GetCanonicalType(); Console.WriteLine($" Canonical: {canonical}"); switch (param.Type) { case CppPointerType ptr: Console.WriteLine($" Points to: {ptr.ElementType}"); break; case CppReferenceType refType: Console.WriteLine($" References: {refType.ElementType}"); break; case CppArrayType arr: Console.WriteLine($" Array of: {arr.ElementType}, Size: {arr.Size}"); break; case CppQualifiedType qualified: Console.WriteLine($" Qualifier: {qualified.Qualifier}, Element: {qualified.ElementType}"); break; case CppFunctionType funcType: Console.WriteLine($" Return: {funcType.ReturnType}"); Console.WriteLine($" Params: {funcType.Parameters.Count}"); break; } } ``` -------------------------------- ### Parse Single C++ Header File using CppParser.ParseFile Source: https://context7.com/xoofx/cppast.net/llms.txt Parses a single C/C++ header file from the disk. This method is useful for processing individual header files and allows for optional parser configuration. It returns a CppCompilation object containing the parsed elements and diagnostics. ```csharp using CppAst; // Parse a single header file var compilation = CppParser.ParseFile("include/myheader.h"); // Check for errors if (compilation.HasErrors) { foreach (var diagnostic in compilation.Diagnostics.Messages) Console.WriteLine(diagnostic); return; } // Access parsed content Console.WriteLine($"Found {compilation.Classes.Count} classes"); Console.WriteLine($"Found {compilation.Functions.Count} functions"); Console.WriteLine($"Found {compilation.Enums.Count} enums"); ``` -------------------------------- ### Injecting Metadata with __cppast Macro (C++) Source: https://github.com/xoofx/cppast.net/blob/main/doc/attributes.md This C++ code demonstrates how to inject custom metadata into struct definitions using a preprocessor macro `__cppast`. This technique is useful for offline processing tools, such as serialization/deserialization libraries, to add information without affecting compilation. ```cpp #if !defined(__cppast) #define __cppast(...) #endif struct __cppast(msgid = 1) TestPBMessage { public: __cppast(id = 1) float x; __cppast(id = 2) double y; __cppast(id = 3) uint64_t z; }; ``` -------------------------------- ### Working with C++ Enumerations using CppAst.NET Source: https://context7.com/xoofx/cppast.net/llms.txt Demonstrates how to parse and work with C++ enumerations, including scoped enums (enum class). It provides access to enum items and their underlying integer types. ```csharp using CppAst; var compilation = CppParser.Parse(@" enum Color { Red, Green, Blue }; enum class Status : unsigned int { OK = 0, Error = 1, Pending = 2 }; "); foreach (var cppEnum in compilation.Enums) { Console.WriteLine($"Enum: {cppEnum.Name}"); Console.WriteLine($" Scoped: {cppEnum.IsScoped}"); Console.WriteLine($" Underlying type: {cppEnum.IntegerType}"); // Access enum items foreach (var item in cppEnum.Items) { Console.WriteLine($" {item.Name} = {item.Value}"); } } // Output: // Enum: Color // Scoped: False // Underlying type: int // Red = 0 // Green = 1 // Blue = 2 // Enum: Status // Scoped: True // Underlying type: unsigned int // OK = 0 // Error = 1 // Pending = 2 ``` -------------------------------- ### Parse Multiple C++ Header Files using CppParser.ParseFiles Source: https://context7.com/xoofx/cppast.net/llms.txt Parses multiple C/C++ header files into a single compilation unit, enabling the resolution of cross-file references. It takes a list of file paths and returns a CppCompilation object that aggregates all parsed declarations and diagnostics from the specified files. ```csharp using CppAst; // Parse multiple header files together var files = new List { "include/types.h", "include/functions.h", "include/classes.h" }; var compilation = CppParser.ParseFiles(files); if (!compilation.HasErrors) { // All declarations from all files are available foreach (var cls in compilation.Classes) Console.WriteLine($"Class: {cls.Name}, Fields: {cls.Fields.Count}"); } ``` -------------------------------- ### Configure CppAst CMake Build Source: https://github.com/xoofx/cppast.net/blob/main/src/CppAst/CMakeLists.txt This script configures the CppAst project by globbing source files, setting the C# language version to 7.3, and defining the shared library target. It also specifies required NuGet packages and enables unsafe code blocks for the target. ```cmake file(GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cs) set(CMAKE_CSharp_FLAGS "${CMAKE_CSharp_FLAGS} /langversion:7.3") add_library(CppAst SHARED ${SOURCE_FILES}) set_target_properties(CppAst PROPERTIES VS_PACKAGE_REFERENCES "ClangSharp_17.0.1;Irony_1.2.0" ) target_compile_options(CppAst PUBLIC "/unsafe") ``` -------------------------------- ### Parse System and Annotate Attributes via ClangSharp Source: https://github.com/xoofx/cppast.net/blob/main/doc/attributes.md This function iterates through cursor children to identify and collect system-level attributes and annotation attributes. It uses libclang's AST traversal to efficiently extract attribute data, avoiding the performance overhead of manual token parsing. ```csharp private List ParseSystemAndAnnotateAttributeInCursor(CXCursor cursor) { List collectAttributes = new List(); cursor.VisitChildren((argCursor, parentCursor, clientData) => { var sourceSpan = new CppSourceSpan(GetSourceLocation(argCursor.SourceRange.Start), GetSourceLocation(argCursor.SourceRange.End)); var meta = argCursor.Spelling.CString; switch (argCursor.Kind) { case CXCursorKind.CXCursor_VisibilityAttr: break; case CXCursorKind.CXCursor_AnnotateAttr: break; case CXCursorKind.CXCursor_AlignedAttr: break; default: break; } return CXChildVisitResult.CXChildVisit_Continue; }, new CXClientData((IntPtr)0)); return collectAttributes; } ``` -------------------------------- ### Parsing and Inspecting Template Specializations Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md This endpoint describes how to use the CppAst.Net library to parse C++ code containing template specializations and access the resulting metadata. ```APIDOC ## GET /api/cppast/templates/parse ### Description Parses a provided C++ source string and returns a compilation object containing metadata about template classes, fields, and their specialization relationships. ### Method GET ### Endpoint /api/cppast/templates/parse ### Parameters #### Query Parameters - **sourceCode** (string) - Required - The C++ source code containing template definitions to be parsed. ### Request Example { "sourceCode": "template struct foo {}; template struct foo {}; foo foobar;" } ### Response #### Success Response (200) - **Classes** (array) - List of parsed C++ classes including their TemplateKind (TemplateClass, TemplateSpecializedClass, PartialTemplateClass). - **Fields** (array) - List of fields found in the source code. #### Response Example { "Classes": [ { "Name": "foo", "TemplateKind": "TemplateClass" }, { "Name": "foo", "TemplateKind": "TemplateSpecializedClass" }, { "Name": "foo", "TemplateKind": "PartialTemplateClass" } ], "Fields": [ { "Name": "foobar", "Type": "foo" } ] } ``` -------------------------------- ### Test Template Partial Specialization in CppAst.Net Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md A unit test demonstrating how to parse C++ template code and verify the correct identification of base templates, partial specializations, and full specializations using the CppAst library. ```csharp [Test] public void TestTemplatePartialSpecialization() { ParseAssert(@" template struct foo {}; template struct foo {}; foo foobar; ", compilation => { Assert.False(compilation.HasErrors); Assert.AreEqual(3, compilation.Classes.Count); Assert.AreEqual(1, compilation.Fields.Count); var baseTemplate = compilation.Classes[0]; var fullSpecializedClass = compilation.Classes[1]; var partialSpecializedTemplate = compilation.Classes[2]; var field = compilation.Fields[0]; Assert.AreEqual(field.Name, "foobar"); Assert.AreEqual(baseTemplate.TemplateKind, CppAst.CppTemplateKind.TemplateClass); Assert.AreEqual(fullSpecializedClass.TemplateKind, CppAst.CppTemplateKind.TemplateSpecializedClass); Assert.AreEqual(partialSpecializedTemplate.TemplateKind, CppAst.CppTemplateKind.PartialTemplateClass); Assert.AreEqual(fullSpecializedClass.SpecializedTemplate, partialSpecializedTemplate); Assert.AreEqual(field.Type, fullSpecializedClass); Assert.AreEqual(partialSpecializedTemplate.TemplateSpecializedArguments.Count, 2); Assert.AreEqual(partialSpecializedTemplate.TemplateSpecializedArguments[0].ArgString, "int"); Assert.AreEqual(partialSpecializedTemplate.TemplateSpecializedArguments[1].IsSpecializedArgument, false); Assert.AreEqual(fullSpecializedClass.TemplateSpecializedArguments.Count, 2); Assert.AreEqual(fullSpecializedClass.TemplateSpecializedArguments[0].ArgString, "int"); Assert.AreEqual(fullSpecializedClass.TemplateSpecializedArguments[1].ArgString, "int"); } ); } ``` -------------------------------- ### Configure CppAst.Tests CMake Library Source: https://github.com/xoofx/cppast.net/blob/main/src/CppAst.Tests/CMakeLists.txt This snippet configures a CMake shared library named CppAst.Tests. It finds all .cs files in the current source directory, sets Visual Studio package references for testing, enables unsafe code compilation, and links against the CppAst library. ```cmake file(GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cs) add_library(CppAst.Tests SHARED ${SOURCE_FILES}) set_target_properties(CppAst.Tests PROPERTIES VS_PACKAGE_REFERENCES "Microsoft.NET.Test.Sdk_17.8.0;nunit_4.0.1;NUnit3TestAdapter_4.5.0" ) target_compile_options(CppAst.Tests PUBLIC "/unsafe") target_link_libraries(CppAst.Tests CppAst) ``` -------------------------------- ### Traversing C++ Namespaces Source: https://context7.com/xoofx/cppast.net/llms.txt Illustrates how to recursively traverse C++ namespaces. It accesses nested declarations like classes, functions, and enums within the namespace hierarchy. ```csharp using CppAst; var compilation = CppParser.Parse(@" namespace outer { namespace inner { struct NestedStruct { int value; }; void nestedFunction(); } class OuterClass {}; enum OuterEnum { A, B, C }; } "); void PrintNamespace(CppNamespace ns, int indent = 0) { var prefix = new string(' ', indent * 2); Console.WriteLine($"{prefix}namespace {ns.Name}"); Console.WriteLine($"{prefix} Inline: {ns.IsInlineNamespace}"); Console.WriteLine($"{prefix} Classes: {ns.Classes.Count}"); Console.WriteLine($"{prefix} Functions: {ns.Functions.Count}"); Console.WriteLine($"{prefix} Enums: {ns.Enums.Count}"); foreach (var nested in ns.Namespaces) PrintNamespace(nested, indent + 1); } foreach (var ns in compilation.Namespaces) PrintNamespace(ns); ``` -------------------------------- ### AttributeKind.TokenAttribute Handling Source: https://github.com/xoofx/cppast.net/blob/main/doc/attributes.md Explains the handling of TokenAttributes, which are for compatibility with older versions. These attributes are moved to a separate property to distinguish them from the new CxxSystemAttribute and AnnotateAttribute. ```APIDOC ## AttributeKind.TokenAttribute ### Description This section describes the handling of `TokenAttribute`s, which represent attributes parsed using the older token-based mechanism. For backward compatibility, these have been moved from the primary `Attributes` property to a new `TokenAttributes` property. ### Purpose To maintain compatibility with previous versions of `cppast.net` while introducing new, more efficient attribute parsing methods (`CxxSystemAttribute` and `AnnotateAttribute`). ### Implementation Details - Original `attribute` parsing based on `token` parsing is now located in the `TokenAttributes` property. - The new `CxxSystemAttribute` and `AnnotateAttribute` are stored in the main `Attributes` property. ### Usage Refer to the relevant test cases within the project for specific examples of how to use `TokenAttribute`s and understand their behavior in relation to the new attribute types. ``` -------------------------------- ### Configure C++ Parser for Windows MSVC Source: https://context7.com/xoofx/cppast.net/llms.txt Configures the C++ parser options for a Windows environment using the MSVC compiler. This includes setting target CPU architecture and Visual Studio version. It allows parsing Windows-specific headers and code. ```csharp using CppAst; // Configure for Windows MSVC targeting x64 var options = new CppParserOptions() .ConfigureForWindowsMsvc(CppTargetCpu.X86_64, CppVisualStudioVersion.VS2022); // Now can parse Windows-specific headers var compilation = CppParser.Parse(@" #include __declspec(dllexport) void MyExportedFunction(); ", options); // Access exported functions foreach (var func in compilation.Functions) { var hasExport = func.Attributes.Any(a => a.Kind == AttributeKind.CxxSystemAttribute && a.Name == "dllexport"); Console.WriteLine($"{func.Name}: exported={hasExport}"); } ``` -------------------------------- ### Define CppAst.Net Macros for Annotate Attribute Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md Defines system macros for CppAst.Net to facilitate the use of annotate attributes. These macros help identify the CppAst.Net handler and wrap arguments for compiler compatibility, ensuring meta-attributes are processed correctly. ```cs Defines = new List() { "__cppast_run__", //Help us for identify the CppAst.Net handler @"__cppast_impl(...)=__attribute__((annotate(#__VA_ARGS__)))", //Help us for use annotate attribute convenience @"__cppast(...)=__cppast_impl(__VA_ARGS__)", //Add a macro wrapper here, so the argument with macro can be handle right for compiler. }; ``` -------------------------------- ### Retrieve Source Location Information Source: https://context7.com/xoofx/cppast.net/llms.txt Shows how to access the Span property of parsed C++ elements to identify file paths, line numbers, and column positions for error reporting or code generation. ```csharp using CppAst; var compilation = CppParser.Parse(@" struct Point { int x; int y; }; void process(Point p); ", "myheader.h"); foreach (var cls in compilation.Classes) { var span = cls.Span; Console.WriteLine($"Class '{cls.Name}' defined at:"); Console.WriteLine($" File: {span.Start.File}"); Console.WriteLine($" Start: Line {span.Start.Line}, Column {span.Start.Column}"); Console.WriteLine($" End: Line {span.End.Line}, Column {span.End.Column}"); } foreach (var func in compilation.Functions) { var loc = func.Span.Start; Console.WriteLine($"Function '{func.Name}' at {loc.File}:{loc.Line}:{loc.Column}"); } ``` -------------------------------- ### Parsing C++ Code with CppAst.Net Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md This snippet demonstrates how to parse C++ code from a string using CppAst.Net and access various C++ constructs like enums, functions, classes, and typedefs. ```APIDOC ## Parsing C++ Code ### Description This example shows how to use the `CppParser.Parse` method to parse C++ code provided as a string. It then iterates through the `CppCompilation` object to access and print diagnostics, enums, functions, classes, and typedefs. ### Method `CppParser.Parse(string cppCode)` ### Endpoint N/A (This is a library usage example) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cs static void Main(string[] args) { // Parse a C++ files var compilation = CppParser.Parse(@"\nenum MyEnum { MyEnum_0, MyEnum_1 };\nvoid function0(int a, int b);\nstruct MyStruct { int field0; int field1;};\ntypedef MyStruct* MyStructPtr;\n"); // Print diagnostic messages foreach (var message in compilation.Diagnostics.Messages) Console.WriteLine(message); // Print All enums foreach (var cppEnum in compilation.Enums) Console.WriteLine(cppEnum); // Print All functions foreach (var cppFunction in compilation.Functions) Console.WriteLine(cppFunction); // Print All classes, structs foreach (var cppClass in compilation.Classes) Console.WriteLine(cppClass); // Print All typedefs foreach (var cppTypedef in compilation.Typedefs) Console.WriteLine(cppTypedef); Console.WriteLine("Hello World!"); } ``` ### Response #### Success Response (200) N/A (This is a console application output) #### Response Example ``` // Output will vary based on C++ code and diagnostics MyEnum void function0(int a, int b) MyStruct MyStruct* Hello World! ``` ``` -------------------------------- ### Parse C++ Code and Access AST Elements with CppAst.Net Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md This C# code snippet demonstrates how to parse C++ code directly from a string using CppAst.Net. It then shows how to iterate through the generated Abstract Syntax Tree (AST) to access and print information about enums, functions, structs, and typedefs. This is useful for code analysis and manipulation within a C# application. ```csharp var compilation = CppParser.Parse(@" enum MyEnum { MyEnum_0, MyEnum_1 }; void function0(int a, int b); struct MyStruct { int field0; int field1; }; typedef MyStruct* MyStructPtr; "); foreach (var message in compilation.Diagnostics.Messages) Console.WriteLine(message); foreach (var cppEnum in compilation.Enums) Console.WriteLine(cppEnum); foreach (var cppFunction in compilation.Functions) Console.WriteLine(cppFunction); foreach (var cppClass in compilation.Classes) Console.WriteLine(cppClass); foreach (var cppTypedef in compilation.Typedefs) Console.WriteLine(cppTypedef); ``` -------------------------------- ### Handling C++ Type Aliases Source: https://context7.com/xoofx/cppast.net/llms.txt Shows how to extract information from typedef declarations. It provides access to the underlying element type, canonical type, and memory size of the alias. ```csharp using CppAst; var compilation = CppParser.Parse(@" typedef int INT32; typedef unsigned long long UINT64; typedef void (*CallbackFunc)(int, int); typedef struct { int x; int y; } Point; "); foreach (var typedef in compilation.Typedefs) { Console.WriteLine($"Typedef: {typedef.Name}"); Console.WriteLine($" Element type: {typedef.ElementType}"); Console.WriteLine($" Canonical type: {typedef.GetCanonicalType()}"); Console.WriteLine($" Size: {typedef.SizeOf} bytes"); } ``` -------------------------------- ### Parse C++ Content from String using CppParser.Parse Source: https://context7.com/xoofx/cppast.net/llms.txt Parses C++ code provided as a string and returns a CppCompilation object. This object contains all parsed elements like enums, functions, structs, and typedefs. It also provides diagnostics for any compilation errors encountered during parsing. The output can be iterated to access specific parsed types. ```csharp using CppAst; // Parse C++ code from a string var compilation = CppParser.Parse(@" enum MyEnum { MyEnum_0, MyEnum_1 }; void function0(int a, int b); struct MyStruct { int field0; int field1; }; typedef MyStruct* MyStructPtr; "); // Check for compilation errors if (compilation.HasErrors) { foreach (var message in compilation.Diagnostics.Messages) Console.WriteLine($"Error: {message}"); return; } // Iterate through all parsed enums foreach (var cppEnum in compilation.Enums) Console.WriteLine(cppEnum); // Output: enum MyEnum {...} // Iterate through all parsed functions foreach (var cppFunction in compilation.Functions) Console.WriteLine(cppFunction); // Output: void function0(int a, int b) // Iterate through all parsed classes/structs foreach (var cppClass in compilation.Classes) Console.WriteLine(cppClass); // Output: struct MyStruct { ... } // Iterate through all parsed typedefs foreach (var cppTypedef in compilation.Typedefs) Console.WriteLine(cppTypedef); // Output: typedef MyStruct* MyStructPtr ``` -------------------------------- ### Define CppAst.Net Macros for AnnotateAttribute Source: https://github.com/xoofx/cppast.net/blob/main/doc/attributes.md Defines system macros for CppAst.Net to facilitate the use of the annotate attribute. These macros help identify the CppAst.Net handler, provide a convenient wrapper for the annotate attribute, and ensure proper handling of macro arguments during compilation. ```C# Defines = new List() { "__cppast_run__", //Help us for identify the CppAst.Net handler "__cppast_impl(...)=__attribute__((annotate(#__VA_ARGS__)))", //Help us for use annotate attribute convenience "__cppast(...)=__cppast_impl(__VA_ARGS__)", //Add a macro wrapper here, so the argument with macro can be handle right for compiler. }; ``` -------------------------------- ### Conditional Compilation for CppAst.Net Parsing Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md Provides conditional compilation directives to ensure that the `__cppast` macro is ignored during standard compilation but recognized by CppAst.Net. This prevents interference with actual code compilation while allowing meta-attributes to be parsed. ```cpp #if !defined(__cppast) #define __cppast(...) #endif ``` -------------------------------- ### Test Template Partial Specialization in C# Source: https://github.com/xoofx/cppast.net/blob/main/doc/Programming Guide For CppAst.Net.md This C# unit test verifies CppAst.Net's ability to parse and differentiate between template classes, fully specialized classes, and partially specialized template classes. It asserts the correct identification of template parameters, specialization arguments, and the relationships between these entities. ```cs [Test] public void TestTemplatePartialSpecialization() { ParseAssert(@" template struct foo {}; template struct foo {}; foo foobar; ", compilation => { Assert.False(compilation.HasErrors); Assert.AreEqual(3, compilation.Classes.Count); Assert.AreEqual(1, compilation.Fields.Count); var baseTemplate = compilation.Classes[0]; var fullSpecializedClass = compilation.Classes[1]; var partialSpecializedTemplate = compilation.Classes[2]; var field = compilation.Fields[0]; Assert.AreEqual(field.Name, "foobar"); Assert.AreEqual(baseTemplate.TemplateKind, CppAst.CppTemplateKind.TemplateClass); Assert.AreEqual(fullSpecializedClass.TemplateKind, CppAst.CppTemplateKind.TemplateSpecializedClass); Assert.AreEqual(partialSpecializedTemplate.TemplateKind, CppAst.CppTemplateKind.PartialTemplateClass); //Need be a specialized for partial template here Assert.AreEqual(fullSpecializedClass.SpecializedTemplate, partialSpecializedTemplate); //Need be a full specialized class for this field Assert.AreEqual(field.Type, fullSpecializedClass); Assert.AreEqual(partialSpecializedTemplate.TemplateSpecializedArguments.Count, 2); //The first argument is integer now Assert.AreEqual(partialSpecializedTemplate.TemplateSpecializedArguments[0].ArgString, "int"); //The second argument is not a specialized argument, we do not specialized a `B` template parameter here(partial specialized template) Assert.AreEqual(partialSpecializedTemplate.TemplateSpecializedArguments[1].IsSpecializedArgument, false); //The field use type is a full specialized type here~", so we can have two `int` template parmerater here //It's a not template or partial template class, so we can instantiate it, see `foo foobar;` before. Assert.AreEqual(fullSpecializedClass.TemplateSpecializedArguments.Count, 2); //The first argument is integer now Assert.AreEqual(fullSpecializedClass.TemplateSpecializedArguments[0].ArgString, "int"); //The second argument is not a specialized argument Assert.AreEqual(fullSpecializedClass.TemplateSpecializedArguments[1].ArgString, "int"); } ); } ```