]> granicus.if.org Git - clang/commitdiff
Add CK_ToUnion and use it for aggregate expression codegen.
authorAnders Carlsson <andersca@mac.com>
Fri, 7 Aug 2009 23:22:37 +0000 (23:22 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 7 Aug 2009 23:22:37 +0000 (23:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78429 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/CodeGen/CGExprAgg.cpp
lib/Sema/SemaExpr.cpp

index e65a842d3fdaa9bb7baa5d4f37b4c0621f8ee6b5..0c884d88b7efc0f018314008d00eb43fe543e470 100644 (file)
@@ -1178,7 +1178,10 @@ public:
     CK_DerivedToBase,
     
     /// CK_Dynamic - Dynamic cast.
-    CK_Dynamic
+    CK_Dynamic,
+    
+    /// CK_ToUnion - Cast to union (GCC extension).
+    CK_ToUnion
   };
   
 private:
index ea0057e40ffa2d749896a129ddb3da374dc2fb4f..b0d91aa916dca985ba8767a2cfe4ff13aa43b22d 100644 (file)
@@ -86,8 +86,7 @@ public:
   }
   
   // Operators.
-  void VisitCStyleCastExpr(CStyleCastExpr *E);
-  void VisitImplicitCastExpr(ImplicitCastExpr *E);
+  void VisitCastExpr(CastExpr *E);
   void VisitCallExpr(const CallExpr *E);
   void VisitStmtExpr(const StmtExpr *E);
   void VisitBinaryOperator(const BinaryOperator *BO);
@@ -166,9 +165,9 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
 //                            Visitor Methods
 //===----------------------------------------------------------------------===//
 
-void AggExprEmitter::VisitCStyleCastExpr(CStyleCastExpr *E) {
-  // GCC union extension
-  if (E->getSubExpr()->getType()->isScalarType()) {
+void AggExprEmitter::VisitCastExpr(CastExpr *E) {
+  if (E->getCastKind() == CastExpr::CK_ToUnion) {
+    // GCC union extension
     QualType PtrTy =
         CGF.getContext().getPointerType(E->getSubExpr()->getType());
     llvm::Value *CastPtr = Builder.CreateBitCast(DestPtr,
@@ -178,10 +177,10 @@ void AggExprEmitter::VisitCStyleCastExpr(CStyleCastExpr *E) {
     return;
   }
 
-  Visit(E->getSubExpr());
-}
-
-void AggExprEmitter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
+  // FIXME: Remove the CK_Unknown check here.
+  assert((E->getCastKind() == CastExpr::CK_NoOp || 
+          E->getCastKind() == CastExpr::CK_Unknown) && 
+         "Only no-op casts allowed!");
   assert(CGF.getContext().hasSameUnqualifiedType(E->getSubExpr()->getType(),
                                                  E->getType()) &&
          "Implicit cast types must be compatible");
index 684c2dafdbaf36430c3677b8da87dcc9087d869b..6f75b59c30513af4309d53871357f59f0d02edfd 100644 (file)
@@ -2990,6 +2990,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
       // FIXME: Check that the cast destination type is complete.
       Diag(TyR.getBegin(), diag::ext_typecheck_cast_nonscalar)
         << castType << castExpr->getSourceRange();
+      Kind = CastExpr::CK_NoOp;
     } else if (castType->isUnionType()) {
       // GCC cast to union extension
       RecordDecl *RD = castType->getAs<RecordType>()->getDecl();
@@ -3006,6 +3007,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
       if (Field == FieldEnd)
         return Diag(TyR.getBegin(), diag::err_typecheck_cast_to_union_no_type)
           << castExpr->getType() << castExpr->getSourceRange();
+      Kind = CastExpr::CK_ToUnion;
     } else {
       // Reject any other conversions to non-scalar types.
       return Diag(TyR.getBegin(), diag::err_typecheck_cond_expect_scalar)