[cfe-commits] r39814 - in /cfe/trunk: AST/StmtPrinter.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp include/clang/AST/Expr.h include/clang/AST/StmtNodes.def

Steve Naroff snaroff at apple.com
Fri Jul 13 09:59:00 PDT 2007


Author: snaroff
Date: Fri Jul 13 11:58:59 2007
New Revision: 39814

URL: http://llvm.org/viewvc/llvm-project?rev=39814&view=rev
Log:

Add (explicit) AST support for implicit casts. This should simplify the 
code generator. Source translation tools can simply ignore this node.

- Added a new Expr node, ImplicitCastExpr.
- Changed UsualUnaryConversions/UsualArithmeticConversions to take references 
to Expr *'s. This will allow these routines to instantiate the new AST node
and pass it back.
- Changed all clients of UsualUnary/UsualArithmetic (lot's of diff's).
- Changed some names in CheckConditionalOperands. Several variables where
only distinguished by their case (e.g. Cond, cond). Yuck (what was I thinking).
- Removed an old/crufty constructor in CastExpr (cleanup).

This check-in does not actually create the new AST node. I wanted to separate
the mechanical changes from the semantic changes. In addition, I need to 
coordinate with Chris, since the semantic change will break the code generator.


Modified:
    cfe/trunk/AST/StmtPrinter.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/StmtNodes.def

Modified: cfe/trunk/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/StmtPrinter.cpp?rev=39814&r1=39813&r2=39814&view=diff

==============================================================================
--- cfe/trunk/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/AST/StmtPrinter.cpp Fri Jul 13 11:58:59 2007
@@ -386,6 +386,9 @@
   OS << "(" << Node->getDestType().getAsString() << ")";
   PrintExpr(Node->getSubExpr());
 }
+void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
+  // No need to print anything.
+}
 void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
   PrintExpr(Node->getLHS());
   OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";

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

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Fri Jul 13 11:58:59 2007
@@ -270,13 +270,13 @@
 private:
   // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
   // functions and arrays to their respective pointers (C99 6.3.2.1)
-  QualType UsualUnaryConversions(QualType t); 
+  QualType UsualUnaryConversions(Expr *&expr); 
   // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
   // operands and then handles 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.
-  QualType UsualArithmeticConversions(QualType &t1, QualType &t2);
+  QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr);
   // DefaultFunctionArrayConversion - converts functions and arrays
   // to their respective pointers (C99 6.3.2.1). If the type isn't a function
   // or array, this routine simply returns the input type (unmodified).
@@ -302,35 +302,35 @@
   /// or a null QualType (indicating an error diagnostic was issued).
     
   /// type checking binary operators (subroutines of ParseBinOp).
-  inline void InvalidOperands(SourceLocation l, Expr *lex, Expr *rex);
-  inline QualType CheckVectorOperands(SourceLocation l, Expr *lex, Expr *rex);
+  inline void InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
+  inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
   inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
