blob: d1f4b25d1deaf49e941500c484984e55087cf23a [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;
24
25 if (IL) {
26 unsigned newIndex = 0;
Steve Naroffa647caa2008-05-06 00:23:44 +000027
28 // Special case the following, which should produce an error.
29 //
30 // struct foo { int z; } w;
31 // int bar (void) {
32 // struct foo bad = { w };
33 // return bad.z;
34 // }
35 if (T->isStructureType() || T->isUnionType())
36 CheckStructUnionTypes(IL, T, newIndex, true);
37 else
38 CheckExplicitInitList(IL, T, newIndex);
39
40 if (!hadError && (newIndex < IL->getNumInits())) {
41 // We have leftover initializers; warn
42 SemaRef->Diag(IL->getInit(newIndex)->getLocStart(),
43 diag::warn_excess_initializers,
44 IL->getInit(newIndex)->getSourceRange());
45 }
Steve Naroff0cca7492008-05-01 22:18:59 +000046 } else {
47 // FIXME: Create an implicit InitListExpr with expressions from the
48 // parent checker.
49 }
50}
51
52int InitListChecker::numArrayElements(QualType DeclType) {
53 int maxElements;
54 if (DeclType->isIncompleteArrayType()) {
55 // FIXME: use a proper constant
56 maxElements = 0x7FFFFFFF;
57 } else if (const VariableArrayType *VAT =
58 DeclType->getAsVariableArrayType()) {
59 // Check for VLAs; in standard C it would be possible to check this
60 // earlier, but I don't know where clang accepts VLAs (gcc accepts
61 // them in all sorts of strange places).
62 SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
63 diag::err_variable_object_no_init,
64 VAT->getSizeExpr()->getSourceRange());
65 hadError = true;
66 maxElements = 0x7FFFFFFF;
67 } else {
68 const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();
69 maxElements = static_cast<int>(CAT->getSize().getZExtValue());
70 }
71 return maxElements;
72}
73
74int InitListChecker::numStructUnionElements(QualType DeclType) {
75 RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
76 return structDecl->getNumMembers() - structDecl->hasFlexibleArrayMember();
77}
78
79void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
80 QualType T, unsigned &Index) {
81 llvm::SmallVector<Expr*, 4> InitExprs;
82 int maxElements = 0;
83
84 if (T->isArrayType())
85 maxElements = numArrayElements(T);
86 else if (T->isStructureType() || T->isUnionType())
87 maxElements = numStructUnionElements(T);
88 else
89 assert(0 && "CheckImplicitInitList(): Illegal type");
90
91 for (int i = 0; i < maxElements; ++i) {
92 // Don't attempt to go past the end of the init list
93 if (Index >= ParentIList->getNumInits())
94 break;
95 Expr* expr = ParentIList->getInit(Index);
96
97 // Add the expr to the new implicit init list and remove if from the old.
98 InitExprs.push_back(expr);
99 ParentIList->removeInit(Index);
100 }
101 // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
102 InitListExpr *ILE = new InitListExpr(SourceLocation(),
103 &InitExprs[0], InitExprs.size(),
104 SourceLocation());
105 ILE->setType(T);
106
107 // Modify the parent InitListExpr to point to the implicit InitListExpr.
108 ParentIList->addInit(Index, ILE);
Steve Naroff0cca7492008-05-01 22:18:59 +0000109 // Now we can check the types.
Steve Naroffa647caa2008-05-06 00:23:44 +0000110 // CheckElementTypes(ParentIList, T, Index);
Steve Naroff0cca7492008-05-01 22:18:59 +0000111}
112
Steve Naroffa647caa2008-05-06 00:23:44 +0000113void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
Steve Naroff0cca7492008-05-01 22:18:59 +0000114 unsigned &Index) {
115 //assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
Steve Naroffa647caa2008-05-06 00:23:44 +0000116 if (IList->isExplicit() && T->isScalarType())
Steve Naroff0cca7492008-05-01 22:18:59 +0000117 SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
118 IList->getSourceRange());
Steve Naroff0cca7492008-05-01 22:18:59 +0000119 CheckElementTypes(IList, T, Index);
Steve Naroffa647caa2008-05-06 00:23:44 +0000120 IList->setType(T);
Steve Naroff0cca7492008-05-01 22:18:59 +0000121}
122
123void InitListChecker::CheckElementTypes(InitListExpr *IList, QualType &DeclType,
124 unsigned &Index) {
125 if (DeclType->isScalarType())
126 CheckScalarType(IList, DeclType, Index);
127 else if (DeclType->isVectorType())
128 CheckVectorType(IList, DeclType, Index);
129 else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
130 if (DeclType->isStructureType() || DeclType->isUnionType())
131 CheckStructUnionTypes(IList, DeclType, Index);
132 else if (DeclType->isArrayType())
133 CheckArrayType(IList, DeclType, Index);
134 else
135 assert(0 && "Aggregate that isn't a function or array?!");
136 } else {
137 // In C, all types are either scalars or aggregates, but
138 // additional handling is needed here for C++ (and possibly others?).
139 assert(0 && "Unsupported initializer type");
140 }
141}
142
143void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
144 unsigned &Index) {
145 if (Index < IList->getNumInits()) {
146 Expr* expr = IList->getInit(Index);
147 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
148 unsigned newIndex = 0;
149 CheckExplicitInitList(SubInitList, DeclType, newIndex);
150 } else {
151 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
152 if (SemaRef->CheckSingleInitializer(expr, DeclType))
153 hadError |= true; // types weren't compatible.
154 else if (savExpr != expr)
155 // The type was promoted, update initializer list.
156 IList->setInit(Index, expr);
157 }
158 ++Index;
159 }
160 // FIXME: Should an error be reported for empty initializer list + scalar?
161}
162
163void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
164 unsigned &Index) {
165 if (Index < IList->getNumInits()) {
166 const VectorType *VT = DeclType->getAsVectorType();
167 int maxElements = VT->getNumElements();
168 QualType elementType = VT->getElementType();
169
170 for (int i = 0; i < maxElements; ++i) {
171 // Don't attempt to go past the end of the init list
172 if (Index >= IList->getNumInits())
173 break;
174 Expr* expr = IList->getInit(Index);
175 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
176 unsigned newIndex = 0;
177 CheckExplicitInitList(SubInitList, elementType, newIndex);
178 newIndex++;
179 } else
180 CheckImplicitInitList(IList, elementType, Index);
181 }
182 }
183}
184
185void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
186 unsigned &Index) {
187 // Check for the special-case of initializing an array with a string.
188 if (Index < IList->getNumInits()) {
189 if (StringLiteral *lit =
190 SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
191 SemaRef->CheckStringLiteralInit(lit, DeclType);
192 ++Index;
193 if (IList->isExplicit() && Index < IList->getNumInits()) {
194 // We have leftover initializers; warn
195 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
196 diag::err_excess_initializers_in_char_array_initializer,
197 IList->getInit(Index)->getSourceRange());
198 }
199 return;
200 }
201 }
202 int maxElements = numArrayElements(DeclType);
203 QualType elementType = DeclType->getAsArrayType()->getElementType();
204 int numElements = 0;
205 for (int i = 0; i < maxElements; ++i, ++numElements) {
206 // Don't attempt to go past the end of the init list
207 if (Index >= IList->getNumInits())
208 break;
209 Expr* expr = IList->getInit(Index);
Steve Naroff0cca7492008-05-01 22:18:59 +0000210 // Now, check the expression against the element type.
211 if (elementType->isScalarType())
212 CheckScalarType(IList, elementType, Index);
Steve Naroffa647caa2008-05-06 00:23:44 +0000213 else if (elementType->isStructureType() || elementType->isUnionType())
214 CheckStructUnionTypes(IList, elementType, Index);
215 else if (StringLiteral *lit =
216 SemaRef->IsStringLiteralInit(expr, elementType)) {
217 SemaRef->CheckStringLiteralInit(lit, elementType);
218 Index++;
219 } else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
Steve Naroff0cca7492008-05-01 22:18:59 +0000220 unsigned newIndex = 0;
221 CheckExplicitInitList(SubInitList, elementType, newIndex);
222 Index++;
Steve Naroff0cca7492008-05-01 22:18:59 +0000223 } else {
224 CheckImplicitInitList(IList, elementType, Index);
Steve Naroffa647caa2008-05-06 00:23:44 +0000225 Index++;
Steve Naroff0cca7492008-05-01 22:18:59 +0000226 }
227 }
228 if (DeclType->isIncompleteArrayType()) {
229 // If this is an incomplete array type, the actual type needs to
230 // be calculated here
231 if (numElements == 0) {
232 // Sizing an array implicitly to zero is not allowed
233 // (It could in theory be allowed, but it doesn't really matter.)
234 SemaRef->Diag(IList->getLocStart(),
235 diag::err_at_least_one_initializer_needed_to_size_array);
236 hadError = true;
237 } else {
238 llvm::APSInt ConstVal(32);
239 ConstVal = numElements;
240 DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
241 ArrayType::Normal, 0);
242 }
243 }
244}
245
246void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
247 QualType DeclType,
Steve Naroffa647caa2008-05-06 00:23:44 +0000248 unsigned &Index,
249 bool topLevel) {
250 if (Index < IList->getNumInits() && !topLevel &&
Steve Naroff0cca7492008-05-01 22:18:59 +0000251 SemaRef->Context.typesAreCompatible(
252 IList->getInit(Index)->getType(), DeclType)) {
253 // We found a compatible struct; per the standard, this initializes the
254 // struct. (The C standard technically says that this only applies for
255 // initializers for declarations with automatic scope; however, this
256 // construct is unambiguous anyway because a struct cannot contain
257 // a type compatible with itself. We'll output an error when we check
258 // if the initializer is constant.)
259 // FIXME: Is a call to CheckSingleInitializer required here?
260 ++Index;
261 } else {
262 RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
263
264 // If the record is invalid, some of it's members are invalid. To avoid
265 // confusion, we forgo checking the intializer for the entire record.
266 if (structDecl->isInvalidDecl()) {
267 hadError = true;
268 return;
269 }
270 // If structDecl is a forward declaration, this loop won't do anything;
271 // That's okay, because an error should get printed out elsewhere. It
272 // might be worthwhile to skip over the rest of the initializer, though.
273 int numMembers = numStructUnionElements(DeclType);
274 for (int i = 0; i < numMembers; i++) {
275 // Don't attempt to go past the end of the init list
276 if (Index >= IList->getNumInits())
277 break;
278 FieldDecl * curField = structDecl->getMember(i);
279 if (!curField->getIdentifier()) {
280 // Don't initialize unnamed fields, e.g. "int : 20;"
281 continue;
282 }
Steve Naroffa647caa2008-05-06 00:23:44 +0000283 QualType elementType = curField->getType();
Steve Naroff0cca7492008-05-01 22:18:59 +0000284 Expr* expr = IList->getInit(Index);
Steve Naroffa647caa2008-05-06 00:23:44 +0000285 if (elementType->isScalarType())
286 CheckScalarType(IList, elementType, Index);
287 else if (elementType->isStructureType() || elementType->isUnionType())
288 CheckStructUnionTypes(IList, elementType, Index);
289 else if (StringLiteral *lit =SemaRef->IsStringLiteralInit(expr, elementType)) {
290 SemaRef->CheckStringLiteralInit(lit, elementType);
Steve Naroff0cca7492008-05-01 22:18:59 +0000291 Index++;
Steve Naroffa647caa2008-05-06 00:23:44 +0000292 } else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
293 unsigned newIndex = 0;
294 CheckExplicitInitList(SubInitList, elementType, newIndex);
295 Index++;
296 } else {
297 CheckImplicitInitList(IList, elementType, Index);
298 Index++;
299 }
Steve Naroff0cca7492008-05-01 22:18:59 +0000300 if (DeclType->isUnionType())
301 break;
302 }
303 // 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!)
306 }
307}
308} // end namespace clang
309