blob: 1889bafacb08ab92ca7fbbc24ce33a1d53354578 [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;
Chris Lattnerc63a1f22008-08-04 07:31:14 +000033 if (const ConstantArrayType *CAT =
34 SemaRef->Context.getAsConstantArrayType(DeclType)) {
Steve Naroff0cca7492008-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 Friedmanf84eda32008-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;
Argyrios Kyrtzidis39ba4ae2008-06-09 23:19:58 +000046 if (structDecl->isUnion())
Eli Friedmanf84eda32008-05-25 14:03:31 +000047 return std::min(InitializableMembers, 1);
48 return InitializableMembers - structDecl->hasFlexibleArrayMember();
Steve Naroff0cca7492008-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 Friedmanb85f7072008-05-19 19:16:24 +000060 else if (T->isVectorType())
61 maxElements = T->getAsVectorType()->getNumElements();
Steve Naroff0cca7492008-05-01 22:18:59 +000062 else
63 assert(0 && "CheckImplicitInitList(): Illegal type");
Eli Friedmanb85f7072008-05-19 19:16:24 +000064
Eli Friedman402256f2008-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 Friedmanb85f7072008-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 Naroff0cca7492008-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(),
90 SourceLocation());
91 ILE->setType(T);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +000092
Steve Naroff0cca7492008-05-01 22:18:59 +000093 // Modify the parent InitListExpr to point to the implicit InitListExpr.
94 ParentIList->addInit(Index, ILE);
Steve Naroff0cca7492008-05-01 22:18:59 +000095}
96
Steve Naroffa647caa2008-05-06 00:23:44 +000097void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
Steve Naroff0cca7492008-05-01 22:18:59 +000098 unsigned &Index) {
Eli Friedmanc9c0ea62008-05-19 20:00:43 +000099 assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000100
Eli Friedmanb85f7072008-05-19 19:16:24 +0000101 CheckListElementTypes(IList, T, Index);
Steve Naroffa647caa2008-05-06 00:23:44 +0000102 IList->setType(T);
Eli Friedman638e1442008-05-25 13:22:35 +0000103 if (hadError)
104 return;
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000105
Eli Friedman638e1442008-05-25 13:22:35 +0000106 if (Index < IList->getNumInits()) {
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000107 // We have leftover initializers
108 if (IList->getNumInits() > 0 &&
109 SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
Eli Friedmanbb504d32008-05-19 20:12:18 +0000110 // Special-case
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000111 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
112 diag::err_excess_initializers_in_char_array_initializer,
113 IList->getInit(Index)->getSourceRange());
114 hadError = true;
Eli Friedmand8dc2102008-05-20 05:25:56 +0000115 } else if (!T->isIncompleteType()) {
116 // Don't warn for incomplete types, since we'll get an error elsewhere
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000117 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
118 diag::warn_excess_initializers,
119 IList->getInit(Index)->getSourceRange());
120 }
121 }
Eli Friedmancda25a92008-05-19 20:20:43 +0000122
Eli Friedman638e1442008-05-25 13:22:35 +0000123 if (T->isScalarType())
Eli Friedmancda25a92008-05-19 20:20:43 +0000124 SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
125 IList->getSourceRange());
Steve Naroff0cca7492008-05-01 22:18:59 +0000126}
127
Eli Friedmanb85f7072008-05-19 19:16:24 +0000128void InitListChecker::CheckListElementTypes(InitListExpr *IList,
129 QualType &DeclType,
130 unsigned &Index) {
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000131 if (DeclType->isScalarType()) {
Steve Naroff0cca7492008-05-01 22:18:59 +0000132 CheckScalarType(IList, DeclType, Index);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000133 } else if (DeclType->isVectorType()) {
Steve Naroff0cca7492008-05-01 22:18:59 +0000134 CheckVectorType(IList, DeclType, Index);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000135 } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
Steve Naroff0cca7492008-05-01 22:18:59 +0000136 if (DeclType->isStructureType() || DeclType->isUnionType())
137 CheckStructUnionTypes(IList, DeclType, Index);
138 else if (DeclType->isArrayType())
139 CheckArrayType(IList, DeclType, Index);
140 else
141 assert(0 && "Aggregate that isn't a function or array?!");
Eli Friedmand8dc2102008-05-20 05:25:56 +0000142 } else if (DeclType->isVoidType()) {
143 // This is clearly invalid, so not much we can do here. Don't bother
144 // with a diagnostic; we'll give an error elsewhere.
145 Index++;
146 hadError = true;
Steve Naroff0cca7492008-05-01 22:18:59 +0000147 } else {
148 // In C, all types are either scalars or aggregates, but
149 // additional handling is needed here for C++ (and possibly others?).
150 assert(0 && "Unsupported initializer type");
151 }
152}
153
Eli Friedmanb85f7072008-05-19 19:16:24 +0000154void InitListChecker::CheckSubElementType(InitListExpr *IList,
155 QualType ElemType,
156 unsigned &Index) {
157 Expr* expr = IList->getInit(Index);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000158 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
159 unsigned newIndex = 0;
160 CheckExplicitInitList(SubInitList, ElemType, newIndex);
161 Index++;
Eli Friedmanb85f7072008-05-19 19:16:24 +0000162 } else if (StringLiteral *lit =
163 SemaRef->IsStringLiteralInit(expr, ElemType)) {
164 SemaRef->CheckStringLiteralInit(lit, ElemType);
165 Index++;
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000166 } else if (ElemType->isScalarType()) {
167 CheckScalarType(IList, ElemType, Index);
Eli Friedmanb85f7072008-05-19 19:16:24 +0000168 } else if (expr->getType()->getAsRecordType() &&
Eli Friedmanc92e5e42008-06-09 03:52:40 +0000169 SemaRef->Context.typesAreCompatible(
170 expr->getType().getUnqualifiedType(),
171 ElemType.getUnqualifiedType())) {
Eli Friedmanb85f7072008-05-19 19:16:24 +0000172 Index++;
173 // FIXME: Add checking
174 } else {
175 CheckImplicitInitList(IList, ElemType, Index);
176 Index++;
177 }
178}
179
Steve Naroff0cca7492008-05-01 22:18:59 +0000180void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
181 unsigned &Index) {
182 if (Index < IList->getNumInits()) {
183 Expr* expr = IList->getInit(Index);
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000184 if (isa<InitListExpr>(expr)) {
Eli Friedmanbb504d32008-05-19 20:12:18 +0000185 SemaRef->Diag(IList->getLocStart(),
186 diag::err_many_braces_around_scalar_init,
187 IList->getSourceRange());
188 hadError = true;
189 ++Index;
190 return;
Steve Naroff0cca7492008-05-01 22:18:59 +0000191 }
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000192 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
193 if (SemaRef->CheckSingleInitializer(expr, DeclType))
Eli Friedmanbb504d32008-05-19 20:12:18 +0000194 hadError = true; // types weren't compatible.
Eli Friedmanc9c0ea62008-05-19 20:00:43 +0000195 else if (savExpr != expr)
196 // The type was promoted, update initializer list.
197 IList->setInit(Index, expr);
Steve Naroff0cca7492008-05-01 22:18:59 +0000198 ++Index;
Eli Friedmanbb504d32008-05-19 20:12:18 +0000199 } else {
200 SemaRef->Diag(IList->getLocStart(),
201 diag::err_empty_scalar_initializer,
202 IList->getSourceRange());
203 hadError = true;
204 return;
Steve Naroff0cca7492008-05-01 22:18:59 +0000205 }
Steve Naroff0cca7492008-05-01 22:18:59 +0000206}
207
208void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
209 unsigned &Index) {
210 if (Index < IList->getNumInits()) {
211 const VectorType *VT = DeclType->getAsVectorType();
212 int maxElements = VT->getNumElements();
213 QualType elementType = VT->getElementType();
214
215 for (int i = 0; i < maxElements; ++i) {
216 // Don't attempt to go past the end of the init list
217 if (Index >= IList->getNumInits())
218 break;
Eli Friedmanb85f7072008-05-19 19:16:24 +0000219 CheckSubElementType(IList, elementType, Index);
Steve Naroff0cca7492008-05-01 22:18:59 +0000220 }
221 }
222}
223
224void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
225 unsigned &Index) {
226 // Check for the special-case of initializing an array with a string.
227 if (Index < IList->getNumInits()) {
228 if (StringLiteral *lit =
229 SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
230 SemaRef->CheckStringLiteralInit(lit, DeclType);
231 ++Index;
Steve Naroff0cca7492008-05-01 22:18:59 +0000232 return;
233 }
234 }
Chris Lattnerc63a1f22008-08-04 07:31:14 +0000235 if (const VariableArrayType *VAT =
236 SemaRef->Context.getAsVariableArrayType(DeclType)) {
Eli Friedman638e1442008-05-25 13:22:35 +0000237 // Check for VLAs; in standard C it would be possible to check this
238 // earlier, but I don't know where clang accepts VLAs (gcc accepts
239 // them in all sorts of strange places).
240 SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
241 diag::err_variable_object_no_init,
242 VAT->getSizeExpr()->getSourceRange());
243 hadError = true;
244 return;
245 }
246
Steve Naroff0cca7492008-05-01 22:18:59 +0000247 int maxElements = numArrayElements(DeclType);
Chris Lattnerc63a1f22008-08-04 07:31:14 +0000248 QualType elementType = SemaRef->Context.getAsArrayType(DeclType)
249 ->getElementType();
Steve Naroff0cca7492008-05-01 22:18:59 +0000250 int numElements = 0;
251 for (int i = 0; i < maxElements; ++i, ++numElements) {
252 // Don't attempt to go past the end of the init list
253 if (Index >= IList->getNumInits())
254 break;
Eli Friedmanb85f7072008-05-19 19:16:24 +0000255 CheckSubElementType(IList, elementType, Index);
Steve Naroff0cca7492008-05-01 22:18:59 +0000256 }
257 if (DeclType->isIncompleteArrayType()) {
258 // If this is an incomplete array type, the actual type needs to
259 // be calculated here
260 if (numElements == 0) {
261 // Sizing an array implicitly to zero is not allowed
262 // (It could in theory be allowed, but it doesn't really matter.)
263 SemaRef->Diag(IList->getLocStart(),
264 diag::err_at_least_one_initializer_needed_to_size_array);
265 hadError = true;
266 } else {
267 llvm::APSInt ConstVal(32);
268 ConstVal = numElements;
269 DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
270 ArrayType::Normal, 0);
271 }
272 }
273}
274
275void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
276 QualType DeclType,
Eli Friedmanb85f7072008-05-19 19:16:24 +0000277 unsigned &Index) {
278 RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
Steve Naroff0cca7492008-05-01 22:18:59 +0000279
Eli Friedmanb85f7072008-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.
289 int numMembers = numStructUnionElements(DeclType);
290 for (int i = 0; i < numMembers; i++) {
291 // Don't attempt to go past the end of the init list
292 if (Index >= IList->getNumInits())
293 break;
294 FieldDecl * curField = structDecl->getMember(i);
295 if (!curField->getIdentifier()) {
296 // Don't initialize unnamed fields, e.g. "int : 20;"
297 continue;
Steve Naroff0cca7492008-05-01 22:18:59 +0000298 }
Eli Friedmanb85f7072008-05-19 19:16:24 +0000299 CheckSubElementType(IList, curField->getType(), Index);
300 if (DeclType->isUnionType())
301 break;
Steve Naroff0cca7492008-05-01 22:18:59 +0000302 }
Eli Friedmanb85f7072008-05-19 19:16:24 +0000303 // FIXME: Implement flexible array initialization GCC extension (it's a
304 // really messy extension to implement, unfortunately...the necessary
305 // information isn't actually even here!)
Steve Naroff0cca7492008-05-01 22:18:59 +0000306}
307} // end namespace clang
308