[cfe-commits] r39414 - in /cfe/cfe/trunk: AST/Expr.cpp AST/Sema.h AST/SemaExpr.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/ASTContext.h

Steve Naroff snaroff at apple.com
Wed Jul 11 09:44:06 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:44:06 2007
New Revision: 39414

URL: http://llvm.org/viewvc/llvm-project?rev=39414&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
A bunch of "small" changes...
- Fixed a bug in ConvertFloatingRankToComplexType() that rendered it useless.
ASTContext was being copied by default (as the result of declaring the argument
incorrectly). Chris gave me the magic potion to disallow this in ASTContext.
- Removed a tab:-)
- Added some much needed comments to the float/complex promotion madness.
- Improved some aesthetics (based on code review w/Chris).

Modified:
    cfe/cfe/trunk/AST/Expr.cpp
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/AST/ASTContext.h

Modified: cfe/cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Expr.cpp?rev=39414&r1=39413&r2=39414&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Expr.cpp (original)
+++ cfe/cfe/trunk/AST/Expr.cpp Wed Jul 11 11:44:06 2007
@@ -135,7 +135,7 @@
     return true;
   case DeclRefExprClass:
     const DeclRefExpr *d = cast<DeclRefExpr>(this);
-	  if (isa<VarDecl>(d->getDecl()))
+    if (isa<VarDecl>(d->getDecl()))
       return true;
     return false;
   case MemberExprClass:
@@ -145,12 +145,9 @@
     return m->getBase()->isLvalue(); // make sure "." is an lvalue
   case UnaryOperatorClass:
     const UnaryOperator *u = cast<UnaryOperator>(this);
-    if (u->getOpcode() == UnaryOperator::Deref)
-      return true;
-    return false;
+    return u->getOpcode() == UnaryOperator::Deref;
   case ParenExprClass:
-    const ParenExpr *pref = cast<ParenExpr>(this);
-    return pref->getSubExpr()->isLvalue();
+    return cast<ParenExpr>(this)->getSubExpr()->isLvalue();
   default: 
     return false;
   }

Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39414&r1=39413&r2=39414&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:44:06 2007
@@ -248,13 +248,13 @@
   /// type checking unary operators (subroutines of ParseUnaryOp).
   /// The unsigned arguments are really enums (UnaryOperator::Opcode)
   ExprResult CheckIncrementDecrementOperand( // C99 6.5.3.1 
-    Expr *op, SourceLocation loc, unsigned c);
+    Expr *op, SourceLocation loc, unsigned OpCode);
   ExprResult CheckAddressOfOperand( // C99 6.5.3.2
-    Expr *op, SourceLocation loc, unsigned c);
+    Expr *op, SourceLocation loc);
   ExprResult CheckIndirectionOperand( // C99 6.5.3.2
-    Expr *op, SourceLocation loc, unsigned c);
+    Expr *op, SourceLocation loc);
   ExprResult CheckArithmeticOperand( // C99 6.5.3.3
-    Expr *op, SourceLocation OpLoc, unsigned Opc);
+    Expr *op, SourceLocation OpLoc, unsigned OpCode);
 };
 
 

Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39414&r1=39413&r2=39414&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:06 2007
@@ -177,9 +177,9 @@
   if (Opc == UnaryOperator::PreInc || Opc == UnaryOperator::PreDec)
     return CheckIncrementDecrementOperand((Expr *)Input, OpLoc, Opc);
   else if (Opc == UnaryOperator::AddrOf)
-    return CheckAddressOfOperand((Expr *)Input, OpLoc, Opc);
+    return CheckAddressOfOperand((Expr *)Input, OpLoc);
   else if (Opc == UnaryOperator::Deref) 
-    return CheckIndirectionOperand((Expr *)Input, OpLoc, Opc);
+    return CheckIndirectionOperand((Expr *)Input, OpLoc);
   else if (UnaryOperator::isArithmeticOp(Opc))
     return CheckArithmeticOperand((Expr *)Input, OpLoc, Opc);
   
@@ -431,7 +431,7 @@
 
 /// ConvertFloatingRankToComplexType - Another helper for converting floats.
 static inline QualType ConvertFloatingRankToComplexType(int rank, 
-                                                        ASTContext C) {
+                                                        ASTContext &C) {
   switch (rank) {
   case 1:
     return C.FloatComplexTy;
@@ -455,10 +455,10 @@
   // if either operand is not of arithmetic type, no conversion is possible.
   if (!lhs->isArithmeticType())
     return lhs;
-  else if (!rhs->isArithmeticType())
+  if (!rhs->isArithmeticType())
     return rhs;
     
-  // if both operands have the same type, no conversion is needed.
+  // if both arithmetic types are identical, no conversion is needed.
   if (lhs == rhs) 
     return lhs;
   
@@ -473,14 +473,22 @@
       return rhs;
 
     // the following code handles three different combinations:
-    // complex/complex, complex/float, float/complex.
+    // complex/complex, complex/float, 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. GetFloatingRank &
+    // ConvertFloatingRankToComplexType handle this without enumerating all
+    // permutations. It also allows us to add new types without breakage.
     int lhsRank = GetFloatingRank(lhs);
     int rhsRank = GetFloatingRank(rhs);
     
-    if (lhsRank >= rhsRank)
-      return ConvertFloatingRankToComplexType(lhsRank, Context);
-    else
-      return ConvertFloatingRankToComplexType(rhsRank, Context);
+    // 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".
+    return ConvertFloatingRankToComplexType(std::max(lhsRank,rhsRank), Context);
   }
   // Now handle "real" floating types (i.e. float, double, long double).
   if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) {
@@ -491,10 +499,7 @@
       return rhs;
 
     // we have two real floating types, float/complex combos were handled above.
-    if (GetFloatingRank(lhs) >= GetFloatingRank(rhs))
-      return lhs;
-    else
-      return rhs;
+    return GetFloatingRank(lhs) >= GetFloatingRank(rhs) ? lhs : rhs;
   }
   // Lastly, handle two integers.
   bool t1Unsigned = lhs->isUnsignedIntegerType();
@@ -650,7 +655,7 @@
 /// Note: The usual conversions are *not* applied to the operand of the & 
 /// operator, and its result is never an lvalue.
 Action::ExprResult
-Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc, unsigned OpCode) {
+Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
   Decl *dcl = getPrimaryDeclaration(op);
   
   if (!op->isLvalue()) {
@@ -664,23 +669,25 @@
     if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) {
       if (vd->getStorageClass() == VarDecl::Register)
         return Diag(OpLoc, diag::err_typecheck_address_of_register);
-    }
+    } else 
+      assert(0 && "Unknown/unexpected decl type");
+    
     // FIXME: add check for bitfields!
   }
   // If the operand has type "type", the result has type "pointer to type".
-  return new UnaryOperator(op, (UnaryOperator::Opcode)OpCode, 
+  return new UnaryOperator(op, UnaryOperator::AddrOf, 
                            Context.getPointerType(op->getType()));
 }
 
 Action::ExprResult
-Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc, unsigned OpCode) {
+Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc) {
   QualType qType = op->getType();
 
   assert(!qType.isNull() && "no type for * expression");
 
   QualType canonType = qType.getCanonicalType();
   
-  return new UnaryOperator(op, (UnaryOperator::Opcode)OpCode, QualType());
+  return new UnaryOperator(op, UnaryOperator::Deref, QualType());
 }
 
 /// CheckArithmeticOperand - Check the arithmetic unary operators (C99 6.5.3.3).

Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39414&r1=39413&r2=39414&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:44:06 2007
@@ -248,13 +248,13 @@
   /// type checking unary operators (subroutines of ParseUnaryOp).
   /// The unsigned arguments are really enums (UnaryOperator::Opcode)
   ExprResult CheckIncrementDecrementOperand( // C99 6.5.3.1 
-    Expr *op, SourceLocation loc, unsigned c);
+    Expr *op, SourceLocation loc, unsigned OpCode);
   ExprResult CheckAddressOfOperand( // C99 6.5.3.2
-    Expr *op, SourceLocation loc, unsigned c);
+    Expr *op, SourceLocation loc);
   ExprResult CheckIndirectionOperand( // C99 6.5.3.2
-    Expr *op, SourceLocation loc, unsigned c);
+    Expr *op, SourceLocation loc);
   ExprResult CheckArithmeticOperand( // C99 6.5.3.3
-    Expr *op, SourceLocation OpLoc, unsigned Opc);
+    Expr *op, SourceLocation OpLoc, unsigned OpCode);
 };
 
 

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:06 2007
@@ -177,9 +177,9 @@
   if (Opc == UnaryOperator::PreInc || Opc == UnaryOperator::PreDec)
     return CheckIncrementDecrementOperand((Expr *)Input, OpLoc, Opc);
   else if (Opc == UnaryOperator::AddrOf)
-    return CheckAddressOfOperand((Expr *)Input, OpLoc, Opc);
+    return CheckAddressOfOperand((Expr *)Input, OpLoc);
   else if (Opc == UnaryOperator::Deref) 
