blob: 42f9b14085e100a93fdf5d673c2789590bfc7eb1 [file] [log] [blame]
Steve Naroffc4d4a482008-05-01 22:18:59 +00001//===--- SemaInit.cpp - Semantic Analysis for Initializers ----------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements semantic analysis for initializers.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Sema.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Expr.h"
Daniel Dunbar8d03cbe2008-08-11 03:27:53 +000017#include "clang/Basic/Diagnostic.h"
Steve Naroffc4d4a482008-05-01 22:18:59 +000018
19namespace clang {
20
21InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
22 hadError = false;
23 SemaRef = S;
Eli Friedmand8535af2008-05-19 20:00:43 +000024
Eli Friedman683cedf2008-05-19 19:16:24 +000025 unsigned newIndex = 0;
Eli Friedmand8535af2008-05-19 20:00:43 +000026
Eli Friedman683cedf2008-05-19 19:16:24 +000027 CheckExplicitInitList(IL, T, newIndex);
Steve Naroffc4d4a482008-05-01 22:18:59 +000028}
29
30int InitListChecker::numArrayElements(QualType DeclType) {
Eli Friedman46f81662008-05-25 13:22:35 +000031 // FIXME: use a proper constant
32 int maxElements = 0x7FFFFFFF;
Chris Lattnera1923f62008-08-04 07:31:14 +000033 if (const ConstantArrayType *CAT =
34 SemaRef->Context.getAsConstantArrayType(DeclType)) {
Steve Naroffc4d4a482008-05-01 22:18:59 +000035 maxElements = static_cast<int>(CAT->getSize().getZExtValue());
36 }
37 return maxElements;
38}
39
40int InitListChecker::numStructUnionElements(QualType DeclType) {
41 RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
Eli Friedman9f5250b2008-05-25 14:03:31 +000042 int InitializableMembers = 0;
43 for (int i = 0; i < structDecl->getNumMembers(); i++)
44 if (structDecl->getMember(i)->getIdentifier())
45 ++InitializableMembers;
Argiris Kirtzidisc6cc7d52008-06-09 23:19:58 +000046 if (structDecl->isUnion())
Eli Friedman9f5250b2008-05-25 14:03:31 +000047 return std::min(InitializableMembers, 1);
48 return InitializableMembers - structDecl->hasFlexibleArrayMember();
Steve Naroffc4d4a482008-05-01 22:18:59 +000049}
50
51void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
52 QualType T, unsigned &Index) {
53 llvm::SmallVector<Expr*, 4> InitExprs;
54 int maxElements = 0;
55
56 if (T->isArrayType())
57 maxElements = numArrayElements(T);
58 else if (T->isStructureType() || T->isUnionType())
59 maxElements = numStructUnionElements(T);
Eli Friedman683cedf2008-05-19 19:16:24 +000060 else if (T->isVectorType())
61 maxElements = T->getAsVectorType()->getNumElements();
Steve Naroffc4d4a482008-05-01 22:18:59 +000062 else
63 assert(0 && "CheckImplicitInitList(): Illegal type");
Eli Friedman683cedf2008-05-19 19:16:24 +000064
Eli Friedmanf8df28c2008-05-25 13:49:22 +000065 if (maxElements == 0) {
66 SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(),
67 diag::err_implicit_empty_initializer);
68 hadError = true;
69 return;
70 }
71
Eli Friedman683cedf2008-05-19 19:16:24 +000072 // Check the element types *before* we create the implicit init list;
73 // otherwise, we might end up taking the wrong number of elements
74 unsigned NewIndex = Index;
75 CheckListElementTypes(ParentIList, T, NewIndex);
76
Steve Naroffc4d4a482008-05-01 22:18:59 +000077 for (int i = 0; i < maxElements; ++i) {
78 // Don't attempt to go past the end of the init list
79 if (Index >= ParentIList->getNumInits())
80 break;
81 Expr* expr = ParentIList->getInit(Index);
82
83 // Add the expr to the new implicit init list and remove if from the old.
84 InitExprs.push_back(expr);
85 ParentIList->removeInit(Index);
86 }
87 // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
88 InitListExpr *ILE = new InitListExpr(SourceLocation(),
89 &InitExprs[0], InitExprs.size(),
Chris Lattner71ca8c82008-10-26 23:43:26 +000090 SourceLocation(),
91 ParentIList->hadDesignators());
Steve Naroffc4d4a482008-05-01 22:18:59 +000092 ILE->setType(T);
Eli Friedmand8535af2008-05-19 20:00:43 +000093
Steve Naroffc4d4a482008-05-01 22:18:59 +000094 // Modify the parent InitListExpr to point to the implicit InitListExpr.
95 ParentIList->addInit(Index, ILE);
Steve Naroffc4d4a482008-05-01 22:18:59 +000096}
97
Steve Naroff56099522008-05-06 00:23:44 +000098void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
Steve Naroffc4d4a482008-05-01 22:18:59 +000099 unsigned &Index) {
Eli Friedmand8535af2008-05-19 20:00:43 +0000100 assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
Eli Friedmand8535af2008-05-19 20:00:43 +0000101
Eli Friedman683cedf2008-05-19 19:16:24 +0000102 CheckListElementTypes(IList, T, Index);
Steve Naroff56099522008-05-06 00:23:44 +0000103 IList->setType(T);
Eli Friedman46f81662008-05-25 13:22:35 +0000104 if (hadError)
105 return;
Eli Friedmand8535af2008-05-19 20:00:43 +0000106
Eli Friedman46f81662008-05-25 13:22:35 +0000107 if (Index < IList->getNumInits()) {
Eli Friedmand8535af2008-05-19 20:00:43 +0000108 // We have leftover initializers
109 if (IList->getNumInits() > 0 &&
110 SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
Eli Friedman71de9eb2008-05-19 20:12:18 +0000111 // Special-case
Eli Friedmand8535af2008-05-19 20:00:43 +0000112 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
Chris Lattner9d2cf082008-11-19 05:27:50 +0000113 diag::err_excess_initializers_in_char_array_initializer)
114 << IList->getInit(Index)->getSourceRange();
Eli Friedmand8535af2008-05-19 20:00:43 +0000115 hadError = true;
Eli Friedmanb9ea6bc2008-05-20 05:25:56 +0000116 } else if (!T->isIncompleteType()) {
117 // Don't warn for incomplete types, since we'll get an error elsewhere
Eli Friedmand8535af2008-05-19 20:00:43 +0000118 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
Chris Lattner9d2cf082008-11-19 05:27:50 +0000119 diag::warn_excess_initializers)
120 << IList->getInit(Index)->getSourceRange();
Eli Friedmand8535af2008-05-19 20:00:43 +0000121 }
122 }
Eli Friedman455f7622008-05-19 20:20:43 +0000123
Eli Friedman46f81662008-05-25 13:22:35 +0000124 if (T->isScalarType())
Chris Lattner9d2cf082008-11-19 05:27:50 +0000125 SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init)
126 << IList->getSourceRange();
Steve Naroffc4d4a482008-05-01 22:18:59 +0000127}
128
Eli Friedman683cedf2008-05-19 19:16:24 +0000129void InitListChecker::CheckListElementTypes(InitListExpr *IList,
130 QualType &DeclType,
131 unsigned &Index) {
Eli Friedmand8535af2008-05-19 20:00:43 +0000132 if (DeclType->isScalarType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000133 CheckScalarType(IList, DeclType, Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000134 } else if (DeclType->isVectorType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000135 CheckVectorType(IList, DeclType, Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000136 } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000137 if (DeclType->isStructureType() || DeclType->isUnionType())
138 CheckStructUnionTypes(IList, DeclType, Index);
139 else if (DeclType->isArrayType())
140 CheckArrayType(IList, DeclType, Index);
141 else
142 assert(0 && "Aggregate that isn't a function or array?!");
Steve Naroffff5b3a82008-08-10 16:05:48 +0000143 } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
144 // This type is invalid, issue a diagnostic.
Eli Friedmanb9ea6bc2008-05-20 05:25:56 +0000145 Index++;
Chris Lattner10f2c2e2008-11-20 06:38:18 +0000146 SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type)
Chris Lattner4bfd2232008-11-24 06:25:27 +0000147 << DeclType;
Eli Friedmanb9ea6bc2008-05-20 05:25:56 +0000148 hadError = true;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000149 } else {
150 // In C, all types are either scalars or aggregates, but
151 // additional handling is needed here for C++ (and possibly others?).
152 assert(0 && "Unsupported initializer type");
153 }
154}
155
Eli Friedman683cedf2008-05-19 19:16:24 +0000156void InitListChecker::CheckSubElementType(InitListExpr *IList,
157 QualType ElemType,
158 unsigned &Index) {
159 Expr* expr = IList->getInit(Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000160 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
161 unsigned newIndex = 0;
162 CheckExplicitInitList(SubInitList, ElemType, newIndex);
163 Index++;
Eli Friedman683cedf2008-05-19 19:16:24 +0000164 } else if (StringLiteral *lit =
165 SemaRef->IsStringLiteralInit(expr, ElemType)) {
166 SemaRef->CheckStringLiteralInit(lit, ElemType);
167 Index++;
Eli Friedmand8535af2008-05-19 20:00:43 +0000168 } else if (ElemType->isScalarType()) {
169 CheckScalarType(IList, ElemType, Index);
Eli Friedman683cedf2008-05-19 19:16:24 +0000170 } else if (expr->getType()->getAsRecordType() &&
Eli Friedman2ccfb512008-06-09 03:52:40 +0000171 SemaRef->Context.typesAreCompatible(
172 expr->getType().getUnqualifiedType(),
173 ElemType.getUnqualifiedType())) {
Eli Friedman683cedf2008-05-19 19:16:24 +0000174 Index++;
175 // FIXME: Add checking
176 } else {
177 CheckImplicitInitList(IList, ElemType, Index);
178 Index++;
179 }
180}
181
Steve Naroffc4d4a482008-05-01 22:18:59 +0000182void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
183 unsigned &Index) {
184 if (Index < IList->getNumInits()) {
185 Expr* expr = IList->getInit(Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000186 if (isa<InitListExpr>(expr)) {
Eli Friedman71de9eb2008-05-19 20:12:18 +0000187 SemaRef->Diag(IList->getLocStart(),
Chris Lattner9d2cf082008-11-19 05:27:50 +0000188 diag::err_many_braces_around_scalar_init)
189 << IList->getSourceRange();
Eli Friedman71de9eb2008-05-19 20:12:18 +0000190 hadError = true;
191 ++Index;
192 return;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000193 }
Eli Friedmand8535af2008-05-19 20:00:43 +0000194 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
195 if (SemaRef->CheckSingleInitializer(expr, DeclType))
Eli Friedman71de9eb2008-05-19 20:12:18 +0000196 hadError = true; // types weren't compatible.
Eli Friedmand8535af2008-05-19 20:00:43 +0000197 else if (savExpr != expr)
198 // The type was promoted, update initializer list.
199 IList->setInit(Index, expr);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000200 ++Index;
Eli Friedman71de9eb2008-05-19 20:12:18 +0000201 } else {
Chris Lattner9d2cf082008-11-19 05:27:50 +0000202 SemaRef->Diag(IList->getLocStart(), diag::err_empty_scalar_initializer)
203 << IList->getSourceRange();
Eli Friedman71de9eb2008-05-19 20:12:18 +0000204 hadError = true;
205 return;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000206 }
Steve Naroffc4d4a482008-05-01 22:18:59 +0000207}
208
209void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
210 unsigned &Index) {
211 if (Index < IList->getNumInits()) {
212 const VectorType *VT = DeclType->getAsVectorType();
213 int maxElements = VT->getNumElements();
214 QualType elementType = VT->getElementType();
215
216 for (int i = 0; i < maxElements; ++i) {
217 // Don't attempt to go past the end of the init list
218 if (Index >= IList->getNumInits())
219 break;
Eli Friedman683cedf2008-05-19 19:16:24 +0000220 CheckSubElementType(IList, elementType, Index);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000221 }
222 }
223}
224
225void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
226 unsigned &Index) {
227 // Check for the special-case of initializing an array with a string.
228 if (Index < IList->getNumInits()) {
229 if (StringLiteral *lit =
230 SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
231 SemaRef->CheckStringLiteralInit(lit, DeclType);
232 ++Index;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000233 return;
234 }
235 }
Chris Lattnera1923f62008-08-04 07:31:14 +0000236 if (const VariableArrayType *VAT =
237 SemaRef->Context.getAsVariableArrayType(DeclType)) {
Eli Friedman46f81662008-05-25 13:22:35 +0000238 // Check for VLAs; in standard C it would be possible to check this
239 // earlier, but I don't know where clang accepts VLAs (gcc accepts
240 // them in all sorts of strange places).
241 SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
Chris Lattner9d2cf082008-11-19 05:27:50 +0000242 diag::err_variable_object_no_init)
243 << VAT->getSizeExpr()->getSourceRange();
Eli Friedman46f81662008-05-25 13:22:35 +0000244 hadError = true;
245 return;
246 }
247
Steve Naroffc4d4a482008-05-01 22:18:59 +0000248 int maxElements = numArrayElements(DeclType);
Chris Lattnera1923f62008-08-04 07:31:14 +0000249 QualType elementType = SemaRef->Context.getAsArrayType(DeclType)
250 ->getElementType();
Steve Naroffc4d4a482008-05-01 22:18:59 +0000251 int numElements = 0;
252 for (int i = 0; i < maxElements; ++i, ++numElements) {
253 // Don't attempt to go past the end of the init list
254 if (Index >= IList->getNumInits())
255 break;
Eli Friedman683cedf2008-05-19 19:16:24 +0000256 CheckSubElementType(IList, elementType, Index);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000257 }
258 if (DeclType->isIncompleteArrayType()) {
259 // If this is an incomplete array type, the actual type needs to
Daniel Dunbar604dacf2008-08-18 20:28:46 +0000260 // be calculated here.
Steve Naroffc4d4a482008-05-01 22:18:59 +0000261 if (numElements == 0) {
Daniel Dunbar604dacf2008-08-18 20:28:46 +0000262 // Sizing an array implicitly to zero is not allowed by ISO C,
263 // but is supported by GNU.
Steve Naroffc4d4a482008-05-01 22:18:59 +0000264 SemaRef->Diag(IList->getLocStart(),
Daniel Dunbar604dacf2008-08-18 20:28:46 +0000265 diag::ext_typecheck_zero_array_size);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000266 }
Daniel Dunbar604dacf2008-08-18 20:28:46 +0000267
268 llvm::APSInt ConstVal(32);
269 ConstVal = numElements;
270 DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
271 ArrayType::Normal, 0);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000272 }
273}
274
275void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
276 QualType DeclType,
Eli Friedman683cedf2008-05-19 19:16:24 +0000277 unsigned &Index) {
278 RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
Steve Naroffc4d4a482008-05-01 22:18:59 +0000279
Eli Friedman683cedf2008-05-19 19:16:24 +0000280 // If the record is invalid, some of it's members are invalid. To avoid
281 // confusion, we forgo checking the intializer for the entire record.
282 if (structDecl->isInvalidDecl()) {
283 hadError = true;
284 return;
285 }
286 // If structDecl is a forward declaration, this loop won't do anything;
287 // That's okay, because an error should get printed out elsewhere. It
288 // might be worthwhile to skip over the rest of the initializer, though.
Eli Friedman171a4632008-08-09 23:45:45 +0000289 int numMembers = DeclType->getAsRecordType()->getDecl()->getNumMembers() -
290 structDecl->hasFlexibleArrayMember();
Eli Friedman683cedf2008-05-19 19:16:24 +0000291 for (int i = 0; i < numMembers; i++) {
292 // Don't attempt to go past the end of the init list
293 if (Index >= IList->getNumInits())
294 break;
295 FieldDecl * curField = structDecl->getMember(i);
296 if (!curField->getIdentifier()) {
297 // Don't initialize unnamed fields, e.g. "int : 20;"
298 continue;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000299 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000300 CheckSubElementType(IList, curField->getType(), Index);
301 if (DeclType->isUnionType())
302 break;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000303 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000304 // FIXME: Implement flexible array initialization GCC extension (it's a
305 // really messy extension to implement, unfortunately...the necessary
306 // information isn't actually even here!)
Steve Naroffc4d4a482008-05-01 22:18:59 +0000307}
308} // end namespace clang
309