Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp

Issue 824853003: [BlinkGCPlugin] Allow tracing member in traceImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix segv Created 5 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // This clang plugin checks various invariants of the Blink garbage 5 // This clang plugin checks various invariants of the Blink garbage
6 // collection infrastructure. 6 // collection infrastructure.
7 // 7 //
8 // Errors are described at: 8 // Errors are described at:
9 // http://www.chromium.org/developers/blink-gc-plugin-errors 9 // http://www.chromium.org/developers/blink-gc-plugin-errors
10 10
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 RecordInfo* receiver_; 315 RecordInfo* receiver_;
316 bool dispatched_to_receiver_; 316 bool dispatched_to_receiver_;
317 }; 317 };
318 318
319 // This visitor checks a tracing method by traversing its body. 319 // This visitor checks a tracing method by traversing its body.
320 // - A member field is considered traced if it is referenced in the body. 320 // - A member field is considered traced if it is referenced in the body.
321 // - A base is traced if a base-qualified call to a trace method is found. 321 // - A base is traced if a base-qualified call to a trace method is found.
322 class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> { 322 class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
323 public: 323 public:
324 CheckTraceVisitor(CXXMethodDecl* trace, RecordInfo* info) 324 CheckTraceVisitor(CXXMethodDecl* trace, RecordInfo* info)
325 : trace_(trace), info_(info) {} 325 : trace_(trace), info_(info), delegates_to_traceimpl_(false) {}
326
327 bool delegates_to_traceimpl() const { return delegates_to_traceimpl_; }
326 328
327 bool VisitMemberExpr(MemberExpr* member) { 329 bool VisitMemberExpr(MemberExpr* member) {
328 // In weak callbacks, consider any occurrence as a correct usage. 330 // In weak callbacks, consider any occurrence as a correct usage.
329 // TODO: We really want to require that isAlive is checked on manually 331 // TODO: We really want to require that isAlive is checked on manually
330 // processed weak fields. 332 // processed weak fields.
331 if (IsWeakCallback()) { 333 if (IsWeakCallback()) {
332 if (FieldDecl* field = dyn_cast<FieldDecl>(member->getMemberDecl())) 334 if (FieldDecl* field = dyn_cast<FieldDecl>(member->getMemberDecl()))
333 FoundField(field); 335 FoundField(field);
334 } 336 }
335 return true; 337 return true;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 return true; 378 return true;
377 CXXRecordDecl* decl = base->getPointeeType()->getAsCXXRecordDecl(); 379 CXXRecordDecl* decl = base->getPointeeType()->getAsCXXRecordDecl();
378 if (decl) 380 if (decl)
379 CheckTraceFieldCall(expr->getMemberName().getAsString(), decl, arg); 381 CheckTraceFieldCall(expr->getMemberName().getAsString(), decl, arg);
380 return true; 382 return true;
381 } 383 }
382 384
383 if (CXXMemberCallExpr* expr = dyn_cast<CXXMemberCallExpr>(call)) { 385 if (CXXMemberCallExpr* expr = dyn_cast<CXXMemberCallExpr>(call)) {
384 if (CheckTraceFieldCall(expr) || CheckRegisterWeakMembers(expr)) 386 if (CheckTraceFieldCall(expr) || CheckRegisterWeakMembers(expr))
385 return true; 387 return true;
388
389 if (expr->getMethodDecl()->getNameAsString() == kTraceImplName) {
390 delegates_to_traceimpl_ = true;
391 return true;
392 }
386 } 393 }
387 394
388 CheckTraceBaseCall(call); 395 CheckTraceBaseCall(call);
389 return true; 396 return true;
390 } 397 }
391 398
392 private: 399 private:
393 400
394 CXXRecordDecl* GetDependentTemplatedDecl(CXXDependentScopeMemberExpr* expr) { 401 CXXRecordDecl* GetDependentTemplatedDecl(CXXDependentScopeMemberExpr* expr) {
395 NestedNameSpecifier* qual = expr->getQualifier(); 402 NestedNameSpecifier* qual = expr->getQualifier();
(...skipping 12 matching lines...) Expand all
408 TemplateDecl* tmpl_decl = tmpl_type->getTemplateName().getAsTemplateDecl(); 415 TemplateDecl* tmpl_decl = tmpl_type->getTemplateName().getAsTemplateDecl();
409 if (!tmpl_decl) 416 if (!tmpl_decl)
410 return 0; 417 return 0;
411 418
412 return dyn_cast<CXXRecordDecl>(tmpl_decl->getTemplatedDecl()); 419 return dyn_cast<CXXRecordDecl>(tmpl_decl->getTemplatedDecl());
413 } 420 }
414 421
415 void CheckCXXDependentScopeMemberExpr(CallExpr* call, 422 void CheckCXXDependentScopeMemberExpr(CallExpr* call,
416 CXXDependentScopeMemberExpr* expr) { 423 CXXDependentScopeMemberExpr* expr) {
417 string fn_name = expr->getMember().getAsString(); 424 string fn_name = expr->getMember().getAsString();
425
426 // Check for VisitorDispatcher::trace(field)
427 if (!expr->isImplicitAccess()) {
428 if (clang::DeclRefExpr* base_decl =
429 clang::dyn_cast<clang::DeclRefExpr>(expr->getBase())) {
430 if (Config::IsVisitorDispatcherType(base_decl->getType()) &&
431 call->getNumArgs() == 1 && fn_name == kTraceName) {
432 FindFieldVisitor finder;
433 finder.TraverseStmt(call->getArg(0));
434 if (finder.field())
435 FoundField(finder.field());
436
437 return;
438 }
439 }
440 }
441
418 CXXRecordDecl* tmpl = GetDependentTemplatedDecl(expr); 442 CXXRecordDecl* tmpl = GetDependentTemplatedDecl(expr);
419 if (!tmpl) 443 if (!tmpl)
420 return; 444 return;
421 445
422 // Check for Super<T>::trace(visitor) 446 // Check for Super<T>::trace(visitor)
423 if (call->getNumArgs() == 1 && fn_name == trace_->getName()) { 447 if (call->getNumArgs() == 1 && fn_name == trace_->getName()) {
424 RecordInfo::Bases::iterator it = info_->GetBases().begin(); 448 RecordInfo::Bases::iterator it = info_->GetBases().begin();
425 for (; it != info_->GetBases().end(); ++it) { 449 for (; it != info_->GetBases().end(); ++it) {
426 if (it->first->getName() == tmpl->getName()) 450 if (it->first->getName() == tmpl->getName())
427 it->second.MarkTraced(); 451 it->second.MarkTraced();
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 } 582 }
559 } else { 583 } else {
560 RecordInfo::Fields::iterator it = info_->GetFields().find(field); 584 RecordInfo::Fields::iterator it = info_->GetFields().find(field);
561 if (it != info_->GetFields().end()) 585 if (it != info_->GetFields().end())
562 MarkTraced(it); 586 MarkTraced(it);
563 } 587 }
564 } 588 }
565 589
566 CXXMethodDecl* trace_; 590 CXXMethodDecl* trace_;
567 RecordInfo* info_; 591 RecordInfo* info_;
592 bool delegates_to_traceimpl_;
568 }; 593 };
569 594
570 // This visitor checks that the fields of a class and the fields of 595 // This visitor checks that the fields of a class and the fields of
571 // its part objects don't define GC roots. 596 // its part objects don't define GC roots.
572 class CheckGCRootsVisitor : public RecursiveEdgeVisitor { 597 class CheckGCRootsVisitor : public RecursiveEdgeVisitor {
573 public: 598 public:
574 typedef std::vector<FieldPoint*> RootPath; 599 typedef std::vector<FieldPoint*> RootPath;
575 typedef std::set<RecordInfo*> VisitingSet; 600 typedef std::set<RecordInfo*> VisitingSet;
576 typedef std::vector<RootPath> Errors; 601 typedef std::vector<RootPath> Errors;
577 602
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 ++it) { 1321 ++it) {
1297 RecordInfo* base = it->second.info(); 1322 RecordInfo* base = it->second.info();
1298 if (CXXMethodDecl* other = base->InheritsNonVirtualTrace()) 1323 if (CXXMethodDecl* other = base->InheritsNonVirtualTrace())
1299 ReportOverriddenNonVirtualTrace(parent, trace, other); 1324 ReportOverriddenNonVirtualTrace(parent, trace, other);
1300 } 1325 }
1301 } 1326 }
1302 1327
1303 CheckTraceVisitor visitor(trace, parent); 1328 CheckTraceVisitor visitor(trace, parent);
1304 visitor.TraverseCXXMethodDecl(trace); 1329 visitor.TraverseCXXMethodDecl(trace);
1305 1330
1331 // Skip reporting if this trace method is a just delegate to
1332 // traceImplmethod.
Yuta Kitamura 2014/12/24 06:31:18 nit: space between "traceImpl" and "method"
kouhei (in TOK) 2014/12/24 09:03:04 Done.
1333 // We will report on CheckTraceMethod on traceImpl method.
1334 if (visitor.delegates_to_traceimpl())
1335 return;
1336
1306 for (RecordInfo::Bases::iterator it = parent->GetBases().begin(); 1337 for (RecordInfo::Bases::iterator it = parent->GetBases().begin();
1307 it != parent->GetBases().end(); 1338 it != parent->GetBases().end();
1308 ++it) { 1339 ++it) {
1309 if (!it->second.IsProperlyTraced()) 1340 if (!it->second.IsProperlyTraced())
1310 ReportBaseRequiresTracing(parent, trace, it->first); 1341 ReportBaseRequiresTracing(parent, trace, it->first);
1311 } 1342 }
1312 1343
1313 for (RecordInfo::Fields::iterator it = parent->GetFields().begin(); 1344 for (RecordInfo::Fields::iterator it = parent->GetFields().begin();
1314 it != parent->GetFields().end(); 1345 it != parent->GetFields().end();
1315 ++it) { 1346 ++it) {
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
1887 1918
1888 private: 1919 private:
1889 BlinkGCPluginOptions options_; 1920 BlinkGCPluginOptions options_;
1890 }; 1921 };
1891 1922
1892 } // namespace 1923 } // namespace
1893 1924
1894 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( 1925 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X(
1895 "blink-gc-plugin", 1926 "blink-gc-plugin",
1896 "Check Blink GC invariants"); 1927 "Check Blink GC invariants");
OLDNEW
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/Config.h » ('j') | tools/clang/blink_gc_plugin/Config.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698