本文整理汇总了C++中QualType::getCanonicalType方法的典型用法代码示例。如果您正苦于以下问题:C++ QualType::getCanonicalType方法的具体用法?C++ QualType::getCanonicalType怎么用?C++ QualType::getCanonicalType使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类QualType
的用法示例。
在下文中一共展示了QualType::getCanonicalType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的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: isHighInt
bool CodeGenTypes::isHighInt(QualType Ty) {
if(const EnumType* et = dyn_cast<EnumType>(Ty.getCanonicalType())) {
Ty = et->getDecl()->getIntegerType();
}
if(const BuiltinType* bt = dyn_cast<BuiltinType>(Ty.getCanonicalType()))
return bt->isHighInt();
return false;
}
示例3: resolveCanonical
QualType TypeResolver::resolveCanonical(QualType Q) const {
if (Q->hasCanonicalType()) return Q.getCanonicalType();
const Type* T = Q.getTypePtr();
switch (Q->getTypeClass()) {
case TC_BUILTIN:
return Q;
case TC_POINTER:
{
const PointerType* P = cast<PointerType>(T);
QualType t1 = P->getPointeeType();
// Pointee will always be in same TypeContext (file), since it's either built-in or UnresolvedType
QualType t2 = resolveCanonical(t1);
assert(t2.isValid());
if (t1 == t2) {
Q->setCanonicalType(Q);
return Q;
} else {
// TODO qualifiers
QualType Canon = typeContext.getPointerType(t2);
if (!Canon->hasCanonicalType()) Canon->setCanonicalType(Canon);
Q->setCanonicalType(Canon);
return Canon;
}
}
case TC_ARRAY:
{
const ArrayType* A = cast<ArrayType>(T);
QualType t1 = A->getElementType();
// NOTE: qualifiers are lost here!
QualType t2 = resolveCanonical(t1);
if (t1 == t2) {
Q->setCanonicalType(Q);
return Q;
} else {
// NOTE: need size Expr, but set ownership to none
QualType Canon = typeContext.getArrayType(t2, A->getSizeExpr(), false, A->isIncremental());
if (!Canon->hasCanonicalType()) Canon->setCanonicalType(Canon);
Q->setCanonicalType(Canon);
return Canon;
}
}
case TC_UNRESOLVED:
assert(0 && "should not get here");
return QualType();
case TC_ALIAS:
case TC_STRUCT:
case TC_ENUM:
case TC_FUNCTION:
return Q.getCanonicalType();
case TC_MODULE:
assert(0 && "TBD");
return Q;
}
assert(0);
}
示例4: RequireCompleteTypeRoger
bool Sema::RequireCompleteTypeRoger(QualType T, RogerRequireCompleteReason RogerOnlyInheritance) {
if (!T->isIncompleteType()) {
return false;
}
if (T.getCanonicalType()->getTypeClass() != Type::Record) {
return false;
}
RecordDecl *Rec = cast<RecordType>(T.getCanonicalType())->getDecl();
return RequireCompleteRecordRoger(Rec, RogerOnlyInheritance);
}
示例5: LargestType
QualType TypeFinder::LargestType(const Expr* Left, const Expr* Right) {
QualType TL = findType(Left);
QualType TR = findType(Right);
// TODO cleanup
QualType Lcanon = TL.getCanonicalType();
QualType Rcanon = TR.getCanonicalType();
assert(Lcanon.isBuiltinType());
assert(Rcanon.isBuiltinType());
const BuiltinType* Lbi = cast<BuiltinType>(Lcanon);
const BuiltinType* Rbi = cast<BuiltinType>(Rcanon);
if (Lbi->getWidth() > Rbi->getWidth()) {
return TL;
}
return TR;
}
示例6: CastRetrievedVal
/// CastRetrievedVal - Used by subclasses of StoreManager to implement
/// implicit casts that arise from loads from regions that are reinterpreted
/// as another region.
SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
QualType castTy) {
if (castTy.isNull() || V.isUnknownOrUndef())
return V;
// The dispatchCast() call below would convert the int into a float.
// What we want, however, is a bit-by-bit reinterpretation of the int
// as a float, which usually yields nothing garbage. For now skip casts
// from ints to floats.
// TODO: What other combinations of types are affected?
if (castTy->isFloatingType()) {
SymbolRef Sym = V.getAsSymbol();
if (Sym && !Sym->getType()->isFloatingType())
return UnknownVal();
}
// When retrieving symbolic pointer and expecting a non-void pointer,
// wrap them into element regions of the expected type if necessary.
// SValBuilder::dispatchCast() doesn't do that, but it is necessary to
// make sure that the retrieved value makes sense, because there's no other
// cast in the AST that would tell us to cast it to the correct pointer type.
// We might need to do that for non-void pointers as well.
// FIXME: We really need a single good function to perform casts for us
// correctly every time we need it.
if (castTy->isPointerType() && !castTy->isVoidPointerType())
if (const auto *SR = dyn_cast_or_null<SymbolicRegion>(V.getAsRegion()))
if (SR->getSymbol()->getType().getCanonicalType() !=
castTy.getCanonicalType())
return loc::MemRegionVal(castRegion(SR, castTy));
return svalBuilder.dispatchCast(V, castTy);
}
示例7: UG
bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
SmallVectorImpl<char> &Buf) {
if (T.isNull())
return true;
T = T.getCanonicalType();
USRGenerator UG(&Ctx, Buf);
UG.VisitType(T);
return UG.ignoreResults();
}
示例8: analyze_value_decl
void FindGPUMacro::analyze_value_decl(ValueDecl *val) {
QualType type = val->getType();
std::pair<uint64_t, unsigned> fieldInfo =
val->getASTContext().getTypeInfo(val->getType());
uint64_t typeSize = fieldInfo.first;
unsigned fieldAlign = fieldInfo.second;
_os << "base type: " << type.getCanonicalType().getAsString()
<< ", size (bits): " << typeSize
<< ", align (bits): " << fieldAlign
<< "\n";
}
示例9: isStdInitializerList
static bool isStdInitializerList(QualType Type) {
Type = Type.getCanonicalType();
if (const auto *TS = Type->getAs<TemplateSpecializationType>()) {
if (const TemplateDecl *TD = TS->getTemplateName().getAsTemplateDecl())
return declIsStdInitializerList(TD);
}
if (const auto *RT = Type->getAs<RecordType>()) {
if (const auto *Specialization =
dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()))
return declIsStdInitializerList(Specialization->getSpecializedTemplate());
}
return false;
}
示例10:
bool
RetainSummaryManager::isKnownSmartPointer(QualType QT) {
QT = QT.getCanonicalType();
const auto *RD = QT->getAsCXXRecordDecl();
if (!RD)
return false;
const IdentifierInfo *II = RD->getIdentifier();
if (II && II->getName() == "smart_ptr")
if (const auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext()))
if (ND->getNameAsString() == "os")
return true;
return false;
}
示例11: canSymbolicate
bool SymbolManager::canSymbolicate(QualType T) {
T = T.getCanonicalType();
if (Loc::isLocType(T))
return true;
if (T->isIntegralOrEnumerationType())
return true;
if (T->isRecordType() && !T->isUnionType())
return true;
return false;
}
示例12: isTriviallyDefaultConstructible
// Based on QualType::isTrivial.
bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
if (Type.isNull())
return false;
if (Type->isArrayType())
return isTriviallyDefaultConstructible(Context.getBaseElementType(Type),
Context);
// Return false for incomplete types after skipping any incomplete array
// types which are expressly allowed by the standard and thus our API.
if (Type->isIncompleteType())
return false;
if (Context.getLangOpts().ObjCAutoRefCount) {
switch (Type.getObjCLifetime()) {
case Qualifiers::OCL_ExplicitNone:
return true;
case Qualifiers::OCL_Strong:
case Qualifiers::OCL_Weak:
case Qualifiers::OCL_Autoreleasing:
return false;
case Qualifiers::OCL_None:
if (Type->isObjCLifetimeType())
return false;
break;
}
}
QualType CanonicalType = Type.getCanonicalType();
if (CanonicalType->isDependentType())
return false;
// As an extension, Clang treats vector types as Scalar types.
if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
return true;
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
return recordIsTriviallyDefaultConstructible(*RT->getDecl(), Context);
}
// No other types can match.
return false;
}
示例13: isSafeToConvert
/// isSafeToConvert - Return true if it is safe to convert this field type,
/// which requires the structure elements contained by-value to all be
/// recursively safe to convert.
static bool
isSafeToConvert(QualType T, CodeGenTypes &CGT,
llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) {
T = T.getCanonicalType();
// If this is a record, check it.
if (const RecordType *RT = dyn_cast<RecordType>(T))
return isSafeToConvert(RT->getDecl(), CGT, AlreadyChecked);
// If this is an array, check the elements, which are embedded inline.
if (const ArrayType *AT = dyn_cast<ArrayType>(T))
return isSafeToConvert(AT->getElementType(), CGT, AlreadyChecked);
// Otherwise, there is no concern about transforming this. We only care about
// things that are contained by-value in a structure that can have another
// structure as a member.
return true;
}
示例14: hasAggregateLLVMType
bool CodeGenFunction::hasAggregateLLVMType(QualType type) {
switch (type.getCanonicalType()->getTypeClass()) {
#define TYPE(name, parent)
#define ABSTRACT_TYPE(name, parent)
#define NON_CANONICAL_TYPE(name, parent) case Type::name:
#define DEPENDENT_TYPE(name, parent) case Type::name:
#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
#include "clang/AST/TypeNodes.def"
llvm_unreachable("non-canonical or dependent type in IR-generation");
case Type::Builtin:
case Type::Pointer:
case Type::BlockPointer:
case Type::LValueReference:
case Type::RValueReference:
case Type::MemberPointer:
case Type::Vector:
case Type::ExtVector:
case Type::FunctionProto:
case Type::FunctionNoProto:
case Type::Enum:
case Type::ObjCObjectPointer:
return false;
// Complexes, arrays, records, and Objective-C objects.
case Type::Complex:
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
case Type::Record:
case Type::ObjCObject:
case Type::ObjCInterface:
return true;
// In IRGen, atomic types are just the underlying type
case Type::Atomic:
return hasAggregateLLVMType(type->getAs<AtomicType>()->getValueType());
}
llvm_unreachable("unknown type kind!");
}
示例15: evalCast
// FIXME: should rewrite according to the cast kind.
SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
castTy = Context.getCanonicalType(castTy);
originalTy = Context.getCanonicalType(originalTy);
if (val.isUnknownOrUndef() || castTy == originalTy)
return val;
if (castTy->isBooleanType()) {
if (val.isUnknownOrUndef())
return val;
if (val.isConstant())
return makeTruthVal(!val.isZeroConstant(), castTy);
if (!Loc::isLocType(originalTy) &&
!originalTy->isIntegralOrEnumerationType() &&
!originalTy->isMemberPointerType())
return UnknownVal();
if (SymbolRef Sym = val.getAsSymbol(true)) {
BasicValueFactory &BVF = getBasicValueFactory();
// FIXME: If we had a state here, we could see if the symbol is known to
// be zero, but we don't.
return makeNonLoc(Sym, BO_NE, BVF.getValue(0, Sym->getType()), castTy);
}
// Loc values are not always true, they could be weakly linked functions.
if (Optional<Loc> L = val.getAs<Loc>())
return evalCastFromLoc(*L, castTy);
Loc L = val.castAs<nonloc::LocAsInteger>().getLoc();
return evalCastFromLoc(L, castTy);
}
// For const casts, casts to void, just propagate the value.
if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
if (shouldBeModeledWithNoOp(Context, Context.getPointerType(castTy),
Context.getPointerType(originalTy)))
return val;
// Check for casts from pointers to integers.
if (castTy->isIntegralOrEnumerationType() && Loc::isLocType(originalTy))
return evalCastFromLoc(val.castAs<Loc>(), castTy);
// Check for casts from integers to pointers.
if (Loc::isLocType(castTy) && originalTy->isIntegralOrEnumerationType()) {
if (Optional<nonloc::LocAsInteger> LV = val.getAs<nonloc::LocAsInteger>()) {
if (const MemRegion *R = LV->getLoc().getAsRegion()) {
StoreManager &storeMgr = StateMgr.getStoreManager();
R = storeMgr.castRegion(R, castTy);
return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
}
return LV->getLoc();
}
return dispatchCast(val, castTy);
}
// Just pass through function and block pointers.
if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
assert(Loc::isLocType(castTy));
return val;
}
// Check for casts from array type to another type.
if (const ArrayType *arrayT =
dyn_cast<ArrayType>(originalTy.getCanonicalType())) {
// We will always decay to a pointer.
QualType elemTy = arrayT->getElementType();
val = StateMgr.ArrayToPointer(val.castAs<Loc>(), elemTy);
// Are we casting from an array to a pointer? If so just pass on
// the decayed value.
if (castTy->isPointerType() || castTy->isReferenceType())
return val;
// Are we casting from an array to an integer? If so, cast the decayed
// pointer value to an integer.
assert(castTy->isIntegralOrEnumerationType());
// FIXME: Keep these here for now in case we decide soon that we
// need the original decayed type.
// QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
// QualType pointerTy = C.getPointerType(elemTy);
return evalCastFromLoc(val.castAs<Loc>(), castTy);
}
// Check for casts from a region to a specific type.
if (const MemRegion *R = val.getAsRegion()) {
// Handle other casts of locations to integers.
if (castTy->isIntegralOrEnumerationType())
return evalCastFromLoc(loc::MemRegionVal(R), castTy);
// FIXME: We should handle the case where we strip off view layers to get
// to a desugared type.
if (!Loc::isLocType(castTy)) {
// FIXME: There can be gross cases where one casts the result of a function
// (that returns a pointer) to some other value that happens to fit
// within that pointer value. We currently have no good way to
// model such operations. When this happens, the underlying operation
// is that the caller is reasoning about bits. Conceptually we are
// layering a "view" of a location on top of those bits. Perhaps
// we need to be more lazy about mutual possible views, even on an
// SVal? This may be necessary for bit-level reasoning as well.
return UnknownVal();
//.........这里部分代码省略.........