blob: e2377e18bae300b8f70d21dbe4b535f04aaec0cc [file] [log] [blame]
Steve Naroff0cca7492008-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 Friedmanc9c0ea62008-05-19 20:00:43 +000024
Eli Friedmanb85f7072008-05-19 19:16:24 +000025 unsigned newIndex = 0;
Eli Friedmanc9c0ea62008-05-19 20:00:43 +000026
Eli Friedmanb85f7072008-05-19 19:16:24 +000027 CheckExplicitInitList(IL, T, newIndex);
Steve Naroff0cca7492008-05-01 22:18:59 +000028}
29
30int InitListChecker::numArrayElements(QualType DeclType) {
Eli Friedman638e1442008-05-25 13:22:35 +000031 // FIXME: use a proper constant
32 int maxElements = 0x7FFFFFFF;
33 if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) {
Steve Naroff0cca7492008-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 Friedmanf84eda32008-05-25 14:03:31 +000041 int InitializableMembers = 0;
42 for (int i = 0; i < structDecl->getNumMembers(); i++)
43 if (structDecl->getMember(i)->getIdentifier())
44 ++InitializableMembers;
Eli Friedmanb85f7072008-05-19 19:16:24 +000045 if (structDecl->getKind() == Decl::Union)
Eli Friedmanf84eda32008-05-25 14:03:31 +000046 return std::min(InitializableMembers, 1);
47 return InitializableMembers - structDecl->hasFlexibleArrayMember();
Steve Naroff0cca7492008-05-01 22:18:59 +000048}
49
50void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
51 QualType T, unsigned &Index) {
52 llvm::SmallVector<Expr*, 4> InitExprs;
53 int maxElements = 0;
54
55 if (T->isArrayType())
56 maxElements = numArrayElements(T);
57 else if (T->isStructureType() || T->isUnionType())
58 maxElements = numStructUnionElements(T);
Eli Friedmanb85f7072008-05-19 19:16:24 +000059 else if (T->isVectorType())
60 maxElements = T->getAsVectorType()->getNumElements();
Steve Naroff0cca7492008-05-01 22:18:59 +000061 else
62 assert(0 && "CheckImplicitInitList(): Illegal type");
Eli Friedmanb85f7072008-05-19 19:16:24 +000063
Eli Friedman402256f2008-05-25 13:49:22 +000064 if (maxElements == 0) {
65 SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(),
66 diag::err_implicit_empty_initializer);
67 hadError = true;
68 return;
69 }
70
Eli Friedmanb85f7072008-05-19 19:16:24 +000071 // Check the element types *before* we create the implicit init list;
72 // otherwise, we might end up taking the wrong number of elements
73 unsigned NewIndex = Index;
74 CheckListElementTypes(ParentIList, T, NewIndex);
75
Steve Naroff0cca7492008-05-01 22:18:59 +000076 for (int i = 0; i < maxElements; ++i) {
77 // Don't attempt to go past the end of the init list
78 if (Index >= ParentIList->getNumInits())
79 break;
80 Expr* expr = ParentIList->getInit(Index);
81
82 // Add the expr to the new implicit init list and remove if from the old.
83 InitExprs.push_back(expr);
84 ParentIList->removeInit(Index);
85 }
86 // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
87 InitListExpr *ILE = new InitListExpr(SourceLocation(),
88 &InitExprs[0], InitExprs.size(),
89 SourceLocation());
90 ILE->setType(T);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +000091
Steve Naroff0cca7492008-05-01 22:18:59 +000092 // Modify the parent InitListExpr to point to the implicit InitListExpr.
93 ParentIList->addInit(Index, ILE);
Steve Naroff0cca7492008-05-01 22:18:59 +000094}
95
Steve Naroffa647caa2008-05-06 00:23:44 +000096void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
Steve Naroff0cca7492008-05-01 22:18:59 +000097 unsigned &Index) {
Eli Friedmanc9c0ea62008-05-19 20:00:43 +000098 assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
Eli Friedmanc9c0ea62008-05-19 20:00:43 +000099
Eli Friedmanb85f7072008-05-19 19:16:24 +0000100 CheckListElementTypes(IList, T, Index);
Steve Naroffa647caa2008-05-06 00:23:44 +0000101 IList->setType(T);
Eli Friedman638e1442008-05-25 13:22:35 +0000102 if (hadError)
103 return;
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000104
Eli Friedman638e1442008-05-25 13:22:35 +0000105 if (Index < IList->getNumInits()) {
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000106 // We have leftover initializers
107 if (IList->getNumInits() > 0 &&
108 SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
Eli Friedmanbb504d32008-05-19 20:12:18 +0000109 // Special-case
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000110 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
111 diag::err_excess_initializers_in_char_array_initializer,
112 IList->getInit(Index)->getSourceRange());
113 hadError = true;
Eli Friedmand8dc2102008-05-20 05:25:56 +0000114 } else if (!T->isIncompleteType()) {
115 // Don't warn for incomplete types, since we'll get an error elsewhere
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000116 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
117 diag::warn_excess_initializers,
118 IList->getInit(Index)->getSourceRange());
119 }
120 }
Eli Friedmancda25a92008-05-19 20:20:43 +0000121
Eli Friedman638e1442008-05-25 13:22:35 +0000122 if (T->isScalarType())
Eli Friedmancda25a92008-05-19 20:20:43 +0000123 SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
124 IList->getSourceRange());
Steve Naroff0cca7492008-05-01 22:18:59 +0000125}
126
Eli Friedmanb85f7072008-05-19 19:16:24 +0000127void InitListChecker::CheckListElementTypes(InitListExpr *IList,
128 QualType &DeclType,
129 unsigned &Index) {
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000130 if (DeclType->isScalarType()) {
Steve Naroff0cca7492008-05-01 22:18:59 +0000131 CheckScalarType(IList, DeclType, Index);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000132 } else if (DeclType->isVectorType()) {
Steve Naroff0cca7492008-05-01 22:18:59 +0000133 CheckVectorType(IList, DeclType, Index);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000134 } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
Steve Naroff0cca7492008-05-01 22:18:59 +0000135 if (DeclType->isStructureType() || DeclType->isUnionType())
136 CheckStructUnionTypes(IList, DeclType, Index);
137 else if (DeclType->isArrayType())
138 CheckArrayType(IList, DeclType, Index);
139 else
140 assert(0 && "Aggregate that isn't a function or array?!");
Eli Friedmand8dc2102008-05-20 05:25:56 +0000141 } else if (DeclType->isVoidType()) {
142 // This is clearly invalid, so not much we can do here. Don't bother
143 // with a diagnostic; we'll give an error elsewhere.
144 Index++;
145 hadError = true;
Steve Naroff0cca7492008-05-01 22:18:59 +0000146 } else {
147 // In C, all types are either scalars or aggregates, but
148 // additional handling is needed here for C++ (and possibly others?).
149 assert(0 && "Unsupported initializer type");
150 }
151}
152
Eli Friedmanb85f7072008-05-19 19:16:24 +0000153void InitListChecker::CheckSubElementType(InitListExpr *IList,
154 QualType ElemType,
155 unsigned &Index) {
156 Expr* expr = IList->getInit(Index);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000157 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
158 unsigned newIndex = 0;
159 CheckExplicitInitList(SubInitList, ElemType, newIndex);
160 Index++;
Eli Friedmanb85f7072008-05-19 19:16:24 +0000161 } else if (StringLiteral *lit =
162 SemaRef->IsStringLiteralInit(expr, ElemType)) {
163 SemaRef->CheckStringLiteralInit(lit, ElemType);
164 Index++;
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000165 } else if (ElemType->isScalarType()) {
166 CheckScalarType(IList, ElemType, Index);
Eli Friedmanb85f7072008-05-19 19:16:24 +0000167 } else if (expr->getType()->getAsRecordType() &&
Eli Friedmanc92e5e42008-06-09 03:52:40 +0000168 SemaRef->Context.typesAreCompatible(
169 expr->getType().getUnqualifiedType(),
170 ElemType.getUnqualifiedType())) {
Eli Friedmanb85f7072008-05-19 19:16:24 +0000171 Index++;
172 // FIXME: Add checking
173 } else {
174 CheckImplicitInitList(IList, ElemType, Index);
175 Index++;
176 }
177}
178
Steve Naroff0cca7492008-05-01 22:18:59 +0000179void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
180 unsigned &Index) {
181 if (Index < IList->getNumInits()) {
182 Expr* expr = IList->getInit(Index);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000183 if (isa<InitListExpr>(expr)) {
Eli Friedmanbb504d32008-05-19 20:12:18 +0000184 SemaRef->Diag(IList->getLocStart(),
185 diag::err_many_braces_around_scalar_init,
186 IList->getSourceRange());
187 hadError = true;
188 ++Index;
189 return;
Steve Naroff0cca7492008-05-01 22:18:59 +0000190 }
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000191 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
192 if (SemaRef->CheckSingleInitializer(expr, DeclType))
Eli Friedmanbb504d32008-05-19 20:12:18 +0000193 hadError = true; // types weren't compatible.
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000194 else if (savExpr != expr)
195 // The type was promoted, update initializer list.
196 IList->setInit(Index, expr);
Steve Naroff0cca7492008-05-01 22:18:59 +0000197 ++Index;
Eli Friedmanbb504d32008-05-19 20:12:18 +0000198 } else {
199 SemaRef->Diag(IList->getLocStart(),
200 diag::err_empty_scalar_initializer,
201 IList->getSourceRange());
202 hadError = true;
203 return;
Steve Naroff0cca7492008-05-01 22:18:59 +0000204 }
Steve Naroff0cca7492008-05-01 22:18:59 +0000205}
206
207void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
208 unsigned &Index) {
209 if (Index < IList->getNumInits()) {
210 const VectorType *VT = DeclType->getAsVectorType();
211 int maxElements = VT->getNumElements();
212 QualType elementType = VT->getElementType();
213
214 for (int i = 0; i < maxElements; ++i) {
215 // Don't attempt to go past the end of the init list
216 if (Index >= IList->getNumInits())
217 break;
Eli Friedmanb85f7072008-05-19 19:16:24 +0000218 CheckSubElementType(IList, elementType, Index);
Steve Naroff0cca7492008-05-01 22:18:59 +0000219 }
220 }
221}
222
223void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
224 unsigned &Index) {
225 // Check for the special-case of initializing an array with a string.
226 if (Index < IList->getNumInits()) {
227 if (StringLiteral *lit =
228 SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
229 SemaRef->CheckStringLiteralInit(lit, DeclType);
230 ++Index;
Steve Naroff0cca7492008-05-01 22:18:59 +0000231 return;
232 }
233 }
Eli Friedman638e1442008-05-25 13:22:35 +0000234 if (const VariableArrayType *VAT = DeclType->getAsVariableArrayType()) {
235 // Check for VLAs; in standard C it would be possible to check this
236 // earlier, but I don't know where clang accepts VLAs (gcc accepts
237 // them in all sorts of strange places).
238 SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
239 diag::err_variable_object_no_init,
240 VAT->getSizeExpr()->getSourceRange());
241 hadError = true;
242 return;
243 }
244
Steve Naroff0cca7492008-05-01 22:18:59 +0000245 int maxElements = numArrayElements(DeclType);
246 QualType elementType = DeclType->getAsArrayType()->getElementType();
247 int numElements = 0;
248 for (int i = 0; i < maxElements; ++i, ++numElements) {
249 // Don't attempt to go past the end of the init list
250 if (Index >= IList->getNumInits())
251 break;
Eli Friedmanb85f7072008-05-19 19:16:24 +0000252 CheckSubElementType(IList, elementType, Index);
Steve Naroff0cca7492008-05-01 22:18:59 +0000253 }
254 if (DeclType->isIncompleteArrayType()) {
255 // If this is an incomplete array type, the actual type needs to
256 // be calculated here
257 if (numElements == 0) {
258 // Sizing an array implicitly to zero is not allowed
259 // (It could in theory be allowed, but it doesn't really matter.)
260 SemaRef->Diag(IList->getLocStart(),
261 diag::err_at_least_one_initializer_needed_to_size_array);
262 hadError = true;
263 } else {
264 llvm::APSInt ConstVal(32);
265 ConstVal = numElements;
266 DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
267 ArrayType::Normal, 0);
268 }
269 }
270}
271
272void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
273 QualType DeclType,
Eli Friedmanb85f7072008-05-19 19:16:24 +0000274 unsigned &Index) {
275 RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
Steve Naroff0cca7492008-05-01 22:18:59 +0000276
Eli Friedmanb85f7072008-05-19 19:16:24 +0000277 // If the record is invalid, some of it's members are invalid. To avoid
278 // confusion, we forgo checking the intializer for the entire record.
279 if (structDecl->isInvalidDecl()) {
280 hadError = true;
281 return;
282 }
283 // If structDecl is a forward declaration, this loop won't do anything;
284 // That's okay, because an error should get printed out elsewhere. It
285 // might be worthwhile to skip over the rest of the initializer, though.
286 int numMembers = numStructUnionElements(DeclType);
287 for (int i = 0; i < numMembers; i++) {
288 // Don't attempt to go past the end of the init list
289 if (Index >= IList->getNumInits())
290 break;
291 FieldDecl * curField = structDecl->getMember(i);
292 if (!curField->getIdentifier()) {
293 // Don't initialize unnamed fields, e.g. "int : 20;"
294 continue;
Steve Naroff0cca7492008-05-01 22:18:59 +0000295 }
Eli Friedmanb85f7072008-05-19 19:16:24 +0000296 CheckSubElementType(IList, curField->getType(), Index);
297 if (DeclType->isUnionType())
298 break;
Steve Naroff0cca7492008-05-01 22:18:59 +0000299 }
Eli Friedmanb85f7072008-05-19 19:16:24 +0000300 // FIXME: Implement flexible array initialization GCC extension (it's a
301 // really messy extension to implement, unfortunately...the necessary
302 // information isn't actually even here!)
Steve Naroff0cca7492008-05-01 22:18:59 +0000303}
304} // end namespace clang
305