[cfe-commits] r54063 - /cfe/trunk/lib/Sema/SemaExpr.cpp

Chris Lattner sabre at nondot.org
Fri Jul 25 14:10:04 PDT 2008


Author: lattner
Date: Fri Jul 25 16:10:04 2008
New Revision: 54063

URL: http://llvm.org/viewvc/llvm-project?rev=54063&view=rev
Log:
move some code, no other change.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=54063&r1=54062&r2=54063&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 25 16:10:04 2008
@@ -28,6 +28,228 @@
 #include "llvm/ADT/StringExtras.h"
 using namespace clang;
 
+//===----------------------------------------------------------------------===//
+//  Standard Promotions and Conversions
+//===----------------------------------------------------------------------===//
+
+/// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
+/// do not have a prototype. Arguments that have type float are promoted to 
+/// double. All other argument types are converted by UsualUnaryConversions().
+void Sema::DefaultArgumentPromotion(Expr *&Expr) {
+  QualType Ty = Expr->getType();
+  assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
+
+  // If this is a 'float' (CVR qualified or typedef) promote to double.
+  if (const BuiltinType *BT = Ty->getAsBuiltinType())
+    if (BT->getKind() == BuiltinType::Float)
+      return ImpCastExprToType(Expr, Context.DoubleTy);
+  
+  UsualUnaryConversions(Expr);
+}
+
+/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
+void Sema::DefaultFunctionArrayConversion(Expr *&E) {
+  QualType Ty = E->getType();
+  assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type");
+
+  if (const ReferenceType *ref = Ty->getAsReferenceType()) {
+    ImpCastExprToType(E, ref->getPointeeType()); // C++ [expr]
+    Ty = E->getType();
+  }
+  if (Ty->isFunctionType())
+    ImpCastExprToType(E, Context.getPointerType(Ty));
+  else if (Ty->isArrayType())
+    ImpCastExprToType(E, Context.getArrayDecayedType(Ty));
+}
+
+/// UsualUnaryConversions - Performs various conversions that are common to most
+/// operators (C99 6.3). The conversions of array and function types are 
+/// sometimes surpressed. For example, the array->pointer conversion doesn't
+/// apply if the array is an argument to the sizeof or address (&) operators.
+/// In these instances, this routine should *not* be called.
+Expr *Sema::UsualUnaryConversions(Expr *&Expr) {
+  QualType Ty = Expr->getType();
+  assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
+  
+  if (const ReferenceType *Ref = Ty->getAsReferenceType()) {
+    ImpCastExprToType(Expr, Ref->getPointeeType()); // C++ [expr]
+    Ty = Expr->getType();
+  }
+  if (Ty->isPromotableIntegerType()) // C99 6.3.1.1p2
+    ImpCastExprToType(Expr, Context.IntTy);
+  else
+    DefaultFunctionArrayConversion(Expr);
+  
+  return Expr;
+}
+
+/// UsualArithmeticConversions - Performs various conversions that are common to
+/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
+/// routine returns the first non-arithmetic type found. The client is 
+/// responsible for emitting appropriate error diagnostics.
+/// FIXME: verify the conversion rules for "complex int" are consistent with
+/// GCC.
+QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
+                                          bool isCompAssign) {
+  if (!isCompAssign) {
+    UsualUnaryConversions(lhsExpr);
+    UsualUnaryConversions(rhsExpr);
+  }
+  // For conversion purposes, we ignore any qualifiers. 
+  // For example, "const float" and "float" are equivalent.
+  QualType lhs = lhsExpr->getType().getCanonicalType().getUnqualifiedType();
+  QualType rhs = rhsExpr->getType().getCanonicalType().getUnqualifiedType();
+  
+  // If both types are identical, no conversion is needed.
+  if (lhs == rhs)
+    return lhs;
+  
+  // If either side is a non-arithmetic type (e.g. a pointer), we are done.
+  // The caller can deal with this (e.g. pointer + int).
+  if (!lhs->isArithmeticType() || !rhs->isArithmeticType())
+    return lhs;
+    
+  // At this point, we have two different arithmetic types. 
+  
+  // 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() || rhs->isComplexIntegerType()) { 
+      // convert the rhs to the lhs complex type.
+      if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
+      return lhs;
+    }
+    if (lhs->isIntegerType() || lhs->isComplexIntegerType()) { 
+      // convert the lhs to the rhs complex type.
+      if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
+      return rhs;
+    }
+    // This handles complex/complex, complex/float, or float/complex.
+    // When both operands are complex, the shorter operand is converted to the 
+    // type of the longer, and that is the type of the result. This corresponds 
+    // to what is done when combining two real floating-point operands. 
+    // The fun begins when size promotion occur across type domains. 
+    // From H&S 6.3.4: When one operand is complex and the other is a real
+    // floating-point type, the less precise type is converted, within it's 
+    // real or complex domain, to the precision of the other type. For example,
+    // when combining a "long double" with a "double _Complex", the 
+    // "double _Complex" is promoted to "long double _Complex".
+    int result = Context.getFloatingTypeOrder(lhs, rhs);
+    
+    if (result > 0) { // The left side is bigger, convert rhs. 
+      rhs = Context.getFloatingTypeOfSizeWithinDomain(lhs, rhs);
+      if (!isCompAssign)
+        ImpCastExprToType(rhsExpr, rhs);
+    } else if (result < 0) { // The right side is bigger, convert lhs. 
+      lhs = Context.getFloatingTypeOfSizeWithinDomain(rhs, lhs);
+      if (!isCompAssign)
+        ImpCastExprToType(lhsExpr, lhs);
+    } 
+    // At this point, lhs and rhs have the same rank/size. Now, make sure the
+    // domains match. This is a requirement for our implementation, C99
+    // does not require this promotion.
+    if (lhs != rhs) { // Domains don't match, we have complex/float mix.
+      if (lhs->isRealFloatingType()) { // handle "double, _Complex double".
+        if (!isCompAssign)
+          ImpCastExprToType(lhsExpr, rhs);
+        return rhs;
+      } else { // handle "_Complex double, double".
+        if (!isCompAssign)
+          ImpCastExprToType(rhsExpr, lhs);
+        return lhs;
+      }
+    }
+    return lhs; // The domain/size match exactly.
+  }
+  // Now handle "real" floating types (i.e. float, double, long double).
+  if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) {
+    // if we have an integer operand, the result is the real floating type.
+    if (rhs->isIntegerType() || rhs->isComplexIntegerType()) { 
+      // convert rhs to the lhs floating point type.
+      if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
+      return lhs;
+    }
+    if (lhs->isIntegerType() || lhs->isComplexIntegerType()) { 
+      // convert lhs to the rhs floating point type.
+      if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
+      return rhs;
+    }
+    // We have two real floating types, float/complex combos were handled above.
+    // Convert the smaller operand to the bigger result.
+    int result = Context.getFloatingTypeOrder(lhs, rhs);
+    
+    if (result > 0) { // convert the rhs
+      if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
+      return lhs;
+    }
+    if (result < 0) { // convert the lhs
+      if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs); // convert the lhs
+      return rhs;
+    }
+    assert(0 && "Sema::UsualArithmeticConversions(): illegal float comparison");
+  }
+  if (lhs->isComplexIntegerType() || rhs->isComplexIntegerType()) {
+    // Handle GCC complex int extension.
+    const ComplexType *lhsComplexInt = lhs->getAsComplexIntegerType();
+    const ComplexType *rhsComplexInt = rhs->getAsComplexIntegerType();
+
+    if (lhsComplexInt && rhsComplexInt) {
+      if (Context.getIntegerTypeOrder(lhsComplexInt->getElementType(), 
+                                      rhsComplexInt->getElementType()) >= 0) {
+        // convert the rhs
+        if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
+        return lhs;
+      }
+      if (!isCompAssign) 
+        ImpCastExprToType(lhsExpr, rhs); // convert the lhs
+      return rhs;
+    } else if (lhsComplexInt && rhs->isIntegerType()) {
+      // convert the rhs to the lhs complex type.
+      if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
+      return lhs;
+    } else if (rhsComplexInt && lhs->isIntegerType()) {
+      // convert the lhs to the rhs complex type.
+      if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
+      return rhs;
+    }
+  }
+  // Finally, we have two differing integer types.
+  // The rules for this case are in C99 6.3.1.8
+  int compare = Context.getIntegerTypeOrder(lhs, rhs);
+  bool lhsSigned = lhs->isSignedIntegerType(),
+       rhsSigned = rhs->isSignedIntegerType();
+  QualType destType;
+  if (lhsSigned == rhsSigned) {
+    // Same signedness; use the higher-ranked type
+    destType = compare >= 0 ? lhs : rhs;
+  } else if (compare != (lhsSigned ? 1 : -1)) {
+    // The unsigned type has greater than or equal rank to the
+    // signed type, so use the unsigned type
+    destType = lhsSigned ? rhs : lhs;
+  } else if (Context.getIntWidth(lhs) != Context.getIntWidth(rhs)) {
+    // The two types are different widths; if we are here, that
+    // means the signed type is larger than the unsigned type, so
+    // use the signed type.
+    destType = lhsSigned ? lhs : rhs;
+  } else {
+    // The signed type is higher-ranked than the unsigned type,
+    // but isn't actually any bigger (like unsigned int and long
+    // on most 32-bit systems).  Use the unsigned type corresponding
+    // to the signed type.
+    destType = Context.getCorrespondingUnsignedType(lhsSigned ? lhs : rhs);
+  }
+  if (!isCompAssign) {
+    ImpCastExprToType(lhsExpr, destType);
+    ImpCastExprToType(rhsExpr, destType);
+  }
+  return destType;
+}
+
+//===----------------------------------------------------------------------===//
+//  Semantic Analysis for various Expression Types
+//===----------------------------------------------------------------------===//
+
+
 /// ActOnStringLiteral - The specified tokens were lexed as pasted string
 /// fragments (e.g. "foo" "bar" L"baz").  The result string has to handle string
 /// concatenation ([C99 5.1.1.2, translation phase #6]), so it may come from
