/// Find the current instantiation that associated with the given type. static CXXRecordDecl *getCurrentInstantiationOf(QualType T, DeclContext *CurContext) { if (T.isNull()) return nullptr; const Type *Ty = T->getCanonicalTypeInternal().getTypePtr(); if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) { CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl()); if (!Record->isDependentContext() || Record->isCurrentInstantiation(CurContext)) return Record; return nullptr; } else if (isa<InjectedClassNameType>(Ty)) return cast<InjectedClassNameType>(Ty)->getDecl(); else return nullptr; }
bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches, bool AllowShortCircuit) const { SmallVector<const CXXRecordDecl*, 8> Queue; llvm::SmallPtrSet<const CXXRecordDecl*, 8> Enqueued; const CXXRecordDecl *Record = this; bool AllMatches = true; while (true) { for (const auto &I : Record->bases()) { const RecordType *Ty = I.getType()->getAs<RecordType>(); if (!Ty) { if (AllowShortCircuit) return false; AllMatches = false; continue; } CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition()); if (!Base || (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))) { if (AllowShortCircuit) return false; AllMatches = false; continue; } if (Enqueued.insert(Base).second) { Queue.push_back(Base); if (!BaseMatches(Base)) { if (AllowShortCircuit) return false; AllMatches = false; continue; } } } if (Queue.empty()) break; Record = Queue.pop_back_val(); // not actually a queue. } return AllMatches; }
bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches, void *OpaqueData, bool AllowShortCircuit) const { SmallVector<const CXXRecordDecl*, 8> Queue; const CXXRecordDecl *Record = this; bool AllMatches = true; while (true) { for (CXXRecordDecl::base_class_const_iterator I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { const RecordType *Ty = I->getType()->getAs<RecordType>(); if (!Ty) { if (AllowShortCircuit) return false; AllMatches = false; continue; } CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition()); if (!Base || (Base->isDependentContext() && !Base->isCurrentInstantiation(Record))) { if (AllowShortCircuit) return false; AllMatches = false; continue; } Queue.push_back(Base); if (!BaseMatches(Base, OpaqueData)) { if (AllowShortCircuit) return false; AllMatches = false; continue; } } if (Queue.empty()) break; Record = Queue.back(); // not actually a queue. Queue.pop_back(); } return AllMatches; }