OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "BlinkGCPluginConsumer.h" | 5 #include "BlinkGCPluginConsumer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "CheckDispatchVisitor.h" | 10 #include "CheckDispatchVisitor.h" |
11 #include "CheckFieldsVisitor.h" | 11 #include "CheckFieldsVisitor.h" |
12 #include "CheckFinalizerVisitor.h" | 12 #include "CheckFinalizerVisitor.h" |
13 #include "CheckGCRootsVisitor.h" | 13 #include "CheckGCRootsVisitor.h" |
14 #include "CheckSingletonVisitor.h" | |
14 #include "CheckTraceVisitor.h" | 15 #include "CheckTraceVisitor.h" |
15 #include "CollectVisitor.h" | 16 #include "CollectVisitor.h" |
16 #include "JsonWriter.h" | 17 #include "JsonWriter.h" |
17 #include "RecordInfo.h" | 18 #include "RecordInfo.h" |
18 #include "clang/AST/RecursiveASTVisitor.h" | 19 #include "clang/AST/RecursiveASTVisitor.h" |
19 #include "clang/Sema/Sema.h" | 20 #include "clang/Sema/Sema.h" |
20 | 21 |
21 using namespace clang; | 22 using namespace clang; |
22 | 23 |
23 namespace { | 24 namespace { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 Config::UseLegacyNames(); | 81 Config::UseLegacyNames(); |
81 } | 82 } |
82 | 83 |
83 void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) { | 84 void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) { |
84 // Don't run the plugin if the compilation unit is already invalid. | 85 // Don't run the plugin if the compilation unit is already invalid. |
85 if (reporter_.hasErrorOccurred()) | 86 if (reporter_.hasErrorOccurred()) |
86 return; | 87 return; |
87 | 88 |
88 ParseFunctionTemplates(context.getTranslationUnitDecl()); | 89 ParseFunctionTemplates(context.getTranslationUnitDecl()); |
89 | 90 |
90 CollectVisitor visitor; | 91 CollectVisitor visitor(options_.warn_singleton_with_scriptwrappables); |
91 visitor.TraverseDecl(context.getTranslationUnitDecl()); | 92 visitor.TraverseDecl(context.getTranslationUnitDecl()); |
92 | 93 |
93 if (options_.dump_graph) { | 94 if (options_.dump_graph) { |
94 std::error_code err; | 95 std::error_code err; |
95 // TODO: Make createDefaultOutputFile or a shorter createOutputFile work. | 96 // TODO: Make createDefaultOutputFile or a shorter createOutputFile work. |
96 json_ = JsonWriter::from(instance_.createOutputFile( | 97 json_ = JsonWriter::from(instance_.createOutputFile( |
97 "", // OutputPath | 98 "", // OutputPath |
98 err, // Errors | 99 err, // Errors |
99 true, // Binary | 100 true, // Binary |
100 true, // RemoveFileOnSignal | 101 true, // RemoveFileOnSignal |
(...skipping 12 matching lines...) Expand all Loading... | |
113 << "Failed to create an output file for the object graph.\n"; | 114 << "Failed to create an output file for the object graph.\n"; |
114 } | 115 } |
115 } | 116 } |
116 | 117 |
117 for (const auto& record : visitor.record_decls()) | 118 for (const auto& record : visitor.record_decls()) |
118 CheckRecord(cache_.Lookup(record)); | 119 CheckRecord(cache_.Lookup(record)); |
119 | 120 |
120 for (const auto& method : visitor.trace_decls()) | 121 for (const auto& method : visitor.trace_decls()) |
121 CheckTracingMethod(method); | 122 CheckTracingMethod(method); |
122 | 123 |
124 for (const auto& singleton : visitor.singleton_decls()) | |
125 CheckStaticSingleton(singleton); | |
126 | |
123 if (json_) { | 127 if (json_) { |
124 json_->CloseList(); | 128 json_->CloseList(); |
125 delete json_; | 129 delete json_; |
126 json_ = 0; | 130 json_ = 0; |
127 } | 131 } |
128 } | 132 } |
129 | 133 |
130 void BlinkGCPluginConsumer::ParseFunctionTemplates(TranslationUnitDecl* decl) { | 134 void BlinkGCPluginConsumer::ParseFunctionTemplates(TranslationUnitDecl* decl) { |
131 if (!instance_.getLangOpts().DelayedTemplateParsing) | 135 if (!instance_.getLangOpts().DelayedTemplateParsing) |
132 return; // Nothing to do. | 136 return; // Nothing to do. |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
557 for (auto& field : parent->GetFields()) { | 561 for (auto& field : parent->GetFields()) { |
558 if (!field.second.IsProperlyTraced() || | 562 if (!field.second.IsProperlyTraced() || |
559 field.second.IsInproperlyTraced()) { | 563 field.second.IsInproperlyTraced()) { |
560 // Report one or more tracing-related field errors. | 564 // Report one or more tracing-related field errors. |
561 reporter_.FieldsImproperlyTraced(parent, trace); | 565 reporter_.FieldsImproperlyTraced(parent, trace); |
562 break; | 566 break; |
563 } | 567 } |
564 } | 568 } |
565 } | 569 } |
566 | 570 |
571 void BlinkGCPluginConsumer::CheckStaticSingleton(clang::VarDecl* singleton) { | |
572 // Ignorance is a declaration-level annotation, so eagerly checked for | |
573 // before adding it to the processing set. | |
574 assert(!Config::IsIgnoreAnnotated(singleton)); | |
575 | |
576 const Type* singleton_type = singleton->getType().getTypePtr(); | |
577 if (singleton_type->isPointerType() || singleton_type->isReferenceType()) | |
578 singleton_type = singleton_type->getPointeeType().getTypePtr(); | |
579 | |
580 CXXRecordDecl* record = singleton_type->getAsCXXRecordDecl(); | |
581 if (!record) | |
582 return; | |
583 | |
584 RecordInfo* info = cache_.Lookup(record); | |
585 if (!info) | |
586 return; | |
587 | |
588 // Walk over singleton type, looking for undesirable ScriptWrappable | |
589 // references. | |
590 CheckSingletonVisitor visitor; | |
591 if (!visitor.CheckIfSafe(info, singleton_type)) { | |
592 reporter_.StaticSingletonContainsScriptWrappable(singleton); | |
593 for (auto error : visitor.illegal_types()) { | |
dcheng
2017/02/16 04:35:51
const auto& to suppress a copy
sof
2017/02/16 06:45:34
done, thanks for catching that one.
| |
594 reporter_.NoteUnsafeScriptWrappableField( | |
595 singleton, error.first, | |
596 QualType::getAsString( | |
597 error.second->getCanonicalTypeInternal().split())); | |
598 } | |
599 } | |
600 } | |
601 | |
567 void BlinkGCPluginConsumer::DumpClass(RecordInfo* info) { | 602 void BlinkGCPluginConsumer::DumpClass(RecordInfo* info) { |
568 if (!json_) | 603 if (!json_) |
569 return; | 604 return; |
570 | 605 |
571 json_->OpenObject(); | 606 json_->OpenObject(); |
572 json_->Write("name", info->record()->getQualifiedNameAsString()); | 607 json_->Write("name", info->record()->getQualifiedNameAsString()); |
573 json_->Write("loc", GetLocString(info->record()->getLocStart())); | 608 json_->Write("loc", GetLocString(info->record()->getLocStart())); |
574 json_->CloseObject(); | 609 json_->CloseObject(); |
575 | 610 |
576 class DumpEdgeVisitor : public RecursiveEdgeVisitor { | 611 class DumpEdgeVisitor : public RecursiveEdgeVisitor { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
717 SourceLocation spelling_location = source_manager.getSpellingLoc(loc); | 752 SourceLocation spelling_location = source_manager.getSpellingLoc(loc); |
718 PresumedLoc ploc = source_manager.getPresumedLoc(spelling_location); | 753 PresumedLoc ploc = source_manager.getPresumedLoc(spelling_location); |
719 if (ploc.isInvalid()) { | 754 if (ploc.isInvalid()) { |
720 // If we're in an invalid location, we're looking at things that aren't | 755 // If we're in an invalid location, we're looking at things that aren't |
721 // actually stated in the source. | 756 // actually stated in the source. |
722 return false; | 757 return false; |
723 } | 758 } |
724 *filename = ploc.getFilename(); | 759 *filename = ploc.getFilename(); |
725 return true; | 760 return true; |
726 } | 761 } |
OLD | NEW |