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.
5 // This file provides a wrapper for CXXRecordDecl that accumulates GC related
6 // information about a class. Accumulated information is memoized and the info
7 // objects are stored in a RecordCache.
9 #ifndef TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
10 #define TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
17 #include "clang/AST/AST.h"
18 #include "clang/AST/CXXInheritance.h"
22 // A potentially tracable and/or lifetime affecting point in the object graph.
25 GraphPoint() : traced_(false) {}
26 void MarkTraced() { traced_ = true; }
27 bool IsProperlyTraced() { return traced_ || !NeedsTracing().IsNeeded(); }
28 virtual const TracingStatus NeedsTracing() = 0;
34 class BasePoint : public GraphPoint {
36 BasePoint(const clang::CXXBaseSpecifier& spec,
38 const TracingStatus& status)
39 : spec_(spec), info_(info), status_(status) {}
40 const TracingStatus NeedsTracing() { return status_; }
41 const clang::CXXBaseSpecifier& spec() { return spec_; }
42 RecordInfo* info() { return info_; }
45 const clang::CXXBaseSpecifier& spec_;
47 TracingStatus status_;
50 class FieldPoint : public GraphPoint {
52 FieldPoint(clang::FieldDecl* field, Edge* edge)
53 : field_(field), edge_(edge) {}
54 const TracingStatus NeedsTracing() {
55 return edge_->NeedsTracing(Edge::kRecursive);
57 clang::FieldDecl* field() { return field_; }
58 Edge* edge() { return edge_; }
61 clang::FieldDecl* field_;
64 friend class RecordCache;
65 void deleteEdge() { delete edge_; }
68 // Wrapper class to lazily collect information about a C++ record.
71 typedef std::map<clang::CXXRecordDecl*, BasePoint> Bases;
72 typedef std::map<clang::FieldDecl*, FieldPoint> Fields;
73 typedef std::vector<const clang::Type*> TemplateArgs;
77 clang::CXXRecordDecl* record() const { return record_; }
78 const std::string& name() const { return name_; }
81 clang::CXXMethodDecl* GetTraceMethod();
82 clang::CXXMethodDecl* GetTraceDispatchMethod();
83 clang::CXXMethodDecl* GetFinalizeDispatchMethod();
85 bool GetTemplateArgs(size_t count, TemplateArgs* output_args);
87 bool IsHeapAllocatedCollection();
92 bool IsStackAllocated();
94 bool IsOnlyPlacementNewable();
95 clang::CXXMethodDecl* DeclaresNewOperator();
97 bool RequiresTraceMethod();
98 bool NeedsFinalization();
99 TracingStatus NeedsTracing(Edge::NeedsTracingOption);
100 clang::CXXMethodDecl* InheritsNonVirtualTrace();
101 bool IsConsideredAbstract();
104 RecordInfo(clang::CXXRecordDecl* record, RecordCache* cache);
106 Fields* CollectFields();
107 Bases* CollectBases();
108 void DetermineTracingMethods();
109 bool InheritsTrace();
111 Edge* CreateEdge(const clang::Type* type);
114 clang::CXXRecordDecl* record_;
115 const std::string name_;
116 TracingStatus fields_need_tracing_;
120 enum CachedBool { kFalse = 0, kTrue = 1, kNotComputed = 2 };
121 CachedBool is_stack_allocated_;
122 CachedBool is_non_newable_;
123 CachedBool is_only_placement_newable_;
124 CachedBool does_need_finalization_;
126 bool determined_trace_methods_;
127 clang::CXXMethodDecl* trace_method_;
128 clang::CXXMethodDecl* trace_dispatch_method_;
129 clang::CXXMethodDecl* finalize_dispatch_method_;
132 clang::CXXBasePaths* base_paths_;
134 friend class RecordCache;
139 RecordInfo* Lookup(clang::CXXRecordDecl* record);
141 RecordInfo* Lookup(const clang::CXXRecordDecl* record) {
142 return Lookup(const_cast<clang::CXXRecordDecl*>(record));
145 RecordInfo* Lookup(clang::DeclContext* decl) {
146 return Lookup(clang::dyn_cast<clang::CXXRecordDecl>(decl));
149 RecordInfo* Lookup(const clang::Type* type) {
150 return Lookup(type->getAsCXXRecordDecl());
153 RecordInfo* Lookup(const clang::QualType& type) {
154 return Lookup(type.getTypePtr());
158 for (Cache::iterator it = cache_.begin(); it != cache_.end(); ++it) {
159 if (!it->second.fields_)
161 for (RecordInfo::Fields::iterator fit = it->second.fields_->begin();
162 fit != it->second.fields_->end();
164 fit->second.deleteEdge();
170 typedef std::map<clang::CXXRecordDecl*, RecordInfo> Cache;
174 #endif // TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_