зеркало из https://github.com/microsoft/clang-1.git
Rework commit r45976, which was incorrect.
- Add Type::isComplexIntegerType(), Type::getAsComplexIntegerType(). - Don't inlude complex types with Type::isIntegerType(), which is too general. - Use the new predicates in Sema::UsualArithmeticConversions() to recognize/convert the types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45992 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
425c08c53c
Коммит
4cdec1c3ca
26
AST/Type.cpp
26
AST/Type.cpp
|
@ -77,6 +77,29 @@ bool Type::isComplexType() const {
|
|||
return isa<ComplexType>(CanonicalType);
|
||||
}
|
||||
|
||||
bool Type::isComplexIntegerType() const {
|
||||
// Check for GCC complex integer extension.
|
||||
if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
|
||||
return CT->getElementType()->isIntegerType();
|
||||
return false;
|
||||
}
|
||||
|
||||
const ComplexType *Type::getAsComplexIntegerType() const {
|
||||
// Are we directly a complex type?
|
||||
if (const ComplexType *CTy = dyn_cast<ComplexType>(this)) {
|
||||
if (CTy->getElementType()->isIntegerType())
|
||||
return CTy;
|
||||
}
|
||||
// If the canonical form of this type isn't the right kind, reject it.
|
||||
const ComplexType *CTy = dyn_cast<ComplexType>(CanonicalType);
|
||||
if (!CTy || !CTy->getElementType()->isIntegerType())
|
||||
return 0;
|
||||
|
||||
// If this is a typedef for a complex type, strip the typedef off without
|
||||
// losing all typedef information.
|
||||
return getDesugaredType()->getAsComplexIntegerType();
|
||||
}
|
||||
|
||||
/// getDesugaredType - Return the specified type with any "sugar" removed from
|
||||
/// type 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
|
||||
|
@ -310,9 +333,6 @@ bool Type::isIntegerType() const {
|
|||
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
|
||||
if (TT->getDecl()->getKind() == Decl::Enum)
|
||||
return true;
|
||||
// Check for GCC complex integer extension.
|
||||
if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
|
||||
return CT->getElementType()->isIntegerType();
|
||||
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
|
||||
return VT->getElementType()->isIntegerType();
|
||||
return false;
|
||||
|
|
|
@ -951,12 +951,25 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
|
|||
|
||||
// Handle complex types first (C99 6.3.1.8p1).
|
||||
if (lhs->isComplexType() || rhs->isComplexType()) {
|
||||
// if we have an integer operand, the result is the complex type.
|
||||
if (rhs->isIntegerType()) { // convert the rhs to the lhs complex type.
|
||||
// Handle GCC complex int extension first.
|
||||
// FIXME: need to verify these conversion rules are consistent with GCC.
|
||||
const ComplexType *lhsComplexInt = lhs->getAsComplexIntegerType();
|
||||
const ComplexType *rhsComplexInt = rhs->getAsComplexIntegerType();
|
||||
|
||||
if (lhsComplexInt && rhsComplexInt) {
|
||||
if (Context.maxIntegerType(lhsComplexInt->getElementType(),
|
||||
rhsComplexInt->getElementType()) == lhs) {
|
||||
if (!isCompAssign) promoteExprToType(rhsExpr, lhs); // convert the rhs
|
||||
return lhs;
|
||||
}
|
||||
if (!isCompAssign) promoteExprToType(lhsExpr, rhs); // convert the lhs
|
||||
return rhs;
|
||||
} else if (lhsComplexInt && rhs->isIntegerType()) {
|
||||
// convert the rhs to the lhs complex type.
|
||||
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);
|
||||
return lhs;
|
||||
}
|
||||
if (lhs->isIntegerType()) { // convert the lhs to the rhs complex type.
|
||||
} else if (rhsComplexInt && lhs->isIntegerType()) {
|
||||
// convert the lhs to the rhs complex type.
|
||||
if (!isCompAssign) promoteExprToType(lhsExpr, rhs);
|
||||
return rhs;
|
||||
}
|
||||
|
|
|
@ -291,7 +291,8 @@ public:
|
|||
bool isArrayType() const;
|
||||
bool isRecordType() const;
|
||||
bool isStructureType() const;
|
||||
bool isUnionType() const;
|
||||
bool isUnionType() const;
|
||||
bool isComplexIntegerType() const; // GCC complex int type.
|
||||
bool isVectorType() const; // GCC vector type.
|
||||
bool isOCUVectorType() const; // OCU vector type.
|
||||
bool isObjCInterfaceType() const; // includes conforming protocol type
|
||||
|
@ -313,6 +314,7 @@ public:
|
|||
const RecordType *getAsUnionType() const;
|
||||
const VectorType *getAsVectorType() const; // GCC vector type.
|
||||
const ComplexType *getAsComplexType() const;
|
||||
const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
|
||||
const OCUVectorType *getAsOCUVectorType() const; // OCU vector type.
|
||||
|
||||
/// getDesugaredType - Return the specified type with any "sugar" removed from
|
||||
|
|
|
@ -5,10 +5,18 @@ __complex__ int arr;
|
|||
__complex__ short brr;
|
||||
__complex__ unsigned xx;
|
||||
__complex__ signed yy;
|
||||
|
||||
__complex__ int result;
|
||||
int ii;
|
||||
|
||||
result = arr*ii;
|
||||
result = ii*brr;
|
||||
|
||||
result = arr*brr;
|
||||
result = xx*yy;
|
||||
|
||||
switch (arr) { // expected-error{{statement requires expression of integer type ('_Complex int' invalid)}}
|
||||
case brr: ; // expected-error{{case label does not reduce to an integer constant}}
|
||||
case xx: ; // expected-error{{case label does not reduce to an integer constant}}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче