CppContainerList throws "The item belongs already to a container" when parsing VTK 9.5 headers Body
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 620
- Forks
- 79
- Avg merge
- 14h 27m
- Merged PRs (30d)
- 1
Description
Description
When parsing VTK 9.5 headers with CppParser.ParseFile, an ArgumentException is thrown:
System.ArgumentException: The item belongs already to a container
at CppAst.CppContainerList`1.Add(TElement item)
at CppAst.CppContainerList`1.AddRange(IEnumerable`1 collection)
at CppAst.CppModelBuilder.GetCppTypeInternal(CXCursor cursor, CXType type, CXCursor parent, Void* data)
Reproduction
var options = new CppParserOptions();
options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64, CppVisualStudioVersion.VS2022);
options.IncludeFolders.Add(@"C:\Program Files\VTK\include\vtk-9.5");
var compilation = CppParser.ParseFile(@"C:\Program Files\VTK\include\vtk-9.5\vtkActor.h", options);
Environment: VTK 9.5 headers, CppAst 0.25.0, ClangSharp 21.1.8.3, Windows x64.
Root Cause
The problem is in CppContainerList<T>.Add() — it enforces strict single-parent ownership:
public void Add(TElement item)
{
if (item.Parent != null)
throw new ArgumentException("The item belongs already to a container");
...
}
During GetCppTypeInternal → CXType_Unexposed handling, ParseTemplateSpecializedArguments resolves template arguments that return type instances already belonging to a container (e.g., a CppClass that was added to compilation.Classes). When these same instances are added to CppUnexposedType.TemplateParameters via AddRange, the strict check fails.
The stack trace consistently points to:
GetCppTypeInternal → VisitElaboratedDecl → GetCppType → GetCppTypeInternal → VisitFunctionDecl → CppContainerList.AddRange
Suggested Fix
Relax Add and Insert to allow re-parenting. Skip duplicates in the same container, otherwise allow the element to move:
public void Add(TElement item)
{
if (item.Parent == Container)
return; // Already in this container
item.Parent = Container;
_elements.Add(item);
}
public void Insert(int index, TElement item)
{
if (item.Parent == Container)
return; // Already in this container
item.Parent = Container;
_elements.Insert(index, item);
}
This is the same approach taken by XML DOM implementations — a node can be moved from one parent to another without error.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with CppContainerList.Add and Insert, then trace CppModelBuilder.GetCppTypeInternal through CXType_Unexposed and ParseTemplateSpecializedArguments. Reproduce the failure by parsing vtkActor.h from VTK 9.5 with the shown options. Done means the header parses without the container ownership exception while duplicate and parent behavior remains covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, csharp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100