| Index: tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
|
| diff --git a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
|
| index 28af4bc098c5aa62af72bed93d51b7b8f0cb722c..ff05e0712001ed921b54f09b9c1e63f2408cbfb7 100644
|
| --- a/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
|
| +++ b/tools/clang/blink_gc_plugin/BlinkGCPluginConsumer.cpp
|
| @@ -11,6 +11,7 @@
|
| #include "CheckFieldsVisitor.h"
|
| #include "CheckFinalizerVisitor.h"
|
| #include "CheckGCRootsVisitor.h"
|
| +#include "CheckSingletonVisitor.h"
|
| #include "CheckTraceVisitor.h"
|
| #include "CollectVisitor.h"
|
| #include "JsonWriter.h"
|
| @@ -87,7 +88,7 @@ void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) {
|
|
|
| ParseFunctionTemplates(context.getTranslationUnitDecl());
|
|
|
| - CollectVisitor visitor;
|
| + CollectVisitor visitor(options_.warn_singleton_with_scriptwrappables);
|
| visitor.TraverseDecl(context.getTranslationUnitDecl());
|
|
|
| if (options_.dump_graph) {
|
| @@ -120,6 +121,9 @@ void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) {
|
| for (const auto& method : visitor.trace_decls())
|
| CheckTracingMethod(method);
|
|
|
| + for (const auto& singleton : visitor.singleton_decls())
|
| + CheckStaticSingleton(singleton);
|
| +
|
| if (json_) {
|
| json_->CloseList();
|
| delete json_;
|
| @@ -564,6 +568,37 @@ void BlinkGCPluginConsumer::CheckTraceMethod(
|
| }
|
| }
|
|
|
| +void BlinkGCPluginConsumer::CheckStaticSingleton(clang::VarDecl* singleton) {
|
| + // Ignorance is a declaration-level annotation, so eagerly checked for
|
| + // before adding it to the processing set.
|
| + assert(!Config::IsIgnoreAnnotated(singleton));
|
| +
|
| + const Type* singleton_type = singleton->getType().getTypePtr();
|
| + if (singleton_type->isPointerType() || singleton_type->isReferenceType())
|
| + singleton_type = singleton_type->getPointeeType().getTypePtr();
|
| +
|
| + CXXRecordDecl* record = singleton_type->getAsCXXRecordDecl();
|
| + if (!record)
|
| + return;
|
| +
|
| + RecordInfo* info = cache_.Lookup(record);
|
| + if (!info)
|
| + return;
|
| +
|
| + // Walk over singleton type, looking for undesirable ScriptWrappable
|
| + // references.
|
| + CheckSingletonVisitor visitor;
|
| + if (!visitor.CheckIfSafe(info, singleton_type)) {
|
| + reporter_.StaticSingletonContainsScriptWrappable(singleton);
|
| + for (const auto& error : visitor.illegal_types()) {
|
| + reporter_.NoteUnsafeScriptWrappableField(
|
| + singleton, error.first,
|
| + QualType::getAsString(
|
| + error.second->getCanonicalTypeInternal().split()));
|
| + }
|
| + }
|
| +}
|
| +
|
| void BlinkGCPluginConsumer::DumpClass(RecordInfo* info) {
|
| if (!json_)
|
| return;
|
|
|