[cfe-commits] r91368 - in /cfe/trunk/lib/Sema: SemaInit.cpp SemaInit.h

Douglas Gregor dgregor at apple.com
Mon Dec 14 16:01:57 PST 2009


Author: dgregor
Date: Mon Dec 14 18:01:57 2009
New Revision: 91368

URL: http://llvm.org/viewvc/llvm-project?rev=91368&view=rev
Log:
Implement value initialization in InitializationSequence; untested
WIP, yet again.

Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaInit.h

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Dec 14 18:01:57 2009
@@ -1970,6 +1970,7 @@
   case SK_QualificationConversionLValue:
   case SK_ListInitialization:
   case SK_ConstructorInitialization:
+  case SK_ZeroInitialization:
     break;
     
   case SK_ConversionSequence:
@@ -2048,6 +2049,13 @@
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddZeroInitializationStep(QualType T) {
+  Step S;
+  S.Kind = SK_ZeroInitialization;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::SetOverloadFailure(FailureKind Failure, 
                                                 OverloadingResult Result) {
   SequenceKind = FailedSequence;
@@ -2458,14 +2466,6 @@
   // FIXME: Implement!
 }
 
-/// \brief Attempt value initialization (C++ [dcl.init]p7).
-static void TryValueInitialization(Sema &S, 
-                                   const InitializedEntity &Entity,
-                                   const InitializationKind &Kind,
-                                   InitializationSequence &Sequence) {
-  // FIXME: Implement!
-}
-
 /// \brief Attempt initialization by constructor (C++ [dcl.init]), which
 /// enumerates the constructors of the initialized entity and performs overload
 /// resolution to select the best.
@@ -2473,6 +2473,7 @@
                                          const InitializedEntity &Entity,
                                          const InitializationKind &Kind,
                                          Expr **Args, unsigned NumArgs,
+                                         QualType DestType,
                                          InitializationSequence &Sequence) {
   Sequence.setSequenceKind(InitializationSequence::ConstructorInitialization);
   
@@ -2489,7 +2490,6 @@
   
   // The type we're converting to is a class type. Enumerate its constructors
   // to see if one is suitable.
-  QualType DestType = Entity.getType().getType();
   const RecordType *DestRecordType = DestType->getAs<RecordType>();
   assert(DestRecordType && "Constructor initialization requires record type");  
   CXXRecordDecl *DestRecordDecl
@@ -2540,6 +2540,41 @@
                                             DestType);
 }
 
+/// \brief Attempt value initialization (C++ [dcl.init]p7).
+static void TryValueInitialization(Sema &S, 
+                                   const InitializedEntity &Entity,
+                                   const InitializationKind &Kind,
+                                   InitializationSequence &Sequence) {
+  // C++ [dcl.init]p5:
+  //
+  //   To value-initialize an object of type T means:
+  QualType T = Entity.getType().getType();
+  
+  //     -- if T is an array type, then each element is value-initialized;
+  while (const ArrayType *AT = S.Context.getAsArrayType(T))
+    T = AT->getElementType();
+  
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      // -- if T is a class type (clause 9) with a user-declared
+      //    constructor (12.1), then the default constructor for T is
+      //    called (and the initialization is ill-formed if T has no
+      //    accessible default constructor);
+      //
+      // FIXME: we really want to refer to a single subobject of the array,
+      // but Entity doesn't have a way to capture that (yet).
+      if (ClassDecl->hasUserDeclaredConstructor())
+        return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);
+      
+      // FIXME: non-union class type w/ non-trivial default constructor gets
+      // zero-initialized, then constructor gets called.
+    }
+  }
+
+  Sequence.AddZeroInitializationStep(Entity.getType().getType());
+  Sequence.setSequenceKind(InitializationSequence::ZeroInitialization);
+}
+
 /// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]),
 /// which enumerates all conversion functions and performs overload resolution
 /// to select the best.
@@ -2776,7 +2811,8 @@
         (Kind.getKind() == InitializationKind::IK_Copy &&
          (Context.hasSameUnqualifiedType(SourceType, DestType) ||
           S.IsDerivedFrom(SourceType, DestType))))
-      TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, *this);
+      TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, 
+                                   Entity.getType().getType(), *this);
     //     - Otherwise (i.e., for the remaining copy-initialization cases), 
     //       user-defined conversion sequences that can convert from the source
     //       type to the destination type or (when a conversion function is 
@@ -3067,6 +3103,16 @@
       CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
       break;
     }
+        
+    case SK_ZeroInitialization: {
+      if (Kind.getKind() == InitializationKind::IK_Value)
+        CurInit = S.Owned(new (S.Context) CXXZeroInitValueExpr(Step->Type,
+                                                   Kind.getRange().getBegin(),
+                                                    Kind.getRange().getEnd()));
+      else
+        CurInit = S.Owned(new (S.Context) ImplicitValueInitExpr(Step->Type));
+      break;
+    }
     }
   }
   

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.h (original)
+++ cfe/trunk/lib/Sema/SemaInit.h Mon Dec 14 18:01:57 2009
@@ -269,7 +269,7 @@
   
   /// \brief Retrieve the source range that covers the initialization.
   SourceRange getRange() const { 
-    return SourceRange(Locations[0], Locations[1]);
+    return SourceRange(Locations[0], Locations[2]);
   }
   
   /// \brief Retrieve the location of the equal sign for copy initialization
@@ -293,6 +293,9 @@
 class InitializationSequence {
 public:
   /// \brief Describes the kind of initialization sequence computed.
+  ///
+  /// FIXME: Much of this information is in the initialization steps... why is
+  /// it duplicated here?
   enum SequenceKind {
     /// \brief A failed initialization sequence. The failure kind tells what
     /// happened.
@@ -313,7 +316,10 @@
     ReferenceBinding,
 
     /// \brief List initialization
-    ListInitialization
+    ListInitialization,
+    
+    /// \brief Zero-initialization.
+    ZeroInitialization
   };
   
   /// \brief Describes the kind of a particular step in an initialization
@@ -342,7 +348,9 @@
     /// \brief Perform list-initialization
     SK_ListInitialization,
     /// \brief Perform initialization via a constructor.
-    SK_ConstructorInitialization
+    SK_ConstructorInitialization,
+    /// \brief Zero-initialize the object
+    SK_ZeroInitialization
   };
   
   /// \brief A single step in the initialization sequence.
@@ -536,9 +544,12 @@
   /// \brief Add a list-initialiation step  
   void AddListInitializationStep(QualType T);
 
-  /// \brief Add a a constructor-initialization step.
+  /// \brief Add a constructor-initialization step.
   void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
                                         QualType T);
+
+  /// \brief Add a zero-initialization step.
+  void AddZeroInitializationStep(QualType T);
   
   /// \brief Note that this initialization sequence failed.
   void SetFailed(FailureKind Failure) {





More information about the cfe-commits mailing list