diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-10-06 23:08:37 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-10-06 23:08:37 +0000 |
commit | 997d00dd13e30faf7fad55404c47745e89b4b4e0 (patch) | |
tree | 85d1a42b8f63aef55a65f1d2b82038b0a90b5ef1 | |
parent | 6c6729f3a8bbdc1d6abdd46f3eb106ca5e2d59c1 (diff) | |
download | llvm-997d00dd13e30faf7fad55404c47745e89b4b4e0.tar.gz |
Simplify handling of direct initializers by letting Sema::AddInitializerToDecl handle conversions, instead of using Sema::ActOnCXXTypeConstructExpr.
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 ;".
llvm-svn: 57219
-rw-r--r-- | clang/include/clang/AST/Decl.h | 14 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticKinds.def | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 29 |
3 files changed, 18 insertions, 27 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 323fe2a5ea2a..b0acc4c1b7a7 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -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; diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 1d62c8d64cfa..87b2baa25447 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -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 diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index edc0a3db6fb7..4d8c16bf53e5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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]); } |