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_
15 #include "clang/AST/AST.h"
16 #include "clang/AST/CXXInheritance.h"
20 // Value to track the tracing status of a point in the tracing graph.
21 // (Points that might need tracing are fields and base classes.)
24 static TracingStatus Unknown() { return kUnknown; }
25 static TracingStatus Required() { return kRequired; }
26 static TracingStatus Unneeded() { return kUnneeded; }
27 static TracingStatus RequiredWeak() {
28 return TracingStatus(kRequired, true);
31 bool IsTracingUnknown() const { return status_ == kUnknown; }
32 bool IsTracingRequired() const { return status_ == kRequired; }
33 bool IsTracingUnneeded() const { return status_ == kUnneeded; }
35 // Updating functions so the status can only become more defined.
36 void MarkTracingRequired() {
37 if (status_ < kRequired) status_ = kRequired;
39 void MarkTracingUnneeded() {
40 if (status_ < kUnneeded) status_ = kUnneeded;
43 bool is_weak() { return is_weak_; }
47 kUnknown, // Point that might need to be traced.
48 kRequired, // Point that must be traced.
49 kUnneeded // Point that need not be traced.
52 TracingStatus(Status status)
56 TracingStatus(Status status, bool is_weak)
64 // Wrapper class to lazily collect information about a C++ record.
67 typedef std::map<clang::CXXRecordDecl*, TracingStatus> Bases;
68 typedef std::map<clang::FieldDecl*, TracingStatus> Fields;
69 typedef std::vector<RecordInfo*> TemplateArgs;
71 enum NeedsTracingOption {
78 clang::CXXRecordDecl* record() const { return record_; }
79 const std::string& name() const { return name_; }
82 clang::CXXMethodDecl* GetTraceMethod();
83 clang::CXXMethodDecl* GetTraceDispatchMethod();
85 bool IsTemplate(TemplateArgs* args = 0);
87 bool IsHeapAllocatedCollection(bool* is_weak = 0);
88 bool IsGCDerived(clang::CXXBasePaths* paths = 0);
91 bool RequiresTraceMethod();
92 TracingStatus NeedsTracing(NeedsTracingOption option = kRecursive);
95 RecordInfo(clang::CXXRecordDecl* record, RecordCache* cache);
97 Fields* CollectFields();
98 Bases* CollectBases();
99 void DetermineTracingMethods();
101 TracingStatus NeedsTracing(clang::FieldDecl* field);
104 clang::CXXRecordDecl* record_;
105 const std::string name_;
106 bool requires_trace_method_;
110 bool determined_trace_methods_;
111 clang::CXXMethodDecl* trace_method_;
112 clang::CXXMethodDecl* trace_dispatch_method_;
114 friend class RecordCache;
119 RecordInfo* Lookup(clang::CXXRecordDecl* record) {
120 if (!record) return 0;
121 Cache::iterator it = cache_.find(record);
122 if (it != cache_.end())
124 return &cache_.insert(std::make_pair(record, RecordInfo(record, this)))
128 RecordInfo* Lookup(const clang::CXXRecordDecl* record) {
129 return Lookup(const_cast<clang::CXXRecordDecl*>(record));
133 typedef std::map<clang::CXXRecordDecl*, RecordInfo> Cache;
137 #endif // TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_