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

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

Issue 940263004: BlinkGCPlugin: Add support for traceAfterDispatchImpl(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adjust switch-case order. Created 5 years, 10 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
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/Config.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 194
195 // Collect record declarations, including nested declarations. 195 // Collect record declarations, including nested declarations.
196 bool VisitCXXRecordDecl(CXXRecordDecl* record) { 196 bool VisitCXXRecordDecl(CXXRecordDecl* record) {
197 if (record->hasDefinition() && record->isCompleteDefinition()) 197 if (record->hasDefinition() && record->isCompleteDefinition())
198 record_decls_.push_back(record); 198 record_decls_.push_back(record);
199 return true; 199 return true;
200 } 200 }
201 201
202 // Collect tracing method definitions, but don't traverse method bodies. 202 // Collect tracing method definitions, but don't traverse method bodies.
203 bool TraverseCXXMethodDecl(CXXMethodDecl* method) { 203 bool TraverseCXXMethodDecl(CXXMethodDecl* method) {
204 if (method->isThisDeclarationADefinition() && 204 if (method->isThisDeclarationADefinition() && Config::IsTraceMethod(method))
205 Config::IsTraceMethod(method, nullptr))
206 trace_decls_.push_back(method); 205 trace_decls_.push_back(method);
207 return true; 206 return true;
208 } 207 }
209 208
210 private: 209 private:
211 RecordVector record_decls_; 210 RecordVector record_decls_;
212 MethodVector trace_decls_; 211 MethodVector trace_decls_;
213 }; 212 };
214 213
215 // This visitor checks that a finalizer method does not have invalid access to 214 // This visitor checks that a finalizer method does not have invalid access to
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 it->second.MarkTraced(); 376 it->second.MarkTraced();
378 } 377 }
379 } 378 }
380 379
381 QualType base = expr->getBaseType(); 380 QualType base = expr->getBaseType();
382 if (!base->isPointerType()) 381 if (!base->isPointerType())
383 return true; 382 return true;
384 CXXRecordDecl* decl = base->getPointeeType()->getAsCXXRecordDecl(); 383 CXXRecordDecl* decl = base->getPointeeType()->getAsCXXRecordDecl();
385 if (decl) 384 if (decl)
386 CheckTraceFieldCall(expr->getMemberName().getAsString(), decl, arg); 385 CheckTraceFieldCall(expr->getMemberName().getAsString(), decl, arg);
387 if (expr->getMemberName().getAsString() == kTraceImplName) 386 if (Config::IsTraceImplName(expr->getMemberName().getAsString()))
388 delegates_to_traceimpl_ = true; 387 delegates_to_traceimpl_ = true;
389 return true; 388 return true;
390 } 389 }
391 390
392 if (CXXMemberCallExpr* expr = dyn_cast<CXXMemberCallExpr>(call)) { 391 if (CXXMemberCallExpr* expr = dyn_cast<CXXMemberCallExpr>(call)) {
393 if (CheckTraceFieldCall(expr) || CheckRegisterWeakMembers(expr)) 392 if (CheckTraceFieldCall(expr) || CheckRegisterWeakMembers(expr))
394 return true; 393 return true;
395 394
396 if (expr->getMethodDecl()->getNameAsString() == kTraceImplName) { 395 if (Config::IsTraceImplName(expr->getMethodDecl()->getNameAsString())) {
397 delegates_to_traceimpl_ = true; 396 delegates_to_traceimpl_ = true;
398 return true; 397 return true;
399 } 398 }
400 } 399 }
401 400
402 CheckTraceBaseCall(call); 401 CheckTraceBaseCall(call);
403 return true; 402 return true;
404 } 403 }
405 404
406 private: 405 private:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 FoundField(finder.field()); 459 FoundField(finder.field());
461 } 460 }
462 } 461 }
463 462
464 bool CheckTraceBaseCall(CallExpr* call) { 463 bool CheckTraceBaseCall(CallExpr* call) {
465 MemberExpr* callee = dyn_cast<MemberExpr>(call->getCallee()); 464 MemberExpr* callee = dyn_cast<MemberExpr>(call->getCallee());
466 if (!callee) 465 if (!callee)
467 return false; 466 return false;
468 467
469 FunctionDecl* fn = dyn_cast<FunctionDecl>(callee->getMemberDecl()); 468 FunctionDecl* fn = dyn_cast<FunctionDecl>(callee->getMemberDecl());
470 if (!fn || !Config::IsTraceMethod(fn, nullptr)) 469 if (!fn || !Config::IsTraceMethod(fn))
471 return false; 470 return false;
472 471
473 if (trace_->getName() == kTraceImplName) { 472 if (trace_->getName() == kTraceImplName) {
474 if (fn->getName() != kTraceName) 473 if (fn->getName() != kTraceName)
475 return false; 474 return false;
475 } else if (trace_->getName() == kTraceAfterDispatchImplName) {
476 if (fn->getName() != kTraceAfterDispatchName)
477 return false;
476 } else { 478 } else {
477 // Currently, a manually dispatched class cannot have mixin bases (having 479 // Currently, a manually dispatched class cannot have mixin bases (having
478 // one would add a vtable which we explicitly check against). This means 480 // one would add a vtable which we explicitly check against). This means
479 // that we can only make calls to a trace method of the same name. Revisit 481 // that we can only make calls to a trace method of the same name. Revisit
480 // this if our mixin/vtable assumption changes. 482 // this if our mixin/vtable assumption changes.
481 if (fn->getName() != trace_->getName()) 483 if (fn->getName() != trace_->getName())
482 return false; 484 return false;
483 } 485 }
484 486
485 CXXRecordDecl* decl = 0; 487 CXXRecordDecl* decl = 0;
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 CheckTraceOrDispatchMethod(cache_.Lookup(*it), method); 1308 CheckTraceOrDispatchMethod(cache_.Lookup(*it), method);
1307 } 1309 }
1308 return; 1310 return;
1309 } 1311 }
1310 1312
1311 CheckTraceOrDispatchMethod(parent, method); 1313 CheckTraceOrDispatchMethod(parent, method);
1312 } 1314 }
1313 1315
1314 // Determine what type of tracing method this is (dispatch or trace). 1316 // Determine what type of tracing method this is (dispatch or trace).
1315 void CheckTraceOrDispatchMethod(RecordInfo* parent, CXXMethodDecl* method) { 1317 void CheckTraceOrDispatchMethod(RecordInfo* parent, CXXMethodDecl* method) {
1316 bool isTraceAfterDispatch; 1318 Config::TraceMethodType trace_type = Config::GetTraceMethodType(method);
1317 if (Config::IsTraceMethod(method, &isTraceAfterDispatch)) { 1319 if (trace_type != Config::TRACE_METHOD ||
1318 if (isTraceAfterDispatch || !parent->GetTraceDispatchMethod()) { 1320 !parent->GetTraceDispatchMethod()) {
1319 CheckTraceMethod(parent, method, isTraceAfterDispatch); 1321 CheckTraceMethod(parent, method, trace_type);
1320 }
1321 // Dispatch methods are checked when we identify subclasses.
1322 } 1322 }
1323 // Dispatch methods are checked when we identify subclasses.
1323 } 1324 }
1324 1325
1325 // Check an actual trace method. 1326 // Check an actual trace method.
1326 void CheckTraceMethod(RecordInfo* parent, 1327 void CheckTraceMethod(RecordInfo* parent,
1327 CXXMethodDecl* trace, 1328 CXXMethodDecl* trace,
1328 bool isTraceAfterDispatch) { 1329 Config::TraceMethodType trace_type) {
1329 // A trace method must not override any non-virtual trace methods. 1330 // A trace method must not override any non-virtual trace methods.
1330 if (!isTraceAfterDispatch) { 1331 if (trace_type == Config::TRACE_METHOD) {
1331 for (RecordInfo::Bases::iterator it = parent->GetBases().begin(); 1332 for (RecordInfo::Bases::iterator it = parent->GetBases().begin();
1332 it != parent->GetBases().end(); 1333 it != parent->GetBases().end();
1333 ++it) { 1334 ++it) {
1334 RecordInfo* base = it->second.info(); 1335 RecordInfo* base = it->second.info();
1335 if (CXXMethodDecl* other = base->InheritsNonVirtualTrace()) 1336 if (CXXMethodDecl* other = base->InheritsNonVirtualTrace())
1336 ReportOverriddenNonVirtualTrace(parent, trace, other); 1337 ReportOverriddenNonVirtualTrace(parent, trace, other);
1337 } 1338 }
1338 } 1339 }
1339 1340
1340 CheckTraceVisitor visitor(trace, parent); 1341 CheckTraceVisitor visitor(trace, parent);
1341 visitor.TraverseCXXMethodDecl(trace); 1342 visitor.TraverseCXXMethodDecl(trace);
1342 1343
1343 // Skip reporting if this trace method is a just delegate to 1344 // Skip reporting if this trace method is a just delegate to
1344 // traceImpl method. We will report on CheckTraceMethod on traceImpl method. 1345 // traceImpl (or traceAfterDispatchImpl) method. We will report on
1346 // CheckTraceMethod on traceImpl method.
1345 if (visitor.delegates_to_traceimpl()) 1347 if (visitor.delegates_to_traceimpl())
1346 return; 1348 return;
1347 1349
1348 for (RecordInfo::Bases::iterator it = parent->GetBases().begin(); 1350 for (RecordInfo::Bases::iterator it = parent->GetBases().begin();
1349 it != parent->GetBases().end(); 1351 it != parent->GetBases().end();
1350 ++it) { 1352 ++it) {
1351 if (!it->second.IsProperlyTraced()) 1353 if (!it->second.IsProperlyTraced())
1352 ReportBaseRequiresTracing(parent, trace, it->first); 1354 ReportBaseRequiresTracing(parent, trace, it->first);
1353 } 1355 }
1354 1356
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 1941
1940 private: 1942 private:
1941 BlinkGCPluginOptions options_; 1943 BlinkGCPluginOptions options_;
1942 }; 1944 };
1943 1945
1944 } // namespace 1946 } // namespace
1945 1947
1946 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( 1948 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X(
1947 "blink-gc-plugin", 1949 "blink-gc-plugin",
1948 "Check Blink GC invariants"); 1950 "Check Blink GC invariants");
OLDNEW
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/Config.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698