aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-10-29 00:13:59 +0000
committerDouglas Gregor <dgregor@apple.com>2008-10-29 00:13:59 +0000
commit27c8dc06f65d7abcf6a7e7f64a7960c9a150ca01 (patch)
tree11c0cafe9243e679b669258afcbf41260033c7be /lib/Sema/SemaDecl.cpp
parent1b450b092a053896e96f0355cf7c7cdc9bba9eab (diff)
Implement initialization of a reference (C++ [dcl.init.ref]) as part
of copy initialization. Other pieces of the puzzle: - Try/Perform-ImplicitConversion now handles implicit conversions that don't involve references. - Try/Perform-CopyInitialization uses CheckSingleAssignmentConstraints for C. PerformCopyInitialization is now used for all argument passing and returning values from a function. - Diagnose errors with declaring references and const values without an initializer. (Uses a new Action callback, ActOnUninitializedDecl). We do not yet have implicit conversion sequences for reference binding, which means that we don't have any overloading support for reference parameters yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58353 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 71c0ceb57f..78f0d8f8be 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -628,6 +628,13 @@ StringLiteral *Sema::IsStringLiteralInit(Expr *Init, QualType DeclType) {
}
bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType) {
+ // C++ [dcl.init.ref]p1:
+ // A variable declared to be a T&, that is “reference to type T”
+ // (8.3.2), shall be initialized by an object, or function, of
+ // type T or by an object that can be converted into a T.
+ if (DeclType->isReferenceType())
+ return CheckReferenceInit(Init, DeclType);
+
// C99 6.7.8p3: The type of the entity to be initialized shall be an array
// of unknown size ("[]") or an object type that is not a variable array type.
if (const VariableArrayType *VAT = Context.getAsVariableArrayType(DeclType))
@@ -1516,6 +1523,49 @@ void Sema::AddInitializerToDecl(DeclTy *dcl, ExprTy *init) {
return;
}
+void Sema::ActOnUninitializedDecl(DeclTy *dcl) {
+ Decl *RealDecl = static_cast<Decl *>(dcl);
+
+ if (VarDecl *Var = dyn_cast<VarDecl>(RealDecl)) {
+ QualType Type = Var->getType();
+ // C++ [dcl.init.ref]p3:
+ // The initializer can be omitted for a reference only in a
+ // parameter declaration (8.3.5), in the declaration of a
+ // function return type, in the declaration of a class member
+ // within its class declaration (9.2), and where the extern
+ // specifier is explicitly used.
+ if (Type->isReferenceType() && Var->getStorageClass() != VarDecl::Extern)
+ Diag(Var->getLocation(),
+ diag::err_reference_var_requires_init,
+ Var->getName(),
+ SourceRange(Var->getLocation(), Var->getLocation()));
+
+ // C++ [dcl.init]p9:
+ //
+ // If no initializer is specified for an object, and the
+ // object is of (possibly cv-qualified) non-POD class type (or
+ // array thereof), the object shall be default-initialized; if
+ // the object is of const-qualified type, the underlying class
+ // type shall have a user-declared default
+ // constructor. Otherwise, if no initializer is specified for
+ // an object, the object and its subobjects, if any, have an
+ // indeterminate initial value; if the object or any of its
+ // subobjects are of const-qualified type, the program is
+ // ill-formed.
+ //
+ // This isn't technically an error in C, so we don't diagnose it.
+ //
+ // FIXME: Actually perform the POD/user-defined default
+ // constructor check.
+ if (getLangOptions().CPlusPlus &&
+ Context.getCanonicalType(Type).isConstQualified())
+ Diag(Var->getLocation(),
+ diag::err_const_var_requires_init,
+ Var->getName(),
+ SourceRange(Var->getLocation(), Var->getLocation()));
+ }
+}
+
/// The declarators are chained together backwards, reverse the list.
Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) {
// Often we have single declarators, handle them quickly.