зеркало из https://github.com/microsoft/clang-1.git
simplify compatibility testing for tag types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49323 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b0489814dc
Коммит
78eca286b0
|
@ -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
|
||||
|
|
|
@ -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<TagType>(LHS), cast<TagType>(RHS), *this);
|
||||
case Type::Builtin:
|
||||
// Only exactly equal builtin types are compatible, which is tested above.
|
||||
return false;
|
||||
|
|
|
@ -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<VectorType>(lhsType) || isa<VectorType>(rhsType)) {
|
||||
// For OCUVector, allow vector splats; float -> <n x float>
|
||||
if (const OCUVectorType *LV = lhsType->getAsOCUVectorType()) {
|
||||
if (const OCUVectorType *LV = dyn_cast<OCUVectorType>(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<PointerType>(lhsType)) {
|
||||
if (rhsType->isIntegerType())
|
||||
return IntToPointer;
|
||||
|
||||
if (rhsType->isPointerType())
|
||||
if (isa<PointerType>(rhsType))
|
||||
return CheckPointerTypesForAssignment(lhsType, rhsType);
|
||||
return Incompatible;
|
||||
}
|
||||
|
||||
if (rhsType->isPointerType()) {
|
||||
if (isa<PointerType>(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<PointerType>(lhsType))
|
||||
return CheckPointerTypesForAssignment(lhsType, rhsType);
|
||||
return Incompatible;
|
||||
}
|
||||
|
||||
if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
|
||||
if (Context.tagTypesAreCompatible(lhsType, rhsType))
|
||||
if (Context.typesAreCompatible(lhsType, rhsType))
|
||||
return Compatible;
|
||||
}
|
||||
return Incompatible;
|
||||
|
|
Загрузка…
Ссылка в новой задаче