I've noticed that RecursionResolvingBinding gets created large
number of times during indexing. Here is a code fragment extracted from
stdio.h that triggers one of the cases:
typedef struct _IO_FILE FILE;
struct _IO_FILE {
struct _IO_FILE *_chain;
};
int fclose(FILE *__stream);
Here's the stack with recursion:
Thread [Worker-1] (Suspended (breakpoint at line 48 in
CPPASTName$RecursionResolvingBinding))
CPPASTName$RecursionResolvingBinding.<init>(IASTName) line:
48
CPPASTName.resolveBinding() line: 74
CPPASTElaboratedTypeSpecifier.getRoleForName(IASTName) line:
95
CPPASTName.isReference() line: 235
CPPSemantics.resolveAmbiguities(LookupData, IASTName) line:
1653
CPPSemantics.resolveAmbiguities(IASTName, Object[]) line:
1530
CPPNamespaceScope(CPPScope).getBindingInAST(IASTName,
boolean) line: 212
CPPNamespaceScope(CPPScope).getBinding(IASTName, boolean,
IIndexFileSet) line: 136
CPPSemantics.lookup(LookupData, Object) line: 679
CPPSemantics.resolveBinding(IASTName) line: 172
CPPVisitor.createBinding(ICPPASTElaboratedTypeSpecifier)
line: 343
CPPVisitor.createBinding(IASTName) line: 237
CPPASTName.resolveBinding() line: 77
CPPASTElaboratedTypeSpecifier.getRoleForName(IASTName) line:
95
CPPASTName.isReference() line: 235
CPPSemantics.resolveAmbiguities(LookupData, IASTName) line:
1653
CPPSemantics.resolveAmbiguities(IASTName, Object[]) line:
1530
CPPNamespaceScope(CPPScope).getBindingInAST(IASTName,
boolean) line: 212
CPPNamespaceScope(CPPScope).getBinding(IASTName, boolean,
IIndexFileSet) line: 136
CPPSemantics.lookup(LookupData, Object) line: 679
CPPSemantics.resolveBinding(IASTName) line: 172
CPPVisitor.createBinding(ICPPASTElaboratedTypeSpecifier)
line: 343
CPPVisitor.createBinding(IASTName) line: 237
CPPASTName.resolveBinding() line: 77
CPPASTElaboratedTypeSpecifier.getRoleForName(IASTName) line:
95
CPPASTName.isReference() line: 235
CPPSemantics.resolveAmbiguities(LookupData, IASTName) line:
1653
CPPSemantics.resolveAmbiguities(IASTName, Object[]) line:
1530
CPPNamespaceScope(CPPScope).getBindingInAST(IASTName,
boolean) line: 212
CPPNamespaceScope(CPPScope).getBinding(IASTName, boolean,
IIndexFileSet) line: 136
CPPSemantics.lookup(LookupData, Object) line: 679
CPPSemantics.resolveBinding(IASTName) line: 172
CPPVisitor.createBinding(ICPPASTElaboratedTypeSpecifier)
line: 343
CPPVisitor.createBinding(IASTName) line: 237
CPPASTName.resolveBinding() line: 77
CPPASTElaboratedTypeSpecifier.getRoleForName(IASTName) line:
95
CPPASTName.isReference() line: 235
CPPSemantics.resolveAmbiguities(LookupData, IASTName) line:
1653
CPPSemantics.resolveAmbiguities(IASTName, Object[]) line:
1530
CPPNamespaceScope(CPPScope).getBindingInAST(IASTName,
boolean) line: 212
CPPNamespaceScope(CPPScope).getBinding(IASTName, boolean,
IIndexFileSet) line: 136
CPPSemantics.lookup(LookupData, Object) line: 679
CPPSemantics.resolveBinding(IASTName) line: 172
CPPVisitor.createBinding(ICPPASTElaboratedTypeSpecifier)
line: 343
CPPVisitor.createBinding(IASTName) line: 237
CPPASTName.resolveBinding() line: 77
CPPASTElaboratedTypeSpecifier.getRoleForName(IASTName) line:
95
CPPASTName.isReference() line: 235
CPPSemantics.resolveAmbiguities(LookupData, IASTName) line:
1653
CPPSemantics.resolveAmbiguities(IASTName, Object[]) line:
1530
CPPNamespaceScope(CPPScope).getBindingInAST(IASTName,
boolean) line: 212
CPPNamespaceScope(CPPScope).getBinding(IASTName, boolean,
IIndexFileSet) line: 136
CPPSemantics.lookup(LookupData, Object) line: 679
CPPSemantics.resolveBinding(IASTName) line: 172
CPPVisitor.createBinding(ICPPASTElaboratedTypeSpecifier)
line: 343
CPPVisitor.createBinding(IASTName) line: 237
CPPASTName.resolveBinding() line: 77
PDOMFastIndexerTask(PDOMWriter).resolveNames(Map<IIndexFileLocation,Symb
ols>, IIndexFileLocation[], ArrayList<IStatus>, IProgressMonitor) line:
236
PDOMFastIndexerTask(PDOMWriter).addSymbols(IASTTranslationUnit,
IIndexFileLocation[], IWritableIndex, int, boolean, int,
ITodoTaskUpdater, IProgressMonitor) line: 150
PDOMFastIndexerTask(AbstractIndexerTask).writeToIndex(int,
IASTTranslationUnit, int, IProgressMonitor) line: 634
PDOMFastIndexerTask(AbstractIndexerTask).parseFile(Object,
int, IIndexFileLocation, IScannerInfo, IProgressMonitor) line: 599
PDOMFastIndexerTask(AbstractIndexerTask).parseLinkage(int,
Map<Integer,List<Object>>, IProgressMonitor) line: 485
PDOMFastIndexerTask(AbstractIndexerTask).runTask(IProgressMonitor) line:
235
PDOMFastIndexerTask(PDOMIndexerTask).run(IProgressMonitor)
line: 109
PDOMIndexerJob.run(IProgressMonitor) line: 94
Worker.run() line: 55
The name being resolved is _IO_FILE inside the typedef.
It's interesting that the resulting AST doesn't contain any
problem bindings. Still, creation of an intermediate
RecursionResolvingBinding doesn't look right. I suspect that 5 recursive
calls leading to creation of a RecursionResolvingBinding cause
significant overhead and should better be avoided. It looks like on real
code base some RecursionResolvingBindings do remain in AST and become
user-visible problems, but I'm not sure if they have similar causes or
not.
I tried to reproduce creation of RecursionResolvingBinding in a
test, but surprisingly the same code inside a test doesn't trigger a
RecursionResolvingBinding.
Please let me know if routine creation of
RecursionResolvingBinding is expected or not.
-sergey