Skip to content

Commit 030f42d

Browse files
committed
Update doc feature support overview
1 parent 320bc7e commit 030f42d

6 files changed

Lines changed: 95 additions & 49 deletions

File tree

doc/Programming Guide For CppAst.Net.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,15 @@ From the above example, we can already see some advantages of CppAst.Net:
192192
2. It supports building Compilation directly from a string, which also facilitates the implementation of unit tests.
193193

194194
### 3.1 Easy to Start with Simple Configuration
195-
  CppAst.Net fundamentally relies on ClangSharp. Those who have experience with ClangSharp might be aware that the compilation and execution experience may not be very smooth. After adding the ClangSharp package from NuGet, attempting to run related examples and test codes might still prompt issues such as the absence of `libclang.dll/ligclang.so`, leading to a less than ideal experience. This situation can't be entirely blamed on ClangSharp, as it mainly stems from NuGet's limitations on the size of native binaries that a package can depend on. Since this issue might be encountered by many, let's first share a workaround to facilitate easier running of your own test codes:
195+
  CppAst.Net fundamentally relies on ClangSharp and its native libclang binaries. After adding the CppAst package from NuGet, projects should still select a runtime identifier so the correct native asset can be restored and loaded. A common project-file configuration is:
196196
```xml
197197
<PropertyGroup>
198198
<!-- Workaround for issue https://github.com/microsoft/ClangSharp/issues/129 -->
199199
<RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == '' AND '$(PackAsTool)' != 'true'">$(NETCoreSdkRuntimeIdentifier)</RuntimeIdentifier>
200200
</PropertyGroup>
201201
```
202202

203-
For the official sample codes mentioned earlier, we can try to start from scratch and create a `C# .netcore 3.1` Console App, and step by step get it to run:
203+
For the official sample code mentioned earlier, we can start from scratch with a modern `.NET 8` console app and get it running step by step:
204204

205205
#### 3.1.1 Creating a Project
206206
**Open Visual Studio and create a C# Console App (the environment used by the author is VS 2022):**
@@ -209,7 +209,7 @@ For the official sample codes mentioned earlier, we can try to start from scratc
209209
**Configure the project name:**
210210
![3-2-guide2](cn/img/3-2-guide2.png)
211211

212-
**Select the .net version (here we directly use .net core 3.1):**
212+
**Select the .NET version (the current package targets .NET 8):**
213213
![3-3-guide](cn/img/3-3-guide.png)
214214

215215
#### 3.1.2 Adding `CppAst.Net` Package via NuGet
@@ -229,26 +229,26 @@ For the official sample codes mentioned earlier, we can try to start from scratc
229229

230230
<PropertyGroup>
231231
<OutputType>Exe</OutputType>
232-
<TargetFramework>netcoreapp3.1</TargetFramework>
232+
<TargetFramework>net8.0</TargetFramework>
233233

234234
<!-- Workaround for issue https://github.com/microsoft/ClangSharp/issues/129 -->
235235
<RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == '' AND '$(PackAsTool)' != 'true'">$(NETCoreSdkRuntimeIdentifier)</RuntimeIdentifier>
236236
</PropertyGroup>
237237

238238
<ItemGroup>
239-
<PackageReference Include="CppAst" Version="0.13.0" />
239+
<PackageReference Include="CppAst" Version="LATEST_VERSION" />
240240
</ItemGroup>
241241

