15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This file defines the names used by GC infrastructure.
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "clang/AST/AST.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "clang/AST/Attr.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kNewOperatorName[] = "operator new";
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char kCreateName[] = "create";
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTraceName[] = "trace";
1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char kFinalizeName[] = "finalizeGarbageCollectedObject";
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kTraceAfterDispatchName[] = "traceAfterDispatch";
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kRegisterWeakMembersName[] = "registerWeakMembers";
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kHeapAllocatorName[] = "HeapAllocator";
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kTraceIfNeededName[] = "TraceIfNeeded";
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Config {
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsMember(const std::string& name) {
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "Member";
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsWeakMember(const std::string& name) {
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "WeakMember";
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsMemberHandle(const std::string& name) {
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return IsMember(name) ||
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           IsWeakMember(name);
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static bool IsPersistent(const std::string& name) {
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "Persistent";
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsPersistentHandle(const std::string& name) {
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return IsPersistent(name) ||
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           IsPersistentGCCollection(name);
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static bool IsRawPtr(const std::string& name) {
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "RawPtr";
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsRefPtr(const std::string& name) {
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "RefPtr";
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsOwnPtr(const std::string& name) {
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "OwnPtr";
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsWTFCollection(const std::string& name) {
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "Vector" ||
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "Deque" ||
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           name == "HashSet" ||
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           name == "ListHashSet" ||
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "LinkedHashSet" ||
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "HashCountedSet" ||
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "HashMap";
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsGCCollection(const std::string& name) {
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "HeapVector" ||
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "HeapDeque" ||
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           name == "HeapHashSet" ||
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "HeapListHashSet" ||
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "HeapLinkedHashSet" ||
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "HeapHashCountedSet" ||
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "HeapHashMap" ||
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           IsPersistentGCCollection(name);
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  static bool IsPersistentGCCollection(const std::string& name) {
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return name == "PersistentHeapVector" ||
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "PersistentHeapDeque" ||
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "PersistentHeapHashSet" ||
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "PersistentHeapListHashSet" ||
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "PersistentHeapLinkedHashSet" ||
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "PersistentHeapHashCountedSet" ||
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           name == "PersistentHeapHashMap";
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static bool IsHashMap(const std::string& name) {
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "HashMap" ||
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           name == "HeapHashMap" ||
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           name == "PersistentHeapHashMap";
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Following http://crrev.com/369633033 (Blink r177436),
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // ignore blink::ScriptWrappable's destructor.
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // FIXME: remove when its non-Oilpan destructor is removed.
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static bool HasIgnorableDestructor(const std::string& ns,
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     const std::string& name) {
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return ns == "blink" && name == "ScriptWrappable";
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Assumes name is a valid collection name.
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static size_t CollectionDimension(const std::string& name) {
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return (IsHashMap(name) || name == "pair") ? 2 : 1;
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static bool IsDummyBase(const std::string& name) {
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return name == "DummyBase";
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static bool IsRefCountedBase(const std::string& name) {
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return name == "RefCounted" ||
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           name == "ThreadSafeRefCounted";
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static bool IsGCMixinBase(const std::string& name) {
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "GarbageCollectedMixin";
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsGCFinalizedBase(const std::string& name) {
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "GarbageCollectedFinalized" ||
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           name == "RefCountedGarbageCollected" ||
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           name == "ThreadSafeRefCountedGarbageCollected";
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool IsGCBase(const std::string& name) {
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return name == "GarbageCollected" ||
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           IsGCFinalizedBase(name) ||
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           IsGCMixinBase(name);
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Returns true of the base classes that do not need a vtable entry for trace
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // because they cannot possibly initiate a GC during construction.
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static bool IsSafePolymorphicBase(const std::string& name) {
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return IsGCBase(name) || IsDummyBase(name) || IsRefCountedBase(name);
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static bool IsAnnotated(clang::Decl* decl, const std::string& anno) {
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    clang::AnnotateAttr* attr = decl->getAttr<clang::AnnotateAttr>();
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return attr && (attr->getAnnotation() == anno);
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static bool IsStackAnnotated(clang::Decl* decl) {
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return IsAnnotated(decl, "blink_stack_allocated");
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static bool IsIgnoreAnnotated(clang::Decl* decl) {
149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return IsAnnotated(decl, "blink_gc_plugin_ignore");
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  static bool IsIgnoreCycleAnnotated(clang::Decl* decl) {
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return IsAnnotated(decl, "blink_gc_plugin_ignore_cycle") ||
154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch           IsIgnoreAnnotated(decl);
155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static bool IsVisitor(const std::string& name) { return name == "Visitor"; }
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static bool IsTraceMethod(clang::FunctionDecl* method,
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            bool* isTraceAfterDispatch = 0) {
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (method->getNumParams() != 1)
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& name = method->getNameAsString();
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (name != kTraceName && name != kTraceAfterDispatchName)
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const clang::QualType& formal_type = method->getParamDecl(0)->getType();
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!formal_type->isPointerType())
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    clang::CXXRecordDecl* pointee_type =
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        formal_type->getPointeeType()->getAsCXXRecordDecl();
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!pointee_type)
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!IsVisitor(pointee_type->getName()))
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (isTraceAfterDispatch)
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      *isTraceAfterDispatch = (name == kTraceAfterDispatchName);
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return true;
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool StartsWith(const std::string& str, const std::string& prefix) {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (prefix.size() > str.size())
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return str.compare(0, prefix.size(), prefix) == 0;
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool EndsWith(const std::string& str, const std::string& suffix) {
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (suffix.size() > str.size())
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return false;
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
199