class CheckGCRootsVisitor : public RecursiveEdgeVisitor {
public:
typedef std::vector<FieldPoint*> RootPath;
+ typedef std::set<RecordInfo*> VisitingSet;
typedef std::vector<RootPath> Errors;
CheckGCRootsVisitor() {}
if (edge->value()->record()->isUnion())
return;
+ // Prevent infinite regress for cyclic part objects.
+ if (visiting_set_.find(edge->value()) != visiting_set_.end())
+ return;
+
+ visiting_set_.insert(edge->value());
// If the value is a part object, then continue checking for roots.
for (Context::iterator it = context().begin();
it != context().end();
return;
}
ContainsGCRoots(edge->value());
+ visiting_set_.erase(edge->value());
}
void VisitPersistent(Persistent* edge) override {
protected:
RootPath current_;
+ VisitingSet visiting_set_;
Errors gc_roots_;
};
}
void HandleTranslationUnit(ASTContext& context) override {
+ // Don't run the plugin if the compilation unit is already invalid.
+ if (diagnostic_.hasErrorOccurred())
+ return;
+
CollectVisitor visitor;
visitor.TraverseDecl(context.getTranslationUnitDecl());
// Check polymorphic classes that are GC-derived or have a trace method.
if (info->record()->hasDefinition() && info->record()->isPolymorphic()) {
+ // TODO: Check classes that inherit a trace method.
CXXMethodDecl* trace = info->GetTraceMethod();
if (trace || info->IsGCDerived())
CheckPolymorphicClass(info, trace);