]> granicus.if.org Git - clang/commitdiff
Switch Sema::AddCXXDirectInitializerToDecl over to InitializationSequence
authorDouglas Gregor <dgregor@apple.com>
Tue, 22 Dec 2009 22:17:25 +0000 (22:17 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 22 Dec 2009 22:17:25 +0000 (22:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91927 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp
test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp
test/SemaCXX/copy-constructor-error.cpp
test/SemaCXX/default2.cpp
test/SemaCXX/direct-initializer.cpp
utils/C++Tests/LLVM-Code-Compile/lit.local.cfg
utils/C++Tests/LLVM-Code-Syntax/lit.local.cfg

index 2d86b5e1b675f36f0bb34f006b9c31d5161aee27..87a33642a0fb49415f01c144ed821dab2a5dbcc1 100644 (file)
@@ -1985,7 +1985,7 @@ public:
   /// non-empty, will create a new CXXExprWithTemporaries expression.
   /// Otherwise, just returs the passed in expression.
   Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr);
-
+  OwningExprResult MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr);
   FullExpr CreateFullExpr(Expr *SubExpr);
   
   virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr);
index dfb353281054b3672195d124a762b1815e1a4cfa..9e30af8f18789098ebe4cc0381f0b27be8c97602 100644 (file)
@@ -3927,53 +3927,50 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
   if (const ArrayType *Array = Context.getAsArrayType(DeclInitType))
     DeclInitType = Context.getBaseElementType(Array);
 
-  // FIXME: This isn't the right place to complete the type.
   if (RequireCompleteType(VDecl->getLocation(), VDecl->getType(),
                           diag::err_typecheck_decl_incomplete_type)) {
     VDecl->setInvalidDecl();
     return;
   }
 
-  if (VDecl->getType()->isRecordType()) {
-    ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
-    
-    CXXConstructorDecl *Constructor
-      = PerformInitializationByConstructor(DeclInitType,
-                                           move(Exprs),
-                                           VDecl->getLocation(),
-                                           SourceRange(VDecl->getLocation(),
-                                                       RParenLoc),
-                                           VDecl->getDeclName(),
-                      InitializationKind::CreateDirect(VDecl->getLocation(), 
-                                                       LParenLoc, 
-                                                       RParenLoc),
-                                           ConstructorArgs);
-    if (!Constructor)
-      RealDecl->setInvalidDecl();
-    else {
-      VDecl->setCXXDirectInitializer(true);
-      if (InitializeVarWithConstructor(VDecl, Constructor, 
-                                       move_arg(ConstructorArgs)))
-        RealDecl->setInvalidDecl();
-      FinalizeVarWithDestructor(VDecl, DeclInitType);
-    }
+  // The variable can not have an abstract class type.
+  if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
+                             diag::err_abstract_type_in_decl,
+                             AbstractVariableType))
+    VDecl->setInvalidDecl();
+
+  const VarDecl *Def = 0;
+  if (VDecl->getDefinition(Def)) {
+    Diag(VDecl->getLocation(), diag::err_redefinition)
+    << VDecl->getDeclName();
+    Diag(Def->getLocation(), diag::note_previous_definition);
+    VDecl->setInvalidDecl();
     return;
   }
-
-  if (NumExprs > 1) {
-    Diag(CommaLocs[0], diag::err_builtin_direct_init_more_than_one_arg)
-      << SourceRange(VDecl->getLocation(), RParenLoc);
-    RealDecl->setInvalidDecl();
+  
+  // Capture the variable that is being initialized and the style of
+  // initialization.
+  InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
+  
+  // FIXME: Poor source location information.
+  InitializationKind Kind
+    = InitializationKind::CreateDirect(VDecl->getLocation(),
+                                       LParenLoc, RParenLoc);
+  
+  InitializationSequence InitSeq(*this, Entity, Kind, 
+                                 (Expr**)Exprs.get(), Exprs.size());
+  OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs));
+  if (Result.isInvalid()) {
+    VDecl->setInvalidDecl();
     return;
   }
-
-  // Let clients know that initialization was done with a direct initializer.
+  
+  Result = MaybeCreateCXXExprWithTemporaries(move(Result));
+  VDecl->setInit(Context, Result.takeAs<Expr>());
   VDecl->setCXXDirectInitializer(true);
 
