Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / tools / clang / blink_gc_plugin / RecordInfo.cpp
index 24eec2a..7378077 100644 (file)
@@ -115,20 +115,41 @@ bool RecordInfo::IsGCFinalized() {
   return false;
 }
 
+bool RecordInfo::IsTreeShared() {
+  if (Config::IsTreeSharedBase(name_))
+    return true;
+  if (!IsGCDerived())
+    return false;
+  for (CXXBasePaths::paths_iterator it = base_paths_->begin();
+       it != base_paths_->end();
+       ++it) {
+    // TreeShared is an immediate base of GCFinalized.
+    if (it->size() < 2) continue;
+    const CXXBasePathElement& elem = (*it)[it->size() - 2];
+    CXXRecordDecl* base = elem.Base->getType()->getAsCXXRecordDecl();
+    if (Config::IsTreeSharedBase(base->getName()))
+      return true;
+  }
+  return false;
+}
+
 // A GC mixin is a class that inherits from a GC mixin base and has
-// has not yet been "mixed in" with another GC base class.
+// not yet been "mixed in" with another GC base class.
 bool RecordInfo::IsGCMixin() {
   if (!IsGCDerived() || base_paths_->begin() == base_paths_->end())
     return false;
-  // Get the last element of the first path.
-  CXXBasePaths::paths_iterator it = base_paths_->begin();
-  const CXXBasePathElement& elem = (*it)[it->size() - 1];
-  CXXRecordDecl* base = elem.Base->getType()->getAsCXXRecordDecl();
-  // If it is not a mixin base we are done.
-  if (!Config::IsGCMixinBase(base->getName()))
-    return false;
-  // This is a mixin if there are no other paths to GC bases.
-  return ++it == base_paths_->end();
+  for (CXXBasePaths::paths_iterator it = base_paths_->begin();
+       it != base_paths_->end();
+       ++it) {
+      // Get the last element of the path.
+      const CXXBasePathElement& elem = (*it)[it->size() - 1];
+      CXXRecordDecl* base = elem.Base->getType()->getAsCXXRecordDecl();
+      // If it is not a mixin base we are done.
+      if (!Config::IsGCMixinBase(base->getName()))
+          return false;
+  }
+  // This is a mixin if all GC bases are mixins.
+  return true;
 }
 
 // Test if a record is allocated on the managed heap.
@@ -209,6 +230,16 @@ bool RecordInfo::IsOnlyPlacementNewable() {
   return is_only_placement_newable_;
 }
 
+CXXMethodDecl* RecordInfo::DeclaresNewOperator() {
+  for (CXXRecordDecl::method_iterator it = record_->method_begin();
+       it != record_->method_end();
+       ++it) {
+    if (it->getNameAsString() == kNewOperatorName && it->getNumParams() == 1)
+      return *it;
+  }
+  return 0;
+}
+
 // An object requires a tracing method if it has any fields that need tracing.
 bool RecordInfo::RequiresTraceMethod() {
   if (IsStackAllocated())
@@ -415,7 +446,7 @@ Edge* RecordInfo::CreateEdge(const Type* type) {
 
   if (type->isPointerType()) {
     if (Edge* ptr = CreateEdge(type->getPointeeType().getTypePtrOrNull()))
-      return new RawPtr(ptr);
+      return new RawPtr(ptr, false);
     return 0;
   }
 
@@ -430,7 +461,7 @@ Edge* RecordInfo::CreateEdge(const Type* type) {
 
   if (Config::IsRawPtr(info->name()) && info->GetTemplateArgs(1, &args)) {
     if (Edge* ptr = CreateEdge(args[0]))
-      return new RawPtr(ptr);
+      return new RawPtr(ptr, true);
     return 0;
   }
 
@@ -483,11 +514,9 @@ Edge* RecordInfo::CreateEdge(const Type* type) {
     for (TemplateArgs::iterator it = args.begin(); it != args.end(); ++it) {
       if (Edge* member = CreateEdge(*it)) {
         edge->members().push_back(member);
-      } else {
-        // We failed to create an edge so abort the entire edge construction.
-        delete edge;  // Will delete the already allocated members.
-        return 0;
       }
+      // TODO: Handle the case where we fail to create an edge (eg, if the
+      // argument is a primitive type or just not fully known yet).
     }
     return edge;
   }