242242
</Project>
243243
```
244-
The `RuntimeIdentifier` entry is essential, as omitting it could lead to runtime errors due to missing libclang native dlls.
244+
Replace `LATEST_VERSION` with the current NuGet version. The `RuntimeIdentifier` entry is recommended so restore selects the native libclang asset for the current platform.
245245

246246
#### 3.1.4 Adding Sample Code and Testing the App
247247
**Add test code in the Main() function of Program.cs:**
248248
```cs
249249
static void Main(string[] args)
250250
{
251-
// Parse a C++ files
251+
// Parse C++ files
252252
var compilation = CppParser.Parse(@"
253253
enum MyEnum { MyEnum_0, MyEnum_1 };
254254
void function0(int a, int b);
@@ -455,7 +455,7 @@ foo<int, int> foobar;
455455

456456
### 4.2 Support for `meta attribute`
457457
&emsp;&emsp;In this section, we added a specific document [attributes.md](https://github.com/xoofx/CppAst.NET/blob/main/doc/attributes.md) to the CppAst.Net code repository. Interested readers can consult it on their own. It mainly addresses the issue mentioned above about needing to configure certain exported items without wanting to separate the code items from the configuration information. Originally, CppAst.Net also had its own implementation of token attributes based on token parsing, but when used in projects, it encountered some issues frequently mentioned by the community:
458-
1. `ParseAttributes()` was time-consuming, leading to the introduction of the `ParseAttributes` parameter in later versions to control whether to parse `attributes`. However, in some cases, we rely on `attributes` to implement certain functionalities, which obviously was inconvenient.
458+
1. Token-based attribute parsing was time-consuming, so current versions keep that compatibility path opt-in through `CppParserOptions.ParseTokenAttributes`.
459459

460460
2. There were flaws in parsing `meta attribute` - `[[]]`. `meta attribute` defined above `Function` and `Field` is semantically legal, but `cppast.net` could not properly support such `meta attribute` defined above objects (with some exceptions, like `namespace`, `class`, `enum`, where the attribute declaration itself cannot be placed above, as the compiler would directly report errors for such usages, it can only be placed after the related keywords, like `class [[deprecated]] Abc{};`).
461461

doc/attributes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## 1. `cppast.net 0.12` Support for `attributes`
22
The original support of `cppast.net` for various types of `attributes`, including the `meta attribute` of `c++17`, is restricted due to the limitation of `libclang` itself `Api`. We need to rely on token-level parsing to implement related functions. In the implementation of `cppast.net 0.12` and previous versions, we used parsing `token` to implement related functions. Even some `attributes` that `libclang` supports well, such as `dllexport`, `dllimport`, etc., `cppast.net` most of the time also uses token parsing. Although this approach is flexible and we can always try to parse the related `attributes` from the `token` level, it also brings some problems and restrictions, including:
3-
1. `ParseAttributes()` is extremely time-consuming, which led to the addition of the `ParseAttributes` parameter in later versions to control whether to parse `attributes`. However, in some cases, we need to rely on `attributes` to complete the related functions, which is obviously inconvenient.
3+
1. Token-based attribute parsing is comparatively expensive, which led to parser options that make fallback token parsing opt-in. In current CppAst versions, this compatibility path is controlled by `CppParserOptions.ParseTokenAttributes`.
44
2. There are defects in the parsing of `meta attribute` - `[[]]`. For `meta attribute` defined above `Function` and `Field`, it is obviously legal at the semantic level, but `cppast.net` does not support this type of `meta attribute` defined above the object very well (there are some exceptions here, like `namespace`, `class`, `enum` these `attribute` declarations, the attribute definition itself cannot be at the top, the compiler will report an error directly for the related usage, it can only be after the related keywords, such as `class [[deprecated]] Abc{};`).
55
3. Individual parameters of `meta attribute` use macros. Because our original implementation is based on `token` parsing, macros during compilation obviously cannot be correctly handled in this case.
66

@@ -17,7 +17,7 @@ Taking the code segment in the `cppast.net` test case as an example:
1717
#define EXPORT_API __attribute__((visibility(""default"")))
1818
#endif
1919
```
20-
For `attributes` like `dllexport` and `visibility` that control interface visibility, we definitely use them more often, not only when `ParseAttributes` is turned on to make it work. We need to provide a high-performance solution for these basic system attributes, and the implementation should not be affected by the switch.
20+
For attributes like `dllexport` and `visibility` that control interface visibility, we need them more often than an opt-in token parser would allow. Current CppAst exposes supported system attributes through `Attributes` without requiring `ParseTokenAttributes`.
2121

2222
---
2323
### 2.2 Injection of Additional Information by Export Tools and Other Tools

doc/cn/Programming Guide For CppAst.Net - cn.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ private static void PrintASTByCursor(CXCursor cursor, int level, List<string> sa
139139
## 3. CppAst.Net - 新的天花板
140140
&emsp;&emsp;前面的铺垫比较长, 终于迎来我们的正主 [CppAst.Net](https://github.com/xoofx/CppAst.NET)了, 还是按照老规矩, **我们先来看一段 CppAst.Net 官网上的示例代码:**
141141
```cs
142-
// Parse a C++ files
142+
// Parse C++ files
143143
var compilation = CppParser.Parse(@"
144144
enum MyEnum { MyEnum_0, MyEnum_1 };
145145
void function0(int a, int b);
@@ -180,15 +180,15 @@ typedef MyStruct* MyStructPtr
180180
2. 能够支持直接从字符串构建 Compilation, 这样也方便实现单元测试.
181181

182182
### 3.1 简单配置即可上手使用
183-
&emsp;&emsp;CppAst.Net底层是依赖ClangSharp的, 有过 ClangSharp 使用经念的同学可能都知道, 整个编译运行的体验可能并不太好, 从 NuGet 添加了 ClangSharp 包之后, 可能我们直接运行相关的示例和测试代码, 还是会提示 `libclang.dll/ligclang.so` 找不到之类的问题, 体验不会特别好, 这个其实也不能全怪 ClangSharp, 主要还是 NuGet 对包本身依赖的原生二进制的大小做了一些限制, 因为这个问题可能比较多人遇到, 我们先贴出一下相关的 Workaround, 方便大家更好的运行自己的测试代码:
183+
&emsp;&emsp;CppAst.Net 底层依赖 ClangSharp 和其 native libclang 二进制。从 NuGet 添加 CppAst 包之后,项目仍建议选择一个运行时标识符,以便还原并加载正确的 native 资产。常见的项目文件配置如下:
184184
```xml
185185
<PropertyGroup>
186186
<!-- Workaround for issue https://github.com/microsoft/ClangSharp/issues/129 -->
187187
<RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == '' AND '$(PackAsTool)' != 'true'">$(NETCoreSdkRuntimeIdentifier)</RuntimeIdentifier>
188188
</PropertyGroup>
189189
```
190190

191-
对于前面说到的官方示例代码, 我们可以尝试从零开始建立一个` C# .netcore 3.1` 的Console App, 一步一步将其运行起来:
191+
对于前面说到的官方示例代码,我们可以尝试从零开始建立一个现代 `.NET 8` Console App一步一步将其运行起来
192192

193193
#### 3.1.1 新建工程
194194
**打开 Visual Studio 建立一个C# Console App (笔者当前使用的环境是 VS 2022):**
@@ -217,27 +217,27 @@ typedef MyStruct* MyStructPtr
217217

218218
<PropertyGroup>
219219
<OutputType>Exe</OutputType>
220-
<TargetFramework>netcoreapp3.1</TargetFramework>
220+
<TargetFramework>net8.0</TargetFramework>
221221

222222
<!-- Workaround for issue https://github.com/microsoft/ClangSharp/issues/129 -->
223223
<RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == '' AND '$(PackAsTool)' != 'true'">$(NETCoreSdkRuntimeIdentifier)</RuntimeIdentifier>
224224
</PropertyGroup>
225225

226226
<ItemGroup>
227-
<PackageReference Include="CppAst" Version="0.13.0" />
227+
<PackageReference Include="CppAst" Version="LATEST_VERSION" />
228228
</ItemGroup>
229229

230230
</Project>
231231

232232
```
233-
也就是上面的 `RuntimeIdentifier` 项, 这个是必须的, 不然容易出现运行时找不到 libclang 的 native dll的报错.
233+
请将 `LATEST_VERSION` 替换为当前 NuGet 版本。上面的 `RuntimeIdentifier` 项建议保留,这样还原时会选择当前平台对应的 native libclang 资产。
234234

235235
#### 3.1.4 添加示例代码后测试运行对应的App
236236
**在Program.cs的Main()函数中添加测试代码:**
237237
```cs
238238
static void Main(string[] args)
239239
{
240-
// Parse a C++ files
240+
// Parse C++ files
241241
var compilation = CppParser.Parse(@"
242242
enum MyEnum { MyEnum_0, MyEnum_1 };
243243
void function0(int a, int b);
@@ -371,7 +371,7 @@ foo<int, int> foobar;
371371

372372
### 4.2 `meta attribute` 支持
373373
&emsp;&emsp;这一部分我们在CppAst.Net的代码仓库里添加了一个具体的文档 [attributes.md](https://github.com/xoofx/CppAst.NET/blob/main/doc/attributes.md), 感兴趣的读者可以自行查阅, 主要是用来解决上面提到的需要对某些导出项进行配置, 但又不希望代码项和配置信息分离的问题的, 原来 CppAst.Net 也有一版自己的基于再次 token parse 的 token attributes实现, 不过实际用于项目存在一些社区中比较多反馈的问题:
374-
1. `ParseAttributes()` 耗时巨大, 所以导致了后来的版本中加入了`ParseAttributes` 参数来控制是否解析 `attributes`, 但某些场合, 我们需要依赖 `attributes` 才能完成相关的功能实现. 这显然带来了不便.
374+
1. 基于 token 的 attribute 解析成本较高,因此当前版本将这条兼容路径改为通过 `CppParserOptions.ParseTokenAttributes` 按需开启。
375375

376376
2.`meta attribute` - `[[]]` 的解析存在缺陷, 像 `Function``Field` 上方定义的 `meta attribute`, 在语义层面, 显然是合法的, 但 `cppast.net` 并不能很好的支持这种在对象上方定义的`meta attribute` (这里存在一些例外情况, 像 `namespace`, `class`, `enum` 这些的 `attribute` 声明, attribute定义本身就不能位于上方, 相关的用法编译器会直接报错, 只能在相关的关键字后面, 如 `class [[deprecated]] Abc{};` 这种 ).
377377

doc/cn/attributes-cn.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## 1. `cppast.net 0.12``attributes` 支持情况
44
`cppast.net` 原有的对各类 `attribute` 的支持, 包括 `c++17``meta attribute` 的支持, 由于 `libclang` 本身 `Api` 的限制, 我们需要借助 token 层级的解析, 才能够完成相关的功能实现. 在 `cppast.net 0.12` 版本及以前的实现中, 我们都使用了解析 `token` 的方式来实现相关的功能, 甚至连一些 `libclang` 中能够很好的支持的 `attribute`, 如 `dllexport`, `dllimport` 等, `cppast.net` 大部分时候也是使用 token 解析来实现的. 这样做虽然灵活, 我们始终能够从 `token` 层级尝试解析相关的 `attribute`, 但也带来了一些问题和限制, 社区中比较多反馈的问题:
5-
1. `ParseAttributes()` 耗时巨大, 所以导致了后来的版本中加入了`ParseAttributes` 参数来控制是否解析 `attributes`, 但某些场合, 我们需要依赖 `attributes` 才能完成相关的功能实现. 这显然带来了不便.
5+
1. 基于 token 的 attribute 解析成本较高,因此后续版本将 fallback token 解析改为按需开启。在当前 CppAst 版本中,这条兼容路径由 `CppParserOptions.ParseTokenAttributes` 控制。
66
2.`meta attribute` - `[[]]` 的解析存在缺陷, 像 `Function``Field` 上方定义的 `meta attribute`, 在语义层面, 显然是合法的, 但 `cppast.net` 并不能很好的支持这种在对象上方定义的`meta attribute` (这里存在一些例外情况, 像 `namespace`, `class`, `enum` 这些的 `attribute` 声明, attribute定义本身就不能位于上方, 相关的用法编译器会直接报错, 只能在相关的关键字后面, 如 `class [[deprecated]] Abc{};` 这种 ).
77
3. `meta attribute` 个别参数使用宏的情况. 因为我们原有的实现是基于 `token` 解析来实现的, 编译期的宏显然不能很好的在这种情况下被正确处理.
88

@@ -19,7 +19,7 @@
1919
#define EXPORT_API __attribute__((visibility(""default"")))
2020
#endif
2121
```
22-
`dllexport``visibility` 这种控制接口可见性的 `attribute`, 我们肯定是比较常用的, 而不仅仅是只有在打开 `ParseAttributes` 的时候才让它能够工作, 我们需要为这些基础的系统属性提供高性能的解决方案, 而且相关的实现应该是不受开关影响的.
22+
`dllexport``visibility` 这种控制接口可见性的 `attribute` 非常常用,不应该依赖可选的 token 解析开关。当前 CppAst 会通过 `Attributes` 暴露支持的系统 attribute,而不需要开启 `ParseTokenAttributes`
2323

2424
---
2525
### 2.2 导出工具等工具额外的信息注入

0 commit comments

Comments
 (0)