return Value.getPointer().get<const Type*>();
}
+ QualType getUnqualifiedTypeSlow() const;
+
friend class QualifierCollector;
public:
QualType() {}
}
/// \brief Determine whether this type is const-qualified.
- bool isConstQualified() const {
- // FIXME: Look through sugar types.
- return isLocalConstQualified();
- }
+ bool isConstQualified() const;
/// \brief Determine whether this particular QualType instance has the
/// "restrict" qualifier set, without looking through typedefs that may have
}
/// \brief Determine whether this type is restrict-qualified.
- bool isRestrictQualified() const {
- // FIXME: Look through sugar types.
- return isLocalRestrictQualified();
- }
+ bool isRestrictQualified() const;
/// \brief Determine whether this particular QualType instance has the
/// "volatile" qualifier set, without looking through typedefs that may have
}
/// \brief Determine whether this type is volatile-qualified.
- bool isVolatileQualified() const {
- // FIXME: Look through sugar types.
- return isLocalVolatileQualified();
- }
+ bool isVolatileQualified() const;
/// \brief Determine whether this particular QualType instance has any
/// qualifiers, without looking through any typedefs that might add
}
/// \brief Determine whether this type has any qualifiers.
- bool hasQualifiers() const {
- // FIXME: Look for qualifiers at any level.
- return hasLocalQualifiers();
- }
+ bool hasQualifiers() const;
/// \brief Determine whether this particular QualType instance has any
/// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
}
/// \brief Retrieve the set of qualifiers applied to this type.
- Qualifiers getQualifiers() const {
- // FIXME: Collect qualifiers from all levels.
- return getLocalQualifiers();
- }
+ Qualifiers getQualifiers() const;
/// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
/// local to this particular QualType instance, not including any qualifiers
/// \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();
- }
+ unsigned getCVRQualifiers() const;
bool isConstant(ASTContext& Ctx) const {
return QualType::isConstant(*this, Ctx);
/// \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();
+ QualType getUnqualifiedType() const {
+ QualType T = getLocalUnqualifiedType();
+ if (!T.hasQualifiers())
+ return T;
+
+ return getUnqualifiedTypeSlow();
}
bool isMoreQualifiedThan(QualType Other) const;
!isa<FunctionType>(T) && !isa<ArrayType>(T);
}
+inline bool QualType::isConstQualified() const {
+ return isLocalConstQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalConstQualified();
+}
+
+inline bool QualType::isRestrictQualified() const {
+ return isLocalRestrictQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalRestrictQualified();
+}
+
+
+inline bool QualType::isVolatileQualified() const {
+ return isLocalVolatileQualified() ||
+ getTypePtr()->getCanonicalTypeInternal().isLocalVolatileQualified();
+}
+
+inline bool QualType::hasQualifiers() const {
+ return hasLocalQualifiers() ||
+ getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers();
+}
+
+inline Qualifiers QualType::getQualifiers() const {
+ Qualifiers Quals = getLocalQualifiers();
+ Quals.addQualifiers(
+ getTypePtr()->getCanonicalTypeInternal().getLocalQualifiers());
+ return Quals;
+}
+
+inline unsigned QualType::getCVRQualifiers() const {
+ return getLocalCVRQualifiers() |
+ getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers();
+}
+
inline void QualType::removeConst() {
removeFastQualifiers(Qualifiers::Const);
}
->getElementType().getTypePtr();
}
+/// \brief Retrieve the unqualified variant of the given type, removing as
+/// little sugar as possible.
+///
+/// This routine looks through various kinds of sugar to find the
+/// least-desuraged type that is unqualified. For example, given:
+///
+/// \code
+/// typedef int Integer;
+/// typedef const Integer CInteger;
+/// typedef CInteger DifferenceType;
+/// \endcode
+///
+/// Executing \c getUnqualifiedTypeSlow() on the type \c DifferenceType will
+/// desugar until we hit the type \c Integer, which has no qualifiers on it.
+QualType QualType::getUnqualifiedTypeSlow() const {
+ QualType Cur = *this;
+ while (true) {
+ if (!Cur.hasQualifiers())
+ return Cur;
+
+ const Type *CurTy = Cur.getTypePtr();
+ switch (CurTy->getTypeClass()) {
+#define ABSTRACT_TYPE(Class, Parent)
+#define TYPE(Class, Parent) \
+ case Type::Class: { \
+ const Class##Type *Ty = cast<Class##Type>(CurTy); \
+ if (!Ty->isSugared()) \
+ return Cur.getLocalUnqualifiedType(); \
+ Cur = Ty->desugar(); \
+ break; \
+ }
+#include "clang/AST/TypeNodes.def"
+ }
+ }
+
+ return Cur.getUnqualifiedType();
+}
+
/// getDesugaredType - Return the specified type with any "sugar" removed from
/// the type. This takes off typedefs, typeof's etc. If the outer level of
/// the type is already concrete, it returns it unmodified. This is similar