forked from OSchip/llvm-project
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
This commit is contained in:
parent
6c6729f3a8
commit
997d00dd13
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue