-void DerivedType::setDerivedTypeProperties() {
- std::vector<const Type *> TypeStack;
- bool isAbstract = false, isRecursive = false;
-
- getTypeProps(this, TypeStack, isAbstract, isRecursive);
- setAbstract(isAbstract);
- setRecursive(isRecursive);
+void Type::PromoteAbstractToConcrete() {
+ if (!isAbstract()) return;
+
+ scc_iterator<TypePromotionGraph> SI = scc_begin(TypePromotionGraph(this));
+ scc_iterator<TypePromotionGraph> SE = scc_end (TypePromotionGraph(this));
+
+ for (; SI != SE; ++SI) {
+ std::vector<Type*> &SCC = *SI;
+
+ // Concrete types are leaves in the tree. Since an SCC will either be all
+ // abstract or all concrete, we only need to check one type.
+ if (SCC[0]->isAbstract()) {
+ if (isa<OpaqueType>(SCC[0]))
+ return; // Not going to be concrete, sorry.
+
+ // If all of the children of all of the types in this SCC are concrete,
+ // then this SCC is now concrete as well. If not, neither this SCC, nor
+ // any parent SCCs will be concrete, so we might as well just exit.
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i)
+ for (Type::subtype_iterator CI = SCC[i]->subtype_begin(),
+ E = SCC[i]->subtype_end(); CI != E; ++CI)
+ if ((*CI)->isAbstract())
+ // If the child type is in our SCC, it doesn't make the entire SCC
+ // abstract unless there is a non-SCC abstract type.
+ if (std::find(SCC.begin(), SCC.end(), *CI) == SCC.end())
+ return; // Not going to be concrete, sorry.
+
+ // Okay, we just discovered this whole SCC is now concrete, mark it as
+ // such!
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
+ assert(SCC[i]->isAbstract() && "Why are we processing concrete types?");
+
+ SCC[i]->setAbstract(false);
+ }
+
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
+ assert(!SCC[i]->isAbstract() && "Concrete type became abstract?");
+ // The type just became concrete, notify all users!
+ cast<DerivedType>(SCC[i])->notifyUsesThatTypeBecameConcrete();
+ }
+ }
+ }