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
3 // found in the LICENSE file.
5 // This file defines the names used by GC infrastructure.
7 // TODO: Restructure the name determination to use fully qualified names (ala,
8 // blink::Foo) so that the plugin can be enabled for all of chromium. Doing so
9 // would allow us to catch errors with structures outside of blink that might
10 // have unsafe pointers to GC allocated blink structures.
12 #ifndef TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
13 #define TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
15 #include "clang/AST/AST.h"
16 #include "clang/AST/Attr.h"
18 const char kNewOperatorName[] = "operator new";
19 const char kCreateName[] = "create";
20 const char kTraceName[] = "trace";
21 const char kFinalizeName[] = "finalizeGarbageCollectedObject";
22 const char kTraceAfterDispatchName[] = "traceAfterDispatch";
23 const char kRegisterWeakMembersName[] = "registerWeakMembers";
24 const char kHeapAllocatorName[] = "HeapAllocator";
25 const char kTraceIfNeededName[] = "TraceIfNeeded";
29 static bool IsMember(const std::string& name) {
30 return name == "Member";
33 static bool IsWeakMember(const std::string& name) {
34 return name == "WeakMember";
37 static bool IsMemberHandle(const std::string& name) {
38 return IsMember(name) ||
42 static bool IsPersistent(const std::string& name) {
43 return name == "Persistent";
46 static bool IsPersistentHandle(const std::string& name) {
47 return IsPersistent(name) ||
48 IsPersistentGCCollection(name);
51 static bool IsRawPtr(const std::string& name) {
52 return name == "RawPtr";
55 static bool IsRefPtr(const std::string& name) {
56 return name == "RefPtr";
59 static bool IsOwnPtr(const std::string& name) {
60 return name == "OwnPtr";
63 static bool IsWTFCollection(const std::string& name) {
64 return name == "Vector" ||
67 name == "ListHashSet" ||
68 name == "LinkedHashSet" ||
69 name == "HashCountedSet" ||
73 static bool IsGCCollection(const std::string& name) {
74 return name == "HeapVector" ||
75 name == "HeapDeque" ||
76 name == "HeapHashSet" ||
77 name == "HeapListHashSet" ||
78 name == "HeapLinkedHashSet" ||
79 name == "HeapHashCountedSet" ||
80 name == "HeapHashMap" ||
81 IsPersistentGCCollection(name);
84 static bool IsPersistentGCCollection(const std::string& name) {
85 return name == "PersistentHeapVector" ||
86 name == "PersistentHeapDeque" ||
87 name == "PersistentHeapHashSet" ||
88 name == "PersistentHeapListHashSet" ||
89 name == "PersistentHeapLinkedHashSet" ||
90 name == "PersistentHeapHashCountedSet" ||
91 name == "PersistentHeapHashMap";
94 static bool IsHashMap(const std::string& name) {
95 return name == "HashMap" ||
96 name == "HeapHashMap" ||
97 name == "PersistentHeapHashMap";
100 // Following http://crrev.com/369633033 (Blink r177436),
101 // ignore blink::ScriptWrappable's destructor.
102 // TODO: remove when its non-Oilpan destructor is removed.
103 static bool HasIgnorableDestructor(const std::string& ns,
104 const std::string& name) {
105 return ns == "blink" && name == "ScriptWrappable";
108 // Assumes name is a valid collection name.
109 static size_t CollectionDimension(const std::string& name) {
110 return (IsHashMap(name) || name == "pair") ? 2 : 1;
113 static bool IsDummyBase(const std::string& name) {
114 return name == "DummyBase";
117 static bool IsRefCountedBase(const std::string& name) {
118 return name == "RefCounted" ||
119 name == "ThreadSafeRefCounted";
122 static bool IsGCMixinBase(const std::string& name) {
123 return name == "GarbageCollectedMixin";
126 static bool IsGCFinalizedBase(const std::string& name) {
127 return name == "GarbageCollectedFinalized" ||
128 name == "RefCountedGarbageCollected" ||
129 name == "ThreadSafeRefCountedGarbageCollected";
132 static bool IsGCBase(const std::string& name) {
133 return name == "GarbageCollected" ||
134 IsGCFinalizedBase(name) ||
138 // Returns true of the base classes that do not need a vtable entry for trace
139 // because they cannot possibly initiate a GC during construction.
140 static bool IsSafePolymorphicBase(const std::string& name) {
141 return IsGCBase(name) || IsDummyBase(name) || IsRefCountedBase(name);
144 static bool IsAnnotated(clang::Decl* decl, const std::string& anno) {
145 clang::AnnotateAttr* attr = decl->getAttr<clang::AnnotateAttr>();
146 return attr && (attr->getAnnotation() == anno);
149 static bool IsStackAnnotated(clang::Decl* decl) {
150 return IsAnnotated(decl, "blink_stack_allocated");
153 static bool IsIgnoreAnnotated(clang::Decl* decl) {
154 return IsAnnotated(decl, "blink_gc_plugin_ignore");
157 static bool IsIgnoreCycleAnnotated(clang::Decl* decl) {
158 return IsAnnotated(decl, "blink_gc_plugin_ignore_cycle") ||
159 IsIgnoreAnnotated(decl);
162 static bool IsVisitor(const std::string& name) { return name == "Visitor"; }
164 static bool IsTraceMethod(clang::FunctionDecl* method,
165 bool* isTraceAfterDispatch = 0) {
166 if (method->getNumParams() != 1)
169 const std::string& name = method->getNameAsString();
170 if (name != kTraceName && name != kTraceAfterDispatchName)
173 const clang::QualType& formal_type = method->getParamDecl(0)->getType();
174 if (!formal_type->isPointerType())
177 clang::CXXRecordDecl* pointee_type =
178 formal_type->getPointeeType()->getAsCXXRecordDecl();
182 if (!IsVisitor(pointee_type->getName()))
185 if (isTraceAfterDispatch)
186 *isTraceAfterDispatch = (name == kTraceAfterDispatchName);
190 static bool StartsWith(const std::string& str, const std::string& prefix) {
191 if (prefix.size() > str.size())
193 return str.compare(0, prefix.size(), prefix) == 0;
196 static bool EndsWith(const std::string& str, const std::string& suffix) {
197 if (suffix.size() > str.size())
199 return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
203 #endif // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_