aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-16 21:35:15 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-16 21:35:15 +0000
commita4923eb7c4b04d360cb2747641a5e92818edf804 (patch)
tree573c9d43fd0b6daf0f1d5ee02ebbffd7e3e84cfd /lib
parentad35a83102683b00a7e28707eee7f2d8c994b742 (diff)
First part of changes to eliminate problems with cv-qualifiers and
sugared types. The basic problem is that our qualifier accessors (getQualifiers, getCVRQualifiers, isConstQualified, etc.) only look at the current QualType and not at any qualifiers that come from sugared types, meaning that we won't see these qualifiers through, e.g., typedefs: typedef const int CInt; typedef CInt Self; Self.isConstQualified() currently returns false! Various bugs (e.g., PR5383) have cropped up all over the front end due to such problems. I'm addressing this problem by splitting each qualifier accessor into two versions: - the "local" version only returns qualifiers on this particular QualType instance - the "normal" version that will eventually combine qualifiers from this QualType instance with the qualifiers on the canonical type to produce the full set of qualifiers. This commit adds the local versions and switches a few callers from the "normal" version (e.g., isConstQualified) over to the "local" version (e.g., isLocalConstQualified) when that is the right thing to do, e.g., because we're printing or serializing the qualifiers. Also, switch a bunch of Context.getCanonicalType(T1).getUnqualifiedType() == Context.getCanonicalType(T2).getQualifiedType() expressions over to Context.hasSameUnqualifiedType(T1, T2) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88969 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp8
-rw-r--r--lib/AST/CXXInheritance.cpp4
-rw-r--r--lib/AST/DeclCXX.cpp4
-rw-r--r--lib/AST/TypePrinter.cpp5
-rw-r--r--lib/Analysis/CFRefCount.cpp2
-rw-r--r--lib/Analysis/SValuator.cpp3
-rw-r--r--lib/Analysis/Store.cpp6
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp2
-rw-r--r--lib/CodeGen/Mangle.cpp6
-rw-r--r--lib/Frontend/DocumentXML.cpp4
-rw-r--r--lib/Frontend/PCHWriter.cpp12
-rw-r--r--lib/Sema/SemaCXXCast.cpp6
-rw-r--r--lib/Sema/SemaChecking.cpp3
-rw-r--r--lib/Sema/SemaDecl.cpp5
-rw-r--r--lib/Sema/SemaDeclCXX.cpp15
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp4
-rw-r--r--lib/Sema/SemaExpr.cpp14
-rw-r--r--lib/Sema/SemaExprCXX.cpp3
-rw-r--r--lib/Sema/SemaInit.cpp3
-rw-r--r--lib/Sema/SemaLookup.cpp6
-rw-r--r--lib/Sema/SemaOverload.cpp47
-rw-r--r--lib/Sema/SemaStmt.cpp3
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp12
-rw-r--r--lib/Sema/TreeTransform.h4
24 files changed, 84 insertions, 97 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 9850ad6f53..1b3e09291d 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1186,7 +1186,7 @@ QualType ASTContext::getNoReturnType(QualType T) {
}
}
- return getQualifiedType(ResultType, T.getQualifiers());
+ return getQualifiedType(ResultType, T.getLocalQualifiers());
}
/// getComplexType - Return the uniqued reference to the type for a complex
@@ -2435,7 +2435,7 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) {
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;
@@ -4204,8 +4204,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
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.
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index d4f6e87173..023bca4363 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -99,8 +99,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
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,
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 9867e5a880..bfa338b365 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -211,7 +211,7 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context,
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
@@ -276,7 +276,7 @@ void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
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.
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 234d38a59f..a482333782 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -63,7 +63,7 @@ void TypePrinter::Print(QualType T, std::string &S) {
return;
// Print qualifiers as appropriate.
- Qualifiers Quals = T.getQualifiers();
+ Qualifiers Quals = T.getLocalQualifiers();
if (!Quals.empty()) {
std::string TQS;
Quals.getAsStringInternal(TQS, Policy);
@@ -550,7 +550,8 @@ void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T,
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.
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index a0846b1abf..55e5f174cb 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1537,7 +1537,7 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD,
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);
}
}
diff --git a/lib/Analysis/SValuator.cpp b/lib/Analysis/SValuator.cpp
index 573cac315b..ac727b0ac6 100644
--- a/lib/Analysis/SValuator.cpp
+++ b/lib/Analysis/SValuator.cpp
@@ -62,8 +62,7 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
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.
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index afe2b4e7bd..2fd72ac0a1 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -64,7 +64,7 @@ const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy)
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.
@@ -199,9 +199,7 @@ SVal StoreManager::CastRetrievedVal(SVal V, const TypedRegion *R,
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;
}
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 41ffddd23a..0551667210 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -851,7 +851,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
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.
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index 91e89fb711..0a7124de36 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -744,15 +744,15 @@ void CXXNameMangler::mangleType(QualType T) {
// 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)
diff --git a/lib/Frontend/DocumentXML.cpp b/lib/Frontend/DocumentXML.cpp
index d92d4cb7b8..0263c30bfd 100644
--- a/lib/Frontend/DocumentXML.cpp
+++ b/lib/Frontend/DocumentXML.cpp
@@ -135,7 +135,7 @@ void DocumentXML::finalize() {
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();
@@ -205,7 +205,7 @@ void DocumentXML::addTypeRecursively(const QualType& pType)
{
addTypeRecursively(pType.getTypePtr());
// beautifier: a non-qualified type shall be transparent
- if (!pType.hasQualifiers())
+ if (!pType.hasLocalQualifiers())
{
Types[pType] = BasicTypes[pType.getTypePtr()];
}
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 2dcb8b0cee..8a45ebce1b 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1248,9 +1248,9 @@ void PCHWriter::WriteType(QualType T) {
// 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 {
@@ -2154,10 +2154,10 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
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.
@@ -2172,7 +2172,7 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
return;
}
- assert(!T.hasQualifiers());
+ assert(!T.hasLocalQualifiers());
if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr())) {
pch::TypeID ID = 0;
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index 3d68e6a109..e5ad338502 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -737,10 +737,8 @@ TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType,
}
// 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
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 38b6ebeefa..92f1ba5d6a 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -628,8 +628,7 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
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());
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c6bbb9a438..502a0f1ab2 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1698,9 +1698,8 @@ static bool isNearlyMatchingFunction(ASTContext &Context,
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;
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b0e18d865c..56381e76f8 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -587,7 +587,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
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:
@@ -1140,8 +1140,7 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
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;
@@ -3649,8 +3648,8 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
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
@@ -4756,7 +4755,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
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
@@ -4785,7 +4784,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
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(),
@@ -4807,7 +4806,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
}
// 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;
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index bdd00b8404..25af0528d8 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -183,7 +183,7 @@ bool Sema::CheckExceptionSpecSubset(
SubIsPointer = true;
}
bool SubIsClass = CanonicalSubT->isRecordType();
- CanonicalSubT = CanonicalSubT.getUnqualifiedType();
+ CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
@@ -205,7 +205,7 @@ bool Sema::CheckExceptionSpecSubset(
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;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 0d4ce60913..b089ffe92f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3070,8 +3070,7 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
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()) {
@@ -3122,8 +3121,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
}
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.
@@ -3139,8 +3137,8 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
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;
@@ -3761,7 +3759,7 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
rhptee = Context.getCanonicalType(rhptee);
} while (lhptee->isPointerType() && rhptee->isPointerType());
- if (lhptee.getUnqualifiedType() == rhptee.getUnqualifiedType())
+ if (Context.hasSameUnqualifiedType(lhptee, rhptee))
return IncompatibleNestedPointerQualifiers;
}
@@ -3791,7 +3789,7 @@ Sema::CheckBlockPointerTypesForAssignment(QualType lhsType,
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))
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index bdd47cc2bb..3fcacfc9f3 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1431,8 +1431,7 @@ QualType Sema::CheckPointerToMemberOperands(
}
}
- 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
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 4746a2597e..0f973d6d9b 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -174,7 +174,8 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
// 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());
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 4f261383ad..d45a1a8b92 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1576,8 +1576,7 @@ IsAcceptableNonMemberOperatorCandidate(FunctionDecl *Fn,
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;
}
@@ -1586,8 +1585,7 @@ IsAcceptableNonMemberOperatorCandidate(FunctionDecl *Fn,
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;
}
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 56a878b694..0ec0189ebf 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -519,8 +519,6 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// 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)
@@ -678,8 +676,9 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// 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;
}
@@ -756,8 +755,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
// 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]);
}
}
}
@@ -864,7 +862,7 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
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;
@@ -876,7 +874,8 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
// 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,
@@ -1348,8 +1347,7 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) {
// 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
@@ -1742,7 +1740,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
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))
@@ -1778,7 +1776,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
// 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
@@ -1818,7 +1816,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
}
// If the types after this point are equivalent, we're done.
- if (T1.getUnqualifiedType() == T2.getUnqualifiedType())
+ if (Context.hasSameUnqualifiedType(T1, T2))
break;
}
@@ -1933,8 +1931,8 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
// -- 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))
@@ -1944,8 +1942,8 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
// -- 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))
@@ -1992,8 +1990,8 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
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))
@@ -2001,8 +1999,8 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
}
// -- 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))
@@ -2114,14 +2112,15 @@ Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
// 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.getCanonic