]> granicus.if.org Git - clang/commitdiff
Simplify handling of direct initializers by letting Sema::AddInitializerToDecl handle...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 6 Oct 2008 23:08:37 +0000 (23:08 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 6 Oct 2008 23:08:37 +0000 (23:08 +0000)
Additional benefit is that diagnostics are the same for both direct-initialization and copy-initialization.

In the case of "int x( expression );":
-The Init expression of VarDecl 'x' will be the expression inside the parentheses.
-VarDecl::hasCXXDirectInitializer for VarDecl 'x' will return true to let clients distinguish from "int x = expression ;".

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57219 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
include/clang/Basic/DiagnosticKinds.def
lib/Sema/SemaDeclCXX.cpp

index 323fe2a5ea2ae41ddc6634901e3766ad0b2d3a48..b0acc4c1b7a706763c60bf4eee370731fabde2ab 100644 (file)
@@ -263,16 +263,10 @@ public:
   void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; }
 
   /// hasCXXDirectInitializer - If true, the initializer was a direct
-  /// initializer, e.g: "int x(1);". The Init expression will be an expression
-  /// that constructs the type with functional notation, e.g. for:
-  ///
-  ///     int x(1);
-  ///
-  /// hasCXXDirectInitializer will be true,
-  /// Init expression will be a "int(1)" functional-cast expression.
-  ///
-  /// Clients can distinguish between "int x(1);" and "int x = int(1);" by
-  /// checking hasCXXDirectInitializer.
+  /// initializer, e.g: "int x(1);". The Init expression will be the expression
+  /// inside the parens or a "ClassType(a,b,c)" class constructor expression for
+  /// class types. Clients can distinguish between "int x(1);" and "int x=1;"
+  /// by checking hasCXXDirectInitializer.
   ///
   bool hasCXXDirectInitializer() const {
     return HasCXXDirectInit;
index 1d62c8d64cfad2113e7fa28a6dddbe14502df0ad..87b2baa254479c5de286ae66a03b45d3a7a2aa12 100644 (file)
@@ -1018,6 +1018,8 @@ DIAG(err_invalid_incomplete_type_use, ERROR,
      "invalid use of incomplete type '%0'")
 DIAG(err_builtin_func_cast_more_than_one_arg, ERROR,
      "function-style cast to a builtin type can only take one argument")
+DIAG(err_builtin_direct_init_more_than_one_arg, ERROR,
+     "initializer of a builtin type can only take one argument")
 DIAG(err_value_init_for_array_type, ERROR,
      "array types cannot be value-initialized")
 // Temporary
index edc0a3db6fb7bd36e6fb989ec9e830af1b98c81d..4d8c16bf53e526ec952419b60e7c6695dc4c8a70 100644 (file)
@@ -558,8 +558,8 @@ void Sema::AddCXXDirectInitializerToDecl(DeclTy *Dcl, SourceLocation LParenLoc,
                                          ExprTy **ExprTys, unsigned NumExprs,
                                          SourceLocation *CommaLocs,
                                          SourceLocation RParenLoc) {
-  Decl *RealDecl = static_cast<Decl *>(Dcl);
   assert(NumExprs != 0 && ExprTys && "missing expressions");
+  Decl *RealDecl = static_cast<Decl *>(Dcl);
 
   // If there is no declaration, there was an error parsing it.  Just ignore
   // the initializer.
@@ -576,11 +576,8 @@ void Sema::AddCXXDirectInitializerToDecl(DeclTy *Dcl, SourceLocation LParenLoc,
     return;
   }
 
-  // We will treat direct-initialization as a copy-initialization with a
-  // type-construction expression of the variable's type. In plain english:
-  // We will treat:
-  //    int x(1);  -as-> int x = int(1);
-  // and for class types:
+  // We will treat direct-initialization as a copy-initialization:
+  //    int x(1);  -as-> int x = 1;
   //    ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
   //
   // Clients that want to distinguish between the two forms, can check for
@@ -594,9 +591,9 @@ void Sema::AddCXXDirectInitializerToDecl(DeclTy *Dcl, SourceLocation LParenLoc,
   // insignificant, but does matter when the entity being initialized has a
   // class type.
 
-  // FIXME: When constructors for class types are supported, determine how 
-  // exactly semantic checking will be done for direct initializers.
   if (VDecl->getType()->isRecordType()) {
+    // FIXME: When constructors for class types are supported, determine how 
+    // exactly semantic checking will be done for direct initializers.
     unsigned DiagID = PP.getDiagnostics().getCustomDiagID(Diagnostic::Error,
                            "initialization for class types is not handled yet");
     Diag(VDecl->getLocation(), DiagID);
@@ -604,19 +601,17 @@ void Sema::AddCXXDirectInitializerToDecl(DeclTy *Dcl, SourceLocation LParenLoc,
     return;
   }
 
-  // Get an expression for constructing the type of the variable, using the
-  // expression list of the initializer.
-  ExprResult Res = ActOnCXXTypeConstructExpr(VDecl->getLocation(),
-                                             VDecl->getType().getAsOpaquePtr(),
-                                             LParenLoc, ExprTys, NumExprs,
-                                             CommaLocs, RParenLoc);
-  if (Res.isInvalid) {
+  if (NumExprs > 1) {
+    Diag(CommaLocs[0], diag::err_builtin_direct_init_more_than_one_arg,
+         SourceRange(VDecl->getLocation(), RParenLoc));
     RealDecl->setInvalidDecl();
     return;
   }
 
-  // Performs additional semantic checks.
-  AddInitializerToDecl(Dcl, Res.Val);
   // Let clients know that initialization was done with a direct initializer.
   VDecl->setCXXDirectInitializer(true);
+
+  assert(NumExprs == 1 && "Expected 1 expression");
+  // Set the init expression, handles conversions.
+  AddInitializerToDecl(Dcl, ExprTys[0]);
 }