• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
8 #define TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
9 
10 #include "clang/AST/AST.h"
11 #include "clang/AST/Attr.h"
12 
13 const char kNewOperatorName[] = "operator new";
14 const char kCreateName[] = "create";
15 const char kTraceName[] = "trace";
16 const char kFinalizeName[] = "finalizeGarbageCollectedObject";
17 const char kTraceAfterDispatchName[] = "traceAfterDispatch";
18 const char kRegisterWeakMembersName[] = "registerWeakMembers";
19 const char kHeapAllocatorName[] = "HeapAllocator";
20 
21 class Config {
22  public:
IsMember(const std::string & name)23   static bool IsMember(const std::string& name) {
24     return name == "Member";
25   }
26 
IsWeakMember(const std::string & name)27   static bool IsWeakMember(const std::string& name) {
28     return name == "WeakMember";
29   }
30 
IsMemberHandle(const std::string & name)31   static bool IsMemberHandle(const std::string& name) {
32     return IsMember(name) ||
33            IsWeakMember(name);
34   }
35 
IsPersistent(const std::string & name)36   static bool IsPersistent(const std::string& name) {
37     return name == "Persistent";
38   }
39 
IsPersistentHandle(const std::string & name)40   static bool IsPersistentHandle(const std::string& name) {
41     return IsPersistent(name) ||
42            IsPersistentGCCollection(name);
43   }
44 
IsRawPtr(const std::string & name)45   static bool IsRawPtr(const std::string& name) {
46     return name == "RawPtr";
47   }
48 
IsRefPtr(const std::string & name)49   static bool IsRefPtr(const std::string& name) {
50     return name == "RefPtr";
51   }
52 
IsOwnPtr(const std::string & name)53   static bool IsOwnPtr(const std::string& name) {
54     return name == "OwnPtr";
55   }
56 
IsWTFCollection(const std::string & name)57   static bool IsWTFCollection(const std::string& name) {
58     return name == "Vector" ||
59            name == "Deque" ||
60            name == "HashSet" ||
61            name == "ListHashSet" ||
62            name == "LinkedHashSet" ||
63            name == "HashCountedSet" ||
64            name == "HashMap";
65   }
66 
IsGCCollection(const std::string & name)67   static bool IsGCCollection(const std::string& name) {
68     return name == "HeapVector" ||
69            name == "HeapDeque" ||
70            name == "HeapHashSet" ||
71            name == "HeapListHashSet" ||
72            name == "HeapLinkedHashSet" ||
73            name == "HeapHashCountedSet" ||
74            name == "HeapHashMap" ||
75            IsPersistentGCCollection(name);
76   }
77 
IsPersistentGCCollection(const std::string & name)78   static bool IsPersistentGCCollection(const std::string& name) {
79     return name == "PersistentHeapVector" ||
80            name == "PersistentHeapDeque" ||
81            name == "PersistentHeapHashSet" ||
82            name == "PersistentHeapListHashSet" ||
83            name == "PersistentHeapLinkedHashSet" ||
84            name == "PersistentHeapHashCountedSet" ||
85            name == "PersistentHeapHashMap";
86   }
87 
IsHashMap(const std::string & name)88   static bool IsHashMap(const std::string& name) {
89     return name == "HashMap" ||
90            name == "HeapHashMap" ||
91            name == "PersistentHeapHashMap";
92   }
93 
94   // Assumes name is a valid collection name.
CollectionDimension(const std::string & name)95   static size_t CollectionDimension(const std::string& name) {
96     return (IsHashMap(name) || name == "pair") ? 2 : 1;
97   }
98 
IsGCMixinBase(const std::string & name)99   static bool IsGCMixinBase(const std::string& name) {
100     return name == "GarbageCollectedMixin";
101   }
102 
IsGCFinalizedBase(const std::string & name)103   static bool IsGCFinalizedBase(const std::string& name) {
104     return name == "GarbageCollectedFinalized" ||
105            name == "RefCountedGarbageCollected";
106   }
107 
IsGCBase(const std::string & name)108   static bool IsGCBase(const std::string& name) {
109     return name == "GarbageCollected" ||
110            IsGCFinalizedBase(name) ||
111            IsGCMixinBase(name);
112   }
113 
IsAnnotated(clang::Decl * decl,const std::string & anno)114   static bool IsAnnotated(clang::Decl* decl, const std::string& anno) {
115     clang::AnnotateAttr* attr = decl->getAttr<clang::AnnotateAttr>();
116     return attr && (attr->getAnnotation() == anno);
117   }
118 
IsStackAnnotated(clang::Decl * decl)119   static bool IsStackAnnotated(clang::Decl* decl) {
120     return IsAnnotated(decl, "blink_stack_allocated");
121   }
122 
IsIgnoreAnnotated(clang::Decl * decl)123   static bool IsIgnoreAnnotated(clang::Decl* decl) {
124     return IsAnnotated(decl, "blink_gc_plugin_ignore");
125   }
126 
IsIgnoreCycleAnnotated(clang::Decl * decl)127   static bool IsIgnoreCycleAnnotated(clang::Decl* decl) {
128     return IsAnnotated(decl, "blink_gc_plugin_ignore_cycle") ||
129            IsIgnoreAnnotated(decl);
130   }
131 
IsVisitor(const std::string & name)132   static bool IsVisitor(const std::string& name) { return name == "Visitor"; }
133 
134   static bool IsTraceMethod(clang::CXXMethodDecl* method,
135                             bool* isTraceAfterDispatch = 0) {
136     if (method->getNumParams() != 1)
137       return false;
138 
139     const std::string& name = method->getNameAsString();
140     if (name != kTraceName && name != kTraceAfterDispatchName)
141       return false;
142 
143     const clang::QualType& formal_type = method->getParamDecl(0)->getType();
144     if (!formal_type->isPointerType())
145       return false;
146 
147     clang::CXXRecordDecl* pointee_type =
148         formal_type->getPointeeType()->getAsCXXRecordDecl();
149     if (!pointee_type)
150       return false;
151 
152     if (!IsVisitor(pointee_type->getName()))
153       return false;
154 
155     if (isTraceAfterDispatch)
156       *isTraceAfterDispatch = (name == kTraceAfterDispatchName);
157     return true;
158   }
159 
StartsWith(const std::string & str,const std::string & prefix)160   static bool StartsWith(const std::string& str, const std::string& prefix) {
161     if (prefix.size() > str.size())
162       return false;
163     return str.compare(0, prefix.size(), prefix) == 0;
164   }
165 
EndsWith(const std::string & str,const std::string & suffix)166   static bool EndsWith(const std::string& str, const std::string& suffix) {
167     if (suffix.size() > str.size())
168       return false;
169     return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
170   }
171 };
172 
173 #endif  // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
174