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