-    Expr *lex, Expr *rex, SourceLocation OpLoc); 
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc); 
   inline QualType CheckRemainderOperands( // C99 6.5.5
-    Expr *lex, Expr *rex, SourceLocation OpLoc); 
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc); 
   inline QualType CheckAdditionOperands( // C99 6.5.6
-    Expr *lex, Expr *rex, SourceLocation OpLoc);
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc);
   inline QualType CheckSubtractionOperands( // C99 6.5.6
-    Expr *lex, Expr *rex, SourceLocation OpLoc);
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc);
   inline QualType CheckShiftOperands( // C99 6.5.7
-    Expr *lex, Expr *rex, SourceLocation OpLoc);
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc);
   inline QualType CheckRelationalOperands( // C99 6.5.8
-    Expr *lex, Expr *rex, SourceLocation OpLoc);
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc);
   inline QualType CheckEqualityOperands( // C99 6.5.9
-    Expr *lex, Expr *rex, SourceLocation OpLoc); 
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc); 
   inline QualType CheckBitwiseOperands( // C99 6.5.[10...12]
-    Expr *lex, Expr *rex, SourceLocation OpLoc); 
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc); 
   inline QualType CheckLogicalOperands( // C99 6.5.[13,14]
-    Expr *lex, Expr *rex, SourceLocation OpLoc);
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc);
   // CheckAssignmentOperands is used for both simple and compound assignment.
   // For simple assignment, pass both expressions and a null converted type.
   // For compound assignment, pass both expressions and the converted type.
   inline QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
     Expr *lex, Expr *rex, SourceLocation OpLoc, QualType convertedType);
   inline QualType CheckCommaOperands( // C99 6.5.17
-    Expr *lex, Expr *rex, SourceLocation OpLoc);
+    Expr *&lex, Expr *&rex, SourceLocation OpLoc);
   inline QualType CheckConditionalOperands( // C99 6.5.15
-    Expr *cond, Expr *lhs, Expr *rhs, SourceLocation questionLoc);
+    Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
   
   /// type checking unary operators (subroutines of ParseUnaryOp).
   /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4

Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=39814&r1=39813&r2=39814&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Fri Jul 13 11:58:59 2007
@@ -311,7 +311,7 @@
     assert(Init == 0 && "Can't have an initializer for a functiondecl!");
     QualType R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0; // FIXME: "auto func();" passes through...
-    
+
     FunctionDecl::StorageClass SC;
     switch (D.getDeclSpec().getStorageClassSpec()) {
       default: assert(0 && "Unknown storage class!");

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

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Fri Jul 13 11:58:59 2007
@@ -375,7 +375,7 @@
   Expr *funcExpr = (Expr *)Fn;
   assert(funcExpr && "no function call expression");
   
-  QualType qType = UsualUnaryConversions(funcExpr->getType());
+  QualType qType = UsualUnaryConversions(funcExpr);
   assert(!qType.isNull() && "no type for function call expression");
 
   // C99 6.5.2.2p1 - "The expression that denotes the called function shall have
@@ -482,62 +482,62 @@
 }
 
 inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