-  assert(NumExprs == 1 && "Expected 1 expression");
-  // Set the init expression, handles conversions.
-  AddInitializerToDecl(Dcl, ExprArg(*this, Exprs.release()[0]),
-                       /*DirectInit=*/true);
+  if (VDecl->getType()->getAs<RecordType>())
+    FinalizeVarWithDestructor(VDecl, DeclInitType);
 }
 
 /// \brief Add the applicable constructor candidates for an initialization
index 92a94daea6f3aca472c83a4fbf279b1843599676..dd3d2ea2ce4f2238a137446a735df88c67ed3ea6 100644 (file)
@@ -2097,6 +2097,14 @@ Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr) {
   return E;
 }
 
+Sema::OwningExprResult 
+Sema::MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr) {
+  if (SubExpr.isInvalid())
+    return ExprError();
+  
+  return Owned(MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>()));
+}
+
 FullExpr Sema::CreateFullExpr(Expr *SubExpr) {
   unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries;
   assert(ExprTemporaries.size() >= FirstTemporary);
index 2ed87b4e68ccf892964be9473b18d99b12971c21..0fa4f650b0bb3516c7770688a50888ef1dc1df65 100644 (file)
@@ -15,4 +15,4 @@ namespace N {
 
 int i = 2; 
 N::S N::j = i;
-N::S N::j(i);
+N::S N::j2(i);
index bdf635d02f24d3bd678f1a81951ef958a37b1aa8..9cae77504b514a3597ecfe03daa35102239f903a 100644 (file)
@@ -1,13 +1,12 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s 
 
-struct S { // expected-note {{candidate function}} 
-   S (S);  // expected-error {{copy constructor must pass its first argument by reference}} \\
-           // expected-note {{candidate function}}
+struct S {
+   S (S);  // expected-error {{copy constructor must pass its first argument by reference}}
 };
 
 S f();
 
 void g() { 
-  S a( f() );  // expected-error {{call to constructor of 'a' is ambiguous}}
+  S a( f() );
 }
 
index eda4be29192d6d01809da66a357b6eb08e21533a..880255e4531b1005274743ce8287c0a5a161e384 100644 (file)
@@ -90,12 +90,12 @@ public:
   }
 
   void test_Z(const Z& z) {
-    Z z2(z); // expected-error{{no matching constructor for initialization of 'z2'}}
+    Z z2(z); // expected-error{{no matching constructor for initialization of 'class Z'}}
   }
 };
 
 void test_Z(const Z& z) {
-  Z z2(z); // expected-error{{no matching constructor for initialization of 'z2'}}
+  Z z2(z); // expected-error{{no matching constructor for initialization of 'class Z'}}
 }
 
 struct ZZ {
index 1a87a3edf334d0be16a31007431f564d3df2a08e..03a5da3a303b2226e1dd3e9aa59c2f44e8ce3e12 100644 (file)
@@ -28,7 +28,7 @@ public:
 void g() {
   X x1(5);
   X x2(1.0, 3, 4.2);
-  X x3(1.0, 1.0); // expected-error{{no matching constructor for initialization of 'x3'; candidates are:}}
+  X x3(1.0, 1.0); // expected-error{{no matching constructor for initialization of 'class X'}}
   Y y(1.0);
   X x4(3.14, y);
 
index 6676e311e3ecd016edb355e375675c91510c6311..b9931144a3d97f051bf0642fa2b47e8ed20ec981 100644 (file)
@@ -11,6 +11,7 @@ root = getRoot(config)
 
 # testFormat: The test format to use to interpret tests.
 target_obj_root = root.llvm_obj_root
+target_obj_root = '/Users/dgregor/Projects/llvm-build-autotools'
 cxxflags = ['-D__STDC_LIMIT_MACROS',
             '-D__STDC_CONSTANT_MACROS',
             '-Wno-sign-compare',
index 6e679659c44c916e4e3fc5974f5b64b68b5dd8da..edcd266fe529a44c774be01aa4669e4d0412c3d3 100644 (file)
@@ -11,6 +11,7 @@ root = getRoot(config)
 
 # testFormat: The test format to use to interpret tests.
 target_obj_root = root.llvm_obj_root
+target_obj_root = '/Users/dgregor/Projects/llvm-build-autotools'
 cxxflags = ['-D__STDC_LIMIT_MACROS',
             '-D__STDC_CONSTANT_MACROS',
             '-I%s/include' % root.llvm_src_root,