Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / tools / clang / blink_gc_plugin / Config.h
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.
4
5 // This file defines the names used by GC infrastructure.
6
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.
11
12 #ifndef TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
13 #define TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
14
15 #include "clang/AST/AST.h"
16 #include "clang/AST/Attr.h"
17
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";
26
27 class Config {
28  public:
29   static bool IsMember(const std::string& name) {
30     return name == "Member";
31   }
32
33   static bool IsWeakMember(const std::string& name) {
34     return name == "WeakMember";
35   }
36
37   static bool IsMemberHandle(const std::string& name) {
38     return IsMember(name) ||
39            IsWeakMember(name);
40   }
41
42   static bool IsPersistent(const std::string& name) {
43     return name == "Persistent";
44   }
45
46   static bool IsPersistentHandle(const std::string& name) {
47     return IsPersistent(name) ||
48            IsPersistentGCCollection(name);
49   }
50
51   static bool IsRawPtr(const std::string& name) {
52     return name == "RawPtr";
53   }
54
55   static bool IsRefPtr(const std::string& name) {
56     return name == "RefPtr";
57   }
58
59   static bool IsOwnPtr(const std::string& name) {
60     return name == "OwnPtr";
61   }
62
63   static bool IsWTFCollection(const std::string& name) {
64     return name == "Vector" ||
65            name == "Deque" ||
66            name == "HashSet" ||
67            name == "ListHashSet" ||
68            name == "LinkedHashSet" ||
69            name == "HashCountedSet" ||
70            name == "HashMap";
71   }
72
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);
82   }
83
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";
92   }
93
94   static bool IsHashMap(const std::string& name) {
95     return name == "HashMap" ||
96            name == "HeapHashMap" ||
97            name == "PersistentHeapHashMap";
98   }
99
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";
106   }
107
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;
111   }
112
113   static bool IsDummyBase(const std::string& name) {
114     return name == "DummyBase";
115   }
116
117   static bool IsRefCountedBase(const std::string& name) {
118     return name == "RefCounted" ||
119            name == "ThreadSafeRefCounted";
120   }
121
122   static bool IsGCMixinBase(const std::string& name) {
123     return name == "GarbageCollectedMixin";
124   }
125
126   static bool IsGCFinalizedBase(const std::string& name) {
127     return name == "GarbageCollectedFinalized" ||
128            name == "RefCountedGarbageCollected" ||
129            name == "ThreadSafeRefCountedGarbageCollected";
130   }
131
132   static bool IsGCBase(const std::string& name) {
133     return name == "GarbageCollected" ||
134            IsGCFinalizedBase(name) ||
135            IsGCMixinBase(name);
136   }
137
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);
142   }
143
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);
147   }
148
149   static bool IsStackAnnotated(clang::Decl* decl) {
150     return IsAnnotated(decl, "blink_stack_allocated");
151   }
152
153   static bool IsIgnoreAnnotated(clang::Decl* decl) {
154     return IsAnnotated(decl, "blink_gc_plugin_ignore");
155   }
156
157   static bool IsIgnoreCycleAnnotated(clang::Decl* decl) {
158     return IsAnnotated(decl, "blink_gc_plugin_ignore_cycle") ||
159            IsIgnoreAnnotated(decl);
160   }
161
162   static bool IsVisitor(const std::string& name) { return name == "Visitor"; }
163
164   static bool IsTraceMethod(clang::FunctionDecl* method,
165                             bool* isTraceAfterDispatch = 0) {
166     if (method->getNumParams() != 1)
167       return false;
168
169     const std::string& name = method->getNameAsString();
170     if (name != kTraceName && name != kTraceAfterDispatchName)
171       return false;
172
173     const clang::QualType& formal_type = method->getParamDecl(0)->getType();
174     if (!formal_type->isPointerType())
175       return false;
176
177     clang::CXXRecordDecl* pointee_type =
178         formal_type->getPointeeType()->getAsCXXRecordDecl();
179     if (!pointee_type)
180       return false;
181
182     if (!IsVisitor(pointee_type->getName()))
183       return false;
184
185     if (isTraceAfterDispatch)
186       *isTraceAfterDispatch = (name == kTraceAfterDispatchName);
187     return true;
188   }
189
190   static bool StartsWith(const std::string& str, const std::string& prefix) {
191     if (prefix.size() > str.size())
192       return false;
193     return str.compare(0, prefix.size(), prefix) == 0;
194   }
195
196   static bool EndsWith(const std::string& str, const std::string& suffix) {
197     if (suffix.size() > str.size())
198       return false;
199     return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
200   }
201 };
202
203 #endif  // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_