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

Unified Diff: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp

Issue 960873002: Update from https://crrev.com/318214 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/android/adb_remote_setup.sh ('k') | tools/clang/blink_gc_plugin/Config.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
index 7dae3810150a394785d0f80835ba81534bccac30..85cf08671894c966f8c74c392c9bcf54aff0e473 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
+++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
@@ -201,8 +201,7 @@ class CollectVisitor : public RecursiveASTVisitor<CollectVisitor> {
// Collect tracing method definitions, but don't traverse method bodies.
bool TraverseCXXMethodDecl(CXXMethodDecl* method) {
- if (method->isThisDeclarationADefinition() &&
- Config::IsTraceMethod(method, nullptr))
+ if (method->isThisDeclarationADefinition() && Config::IsTraceMethod(method))
trace_decls_.push_back(method);
return true;
}
@@ -366,6 +365,11 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
Expr* arg = call->getArg(0);
if (UnresolvedMemberExpr* expr = dyn_cast<UnresolvedMemberExpr>(callee)) {
+ // This could be a trace call of a base class, as explained in the
+ // comments of CheckTraceBaseCall().
+ if (CheckTraceBaseCall(call))
+ return true;
+
// If we find a call to registerWeakMembers which is unresolved we
// unsoundly consider all weak members as traced.
// TODO: Find out how to validate weak member tracing for unresolved call.
@@ -384,7 +388,7 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
CXXRecordDecl* decl = base->getPointeeType()->getAsCXXRecordDecl();
if (decl)
CheckTraceFieldCall(expr->getMemberName().getAsString(), decl, arg);
- if (expr->getMemberName().getAsString() == kTraceImplName)
+ if (Config::IsTraceImplName(expr->getMemberName().getAsString()))
delegates_to_traceimpl_ = true;
return true;
}
@@ -393,7 +397,7 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
if (CheckTraceFieldCall(expr) || CheckRegisterWeakMembers(expr))
return true;
- if (expr->getMethodDecl()->getNameAsString() == kTraceImplName) {
+ if (Config::IsTraceImplName(expr->getMethodDecl()->getNameAsString())) {
delegates_to_traceimpl_ = true;
return true;
}
@@ -404,7 +408,6 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
}
private:
-
CXXRecordDecl* GetDependentTemplatedDecl(CXXDependentScopeMemberExpr* expr) {
NestedNameSpecifier* qual = expr->getQualifier();
if (!qual)
@@ -462,39 +465,87 @@ class CheckTraceVisitor : public RecursiveASTVisitor<CheckTraceVisitor> {
}
bool CheckTraceBaseCall(CallExpr* call) {
- MemberExpr* callee = dyn_cast<MemberExpr>(call->getCallee());
- if (!callee)
- return false;
+ // Checks for "Base::trace(visitor)"-like calls.
+
+ // Checking code for these two variables is shared among MemberExpr* case
+ // and UnresolvedMemberCase* case below.
+ //
+ // For example, if we've got "Base::trace(visitor)" as |call|,
+ // callee_record will be "Base", and func_name will be "trace".
+ CXXRecordDecl* callee_record = nullptr;
+ std::string func_name;
+
+ if (MemberExpr* callee = dyn_cast<MemberExpr>(call->getCallee())) {
+ if (!callee->hasQualifier())
+ return false;
- FunctionDecl* fn = dyn_cast<FunctionDecl>(callee->getMemberDecl());
- if (!fn || !Config::IsTraceMethod(fn, nullptr))
- return false;
+ FunctionDecl* trace_decl =
+ dyn_cast<FunctionDecl>(callee->getMemberDecl());
+ if (!trace_decl || !Config::IsTraceMethod(trace_decl))
+ return false;
+
+ const Type* type = callee->getQualifier()->getAsType();
+ if (!type)
+ return false;
+
+ callee_record = type->getAsCXXRecordDecl();
+ func_name = trace_decl->getName();
+ } else if (UnresolvedMemberExpr* callee =
+ dyn_cast<UnresolvedMemberExpr>(call->getCallee())) {
+ // Callee part may become unresolved if the type of the argument
+ // ("visitor") is a template parameter and the called function is
+ // overloaded (i.e. trace(Visitor*) and
+ // trace(InlinedGlobalMarkingVisitor)).
+ //
+ // Here, we try to find a function that looks like trace() from the
+ // candidate overloaded functions, and if we find one, we assume it is
+ // called here.
+
+ CXXMethodDecl* trace_decl = nullptr;
+ for (NamedDecl* named_decl : callee->decls()) {
+ if (CXXMethodDecl* method_decl = dyn_cast<CXXMethodDecl>(named_decl)) {
+ if (Config::IsTraceMethod(method_decl)) {
+ trace_decl = method_decl;
+ break;
+ }
+ }
+ }
+ if (!trace_decl)
+ return false;
+
+ // Check if the passed argument is named "visitor".
+ if (call->getNumArgs() != 1)
+ return false;
+ DeclRefExpr* arg = dyn_cast<DeclRefExpr>(call->getArg(0));
+ if (!arg || arg->getNameInfo().getAsString() != kVisitorVarName)
+ return false;
+
+ callee_record = trace_decl->getParent();
+ func_name = callee->getMemberName().getAsString();
+ }
if (trace_->getName() == kTraceImplName) {
- if (fn->getName() != kTraceName)
+ if (func_name != kTraceName)
+ return false;
+ } else if (trace_->getName() == kTraceAfterDispatchImplName) {
+ if (func_name != kTraceAfterDispatchName)
return false;
} else {
// Currently, a manually dispatched class cannot have mixin bases (having
// one would add a vtable which we explicitly check against). This means
// that we can only make calls to a trace method of the same name. Revisit
// this if our mixin/vtable assumption changes.
- if (fn->getName() != trace_->getName())
+ if (func_name != trace_->getName())
return false;
}
- CXXRecordDecl* decl = 0;
- if (callee && callee->hasQualifier()) {
- if (const Type* type = callee->getQualifier()->getAsType())
- decl = type->getAsCXXRecordDecl();
- }
- if (!decl)
+ if (!callee_record)
+ return false;
+ RecordInfo::Bases::iterator iter = info_->GetBases().find(callee_record);
+ if (iter == info_->GetBases().end())
return false;
- RecordInfo::Bases::iterator it = info_->GetBases().find(decl);
- if (it != info_->GetBases().end()) {
- it->second.MarkTraced();
- }
-
+ iter->second.MarkTraced();
return true;
}
@@ -1313,21 +1364,20 @@ class BlinkGCPluginConsumer : public ASTConsumer {
// Determine what type of tracing method this is (dispatch or trace).
void CheckTraceOrDispatchMethod(RecordInfo* parent, CXXMethodDecl* method) {
- bool isTraceAfterDispatch;
- if (Config::IsTraceMethod(method, &isTraceAfterDispatch)) {
- if (isTraceAfterDispatch || !parent->GetTraceDispatchMethod()) {
- CheckTraceMethod(parent, method, isTraceAfterDispatch);
- }
- // Dispatch methods are checked when we identify subclasses.
+ Config::TraceMethodType trace_type = Config::GetTraceMethodType(method);
+ if (trace_type != Config::TRACE_METHOD ||
+ !parent->GetTraceDispatchMethod()) {
+ CheckTraceMethod(parent, method, trace_type);
}
+ // Dispatch methods are checked when we identify subclasses.
}
// Check an actual trace method.
void CheckTraceMethod(RecordInfo* parent,
CXXMethodDecl* trace,
- bool isTraceAfterDispatch) {
+ Config::TraceMethodType trace_type) {
// A trace method must not override any non-virtual trace methods.
- if (!isTraceAfterDispatch) {
+ if (trace_type == Config::TRACE_METHOD) {
for (RecordInfo::Bases::iterator it = parent->GetBases().begin();
it != parent->GetBases().end();
++it) {
@@ -1341,7 +1391,8 @@ class BlinkGCPluginConsumer : public ASTConsumer {
visitor.TraverseCXXMethodDecl(trace);
// Skip reporting if this trace method is a just delegate to
- // traceImpl method. We will report on CheckTraceMethod on traceImpl method.
+ // traceImpl (or traceAfterDispatchImpl) method. We will report on
+ // CheckTraceMethod on traceImpl method.
if (visitor.delegates_to_traceimpl())
return;
« no previous file with comments | « tools/android/adb_remote_setup.sh ('k') | tools/clang/blink_gc_plugin/Config.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698