int InterfaceDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) { //printf("%s.InterfaceDeclaration::isBaseOf(cd = '%s')\n", toChars(), cd->toChars()); assert(!baseClass); for (size_t j = 0; j < cd->interfaces_dim; j++) { BaseClass *b = cd->interfaces[j]; //printf("\tbase %s\n", b->base->toChars()); if (this == b->base) { //printf("\tfound at offset %d\n", b->offset); if (poffset) { *poffset = b->offset; if (j && cd->isInterfaceDeclaration()) *poffset = OFFSET_RUNTIME; } return 1; } if (isBaseOf(b, poffset)) { if (j && poffset && cd->isInterfaceDeclaration()) *poffset = OFFSET_RUNTIME; return 1; } } if (cd->baseClass && isBaseOf(cd->baseClass, poffset)) return 1; if (poffset) *poffset = 0; return 0; }
int InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset) { //printf("%s.InterfaceDeclaration::isBaseOf(bc = '%s')\n", toChars(), bc->base->toChars()); for (size_t j = 0; j < bc->baseInterfaces_dim; j++) { BaseClass *b = &bc->baseInterfaces[j]; if (this == b->base) { if (poffset) { *poffset = b->offset; if (j && bc->base->isInterfaceDeclaration()) *poffset = OFFSET_RUNTIME; } return 1; } if (isBaseOf(b, poffset)) { if (j && poffset && bc->base->isInterfaceDeclaration()) *poffset = OFFSET_RUNTIME; return 1; } } if (poffset) *poffset = 0; return 0; }
ASTNodeKind ASTNodeKind::getMostDerivedCommonAncestor(ASTNodeKind Kind1, ASTNodeKind Kind2) { NodeKindId Parent = Kind1.KindId; while (!isBaseOf(Parent, Kind2.KindId, nullptr) && Parent != NKI_None) { Parent = AllKindInfo[Parent].ParentId; } return ASTNodeKind(Parent); }
bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const { const auto From = getSupportedKind(); auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>(); auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>(); /// Mimic the implicit conversions of Matcher<>. /// - From Matcher<Type> to Matcher<QualType> if (From.isSame(TypeKind) && To.isSame(QualKind)) return true; /// - From Matcher<Base> to Matcher<Derived> return From.isBaseOf(To); }
bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const { return isBaseOf(KindId, Other.KindId, Distance); }
static const TypeVec throwsException(const Stmt *St, const TypeVec &Caught, llvm::SmallSet<const FunctionDecl *, 32> &CallStack) { TypeVec Results; if (!St) return Results; if (const auto *Throw = dyn_cast<CXXThrowExpr>(St)) { if (const auto *ThrownExpr = Throw->getSubExpr()) { const auto *ThrownType = ThrownExpr->getType()->getUnqualifiedDesugaredType(); if (ThrownType->isReferenceType()) { ThrownType = ThrownType->castAs<ReferenceType>() ->getPointeeType() ->getUnqualifiedDesugaredType(); } if (const auto *TD = ThrownType->getAsTagDecl()) { if (TD->getDeclName().isIdentifier() && TD->getName() == "bad_alloc" && TD->isInStdNamespace()) return Results; } Results.push_back(ThrownExpr->getType()->getUnqualifiedDesugaredType()); } else { Results.append(Caught.begin(), Caught.end()); } } else if (const auto *Try = dyn_cast<CXXTryStmt>(St)) { TypeVec Uncaught = throwsException(Try->getTryBlock(), Caught, CallStack); for (unsigned i = 0; i < Try->getNumHandlers(); ++i) { const CXXCatchStmt *Catch = Try->getHandler(i); if (!Catch->getExceptionDecl()) { const TypeVec Rethrown = throwsException(Catch->getHandlerBlock(), Uncaught, CallStack); Results.append(Rethrown.begin(), Rethrown.end()); Uncaught.clear(); } else { const auto *CaughtType = Catch->getCaughtType()->getUnqualifiedDesugaredType(); if (CaughtType->isReferenceType()) { CaughtType = CaughtType->castAs<ReferenceType>() ->getPointeeType() ->getUnqualifiedDesugaredType(); } auto NewEnd = llvm::remove_if(Uncaught, [&CaughtType](const Type *ThrownType) { return ThrownType == CaughtType || isBaseOf(ThrownType, CaughtType); }); if (NewEnd != Uncaught.end()) { Uncaught.erase(NewEnd, Uncaught.end()); const TypeVec Rethrown = throwsException( Catch->getHandlerBlock(), TypeVec(1, CaughtType), CallStack); Results.append(Rethrown.begin(), Rethrown.end()); } } } Results.append(Uncaught.begin(), Uncaught.end()); } else if (const auto *Call = dyn_cast<CallExpr>(St)) { if (const FunctionDecl *Func = Call->getDirectCallee()) { TypeVec Excs = throwsException(Func, CallStack); Results.append(Excs.begin(), Excs.end()); } } else { for (const Stmt *Child : St->children()) { TypeVec Excs = throwsException(Child, Caught, CallStack); Results.append(Excs.begin(), Excs.end()); } } return Results; }