123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- // This file defines the names used by GC infrastructure.
- // TODO: Restructure the name determination to use fully qualified names (ala,
- // blink::Foo) so that the plugin can be enabled for all of chromium. Doing so
- // would allow us to catch errors with structures outside of blink that might
- // have unsafe pointers to GC allocated blink structures.
- #ifndef TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
- #define TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
- #include <cassert>
- #include "clang/AST/AST.h"
- #include "clang/AST/Attr.h"
- extern const char kNewOperatorName[];
- extern const char kCreateName[];
- extern const char kTraceName[];
- extern const char kFinalizeName[];
- extern const char kTraceAfterDispatchName[];
- extern const char kRegisterWeakMembersName[];
- extern const char kHeapAllocatorName[];
- extern const char kTraceIfNeededName[];
- extern const char kVisitorDispatcherName[];
- extern const char kVisitorVarName[];
- extern const char kAdjustAndMarkName[];
- extern const char kIsHeapObjectAliveName[];
- extern const char kConstIteratorName[];
- extern const char kIteratorName[];
- extern const char kConstReverseIteratorName[];
- extern const char kReverseIteratorName[];
- class Config {
- public:
- static bool IsMember(llvm::StringRef name) {
- return name == "Member";
- }
- static bool IsWeakMember(llvm::StringRef name) {
- return name == "WeakMember";
- }
- static bool IsMemberHandle(llvm::StringRef name) {
- return IsMember(name) ||
- IsWeakMember(name);
- }
- static bool IsPersistent(llvm::StringRef name) {
- return name == "Persistent" ||
- name == "WeakPersistent" ;
- }
- static bool IsCrossThreadPersistent(llvm::StringRef name) {
- return name == "CrossThreadPersistent" ||
- name == "CrossThreadWeakPersistent" ;
- }
- static bool IsRefPtr(llvm::StringRef name) { return name == "scoped_refptr"; }
- static bool IsWeakPtr(llvm::StringRef name) { return name == "WeakPtr"; }
- static bool IsRefOrWeakPtr(llvm::StringRef name) {
- return IsRefPtr(name) || IsWeakPtr(name);
- }
- static bool IsUniquePtr(llvm::StringRef name) {
- return name == "unique_ptr";
- }
- static bool IsTraceWrapperV8Reference(llvm::StringRef name) {
- return name == "TraceWrapperV8Reference";
- }
- static bool IsWTFCollection(llvm::StringRef name) {
- return name == "Vector" ||
- name == "Deque" ||
- name == "HashSet" ||
- name == "ListHashSet" ||
- name == "LinkedHashSet" ||
- name == "HashCountedSet" ||
- name == "HashMap";
- }
- static bool IsGCCollection(llvm::StringRef name) {
- return name == "HeapVector" || name == "HeapDeque" ||
- name == "HeapHashSet" || name == "HeapListHashSet" ||
- name == "HeapLinkedHashSet" || name == "HeapHashCountedSet" ||
- name == "HeapHashMap";
- }
- static bool IsGCCollectionWithUnsafeIterator(llvm::StringRef name) {
- if (!IsGCCollection(name))
- return false;
- // The list hash set iterators refer to the set, not the
- // backing store and are consequently safe.
- if (name == "HeapListHashSet" || name == "PersistentHeapListHashSet")
- return false;
- return true;
- }
- static bool IsHashMap(llvm::StringRef name) {
- return name == "HashMap" ||
- name == "HeapHashMap" ||
- name == "PersistentHeapHashMap";
- }
- // Assumes name is a valid collection name.
- static size_t CollectionDimension(llvm::StringRef name) {
- return (IsHashMap(name) || name == "pair") ? 2 : 1;
- }
- static bool IsRefCountedBase(llvm::StringRef name) {
- return name == "RefCounted" ||
- name == "ThreadSafeRefCounted";
- }
- static bool IsGCSimpleBase(llvm::StringRef name) {
- return name == "GarbageCollected";
- }
- static bool IsGCMixinBase(llvm::StringRef name) {
- return name == "GarbageCollectedMixin";
- }
- static bool IsGCBase(llvm::StringRef name) {
- return IsGCSimpleBase(name) || IsGCMixinBase(name);
- }
- static bool IsIterator(llvm::StringRef name) {
- return name == kIteratorName || name == kConstIteratorName ||
- name == kReverseIteratorName || name == kConstReverseIteratorName;
- }
- // Returns true of the base classes that do not need a vtable entry for trace
- // because they cannot possibly initiate a GC during construction.
- static bool IsSafePolymorphicBase(llvm::StringRef name) {
- return IsGCBase(name) || IsRefCountedBase(name);
- }
- static bool IsAnnotated(clang::Decl* decl, const std::string& anno) {
- clang::AnnotateAttr* attr = decl->getAttr<clang::AnnotateAttr>();
- return attr && (attr->getAnnotation() == anno);
- }
- static bool IsStackAnnotated(clang::Decl* decl) {
- return IsAnnotated(decl, "blink_stack_allocated");
- }
- static bool IsIgnoreAnnotated(clang::Decl* decl) {
- return IsAnnotated(decl, "blink_gc_plugin_ignore");
- }
- static bool IsIgnoreCycleAnnotated(clang::Decl* decl) {
- return IsAnnotated(decl, "blink_gc_plugin_ignore_cycle") ||
- IsIgnoreAnnotated(decl);
- }
- static bool IsVisitor(llvm::StringRef name) {
- return name == "Visitor" || name == "VisitorHelper";
- }
- static bool IsVisitorPtrType(const clang::QualType& formal_type) {
- if (!formal_type->isPointerType())
- return false;
- clang::CXXRecordDecl* pointee_type =
- formal_type->getPointeeType()->getAsCXXRecordDecl();
- if (!pointee_type)
- return false;
- if (!IsVisitor(pointee_type->getName()))
- return false;
- return true;
- }
- static bool IsVisitorDispatcherType(const clang::QualType& formal_type) {
- if (const clang::SubstTemplateTypeParmType* subst_type =
- clang::dyn_cast<clang::SubstTemplateTypeParmType>(
- formal_type.getTypePtr())) {
- if (IsVisitorPtrType(subst_type->getReplacementType())) {
- // VisitorDispatcher template parameter substituted to Visitor*.
- return true;
- }
- } else if (const clang::TemplateTypeParmType* parm_type =
- clang::dyn_cast<clang::TemplateTypeParmType>(
- formal_type.getTypePtr())) {
- if (parm_type->getDecl()->getName() == kVisitorDispatcherName) {
- // Unresolved, but its parameter name is VisitorDispatcher.
- return true;
- }
- }
- return IsVisitorPtrType(formal_type);
- }
- enum TraceMethodType {
- NOT_TRACE_METHOD,
- TRACE_METHOD,
- TRACE_AFTER_DISPATCH_METHOD,
- };
- static TraceMethodType GetTraceMethodType(const clang::FunctionDecl* method) {
- if (method->getNumParams() != 1)
- return NOT_TRACE_METHOD;
- const std::string& name = method->getNameAsString();
- if (name != kTraceName && name != kTraceAfterDispatchName)
- return NOT_TRACE_METHOD;
- const clang::QualType& formal_type = method->getParamDecl(0)->getType();
- if (!IsVisitorPtrType(formal_type)) {
- return NOT_TRACE_METHOD;
- }
- if (name == kTraceName)
- return TRACE_METHOD;
- if (name == kTraceAfterDispatchName)
- return TRACE_AFTER_DISPATCH_METHOD;
- assert(false && "Should not reach here");
- return NOT_TRACE_METHOD;
- }
- static bool IsTraceMethod(const clang::FunctionDecl* method) {
- return GetTraceMethodType(method) != NOT_TRACE_METHOD;
- }
- static bool IsTraceWrappersMethod(const clang::FunctionDecl* method);
- static bool StartsWith(const std::string& str, const std::string& prefix) {
- if (prefix.size() > str.size())
- return false;
- return str.compare(0, prefix.size(), prefix) == 0;
- }
- static bool EndsWith(const std::string& str, const std::string& suffix) {
- if (suffix.size() > str.size())
- return false;
- return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
- }
- // Test if a template specialization is an instantiation.
- static bool IsTemplateInstantiation(clang::CXXRecordDecl* record);
- };
- #endif // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
|