blob: 8f1bac7246d4b5cbd38f60e630130970b1c3485c [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
Eli Friedman683cedf2008-05-19 19:16:24 +000025 unsigned newIndex = 0;
Steve Naroff56099522008-05-06 00:23:44 +000026
Eli Friedman683cedf2008-05-19 19:16:24 +000027 CheckExplicitInitList(IL, T, newIndex);
Steve Naroff56099522008-05-06 00:23:44 +000028
Eli Friedman683cedf2008-05-19 19:16:24 +000029 if (!hadError && (newIndex < IL->getNumInits())) {
30 // We have leftover initializers; warn
31 SemaRef->Diag(IL->getInit(newIndex)->getLocStart(),
32 diag::warn_excess_initializers,
33 IL->getInit(newIndex)->getSourceRange());
34 }
Steve Naroffc4d4a482008-05-01 22:18:59 +000035}
36
37int InitListChecker::numArrayElements(QualType DeclType) {
38 int maxElements;
39 if (DeclType->isIncompleteArrayType()) {
40 // FIXME: use a proper constant
41 maxElements = 0x7FFFFFFF;
42 } else if (const VariableArrayType *VAT =
43 DeclType->getAsVariableArrayType()) {
44 // Check for VLAs; in standard C it would be possible to check this
45 // earlier, but I don't know where clang accepts VLAs (gcc accepts
46 // them in all sorts of strange places).
47 SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
48 diag::err_variable_object_no_init,
49 VAT->getSizeExpr()->getSourceRange());
50 hadError = true;
51 maxElements = 0x7FFFFFFF;
52 } else {
53 const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();
54 maxElements = static_cast<int>(CAT->getSize().getZExtValue());
55 }
56 return maxElements;
57}
58
59int InitListChecker::numStructUnionElements(QualType DeclType) {
60 RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
Eli Friedman683cedf2008-05-19 19:16:24 +000061 if (structDecl->getKind() == Decl::Union)
62 return std::min(structDecl->getNumMembers(), 1);
Steve Naroffc4d4a482008-05-01 22:18:59 +000063 return structDecl->getNumMembers() - structDecl->hasFlexibleArrayMember();
64}
65
66void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
67 QualType T, unsigned &Index) {
68 llvm::SmallVector<Expr*, 4> InitExprs;
69 int maxElements = 0;
70
71 if (T->isArrayType())
72 maxElements = numArrayElements(T);
73 else if (T->isStructureType() || T->isUnionType())
74 maxElements = numStructUnionElements(T);
Eli Friedman683cedf2008-05-19 19:16:24 +000075 else if (T->isVectorType())
76 maxElements = T->getAsVectorType()->getNumElements();
Steve Naroffc4d4a482008-05-01 22:18:59 +000077 else
78 assert(0 && "CheckImplicitInitList(): Illegal type");
Eli Friedman683cedf2008-05-19 19:16:24 +000079
80 // Check the element types *before* we create the implicit init list;
81 // otherwise, we might end up taking the wrong number of elements
82 unsigned NewIndex = Index;
83 CheckListElementTypes(ParentIList, T, NewIndex);
84
Steve Naroffc4d4a482008-05-01 22:18:59 +000085 for (int i = 0; i < maxElements; ++i) {
86 // Don't attempt to go past the end of the init list
87 if (Index >= ParentIList->getNumInits())
88 break;
89 Expr* expr = ParentIList->getInit(Index);
90
91 // Add the expr to the new implicit init list and remove if from the old.
92 InitExprs.push_back(expr);
93 ParentIList->removeInit(Index);
94 }
95 // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
96 InitListExpr *ILE = new InitListExpr(SourceLocation(),
97 &InitExprs[0], InitExprs.size(),
98 SourceLocation());
99 ILE->setType(T);
100
101 // Modify the parent InitListExpr to point to the implicit InitListExpr.
102 ParentIList->addInit(Index, ILE);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000103}
104
Steve Naroff56099522008-05-06 00:23:44 +0000105void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
Steve Naroffc4d4a482008-05-01 22:18:59 +0000106 unsigned &Index) {
107 //assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
Steve Naroff56099522008-05-06 00:23:44 +0000108 if (IList->isExplicit() && T->isScalarType())
Steve Naroffc4d4a482008-05-01 22:18:59 +0000109 SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
110 IList->getSourceRange());
Eli Friedman683cedf2008-05-19 19:16:24 +0000111 CheckListElementTypes(IList, T, Index);
Steve Naroff56099522008-05-06 00:23:44 +0000112 IList->setType(T);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000113}
114
Eli Friedman683cedf2008-05-19 19:16:24 +0000115void InitListChecker::CheckListElementTypes(InitListExpr *IList,
116 QualType &DeclType,
117 unsigned &Index) {
Steve Naroffc4d4a482008-05-01 22:18:59 +0000118 if (DeclType->isScalarType())
119 CheckScalarType(IList, DeclType, Index);
120 else if (DeclType->isVectorType())
121 CheckVectorType(IList, DeclType, Index);
122 else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
123 if (DeclType->isStructureType() || DeclType->isUnionType())
124 CheckStructUnionTypes(IList, DeclType, Index);
125 else if (DeclType->isArrayType())
126 CheckArrayType(IList, DeclType, Index);
127 else
128 assert(0 && "Aggregate that isn't a function or array?!");
129 } else {
130 // In C, all types are either scalars or aggregates, but
131 // additional handling is needed here for C++ (and possibly others?).
132 assert(0 && "Unsupported initializer type");
133 }
134}
135
Eli Friedman683cedf2008-05-19 19:16:24 +0000136void InitListChecker::CheckSubElementType(InitListExpr *IList,
137 QualType ElemType,
138 unsigned &Index) {
139 Expr* expr = IList->getInit(Index);
140 if (ElemType->isScalarType()) {
141 CheckScalarType(IList, ElemType, Index);
142 } else if (StringLiteral *lit =
143 SemaRef->IsStringLiteralInit(expr, ElemType)) {
144 SemaRef->CheckStringLiteralInit(lit, ElemType);
145 Index++;
146 } else if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
147 unsigned newIndex = 0;
148 CheckExplicitInitList(SubInitList, ElemType, newIndex);
149 Index++;
150 } else if (expr->getType()->getAsRecordType() &&
151 SemaRef->Context.typesAreCompatible(
152 IList->getInit(Index)->getType(), ElemType)) {
153 Index++;
154 // FIXME: Add checking
155 } else {
156 CheckImplicitInitList(IList, ElemType, Index);
157 Index++;
158 }
159}
160
Steve Naroffc4d4a482008-05-01 22:18:59 +0000161void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
162 unsigned &Index) {
163 if (Index < IList->getNumInits()) {
164 Expr* expr = IList->getInit(Index);
165 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
Eli Friedman683cedf2008-05-19 19:16:24 +0000166 unsigned newIndex = 0;
167 CheckExplicitInitList(SubInitList, DeclType, newIndex);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000168 } else {
169 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
170 if (SemaRef->CheckSingleInitializer(expr, DeclType))
171 hadError |= true; // types weren't compatible.
172 else if (savExpr != expr)
173 // The type was promoted, update initializer list.
174 IList->setInit(Index, expr);
175 }
176 ++Index;
177 }
178 // FIXME: Should an error be reported for empty initializer list + scalar?
179}
180
181void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
182 unsigned &Index) {
183 if (Index < IList->getNumInits()) {
184 const VectorType *VT = DeclType->getAsVectorType();
185 int maxElements = VT->getNumElements();
186 QualType elementType = VT->getElementType();
187
188 for (int i = 0; i < maxElements; ++i) {
189 // Don't attempt to go past the end of the init list
190 if (Index >= IList->getNumInits())
191 break;
Eli Friedman683cedf2008-05-19 19:16:24 +0000192 CheckSubElementType(IList, elementType, Index);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000193 }
194 }
195}
196
197void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
198 unsigned &Index) {
199 // Check for the special-case of initializing an array with a string.
200 if (Index < IList->getNumInits()) {
201 if (StringLiteral *lit =
202 SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
203 SemaRef->CheckStringLiteralInit(lit, DeclType);
204 ++Index;
Eli Friedman683cedf2008-05-19 19:16:24 +0000205#if 0
Steve Naroffc4d4a482008-05-01 22:18:59 +0000206 if (IList->isExplicit() && Index < IList->getNumInits()) {
207 // We have leftover initializers; warn
208 SemaRef->Diag(IList->getInit(Index)->getLocStart(),
209 diag::err_excess_initializers_in_char_array_initializer,
210 IList->getInit(Index)->getSourceRange());
211 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000212#endif
Steve Naroffc4d4a482008-05-01 22:18:59 +0000213 return;
214 }
215 }
216 int maxElements = numArrayElements(DeclType);
217 QualType elementType = DeclType->getAsArrayType()->getElementType();
218 int numElements = 0;
219 for (int i = 0; i < maxElements; ++i, ++numElements) {
220 // Don't attempt to go past the end of the init list
221 if (Index >= IList->getNumInits())
222 break;
Eli Friedman683cedf2008-05-19 19:16:24 +0000223 CheckSubElementType(IList, elementType, Index);
Steve Naroffc4d4a482008-05-01 22:18:59 +0000224 }
225 if (DeclType->isIncompleteArrayType()) {
226 // If this is an incomplete array type, the actual type needs to
227 // be calculated here
228 if (numElements == 0) {
229 // Sizing an array implicitly to zero is not allowed
230 // (It could in theory be allowed, but it doesn't really matter.)
231 SemaRef->Diag(IList->getLocStart(),
232 diag::err_at_least_one_initializer_needed_to_size_array);
233 hadError = true;
234 } else {
235 llvm::APSInt ConstVal(32);
236 ConstVal = numElements;
237 DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
238 ArrayType::Normal, 0);
239 }
240 }
241}
242
243void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
244 QualType DeclType,
Eli Friedman683cedf2008-05-19 19:16:24 +0000245 unsigned &Index) {
246 RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
Steve Naroffc4d4a482008-05-01 22:18:59 +0000247
Eli Friedman683cedf2008-05-19 19:16:24 +0000248 // If the record is invalid, some of it's members are invalid. To avoid
249 // confusion, we forgo checking the intializer for the entire record.
250 if (structDecl->isInvalidDecl()) {
251 hadError = true;
252 return;
253 }
254 // If structDecl is a forward declaration, this loop won't do anything;
255 // That's okay, because an error should get printed out elsewhere. It
256 // might be worthwhile to skip over the rest of the initializer, though.
257 int numMembers = numStructUnionElements(DeclType);
258 for (int i = 0; i < numMembers; i++) {
259 // Don't attempt to go past the end of the init list
260 if (Index >= IList->getNumInits())
261 break;
262 FieldDecl * curField = structDecl->getMember(i);
263 if (!curField->getIdentifier()) {
264 // Don't initialize unnamed fields, e.g. "int : 20;"
265 continue;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000266 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000267 CheckSubElementType(IList, curField->getType(), Index);
268 if (DeclType->isUnionType())
269 break;
Steve Naroffc4d4a482008-05-01 22:18:59 +0000270 }
Eli Friedman683cedf2008-05-19 19:16:24 +0000271 // FIXME: Implement flexible array initialization GCC extension (it's a
272 // really messy extension to implement, unfortunately...the necessary
273 // information isn't actually even here!)
Steve Naroffc4d4a482008-05-01 22:18:59 +0000274}
275} // end namespace clang
276