[cfe-commits] r39409 - in /cfe/cfe/trunk: AST/SemaExpr.cpp AST/Type.cpp Sema/SemaExpr.cpp include/clang/AST/ExprCXX.h include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def

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


Author: snaroff
Date: Wed Jul 11 11:44:03 2007
New Revision: 39409

URL: http://llvm.org/viewvc/llvm-project?rev=39409&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
- Added Type::isPromotableIntegerType().
- The unary operators are now largely complete (Sema::ParseUnaryOp and friends).
- Implemented ImplicitConversion hook (was a stub).

Modified:
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/AST/Type.cpp
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/cfe/trunk/include/clang/AST/Type.h
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:03 2007
@@ -180,9 +180,42 @@
     return CheckAddressOfOperand((Expr *)Input, OpLoc, Opc);
   else if (Opc == UnaryOperator::Deref) 
     return CheckIndirectionOperand((Expr *)Input, OpLoc, Opc);
-  
-  // when all the check functions are written, this will go away...
-  return new UnaryOperator((Expr*)Input, Opc, QualType());
+  else { 
+    // handle the arithmetic unary operators (C99 6.5.3.3)
+    QualType opType = ImplicitConversion((Expr *)Input)->getType();
+    assert(!opType.isNull() && "no type for arithmetic unary expression");
+    QualType resultType = opType;
+    
+    switch (Opc) {
+    case UnaryOperator::Plus:
+    case UnaryOperator::Minus:
+      if (!opType->isArithmeticType()) // C99 6.5.3.3p1
+        return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+      if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+        resultType = Context.IntTy;
+      break;
+    case UnaryOperator::Not: // bitwise complement
+      if (!opType->isIntegralType()) // C99 6.5.3.3p1
+        return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+      if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+        resultType = Context.IntTy;
+      break;
+    case UnaryOperator::LNot: // logical negation
+      if (!opType->isScalarType()) // C99 6.5.3.3p1
+        return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+      if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+        resultType = Context.IntTy;
+      break;
+    case UnaryOperator::SizeOf: // C99 6.5.3.4 TODO
+      break;
+    default: 
+      break;
+    }
+    return new UnaryOperator((Expr*)Input, Opc, resultType);
+  }
 }
 
 Action::ExprResult Sema::
@@ -392,12 +425,21 @@
   return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
 }
 
+/// ImplicitConversion - Performs various conversions that are common to most
+/// operators. At present, this routine only handles conversions that require
+/// synthesizing an expression/type. Arithmetic type promotions are done locally,
+/// since they don't require a new expression.
 Expr *Sema::ImplicitConversion(Expr *E) {
-#if 0
   QualType t = E->getType();
-  if (t != 0) t.dump();
-  else printf("no type for expr %s\n", E->getStmtClassName());
-#endif
+  assert(!t.isNull() && "no type for implicit conversion");
+  
+  if (t->isFunctionType()) // C99 6.3.2.1p4
+    return new UnaryOperator(E, UnaryOperator::AddrOf, Context.getPointerType(t));
+  else if (t->isArrayType()) { // C99 6.3.2.1p3
+    QualType elt = cast<ArrayType>(t)->getElementType();
+    QualType convertedType = Context.getPointerType(elt);
+    return new UnaryOperator(E, UnaryOperator::AddrOf, convertedType);
+  }
   return E;
 }
 

Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39409&r1=39408&r2=39409&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:44:03 2007
@@ -199,6 +199,24 @@
     return false;    
 }
 
+bool Type::isPromotableIntegerType() const {
+  if (CanonicalType->getTypeClass() == Builtin) {
+    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType.getTypePtr());
+    switch (BT->getKind()) {
+      case BuiltinType::Bool:
+      case BuiltinType::Char:
+      case BuiltinType::SChar:
+      case BuiltinType::UChar:
+      case BuiltinType::Short:
+      case BuiltinType::UShort:
+        return true;
+      default: 
+        return false;
+    }
+  }
+  return false;
+}
+
 /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
 /// does not have an incomplete type, does not have a const-qualified type, and
 /// if it is a structure or union, does not have any member (including, 

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:03 2007
@@ -180,9 +180,42 @@
     return CheckAddressOfOperand((Expr *)Input, OpLoc, Opc);
   else if (Opc == UnaryOperator::Deref) 
     return CheckIndirectionOperand((Expr *)Input, OpLoc, Opc);
