| Index: tools/clang/blink_gc_plugin/RecordInfo.h
|
| diff --git a/tools/clang/blink_gc_plugin/RecordInfo.h b/tools/clang/blink_gc_plugin/RecordInfo.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e59c0b702d51ffa58bb85c78ec93ff153c1afd9a
|
| --- /dev/null
|
| +++ b/tools/clang/blink_gc_plugin/RecordInfo.h
|
| @@ -0,0 +1,190 @@
|
| +// 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 provides a wrapper for CXXRecordDecl that accumulates GC related
|
| +// information about a class. Accumulated information is memoized and the info
|
| +// objects are stored in a RecordCache.
|
| +
|
| +#ifndef TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
|
| +#define TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
|
| +
|
| +#include <map>
|
| +#include <vector>
|
| +
|
| +#include "Edge.h"
|
| +
|
| +#include "clang/AST/AST.h"
|
| +#include "clang/AST/CXXInheritance.h"
|
| +
|
| +class RecordCache;
|
| +
|
| +// A potentially tracable and/or lifetime affecting point in the object graph.
|
| +class GraphPoint {
|
| + public:
|
| + GraphPoint() : traced_(false) {}
|
| + virtual ~GraphPoint() {}
|
| + void MarkTraced() { traced_ = true; }
|
| + bool IsProperlyTraced() { return traced_ || !NeedsTracing().IsNeeded(); }
|
| + virtual const TracingStatus NeedsTracing() = 0;
|
| +
|
| + private:
|
| + bool traced_;
|
| +};
|
| +
|
| +class BasePoint : public GraphPoint {
|
| + public:
|
| + BasePoint(const clang::CXXBaseSpecifier& spec,
|
| + RecordInfo* info,
|
| + const TracingStatus& status)
|
| + : spec_(spec), info_(info), status_(status) {}
|
| + const TracingStatus NeedsTracing() { return status_; }
|
| + const clang::CXXBaseSpecifier& spec() { return spec_; }
|
| + RecordInfo* info() { return info_; }
|
| +
|
| + private:
|
| + const clang::CXXBaseSpecifier& spec_;
|
| + RecordInfo* info_;
|
| + TracingStatus status_;
|
| +};
|
| +
|
| +class FieldPoint : public GraphPoint {
|
| + public:
|
| + FieldPoint(clang::FieldDecl* field, Edge* edge)
|
| + : field_(field), edge_(edge) {}
|
| + const TracingStatus NeedsTracing() {
|
| + return edge_->NeedsTracing(Edge::kRecursive);
|
| + }
|
| + clang::FieldDecl* field() { return field_; }
|
| + Edge* edge() { return edge_; }
|
| +
|
| + private:
|
| + clang::FieldDecl* field_;
|
| + Edge* edge_;
|
| +
|
| + friend class RecordCache;
|
| + void deleteEdge() { delete edge_; }
|
| +};
|
| +
|
| +// Wrapper class to lazily collect information about a C++ record.
|
| +class RecordInfo {
|
| + public:
|
| + typedef std::map<clang::CXXRecordDecl*, BasePoint> Bases;
|
| + typedef std::map<clang::FieldDecl*, FieldPoint> Fields;
|
| + typedef std::vector<const clang::Type*> TemplateArgs;
|
| +
|
| + ~RecordInfo();
|
| +
|
| + clang::CXXRecordDecl* record() const { return record_; }
|
| + const std::string& name() const { return name_; }
|
| + Fields& GetFields();
|
| + Bases& GetBases();
|
| + clang::CXXMethodDecl* GetTraceMethod();
|
| + clang::CXXMethodDecl* GetTraceDispatchMethod();
|
| + clang::CXXMethodDecl* GetFinalizeDispatchMethod();
|
| +
|
| + bool GetTemplateArgs(size_t count, TemplateArgs* output_args);
|
| +
|
| + bool IsHeapAllocatedCollection();
|
| + bool IsGCDerived();
|
| + bool IsGCAllocated();
|
| + bool IsGCFinalized();
|
| + bool IsGCMixin();
|
| + bool IsStackAllocated();
|
| + bool IsNonNewable();
|
| + bool IsOnlyPlacementNewable();
|
| + bool IsGCMixinInstance();
|
| + bool IsEagerlyFinalized();
|
| +
|
| + bool HasDefinition();
|
| +
|
| + clang::CXXMethodDecl* DeclaresNewOperator();
|
| +
|
| + bool RequiresTraceMethod();
|
| + bool NeedsFinalization();
|
| + bool DeclaresGCMixinMethods();
|
| + bool DeclaresLocalTraceMethod();
|
| + TracingStatus NeedsTracing(Edge::NeedsTracingOption);
|
| + clang::CXXMethodDecl* InheritsNonVirtualTrace();
|
| + bool IsConsideredAbstract();
|
| +
|
| + static clang::CXXRecordDecl* GetDependentTemplatedDecl(const clang::Type&);
|
| +
|
| + private:
|
| + RecordInfo(clang::CXXRecordDecl* record, RecordCache* cache);
|
| +
|
| + void walkBases();
|
| +
|
| + Fields* CollectFields();
|
| + Bases* CollectBases();
|
| + void DetermineTracingMethods();
|
| + bool InheritsTrace();
|
| +
|
| + Edge* CreateEdge(const clang::Type* type);
|
| +
|
| + RecordCache* cache_;
|
| + clang::CXXRecordDecl* record_;
|
| + const std::string name_;
|
| + TracingStatus fields_need_tracing_;
|
| + Bases* bases_;
|
| + Fields* fields_;
|
| +
|
| + enum CachedBool { kFalse = 0, kTrue = 1, kNotComputed = 2 };
|
| + CachedBool is_stack_allocated_;
|
| + CachedBool is_non_newable_;
|
| + CachedBool is_only_placement_newable_;
|
| + CachedBool does_need_finalization_;
|
| + CachedBool has_gc_mixin_methods_;
|
| + CachedBool is_declaring_local_trace_;
|
| + CachedBool is_eagerly_finalized_;
|
| +
|
| + bool determined_trace_methods_;
|
| + clang::CXXMethodDecl* trace_method_;
|
| + clang::CXXMethodDecl* trace_dispatch_method_;
|
| + clang::CXXMethodDecl* finalize_dispatch_method_;
|
| +
|
| + bool is_gc_derived_;
|
| +
|
| + std::vector<std::string> gc_base_names_;
|
| +
|
| + friend class RecordCache;
|
| +};
|
| +
|
| +class RecordCache {
|
| + public:
|
| + RecordInfo* Lookup(clang::CXXRecordDecl* record);
|
| +
|
| + RecordInfo* Lookup(const clang::CXXRecordDecl* record) {
|
| + return Lookup(const_cast<clang::CXXRecordDecl*>(record));
|
| + }
|
| +
|
| + RecordInfo* Lookup(clang::DeclContext* decl) {
|
| + return Lookup(clang::dyn_cast<clang::CXXRecordDecl>(decl));
|
| + }
|
| +
|
| + RecordInfo* Lookup(const clang::Type* type) {
|
| + return Lookup(type->getAsCXXRecordDecl());
|
| + }
|
| +
|
| + RecordInfo* Lookup(const clang::QualType& type) {
|
| + return Lookup(type.getTypePtr());
|
| + }
|
| +
|
| + ~RecordCache() {
|
| + for (Cache::iterator it = cache_.begin(); it != cache_.end(); ++it) {
|
| + if (!it->second.fields_)
|
| + continue;
|
| + for (RecordInfo::Fields::iterator fit = it->second.fields_->begin();
|
| + fit != it->second.fields_->end();
|
| + ++fit) {
|
| + fit->second.deleteEdge();
|
| + }
|
| + }
|
| + }
|
| +
|
| + private:
|
| + typedef std::map<clang::CXXRecordDecl*, RecordInfo> Cache;
|
| + Cache cache_;
|
| +};
|
| +
|
| +#endif // TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
|
|
|