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_
17 #include "clang/AST/AST.h"
18 #include "clang/AST/Attr.h"
20 const char kNewOperatorName
[] = "operator new";
21 const char kCreateName
[] = "create";
22 const char kTraceName
[] = "trace";
23 const char kTraceImplName
[] = "traceImpl";
24 const char kFinalizeName
[] = "finalizeGarbageCollectedObject";
25 const char kTraceAfterDispatchName
[] = "traceAfterDispatch";
26 const char kTraceAfterDispatchImplName
[] = "traceAfterDispatchImpl";
27 const char kRegisterWeakMembersName
[] = "registerWeakMembers";
28 const char kHeapAllocatorName
[] = "HeapAllocator";
29 const char kTraceIfNeededName
[] = "TraceIfNeeded";
30 const char kVisitorDispatcherName
[] = "VisitorDispatcher";
31 const char kVisitorVarName
[] = "visitor";
32 const char kAdjustAndMarkName
[] = "adjustAndMark";
33 const char kIsHeapObjectAliveName
[] = "isHeapObjectAlive";
34 const char kIsEagerlyFinalizedName
[] = "IsEagerlyFinalizedMarker";
38 static bool IsMember(const std::string
& name
) {
39 return name
== "Member";
42 static bool IsWeakMember(const std::string
& name
) {
43 return name
== "WeakMember";
46 static bool IsMemberHandle(const std::string
& name
) {
47 return IsMember(name
) ||
51 static bool IsPersistent(const std::string
& name
) {
52 return name
== "Persistent";
55 static bool IsPersistentHandle(const std::string
& name
) {
56 return IsPersistent(name
) ||
57 IsPersistentGCCollection(name
);
60 static bool IsRawPtr(const std::string
& name
) {
61 return name
== "RawPtr";
64 static bool IsRefPtr(const std::string
& name
) {
65 return name
== "RefPtr";
68 static bool IsOwnPtr(const std::string
& name
) {
69 return name
== "OwnPtr";
72 static bool IsWTFCollection(const std::string
& name
) {
73 return name
== "Vector" ||
76 name
== "ListHashSet" ||
77 name
== "LinkedHashSet" ||
78 name
== "HashCountedSet" ||
82 static bool IsGCCollection(const std::string
& name
) {
83 return name
== "HeapVector" ||
84 name
== "HeapDeque" ||
85 name
== "HeapHashSet" ||
86 name
== "HeapListHashSet" ||
87 name
== "HeapLinkedHashSet" ||
88 name
== "HeapHashCountedSet" ||
89 name
== "HeapHashMap" ||
90 IsPersistentGCCollection(name
);
93 static bool IsPersistentGCCollection(const std::string
& name
) {
94 return name
== "PersistentHeapVector" ||
95 name
== "PersistentHeapDeque" ||
96 name
== "PersistentHeapHashSet" ||
97 name
== "PersistentHeapListHashSet" ||
98 name
== "PersistentHeapLinkedHashSet" ||
99 name
== "PersistentHeapHashCountedSet" ||
100 name
== "PersistentHeapHashMap";
103 static bool IsHashMap(const std::string
& name
) {
104 return name
== "HashMap" ||
105 name
== "HeapHashMap" ||
106 name
== "PersistentHeapHashMap";
109 // Following http://crrev.com/369633033 (Blink r177436),
110 // ignore blink::ScriptWrappable's destructor.
111 // TODO: remove when its non-Oilpan destructor is removed.
112 static bool HasIgnorableDestructor(const std::string
& ns
,
113 const std::string
& name
) {
114 return ns
== "blink" && name
== "ScriptWrappable";
117 // Assumes name is a valid collection name.
118 static size_t CollectionDimension(const std::string
& name
) {
119 return (IsHashMap(name
) || name
== "pair") ? 2 : 1;
122 static bool IsDummyBase(const std::string
& name
) {
123 return name
== "DummyBase";
126 static bool IsRefCountedBase(const std::string
& name
) {
127 return name
== "RefCounted" ||
128 name
== "ThreadSafeRefCounted";
131 static bool IsGCMixinBase(const std::string
& name
) {
132 return name
== "GarbageCollectedMixin";
135 static bool IsGCFinalizedBase(const std::string
& name
) {
136 return name
== "GarbageCollectedFinalized" ||
137 name
== "RefCountedGarbageCollected" ||
138 name
== "ThreadSafeRefCountedGarbageCollected";
141 static bool IsGCBase(const std::string
& name
) {
142 return name
== "GarbageCollected" ||
143 IsGCFinalizedBase(name
) ||
147 // Returns true of the base classes that do not need a vtable entry for trace
148 // because they cannot possibly initiate a GC during construction.
149 static bool IsSafePolymorphicBase(const std::string
& name
) {
150 return IsGCBase(name
) || IsDummyBase(name
) || IsRefCountedBase(name
);
153 static bool IsAnnotated(clang::Decl
* decl
, const std::string
& anno
) {
154 clang::AnnotateAttr
* attr
= decl
->getAttr
<clang::AnnotateAttr
>();
155 return attr
&& (attr
->getAnnotation() == anno
);
158 static bool IsStackAnnotated(clang::Decl
* decl
) {
159 return IsAnnotated(decl
, "blink_stack_allocated");
162 static bool IsIgnoreAnnotated(clang::Decl
* decl
) {
163 return IsAnnotated(decl
, "blink_gc_plugin_ignore");
166 static bool IsIgnoreCycleAnnotated(clang::Decl
* decl
) {
167 return IsAnnotated(decl
, "blink_gc_plugin_ignore_cycle") ||
168 IsIgnoreAnnotated(decl
);
171 static bool IsVisitor(const std::string
& name
) {
172 return name
== "Visitor" || name
== "VisitorHelper";
175 static bool IsVisitorPtrType(const clang::QualType
& formal_type
) {
176 if (!formal_type
->isPointerType())
179 clang::CXXRecordDecl
* pointee_type
=
180 formal_type
->getPointeeType()->getAsCXXRecordDecl();
184 if (!IsVisitor(pointee_type
->getName()))
190 static bool IsVisitorDispatcherType(const clang::QualType
& formal_type
) {
191 if (const clang::SubstTemplateTypeParmType
* subst_type
=
192 clang::dyn_cast
<clang::SubstTemplateTypeParmType
>(
193 formal_type
.getTypePtr())) {
194 if (IsVisitorPtrType(subst_type
->getReplacementType())) {
195 // VisitorDispatcher template parameter substituted to Visitor*.
198 } else if (const clang::TemplateTypeParmType
* parm_type
=
199 clang::dyn_cast
<clang::TemplateTypeParmType
>(
200 formal_type
.getTypePtr())) {
201 if (parm_type
->getDecl()->getName() == kVisitorDispatcherName
) {
202 // Unresolved, but its parameter name is VisitorDispatcher.
207 return IsVisitorPtrType(formal_type
);
210 enum TraceMethodType
{
213 TRACE_AFTER_DISPATCH_METHOD
,
215 TRACE_AFTER_DISPATCH_IMPL_METHOD
218 static TraceMethodType
GetTraceMethodType(const clang::FunctionDecl
* method
) {
219 if (method
->getNumParams() != 1)
220 return NOT_TRACE_METHOD
;
222 const std::string
& name
= method
->getNameAsString();
223 if (name
!= kTraceName
&& name
!= kTraceAfterDispatchName
&&
224 name
!= kTraceImplName
&& name
!= kTraceAfterDispatchImplName
)
225 return NOT_TRACE_METHOD
;
227 const clang::QualType
& formal_type
= method
->getParamDecl(0)->getType();
228 if (name
== kTraceImplName
|| name
== kTraceAfterDispatchImplName
) {
229 if (!IsVisitorDispatcherType(formal_type
))
230 return NOT_TRACE_METHOD
;
231 } else if (!IsVisitorPtrType(formal_type
)) {
232 return NOT_TRACE_METHOD
;
235 if (name
== kTraceName
)
237 if (name
== kTraceAfterDispatchName
)
238 return TRACE_AFTER_DISPATCH_METHOD
;
239 if (name
== kTraceImplName
)
240 return TRACE_IMPL_METHOD
;
241 if (name
== kTraceAfterDispatchImplName
)
242 return TRACE_AFTER_DISPATCH_IMPL_METHOD
;
244 assert(false && "Should not reach here");
245 return NOT_TRACE_METHOD
;
248 static bool IsTraceMethod(const clang::FunctionDecl
* method
) {
249 return GetTraceMethodType(method
) != NOT_TRACE_METHOD
;
252 static bool IsTraceImplName(const std::string
& name
) {
253 return name
== kTraceImplName
|| name
== kTraceAfterDispatchImplName
;
256 static bool StartsWith(const std::string
& str
, const std::string
& prefix
) {
257 if (prefix
.size() > str
.size())
259 return str
.compare(0, prefix
.size(), prefix
) == 0;
262 static bool EndsWith(const std::string
& str
, const std::string
& suffix
) {
263 if (suffix
.size() > str
.size())
265 return str
.compare(str
.size() - suffix
.size(), suffix
.size(), suffix
) == 0;
269 #endif // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_