[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