本文整理汇总了C++中QualType::getPointeeCXXRecordDecl方法的典型用法代码示例。如果您正苦于以下问题:C++ QualType::getPointeeCXXRecordDecl方法的具体用法?C++ QualType::getPointeeCXXRecordDecl怎么用?C++ QualType::getPointeeCXXRecordDecl使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QualType
的用法示例。
在下文中一共展示了QualType::getPointeeCXXRecordDecl方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: adjustReturnValue
/// Adjusts a return value when the called function's return type does not
/// match the caller's expression type. This can happen when a dynamic call
/// is devirtualized, and the overridding method has a covariant (more specific)
/// return type than the parent's method. For C++ objects, this means we need
/// to add base casts.
static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy,
StoreManager &StoreMgr) {
// For now, the only adjustments we handle apply only to locations.
if (!V.getAs<Loc>())
return V;
// If the types already match, don't do any unnecessary work.
ExpectedTy = ExpectedTy.getCanonicalType();
ActualTy = ActualTy.getCanonicalType();
if (ExpectedTy == ActualTy)
return V;
// No adjustment is needed between Objective-C pointer types.
if (ExpectedTy->isObjCObjectPointerType() &&
ActualTy->isObjCObjectPointerType())
return V;
// C++ object pointers may need "derived-to-base" casts.
const CXXRecordDecl *ExpectedClass = ExpectedTy->getPointeeCXXRecordDecl();
const CXXRecordDecl *ActualClass = ActualTy->getPointeeCXXRecordDecl();
if (ExpectedClass && ActualClass) {
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
if (ActualClass->isDerivedFrom(ExpectedClass, Paths) &&
!Paths.isAmbiguous(ActualTy->getCanonicalTypeUnqualified())) {
return StoreMgr.evalDerivedToBase(V, Paths.front());
}
}
// Unfortunately, Objective-C does not enforce that overridden methods have
// covariant return types, so we can't assert that that never happens.
// Be safe and return UnknownVal().
return UnknownVal();
}
示例2: evalDerivedToBase
SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType,
bool IsVirtual) {
const MemRegion *DerivedReg = Derived.getAsRegion();
if (!DerivedReg)
return Derived;
const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();
if (!BaseDecl)
BaseDecl = BaseType->getAsCXXRecordDecl();
assert(BaseDecl && "not a C++ object?");
if (const auto *AlreadyDerivedReg =
dyn_cast<CXXDerivedObjectRegion>(DerivedReg)) {
if (const auto *SR =
dyn_cast<SymbolicRegion>(AlreadyDerivedReg->getSuperRegion()))
if (SR->getSymbol()->getType()->getPointeeCXXRecordDecl() == BaseDecl)
return loc::MemRegionVal(SR);
DerivedReg = AlreadyDerivedReg->getSuperRegion();
}
const MemRegion *BaseReg = MRMgr.getCXXBaseObjectRegion(
BaseDecl, cast<SubRegion>(DerivedReg), IsVirtual);
return loc::MemRegionVal(BaseReg);
}
示例3: while
const CXXRecordDecl *Utils::recordForMemberCall(CXXMemberCallExpr *call, string &implicitCallee)
{
implicitCallee.clear();
Expr *implicitArgument= call->getImplicitObjectArgument();
if (!implicitArgument) {
return nullptr;
}
Stmt *s = implicitArgument;
while (s) {
if (auto declRef = dyn_cast<DeclRefExpr>(s)) {
if (declRef->getDecl()) {
implicitCallee = declRef->getDecl()->getNameAsString();
QualType qt = declRef->getDecl()->getType();
return qt->getPointeeCXXRecordDecl();
} else {
return nullptr;
}
} else if (auto thisExpr = dyn_cast<CXXThisExpr>(s)) {
implicitCallee = "this";
return thisExpr->getType()->getPointeeCXXRecordDecl();
} else if (auto memberExpr = dyn_cast<MemberExpr>(s)) {
auto decl = memberExpr->getMemberDecl();
if (decl) {
implicitCallee = decl->getNameAsString();
QualType qt = decl->getType();
return qt->getPointeeCXXRecordDecl();
} else {
return nullptr;
}
}
s = s->child_begin() == s->child_end() ? nullptr : *(s->child_begin());
}
return nullptr;
}
示例4: evalDerivedToBase
SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType) {
loc::MemRegionVal *DerivedRegVal = dyn_cast<loc::MemRegionVal>(&Derived);
if (!DerivedRegVal)
return Derived;
const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();
if (!BaseDecl)
BaseDecl = BaseType->getAsCXXRecordDecl();
assert(BaseDecl && "not a C++ object?");
const MemRegion *BaseReg =
MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion());
return loc::MemRegionVal(BaseReg);
}
示例5: evalDerivedToBase
SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType,
bool IsVirtual) {
Optional<loc::MemRegionVal> DerivedRegVal =
Derived.getAs<loc::MemRegionVal>();
if (!DerivedRegVal)
return Derived;
const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();
if (!BaseDecl)
BaseDecl = BaseType->getAsCXXRecordDecl();
assert(BaseDecl && "not a C++ object?");
const MemRegion *BaseReg =
MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion(),
IsVirtual);
return loc::MemRegionVal(BaseReg);
}
示例6: regionMatchesCXXRecordType
static bool regionMatchesCXXRecordType(SVal V, QualType Ty) {
const MemRegion *MR = V.getAsRegion();
if (!MR)
return true;
const auto *TVR = dyn_cast<TypedValueRegion>(MR);
if (!TVR)
return true;
const CXXRecordDecl *RD = TVR->getValueType()->getAsCXXRecordDecl();
if (!RD)
return true;
const CXXRecordDecl *Expected = Ty->getPointeeCXXRecordDecl();
if (!Expected)
Expected = Ty->getAsCXXRecordDecl();
return Expected->getCanonicalDecl() == RD->getCanonicalDecl();
}
示例7: attemptDownCast
SVal StoreManager::attemptDownCast(SVal Base, QualType TargetType,
bool &Failed) {
Failed = false;
const MemRegion *MR = Base.getAsRegion();
if (!MR)
return UnknownVal();
// Assume the derived class is a pointer or a reference to a CXX record.
TargetType = TargetType->getPointeeType();
assert(!TargetType.isNull());
const CXXRecordDecl *TargetClass = TargetType->getAsCXXRecordDecl();
if (!TargetClass && !TargetType->isVoidType())
return UnknownVal();
// Drill down the CXXBaseObject chains, which represent upcasts (casts from
// derived to base).
while (const CXXRecordDecl *MRClass = getCXXRecordType(MR)) {
// If found the derived class, the cast succeeds.
if (MRClass == TargetClass)
return loc::MemRegionVal(MR);
// We skip over incomplete types. They must be the result of an earlier
// reinterpret_cast, as one can only dynamic_cast between types in the same
// class hierarchy.
if (!TargetType->isVoidType() && MRClass->hasDefinition()) {
// Static upcasts are marked as DerivedToBase casts by Sema, so this will
// only happen when multiple or virtual inheritance is involved.
CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
if (MRClass->isDerivedFrom(TargetClass, Paths))
return evalDerivedToBase(loc::MemRegionVal(MR), Paths.front());
}
if (const auto *BaseR = dyn_cast<CXXBaseObjectRegion>(MR)) {
// Drill down the chain to get the derived classes.
MR = BaseR->getSuperRegion();
continue;
}
// If this is a cast to void*, return the region.
if (TargetType->isVoidType())
return loc::MemRegionVal(MR);
// Strange use of reinterpret_cast can give us paths we don't reason
// about well, by putting in ElementRegions where we'd expect
// CXXBaseObjectRegions. If it's a valid reinterpret_cast (i.e. if the
// derived class has a zero offset from the base class), then it's safe
// to strip the cast; if it's invalid, -Wreinterpret-base-class should
// catch it. In the interest of performance, the analyzer will silently
// do the wrong thing in the invalid case (because offsets for subregions
// will be wrong).
const MemRegion *Uncasted = MR->StripCasts(/*IncludeBaseCasts=*/false);
if (Uncasted == MR) {
// We reached the bottom of the hierarchy and did not find the derived
// class. We must be casting the base to derived, so the cast should
// fail.
break;
}
MR = Uncasted;
}
// If we're casting a symbolic base pointer to a derived class, use
// CXXDerivedObjectRegion to represent the cast. If it's a pointer to an
// unrelated type, it must be a weird reinterpret_cast and we have to
// be fine with ElementRegion. TODO: Should we instead make
// Derived{TargetClass, Element{SourceClass, SR}}?
if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) {
QualType T = SR->getSymbol()->getType();
const CXXRecordDecl *SourceClass = T->getPointeeCXXRecordDecl();
if (TargetClass && SourceClass && TargetClass->isDerivedFrom(SourceClass))
return loc::MemRegionVal(
MRMgr.getCXXDerivedObjectRegion(TargetClass, SR));
return loc::MemRegionVal(GetElementZeroRegion(SR, TargetType));
}
// We failed if the region we ended up with has perfect type info.
Failed = isa<TypedValueRegion>(MR);
return UnknownVal();
}
示例8: check
void ProTypeCstyleCastCheck::check(const MatchFinder::MatchResult &Result) {
const auto *MatchedCast = Result.Nodes.getNodeAs<CStyleCastExpr>("cast");
if (MatchedCast->getCastKind() == CK_BitCast ||
MatchedCast->getCastKind() == CK_LValueBitCast ||
MatchedCast->getCastKind() == CK_IntegralToPointer ||
MatchedCast->getCastKind() == CK_PointerToIntegral ||
MatchedCast->getCastKind() == CK_ReinterpretMemberPointer) {
diag(MatchedCast->getLocStart(),
"do not use C-style cast to convert between unrelated types");
return;
}
QualType SourceType = MatchedCast->getSubExpr()->getType();
if (MatchedCast->getCastKind() == CK_BaseToDerived) {
const auto *SourceDecl = SourceType->getPointeeCXXRecordDecl();
if (!SourceDecl) // The cast is from object to reference.
SourceDecl = SourceType->getAsCXXRecordDecl();
if (!SourceDecl)
return;
if (SourceDecl->isPolymorphic()) {
// Leave type spelling exactly as it was (unlike
// getTypeAsWritten().getAsString() which would spell enum types 'enum
// X').
StringRef DestTypeString = Lexer::getSourceText(
CharSourceRange::getTokenRange(
MatchedCast->getLParenLoc().getLocWithOffset(1),
MatchedCast->getRParenLoc().getLocWithOffset(-1)),
*Result.SourceManager, getLangOpts());
auto diag_builder = diag(
MatchedCast->getLocStart(),
"do not use C-style cast to downcast from a base to a derived class; "
"use dynamic_cast instead");
const Expr *SubExpr =
MatchedCast->getSubExprAsWritten()->IgnoreImpCasts();
std::string CastText = ("dynamic_cast<" + DestTypeString + ">").str();
if (!isa<ParenExpr>(SubExpr)) {
CastText.push_back('(');
diag_builder << FixItHint::CreateInsertion(
Lexer::getLocForEndOfToken(SubExpr->getLocEnd(), 0,
*Result.SourceManager, getLangOpts()),
")");
}
auto ParenRange = CharSourceRange::getTokenRange(
MatchedCast->getLParenLoc(), MatchedCast->getRParenLoc());
diag_builder << FixItHint::CreateReplacement(ParenRange, CastText);
} else {
diag(
MatchedCast->getLocStart(),
"do not use C-style cast to downcast from a base to a derived class");
}
return;
}
if (MatchedCast->getCastKind() == CK_NoOp &&
needsConstCast(SourceType, MatchedCast->getType())) {
diag(MatchedCast->getLocStart(),
"do not use C-style cast to cast away constness");
}
}
示例9: isOSObjectPtr
static bool isOSObjectPtr(QualType QT) {
return isOSObjectSubclass(QT->getPointeeCXXRecordDecl());
}