SemaInit.cpp revision 455f762af54cfa1cea58d8c03eeec109bc798bcb
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  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();
54  if (structDecl->getKind() == Decl::Union)
55    return std::min(structDecl->getNumMembers(), 1);
56  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);
68  else if (T->isVectorType())
69    maxElements = T->getAsVectorType()->getNumElements();
70  else
71    assert(0 && "CheckImplicitInitList(): Illegal type");
72
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
78  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);
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
105  if (!hadError && (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 {
115      SemaRef->Diag(IList->getInit(Index)->getLocStart(),
116                    diag::warn_excess_initializers,
117                    IList->getInit(Index)->getSourceRange());
118    }
119  }
120
121  if (!hadError && T->isScalarType())
122    SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
123                  IList->getSourceRange());
124}
125
126void InitListChecker::CheckListElementTypes(InitListExpr *IList,
127                                            QualType &DeclType,
128                                            unsigned &Index) {
129  if (DeclType->isScalarType()) {
130    CheckScalarType(IList, DeclType, Index);
131  } else if (DeclType->isVectorType()) {
132    CheckVectorType(IList, DeclType, Index);
133  } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
134    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
147void InitListChecker::CheckSubElementType(InitListExpr *IList,
148                                          QualType ElemType,
149                                          unsigned &Index) {
150  Expr* expr = IList->getInit(Index);
151  if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
152    unsigned newIndex = 0;
153    CheckExplicitInitList(SubInitList, ElemType, newIndex);
154    Index++;
155  } else if (StringLiteral *lit =
156             SemaRef->IsStringLiteralInit(expr, ElemType)) {
157    SemaRef->CheckStringLiteralInit(lit, ElemType);
158    Index++;
159  } else if (ElemType->isScalarType()) {
160    CheckScalarType(IList, ElemType, Index);
161  } 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
172void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
173                                      unsigned &Index) {
174  if (Index < IList->getNumInits()) {
175    Expr* expr = IList->getInit(Index);
176    if (isa<InitListExpr>(expr)) {
177      SemaRef->Diag(IList->getLocStart(),
178                    diag::err_many_braces_around_scalar_init,
179                    IList->getSourceRange());
180      hadError = true;
181      ++Index;
182      return;
183    }
184    Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
185    if (SemaRef->CheckSingleInitializer(expr, DeclType))
186      hadError = true; // types weren't compatible.
187    else if (savExpr != expr)
188      // The type was promoted, update initializer list.
189      IList->setInit(Index, expr);
190    ++Index;
191  } else {
192    SemaRef->Diag(IList->getLocStart(),
193                  diag::err_empty_scalar_initializer,
194                  IList->getSourceRange());
195    hadError = true;
196    return;
197  }
198}
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;
211      CheckSubElementType(IList, elementType, Index);
212    }
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;
224      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;
234    CheckSubElementType(IList, elementType, Index);
235  }
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,
256                                            unsigned &Index) {
257  RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
258
259  // 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;
277    }
278    CheckSubElementType(IList, curField->getType(), Index);
279    if (DeclType->isUnionType())
280      break;
281  }
282  // 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!)
285}
286} // end namespace clang
287
288