[cfe-commits] r63317 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/StmtNodes.def lib/AST/Expr.cpp lib/AST/StmtPrinter.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CGExprComplex.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaInit.cpp test/CodeGen/designated-initializers.c

Douglas Gregor dgregor at apple.com
Thu Jan 29 09:44:32 PST 2009


Author: dgregor
Date: Thu Jan 29 11:44:32 2009
New Revision: 63317

URL: http://llvm.org/viewvc/llvm-project?rev=63317&view=rev
Log:
Introduce a new expression node, ImplicitValueInitExpr, that
represents an implicit value-initialization of a subobject of a
particular type. This replaces the (ab)use of CXXZeroValueInitExpr
within initializer lists for the "holes" that occur due to the use of
C99 designated initializers.

The new test case is currently XFAIL'd, because CodeGen's
ConstExprEmitter (in lib/CodeGen/CGExprConstant.cpp) needs to be
taught to value-initialize when it sees ImplicitValueInitExprs.


Added:
    cfe/trunk/test/CodeGen/designated-initializers.c
Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/StmtNodes.def
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprComplex.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Jan 29 11:44:32 2009
@@ -1645,7 +1645,7 @@
 /// initializations into the subobject they initialize. Additionally,
 /// any "holes" in the initialization, where no initializer has been
 /// specified for a particular subobject, will be replaced with
-/// implicitly-generated CXXZeroInitValueExpr expressions that
+/// implicitly-generated ImplicitValueInitExpr expressions that
 /// value-initialize the subobjects. Note, however, that the
 /// initializer lists may still have fewer initializers than there are
 /// elements to initialize within the object.
@@ -1987,6 +1987,31 @@
   virtual child_iterator child_end(); 
 };
 
+/// \brief Represents an implicitly-generated value initialization of
+/// an object of a given type.
+///
+/// Implicit value initializations occur within semantic initialize
+/// list expressions (\see InitListExpr) as placeholders for subobject
+/// initializations not explicitly specified by the user.
+class ImplicitValueInitExpr : public Expr { 
+public:
+  explicit ImplicitValueInitExpr(QualType ty) 
+    : Expr(ImplicitValueInitExprClass, ty) { }
+
+  static bool classof(const Stmt *T) { 
+    return T->getStmtClass() == ImplicitValueInitExprClass;
+  }
+  static bool classof(const ImplicitValueInitExpr *) { return true; }
+
+  virtual SourceRange getSourceRange() const {
+    return SourceRange();
+  }
+
+  // Iterators
+  virtual child_iterator child_begin();
+  virtual child_iterator child_end(); 
+};
+
 //===----------------------------------------------------------------------===//
 // Clang Extensions
 //===----------------------------------------------------------------------===//

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

==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Thu Jan 29 11:44:32 2009
@@ -86,6 +86,7 @@
 STMT(ExtVectorElementExpr  , Expr)
 STMT(InitListExpr          , Expr)
 STMT(DesignatedInitExpr    , Expr)
+STMT(ImplicitValueInitExpr , Expr)
 STMT(VAArgExpr             , Expr)
 
 // GNU Extensions.

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

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Jan 29 11:44:32 2009
@@ -735,6 +735,8 @@
     }
     return true;
   }
+  case ImplicitValueInitExprClass:
+    return true;
   case ParenExprClass: {
     return cast<ParenExpr>(this)->getSubExpr()->isConstantInitializer(Ctx);
   }
@@ -1672,7 +1674,7 @@
   return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0;
 }
 
-/// DesignatedInitExpr
+// DesignatedInitExpr
 Stmt::child_iterator DesignatedInitExpr::child_begin() {
   char* Ptr = static_cast<char*>(static_cast<void *>(this));
   Ptr += sizeof(DesignatedInitExpr);
@@ -1683,6 +1685,15 @@
   return child_iterator(&*child_begin() + NumSubExprs);
 }
 
+// ImplicitValueInitExpr
+Stmt::child_iterator ImplicitValueInitExpr::child_begin() { 
+  return child_iterator(); 
+}
+
+Stmt::child_iterator ImplicitValueInitExpr::child_end() { 
+  return child_iterator(); 
+}
+
 // ObjCStringLiteral
 Stmt::child_iterator ObjCStringLiteral::child_begin() { 
   return child_iterator();

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

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Thu Jan 29 11:44:32 2009
@@ -906,6 +906,10 @@
   PrintExpr(Node->getInit());
 }
 
+void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
+  OS << "/*implicit*/" << Node->getType().getAsString() << "()";
+}
+
 void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
   OS << "va_arg(";
   PrintExpr(Node->getSubExpr());

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=63317&r1=63316&r2=63317&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Jan 29 11:44:32 2009
@@ -339,10 +339,10 @@
 
 void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
   // FIXME: Are initializers affected by volatile?
