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; |