[cfe-commits] r150028 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/ASTContext.cpp lib/AST/ItaniumMangle.cpp lib/AST/Type.cpp lib/AST/TypePrinter.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaType.cpp
John McCall
rjmccall at apple.com
Tue Feb 7 16:46:36 PST 2012
Author: rjmccall
Date: Tue Feb 7 18:46:36 2012
New Revision: 150028
URL: http://llvm.org/viewvc/llvm-project?rev=150028&view=rev
Log:
Revise the SplitQualType interface to make it its own thing instead of
a typedef of std::pair. This slightly improves type-safety, but mostly
makes code using it clearer to read as well as making it possible to add
methods to the type.
Add such a method for efficiently single-step desugaring a split type.
Add a method to single-step desugaring a locally-unqualified type.
Implement both the SplitQualType and QualType methods in terms of that.
Also, fix a typo ("ObjCGLifetime").
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/ItaniumMangle.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypePrinter.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Feb 7 18:46:36 2012
@@ -1134,6 +1134,11 @@
return getQualifiedType(T, Qualifiers::fromCVRMask(CVR));
}
+ /// getQualifiedType - Un-split a SplitQualType.
+ QualType getQualifiedType(SplitQualType split) const {
+ return getQualifiedType(split.Ty, split.Quals);
+ }
+
/// getQualifiedType - Returns a type with additional qualifiers.
QualType getQualifiedType(QualType T, Qualifiers Qs) const {
if (!Qs.hasNonFastQualifiers())
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Tue Feb 7 18:46:36 2012
@@ -236,7 +236,7 @@
qs.removeObjCGCAttr();
return qs;
}
- Qualifiers withoutObjCGLifetime() const {
+ Qualifiers withoutObjCLifetime() const {
Qualifiers qs = *this;
qs.removeObjCLifetime();
return qs;
@@ -252,7 +252,8 @@
void removeObjCLifetime() { setObjCLifetime(OCL_None); }
void addObjCLifetime(ObjCLifetime type) {
assert(type);
- setObjCLifetime(type);
+ assert(!hasObjCLifetime());
+ Mask |= (type << LifetimeShift);
}
/// True if the lifetime is neither None or ExplicitNone.
@@ -447,7 +448,32 @@
CC_AAPCS_VFP // __attribute__((pcs("aapcs-vfp")))
};
-typedef std::pair<const Type*, Qualifiers> SplitQualType;
+/// A std::pair-like structure for storing a qualified type split
+/// into its local qualifiers and its locally-unqualified type.
+struct SplitQualType {
+ /// The locally-unqualified type.
+ const Type *Ty;
+
+ /// The local qualifiers.
+ Qualifiers Quals;
+
+ SplitQualType() : Ty(0), Quals() {}
+ SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
+
+ SplitQualType getSingleStepDesugaredType() const; // end of this file
+
+ // Make llvm::tie work.
+ operator std::pair<const Type *,Qualifiers>() const {
+ return std::pair<const Type *,Qualifiers>(Ty, Quals);
+ }
+
+ friend bool operator==(SplitQualType a, SplitQualType b) {
+ return a.Ty == b.Ty && a.Quals == b.Quals;
+ }
+ friend bool operator!=(SplitQualType a, SplitQualType b) {
+ return a.Ty != b.Ty || a.Quals != b.Quals;
+ }
+};
/// QualType - For efficiency, we don't store CV-qualified types as nodes on
/// their own: instead each reference to a type stores the qualifiers. This
@@ -769,7 +795,9 @@
///
/// This routine takes off the first typedef, typeof, etc. If the outer level
/// of the type is already concrete, it returns it unmodified.
- QualType getSingleStepDesugaredType(const ASTContext &Context) const;
+ QualType getSingleStepDesugaredType(const ASTContext &Context) const {
+ return getSingleStepDesugaredTypeImpl(*this, Context);
+ }
/// IgnoreParens - Returns the specified type after dropping any
/// outer-level parentheses.
@@ -791,7 +819,7 @@
return getAsString(split());
}
static std::string getAsString(SplitQualType split) {
- return getAsString(split.first, split.second);
+ return getAsString(split.Ty, split.Quals);
}
static std::string getAsString(const Type *ty, Qualifiers qs);
@@ -806,7 +834,7 @@
}
static void getAsStringInternal(SplitQualType split, std::string &out,
const PrintingPolicy &policy) {
- return getAsStringInternal(split.first, split.second, out, policy);
+ return getAsStringInternal(split.Ty, split.Quals, out, policy);
}
static void getAsStringInternal(const Type *ty, Qualifiers qs,
std::string &out,
@@ -887,6 +915,8 @@
static QualType getDesugaredType(QualType T, const ASTContext &Context);
static SplitQualType getSplitDesugaredType(QualType T);
static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
+ static QualType getSingleStepDesugaredTypeImpl(QualType type,
+ const ASTContext &C);
static QualType IgnoreParens(QualType T);
static DestructionKind isDestructedTypeImpl(QualType type);
};
@@ -1333,6 +1363,11 @@
return CanonicalType == QualType(this, 0);
}
+ /// Pull a single level of sugar off of this locally-unqualified type.
+ /// Users should generally prefer SplitQualType::getSingleStepDesugaredType()
+ /// or QualType::getSingleStepDesugaredType(const ASTContext&).
+ QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
+
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@@ -4406,6 +4441,13 @@
// Inline function definitions.
+inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
+ SplitQualType desugar =
+ Ty->getLocallyUnqualifiedSingleStepDesugaredType().split();
+ desugar.Quals.addConsistentQualifiers(Quals);
+ return desugar;
+}
+
inline const Type *QualType::getTypePtr() const {
return getCommonPtr()->BaseType;
}
@@ -4490,7 +4532,7 @@
if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
return QualType(getTypePtr(), 0);
- return QualType(getSplitUnqualifiedTypeImpl(*this).first, 0);
+ return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
}
inline SplitQualType QualType::getSplitUnqualifiedType() const {
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Feb 7 18:46:36 2012
@@ -1526,7 +1526,7 @@
def err_attr_objc_ownership_bad_type : Error<
"the type %0 cannot be retained">;
def err_attr_objc_ownership_redundant : Error<
- "the type %0 already has retainment attributes set on it">;
+ "the type %0 is already explicitly ownership-qualified">;
def err_attribute_not_string : Error<
"argument to %0 attribute was not a string literal">;
def err_only_annotate_after_access_spec : Error<
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Feb 7 18:46:36 2012
@@ -1387,8 +1387,8 @@
QualType canon;
if (!baseType->isCanonicalUnqualified()) {
SplitQualType canonSplit = baseType->getCanonicalTypeInternal().split();
- canonSplit.second.addConsistentQualifiers(quals);
- canon = getExtQualType(canonSplit.first, canonSplit.second);
+ canonSplit.Quals.addConsistentQualifiers(quals);
+ canon = getExtQualType(canonSplit.Ty, canonSplit.Quals);
// Re-find the insert position.
(void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos);
@@ -1690,9 +1690,9 @@
QualType Canon;
if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) {
SplitQualType canonSplit = getCanonicalType(EltTy).split();
- Canon = getConstantArrayType(QualType(canonSplit.first, 0), ArySize,
+ Canon = getConstantArrayType(QualType(canonSplit.Ty, 0), ArySize,
ASM, IndexTypeQuals);
- Canon = getQualifiedType(Canon, canonSplit.second);
+ Canon = getQualifiedType(Canon, canonSplit.Quals);
// Get the new insert position for the node we care about.
ConstantArrayType *NewIP =
@@ -1717,7 +1717,7 @@
QualType result;
SplitQualType split = type.getSplitDesugaredType();
- const Type *ty = split.first;
+ const Type *ty = split.Ty;
switch (ty->getTypeClass()) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
@@ -1836,7 +1836,7 @@
}
// Apply the top-level qualifiers from the original.
- return getQualifiedType(result, split.second);
+ return getQualifiedType(result, split.Quals);
}
/// getVariableArrayType - Returns a non-unique reference to the type for a
@@ -1853,9 +1853,9 @@
// Be sure to pull qualifiers off the element type.
if (!EltTy.isCanonical() || EltTy.hasLocalQualifiers()) {
SplitQualType canonSplit = getCanonicalType(EltTy).split();
- Canon = getVariableArrayType(QualType(canonSplit.first, 0), NumElts, ASM,
+ Canon = getVariableArrayType(QualType(canonSplit.Ty, 0), NumElts, ASM,
IndexTypeQuals, Brackets);
- Canon = getQualifiedType(Canon, canonSplit.second);
+ Canon = getQualifiedType(Canon, canonSplit.Quals);
}
VariableArrayType *New = new(*this, TypeAlignment)
@@ -1900,7 +1900,7 @@
void *insertPos = 0;
llvm::FoldingSetNodeID ID;
DependentSizedArrayType::Profile(ID, *this,
- QualType(canonElementType.first, 0),
+ QualType(canonElementType.Ty, 0),
ASM, elementTypeQuals, numElements);
// Look for an existing type with these properties.
@@ -1910,7 +1910,7 @@
// If we don't have one, build one.
if (!canonTy) {
canonTy = new (*this, TypeAlignment)
- DependentSizedArrayType(*this, QualType(canonElementType.first, 0),
+ DependentSizedArrayType(*this, QualType(canonElementType.Ty, 0),
QualType(), numElements, ASM, elementTypeQuals,
brackets);
DependentSizedArrayTypes.InsertNode(canonTy, insertPos);
@@ -1919,11 +1919,11 @@
// Apply qualifiers from the element type to the array.
QualType canon = getQualifiedType(QualType(canonTy,0),
- canonElementType.second);
+ canonElementType.Quals);
// If we didn't need extra canonicalization for the element type,
// then just use that as our result.
- if (QualType(canonElementType.first, 0) == elementType)
+ if (QualType(canonElementType.Ty, 0) == elementType)
return canon;
// Otherwise, we need to build a type which follows the spelling
@@ -1954,9 +1954,9 @@
if (!elementType.isCanonical() || elementType.hasLocalQualifiers()) {
SplitQualType canonSplit = getCanonicalType(elementType).split();
- canon = getIncompleteArrayType(QualType(canonSplit.first, 0),
+ canon = getIncompleteArrayType(QualType(canonSplit.Ty, 0),
ASM, elementTypeQuals);
- canon = getQualifiedType(canon, canonSplit.second);
+ canon = getQualifiedType(canon, canonSplit.Quals);
// Get the new insert position for the node we care about.
IncompleteArrayType *existing =
@@ -3134,12 +3134,12 @@
// We then have to strip that sugar back off with
// getUnqualifiedDesugaredType(), which is silly.
const ArrayType *AT =
- dyn_cast<ArrayType>(splitType.first->getUnqualifiedDesugaredType());
+ dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType());
// If we don't have an array, just use the results in splitType.
if (!AT) {
- quals = splitType.second;
- return QualType(splitType.first, 0);
+ quals = splitType.Quals;
+ return QualType(splitType.Ty, 0);
}
// Otherwise, recurse on the array's element type.
@@ -3150,13 +3150,13 @@
// can just use the results in splitType.
if (elementType == unqualElementType) {
assert(quals.empty()); // from the recursive call
- quals = splitType.second;
- return QualType(splitType.first, 0);
+ quals = splitType.Quals;
+ return QualType(splitType.Ty, 0);
}
// Otherwise, add in the qualifiers from the outermost type, then
// build the type back up.
- quals.addConsistentQualifiers(splitType.second);
+ quals.addConsistentQualifiers(splitType.Quals);
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
return getConstantArrayType(unqualElementType, CAT->getSize(),
@@ -3458,10 +3458,10 @@
// we must propagate them down into the element type.
SplitQualType split = T.getSplitDesugaredType();
- Qualifiers qs = split.second;
+ Qualifiers qs = split.Quals;
// If we have a simple case, just return now.
- const ArrayType *ATy = dyn_cast<ArrayType>(split.first);
+ const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty);
if (ATy == 0 || qs.empty())
return ATy;
@@ -3548,11 +3548,11 @@
Qualifiers qs;
while (true) {
SplitQualType split = type.getSplitDesugaredType();
- const ArrayType *array = split.first->getAsArrayTypeUnsafe();
+ const ArrayType *array = split.Ty->getAsArrayTypeUnsafe();
if (!array) break;
type = array->getElementType();
- qs.addConsistentQualifiers(split.second);
+ qs.addConsistentQualifiers(split.Quals);
}
return getQualifiedType(type, qs);
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Tue Feb 7 18:46:36 2012
@@ -1655,8 +1655,8 @@
} while (true);
}
SplitQualType split = T.split();
- Qualifiers quals = split.second;
- const Type *ty = split.first;
+ Qualifiers quals = split.Quals;
+ const Type *ty = split.Ty;
bool isSubstitutable = quals || !isa<BuiltinType>(T);
if (isSubstitutable && mangleSubstitution(T))
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Tue Feb 7 18:46:36 2012
@@ -197,27 +197,28 @@
/// concrete.
QualType QualType::getDesugaredType(QualType T, const ASTContext &Context) {
SplitQualType split = getSplitDesugaredType(T);
- return Context.getQualifiedType(split.first, split.second);
+ return Context.getQualifiedType(split.Ty, split.Quals);
}
-QualType QualType::getSingleStepDesugaredType(const ASTContext &Context) const {
- QualifierCollector Qs;
-
- const Type *CurTy = Qs.strip(*this);
- switch (CurTy->getTypeClass()) {
+QualType QualType::getSingleStepDesugaredTypeImpl(QualType type,
+ const ASTContext &Context) {
+ SplitQualType split = type.split();
+ QualType desugar = split.Ty->getLocallyUnqualifiedSingleStepDesugaredType();
+ return Context.getQualifiedType(desugar, split.Quals);
+}
+
+QualType Type::getLocallyUnqualifiedSingleStepDesugaredType() const {
+ switch (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 *this; \
- return Context.getQualifiedType(Ty->desugar(), Qs); \
- break; \
+ const Class##Type *ty = cast<Class##Type>(this); \
+ if (!ty->isSugared()) return QualType(ty, 0); \
+ return ty->desugar(); \
}
#include "clang/AST/TypeNodes.def"
}
-
- return *this;
+ llvm_unreachable("bad type kind!");
}
SplitQualType QualType::getSplitDesugaredType(QualType T) {
@@ -245,21 +246,21 @@
SplitQualType split = type.split();
// All the qualifiers we've seen so far.
- Qualifiers quals = split.second;
+ Qualifiers quals = split.Quals;
// The last type node we saw with any nodes inside it.
- const Type *lastTypeWithQuals = split.first;
+ const Type *lastTypeWithQuals = split.Ty;
while (true) {
QualType next;
// Do a single-step desugar, aborting the loop if the type isn't
// sugared.
- switch (split.first->getTypeClass()) {
+ switch (split.Ty->getTypeClass()) {
#define ABSTRACT_TYPE(Class, Parent)
#define TYPE(Class, Parent) \
case Type::Class: { \
- const Class##Type *ty = cast<Class##Type>(split.first); \
+ const Class##Type *ty = cast<Class##Type>(split.Ty); \
if (!ty->isSugared()) goto done; \
next = ty->desugar(); \
break; \
@@ -270,9 +271,9 @@
// Otherwise, split the underlying type. If that yields qualifiers,
// update the information.
split = next.split();
- if (!split.second.empty()) {
- lastTypeWithQuals = split.first;
- quals.addConsistentQualifiers(split.second);
+ if (!split.Quals.empty()) {
+ lastTypeWithQuals = split.Ty;
+ quals.addConsistentQualifiers(split.Quals);
}
}
Modified: cfe/trunk/lib/AST/TypePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)
+++ cfe/trunk/lib/AST/TypePrinter.cpp Tue Feb 7 18:46:36 2012
@@ -75,7 +75,7 @@
void TypePrinter::print(QualType t, std::string &buffer) {
SplitQualType split = t.split();
- print(split.first, split.second, buffer);
+ print(split.Ty, split.Quals, buffer);
}
void TypePrinter::print(const Type *T, Qualifiers Quals, std::string &buffer) {
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Feb 7 18:46:36 2012
@@ -4982,9 +4982,9 @@
// It's okay to add or remove GC or lifetime qualifiers when converting to
// and from void*.
- else if (lhq.withoutObjCGCAttr().withoutObjCGLifetime()
+ else if (lhq.withoutObjCGCAttr().withoutObjCLifetime()
.compatiblyIncludes(
- rhq.withoutObjCGCAttr().withoutObjCGLifetime())
+ rhq.withoutObjCGCAttr().withoutObjCLifetime())
&& (lhptee->isVoidType() || rhptee->isVoidType()))
; // keep old
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Feb 7 18:46:36 2012
@@ -2211,7 +2211,7 @@
Qualifiers ToQuals = ToPointee.getQualifiers();
if (!ToPointee->isObjCLifetimeType() ||
ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing ||
- !ToQuals.withoutObjCGLifetime().empty())
+ !ToQuals.withoutObjCLifetime().empty())
return false;
// Argument must be a pointer to __strong to __weak.
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=150028&r1=150027&r2=150028&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Feb 7 18:46:36 2012
@@ -3497,9 +3497,9 @@
SplitQualType SplitOld = Old.split();
// As a special case, tail-recurse if there are no qualifiers.
- if (SplitOld.second.empty())
- return wrap(C, SplitOld.first, I);
- return C.getQualifiedType(wrap(C, SplitOld.first, I), SplitOld.second);
+ if (SplitOld.Quals.empty())
+ return wrap(C, SplitOld.Ty, I);
+ return C.getQualifiedType(wrap(C, SplitOld.Ty, I), SplitOld.Quals);
}
QualType wrap(ASTContext &C, const Type *Old, unsigned I) {
More information about the cfe-commits
mailing list