-  Expr *Cond, Expr *LHS, Expr *RHS, SourceLocation questionLoc) {
-  QualType cond = Cond->getType();
-  QualType lhs = LHS->getType();
-  QualType rhs = RHS->getType();
-  
-  assert(!cond.isNull() && "ParseConditionalOp(): no conditional type");
-  assert(!lhs.isNull() && "ParseConditionalOp(): no lhs type");
-  assert(!rhs.isNull() && "ParseConditionalOp(): no rhs type");
-
-  cond = UsualUnaryConversions(cond);
-  lhs = UsualUnaryConversions(lhs);
-  rhs = UsualUnaryConversions(rhs);
+  Expr *&cond, Expr *&lex, Expr *&rex, SourceLocation questionLoc) {
+  QualType condT = cond->getType();
+  QualType lexT = lex->getType();
+  QualType rexT = rex->getType();
+  
+  assert(!condT.isNull() && "ParseConditionalOp(): no conditional type");
+  assert(!lexT.isNull() && "ParseConditionalOp(): no lhs type");
+  assert(!rexT.isNull() && "ParseConditionalOp(): no rhs type");
+
+  condT = UsualUnaryConversions(cond);
+  lexT = UsualUnaryConversions(lex);
+  rexT = UsualUnaryConversions(rex);
   
   // first, check the condition.
-  if (!cond->isScalarType()) { // C99 6.5.15p2
-    Diag(Cond->getLocStart(), diag::err_typecheck_cond_expect_scalar, 
-         cond.getAsString());
+  if (!condT->isScalarType()) { // C99 6.5.15p2
+    Diag(cond->getLocStart(), diag::err_typecheck_cond_expect_scalar, 
+         condT.getAsString());
     return QualType();
   }
   // now check the two expressions.
-  if (lhs->isArithmeticType() && rhs->isArithmeticType()) // C99 6.5.15p3,5
-    return UsualArithmeticConversions(lhs, rhs);
+  if (lexT->isArithmeticType() && rexT->isArithmeticType()) // C99 6.5.15p3,5
+    return UsualArithmeticConversions(lex, rex);
     
-  if ((lhs->isStructureType() && rhs->isStructureType()) || // C99 6.5.15p3
-      (lhs->isUnionType() && rhs->isUnionType())) {
-    TagType *lTag = cast<TagType>(lhs.getCanonicalType());
-    TagType *rTag = cast<TagType>(rhs.getCanonicalType());
+  if ((lexT->isStructureType() && rexT->isStructureType()) || // C99 6.5.15p3
+      (lexT->isUnionType() && rexT->isUnionType())) {
+    TagType *lTag = cast<TagType>(lexT.getCanonicalType());
+    TagType *rTag = cast<TagType>(rexT.getCanonicalType());
     
     if (lTag->getDecl()->getIdentifier() == rTag->getDecl()->getIdentifier()) 
-      return lhs;
+      return lexT;
     else {
       Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands,
-           lhs.getAsString(), rhs.getAsString(),
-           LHS->getSourceRange(), RHS->getSourceRange());
+           lexT.getAsString(), rexT.getAsString(),
+           lex->getSourceRange(), rex->getSourceRange());
       return QualType();
     }
   }
-  if (lhs->isPointerType() && RHS->isNullPointerConstant()) // C99 6.5.15p3
-    return lhs;
-  if (rhs->isPointerType() && LHS->isNullPointerConstant())
-    return rhs;
+  if (lexT->isPointerType() && rex->isNullPointerConstant()) // C99 6.5.15p3
+    return lexT;
+  if (rexT->isPointerType() && lex->isNullPointerConstant())
+    return rexT;
     
-  if (lhs->isPointerType() && rhs->isPointerType()) { // C99 6.5.15p3,6
+  if (lexT->isPointerType() && rexT->isPointerType()) { // C99 6.5.15p3,6
     QualType lhptee, rhptee;
     
     // get the "pointed to" type
-    lhptee = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
-    rhptee = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
+    lhptee = cast<PointerType>(lexT.getCanonicalType())->getPointeeType();
+    rhptee = cast<PointerType>(rexT.getCanonicalType())->getPointeeType();
 
     // ignore qualifiers on void (C99 6.5.15p3, clause 6)
     if (lhptee.getUnqualifiedType()->isVoidType() &&
         (rhptee->isObjectType() || rhptee->isIncompleteType()))
-      return lhs;
+      return lexT;
     if (rhptee.getUnqualifiedType()->isVoidType() &&
         (lhptee->isObjectType() || lhptee->isIncompleteType()))
-      return rhs;
+      return rexT;
 
     // FIXME: C99 6.5.15p6: If both operands are pointers to compatible types
     // *or* to differently qualified versions of compatible types, the result
@@ -546,17 +546,17 @@
     if (!Type::typesAreCompatible(lhptee.getUnqualifiedType(), 
                                   rhptee.getUnqualifiedType())) {
       Diag(questionLoc, diag::ext_typecheck_cond_incompatible_pointers,
-           lhs.getAsString(), rhs.getAsString(),
-           LHS->getSourceRange(), RHS->getSourceRange());
-      return lhs; // FIXME: this is an _ext - is this return o.k?
+           lexT.getAsString(), rexT.getAsString(),
+           lex->getSourceRange(), rex->getSourceRange());
+      return lexT; // FIXME: this is an _ext - is this return o.k?
     }
   }
-  if (lhs->isVoidType() && rhs->isVoidType()) // C99 6.5.15p3
-    return lhs;
+  if (lexT->isVoidType() && rexT->isVoidType()) // C99 6.5.15p3
+    return lexT;
     
   Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands,
-       lhs.getAsString(), rhs.getAsString(),
-       LHS->getSourceRange(), RHS->getSourceRange());
+       lexT.getAsString(), rexT.getAsString(),
+       lex->getSourceRange(), rex->getSourceRange());
   return QualType();
 }
 
