[cfe-commits] r146673 - /cfe/trunk/lib/Sema/SemaDecl.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Thu Dec 15 11:20:59 PST 2011
Author: rsmith
Date: Thu Dec 15 13:20:59 2011
New Revision: 146673
URL: http://llvm.org/viewvc/llvm-project?rev=146673&view=rev
Log:
Refactor and simplify AddInitializerToDecl.
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=146673&r1=146672&r2=146673&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Dec 15 13:20:59 2011
@@ -5946,7 +5946,7 @@
return;
}
- // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
+ // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
TypeSourceInfo *DeducedType = 0;
if (!DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType))
@@ -5969,7 +5969,14 @@
if (VarDecl *Old = VDecl->getPreviousDeclaration())
MergeVarDeclTypes(VDecl, Old);
}
-
+
+ if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) {
+ // C99 6.7.8p5. C++ has no such restriction, but that is a defect.
+ Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
+ VDecl->setInvalidDecl();
+ return;
+ }
+
// A definition must end up with a complete type, which means it must be
// complete with the restriction that an array type might be completed by the
@@ -6036,44 +6043,58 @@
return;
}
- // Capture the variable that is being initialized and the style of
- // initialization.
- InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
-
- // FIXME: Poor source location information.
- InitializationKind Kind
- = DirectInit? InitializationKind::CreateDirect(VDecl->getLocation(),
- Init->getLocStart(),
- Init->getLocEnd())
- : InitializationKind::CreateCopy(VDecl->getLocation(),
- Init->getLocStart());
-
// Get the decls type and save a reference for later, since
// CheckInitializerTypes may change it.
QualType DclT = VDecl->getType(), SavT = DclT;
- if (VDecl->isLocalVarDecl()) {
- if (VDecl->hasExternalStorage()) { // C99 6.7.8p5
- Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
+
+ // Perform the initialization.
+ if (!VDecl->isInvalidDecl()) {
+ InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
+ InitializationKind Kind
+ = DirectInit ? InitializationKind::CreateDirect(VDecl->getLocation(),
+ Init->getLocStart(),
+ Init->getLocEnd())
+ : InitializationKind::CreateCopy(VDecl->getLocation(),
+ Init->getLocStart());
+
+ InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, &Init, 1),
+ &DclT);
+ if (Result.isInvalid()) {
VDecl->setInvalidDecl();
- } else if (!VDecl->isInvalidDecl()) {
- InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, &Init, 1),
- &DclT);
- if (Result.isInvalid()) {
- VDecl->setInvalidDecl();
- return;
- }
+ return;
+ }
- Init = Result.takeAs<Expr>();
+ Init = Result.takeAs<Expr>();
+ }
- // C++ 3.6.2p2, allow dynamic initialization of static initializers.
- // Don't check invalid declarations to avoid emitting useless diagnostics.
- if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
- if (VDecl->getStorageClass() == SC_Static) // C99 6.7.8p4.
- CheckForConstantInitializer(Init, DclT);
- }
- }
+ // If the type changed, it means we had an incomplete type that was
+ // completed by the initializer. For example:
+ // int ary[] = { 1, 3, 5 };
+ // "ary" transitions from a VariableArrayType to a ConstantArrayType.
+ if (!VDecl->isInvalidDecl() && (DclT != SavT)) {
+ VDecl->setType(DclT);
+ Init->setType(DclT.getNonReferenceType());
+ }
+
+ // Check any implicit conversions within the expression.
+ CheckImplicitConversions(Init, VDecl->getLocation());
+
+ if (!VDecl->isInvalidDecl())
+ checkUnsafeAssigns(VDecl->getLocation(), VDecl->getType(), Init);
+
+ Init = MaybeCreateExprWithCleanups(Init);
+ // Attach the initializer to the decl.
+ VDecl->setInit(Init);
+
+ if (VDecl->isLocalVarDecl()) {
+ // C99 6.7.8p4: All the expressions in an initializer for an object that has
+ // static storage duration shall be constant expressions or string literals.
+ // C++ does not have this restriction.
+ if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl() &&
+ VDecl->getStorageClass() == SC_Static)
+ CheckForConstantInitializer(Init, DclT);
} else if (VDecl->isStaticDataMember() &&
VDecl->getLexicalDeclContext()->isRecord()) {
// This is an in-class initialization for a static data member, e.g.,
@@ -6082,26 +6103,12 @@
// static const int value = 17;
// };
- // Try to perform the initialization regardless.
- if (!VDecl->isInvalidDecl()) {
- InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, &Init, 1),
- &DclT);
- if (Result.isInvalid()) {
- VDecl->setInvalidDecl();
- return;
- }
-
- Init = Result.takeAs<Expr>();
- }
-
// C++ [class.mem]p4:
// A member-declarator can contain a constant-initializer only
// if it declares a static member (9.4) of const integral or
// const enumeration type, see 9.4.2.
//
- // C++0x [class.static.data]p3:
+ // C++11 [class.static.data]p3:
// If a non-volatile const static data member is of integral or
// enumeration type, its declaration in the class definition can
// specify a brace-or-equal-initializer in which every initalizer-clause
@@ -6110,10 +6117,9 @@
// with the constexpr specifier; if so, its declaration shall specify a
// brace-or-equal-initializer in which every initializer-clause that is
// an assignment-expression is a constant expression.
- QualType T = VDecl->getType();
// Do nothing on dependent types.
- if (T->isDependentType()) {
+ if (DclT->isDependentType()) {
// Allow any 'static constexpr' members, whether or not they are of literal
// type. We separately check that the initializer is a constant expression,
@@ -6121,17 +6127,17 @@
} else if (VDecl->isConstexpr()) {
// Require constness.
- } else if (!T.isConstQualified()) {
+ } else if (!DclT.isConstQualified()) {
Diag(VDecl->getLocation(), diag::err_in_class_initializer_non_const)
<< Init->getSourceRange();
VDecl->setInvalidDecl();
// We allow integer constant expressions in all cases.
- } else if (T->isIntegralOrEnumerationType()) {
+ } else if (DclT->isIntegralOrEnumerationType()) {
// Check whether the expression is a constant expression.
SourceLocation Loc;
- if (getLangOptions().CPlusPlus0x && T.isVolatileQualified())
- // In C++0x, a non-constexpr const static data member with an
+ if (getLangOptions().CPlusPlus0x && DclT.isVolatileQualified())
+ // In C++11, a non-constexpr const static data member with an
// in-class initializer cannot be volatile.
Diag(VDecl->getLocation(), diag::err_in_class_initializer_volatile);
else if (Init->isValueDependent())
@@ -6151,77 +6157,43 @@
VDecl->setInvalidDecl();
}
- // We allow floating-point constants as an extension.
- } else if (T->isFloatingType()) { // also permits complex, which is ok
+ // We allow foldable floating-point constants as an extension.
+ } else if (DclT->isFloatingType()) { // also permits complex, which is ok
Diag(VDecl->getLocation(), diag::ext_in_class_initializer_float_type)
- << T << Init->getSourceRange();
+ << DclT << Init->getSourceRange();
if (getLangOptions().CPlusPlus0x)
Diag(VDecl->getLocation(),
diag::note_in_class_initializer_float_type_constexpr)
<< FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr ");
- if (!Init->isValueDependent() &&
- !Init->isConstantInitializer(Context, false)) {
+ if (!Init->isValueDependent() && !Init->isEvaluatable(Context)) {
Diag(Init->getExprLoc(), diag::err_in_class_initializer_non_constant)
<< Init->getSourceRange();
VDecl->setInvalidDecl();
}
- // Suggest adding 'constexpr' in C++0x for literal types.
- } else if (getLangOptions().CPlusPlus0x && T->isLiteralType()) {
+ // Suggest adding 'constexpr' in C++11 for literal types.
+ } else if (getLangOptions().CPlusPlus0x && DclT->isLiteralType()) {
Diag(VDecl->getLocation(), diag::err_in_class_initializer_literal_type)
- << T << Init->getSourceRange()
+ << DclT << Init->getSourceRange()
<< FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr ");
VDecl->setConstexpr(true);
} else {
Diag(VDecl->getLocation(), diag::err_in_class_initializer_bad_type)
- << T << Init->getSourceRange();
+ << DclT << Init->getSourceRange();
VDecl->setInvalidDecl();
}
} else if (VDecl->isFileVarDecl()) {
- if (VDecl->getStorageClassAsWritten() == SC_Extern &&
- (!getLangOptions().CPlusPlus ||
+ if (VDecl->getStorageClassAsWritten() == SC_Extern &&
+ (!getLangOptions().CPlusPlus ||
!Context.getBaseElementType(VDecl->getType()).isConstQualified()))
Diag(VDecl->getLocation(), diag::warn_extern_init);
- if (!VDecl->isInvalidDecl()) {
- InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, &Init, 1),
- &DclT);
- if (Result.isInvalid()) {
- VDecl->setInvalidDecl();
- return;
- }
- Init = Result.takeAs<Expr>();
- }
-
- // C++ 3.6.2p2, allow dynamic initialization of static initializers.
- // Don't check invalid declarations to avoid emitting useless diagnostics.
- if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
- // C99 6.7.8p4. All file scoped initializers need to be constant.
+ // C99 6.7.8p4. All file scoped initializers need to be constant.
+ if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl())
CheckForConstantInitializer(Init, DclT);
- }
- }
- // If the type changed, it means we had an incomplete type that was
- // completed by the initializer. For example:
- // int ary[] = { 1, 3, 5 };
- // "ary" transitions from a VariableArrayType to a ConstantArrayType.
- if (!VDecl->isInvalidDecl() && (DclT != SavT)) {
- VDecl->setType(DclT);
- Init->setType(DclT.getNonReferenceType());
}
-
- // Check any implicit conversions within the expression.
- CheckImplicitConversions(Init, VDecl->getLocation());
-
- if (!VDecl->isInvalidDecl())
- checkUnsafeAssigns(VDecl->getLocation(), VDecl->getType(), Init);
-
- Init = MaybeCreateExprWithCleanups(Init);
- // Attach the initializer to the decl.
- VDecl->setInit(Init);
CheckCompleteVariableDeclaration(VDecl);
}
More information about the cfe-commits
mailing list