本文整理汇总了C++中Sema::IsDerivedFrom方法的典型用法代码示例。如果您正苦于以下问题:C++ Sema::IsDerivedFrom方法的具体用法?C++ Sema::IsDerivedFrom怎么用?C++ Sema::IsDerivedFrom使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Sema
的用法示例。
在下文中一共展示了Sema::IsDerivedFrom方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SrcClass
/// TryStaticMemberPointerUpcast - Tests whether a conversion according to
/// C++ 5.2.9p9 is valid:
///
/// An rvalue of type "pointer to member of D of type cv1 T" can be
/// converted to an rvalue of type "pointer to member of B of type cv2 T",
/// where B is a base class of D [...].
///
TryCastResult
TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType,
bool CStyle, const SourceRange &OpRange,
unsigned &msg)
{
const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();
if (!DestMemPtr)
return TC_NotApplicable;
const MemberPointerType *SrcMemPtr = SrcType->getAs<MemberPointerType>();
if (!SrcMemPtr) {
msg = diag::err_bad_static_cast_member_pointer_nonmp;
return TC_NotApplicable;
}
// T == T, modulo cv
if (Self.Context.getCanonicalType(
SrcMemPtr->getPointeeType().getUnqualifiedType()) !=
Self.Context.getCanonicalType(DestMemPtr->getPointeeType().
getUnqualifiedType()))
return TC_NotApplicable;
// B base of D
QualType SrcClass(SrcMemPtr->getClass(), 0);
QualType DestClass(DestMemPtr->getClass(), 0);
BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/!CStyle,
/*DetectVirtual=*/true);
if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) {
return TC_NotApplicable;
}
// B is a base of D. But is it an allowed base? If not, it's a hard error.
if (Paths.isAmbiguous(DestClass)) {
Paths.clear();
Paths.setRecordingPaths(true);
bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths);
assert(StillOkay);
StillOkay = StillOkay;
std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths);
Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv)
<< 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
msg = 0;
return TC_Failed;
}
if (const RecordType *VBase = Paths.getDetectedVirtual()) {
Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual)
<< SrcClass << DestClass << QualType(VBase, 0) << OpRange;
msg = 0;
return TC_Failed;
}
if (!CStyle && Self.CheckBaseClassAccess(DestType, SrcType,
diag::err_downcast_from_inaccessible_base, Paths,
OpRange.getBegin(), DeclarationName())) {
msg = 0;
return TC_Failed;
}
return TC_Success;
}
示例2: SrcClass
/// TryStaticMemberPointerUpcast - Tests whether a conversion according to
/// C++ 5.2.9p9 is valid:
///
/// An rvalue of type "pointer to member of D of type cv1 T" can be
/// converted to an rvalue of type "pointer to member of B of type cv2 T",
/// where B is a base class of D [...].
///
TryStaticCastResult
TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType,
const SourceRange &OpRange)
{
const MemberPointerType *SrcMemPtr = SrcType->getAsMemberPointerType();
if (!SrcMemPtr)
return TSC_NotApplicable;
const MemberPointerType *DestMemPtr = DestType->getAsMemberPointerType();
if (!DestMemPtr)
return TSC_NotApplicable;
// T == T, modulo cv
if (Self.Context.getCanonicalType(
SrcMemPtr->getPointeeType().getUnqualifiedType()) !=
Self.Context.getCanonicalType(DestMemPtr->getPointeeType().
getUnqualifiedType()))
return TSC_NotApplicable;
// B base of D
QualType SrcClass(SrcMemPtr->getClass(), 0);
QualType DestClass(DestMemPtr->getClass(), 0);
BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false,
/*DetectVirtual=*/true);
if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) {
return TSC_NotApplicable;
}
// B is a base of D. But is it an allowed base? If not, it's a hard error.
if (Paths.isAmbiguous(DestClass)) {
Paths.clear();
Paths.setRecordingPaths(true);
bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths);
assert(StillOkay);
StillOkay = StillOkay;
std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths);
Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv)
<< 1 << SrcClass << DestClass << PathDisplayStr << OpRange;
return TSC_Failed;
}
if (const RecordType *VBase = Paths.getDetectedVirtual()) {
Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual)
<< SrcClass << DestClass << QualType(VBase, 0) << OpRange;
return TSC_Failed;
}
// FIXME: Test accessibility.
return TSC_Success;
}
示例3: if
//.........这里部分代码省略.........
if (DestPointer) {
DestPointee = DestPointer->getPointeeType();
} else if (DestReference) {
DestPointee = DestReference->getPointeeType();
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)
<< OrigDestType << DestRange;
return;
}
const RecordType *DestRecord = DestPointee->getAsRecordType();
if (DestPointee->isVoidType()) {
assert(DestPointer && "Reference to void is not possible");
} else if (DestRecord) {
if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,
diag::err_bad_dynamic_cast_incomplete,
DestRange))
return;
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
<< DestPointee.getUnqualifiedType() << DestRange;
return;
}
// C++0x 5.2.7p2: If T is a pointer type, v shall be an rvalue of a pointer to
// complete class type, [...]. If T is an lvalue reference type, v shall be
// an lvalue of a complete class type, [...]. If T is an rvalue reference
// type, v shall be an expression having a complete effective class type,
// [...]
QualType SrcType = Self.Context.getCanonicalType(OrigSrcType);
QualType SrcPointee;
if (DestPointer) {
if (const PointerType *SrcPointer = SrcType->getAsPointerType()) {
SrcPointee = SrcPointer->getPointeeType();
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
<< OrigSrcType << SrcExpr->getSourceRange();
return;
}
} else if (DestReference->isLValueReferenceType()) {
if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
<< "dynamic_cast" << OrigDestType << OpRange;
}
SrcPointee = SrcType;
} else {
SrcPointee = SrcType;
}
const RecordType *SrcRecord = SrcPointee->getAsRecordType();
if (SrcRecord) {
if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
diag::err_bad_dynamic_cast_incomplete,
SrcExpr->getSourceRange()))
return;
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
<< SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
return;
}
assert((DestPointer || DestReference) &&
"Bad destination non-ptr/ref slipped through.");
assert((DestRecord || DestPointee->isVoidType()) &&
"Bad destination pointee slipped through.");
assert(SrcRecord && "Bad source pointee slipped through.");
// C++ 5.2.7p1: The dynamic_cast operator shall not cast away constness.
if (!DestPointee.isAtLeastAsQualifiedAs(SrcPointee)) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_const_away)
<< "dynamic_cast" << OrigDestType << OrigSrcType << OpRange;
return;
}
// C++ 5.2.7p3: If the type of v is the same as the required result type,
// [except for cv].
if (DestRecord == SrcRecord) {
return;
}
// C++ 5.2.7p5
// Upcasts are resolved statically.
if (DestRecord && Self.IsDerivedFrom(SrcPointee, DestPointee)) {
Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,
OpRange.getBegin(), OpRange);
// Diagnostic already emitted on error.
return;
}
// C++ 5.2.7p6: Otherwise, v shall be [polymorphic].
const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition(Self.Context);
assert(SrcDecl && "Definition missing");
if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
<< SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
}
// Done. Everything else is run-time checks.
}
示例4: Paths
/// TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and
/// TryStaticPointerDowncast. Tests whether a static downcast from SrcType to
/// DestType, both of which must be canonical, is possible and allowed.
TryStaticCastResult
TryStaticDowncast(Sema &Self, QualType SrcType, QualType DestType,
const SourceRange &OpRange, QualType OrigSrcType,
QualType OrigDestType)
{
// Downcast can only happen in class hierarchies, so we need classes.
if (!DestType->isRecordType() || !SrcType->isRecordType()) {
return TSC_NotApplicable;
}
BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false,
/*DetectVirtual=*/true);
if (!Self.IsDerivedFrom(DestType, SrcType, Paths)) {
return TSC_NotApplicable;
}
// Target type does derive from source type. Now we're serious. If an error
// appears now, it's not ignored.
// This may not be entirely in line with the standard. Take for example:
// struct A {};
// struct B : virtual A {
// B(A&);
// };
//
// void f()
// {
// (void)static_cast<const B&>(*((A*)0));
// }
// As far as the standard is concerned, p5 does not apply (A is virtual), so
// p2 should be used instead - "const B& t(*((A*)0));" is perfectly valid.
// However, both GCC and Comeau reject this example, and accepting it would
// mean more complex code if we're to preserve the nice error message.
// FIXME: Being 100% compliant here would be nice to have.
// Must preserve cv, as always.
if (!DestType.isAtLeastAsQualifiedAs(SrcType)) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_const_away)
<< "static_cast" << OrigDestType << OrigSrcType << OpRange;
return TSC_Failed;
}
if (Paths.isAmbiguous(SrcType.getUnqualifiedType())) {
// This code is analoguous to that in CheckDerivedToBaseConversion, except
// that it builds the paths in reverse order.
// To sum up: record all paths to the base and build a nice string from
// them. Use it to spice up the error message.
Paths.clear();
Paths.setRecordingPaths(true);
Self.IsDerivedFrom(DestType, SrcType, Paths);
std::string PathDisplayStr;
std::set<unsigned> DisplayedPaths;
for (BasePaths::paths_iterator Path = Paths.begin();
Path != Paths.end(); ++Path) {
if (DisplayedPaths.insert(Path->back().SubobjectNumber).second) {
// We haven't displayed a path to this particular base
// class subobject yet.
PathDisplayStr += "\n ";
for (BasePath::const_reverse_iterator Element = Path->rbegin();
Element != Path->rend(); ++Element)
PathDisplayStr += Element->Base->getType().getAsString() + " -> ";
PathDisplayStr += DestType.getAsString();
}
}
Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast)
<< SrcType.getUnqualifiedType() << DestType.getUnqualifiedType()
<< PathDisplayStr << OpRange;
return TSC_Failed;
}
if (Paths.getDetectedVirtual() != 0) {
QualType VirtualBase(Paths.getDetectedVirtual(), 0);
Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)
<< OrigSrcType << OrigDestType << VirtualBase << OpRange;
return TSC_Failed;
}
// FIXME: Test accessibility.
return TSC_Success;
}