blob: d5378d30d5c4d3fa7dcbd184e8e4acb2d2f573c2 [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) {
31 int maxElements;
32 if (DeclType->isIncompleteArrayType()) {
33 // FIXME: use a proper constant
34 maxElements = 0x7FFFFFFF;
35 } else if (const VariableArrayType *VAT =
36 DeclType->getAsVariableArrayType()) {
37 // Check for VLAs; in standard C it would be possible to check this
38 // earlier, but I don't know where clang accepts VLAs (gcc accepts
39 // them in all sorts of strange places).
40 SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
41 diag::err_variable_object_no_init,
42 VAT->getSizeExpr()->getSourceRange());
43 hadError = true;
44 maxElements = 0x7FFFFFFF;
45 } else {
46 const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();
47 maxElements = static_cast<int>(CAT->getSize().getZExtValue());
48 }
49 return maxElements;
50}
51
52int InitListChecker::numStructUnionElements(QualType DeclType) {
53 RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
Eli Friedman683cedf2008-05-19 19:16:24 +000054 if (structDecl->getKind() == Decl::Union)
55 return std::min(structDecl->getNumMembers(), 1);
Steve Naroffc4d4a482008-05-01 22:18:59 +000056 return structDecl->getNumMembers() - structDecl->hasFlexibleArrayMember();
57}
58
59void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
60 QualType T, unsigned &Index) {
61 llvm::SmallVector<Expr*, 4> InitExprs;
62 int maxElements = 0;
63
64 if (T->isArrayType())
65 maxElements = numArrayElements(T);
66 else if (T->isStructureType() || T->isUnionType())
67 maxElements = numStructUnionElements(T);
Eli Friedman683cedf2008-05-19 19:16:24 +000068 else if (T->isVectorType())
69 maxElements = T->getAsVectorType()->getNumElements();
Steve Naroffc4d4a482008-05-01 22:18:59 +000070 else
71 assert(0 && "CheckImplicitInitList(): Illegal type");
Eli Friedman683cedf2008-05-19 19:16:24 +000072
73 // Check the element types *before* we create the implicit init list;
74 // otherwise, we might end up taking the wrong number of elements
75 unsigned NewIndex = Index;
76 CheckListElementTypes(ParentIList, T, NewIndex);
77
Steve Naroffc4d4a482008-05-01 22:18:59 +000078 for (int i = 0; i < maxElements; ++i) {
79 // Don't attempt to go past the end of the init list
80 if (Index >= ParentIList->getNumInits())
81 break;
82 Expr* expr = ParentIList->getInit(Index);
83
84 // Add the expr to the new implicit init list and remove if from the old.
85 InitExprs.push_back(expr);
86 ParentIList->removeInit(Index);
87 }
88 // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
89 InitListExpr *ILE = new InitListExpr(SourceLocation(),
90 &InitExprs[0], InitExprs.size(),
91 SourceLocation());
92 ILE->setType(T);
Eli Friedmand8535af2008-05-19 20:00:43 +000093
Steve Naroffc4d4a482008-05-01 22:18:59 +000094 // Modify the parent InitListExpr to point to the implicit InitListExpr.
95 ParentIList->addInit(Index, ILE);
Steve Naroffc4d4a482008-05-01 22:18:59 +000096}
97
Steve Naroff56099522008-05-06 00:23:44 +000098void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
Steve Naroffc4d4a482008-05-01 22:18:59 +000099 unsigned &Index) {
Eli Friedmand8535af2008-05-19 20:00:43 +0000100 assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
Eli Friedmand8535af2008-05-19 20:00:43 +0000101
Eli Friedman683cedf2008-05-19 19:16:24 +0000102 CheckListElementTypes(IList, T, Index);
Steve Naroff56099522008-05-06 00:23:44 +0000103 IList->setType(T);
Eli Friedmand8535af2008-05-19 20:00:43 +0000104
105 if (!hadError && (Index < IList->getNumInits())) {
106 // We have leftover initializers
107 if (IList->getNumInits() > 0 &&
108 SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
Eli Friedman71de9eb2008-05-19 20:12:18 +0000109 // Special-case
Eli Friedmand8535af2008-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;
114 } else {
115 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
116 diag::warn_excess_initializers,
117 IList->getInit(Index)->getSourceRange());
118 }
119 }
Eli Friedman455f7622008-05-19 20:20:43 +0000120
121 if (!hadError && T->isScalarType())
122 SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
123 IList->getSourceRange());
Steve Naroffc4d4a482008-05-01 22:18:59 +0000124}
125
Eli Friedman683cedf2008-05-19 19:16:24 +0000126void InitListChecker::CheckListElementTypes(InitListExpr *IList,
127 QualType &DeclType,
128 unsigned &Index) {
Eli Friedmand8535af2008-05-19 20:00:43 +0000129 if (DeclType->isScalarType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000130 CheckScalarType(IList, DeclType, Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000131 } else if (DeclType->isVectorType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000132 CheckVectorType(IList, DeclType, Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000133 } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000134 if (DeclType->isStructureType() || DeclType->isUnionType())
135 CheckStructUnionTypes(IList, DeclType, Index);
136 else if (DeclType->isArrayType())
137 CheckArrayType(IList, DeclType, Index);
138 else
139 assert(0 && "Aggregate that isn't a function or array?!");
140 } else {
141 // In C, all types are either scalars or aggregates, but
142 // additional handling is needed here for C++ (and possibly others?).
143 assert(0 && "Unsupported initializer type");
144 }
145}
146
Eli Friedman683cedf2008-05-19 19:16:24 +0000147void InitListChecker::CheckSubElementType(InitListExpr *IList,
148 QualType ElemType,
149 unsigned &Index) {
150 Expr* expr = IList->getInit(Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000151 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
152 unsigned newIndex = 0;
153 CheckExplicitInitList(SubInitList, ElemType, newIndex);
154 Index++;
Eli Friedman683cedf2008-05-19 19:16:24 +0000155 } else if (StringLiteral *lit =
156 SemaRef->IsStringLiteralInit(expr, ElemType)) {
157 SemaRef->CheckStringLiteralInit(lit, ElemType);
158 Index++;
Eli Friedmand8535af2008-05-19 20:00:43 +0000159 } else if (ElemType->isScalarType()) {
160 CheckScalarType(IList, ElemType, Index);
Eli Friedman683cedf2008-05-19 19:16:24 +0000161 } else if (expr->getType()->getAsRecordType() &&
162 SemaRef->Context.typesAreCompatible(
163 IList->getInit(Index)->getType(), ElemType)) {
164 Index++;
165 // FIXME: Add checking
166 } else {
167 CheckImplicitInitList(IList, ElemType, Index);
168 Index++;
169 }
170}
171
Steve Naroffc4d4a482008-05-01 22:18:59 +0000172void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
173 unsigned &Index) {
174 if (Index < IList->getNumInits()) {
175 Expr* expr = IList->getInit(Index);
Eli Friedmand8535af2008-05-19 20:00:43 +0000176 if (isa<InitListExpr>(expr)) {
Eli Friedman71de9eb2008-05-19 20:12:18 +0000177 SemaRef->Diag(IList->getLocStart(),
178 diag::err_many_braces_around_scalar_init,
179 IList->getSourceRange());
180 hadError = true;
181 ++Index;
182 return;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000183 }
Eli Friedmand8535af2008-05-19 20:00:43 +0000184 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
185 if (SemaRef->CheckSingleInitializer(expr, DeclType))
Eli Friedman71de9eb2008-05-19 20:12:18 +0000186 hadError = true; // types weren't compatible.
Eli Friedmand8535af2008-05-19 20:00:43 +0000187 else if (savExpr != expr)
188 // The type was promoted, update initializer list.
189 IList->setInit(Index, expr);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000190 ++Index;
Eli Friedman71de9eb2008-05-19 20:12:18 +0000191 } else {
192 SemaRef->Diag(IList->getLocStart(),
193 diag::err_empty_scalar_initializer,
194 IList->getSourceRange());
195 hadError = true;
196 return;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000197 }
Steve Naroffc4d4a482008-05-01 22:18:59 +0000198}
199
200void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
201 unsigned &Index) {
202 if (Index < IList->getNumInits()) {
203 const VectorType *VT = DeclType->getAsVectorType();
204 int maxElements = VT->getNumElements();
205 QualType elementType = VT->getElementType();
206
207 for (int i = 0; i < maxElements; ++i) {
208 // Don't attempt to go past the end of the init list
209 if (Index >= IList->getNumInits())
210 break;
Eli Friedman683cedf2008-05-19 19:16:24 +0000211 CheckSubElementType(IList, elementType, Index);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000212 }
213 }
214}
215
216void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
217 unsigned &Index) {
218 // Check for the special-case of initializing an array with a string.
219 if (Index < IList->getNumInits()) {
220 if (StringLiteral *lit =
221 SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
222 SemaRef->CheckStringLiteralInit(lit, DeclType);
223 ++Index;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000224 return;
225 }
226 }
227 int maxElements = numArrayElements(DeclType);
228 QualType elementType = DeclType->getAsArrayType()->getElementType();
229 int numElements = 0;
230 for (int i = 0; i < maxElements; ++i, ++numElements) {
231 // Don't attempt to go past the end of the init list
232 if (Index >= IList->getNumInits())
233 break;
Eli Friedman683cedf2008-05-19 19:16:24 +0000234 CheckSubElementType(IList, elementType, Index);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000235 }
236 if (DeclType->isIncompleteArrayType()) {
237 // If this is an incomplete array type, the actual type needs to
238 // be calculated here
239 if (numElements == 0) {
240 // Sizing an array implicitly to zero is not allowed
241 // (It could in theory be allowed, but it doesn't really matter.)
242 SemaRef->Diag(IList->getLocStart(),
243 diag::err_at_least_one_initializer_needed_to_size_array);
244 hadError = true;
245 } else {
246 llvm::APSInt ConstVal(32);
247 ConstVal = numElements;
248 DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
249 ArrayType::Normal, 0);
250 }
251 }
252}
253
254void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
255 QualType DeclType,
Eli Friedman683cedf2008-05-19 19:16:24 +0000256 unsigned &Index) {
257 RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
Steve Naroffc4d4a482008-05-01 22:18:59 +0000258
Eli Friedman683cedf2008-05-19 19:16:24 +0000259 // If the record is invalid, some of it's members are invalid. To avoid
260 // confusion, we forgo checking the intializer for the entire record.
261 if (structDecl->isInvalidDecl()) {
262 hadError = true;
263 return;
264 }
265 // If structDecl is a forward declaration, this loop won't do anything;
266 // That's okay, because an error should get printed out elsewhere. It
267 // might be worthwhile to skip over the rest of the initializer, though.
268 int numMembers = numStructUnionElements(DeclType);
269 for (int i = 0; i < numMembers; i++) {
270 // Don't attempt to go past the end of the init list
271 if (Index >= IList->getNumInits())
272 break;
273 FieldDecl * curField = structDecl->getMember(i);
274 if (!curField->getIdentifier()) {
275 // Don't initialize unnamed fields, e.g. "int : 20;"
276 continue;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000277 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000278 CheckSubElementType(IList, curField->getType(), Index);
279 if (DeclType->isUnionType())
280 break;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000281 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000282 // FIXME: Implement flexible array initialization GCC extension (it's a
283 // really messy extension to implement, unfortunately...the necessary
284 // information isn't actually even here!)
Steve Naroffc4d4a482008-05-01 22:18:59 +0000285}
286} // end namespace clang
287