@@ -1068,218 +1290,6 @@
                                  RHSExpr, result);
 }
 
-/// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
-/// do not have a prototype. Arguments that have type float are promoted to 
-/// double. All other argument types are converted by UsualUnaryConversions().
-void Sema::DefaultArgumentPromotion(Expr *&Expr) {
-  QualType Ty = Expr->getType();
-  assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
-
-  // If this is a 'float' (CVR qualified or typedef) promote to double.
-  if (const BuiltinType *BT = Ty->getAsBuiltinType())
-    if (BT->getKind() == BuiltinType::Float)
-      return ImpCastExprToType(Expr, Context.DoubleTy);
-  
-  UsualUnaryConversions(Expr);
-}
-
-/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
-void Sema::DefaultFunctionArrayConversion(Expr *&E) {
-  QualType Ty = E->getType();
-  assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type");
-
-  if (const ReferenceType *ref = Ty->getAsReferenceType()) {
-    ImpCastExprToType(E, ref->getPointeeType()); // C++ [expr]
-    Ty = E->getType();
-  }
-  if (Ty->isFunctionType())
-    ImpCastExprToType(E, Context.getPointerType(Ty));
-  else if (Ty->isArrayType())
-    ImpCastExprToType(E, Context.getArrayDecayedType(Ty));
-}
-
-/// UsualUnaryConversions - Performs various conversions that are common to most
-/// operators (C99 6.3). The conversions of array and function types are 
-/// sometimes surpressed. For example, the array->pointer conversion doesn't
-/// apply if the array is an argument to the sizeof or address (&) operators.
-/// In these instances, this routine should *not* be called.
-Expr *Sema::UsualUnaryConversions(Expr *&Expr) {
-  QualType Ty = Expr->getType();
-  assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
-  
-  if (const ReferenceType *Ref = Ty->getAsReferenceType()) {
-    ImpCastExprToType(Expr, Ref->getPointeeType()); // C++ [expr]
-    Ty = Expr->getType();
-  }
-  if (Ty->isPromotableIntegerType()) // C99 6.3.1.1p2
-    ImpCastExprToType(Expr, Context.IntTy);
-  else
-    DefaultFunctionArrayConversion(Expr);
-  
-  return Expr;
-}
-
-/// UsualArithmeticConversions - Performs various conversions that are common to
-/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
-/// routine returns the first non-arithmetic type found. The client is 
-/// responsible for emitting appropriate error diagnostics.
-/// FIXME: verify the conversion rules for "complex int" are consistent with
-/// GCC.
-QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
-                                          bool isCompAssign) {
-  if (!isCompAssign) {
-    UsualUnaryConversions(lhsExpr);
-    UsualUnaryConversions(rhsExpr);
-  }
-  // For conversion purposes, we ignore any qualifiers. 
-  // For example, "const float" and "float" are equivalent.
-  QualType lhs = lhsExpr->getType().getCanonicalType().getUnqualifiedType();
-  QualType rhs = rhsExpr->getType().getCanonicalType().getUnqualifiedType();
-  
-  // If both types are identical, no conversion is needed.
-  if (lhs == rhs)
-    return lhs;
-  
-  // If either side is a non-arithmetic type (e.g. a pointer), we are done.
-  // The caller can deal with this (e.g. pointer + int).
-  if (!lhs->isArithmeticType() || !rhs->isArithmeticType())
-    return lhs;
-    
-  // At this point, we have two different arithmetic types. 
-  
-  // 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() || rhs->isComplexIntegerType()) { 
-      // convert the rhs to the lhs complex type.
-      if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
-      return lhs;
-    }
-    if (lhs->isIntegerType() || lhs->isComplexIntegerType()) { 
-      // convert the lhs to the rhs complex type.
-      if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
-      return rhs;
-    }
-    // This handles complex/complex, complex/float, or float/complex.
-    // When both operands are complex, the shorter operand is converted to the 
-    // type of the longer, and that is the type of the result. This corresponds 
-    // to what is done when combining two real floating-point operands. 
-    // The fun begins when size promotion occur across type domains. 
-    // From H&S 6.3.4: When one operand is complex and the other is a real
-    // floating-point type, the less precise type is converted, within it's 
-    // real or complex domain, to the precision of the other type. For example,
-    // when combining a "long double" with a "double _Complex", the 
-    // "double _Complex" is promoted to "long double _Complex".
-    int result = Context.getFloatingTypeOrder(lhs, rhs);
-    
-    if (result > 0) { // The left side is bigger, convert rhs. 
-      rhs = Context.getFloatingTypeOfSizeWithinDomain(lhs, rhs);
-      if (!isCompAssign)
-        ImpCastExprToType(rhsExpr, rhs);
-    } else if (result < 0) { // The right side is bigger, convert lhs. 
-      lhs = Context.getFloatingTypeOfSizeWithinDomain(rhs, lhs);
-      if (!isCompAssign)
-        ImpCastExprToType(lhsExpr, lhs);
-    } 
-    // At this point, lhs and rhs have the same rank/size. Now, make sure the
-    // domains match. This is a requirement for our implementation, C99
-    // does not require this promotion.
-    if (lhs != rhs) { // Domains don't match, we have complex/float mix.
-      if (lhs->isRealFloatingType()) { // handle "double, _Complex double".
-        if (!isCompAssign)
-          ImpCastExprToType(lhsExpr, rhs);
-        return rhs;
-      } else { // handle "_Complex double, double".
-        if (!isCompAssign)
-          ImpCastExprToType(rhsExpr, lhs);
-        return lhs;
-      }
-    }
-    return lhs; // The domain/size match exactly.
-  }
-  // Now handle "real" floating types (i.e. float, double, long double).
-  if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) {
-    // if we have an integer operand, the result is the real floating type.
-    if (rhs->isIntegerType() || rhs->isComplexIntegerType()) { 
-      // convert rhs to the lhs floating point type.
-      if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
-      return lhs;
-    }
-    if (lhs->isIntegerType() || lhs->isComplexIntegerType()) { 
-      // convert lhs to the rhs floating point type.
-      if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
-      return rhs;
-    }
-    // We have two real floating types, float/complex combos were handled above.
-    // Convert the smaller operand to the bigger result.
-    int result = Context.getFloatingTypeOrder(lhs, rhs);
-    
-    if (result > 0) { // convert the rhs
-      if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
-      return lhs;
-    }
-    if (result < 0) { // convert the lhs
-      if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs); // convert the lhs
-      return rhs;
-    }
-    assert(0 && "Sema::UsualArithmeticConversions(): illegal float comparison");
-  }
-  if (lhs->isComplexIntegerType() || rhs->isComplexIntegerType()) {
-    // Handle GCC complex int extension.
-    const ComplexType *lhsComplexInt = lhs->getAsComplexIntegerType();
-    const ComplexType *rhsComplexInt = rhs->getAsComplexIntegerType();
-
-    if (lhsComplexInt && rhsComplexInt) {
-      if (Context.getIntegerTypeOrder(lhsComplexInt->getElementType(), 
-                                      rhsComplexInt->getElementType()) >= 0) {
-        // convert the rhs
-        if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
-        return lhs;
-      }
-      if (!isCompAssign) 
-        ImpCastExprToType(lhsExpr, rhs); // convert the lhs
-      return rhs;
-    } else if (lhsComplexInt && rhs->isIntegerType()) {
-      // convert the rhs to the lhs complex type.
-      if (!isCompAssign) ImpCastExprToType(rhsExpr, lhs);
-      return lhs;
-    } else if (rhsComplexInt && lhs->isIntegerType()) {
-      // convert the lhs to the rhs complex type.
-      if (!isCompAssign) ImpCastExprToType(lhsExpr, rhs);
-      return rhs;
-    }
-  }
-  // Finally, we have two differing integer types.
-  // The rules for this case are in C99 6.3.1.8
-  int compare = Context.getIntegerTypeOrder(lhs, rhs);
-  bool lhsSigned = lhs->isSignedIntegerType(),
-       rhsSigned = rhs->isSignedIntegerType();
-  QualType destType;
-  if (lhsSigned == rhsSigned) {
-    // Same signedness; use the higher-ranked type
-    destType = compare >= 0 ? lhs : rhs;
-  } else if (compare != (lhsSigned ? 1 : -1)) {
-    // The unsigned type has greater than or equal rank to the
-    // signed type, so use the unsigned type
-    destType = lhsSigned ? rhs : lhs;
-  } else if (Context.getIntWidth(lhs) != Context.getIntWidth(rhs)) {
-    // The two types are different widths; if we are here, that
-    // means the signed type is larger than the unsigned type, so
-    // use the signed type.
-    destType = lhsSigned ? lhs : rhs;
-  } else {
-    // The signed type is higher-ranked than the unsigned type,
-    // but isn't actually any bigger (like unsigned int and long
-    // on most 32-bit systems).  Use the unsigned type corresponding
-    // to the signed type.
-    destType = Context.getCorrespondingUnsignedType(lhsSigned ? lhs : rhs);
-  }
-  if (!isCompAssign) {
-    ImpCastExprToType(lhsExpr, destType);
-    ImpCastExprToType(rhsExpr, destType);
-  }
-  return destType;
-}
 
 // CheckPointerTypesForAssignment - This is a very tricky routine (despite
 // being closely modeled after the C99 spec:-). The odd characteristic of this 





More information about the cfe-commits mailing list