Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / tools / clang / blink_gc_plugin / RecordInfo.h
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.
4
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.
8
9 #ifndef TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
10 #define TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
11
12 #include <map>
13 #include <vector>
14
15 #include "clang/AST/AST.h"
16 #include "clang/AST/CXXInheritance.h"
17
18 class RecordCache;
19
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.)
22 class TracingStatus {
23  public:
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);
29   }
30
31   bool IsTracingUnknown() const { return status_ == kUnknown; }
32   bool IsTracingRequired() const { return status_ == kRequired; }
33   bool IsTracingUnneeded() const { return status_ == kUnneeded; }
34
35   // Updating functions so the status can only become more defined.
36   void MarkTracingRequired() {
37     if (status_ < kRequired) status_ = kRequired;
38   }
39   void MarkTracingUnneeded() {
40     if (status_ < kUnneeded) status_ = kUnneeded;
41   }
42
43   bool is_weak() { return is_weak_; }
44
45  private:
46   enum Status {
47     kUnknown,    // Point that might need to be traced.
48     kRequired,   // Point that must be traced.
49     kUnneeded    // Point that need not be traced.
50   };
51
52   TracingStatus(Status status)
53       : status_(status),
54         is_weak_(false) { }
55
56   TracingStatus(Status status, bool is_weak)
57       : status_(status),
58         is_weak_(is_weak) { }
59
60   Status status_;
61   bool is_weak_;
62 };
63
64 // Wrapper class to lazily collect information about a C++ record.
65 class RecordInfo {
66 public:
67   typedef std::map<clang::CXXRecordDecl*, TracingStatus> Bases;
68   typedef std::map<clang::FieldDecl*, TracingStatus> Fields;
69   typedef std::vector<RecordInfo*> TemplateArgs;
70
71   enum NeedsTracingOption {
72     kRecursive,
73     kNonRecursive
74   };
75
76   ~RecordInfo();
77
78   clang::CXXRecordDecl* record() const { return record_; }
79   const std::string& name() const { return name_; }
80   Fields& GetFields();
81   Bases& GetBases();
82   clang::CXXMethodDecl* GetTraceMethod();
83   clang::CXXMethodDecl* GetTraceDispatchMethod();
84
85   bool IsTemplate(TemplateArgs* args = 0);
86
87   bool IsHeapAllocatedCollection(bool* is_weak = 0);
88   bool IsGCDerived(clang::CXXBasePaths* paths = 0);
89
90   bool IsNonNewable();
91   bool RequiresTraceMethod();
92   TracingStatus NeedsTracing(NeedsTracingOption option = kRecursive);
93
94 private:
95   RecordInfo(clang::CXXRecordDecl* record, RecordCache* cache);
96
97   Fields* CollectFields();
98   Bases* CollectBases();
99   void DetermineTracingMethods();
100
101   TracingStatus NeedsTracing(clang::FieldDecl* field);
102
103   RecordCache* cache_;
104   clang::CXXRecordDecl* record_;
105   const std::string name_;
106   bool requires_trace_method_;
107   Bases* bases_;
108   Fields* fields_;
109
110   bool determined_trace_methods_;
111   clang::CXXMethodDecl* trace_method_;
112   clang::CXXMethodDecl* trace_dispatch_method_;
113
114   friend class RecordCache;
115 };
116
117 class RecordCache {
118 public:
119   RecordInfo* Lookup(clang::CXXRecordDecl* record) {
120     if (!record) return 0;
121     Cache::iterator it = cache_.find(record);
122     if (it != cache_.end())
123       return &it->second;
124     return &cache_.insert(std::make_pair(record, RecordInfo(record, this)))
125             .first->second;
126   }
127
128   RecordInfo* Lookup(const clang::CXXRecordDecl* record) {
129     return Lookup(const_cast<clang::CXXRecordDecl*>(record));
130   }
131
132 private:
133   typedef std::map<clang::CXXRecordDecl*, RecordInfo> Cache;
134   Cache cache_;
135 };
136
137 #endif // TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_