-  if (E->getType()->isComplexType()) {
-    CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
-  } else if (isa<CXXZeroInitValueExpr>(E)) {
+  if (isa<ImplicitValueInitExpr>(E)) {
     EmitNullInitializationToLValue(LV, E->getType());
+  } else if (E->getType()->isComplexType()) {
+    CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
   } else if (CGF.hasAggregateLLVMType(E->getType())) {
     CGF.EmitAnyExpr(E, LV.getAddress(), false);
   } else {

Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=63317&r1=63316&r2=63317&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Thu Jan 29 11:44:32 2009
@@ -130,6 +130,12 @@
     llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
     return ComplexPairTy(Null, Null);
   }
+  ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+    assert(E->getType()->isAnyComplexType() && "Expected complex type!");
+    QualType Elem = E->getType()->getAsComplexType()->getElementType();
+    llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
+    return ComplexPairTy(Null, Null);
+  }
   
   struct BinOpInfo {
     ComplexPairTy LHS;

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=63317&r1=63316&r2=63317&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Thu Jan 29 11:44:32 2009
@@ -248,11 +248,6 @@
 
     FieldDecl* curField = ILE->getInitializedFieldInUnion();
     if (!curField) {
-#ifndef NDEBUG
-#endif
-    }
-
-    if (!curField) {
       // There's no field to initialize, so value-initialize the union.
 #ifndef NDEBUG
       // Make sure that it's really an empty and not a failure of

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=63317&r1=63316&r2=63317&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Jan 29 11:44:32 2009
@@ -200,6 +200,9 @@
     return V;
   }
   
+  Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
+    return llvm::Constant::getNullValue(ConvertType(E->getType()));
+  }
   Value *VisitImplicitCastExpr(const ImplicitCastExpr *E);
   Value *VisitCastExpr(const CastExpr *E) { 
     return EmitCastExpr(E->getSubExpr(), E->getType());

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 29 11:44:32 2009
@@ -2220,17 +2220,17 @@
   if (CompoundLiteralExpr *e = dyn_cast<CompoundLiteralExpr>(Init))
     return CheckForConstantInitializer(e->getInitializer(), DclT);
 
+  if (isa<ImplicitValueInitExpr>(Init)) {
+    // FIXME: In C++, check for non-POD types.
+    return false;
+  }
+
   if (InitListExpr *Exp = dyn_cast<InitListExpr>(Init)) {
     unsigned numInits = Exp->getNumInits();
     for (unsigned i = 0; i < numInits; i++) {
       // FIXME: Need to get the type of the declaration for C++,
       // because it could be a reference?
 
-      // Implicitly-generated value initializations are okay.
-      if (isa<CXXZeroInitValueExpr>(Exp->getInit(i)) &&
-          cast<CXXZeroInitValueExpr>(Exp->getInit(i))->isImplicit()) 
-        continue;
-
       if (CheckForConstantInitializer(Exp->getInit(i),
                                       Exp->getInit(i)->getType()))
         return true;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Jan 29 11:44:32 2009
@@ -17,7 +17,6 @@
 #include "clang/Parse/Designator.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
 #include <map>
 using namespace clang;
 
@@ -137,10 +136,9 @@
       // FIXME: Check for fields with reference type in C++?
       if (!ILE->getInit(Init))
         ILE->setInit(Init, 
-                     new (Context) CXXZeroInitValueExpr(Field->getType(), 
-                                                        SourceLocation(),
-                                                        SourceLocation()));
-      else if (InitListExpr *InnerILE = dyn_cast<InitListExpr>(ILE->getInit(Init)))
+                     new (Context) ImplicitValueInitExpr(Field->getType()));
+      else if (InitListExpr *InnerILE 
+                 = dyn_cast<InitListExpr>(ILE->getInit(Init)))
         fillInValueInitializations(Context, InnerILE);
       ++Init;
     }
@@ -160,9 +158,7 @@
   for (unsigned Init = 0, NumInits = ILE->getNumInits(); Init != NumInits; 
        ++Init) {
     if (!ILE->getInit(Init))
-      ILE->setInit(Init, new (Context) CXXZeroInitValueExpr(ElementType, 
-                                                            SourceLocation(),
-                                                            SourceLocation()));
+      ILE->setInit(Init, new (Context) ImplicitValueInitExpr(ElementType));
     else if (InitListExpr *InnerILE =dyn_cast<InitListExpr>(ILE->getInit(Init)))
       fillInValueInitializations(Context, InnerILE);
   }
@@ -550,6 +546,22 @@
     hadError = true;
     return;
   }    
+
+  if (DeclType->isUnionType() && IList->getNumInits() == 0) {
+    // Value-initialize the first named member of the union.
+    RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
+    for (RecordDecl::field_iterator FieldEnd = RD->field_end();
+         Field != FieldEnd; ++Field) {
+      if (Field->getDeclName()) {
+        StructuredList->setInitializedFieldInUnion(*Field);
+        break;
+      }
+    }
+    return;
+  }
+
+
+
   // If structDecl is a forward declaration, this loop won't do
   // anything except look at designated initializers; That's okay,
   // because an error should get printed out elsewhere. It might be

Added: cfe/trunk/test/CodeGen/designated-initializers.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/designated-initializers.c?rev=63317&view=auto

==============================================================================
--- cfe/trunk/test/CodeGen/designated-initializers.c (added)
+++ cfe/trunk/test/CodeGen/designated-initializers.c Thu Jan 29 11:44:32 2009
@@ -0,0 +1,17 @@
+// RUN: clang %s -emit-llvm -o -
+// XFAIL
+struct foo {
+    void *a;
+    int b;
+};
+
+union { int i; float f; } u = { };
+
+int main(int argc, char **argv)
+{
+  union { int i; float f; } u2 = { };
+    static struct foo foo = {
+        .b = 1024,
+    };
+}
+





More information about the cfe-commits mailing list