SemaInit.cpp revision 4bfd223a74022ce30ac1b86683bac054ab5fac34
1//===--- 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/Basic/Diagnostic.h"
18
19namespace clang {
20
21InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
22  hadError = false;
23  SemaRef = S;
24
25  unsigned newIndex = 0;
26
27  CheckExplicitInitList(IL, T, newIndex);
28}
29
30int InitListChecker::numArrayElements(QualType DeclType) {
31  // FIXME: use a proper constant
32  int maxElements = 0x7FFFFFFF;
33  if (const ConstantArrayType *CAT =
34        SemaRef->Context.getAsConstantArrayType(DeclType)) {
35    maxElements = static_cast<int>(CAT->getSize().getZExtValue());
36  }
37  return maxElements;
38}
39
40int InitListChecker::numStructUnionElements(QualType DeclType) {
41  RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
42  int InitializableMembers = 0;
43  for (int i = 0; i < structDecl->getNumMembers(); i++)
44    if (structDecl->getMember(i)->getIdentifier())
45      ++InitializableMembers;
46  if (structDecl->isUnion())
47    return std::min(InitializableMembers, 1);
48  return InitializableMembers - structDecl->hasFlexibleArrayMember();
49}
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);
60  else if (T->isVectorType())
61    maxElements = T->getAsVectorType()->getNumElements();
62  else
63    assert(0 && "CheckImplicitInitList(): Illegal type");
64
65  if (maxElements == 0) {
66    SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(),
67                  diag::err_implicit_empty_initializer);
68    hadError = true;
69    return;
70  }
71
72  // 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
77  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                                       ParentIList->hadDesignators());
92  ILE->setType(T);
93
94  // Modify the parent InitListExpr to point to the implicit InitListExpr.
95  ParentIList->addInit(Index, ILE);
96}
97
98void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
99                                            unsigned &Index) {
100  assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
101
102  CheckListElementTypes(IList, T, Index);
103  IList->setType(T);
104  if (hadError)
105    return;
106
107  if (Index < IList->getNumInits()) {
108    // We have leftover initializers
109    if (IList->getNumInits() > 0 &&
110        SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
111      // Special-case
112      SemaRef->Diag(IList->getInit(Index)->getLocStart(),
113                    diag::err_excess_initializers_in_char_array_initializer)
114        << IList->getInit(Index)->getSourceRange();
115      hadError = true;
116    } else if (!T->isIncompleteType()) {
117      // Don't warn for incomplete types, since we'll get an error elsewhere
118      SemaRef->Diag(IList->getInit(Index)->getLocStart(),
119                    diag::warn_excess_initializers)
120        << IList->getInit(Index)->getSourceRange();
121    }
122  }
123
124  if (T->isScalarType())
125    SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init)
126      << IList->getSourceRange();
127}
128
129void InitListChecker::CheckListElementTypes(InitListExpr *IList,
130                                            QualType &DeclType,
131                                            unsigned &Index) {
132  if (DeclType->isScalarType()) {
133    CheckScalarType(IList, DeclType, Index);
134  } else if (DeclType->isVectorType()) {
135    CheckVectorType(IList, DeclType, Index);
136  } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
137    if (DeclType->isStructureType() || DeclType->isUnionType())
138      CheckStructUnionTypes(IList, DeclType, Index);
139    else if (DeclType->isArrayType())
140      CheckArrayType(IList, DeclType, Index);
141    else
142      assert(0 && "Aggregate that isn't a function or array?!");
143  } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
144    // This type is invalid, issue a diagnostic.
145    Index++;
146    SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type)
147      << DeclType;
148    hadError = true;
149  } else {
150    // In C, all types are either scalars or aggregates, but
151    // additional handling is needed here for C++ (and possibly others?).
152    assert(0 && "Unsupported initializer type");
153  }
154}
155
156void InitListChecker::CheckSubElementType(InitListExpr *IList,
157                                          QualType ElemType,
158                                          unsigned &Index) {
159  Expr* expr = IList->getInit(Index);
160  if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
161    unsigned newIndex = 0;
162    CheckExplicitInitList(SubInitList, ElemType, newIndex);
163    Index++;
164  } else if (StringLiteral *lit =
165             SemaRef->IsStringLiteralInit(expr, ElemType)) {
166    SemaRef->CheckStringLiteralInit(lit, ElemType);
167    Index++;
168  } else if (ElemType->isScalarType()) {
169    CheckScalarType(IList, ElemType, Index);
170  } else if (expr->getType()->getAsRecordType() &&
171             SemaRef->Context.typesAreCompatible(
172               expr->getType().getUnqualifiedType(),
173               ElemType.getUnqualifiedType())) {
174    Index++;
175    // FIXME: Add checking
176  } else {
177    CheckImplicitInitList(IList, ElemType, Index);
178    Index++;
179  }
180}
181
182void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
183                                      unsigned &Index) {
184  if (Index < IList->getNumInits()) {
185    Expr* expr = IList->getInit(Index);
186    if (isa<InitListExpr>(expr)) {
187      SemaRef->Diag(IList->getLocStart(),
188                    diag::err_many_braces_around_scalar_init)
189        << IList->getSourceRange();
190      hadError = true;
191      ++Index;
192      return;
193    }
194    Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
195    if (SemaRef->CheckSingleInitializer(expr, DeclType))
196      hadError = true; // types weren't compatible.
197    else if (savExpr != expr)
198      // The type was promoted, update initializer list.
199      IList->setInit(Index, expr);
200    ++Index;
201  } else {
202    SemaRef->Diag(IList->getLocStart(), diag::err_empty_scalar_initializer)
203      << IList->getSourceRange();
204    hadError = true;
205    return;
206  }
207}
208
209void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
210                                      unsigned &Index) {
211  if (Index < IList->getNumInits()) {
212    const VectorType *VT = DeclType->getAsVectorType();
213    int maxElements = VT->getNumElements();
214    QualType elementType = VT->getElementType();
215
216    for (int i = 0; i < maxElements; ++i) {
217      // Don't attempt to go past the end of the init list
218      if (Index >= IList->getNumInits())
219        break;
220      CheckSubElementType(IList, elementType, Index);
221    }
222  }
223}
224
225void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
226                                     unsigned &Index) {
227  // Check for the special-case of initializing an array with a string.
228  if (Index < IList->getNumInits()) {
229    if (StringLiteral *lit =
230        SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
231      SemaRef->CheckStringLiteralInit(lit, DeclType);
232      ++Index;
233      return;
234    }
235  }
236  if (const VariableArrayType *VAT =
237        SemaRef->Context.getAsVariableArrayType(DeclType)) {
238    // Check for VLAs; in standard C it would be possible to check this
239    // earlier, but I don't know where clang accepts VLAs (gcc accepts
240    // them in all sorts of strange places).
241    SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
242                  diag::err_variable_object_no_init)
243      << VAT->getSizeExpr()->getSourceRange();
244    hadError = true;
245    return;
246  }
247
248  int maxElements = numArrayElements(DeclType);
249  QualType elementType = SemaRef->Context.getAsArrayType(DeclType)
250                             ->getElementType();
251  int numElements = 0;
252  for (int i = 0; i < maxElements; ++i, ++numElements) {
253    // Don't attempt to go past the end of the init list
254    if (Index >= IList->getNumInits())
255      break;
256    CheckSubElementType(IList, elementType, Index);
257  }
258  if (DeclType->isIncompleteArrayType()) {
259    // If this is an incomplete array type, the actual type needs to
260    // be calculated here.
261    if (numElements == 0) {
262      // Sizing an array implicitly to zero is not allowed by ISO C,
263      // but is supported by GNU.
264      SemaRef->Diag(IList->getLocStart(),
265                    diag::ext_typecheck_zero_array_size);
266    }
267
268    llvm::APSInt ConstVal(32);
269    ConstVal = numElements;
270    DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
271                                                     ArrayType::Normal, 0);
272  }
273}
274
275void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
276                                            QualType DeclType,
277                                            unsigned &Index) {
278  RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
279
280  // 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 = DeclType->getAsRecordType()->getDecl()->getNumMembers() -
290                   structDecl->hasFlexibleArrayMember();
291  for (int i = 0; i < numMembers; i++) {
292    // Don't attempt to go past the end of the init list
293    if (Index >= IList->getNumInits())
294      break;
295    FieldDecl * curField = structDecl->getMember(i);
296    if (!curField->getIdentifier()) {
297      // Don't initialize unnamed fields, e.g. "int : 20;"
298      continue;
299    }
300    CheckSubElementType(IList, curField->getType(), Index);
301    if (DeclType->isUnionType())
302      break;
303  }
304  // FIXME: Implement flexible array initialization GCC extension (it's a
305  // really messy extension to implement, unfortunately...the necessary
306  // information isn't actually even here!)
307}
308} // end namespace clang
309
310