From: Chris Lattner Date: Mon, 7 Apr 2008 06:49:41 +0000 (+0000) Subject: simplify compatibility testing for tag types. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=78eca286b0898e98bb2cee943b4ecbea9cc07dd6;p=clang simplify compatibility testing for tag types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49323 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index faae136817..411fba3a16 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -327,7 +327,6 @@ public: /// Compatibility predicates used to check assignment expressions. bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1 - bool tagTypesAreCompatible(QualType, QualType); // C99 6.2.7p1 bool pointerTypesAreCompatible(QualType, QualType); // C99 6.7.5.1p2 bool referenceTypesAreCompatible(QualType, QualType); // C++ 5.17p6 bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15 diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f6330f67ab..4d0fa755b3 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1499,17 +1499,20 @@ static bool areCompatVectorTypes(const VectorType *LHS, LHS->getNumElements() == RHS->getNumElements(); } -// C99 6.2.7p1: If both are complete types, then the following additional -// requirements apply...FIXME (handle compatibility across source files). -bool ASTContext::tagTypesAreCompatible(QualType lhs, QualType rhs) { +/// C99 6.2.7p1: If both are complete types, then the following additional +/// requirements apply. +/// FIXME (handle compatibility across source files). +static bool areCompatTagTypes(TagType *LHS, TagType *RHS, + const ASTContext &C) { // "Class" and "id" are compatible built-in structure types. - if (isObjCIdType(lhs) && isObjCClassType(rhs) || - isObjCClassType(lhs) && isObjCIdType(rhs)) + if (C.isObjCIdType(QualType(LHS, 0)) && C.isObjCClassType(QualType(RHS, 0)) || + C.isObjCClassType(QualType(LHS, 0)) && C.isObjCIdType(QualType(RHS, 0))) return true; - // Within a translation unit a tag type is - // only compatible with itself. - return lhs.getCanonicalType() == rhs.getCanonicalType(); + // Within a translation unit a tag type is only compatible with itself. Self + // equality is already handled by the time we get here. + assert(LHS != RHS && "Self equality not handled!"); + return false; } bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) { @@ -1695,7 +1698,7 @@ bool ASTContext::typesAreCompatible(QualType LHS_NC, QualType RHS_NC) { case Type::FunctionNoProto: return functionTypesAreCompatible(LHS, RHS); case Type::Tagged: // handle structures, unions - return tagTypesAreCompatible(LHS, RHS); + return areCompatTagTypes(cast(LHS), cast(RHS), *this); case Type::Builtin: // Only exactly equal builtin types are compatible, which is tested above. return false; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a528519d26..f0f05006f3 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1167,7 +1167,6 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) { /// /// As a result, the code for dealing with pointers is more complex than the /// C99 spec dictates. -/// Note: the warning above turn into errors when -pedantic-errors is enabled. /// Sema::AssignConvertType Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { @@ -1191,9 +1190,9 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { return Incompatible; } - if (lhsType->isVectorType() || rhsType->isVectorType()) { + if (isa(lhsType) || isa(rhsType)) { // For OCUVector, allow vector splats; float -> - if (const OCUVectorType *LV = lhsType->getAsOCUVectorType()) { + if (const OCUVectorType *LV = dyn_cast(lhsType)) { if (LV->getElementType().getTypePtr() == rhsType.getTypePtr()) return Compatible; } @@ -1216,27 +1215,27 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) return Compatible; - if (lhsType->isPointerType()) { + if (isa(lhsType)) { if (rhsType->isIntegerType()) return IntToPointer; - if (rhsType->isPointerType()) + if (isa(rhsType)) return CheckPointerTypesForAssignment(lhsType, rhsType); return Incompatible; } - if (rhsType->isPointerType()) { + if (isa(rhsType)) { // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer. - if ((lhsType->isIntegerType()) && (lhsType != Context.BoolTy)) + if (lhsType->isIntegerType() && lhsType != Context.BoolTy) return PointerToInt; - if (lhsType->isPointerType()) + if (isa(lhsType)) return CheckPointerTypesForAssignment(lhsType, rhsType); return Incompatible; } if (isa(lhsType) && isa(rhsType)) { - if (Context.tagTypesAreCompatible(lhsType, rhsType)) + if (Context.typesAreCompatible(lhsType, rhsType)) return Compatible; } return Incompatible;