-  
-  // when all the check functions are written, this will go away...
-  return new UnaryOperator((Expr*)Input, Opc, QualType());
+  else { 
+    // handle the arithmetic unary operators (C99 6.5.3.3)
+    QualType opType = ImplicitConversion((Expr *)Input)->getType();
+    assert(!opType.isNull() && "no type for arithmetic unary expression");
+    QualType resultType = opType;
+    
+    switch (Opc) {
+    case UnaryOperator::Plus:
+    case UnaryOperator::Minus:
+      if (!opType->isArithmeticType()) // C99 6.5.3.3p1
+        return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+      if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+        resultType = Context.IntTy;
+      break;
+    case UnaryOperator::Not: // bitwise complement
+      if (!opType->isIntegralType()) // C99 6.5.3.3p1
+        return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+      if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+        resultType = Context.IntTy;
+      break;
+    case UnaryOperator::LNot: // logical negation
+      if (!opType->isScalarType()) // C99 6.5.3.3p1
+        return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+      if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+        resultType = Context.IntTy;
+      break;
+    case UnaryOperator::SizeOf: // C99 6.5.3.4 TODO
+      break;
+    default: 
+      break;
+    }
+    return new UnaryOperator((Expr*)Input, Opc, resultType);
+  }
 }
 
 Action::ExprResult Sema::
@@ -392,12 +425,21 @@
   return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
 }
 
+/// ImplicitConversion - Performs various conversions that are common to most
+/// operators. At present, this routine only handles conversions that require
+/// synthesizing an expression/type. Arithmetic type promotions are done locally,
+/// since they don't require a new expression.
 Expr *Sema::ImplicitConversion(Expr *E) {
-#if 0
   QualType t = E->getType();
-  if (t != 0) t.dump();
-  else printf("no type for expr %s\n", E->getStmtClassName());
-#endif
+  assert(!t.isNull() && "no type for implicit conversion");
+  
+  if (t->isFunctionType()) // C99 6.3.2.1p4
+    return new UnaryOperator(E, UnaryOperator::AddrOf, Context.getPointerType(t));
+  else if (t->isArrayType()) { // C99 6.3.2.1p3
+    QualType elt = cast<ArrayType>(t)->getElementType();
+    QualType convertedType = Context.getPointerType(elt);
+    return new UnaryOperator(E, UnaryOperator::AddrOf, convertedType);
+  }
   return E;
 }
 

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/cfe/trunk/include/clang/AST/ExprCXX.h Wed Jul 11 11:44:03 2007
@@ -51,8 +51,6 @@
     CXXBoolLiteralExpr(bool val) : 
       Expr(CXXBoolLiteralExprClass, QualType()), Value(val) {}
       
-    virtual Expr *getPrimaryExpr() { return this; }
-
     virtual void visit(StmtVisitor &Visitor);
   };
 

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:44:03 2007
@@ -226,6 +226,9 @@
   bool isAggregateType() const;  // C99 6.2.5p21 (arrays, structures)
   
   bool isLvalue() const;         // C99 6.3.2.1
+  
+  /// Type Conversions/Promotions
+  bool isPromotableIntegerType() const; // C99 6.3.1.1p2
 private:
   // this forces clients to use isModifiableLvalue on QualType, the class that 
   // knows if the type is const. This predicate is a helper to QualType. 

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39409&r1=39408&r2=39409&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:44:03 2007
@@ -533,6 +533,8 @@
      "address of register variable requested")
 DIAG(err_typecheck_invalid_lvalue_addrof, ERROR,
      "invalid lvalue in address expression")
+DIAG(err_typecheck_unary_expr, ERROR,
+     "invalid argument type to unary expression '%s'")
 
 // Statements.
 DIAG(err_continue_not_in_loop, ERROR,





More information about the cfe-commits mailing list