/// \brief Determine whether the given types are equivalent after
/// cvr-qualifiers have been removed.
bool hasSameUnqualifiedType(QualType T1, QualType T2) {
- T1 = getCanonicalType(T1);
- T2 = getCanonicalType(T2);
- return T1.getUnqualifiedType() == T2.getUnqualifiedType();
+ CanQualType CT1 = getCanonicalType(T1);
+ CanQualType CT2 = getCanonicalType(T2);
+ return CT1.getUnqualifiedType() == CT2.getUnqualifiedType();
}
/// \brief Retrieves the "canonical" declaration of
CanProxy<T> operator->() const;
/// \brief Retrieve all qualifiers.
- Qualifiers getQualifiers() const { return Stored.getQualifiers(); }
+ Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
/// \brief Retrieve the const/volatile/restrict qualifiers.
- unsigned getCVRQualifiers() const { return Stored.getCVRQualifiers(); }
+ unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
/// \brief Determines whether this type has any qualifiers
- bool hasQualifiers() const { return Stored.hasQualifiers(); }
+ bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
bool isConstQualified() const {
- return Stored.isConstQualified();
+ return Stored.isLocalConstQualified();
}
bool isVolatileQualified() const {
- return Stored.isVolatileQualified();
+ return Stored.isLocalVolatileQualified();
}
bool isRestrictQualified() const {
- return Stored.isRestrictQualified();
+ return Stored.isLocalRestrictQualified();
}
/// \brief Retrieve the unqualified form of this type.
//----------------------------------------------------------------------------//
template<typename T>
inline CanQual<T> CanQual<T>::getUnqualifiedType() const {
- return CanQual<T>::CreateUnsafe(Stored.getUnqualifiedType());
+ return CanQual<T>::CreateUnsafe(Stored.getLocalUnqualifiedType());
}
template<typename T>
llvm::PointerIntPair<llvm::PointerUnion<const Type*,const ExtQuals*>,
Qualifiers::FastWidth> Value;
- bool hasExtQuals() const {
- return Value.getPointer().is<const ExtQuals*>();
- }
-
const ExtQuals *getExtQualsUnsafe() const {
return Value.getPointer().get<const ExtQuals*>();
}
QualType(const ExtQuals *Ptr, unsigned Quals)
: Value(Ptr, Quals) {}
- unsigned getFastQualifiers() const { return Value.getInt(); }
- void setFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
+ unsigned getLocalFastQualifiers() const { return Value.getInt(); }
+ void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
/// Retrieves a pointer to the underlying (unqualified) type.
/// This should really return a const Type, but it's not worth
/// changing all the users right now.
Type *getTypePtr() const {
- if (hasNonFastQualifiers())
+ if (hasLocalNonFastQualifiers())
return const_cast<Type*>(getExtQualsUnsafe()->getBaseType());
return const_cast<Type*>(getTypePtrUnsafe());
}
return Value.getPointer().isNull();
}
+ /// \brief Determine whether this particular QualType instance has the
+ /// "const" qualifier set, without looking through typedefs that may have
+ /// added "const" at a different level.
+ bool isLocalConstQualified() const {
+ return (getLocalFastQualifiers() & Qualifiers::Const);
+ }
+
+ /// \brief Determine whether this type is const-qualified.
bool isConstQualified() const {
- return (getFastQualifiers() & Qualifiers::Const);
+ // FIXME: Look through sugar types.
+ return isLocalConstQualified();
+ }
+
+ /// \brief Determine whether this particular QualType instance has the
+ /// "restrict" qualifier set, without looking through typedefs that may have
+ /// added "restrict" at a different level.
+ bool isLocalRestrictQualified() const {
+ return (getLocalFastQualifiers() & Qualifiers::Restrict);
}
+
+ /// \brief Determine whether this type is restrict-qualified.
bool isRestrictQualified() const {
- return (getFastQualifiers() & Qualifiers::Restrict);
+ // FIXME: Look through sugar types.
+ return isLocalRestrictQualified();
+ }
+
+ /// \brief Determine whether this particular QualType instance has the
+ /// "volatile" qualifier set, without looking through typedefs that may have
+ /// added "volatile" at a different level.
+ bool isLocalVolatileQualified() const {
+ return (hasLocalNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
}
+
+ /// \brief Determine whether this type is volatile-qualified.
bool isVolatileQualified() const {
- return (hasNonFastQualifiers() && getExtQualsUnsafe()->hasVolatile());
+ // FIXME: Look through sugar types.
+ return isLocalVolatileQualified();
+ }
+
+ /// \brief Determine whether this particular QualType instance has any
+ /// qualifiers, without looking through any typedefs that might add
+ /// qualifiers at a different level.
+ bool hasLocalQualifiers() const {
+ return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
}
- // Determines whether this type has any direct qualifiers.
+ /// \brief Determine whether this type has any qualifiers.
bool hasQualifiers() const {
- return getFastQualifiers() || hasNonFastQualifiers();
+ // FIXME: Look for qualifiers at any level.
+ return hasLocalQualifiers();
}
-
- bool hasNonFastQualifiers() const {
- return hasExtQuals();
+
+ /// \brief Determine whether this particular QualType instance has any
+ /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
+ /// instance.
+ bool hasLocalNonFastQualifiers() const {
+ return Value.getPointer().is<const ExtQuals*>();
}
- // Retrieves the set of qualifiers belonging to this type.
- Qualifiers getQualifiers() const {
+ /// \brief Retrieve the set of qualifiers local to this particular QualType
+ /// instance, not including any qualifiers acquired through typedefs or
+ /// other sugar.
+ Qualifiers getLocalQualifiers() const {
Qualifiers Quals;
- if (hasNonFastQualifiers())
+ if (hasLocalNonFastQualifiers())
Quals = getExtQualsUnsafe()->getQualifiers();
- Quals.addFastQualifiers(getFastQualifiers());
+ Quals.addFastQualifiers(getLocalFastQualifiers());
return Quals;
}
- // Retrieves the CVR qualifiers of this type.
- unsigned getCVRQualifiers() const {
- unsigned CVR = getFastQualifiers();
- if (isVolatileQualified()) CVR |= Qualifiers::Volatile;
+ /// \brief Retrieve the set of qualifiers applied to this type.
+ Qualifiers getQualifiers() const {
+ // FIXME: Collect qualifiers from all levels.
+ return getLocalQualifiers();
+ }
+
+ /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// local to this particular QualType instance, not including any qualifiers
+ /// acquired through typedefs or other sugar.
+ unsigned getLocalCVRQualifiers() const {
+ unsigned CVR = getLocalFastQualifiers();
+ if (isLocalVolatileQualified())
+ CVR |= Qualifiers::Volatile;
return CVR;
}
+ /// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
+ /// applied to this type.
+ unsigned getCVRQualifiers() const {
+ // FIXME: Collect qualifiers from all levels.
+ return getLocalCVRQualifiers();
+ }
+
bool isConstant(ASTContext& Ctx) const {
return QualType::isConstant(*this, Ctx);
}
Value.setInt(Value.getInt() | TQs);
}
+ // FIXME: The remove* functions are semantically broken, because they might
+ // not remove a qualifier stored on a typedef. Most of the with* functions
+ // have the same problem.
void removeConst();
void removeVolatile();
void removeRestrict();
return T;
}
- QualType getUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+ /// \brief Return this type with all of the instance-specific qualifiers
+ /// removed, but without removing any qualifiers that may have been applied
+ /// through typedefs.
+ QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
+ /// \brief Return the unqualified form of the given type, which might be
+ /// desugared to eliminate qualifiers introduced via typedefs.
+ QualType getUnqualifiedType() const {
+ // FIXME: We may have to desugar the type to remove qualifiers.
+ return getLocalUnqualifiedType();
+ }
+
bool isMoreQualifiedThan(QualType Other) const;
bool isAtLeastAsQualifiedAs(QualType Other) const;
QualType getNonReferenceType() const;
/// Collect any qualifiers on the given type and return an
/// unqualified type.
const Type *strip(QualType QT) {
- addFastQualifiers(QT.getFastQualifiers());
- if (QT.hasNonFastQualifiers()) {
+ addFastQualifiers(QT.getLocalFastQualifiers());
+ if (QT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = QT.getExtQualsUnsafe();
Context = &EQ->getContext();
addQualifiers(EQ->getQualifiers());
inline bool QualType::isCanonical() const {
const Type *T = getTypePtr();
- if (hasQualifiers())
+ if (hasLocalQualifiers())
return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
return T->isCanonicalUnqualified();
}
inline bool QualType::isCanonicalAsParam() const {
- if (hasQualifiers()) return false;
+ if (hasLocalQualifiers()) return false;
const Type *T = getTypePtr();
return T->isCanonicalUnqualified() &&
!isa<FunctionType>(T) && !isa<ArrayType>(T);
/// getAddressSpace - Return the address space of this type.
inline unsigned QualType::getAddressSpace() const {
- if (hasNonFastQualifiers()) {
+ if (hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = getExtQualsUnsafe();
if (EQ->hasAddressSpace())
return EQ->getAddressSpace();
}
QualType CT = getTypePtr()->getCanonicalTypeInternal();
- if (CT.hasNonFastQualifiers()) {
+ if (CT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = CT.getExtQualsUnsafe();
if (EQ->hasAddressSpace())
return EQ->getAddressSpace();
/// getObjCGCAttr - Return the gc attribute of this type.
inline Qualifiers::GC QualType::getObjCGCAttr() const {
- if (hasNonFastQualifiers()) {
+ if (hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = getExtQualsUnsafe();
if (EQ->hasObjCGCAttr())
return EQ->getObjCGCAttr();
}
QualType CT = getTypePtr()->getCanonicalTypeInternal();
- if (CT.hasNonFastQualifiers()) {
+ if (CT.hasLocalNonFastQualifiers()) {
const ExtQuals *EQ = CT.getExtQualsUnsafe();
if (EQ->hasObjCGCAttr())
return EQ->getObjCGCAttr();
return 0;
}
-// NOTE: All of these methods use "getUnqualifiedType" to strip off address
-// space qualifiers if present.
inline bool Type::isFunctionType() const {
- return isa<FunctionType>(CanonicalType.getUnqualifiedType());
+ return isa<FunctionType>(CanonicalType);
}
inline bool Type::isPointerType() const {
- return isa<PointerType>(CanonicalType.getUnqualifiedType());
+ return isa<PointerType>(CanonicalType);
}
inline bool Type::isAnyPointerType() const {
return isPointerType() || isObjCObjectPointerType();
}
inline bool Type::isBlockPointerType() const {
- return isa<BlockPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<BlockPointerType>(CanonicalType);
}
inline bool Type::isReferenceType() const {
- return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<ReferenceType>(CanonicalType);
}
inline bool Type::isLValueReferenceType() const {
- return isa<LValueReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<LValueReferenceType>(CanonicalType);
}
inline bool Type::isRValueReferenceType() const {
- return isa<RValueReferenceType>(CanonicalType.getUnqualifiedType());
+ return isa<RValueReferenceType>(CanonicalType);
}
inline bool Type::isFunctionPointerType() const {
if (const PointerType* T = getAs<PointerType>())
return false;
}
inline bool Type::isMemberPointerType() const {
- return isa<MemberPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<MemberPointerType>(CanonicalType);
}
inline bool Type::isMemberFunctionPointerType() const {
if (const MemberPointerType* T = getAs<MemberPointerType>())
return false;
}
inline bool Type::isArrayType() const {
- return isa<ArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<ArrayType>(CanonicalType);
}
inline bool Type::isConstantArrayType() const {
- return isa<ConstantArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<ConstantArrayType>(CanonicalType);
}
inline bool Type::isIncompleteArrayType() const {
- return isa<IncompleteArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<IncompleteArrayType>(CanonicalType);
}
inline bool Type::isVariableArrayType() const {
- return isa<VariableArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<VariableArrayType>(CanonicalType);
}
inline bool Type::isDependentSizedArrayType() const {
- return isa<DependentSizedArrayType>(CanonicalType.getUnqualifiedType());
+ return isa<DependentSizedArrayType>(CanonicalType);
}
inline bool Type::isRecordType() const {
- return isa<RecordType>(CanonicalType.getUnqualifiedType());
+ return isa<RecordType>(CanonicalType);
}
inline bool Type::isAnyComplexType() const {
- return isa<ComplexType>(CanonicalType.getUnqualifiedType());
+ return isa<ComplexType>(CanonicalType);
}
inline bool Type::isVectorType() const {
- return isa<VectorType>(CanonicalType.getUnqualifiedType());
+ return isa<VectorType>(CanonicalType);
}
inline bool Type::isExtVectorType() const {
- return isa<ExtVectorType>(CanonicalType.getUnqualifiedType());
+ return isa<ExtVectorType>(CanonicalType);
}
inline bool Type::isObjCObjectPointerType() const {
- return isa<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
+ return isa<ObjCObjectPointerType>(CanonicalType);
}
inline bool Type::isObjCInterfaceType() const {
- return isa<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
+ return isa<ObjCInterfaceType>(CanonicalType);
}
inline bool Type::isObjCQualifiedIdType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
return isObjCIdType() || isObjCClassType();
}
inline bool Type::isTemplateTypeParmType() const {
- return isa<TemplateTypeParmType>(CanonicalType.getUnqualifiedType());
+ return isa<TemplateTypeParmType>(CanonicalType);
}
inline bool Type::isSpecificBuiltinType(unsigned K) const {
: Ty(ty), Data(opaqueData) { }
TypeLocClass getTypeLocClass() const {
- if (getType().hasQualifiers()) return Qualified;
+ if (getType().hasLocalQualifiers()) return Qualified;
return (TypeLocClass) getType()->getTypeClass();
}
}
static bool classof(const TypeLoc *TL) {
- return !TL->getType().hasQualifiers();
+ return !TL->getType().hasLocalQualifiers();
}
static bool classof(const UnqualTypeLoc *TL) { return true; }
};
}
static bool classof(const TypeLoc *TL) {
- return TL->getType().hasQualifiers();
+ return TL->getType().hasLocalQualifiers();
}
static bool classof(const QualifiedTypeLoc *TL) { return true; }
};
return QualType::getFromOpaquePtr((void*) 2);
}
static inline unsigned getHashValue(QualType T) {
- assert(!T.getFastQualifiers() && "hash invalid for types with fast quals");
+ assert(!T.getLocalFastQualifiers() &&
+ "hash invalid for types with fast quals");
uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
return (unsigned(v) >> 4) ^ (unsigned(v) >> 9);
}
NODE_XML(QualType, "CvQualifiedType")
ID_ATTRIBUTE_XML
TYPE_ATTRIBUTE_XML(getTypePtr()) // the qualified type, e.g. for 'T* const' it's 'T*'
- ATTRIBUTE_OPT_XML(isConstQualified(), "const") // boolean
- ATTRIBUTE_OPT_XML(isVolatileQualified(), "volatile") // boolean
- ATTRIBUTE_OPT_XML(isRestrictQualified(), "restrict") // boolean
+ ATTRIBUTE_OPT_XML(isLocalConstQualified(), "const") // boolean
+ ATTRIBUTE_OPT_XML(isLocalVolatileQualified(), "volatile") // boolean
+ ATTRIBUTE_OPT_XML(isLocalRestrictQualified(), "restrict") // boolean
ATTRIBUTE_OPT_XML(getObjCGCAttr(), "objc_gc") // Qualifiers::GC
ATTRIBUTE_OPT_XML(getAddressSpace(), "address_space") // unsigned
END_NODE_XML
}
}
- return getQualifiedType(ResultType, T.getQualifiers());
+ return getQualifiedType(ResultType, T.getLocalQualifiers());
}
/// getComplexType - Return the uniqued reference to the type for a complex
const ArrayType *ASTContext::getAsArrayType(QualType T) {
// Handle the non-qualified case efficiently.
- if (!T.hasQualifiers()) {
+ if (!T.hasLocalQualifiers()) {
// Handle the common positive case fast.
if (const ArrayType *AT = dyn_cast<ArrayType>(T))
return AT;
return LHS;
// If the qualifiers are different, the types aren't compatible... mostly.
- Qualifiers LQuals = LHSCan.getQualifiers();
- Qualifiers RQuals = RHSCan.getQualifiers();
+ Qualifiers LQuals = LHSCan.getLocalQualifiers();
+ Qualifiers RQuals = RHSCan.getLocalQualifiers();
if (LQuals != RQuals) {
// If any of these qualifiers are different, we have a type
// mismatch.
for (base_class_const_iterator BaseSpec = bases_begin(),
BaseSpecEnd = bases_end(); BaseSpec != BaseSpecEnd; ++BaseSpec) {
// Find the record of the base class subobjects for this type.
- QualType BaseType = Context.getCanonicalType(BaseSpec->getType());
- BaseType = BaseType.getUnqualifiedType();
+ QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
+ .getUnqualifiedType();
// C++ [temp.dep]p3:
// In the definition of a class template or a member of a class template,
if (!ArgType.isConstQualified())
AcceptsConst = false;
}
- if (Context.getCanonicalType(ArgType).getUnqualifiedType() != ClassType)
+ if (!Context.hasSameUnqualifiedType(ArgType, ClassType))
continue;
MD = Method;
// We have a single argument of type cv X or cv X&, i.e. we've found the
QualType ClassType = Context.getCanonicalType(Context.getTypeDeclType(
const_cast<CXXRecordDecl*>(this)));
- if (ClassType != Context.getCanonicalType(ArgType))
+ if (!Context.hasSameUnqualifiedType(ClassType, ArgType))
return;
// This is a copy assignment operator.
return;
// Print qualifiers as appropriate.
- Qualifiers Quals = T.getQualifiers();
+ Qualifiers Quals = T.getLocalQualifiers();
if (!Quals.empty()) {
std::string TQS;
Quals.getAsStringInternal(TQS, Policy);
ObjCQIString += '>';
}
- T->getPointeeType().getQualifiers().getAsStringInternal(ObjCQIString, Policy);
+ T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString,
+ Policy);
if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
ObjCQIString += " *"; // Don't forget the implicit pointer.
E = MD->param_end(); I != E; ++I, ++i)
if (ParmVarDecl *PD = *I) {
QualType Ty = Ctx.getCanonicalType(PD->getType());
- if (Ty.getUnqualifiedType() == Ctx.VoidPtrTy)
+ if (Ty.getLocalUnqualifiedType() == Ctx.VoidPtrTy)
ScratchArgs = AF.Add(ScratchArgs, i, StopTracking);
}
}
ASTContext &C = ValMgr.getContext();
// For const casts, just propagate the value.
- if (C.getCanonicalType(castTy).getUnqualifiedType() ==
- C.getCanonicalType(originalTy).getUnqualifiedType())
+ if (C.hasSameUnqualifiedType(castTy, originalTy))
return CastResult(state, val);
// Check for casts from pointers to integers.
QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
// Handle casts to void*. We just pass the region through.
- if (CanonPointeeTy.getUnqualifiedType() == Ctx.VoidTy)
+ if (CanonPointeeTy.getLocalUnqualifiedType() == Ctx.VoidTy)
return R;
// Handle casts from compatible types.
if (castTy.isNull())
return V;
- assert(Ctx.getCanonicalType(castTy).getUnqualifiedType() ==
- Ctx.getCanonicalType(R->getValueType(Ctx)).getUnqualifiedType());
-
+ assert(Ctx.hasSameUnqualifiedType(castTy, R->getValueType(Ctx)));
return V;
}
llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,
llvm::DICompileUnit Unit) {
// Handle qualifiers, which recursively handles what they refer to.
- if (Ty.hasQualifiers())
+ if (Ty.hasLocalQualifiers())
return CreateQualifiedType(Ty, Unit);
// Work out details of type.
// Only operate on the canonical type!
T = Context.getASTContext().getCanonicalType(T);
- bool IsSubstitutable = T.hasQualifiers() || !isa<BuiltinType>(T);
+ bool IsSubstitutable = T.hasLocalQualifiers() || !isa<BuiltinType>(T);
if (IsSubstitutable && mangleSubstitution(T))
return;
- if (Qualifiers Quals = T.getQualifiers()) {
+ if (Qualifiers Quals = T.getLocalQualifiers()) {
mangleQualifiers(Quals);
// Recurse: even if the qualified type isn't yet substitutable,
// the unqualified type might be.
- mangleType(T.getUnqualifiedType());
+ mangleType(T.getLocalUnqualifiedType());
} else {
switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, PARENT)
for (XML::IdMap<QualType>::iterator i = Types.begin(), e = Types.end();
i != e; ++i) {
- if (i->first.hasQualifiers()) {
+ if (i->first.hasLocalQualifiers()) {
writeTypeToXML(i->first);
addAttribute("id", getPrefixedId(i->second, ID_NORMAL));
toParent();
{
addTypeRecursively(pType.getTypePtr());
// beautifier: a non-qualified type shall be transparent
- if (!pType.hasQualifiers())
+ if (!pType.hasLocalQualifiers())
{
Types[pType] = BasicTypes[pType.getTypePtr()];
}
// Emit the type's representation.
PCHTypeWriter W(*this, Record);
- if (T.hasNonFastQualifiers()) {
- Qualifiers Qs = T.getQualifiers();
- AddTypeRef(T.getUnqualifiedType(), Record);
+ if (T.hasLocalNonFastQualifiers()) {
+ Qualifiers Qs = T.getLocalQualifiers();
+ AddTypeRef(T.getLocalUnqualifiedType(), Record);
Record.push_back(Qs.getAsOpaqueValue());
W.Code = pch::TYPE_EXT_QUAL;
} else {
return;
}
- unsigned FastQuals = T.getFastQualifiers();
+ unsigned FastQuals = T.getLocalFastQualifiers();
T.removeFastQualifiers();
- if (T.hasNonFastQualifiers()) {
+ if (T.hasLocalNonFastQualifiers()) {
pch::TypeID &ID = TypeIDs[T];
if (ID == 0) {
// We haven't seen these qualifiers applied to this type before.
return;
}
- assert(!T.hasQualifiers());
+ assert(!T.hasLocalQualifiers());
if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
pch::TypeID ID = 0;
}
// T == T, modulo cv
- if (Self.Context.getCanonicalType(
- SrcMemPtr->getPointeeType().getUnqualifiedType()) !=
- Self.Context.getCanonicalType(DestMemPtr->getPointeeType().
- getUnqualifiedType()))
+ if (!Self.Context.hasSameUnqualifiedType(SrcMemPtr->getPointeeType(),
+ DestMemPtr->getPointeeType()))
return TC_NotApplicable;
// B base of D
return ExprError();
}
- if (Context.getCanonicalType(FAType).getUnqualifiedType() !=
- Context.getCanonicalType(SAType).getUnqualifiedType()) {
+ if (!Context.hasSameUnqualifiedType(FAType, SAType)) {
Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector)
<< SourceRange(TheCall->getArg(0)->getLocStart(),
TheCall->getArg(1)->getLocEnd());
QualType DeclParamTy = Declaration->getParamDecl(Idx)->getType();
QualType DefParamTy = Definition->getParamDecl(Idx)->getType();
- DeclParamTy = Context.getCanonicalType(DeclParamTy.getNonReferenceType());
- DefParamTy = Context.getCanonicalType(DefParamTy.getNonReferenceType());
- if (DeclParamTy.getUnqualifiedType() != DefParamTy.getUnqualifiedType())
+ if (!Context.hasSameUnqualifiedType(DeclParamTy.getNonReferenceType(),
+ DefParamTy.getNonReferenceType()))
return false;
}
for (unsigned idx = 0; idx < NumBases; ++idx) {
QualType NewBaseType
= Context.getCanonicalType(Bases[idx]->getType());
- NewBaseType = NewBaseType.getUnqualifiedType();
+ NewBaseType = NewBaseType.getLocalUnqualifiedType();
if (KnownBaseTypes[NewBaseType]) {
// C++ [class.mi]p3:
const CXXBaseSpecifier *DirectBaseSpec = 0;
for (CXXRecordDecl::base_class_const_iterator Base =
ClassDecl->bases_begin(); Base != ClassDecl->bases_end(); ++Base) {
- if (Context.getCanonicalType(BaseType).getUnqualifiedType() ==
- Context.getCanonicalType(Base->getType()).getUnqualifiedType()) {
+ if (Context.hasSameUnqualifiedType(BaseType, Base->getType())) {
// We found a direct base of this type. That's what we're
// initializing.
DirectBaseSpec = &*Base;
QualType T1 = Context.getCanonicalType(OrigT1);
QualType T2 = Context.getCanonicalType(OrigT2);
- QualType UnqualT1 = T1.getUnqualifiedType();
- QualType UnqualT2 = T2.getUnqualifiedType();
+ QualType UnqualT1 = T1.getLocalUnqualifiedType();
+ QualType UnqualT2 = T2.getLocalUnqualifiedType();
// C++ [dcl.init.ref]p4:
// Given types "cv1 T1" and "cv2 T2," "cv1 T1" is
QualType COldTy = Context.getCanonicalType(OldTy);
if (CNewTy == COldTy &&
- CNewTy.getCVRQualifiers() == COldTy.getCVRQualifiers())
+ CNewTy.getLocalCVRQualifiers() == COldTy.getLocalCVRQualifiers())
return false;
// Check if the return types are covariant
return true;
}
- if (NewClassTy.getUnqualifiedType() != OldClassTy.getUnqualifiedType()) {
+ if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
// Check if the new class derives from the old class.
if (!IsDerivedFrom(NewClassTy, OldClassTy)) {
Diag(New->getLocation(),
}
// The qualifiers of the return types must be the same.
- if (CNewTy.getCVRQualifiers() != COldTy.getCVRQualifiers()) {
+ if (CNewTy.getLocalCVRQualifiers() != COldTy.getLocalCVRQualifiers()) {
Diag(New->getLocation(),
diag::err_covariant_return_type_different_qualifications)
<< New->getDeclName() << NewTy << OldTy;
SubIsPointer = true;
}
bool SubIsClass = CanonicalSubT->isRecordType();
- CanonicalSubT = CanonicalSubT.getUnqualifiedType();
+ CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
continue;
}
}
- CanonicalSuperT = CanonicalSuperT.getUnqualifiedType();
+ CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType();
// If the types are the same, move on to the next type in the subset.
if (CanonicalSubT == CanonicalSuperT) {
Contained = true;
static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
QualType SrcTy, QualType DestTy) {
- if (Context.getCanonicalType(SrcTy).getUnqualifiedType() ==
- Context.getCanonicalType(DestTy).getUnqualifiedType())
+ if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
return CastExpr::CK_NoOp;
if (SrcTy->hasPointerRepresentation()) {
}
if (!castType->isScalarType() && !castType->isVectorType()) {
- if (Context.getCanonicalType(castType).getUnqualifiedType() ==
- Context.getCanonicalType(castExpr->getType().getUnqualifiedType()) &&
+ if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) &&
(castType->isStructureType() || castType->isUnionType())) {
// GCC struct/union extension: allow cast to self.
// FIXME: Check that the cast destination type is complete.
RecordDecl::field_iterator Field, FieldEnd;
for (Field = RD->field_begin(), FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
- if (Context.getCanonicalType(Field->getType()).getUnqualifiedType() ==
- Context.getCanonicalType(castExpr->getType()).getUnqualifiedType()) {
+ if (Context.hasSameUnqualifiedType(Field->getType(),
+ castExpr->getType())) {
Diag(TyR.getBegin(), diag::ext_typecheck_cast_to_union)
<< castExpr->getSourceRange();
break;
rhptee = Context.getCanonicalType(rhptee);
} while (lhptee->isPointerType() && rhptee->isPointerType());
- if (lhptee.getUnqualifiedType() == rhptee.getUnqualifiedType())
+ if (Context.hasSameUnqualifiedType(lhptee, rhptee))
return IncompatibleNestedPointerQualifiers;
}
AssignConvertType ConvTy = Compatible;
// For blocks we enforce that qualifiers are identical.
- if (lhptee.getCVRQualifiers() != rhptee.getCVRQualifiers())
+ if (lhptee.getLocalCVRQualifiers() != rhptee.getLocalCVRQualifiers())
ConvTy = CompatiblePointerDiscardsQualifiers;
if (!Context.typesAreCompatible(lhptee, rhptee))
}
}
- if (Context.getCanonicalType(Class).getUnqualifiedType() !=
- Context.getCanonicalType(LType).getUnqualifiedType()) {
+ if (!Context.hasSameUnqualifiedType(Class, LType)) {
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false,
/*DetectVirtual=*/false);
// FIXME: Would it be useful to print full ambiguity paths, or is that
// copy-initialization where the cv-unqualified version of the
// source type is the same class as, or a derived class of, the
// class of the destination, constructors are considered.
- if ((DeclTypeC.getUnqualifiedType() == InitTypeC.getUnqualifiedType()) ||
+ if ((DeclTypeC.getLocalUnqualifiedType()
+ == InitTypeC.getLocalUnqualifiedType()) ||
IsDerivedFrom(InitTypeC, DeclTypeC)) {
const CXXRecordDecl *RD =
cast<CXXRecordDecl>(DeclType->getAs<RecordType>()->getDecl());
if (T1->isEnumeralType()) {
QualType ArgType = Proto->getArgType(0).getNonReferenceType();
- if (Context.getCanonicalType(T1).getUnqualifiedType()
- == Context.getCanonicalType(ArgType).getUnqualifiedType())
+ if (Context.hasSameUnqualifiedType(T1, ArgType))
return true;
}
if (!T2.isNull() && T2->isEnumeralType()) {
QualType ArgType = Proto->getArgType(1).getNonReferenceType();
- if (Context.getCanonicalType(T2).getUnqualifiedType()
- == Context.getCanonicalType(ArgType).getUnqualifiedType())
+ if (Context.hasSameUnqualifiedType(T2, ArgType))
return true;
}
// cv-unqualified version of T. Otherwise, the type of the rvalue
// is T (C++ 4.1p1). C++ can't get here with class types; in C, we
// just strip the qualifiers because they don't matter.
-
- // FIXME: Doesn't see through to qualifiers behind a typedef!
FromType = FromType.getUnqualifiedType();
} else if (FromType->isArrayType()) {
// Array-to-pointer conversion (C++ 4.2)
// a conversion. [...]
CanonFrom = Context.getCanonicalType(FromType);
CanonTo = Context.getCanonicalType(ToType);
- if (CanonFrom.getUnqualifiedType() == CanonTo.getUnqualifiedType() &&
- CanonFrom.getCVRQualifiers() != CanonTo.getCVRQualifiers()) {
+ if (CanonFrom.getLocalUnqualifiedType()
+ == CanonTo.getLocalUnqualifiedType() &&
+ CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()) {
FromType = ToType;
CanonFrom = CanonTo;
}
// We found the type that we can promote to. If this is the
// type we wanted, we have a promotion. Otherwise, no
// promotion.
- return Context.getCanonicalType(ToType).getUnqualifiedType()
- == Context.getCanonicalType(PromoteTypes[Idx]).getUnqualifiedType();
+ return Context.hasSameUnqualifiedType(ToType, PromoteTypes[Idx]);
}
}
}
Qualifiers Quals = CanonFromPointee.getQualifiers();
// Exact qualifier match -> return the pointer type we're converting to.
- if (CanonToPointee.getQualifiers() == Quals) {
+ if (CanonToPointee.getLocalQualifiers() == Quals) {
// ToType is exactly what we need. Return it.
if (!ToType.isNull())
return ToType;
// Just build a canonical type that has the right qualifiers.
return Context.getPointerType(
- Context.getQualifiedType(CanonToPointee.getUnqualifiedType(), Quals));
+ Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(),
+ Quals));
}
static bool isNullPointerConstantForConversion(Expr *Expr,
// of types. If we unwrapped any pointers, and if FromType and
// ToType have the same unqualified type (since we checked
// qualifiers above), then this is a qualification conversion.
- return UnwrappedAnyPointer &&
- FromType.getUnqualifiedType() == ToType.getUnqualifiedType();
+ return UnwrappedAnyPointer && Context.hasSameUnqualifiedType(FromType,ToType);
}
/// \brief Given a function template or function, extract the function template
QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr);
T1 = Context.getCanonicalType(T1);
T2 = Context.getCanonicalType(T2);
- if (T1.getUnqualifiedType() == T2.getUnqualifiedType()) {
+ if (Context.hasSameUnqualifiedType(T1, T2)) {
if (T2.isMoreQualifiedThan(T1))
return ImplicitConversionSequence::Better;
else if (T1.isMoreQualifiedThan(T2))
// If the types are the same, we won't learn anything by unwrapped
// them.
- if (T1.getUnqualifiedType() == T2.getUnqualifiedType())
+ if (Context.hasSameUnqualifiedType(T1, T2))
return ImplicitConversionSequence::Indistinguishable;
ImplicitConversionSequence::CompareKind Result
}
// If the types after this point are equivalent, we're done.
- if (T1.getUnqualifiedType() == T2.getUnqualifiedType())
+ if (Context.hasSameUnqualifiedType(T1, T2))
break;
}
// -- binding of an expression of type C to a reference of type
// B& is better than binding an expression of type C to a
// reference of type A&,
- if (FromType1.getUnqualifiedType() == FromType2.getUnqualifiedType() &&
- ToType1.getUnqualifiedType() != ToType2.getUnqualifiedType()) {
+ if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+ !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
if (IsDerivedFrom(ToType1, ToType2))
return ImplicitConversionSequence::Better;
else if (IsDerivedFrom(ToType2, ToType1))
// -- binding of an expression of type B to a reference of type
// A& is better than binding an expression of type C to a
// reference of type A&,
- if (FromType1.getUnqualifiedType() != FromType2.getUnqualifiedType() &&
- ToType1.getUnqualifiedType() == ToType2.getUnqualifiedType()) {
+ if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+ Context.hasSameUnqualifiedType(ToType1, ToType2)) {
if (IsDerivedFrom(FromType2, FromType1))
return ImplicitConversionSequence::Better;
else if (IsDerivedFrom(FromType1, FromType2))
if (SCS1.CopyConstructor && SCS2.CopyConstructor &&
SCS1.Second == ICK_Derived_To_Base) {
// -- conversion of C to B is better than conversion of C to A,
- if (FromType1.getUnqualifiedType() == FromType2.getUnqualifiedType() &&
- ToType1.getUnqualifiedType() != ToType2.getUnqualifiedType()) {
+ if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+ !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
if (IsDerivedFrom(ToType1, ToType2))
return ImplicitConversionSequence::Better;
else if (IsDerivedFrom(ToType2, ToType1))
}
// -- conversion of B to A is better than conversion of C to A.
- if (FromType1.getUnqualifiedType() != FromType2.getUnqualifiedType() &&
- ToType1.getUnqualifiedType() == ToType2.getUnqualifiedType()) {
+ if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+ Context.hasSameUnqualifiedType(ToType1, ToType2)) {
if (IsDerivedFrom(FromType2, FromType1))
return ImplicitConversionSequence::Better;
else if (IsDerivedFrom(FromType1, FromType2))
// First check the qualifiers. We don't care about lvalue-vs-rvalue
// with the implicit object parameter (C++ [over.match.funcs]p5).
QualType FromTypeCanon = Context.getCanonicalType(FromType);
- if (ImplicitParamType.getCVRQualifiers() != FromTypeCanon.getCVRQualifiers() &&
+ if (ImplicitParamType.getCVRQualifiers()
+ != FromTypeCanon.getLocalCVRQualifiers() &&
!ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon))
return ICS;
// Check that we have either the same type or a derived type. It
// affects the conversion rank.
QualType ClassTypeCanon = Context.getCanonicalType(ClassType);
- if (ClassTypeCanon == FromTypeCanon.getUnqualifiedType())
+ if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType())
ICS.Standard.Second = ICK_Identity;
else if (IsDerivedFrom(FromType, ClassType))
ICS.Standard.Second = ICK_Derived_To_Base;
Ty = RefTy->getPointeeType();
// We don't care about qualifiers on the type.
- Ty = Ty.getUnqualifiedType();
+ Ty = Ty.getLocalUnqualifiedType();
// If we're dealing with an array type, decay to the pointer.
if (Ty->isArrayType())
if (!RetType->isRecordType())
return false;
// ... the same cv-unqualified type as the function return type ...
- if (Ctx.getCanonicalType(RetType).getUnqualifiedType() !=
- Ctx.getCanonicalType(ExprType).getUnqualifiedType())
+ if (!Ctx.hasSameUnqualifiedType(RetType, ExprType))
return false;
// ... the expression is the name of a non-volatile automatic object ...
// We ignore parentheses here.
Qualifiers &Quals) {
assert(T.isCanonical() && "Only operates on canonical types");
if (!isa<ArrayType>(T)) {
- Quals = T.getQualifiers();
- return T.getUnqualifiedType();
+ Quals = T.getLocalQualifiers();
+ return T.getLocalUnqualifiedType();
}
assert(!T.hasQualifiers() && "canonical array type has qualifiers!");
// - If A is a cv-qualified type, the top level cv-qualifiers of A’s
// type are ignored for type deduction.
QualType CanonArgType = Context.getCanonicalType(ArgType);
- if (CanonArgType.getCVRQualifiers())
- ArgType = CanonArgType.getUnqualifiedType();
+ if (CanonArgType.getLocalCVRQualifiers())
+ ArgType = CanonArgType.getLocalUnqualifiedType();
}
}
// C++0x [temp.deduct.call]p3:
// If P is a cv-qualified type, the top level cv-qualifiers of P’s type
// are ignored for type deduction.
- if (CanonParamType.getCVRQualifiers())
- ParamType = CanonParamType.getUnqualifiedType();
+ if (CanonParamType.getLocalCVRQualifiers())
+ ParamType = CanonParamType.getLocalUnqualifiedType();
if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
// [...] If P is a reference type, the type referred to by P is used
// for type deduction.
QualType
TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
QualifiedTypeLoc T) {
- Qualifiers Quals = T.getType().getQualifiers();
+ Qualifiers Quals = T.getType().getLocalQualifiers();
QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
if (Result.isNull())
QualType T) {
if (T->isDependentType() || T->isRecordType() ||
(SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
- assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
+ assert(!T.hasLocalQualifiers() && "Can't get cv-qualifiers here");
return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
T.getTypePtr());
}