blob: 6eb072eebafaefb381bb125d8f856f44bd41debf [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"
17#include "clang/AST/Type.h"
18
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;
33 if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +000034 maxElements = static_cast<int>(CAT->getSize().getZExtValue());
35 }
36 return maxElements;
37}
38
39int InitListChecker::numStructUnionElements(QualType DeclType) {
40 RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
Eli Friedman683cedf2008-05-19 19:16:24 +000041 if (structDecl->getKind() == Decl::Union)
42 return std::min(structDecl->getNumMembers(), 1);
Steve Naroffc4d4a482008-05-01 22:18:59 +000043 return structDecl->getNumMembers() - structDecl->hasFlexibleArrayMember();
44}
45
46void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
47 QualType T, unsigned &Index) {
48 llvm::SmallVector<Expr*, 4> InitExprs;
49 int maxElements = 0;
50
51 if (T->isArrayType())
52 maxElements = numArrayElements(T);
53 else if (T->isStructureType() || T->isUnionType())
54 maxElements = numStructUnionElements(T);
Eli Friedman683cedf2008-05-19 19:16:24 +000055 else if (T->isVectorType())
56 maxElements = T->getAsVectorType()->getNumElements();
Steve Naroffc4d4a482008-05-01 22:18:59 +000057 else
58 assert(0 && "CheckImplicitInitList(): Illegal type");
Eli Friedman683cedf2008-05-19 19:16:24 +000059
Eli Friedmanf8df28c2008-05-25 13:49:22 +000060 if (maxElements == 0) {
61 SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(),
62 diag::err_implicit_empty_initializer);
63 hadError = true;
64 return;
65 }
66
Eli Friedman683cedf2008-05-19 19:16:24 +000067 // Check the element types *before* we create the implicit init list;
68 // otherwise, we might end up taking the wrong number of elements
69 unsigned NewIndex = Index;
70 CheckListElementTypes(ParentIList, T, NewIndex);
71
Steve Naroffc4d4a482008-05-01 22:18:59 +000072 for (int i = 0; i < maxElements; ++i) {
73 // Don't attempt to go past the end of the init list
74 if (Index >= ParentIList->getNumInits())
75 break;
76 Expr* expr = ParentIList->getInit(Index);
77
78 // Add the expr to the new implicit init list and remove if from the old.
79 InitExprs.push_back(expr);
80 ParentIList->removeInit(Index);
81 }
82 // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
83 InitListExpr *ILE = new InitListExpr(SourceLocation(),
84 &InitExprs[0], InitExprs.size(),
85 SourceLocation());
86 ILE->setType(T);
Eli Friedmand8535af2008-05-19 20:00:43 +000087
Steve Naroffc4d4a482008-05-01 22:18:59 +000088 // Modify the parent InitListExpr to point to the implicit InitListExpr.
89 ParentIList->addInit(Index, ILE);
Steve Naroffc4d4a482008-05-01 22:18:59 +000090}
91
Steve Naroff56099522008-05-06 00:23:44 +000092void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
Steve Naroffc4d4a482008-05-01 22:18:59 +000093 unsigned &Index) {
Eli Friedmand8535af2008-05-19 20:00:43 +000094 assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
Eli Friedmand8535af2008-05-19 20:00:43 +000095
Eli Friedman683cedf2008-05-19 19:16:24 +000096 CheckListElementTypes(IList, T, Index);
Steve Naroff56099522008-05-06 00:23:44 +000097 IList->setType(T);
Eli Friedman46f81662008-05-25 13:22:35 +000098 if (hadError)
99 return;
Eli Friedmand8535af2008-05-19 20:00:43 +0000100
Eli Friedman46f81662008-05-25 13:22:35 +0000101 if (Index < IList->getNumInits()) {
Eli Friedmand8535af2008-05-19 20:00:43 +0000102 // We have leftover initializers
103 if (IList->getNumInits() > 0 &&
104 SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
Eli Friedman71de9eb2008-05-19 20:12:18 +0000105 // Special-case
Eli Friedmand8535af2008-05-19 20:00:43 +0000106 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
107 diag::err_excess_initializers_in_char_array_initializer,
108 IList->getInit(Index)->getSourceRange());
109 hadError = true;
Eli Friedmanb9ea6bc2008-05-20 05:25:56 +0000110 } else if (!T->isIncompleteType()) {
111 // Don't warn for incomplete types, since we'll get an error elsewhere
Eli Friedmand8535af2008-05-19 20:00:43 +0000112 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
113 diag::warn_excess_initializers,
114 IList->getInit(Index)->getSourceRange());
115 }
116 }
Eli Friedman455f7622008-05-19 20:20:43 +0000117
Eli Friedman46f81662008-05-25 13:22:35 +0000118 if (T->isScalarType())
Eli Friedman455f7622008-05-19 20:20:43 +0000119 SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
120 IList->getSourceRange());
Steve Naroffc4d4a482008-05-01 22:18:59 +0000121}
122
Eli Friedman683cedf2008-05-19 19:16:24 +0000123void InitListChecker::CheckListElementTypes(InitListExpr *IList,
124 QualType &DeclType,
125 unsigned &Index) {
Eli Friedmand8535af2008-05-19 20:00:43 +0000126 if (DeclType->isScalarType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000127 CheckScalarType(IList, DeclType, Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000128 } else if (DeclType->isVectorType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000129 CheckVectorType(IList, DeclType, Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000130 } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000131 if (DeclType->isStructureType() || DeclType->isUnionType())
132 CheckStructUnionTypes(IList, DeclType, Index);
133 else if (DeclType->isArrayType())
134 CheckArrayType(IList, DeclType, Index);
135 else
136 assert(0 && "Aggregate that isn't a function or array?!");
Eli Friedmanb9ea6bc2008-05-20 05:25:56 +0000137 } else if (DeclType->isVoidType()) {
138 // This is clearly invalid, so not much we can do here. Don't bother
139 // with a diagnostic; we'll give an error elsewhere.
140 Index++;
141 hadError = true;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000142 } else {
143 // In C, all types are either scalars or aggregates, but
144 // additional handling is needed here for C++ (and possibly others?).
145 assert(0 && "Unsupported initializer type");
146 }
147}
148
Eli Friedman683cedf2008-05-19 19:16:24 +0000149void InitListChecker::CheckSubElementType(InitListExpr *IList,
150 QualType ElemType,
151 unsigned &Index) {
152 Expr* expr = IList->getInit(Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000153 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
154 unsigned newIndex = 0;
155 CheckExplicitInitList(SubInitList, ElemType, newIndex);
156 Index++;
Eli Friedman683cedf2008-05-19 19:16:24 +0000157 } else if (StringLiteral *lit =
158 SemaRef->IsStringLiteralInit(expr, ElemType)) {
159 SemaRef->CheckStringLiteralInit(lit, ElemType);
160 Index++;
Eli Friedmand8535af2008-05-19 20:00:43 +0000161 } else if (ElemType->isScalarType()) {
162 CheckScalarType(IList, ElemType, Index);
Eli Friedman683cedf2008-05-19 19:16:24 +0000163 } else if (expr->getType()->getAsRecordType() &&
Eli Friedman46f81662008-05-25 13:22:35 +0000164 SemaRef->Context.typesAreCompatible(expr->getType(), ElemType)) {
Eli Friedman683cedf2008-05-19 19:16:24 +0000165 Index++;
166 // FIXME: Add checking
167 } else {
168 CheckImplicitInitList(IList, ElemType, Index);
169 Index++;
170 }
171}
172
Steve Naroffc4d4a482008-05-01 22:18:59 +0000173void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
174 unsigned &Index) {
175 if (Index < IList->getNumInits()) {
176 Expr* expr = IList->getInit(Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000177 if (isa<InitListExpr>(expr)) {
Eli Friedman71de9eb2008-05-19 20:12:18 +0000178 SemaRef->Diag(IList->getLocStart(),
179 diag::err_many_braces_around_scalar_init,
180 IList->getSourceRange());
181 hadError = true;
182 ++Index;
183 return;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000184 }
Eli Friedmand8535af2008-05-19 20:00:43 +0000185 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
186 if (SemaRef->CheckSingleInitializer(expr, DeclType))
Eli Friedman71de9eb2008-05-19 20:12:18 +0000187 hadError = true; // types weren't compatible.
Eli Friedmand8535af2008-05-19 20:00:43 +0000188 else if (savExpr != expr)
189 // The type was promoted, update initializer list.
190 IList->setInit(Index, expr);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000191 ++Index;
Eli Friedman71de9eb2008-05-19 20:12:18 +0000192 } else {
193 SemaRef->Diag(IList->getLocStart(),
194 diag::err_empty_scalar_initializer,
195 IList->getSourceRange());
196 hadError = true;
197 return;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000198 }
Steve Naroffc4d4a482008-05-01 22:18:59 +0000199}
200
201void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
202 unsigned &Index) {
203 if (Index < IList->getNumInits()) {
204 const VectorType *VT = DeclType->getAsVectorType();
205 int maxElements = VT->getNumElements();
206 QualType elementType = VT->getElementType();
207
208 for (int i = 0; i < maxElements; ++i) {
209 // Don't attempt to go past the end of the init list
210 if (Index >= IList->getNumInits())
211 break;
Eli Friedman683cedf2008-05-19 19:16:24 +0000212 CheckSubElementType(IList, elementType, Index);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000213 }
214 }
215}
216
217void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
218 unsigned &Index) {
219 // Check for the special-case of initializing an array with a string.
220 if (Index < IList->getNumInits()) {
221 if (StringLiteral *lit =
222 SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
223 SemaRef->CheckStringLiteralInit(lit, DeclType);
224 ++Index;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000225 return;
226 }
227 }
Eli Friedman46f81662008-05-25 13:22:35 +0000228 if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType()) {
229 // Check for VLAs; in standard C it would be possible to check this
230 // earlier, but I don't know where clang accepts VLAs (gcc accepts
231 // them in all sorts of strange places).
232 SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
233 diag::err_variable_object_no_init,
234 VAT->getSizeExpr()->getSourceRange());
235 hadError = true;
236 return;
237 }
238
Steve Naroffc4d4a482008-05-01 22:18:59 +0000239 int maxElements = numArrayElements(DeclType);
240 QualType elementType = DeclType->getAsArrayType()->getElementType();
241 int numElements = 0;
242 for (int i = 0; i < maxElements; ++i, ++numElements) {
243 // Don't attempt to go past the end of the init list
244 if (Index >= IList->getNumInits())
245 break;
Eli Friedman683cedf2008-05-19 19:16:24 +0000246 CheckSubElementType(IList, elementType, Index);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000247 }
248 if (DeclType->isIncompleteArrayType()) {
249 // If this is an incomplete array type, the actual type needs to
250 // be calculated here
251 if (numElements == 0) {
252 // Sizing an array implicitly to zero is not allowed
253 // (It could in theory be allowed, but it doesn't really matter.)
254 SemaRef->Diag(IList->getLocStart(),
255 diag::err_at_least_one_initializer_needed_to_size_array);
256 hadError = true;
257 } else {
258 llvm::APSInt ConstVal(32);
259 ConstVal = numElements;
260 DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
261 ArrayType::Normal, 0);
262 }
263 }
264}
265
266void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
267 QualType DeclType,
Eli Friedman683cedf2008-05-19 19:16:24 +0000268 unsigned &Index) {
269 RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
Steve Naroffc4d4a482008-05-01 22:18:59 +0000270
Eli Friedman683cedf2008-05-19 19:16:24 +0000271 // If the record is invalid, some of it's members are invalid. To avoid
272 // confusion, we forgo checking the intializer for the entire record.
273 if (structDecl->isInvalidDecl()) {
274 hadError = true;
275 return;
276 }
277 // If structDecl is a forward declaration, this loop won't do anything;
278 // That's okay, because an error should get printed out elsewhere. It
279 // might be worthwhile to skip over the rest of the initializer, though.
280 int numMembers = numStructUnionElements(DeclType);
281 for (int i = 0; i < numMembers; i++) {
282 // Don't attempt to go past the end of the init list
283 if (Index >= IList->getNumInits())
284 break;
285 FieldDecl * curField = structDecl->getMember(i);
286 if (!curField->getIdentifier()) {
287 // Don't initialize unnamed fields, e.g. "int : 20;"
288 continue;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000289 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000290 CheckSubElementType(IList, curField->getType(), Index);
291 if (DeclType->isUnionType())
292 break;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000293 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000294 // FIXME: Implement flexible array initialization GCC extension (it's a
295 // really messy extension to implement, unfortunately...the necessary
296 // information isn't actually even here!)
Steve Naroffc4d4a482008-05-01 22:18:59 +0000297}
298} // end namespace clang
299