예제 #1
0
/// 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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}