Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "Config.h" | 5 #include "Config.h" |
| 6 #include "RecordInfo.h" | 6 #include "RecordInfo.h" |
| 7 | 7 |
| 8 #include "clang/AST/Attr.h" | 8 #include "clang/AST/Attr.h" |
| 9 | 9 |
| 10 using namespace clang; | 10 using namespace clang; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 bool RecordInfo::InheritsNonPureTrace() { | 187 bool RecordInfo::InheritsNonPureTrace() { |
| 188 if (CXXMethodDecl* trace = GetTraceMethod()) | 188 if (CXXMethodDecl* trace = GetTraceMethod()) |
| 189 return !trace->isPure(); | 189 return !trace->isPure(); |
| 190 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | 190 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { |
| 191 if (it->second.info()->InheritsNonPureTrace()) | 191 if (it->second.info()->InheritsNonPureTrace()) |
| 192 return true; | 192 return true; |
| 193 } | 193 } |
| 194 return false; | 194 return false; |
| 195 } | 195 } |
| 196 | 196 |
| 197 CXXMethodDecl* RecordInfo::InheritsNonVirtualTrace() { | |
| 198 if (CXXMethodDecl* trace = GetTraceMethod()) | |
| 199 return trace->isVirtual() ? 0 : trace; | |
| 200 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | |
| 201 if (CXXMethodDecl* trace = it->second.info()->InheritsNonVirtualTrace()) | |
| 202 return trace; | |
| 203 } | |
| 204 return 0; | |
| 205 } | |
| 206 | |
| 207 // A (non-virtual) class is considered abstract in Blink if it has | |
| 208 // no public constructors and no create methods. | |
| 209 bool RecordInfo::IsConsideredAbstract() { | |
| 210 for (CXXRecordDecl::ctor_iterator it = record_->ctor_begin(); | |
| 211 it != record_->ctor_end(); | |
| 212 ++it) { | |
| 213 if (!it->isCopyOrMoveConstructor() && it->getAccess() == AS_public) | |
| 214 return false; | |
| 215 } | |
| 216 for (CXXRecordDecl::method_iterator it = record_->method_begin(); | |
| 217 it != record_->method_end(); | |
| 218 ++it) { | |
| 219 if (it->getNameAsString() == kCreateName) | |
| 220 return false; | |
| 221 } | |
| 222 return true; | |
| 223 } | |
| 224 | |
| 197 RecordInfo::Bases* RecordInfo::CollectBases() { | 225 RecordInfo::Bases* RecordInfo::CollectBases() { |
| 198 // Compute the collection locally to avoid inconsistent states. | 226 // Compute the collection locally to avoid inconsistent states. |
| 199 Bases* bases = new Bases; | 227 Bases* bases = new Bases; |
| 200 if (!record_->hasDefinition()) | 228 if (!record_->hasDefinition()) |
| 201 return bases; | 229 return bases; |
| 202 for (CXXRecordDecl::base_class_iterator it = record_->bases_begin(); | 230 for (CXXRecordDecl::base_class_iterator it = record_->bases_begin(); |
| 203 it != record_->bases_end(); | 231 it != record_->bases_end(); |
| 204 ++it) { | 232 ++it) { |
| 205 const CXXBaseSpecifier& spec = *it; | 233 const CXXBaseSpecifier& spec = *it; |
| 206 RecordInfo* info = cache_->Lookup(spec.getType()); | 234 RecordInfo* info = cache_->Lookup(spec.getType()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 if (determined_trace_methods_) | 275 if (determined_trace_methods_) |
| 248 return; | 276 return; |
| 249 determined_trace_methods_ = true; | 277 determined_trace_methods_ = true; |
| 250 CXXMethodDecl* trace = 0; | 278 CXXMethodDecl* trace = 0; |
| 251 CXXMethodDecl* traceAfterDispatch = 0; | 279 CXXMethodDecl* traceAfterDispatch = 0; |
| 252 bool isTraceAfterDispatch; | 280 bool isTraceAfterDispatch; |
| 253 for (CXXRecordDecl::method_iterator it = record_->method_begin(); | 281 for (CXXRecordDecl::method_iterator it = record_->method_begin(); |
| 254 it != record_->method_end(); | 282 it != record_->method_end(); |
| 255 ++it) { | 283 ++it) { |
| 256 if (Config::IsTraceMethod(*it, &isTraceAfterDispatch)) { | 284 if (Config::IsTraceMethod(*it, &isTraceAfterDispatch)) { |
| 257 // TODO: Test that the formal parameter is of type Visitor*. | |
| 258 if (isTraceAfterDispatch) { | 285 if (isTraceAfterDispatch) { |
| 259 traceAfterDispatch = *it; | 286 traceAfterDispatch = *it; |
| 260 } else { | 287 } else { |
| 261 trace = *it; | 288 trace = *it; |
| 262 } | 289 } |
| 263 } | 290 } |
| 264 } | 291 } |
| 265 if (traceAfterDispatch) { | 292 if (traceAfterDispatch) { |
| 266 trace_method_ = traceAfterDispatch; | 293 trace_method_ = traceAfterDispatch; |
| 267 trace_dispatch_method_ = trace; | 294 trace_dispatch_method_ = trace; |
| 268 } else { | 295 } else { |
| 269 // TODO: Can we never have a dispatch method called trace without the same | 296 // TODO: Can we never have a dispatch method called trace without the same |
| 270 // class defining a traceAfterDispatch method? | 297 // class defining a traceAfterDispatch method? |
| 271 trace_method_ = trace; | 298 trace_method_ = trace; |
| 272 trace_dispatch_method_ = 0; | 299 trace_dispatch_method_ = 0; |
| 273 } | 300 } |
| 301 if (trace_dispatch_method_) | |
| 302 return; | |
|
Mads Ager (chromium)
2014/03/18 09:19:32
How about removing this and instead moving the bel
zerny-chromium
2014/03/18 10:03:41
The for loop might need to run in either branch si
| |
| 303 // If this class does not define a trace dispatch method search inherit it. | |
|
Mads Ager (chromium)
2014/03/18 09:19:32
search the inheritance hierarchy for it?
zerny-chromium
2014/03/18 10:03:41
Yes. Thanks.
| |
| 304 for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { | |
| 305 if (CXXMethodDecl* dispatch = it->second.info()->GetTraceDispatchMethod()) { | |
| 306 // TODO: Does it make sense to inherit multiple dispatch methods? | |
| 307 assert(!trace_dispatch_method_ && "Multiple trace dispatching methods"); | |
| 308 trace_dispatch_method_ = dispatch; | |
| 309 } | |
| 310 } | |
| 274 } | 311 } |
| 275 | 312 |
| 276 // TODO: Add classes with a finalize() method that specialize FinalizerTrait. | 313 // TODO: Add classes with a finalize() method that specialize FinalizerTrait. |
| 277 bool RecordInfo::NeedsFinalization() { | 314 bool RecordInfo::NeedsFinalization() { |
| 278 return record_->hasNonTrivialDestructor(); | 315 return record_->hasNonTrivialDestructor(); |
| 279 } | 316 } |
| 280 | 317 |
| 281 // A class needs tracing if: | 318 // A class needs tracing if: |
| 282 // - it is allocated on the managed heap, | 319 // - it is allocated on the managed heap, |
| 283 // - it is derived from a class that needs tracing, or | 320 // - it is derived from a class that needs tracing, or |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 // We failed to create an edge so abort the entire edge construction. | 417 // We failed to create an edge so abort the entire edge construction. |
| 381 delete edge; // Will delete the already allocated members. | 418 delete edge; // Will delete the already allocated members. |
| 382 return 0; | 419 return 0; |
| 383 } | 420 } |
| 384 } | 421 } |
| 385 return edge; | 422 return edge; |
| 386 } | 423 } |
| 387 | 424 |
| 388 return new Value(info); | 425 return new Value(info); |
| 389 } | 426 } |
| OLD | NEW |