-    return CheckIndirectionOperand((Expr *)Input, OpLoc, Opc);
+    return CheckIndirectionOperand((Expr *)Input, OpLoc);
   else if (UnaryOperator::isArithmeticOp(Opc))
     return CheckArithmeticOperand((Expr *)Input, OpLoc, Opc);
   
@@ -431,7 +431,7 @@
 
 /// ConvertFloatingRankToComplexType - Another helper for converting floats.
 static inline QualType ConvertFloatingRankToComplexType(int rank, 
-                                                        ASTContext C) {
+                                                        ASTContext &C) {
   switch (rank) {
   case 1:
     return C.FloatComplexTy;
@@ -455,10 +455,10 @@
   // if either operand is not of arithmetic type, no conversion is possible.
   if (!lhs->isArithmeticType())
     return lhs;
-  else if (!rhs->isArithmeticType())
+  if (!rhs->isArithmeticType())
     return rhs;
     
-  // if both operands have the same type, no conversion is needed.
+  // if both arithmetic types are identical, no conversion is needed.
   if (lhs == rhs) 
     return lhs;
   
@@ -473,14 +473,22 @@
       return rhs;
 
     // the following code handles three different combinations:
-    // complex/complex, complex/float, float/complex.
+    // complex/complex, complex/float, 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. GetFloatingRank &
+    // ConvertFloatingRankToComplexType handle this without enumerating all
+    // permutations. It also allows us to add new types without breakage.
     int lhsRank = GetFloatingRank(lhs);
     int rhsRank = GetFloatingRank(rhs);
     
-    if (lhsRank >= rhsRank)
-      return ConvertFloatingRankToComplexType(lhsRank, Context);
-    else
-      return ConvertFloatingRankToComplexType(rhsRank, Context);
+    // 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".
+    return ConvertFloatingRankToComplexType(std::max(lhsRank,rhsRank), Context);
   }
   // Now handle "real" floating types (i.e. float, double, long double).
   if (lhs->isRealFloatingType() || rhs->isRealFloatingType()) {
@@ -491,10 +499,7 @@
       return rhs;
 
     // we have two real floating types, float/complex combos were handled above.
-    if (GetFloatingRank(lhs) >= GetFloatingRank(rhs))
-      return lhs;
-    else
-      return rhs;
+    return GetFloatingRank(lhs) >= GetFloatingRank(rhs) ? lhs : rhs;
   }
   // Lastly, handle two integers.
   bool t1Unsigned = lhs->isUnsignedIntegerType();
@@ -650,7 +655,7 @@
 /// Note: The usual conversions are *not* applied to the operand of the & 
 /// operator, and its result is never an lvalue.
 Action::ExprResult
-Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc, unsigned OpCode) {
+Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
   Decl *dcl = getPrimaryDeclaration(op);
   
   if (!op->isLvalue()) {
@@ -664,23 +669,25 @@
     if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) {
       if (vd->getStorageClass() == VarDecl::Register)
         return Diag(OpLoc, diag::err_typecheck_address_of_register);
-    }
+    } else 
+      assert(0 && "Unknown/unexpected decl type");
+    
     // FIXME: add check for bitfields!
   }
   // If the operand has type "type", the result has type "pointer to type".
-  return new UnaryOperator(op, (UnaryOperator::Opcode)OpCode, 
+  return new UnaryOperator(op, UnaryOperator::AddrOf, 
                            Context.getPointerType(op->getType()));
 }
 
 Action::ExprResult
-Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc, unsigned OpCode) {
+Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc) {
   QualType qType = op->getType();
 
   assert(!qType.isNull() && "no type for * expression");
 
   QualType canonType = qType.getCanonicalType();
   
-  return new UnaryOperator(op, (UnaryOperator::Opcode)OpCode, QualType());
+  return new UnaryOperator(op, UnaryOperator::Deref, QualType());
 }
 
 /// CheckArithmeticOperand - Check the arithmetic unary operators (C99 6.5.3.3).

Modified: cfe/cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/ASTContext.h?rev=39414&r1=39413&r2=39414&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/cfe/trunk/include/clang/AST/ASTContext.h Wed Jul 11 11:44:06 2007
@@ -83,6 +83,9 @@
   /// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4).
   QualType getSizeType() const;
 private:
+  ASTContext(const ASTContext&); // DO NOT IMPLEMENT
+  void operator=(const ASTContext&); // DO NOT IMPLEMENT
+  
   void InitBuiltinTypes();
   void InitBuiltinType(QualType &R, BuiltinType::Kind K);
 };





More information about the cfe-commits mailing list