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