[cfe-commits] r39429 - in /cfe/cfe/trunk: AST/Sema.h AST/SemaExpr.cpp Sema/Sema.h Sema/SemaExpr.cpp
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:44:17 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:44:16 2007
New Revision: 39429
URL: http://llvm.org/viewvc/llvm-project?rev=39429&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Refactored assignment conversion code.
- added Sema::UsualAssignmentConversions(). It will service simple
assignment, argument passing, initialization, and return.
- simplified Sema::CheckAssignmentOperands() using the previous function.
Modified:
cfe/cfe/trunk/AST/Sema.h
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaExpr.cpp
Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39429&r1=39428&r2=39429&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:44:16 2007
@@ -226,6 +226,10 @@
QualType UsualUnaryConversion(QualType t); // C99 6.3
QualType UsualArithmeticConversions(QualType t1, QualType t2); // C99 6.3.1.8
+ // Conversions for assignment, argument passing, initialization, or return
+ QualType UsualAssignmentConversions(QualType lhs, QualType rhs, // C99 6.5.16
+ Expr *rex, SourceLocation loc);
+
/// the following "Check" methods will either return a well formed AST node
/// or will return true if the expressions didn't type check properly.
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39429&r1=39428&r2=39429&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:16 2007
@@ -497,6 +497,57 @@
return Context.maxIntegerType(lhs, rhs);
}
+QualType Sema::UsualAssignmentConversions(QualType lhsType, QualType rhsType,
+ Expr *rex, SourceLocation loc) {
+ if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
+ return lhsType;
+ else if (lhsType->isPointerType()) {
+ if (rhsType->isIntegerType()) {
+ // check for null pointer constant (C99 6.3.2.3p3)
+ const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(rex);
+ if (!constant || constant->getValue() != 0)
+ Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
+ return lhsType;
+ }
+ // FIXME: make sure the qualifier are matching
+ if (rhsType->isPointerType()) {
+ if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
+ Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
+ return lhsType;
+ }
+ } else if (rhsType->isPointerType()) {
+ if (lhsType->isIntegerType()) {
+ // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
+ if (lhsType != Context.BoolTy)
+ Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
+ return lhsType;
+ }
+ // - both operands are pointers to qualified or unqualified versions of
+ // compatible types, and the type pointed to by the left has *all* the
+ // qualifiers of the type pointed to by the right;
+ if (lhsType->isPointerType()) {
+ if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
+ Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
+ return lhsType;
+ }
+ } else if (lhsType->isArrayType() && rhsType->isArrayType()) {
+ /// int aryInt[3], aryInt2[3];
+ /// aryInt = aryInt2; // gcc considers this an error (FIXME?)
+ if (Type::arrayTypesAreCompatible(lhsType, rhsType))
+ return lhsType;
+ } else if (lhsType->isStructureType() && rhsType->isStructureType()) {
+ if (Type::structureTypesAreCompatible(lhsType, rhsType))
+ return lhsType;
+ } else if (lhsType->isUnionType() && rhsType->isUnionType()) {
+ if (Type::unionTypesAreCompatible(lhsType, rhsType))
+ return lhsType;
+ } else if (lhsType->isFunctionType() && rhsType->isFunctionType()) {
+ if (Type::functionTypesAreCompatible(lhsType, rhsType))
+ return lhsType;
+ }
+ return QualType(); // incompatible
+}
+
Action::ExprResult Sema::CheckMultiplicativeOperands(
Expr *lex, Expr *rex, SourceLocation loc, unsigned code)
{
@@ -628,55 +679,15 @@
if (lhsType.isConstQualified())
return Diag(loc, diag::err_typecheck_assign_const);
- if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
+ if (lhsType == rhsType) // common case, fast path...
return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- } else if (lhsType->isPointerType()) {
- if (rhsType->isIntegerType()) {
- // check for null pointer constant (C99 6.3.2.3p3)
- const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(rex);
- if (!constant || constant->getValue() != 0)
- Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- // FIXME: make sure the qualifier are matching
- if (rhsType->isPointerType()) {
- if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
- Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- } else if (rhsType->isPointerType()) {
- if (lhsType->isIntegerType()) {
- // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
- if (lhsType != Context.BoolTy)
- Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- // - both operands are pointers to qualified or unqualified versions of
- // compatible types, and the type pointed to by the left has *all* the
- // qualifiers of the type pointed to by the right;
- if (lhsType->isPointerType()) {
- if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
- Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- } else if (lhsType->isArrayType() && rhsType->isArrayType()) {
- /// int aryInt[3], aryInt2[3];
- /// aryInt = aryInt2; // gcc considers this an error (FIXME?)
- if (Type::arrayTypesAreCompatible(lhsType, rhsType))
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- } else if (lhsType->isStructureType() && rhsType->isStructureType()) {
- if (Type::structureTypesAreCompatible(lhsType, rhsType))
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- } else if (lhsType->isUnionType() && rhsType->isUnionType()) {
- if (Type::unionTypesAreCompatible(lhsType, rhsType))
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- } else if (lhsType->isFunctionType() && rhsType->isFunctionType()) {
- if (Type::functionTypesAreCompatible(lhsType, rhsType))
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- return Diag(loc, diag::err_typecheck_assign_incompatible);
+
+ QualType result = UsualAssignmentConversions(lhsType, rhsType, rex, loc);
+ if (result.isNull())
+ return Diag(loc, diag::err_typecheck_assign_incompatible);
+ else
+ return new BinaryOperator(lex, rex, (BOP)code, result);
}
-
// FIXME: type check compound assignments...
return new BinaryOperator(lex, rex, (BOP)code, Context.IntTy);
}
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39429&r1=39428&r2=39429&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:44:16 2007
@@ -226,6 +226,10 @@
QualType UsualUnaryConversion(QualType t); // C99 6.3
QualType UsualArithmeticConversions(QualType t1, QualType t2); // C99 6.3.1.8
+ // Conversions for assignment, argument passing, initialization, or return
+ QualType UsualAssignmentConversions(QualType lhs, QualType rhs, // C99 6.5.16
+ Expr *rex, SourceLocation loc);
+
/// the following "Check" methods will either return a well formed AST node
/// or will return true if the expressions didn't type check properly.
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39429&r1=39428&r2=39429&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:16 2007
@@ -497,6 +497,57 @@
return Context.maxIntegerType(lhs, rhs);
}
+QualType Sema::UsualAssignmentConversions(QualType lhsType, QualType rhsType,
+ Expr *rex, SourceLocation loc) {
+ if (lhsType->isArithmeticType() && rhsType->isArithmeticType())
+ return lhsType;
+ else if (lhsType->isPointerType()) {
+ if (rhsType->isIntegerType()) {
+ // check for null pointer constant (C99 6.3.2.3p3)
+ const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(rex);
+ if (!constant || constant->getValue() != 0)
+ Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
+ return lhsType;
+ }
+ // FIXME: make sure the qualifier are matching
+ if (rhsType->isPointerType()) {
+ if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
+ Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
+ return lhsType;
+ }
+ } else if (rhsType->isPointerType()) {
+ if (lhsType->isIntegerType()) {
+ // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
+ if (lhsType != Context.BoolTy)
+ Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
+ return lhsType;
+ }
+ // - both operands are pointers to qualified or unqualified versions of
+ // compatible types, and the type pointed to by the left has *all* the
+ // qualifiers of the type pointed to by the right;
+ if (lhsType->isPointerType()) {
+ if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
+ Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
+ return lhsType;
+ }
+ } else if (lhsType->isArrayType() && rhsType->isArrayType()) {
+ /// int aryInt[3], aryInt2[3];
+ /// aryInt = aryInt2; // gcc considers this an error (FIXME?)
+ if (Type::arrayTypesAreCompatible(lhsType, rhsType))
+ return lhsType;
+ } else if (lhsType->isStructureType() && rhsType->isStructureType()) {
+ if (Type::structureTypesAreCompatible(lhsType, rhsType))
+ return lhsType;
+ } else if (lhsType->isUnionType() && rhsType->isUnionType()) {
+ if (Type::unionTypesAreCompatible(lhsType, rhsType))
+ return lhsType;
+ } else if (lhsType->isFunctionType() && rhsType->isFunctionType()) {
+ if (Type::functionTypesAreCompatible(lhsType, rhsType))
+ return lhsType;
+ }
+ return QualType(); // incompatible
+}
+
Action::ExprResult Sema::CheckMultiplicativeOperands(
Expr *lex, Expr *rex, SourceLocation loc, unsigned code)
{
@@ -628,55 +679,15 @@
if (lhsType.isConstQualified())
return Diag(loc, diag::err_typecheck_assign_const);
- if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
+ if (lhsType == rhsType) // common case, fast path...
return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- } else if (lhsType->isPointerType()) {
- if (rhsType->isIntegerType()) {
- // check for null pointer constant (C99 6.3.2.3p3)
- const IntegerLiteral *constant = dyn_cast<IntegerLiteral>(rex);
- if (!constant || constant->getValue() != 0)
- Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- // FIXME: make sure the qualifier are matching
- if (rhsType->isPointerType()) {
- if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
- Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- } else if (rhsType->isPointerType()) {
- if (lhsType->isIntegerType()) {
- // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
- if (lhsType != Context.BoolTy)
- Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- // - both operands are pointers to qualified or unqualified versions of
- // compatible types, and the type pointed to by the left has *all* the
- // qualifiers of the type pointed to by the right;
- if (lhsType->isPointerType()) {
- if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
- Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- } else if (lhsType->isArrayType() && rhsType->isArrayType()) {
- /// int aryInt[3], aryInt2[3];
- /// aryInt = aryInt2; // gcc considers this an error (FIXME?)
- if (Type::arrayTypesAreCompatible(lhsType, rhsType))
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- } else if (lhsType->isStructureType() && rhsType->isStructureType()) {
- if (Type::structureTypesAreCompatible(lhsType, rhsType))
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- } else if (lhsType->isUnionType() && rhsType->isUnionType()) {
- if (Type::unionTypesAreCompatible(lhsType, rhsType))
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- } else if (lhsType->isFunctionType() && rhsType->isFunctionType()) {
- if (Type::functionTypesAreCompatible(lhsType, rhsType))
- return new BinaryOperator(lex, rex, (BOP)code, lhsType);
- }
- return Diag(loc, diag::err_typecheck_assign_incompatible);
+
+ QualType result = UsualAssignmentConversions(lhsType, rhsType, rex, loc);
+ if (result.isNull())
+ return Diag(loc, diag::err_typecheck_assign_incompatible);
+ else
+ return new BinaryOperator(lex, rex, (BOP)code, result);
}
-
// FIXME: type check compound assignments...
return new BinaryOperator(lex, rex, (BOP)code, Context.IntTy);
}
More information about the cfe-commits
mailing list