@@ -566,8 +566,8 @@
                                             SourceLocation ColonLoc,
                                             ExprTy *Cond, ExprTy *LHS,
                                             ExprTy *RHS) {
-  QualType result = CheckConditionalOperands((Expr *)Cond, (Expr *)LHS, 
-                                             (Expr *)RHS, QuestionLoc);
+  QualType result = CheckConditionalOperands((Expr *&)Cond, (Expr *&)LHS, 
+                                             (Expr *&)RHS, QuestionLoc);
   if (result.isNull())
     return true;
   return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, result);
@@ -586,7 +586,8 @@
 /// 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.
-QualType Sema::UsualUnaryConversions(QualType t) {
+QualType Sema::UsualUnaryConversions(Expr *&expr) {
+  QualType t = expr->getType();
   assert(!t.isNull() && "UsualUnaryConversions - missing type");
   
   if (t->isPromotableIntegerType()) // C99 6.3.1.1p2
@@ -598,9 +599,9 @@
 /// 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.
-QualType Sema::UsualArithmeticConversions(QualType &lhs, QualType &rhs) {
-  lhs = UsualUnaryConversions(lhs);
-  rhs = UsualUnaryConversions(rhs);
+QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr) {
+  QualType lhs = UsualUnaryConversions(lhsExpr);
+  QualType rhs = UsualUnaryConversions(rhsExpr);
   
   // If both types are identical, no conversion is needed.
   if (lhs == rhs) 
@@ -737,14 +738,14 @@
   return Incompatible;
 }
 
-inline void Sema::InvalidOperands(SourceLocation loc, Expr *lex, Expr *rex) {
+inline void Sema::InvalidOperands(SourceLocation loc, Expr *&lex, Expr *&rex) {
   Diag(loc, diag::err_typecheck_invalid_operands, 
        lex->getType().getAsString(), rex->getType().getAsString(),
        lex->getSourceRange(), rex->getSourceRange());
 }
 
-inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *lex, 
-                                                              Expr *rex) {
+inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *&lex, 
+                                                              Expr *&rex) {
   QualType lhsType = lex->getType(), rhsType = rex->getType();
   
   // make sure the vector types are identical. 
@@ -758,13 +759,12 @@
 }    
 
 inline QualType Sema::CheckMultiplyDivideOperands(
-  Expr *lex, Expr *rex, SourceLocation loc) 
+  Expr *&lex, Expr *&rex, SourceLocation loc) 
 {
-  QualType lhsType = lex->getType(), rhsType = rex->getType();
-  
-  if (lhsType->isVectorType() || rhsType->isVectorType())
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
     return CheckVectorOperands(loc, lex, rex);
-  QualType resType = UsualArithmeticConversions(lhsType, rhsType);
+    
+  QualType resType = UsualArithmeticConversions(lex, rex);
   
   if (resType->isArithmeticType())
     return resType;
@@ -773,10 +773,9 @@
 }
 
 inline QualType Sema::CheckRemainderOperands(
-  Expr *lex, Expr *rex, SourceLocation loc) 
+  Expr *&lex, Expr *&rex, SourceLocation loc) 
 {
-  QualType lhsType = lex->getType(), rhsType = rex->getType();
-  QualType resType = UsualArithmeticConversions(lhsType, rhsType);
+  QualType resType = UsualArithmeticConversions(lex, rex);
   
   if (resType->isIntegerType())
     return resType;
@@ -785,13 +784,14 @@
 }
 
 inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
-  Expr *lex, Expr *rex, SourceLocation loc) 
+  Expr *&lex, Expr *&rex, SourceLocation loc) 
 {
   QualType lhsType = lex->getType(), rhsType = rex->getType();
 
   if (lhsType->isVectorType() || rhsType->isVectorType())
-    return CheckVectorOperands(loc, lex, rex);    
-  QualType resType = UsualArithmeticConversions(lhsType, rhsType);
+    return CheckVectorOperands(loc, lex, rex);
+
+  QualType resType = UsualArithmeticConversions(lex, rex);
 
   // handle the common case first (both operands are arithmetic).
   if (resType->isArithmeticType())
@@ -805,13 +805,13 @@
 }
 
 inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6
