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

Unified Diff: tools/clang/blink_gc_plugin/Config.h

Issue 1385193002: Bisect clang Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 246985 Created 5 years, 2 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/clang/blink_gc_plugin/CollectVisitor.cpp ('k') | tools/clang/blink_gc_plugin/Config.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/clang/blink_gc_plugin/Config.h
diff --git a/tools/clang/blink_gc_plugin/Config.h b/tools/clang/blink_gc_plugin/Config.h
new file mode 100644
index 0000000000000000000000000000000000000000..c62de053306072539003ef93baead1c3dd3a13db
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/Config.h
@@ -0,0 +1,272 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file defines the names used by GC infrastructure.
+
+// TODO: Restructure the name determination to use fully qualified names (ala,
+// blink::Foo) so that the plugin can be enabled for all of chromium. Doing so
+// would allow us to catch errors with structures outside of blink that might
+// have unsafe pointers to GC allocated blink structures.
+
+#ifndef TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
+#define TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
+
+#include <cassert>
+
+#include "clang/AST/AST.h"
+#include "clang/AST/Attr.h"
+
+const char kNewOperatorName[] = "operator new";
+const char kCreateName[] = "create";
+const char kTraceName[] = "trace";
+const char kTraceImplName[] = "traceImpl";
+const char kFinalizeName[] = "finalizeGarbageCollectedObject";
+const char kTraceAfterDispatchName[] = "traceAfterDispatch";
+const char kTraceAfterDispatchImplName[] = "traceAfterDispatchImpl";
+const char kRegisterWeakMembersName[] = "registerWeakMembers";
+const char kHeapAllocatorName[] = "HeapAllocator";
+const char kTraceIfNeededName[] = "TraceIfNeeded";
+const char kVisitorDispatcherName[] = "VisitorDispatcher";
+const char kVisitorVarName[] = "visitor";
+const char kAdjustAndMarkName[] = "adjustAndMark";
+const char kIsHeapObjectAliveName[] = "isHeapObjectAlive";
+const char kIsEagerlyFinalizedName[] = "IsEagerlyFinalizedMarker";
+
+class Config {
+ public:
+ static bool IsMember(const std::string& name) {
+ return name == "Member";
+ }
+
+ static bool IsWeakMember(const std::string& name) {
+ return name == "WeakMember";
+ }
+
+ static bool IsMemberHandle(const std::string& name) {
+ return IsMember(name) ||
+ IsWeakMember(name);
+ }
+
+ static bool IsPersistent(const std::string& name) {
+ return name == "Persistent";
+ }
+
+ static bool IsPersistentHandle(const std::string& name) {
+ return IsPersistent(name) ||
+ IsPersistentGCCollection(name);
+ }
+
+ static bool IsRawPtr(const std::string& name) {
+ return name == "RawPtr";
+ }
+
+ static bool IsRefPtr(const std::string& name) {
+ return name == "RefPtr";
+ }
+
+ static bool IsOwnPtr(const std::string& name) {
+ return name == "OwnPtr";
+ }
+
+ static bool IsWTFCollection(const std::string& name) {
+ return name == "Vector" ||
+ name == "Deque" ||
+ name == "HashSet" ||
+ name == "ListHashSet" ||
+ name == "LinkedHashSet" ||
+ name == "HashCountedSet" ||
+ name == "HashMap";
+ }
+
+ static bool IsGCCollection(const std::string& name) {
+ return name == "HeapVector" ||
+ name == "HeapDeque" ||
+ name == "HeapHashSet" ||
+ name == "HeapListHashSet" ||
+ name == "HeapLinkedHashSet" ||
+ name == "HeapHashCountedSet" ||
+ name == "HeapHashMap" ||
+ IsPersistentGCCollection(name);
+ }
+
+ static bool IsPersistentGCCollection(const std::string& name) {
+ return name == "PersistentHeapVector" ||
+ name == "PersistentHeapDeque" ||
+ name == "PersistentHeapHashSet" ||
+ name == "PersistentHeapListHashSet" ||
+ name == "PersistentHeapLinkedHashSet" ||
+ name == "PersistentHeapHashCountedSet" ||
+ name == "PersistentHeapHashMap";
+ }
+
+ static bool IsHashMap(const std::string& name) {
+ return name == "HashMap" ||
+ name == "HeapHashMap" ||
+ name == "PersistentHeapHashMap";
+ }
+
+ // Following http://crrev.com/369633033 (Blink r177436),
+ // ignore blink::ScriptWrappable's destructor.
+ // TODO: remove when its non-Oilpan destructor is removed.
+ static bool HasIgnorableDestructor(const std::string& ns,
+ const std::string& name) {
+ return ns == "blink" && name == "ScriptWrappable";
+ }
+
+ // Assumes name is a valid collection name.
+ static size_t CollectionDimension(const std::string& name) {
+ return (IsHashMap(name) || name == "pair") ? 2 : 1;
+ }
+
+ static bool IsDummyBase(const std::string& name) {
+ return name == "DummyBase";
+ }
+
+ static bool IsRefCountedBase(const std::string& name) {
+ return name == "RefCounted" ||
+ name == "ThreadSafeRefCounted";
+ }
+
+ static bool IsGCMixinBase(const std::string& name) {
+ return name == "GarbageCollectedMixin";
+ }
+
+ static bool IsGCFinalizedBase(const std::string& name) {
+ return name == "GarbageCollectedFinalized" ||
+ name == "RefCountedGarbageCollected" ||
+ name == "ThreadSafeRefCountedGarbageCollected";
+ }
+
+ static bool IsGCBase(const std::string& name) {
+ return name == "GarbageCollected" ||
+ IsGCFinalizedBase(name) ||
+ IsGCMixinBase(name);
+ }
+
+ // Returns true of the base classes that do not need a vtable entry for trace
+ // because they cannot possibly initiate a GC during construction.
+ static bool IsSafePolymorphicBase(const std::string& name) {
+ return IsGCBase(name) || IsDummyBase(name) || IsRefCountedBase(name);
+ }
+
+ static bool IsAnnotated(clang::Decl* decl, const std::string& anno) {
+ clang::AnnotateAttr* attr = decl->getAttr<clang::AnnotateAttr>();
+ return attr && (attr->getAnnotation() == anno);
+ }
+
+ static bool IsStackAnnotated(clang::Decl* decl) {
+ return IsAnnotated(decl, "blink_stack_allocated");
+ }
+
+ static bool IsIgnoreAnnotated(clang::Decl* decl) {
+ return IsAnnotated(decl, "blink_gc_plugin_ignore");
+ }
+
+ static bool IsIgnoreCycleAnnotated(clang::Decl* decl) {
+ return IsAnnotated(decl, "blink_gc_plugin_ignore_cycle") ||
+ IsIgnoreAnnotated(decl);
+ }
+
+ static bool IsVisitor(const std::string& name) {
+ return name == "Visitor" || name == "VisitorHelper";
+ }
+
+ static bool IsVisitorPtrType(const clang::QualType& formal_type) {
+ if (!formal_type->isPointerType())
+ return false;
+
+ clang::CXXRecordDecl* pointee_type =
+ formal_type->getPointeeType()->getAsCXXRecordDecl();
+ if (!pointee_type)
+ return false;
+
+ if (!IsVisitor(pointee_type->getName()))
+ return false;
+
+ return true;
+ }
+
+ static bool IsVisitorDispatcherType(const clang::QualType& formal_type) {
+ if (const clang::SubstTemplateTypeParmType* subst_type =
+ clang::dyn_cast<clang::SubstTemplateTypeParmType>(
+ formal_type.getTypePtr())) {
+ if (IsVisitorPtrType(subst_type->getReplacementType())) {
+ // VisitorDispatcher template parameter substituted to Visitor*.
+ return true;
+ }
+ } else if (const clang::TemplateTypeParmType* parm_type =
+ clang::dyn_cast<clang::TemplateTypeParmType>(
+ formal_type.getTypePtr())) {
+ if (parm_type->getDecl()->getName() == kVisitorDispatcherName) {
+ // Unresolved, but its parameter name is VisitorDispatcher.
+ return true;
+ }
+ }
+
+ return IsVisitorPtrType(formal_type);
+ }
+
+ enum TraceMethodType {
+ NOT_TRACE_METHOD,
+ TRACE_METHOD,
+ TRACE_AFTER_DISPATCH_METHOD,
+ TRACE_IMPL_METHOD,
+ TRACE_AFTER_DISPATCH_IMPL_METHOD
+ };
+
+ static TraceMethodType GetTraceMethodType(const clang::FunctionDecl* method) {
+ if (method->getNumParams() != 1)
+ return NOT_TRACE_METHOD;
+
+ const std::string& name = method->getNameAsString();
+ if (name != kTraceName && name != kTraceAfterDispatchName &&
+ name != kTraceImplName && name != kTraceAfterDispatchImplName)
+ return NOT_TRACE_METHOD;
+
+ const clang::QualType& formal_type = method->getParamDecl(0)->getType();
+ if (name == kTraceImplName || name == kTraceAfterDispatchImplName) {
+ if (!IsVisitorDispatcherType(formal_type))
+ return NOT_TRACE_METHOD;
+ } else if (!IsVisitorPtrType(formal_type)) {
+ return NOT_TRACE_METHOD;
+ }
+
+ if (name == kTraceName)
+ return TRACE_METHOD;
+ if (name == kTraceAfterDispatchName)
+ return TRACE_AFTER_DISPATCH_METHOD;
+ if (name == kTraceImplName)
+ return TRACE_IMPL_METHOD;
+ if (name == kTraceAfterDispatchImplName)
+ return TRACE_AFTER_DISPATCH_IMPL_METHOD;
+
+ assert(false && "Should not reach here");
+ return NOT_TRACE_METHOD;
+ }
+
+ static bool IsTraceMethod(const clang::FunctionDecl* method) {
+ return GetTraceMethodType(method) != NOT_TRACE_METHOD;
+ }
+
+ static bool IsTraceImplName(const std::string& name) {
+ return name == kTraceImplName || name == kTraceAfterDispatchImplName;
+ }
+
+ static bool StartsWith(const std::string& str, const std::string& prefix) {
+ if (prefix.size() > str.size())
+ return false;
+ return str.compare(0, prefix.size(), prefix) == 0;
+ }
+
+ static bool EndsWith(const std::string& str, const std::string& suffix) {
+ if (suffix.size() > str.size())
+ return false;
+ return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+ }
+
+ // Test if a template specialization is an instantiation.
+ static bool IsTemplateInstantiation(clang::CXXRecordDecl* record);
+};
+
+#endif // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
« no previous file with comments | « tools/clang/blink_gc_plugin/CollectVisitor.cpp ('k') | tools/clang/blink_gc_plugin/Config.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698