| Index: tools/clang/blink_gc_plugin/RecordInfo.cpp
|
| diff --git a/tools/clang/blink_gc_plugin/RecordInfo.cpp b/tools/clang/blink_gc_plugin/RecordInfo.cpp
|
| index 46b8606a344d06d92c71eafd0cc3c2c5608021da..fe211ac8b9ce4b474bf7af7c7542a8589272c679 100644
|
| --- a/tools/clang/blink_gc_plugin/RecordInfo.cpp
|
| +++ b/tools/clang/blink_gc_plugin/RecordInfo.cpp
|
| @@ -113,10 +113,10 @@ void RecordInfo::walkBases() {
|
| // have a "GC base name", so are to be included and considered.
|
| SmallVector<const CXXRecordDecl*, 8> queue;
|
|
|
| - const CXXRecordDecl *base_record = record();
|
| + const CXXRecordDecl* base_record = record();
|
| while (true) {
|
| for (const auto& it : base_record->bases()) {
|
| - const RecordType *type = it.getType()->getAs<RecordType>();
|
| + const RecordType* type = it.getType()->getAs<RecordType>();
|
| CXXRecordDecl* base;
|
| if (!type)
|
| base = GetDependentTemplatedDecl(*it.getType());
|
| @@ -171,17 +171,19 @@ bool RecordInfo::IsGCAllocated() {
|
| }
|
|
|
| bool RecordInfo::IsEagerlyFinalized() {
|
| - if (is_eagerly_finalized_ == kNotComputed) {
|
| - is_eagerly_finalized_ = kFalse;
|
| - if (IsGCFinalized()) {
|
| - for (Decl* decl : record_->decls()) {
|
| - if (TypedefDecl* typedef_decl = dyn_cast<TypedefDecl>(decl)) {
|
| - if (typedef_decl->getNameAsString() == kIsEagerlyFinalizedName) {
|
| - is_eagerly_finalized_ = kTrue;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| + if (is_eagerly_finalized_ != kNotComputed)
|
| + return is_eagerly_finalized_;
|
| +
|
| + is_eagerly_finalized_ = kFalse;
|
| + if (!IsGCFinalized())
|
| + return is_eagerly_finalized_;
|
| +
|
| + for (Decl* decl : record_->decls()) {
|
| + if (TypedefDecl* typedef_decl = dyn_cast<TypedefDecl>(decl)) {
|
| + if (typedef_decl->getNameAsString() != kIsEagerlyFinalizedName)
|
| + continue;
|
| + is_eagerly_finalized_ = kTrue;
|
| + break;
|
| }
|
| }
|
| return is_eagerly_finalized_;
|
| @@ -414,7 +416,13 @@ RecordInfo::Fields* RecordInfo::CollectFields() {
|
| // Ignore fields annotated with the GC_PLUGIN_IGNORE macro.
|
| if (Config::IsIgnoreAnnotated(field))
|
| continue;
|
| - if (Edge* edge = CreateEdge(field->getType().getTypePtrOrNull())) {
|
| + // Check if the unexpanded type should be recorded; needed
|
| + // to track iterator aliases only
|
| + const Type* unexpandedType = field->getType().getSplitUnqualifiedType().Ty;
|
| + Edge* edge = CreateEdgeFromOriginalType(unexpandedType);
|
| + if (!edge)
|
| + edge = CreateEdge(field->getType().getTypePtrOrNull());
|
| + if (edge) {
|
| fields_status = fields_status.LUB(edge->NeedsTracing(Edge::kRecursive));
|
| fields->insert(std::make_pair(field, FieldPoint(field, edge)));
|
| }
|
| @@ -567,6 +575,36 @@ static bool isInStdNamespace(clang::Sema& sema, NamespaceDecl* ns)
|
| return false;
|
| }
|
|
|
| +Edge* RecordInfo::CreateEdgeFromOriginalType(const Type* type) {
|
| + if (!type)
|
| + return nullptr;
|
| +
|
| + // look for "typedef ... iterator;"
|
| + if (!isa<ElaboratedType>(type))
|
| + return nullptr;
|
| + const ElaboratedType* elaboratedType = cast<ElaboratedType>(type);
|
| + if (!isa<TypedefType>(elaboratedType->getNamedType()))
|
| + return nullptr;
|
| + const TypedefType* typedefType =
|
| + cast<TypedefType>(elaboratedType->getNamedType());
|
| + std::string typeName = typedefType->getDecl()->getNameAsString();
|
| + if (!Config::IsIterator(typeName))
|
| + return nullptr;
|
| + RecordInfo* info =
|
| + cache_->Lookup(elaboratedType->getQualifier()->getAsType());
|
| +
|
| + bool on_heap = false;
|
| + bool is_unsafe = false;
|
| + // Silently handle unknown types; the on-heap collection types will
|
| + // have to be in scope for the declaration to compile, though.
|
| + if (info) {
|
| + is_unsafe = Config::IsGCCollectionWithUnsafeIterator(info->name());
|
| + // Don't mark iterator as being on the heap if it is not supported.
|
| + on_heap = !is_unsafe && Config::IsGCCollection(info->name());
|
| + }
|
| + return new Iterator(info, on_heap, is_unsafe);
|
| +}
|
| +
|
| Edge* RecordInfo::CreateEdge(const Type* type) {
|
| if (!type) {
|
| return 0;
|
|
|