-  Expr *lex, Expr *rex, SourceLocation loc) 
+  Expr *&lex, Expr *&rex, SourceLocation loc) 
 {
   QualType lhsType = lex->getType(), rhsType = rex->getType();
 
   if (lhsType->isVectorType() || rhsType->isVectorType())
     return CheckVectorOperands(loc, lex, rex);
-  QualType resType = UsualArithmeticConversions(lhsType, rhsType);
+  QualType resType = UsualArithmeticConversions(lex, rex);
   
   // handle the common case first (both operands are arithmetic).
   if (resType->isArithmeticType())
@@ -825,12 +825,12 @@
 }
 
 inline QualType Sema::CheckShiftOperands( // C99 6.5.7
-  Expr *lex, Expr *rex, SourceLocation loc)
+  Expr *&lex, Expr *&rex, SourceLocation loc)
 {
   // FIXME: Shifts don't perform usual arithmetic conversions.  This is wrong
   // for int << longlong -> the result type should be int, not long long.
   QualType lhsType = lex->getType(), rhsType = rex->getType();
-  QualType resType = UsualArithmeticConversions(lhsType, rhsType);
+  QualType resType = UsualArithmeticConversions(lex, rex);
   
   if (resType->isIntegerType())
     return resType;
@@ -839,10 +839,10 @@
 }
 
 inline QualType Sema::CheckRelationalOperands( // C99 6.5.8
-  Expr *lex, Expr *rex, SourceLocation loc)
+  Expr *&lex, Expr *&rex, SourceLocation loc)
 {
-  QualType lType = UsualUnaryConversions(lex->getType());
-  QualType rType = UsualUnaryConversions(rex->getType());
+  QualType lType = UsualUnaryConversions(lex);
+  QualType rType = UsualUnaryConversions(rex);
   
   if (lType->isRealType() && rType->isRealType())
     return Context.IntTy;
@@ -869,10 +869,10 @@
 }
 
 inline QualType Sema::CheckEqualityOperands( // C99 6.5.9
-  Expr *lex, Expr *rex, SourceLocation loc)
+  Expr *&lex, Expr *&rex, SourceLocation loc)
 {
-  QualType lType = UsualUnaryConversions(lex->getType());
-  QualType rType = UsualUnaryConversions(rex->getType());
+  QualType lType = UsualUnaryConversions(lex);
+  QualType rType = UsualUnaryConversions(rex);
   
   if (lType->isArithmeticType() && rType->isArithmeticType())
     return Context.IntTy;
@@ -899,13 +899,13 @@
 }
 
 inline QualType Sema::CheckBitwiseOperands(
-  Expr *lex, Expr *rex, SourceLocation loc) 
+  Expr *&lex, Expr *&rex, SourceLocation loc) 
 {
   QualType lhsType = lex->getType(), rhsType = rex->getType();
   
   if (lhsType->isVectorType() || rhsType->isVectorType())
     return CheckVectorOperands(loc, lex, rex);
-  QualType resType = UsualArithmeticConversions(lhsType, rhsType);
+  QualType resType = UsualArithmeticConversions(lex, rex);
   
   if (resType->isIntegerType())
     return resType;
@@ -914,10 +914,10 @@
 }
 
 inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
-  Expr *lex, Expr *rex, SourceLocation loc) 
+  Expr *&lex, Expr *&rex, SourceLocation loc) 
 {
-  QualType lhsType = UsualUnaryConversions(lex->getType());
-  QualType rhsType = UsualUnaryConversions(rex->getType());
+  QualType lhsType = UsualUnaryConversions(lex);
+  QualType rhsType = UsualUnaryConversions(rex);
   
   if (lhsType->isScalarType() || rhsType->isScalarType())
     return Context.IntTy;
@@ -1007,13 +1007,14 @@
 }
 
 inline QualType Sema::CheckCommaOperands( // C99 6.5.17
-  Expr *lex, Expr *rex, SourceLocation loc) {
-  return UsualUnaryConversions(rex->getType());
+  Expr *&lex, Expr *&rex, SourceLocation loc) {
+  return UsualUnaryConversions(rex);
 }
 
+/// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
+/// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
 QualType Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc) {
-  QualType lhsType = op->getType(), rhsType = Context.IntTy;
-  QualType resType = UsualArithmeticConversions(lhsType, rhsType);
+  QualType resType = op->getType();
   assert(!resType.isNull() && "no type for increment/decrement expression");
 
   // C99 6.5.2.4p1
@@ -1100,7 +1101,7 @@
 }
 
 QualType Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc) {
-  QualType qType = UsualUnaryConversions(op->getType());
+  QualType qType = UsualUnaryConversions(op);
   
   assert(!qType.isNull() && "no type for * expression");
 
@@ -1307,13 +1308,13 @@
     break;
   case UnaryOperator::Plus:
   case UnaryOperator::Minus:
-    resultType = UsualUnaryConversions(Input->getType());
+    resultType = UsualUnaryConversions(Input);
     if (!resultType->isArithmeticType())  // C99 6.5.3.3p1
       return Diag(OpLoc, diag::err_typecheck_unary_expr, 
                   resultType.getAsString());
     break;
   case UnaryOperator::Not: // bitwise complement
-    resultType = UsualUnaryConversions(Input->getType());
+    resultType = UsualUnaryConversions(Input);
     if (!resultType->isIntegerType())  // C99 6.5.3.3p1
       return Diag(OpLoc, diag::err_typecheck_unary_expr,
                   resultType.getAsString());

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

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Jul 13 11:58:59 2007
@@ -426,6 +426,24 @@
   static bool classof(const MemberExpr *) { return true; }
 };
 
+/// ImplicitCastExpr - Allows us to explicitly represent implicit type 
+/// conversions. For example: converting T[]->T*, void f()->void (*f)(), 
+/// float->double, short->int, etc.
+///
+class ImplicitCastExpr : public Expr {
+  QualType Ty;
+  Expr *Op;
+public:
+  ImplicitCastExpr(QualType ty, Expr *op) : 
+    Expr(ImplicitCastExprClass, ty), Ty(ty), Op(op) {}
+    
+  virtual void visit(StmtVisitor &Visitor);
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == ImplicitCastExprClass; 
+  }
+  static bool classof(const ImplicitCastExpr *) { return true; }
+};
+
 /// CastExpr - [C99 6.5.4] Cast Operators.
 ///
 class CastExpr : public Expr {
@@ -435,9 +453,7 @@
 public:
   CastExpr(QualType ty, Expr *op, SourceLocation l) : 
     Expr(CastExprClass, ty), Ty(ty), Op(op), Loc(l) {}
-  CastExpr(StmtClass SC, QualType ty, Expr *op) : 
-    Expr(SC, QualType()), Ty(ty), Op(op), Loc(SourceLocation()) {}
-  
+
   SourceLocation getLParenLoc() const { return Loc; }
   
   QualType getDestType() const { return Ty; }

Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=39814&r1=39813&r2=39814&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Fri Jul 13 11:58:59 2007
@@ -58,14 +58,15 @@
 STMT(44, CastExpr             , Expr)
 STMT(45, BinaryOperator       , Expr)
 STMT(46, ConditionalOperator  , Expr)
+STMT(47, ImplicitCastExpr     , Expr)
 
 // GNU Extensions.
-STMT(47, AddrLabel            , Expr)
+STMT(48, AddrLabel            , Expr)
 
 // C++ Expressions.
-STMT(48, CXXCastExpr          , Expr)
-STMT(49, CXXBoolLiteralExpr   , Expr)
-LAST_EXPR(49)
+STMT(49, CXXCastExpr          , Expr)
+STMT(50, CXXBoolLiteralExpr   , Expr)
+LAST_EXPR(50)
 
 #undef STMT
 #undef FIRST_STMT





More information about the cfe-commits mailing list