SemaInit.cpp revision dcd5ef12488e4c7ea844327835896ca86b609a97
10cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//===--- SemaInit.cpp - Semantic Analysis for Initializers ----------------===//
20cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//
30cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//                     The LLVM Compiler Infrastructure
40cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//
50cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff// This file is distributed under the University of Illinois Open Source
60cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff// License. See LICENSE.TXT for details.
70cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//
80cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//===----------------------------------------------------------------------===//
90cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//
10dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner//  This file implements semantic analysis for initializers.
11dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner//
12dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner//===----------------------------------------------------------------------===//
13dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner
148b419b9b5f21cf948cf6fe788f67bf1efd97524cChris Lattner#include "Sema.h"
150cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff#include "clang/AST/ASTContext.h"
160cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff#include "clang/AST/Expr.h"
170cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff#include "clang/Basic/Diagnostic.h"
1820093b4bf698f292c664676987541d5103b65b15Douglas Gregor
19c171e3b192a372669cf622ff0b6a847f8e5b4220Douglas Gregornamespace clang {
200cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
2105c13a3411782108d65aab3c77b1a231a4963bc0Douglas GregorInitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
220cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  hadError = false;
232078bb9c9336da56ea521e98e718556b227541f6Anders Carlsson  SemaRef = S;
2479e079d3caecc0ddd7128dc038d3f8960bbab62eChris Lattner
25d6542d8efcf8389c3aab764f9e29ac284e16eda6Douglas Gregor  unsigned newIndex = 0;
2620093b4bf698f292c664676987541d5103b65b15Douglas Gregor
27c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor  CheckExplicitInitList(IL, T, newIndex);
2805c13a3411782108d65aab3c77b1a231a4963bc0Douglas Gregor}
290cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
30dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattnerint InitListChecker::numArrayElements(QualType DeclType) {
31dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner  // FIXME: use a proper constant
32dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner  int maxElements = 0x7FFFFFFF;
33dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner  if (const ConstantArrayType *CAT =
3479e079d3caecc0ddd7128dc038d3f8960bbab62eChris Lattner        SemaRef->Context.getAsConstantArrayType(DeclType)) {
358879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner    maxElements = static_cast<int>(CAT->getSize().getZExtValue());
368879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner  }
378879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner  return maxElements;
388718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman}
398718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman
408718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedmanint InitListChecker::numStructUnionElements(QualType DeclType) {
418879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner  RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
428879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner  int InitializableMembers = 0;
431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  for (int i = 0; i < structDecl->getNumMembers(); i++)
448879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner    if (structDecl->getMember(i)->getIdentifier())
458879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner      ++InitializableMembers;
468879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner  if (structDecl->isUnion())
478879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner    return std::min(InitializableMembers, 1);
488879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner  return InitializableMembers - structDecl->hasFlexibleArrayMember();
498879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner}
50220b6369d7717bfe6894b46cef055d3e763827f2Chris Lattner
51bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedmanvoid InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
52bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedman                                            QualType T, unsigned &Index) {
538879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner  llvm::SmallVector<Expr*, 4> InitExprs;
548879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner  int maxElements = 0;
558879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner
56bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedman  if (T->isArrayType())
578879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner    maxElements = numArrayElements(T);
58bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedman  else if (T->isStructureType() || T->isUnionType())
59bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedman    maxElements = numStructUnionElements(T);
60bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedman  else if (T->isVectorType())
61bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedman    maxElements = T->getAsVectorType()->getNumElements();
62bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedman  else
63bb6415c69fc6440c337970e39749d4d482d9de42Eli Friedman    assert(0 && "CheckImplicitInitList(): Illegal type");
648879e3b29d2527260c401bce0ed0e401901ef601Chris Lattner
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  if (maxElements == 0) {
66dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner    SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(),
67dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner                  diag::err_implicit_empty_initializer);
68dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner    hadError = true;
6979e079d3caecc0ddd7128dc038d3f8960bbab62eChris Lattner    return;
7079e079d3caecc0ddd7128dc038d3f8960bbab62eChris Lattner  }
7179e079d3caecc0ddd7128dc038d3f8960bbab62eChris Lattner
7279e079d3caecc0ddd7128dc038d3f8960bbab62eChris Lattner  // Check the element types *before* we create the implicit init list;
7379e079d3caecc0ddd7128dc038d3f8960bbab62eChris Lattner  // otherwise, we might end up taking the wrong number of elements
741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  unsigned NewIndex = Index;
7579e079d3caecc0ddd7128dc038d3f8960bbab62eChris Lattner  CheckListElementTypes(ParentIList, T, NewIndex);
76dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner
771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  for (int i = 0; i < maxElements; ++i) {
78dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner    // Don't attempt to go past the end of the init list
79dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner    if (Index >= ParentIList->getNumInits())
8019da8cdfb3d5cd31e06d02c7bab1eb1bd41a7949Chris Lattner      break;
81dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner    Expr* expr = ParentIList->getInit(Index);
8246a617a792bfab0d9b1e057371ea3b9540802226John McCall
8346a617a792bfab0d9b1e057371ea3b9540802226John McCall    // Add the expr to the new implicit init list and remove if from the old.
8446a617a792bfab0d9b1e057371ea3b9540802226John McCall    InitExprs.push_back(expr);
8519da8cdfb3d5cd31e06d02c7bab1eb1bd41a7949Chris Lattner    ParentIList->removeInit(Index);
86dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner  }
871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
888718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman  InitListExpr *ILE = new InitListExpr(SourceLocation(),
891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                       &InitExprs[0], InitExprs.size(),
908718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman                                       SourceLocation(),
918718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman                                       ParentIList->hadDesignators());
928718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman  ILE->setType(T);
938718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman
948718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman  // Modify the parent InitListExpr to point to the implicit InitListExpr.
958718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman  ParentIList->addInit(Index, ILE);
968718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman}
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
988718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedmanvoid InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
998718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman                                            unsigned &Index) {
1008718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman  assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
1018718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman
1028718a6a02ccc53fea758677781a8df3a8b0c41c9Eli Friedman  CheckListElementTypes(IList, T, Index);
103dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner  IList->setType(T);
104dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner  if (hadError)
105dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner    return;
106dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner
107dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner  if (Index < IList->getNumInits()) {
108dd8e0065207e953bb28b95ad9cb6b2c13f56b3b8Chris Lattner    // We have leftover initializers
1099e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    if (IList->getNumInits() > 0 &&
1109e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor        SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
1119e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor      // Special-case
1129e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor      SemaRef->Diag(IList->getInit(Index)->getLocStart(),
1139e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor                    diag::err_excess_initializers_in_char_array_initializer)
1149e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor        << IList->getInit(Index)->getSourceRange();
1159e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor      hadError = true;
1169e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    } else if (!T->isIncompleteType()) {
1179e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor      // Don't warn for incomplete types, since we'll get an error elsewhere
1189e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor      SemaRef->Diag(IList->getInit(Index)->getLocStart(),
1199e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor                    diag::warn_excess_initializers)
1209e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor        << IList->getInit(Index)->getSourceRange();
1219e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    }
1229e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor  }
1239e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor
1249e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor  if (T->isScalarType())
1259e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init)
1269e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor      << IList->getSourceRange();
1279e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor}
1289e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor
1299e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregorvoid InitListChecker::CheckListElementTypes(InitListExpr *IList,
1309e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor                                            QualType &DeclType,
1319e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor                                            unsigned &Index) {
1329e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor  if (DeclType->isScalarType()) {
1339e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    CheckScalarType(IList, DeclType, Index);
1349e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor  } else if (DeclType->isVectorType()) {
1359e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    CheckVectorType(IList, DeclType, Index);
1368b419b9b5f21cf948cf6fe788f67bf1efd97524cChris Lattner  } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
137c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    if (DeclType->isStructureType() || DeclType->isUnionType())
1380820254f97bb8925d933a3664ea1c6fca3997b97Chris Lattner      CheckStructUnionTypes(IList, DeclType, Index);
139c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    else if (DeclType->isArrayType())
140c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor      CheckArrayType(IList, DeclType, Index);
141c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    else
1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      assert(0 && "Aggregate that isn't a function or array?!");
1438ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson  } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
144987dc6a3fa0917de269c9d60b7d4f21c68b8b09fAnders Carlsson    // This type is invalid, issue a diagnostic.
1459e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    Index++;
146eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor    SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type,
147eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor                  DeclType.getAsString());
1488ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson    hadError = true;
14946f4659f9d012ca2e2050c1fc39a59666114b3f9Anders Carlsson  } else {
1509e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    // In C, all types are either scalars or aggregates, but
151eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor    // additional handling is needed here for C++ (and possibly others?).
152eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor    assert(0 && "Unsupported initializer type");
1538ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson  }
15446f4659f9d012ca2e2050c1fc39a59666114b3f9Anders Carlsson}
1551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
156c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregorvoid InitListChecker::CheckSubElementType(InitListExpr *IList,
1579e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor                                          QualType ElemType,
158eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor                                          unsigned &Index) {
159eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor  Expr* expr = IList->getInit(Index);
1608ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson  if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
16146f4659f9d012ca2e2050c1fc39a59666114b3f9Anders Carlsson    unsigned newIndex = 0;
162c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    CheckExplicitInitList(SubInitList, ElemType, newIndex);
1639e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    Index++;
1649e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor  } else if (StringLiteral *lit =
1658ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson             SemaRef->IsStringLiteralInit(expr, ElemType)) {
16646f4659f9d012ca2e2050c1fc39a59666114b3f9Anders Carlsson    SemaRef->CheckStringLiteralInit(lit, ElemType);
167c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    Index++;
1689e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor  } else if (ElemType->isScalarType()) {
1699e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    CheckScalarType(IList, ElemType, Index);
1708ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson  } else if (expr->getType()->getAsRecordType() &&
1718ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson             SemaRef->Context.typesAreCompatible(
172930d8b5ecc074cca01ecd9a522a55f55f3b72396Douglas Gregor               expr->getType().getUnqualifiedType(),
173930d8b5ecc074cca01ecd9a522a55f55f3b72396Douglas Gregor               ElemType.getUnqualifiedType())) {
174930d8b5ecc074cca01ecd9a522a55f55f3b72396Douglas Gregor    Index++;
1758ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson    // FIXME: Add checking
17646f4659f9d012ca2e2050c1fc39a59666114b3f9Anders Carlsson  } else {
1779e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    CheckImplicitInitList(IList, ElemType, Index);
1789e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor    Index++;
1798ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson  }
1802bbae5de98f486d03e10c039668182075b5569ddAnders Carlsson}
1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
182c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregorvoid InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
1839e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor                                      unsigned &Index) {
184eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor  if (Index < IList->getNumInits()) {
185eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor    Expr* expr = IList->getInit(Index);
1868ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson    if (isa<InitListExpr>(expr)) {
187784f69940755dd66cf244dd84f57a57d358e5c43Anders Carlsson      SemaRef->Diag(IList->getLocStart(),
1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                    diag::err_many_braces_around_scalar_init)
189c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor        << IList->getSourceRange();
1909e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor      hadError = true;
1919e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor      ++Index;
1928ff9e86c492c784b3ce2abe5b5d870cd6db365a8Anders Carlsson      return;
1939a8a70ef79f68db5b17d505eb9681bf161384fe8Anders Carlsson    }
194711997184366d584c9c437102cae1e9d9927b986Douglas Gregor    Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (SemaRef->CheckSingleInitializer(expr, DeclType))
196c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor      hadError = true; // types weren't compatible.
197c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    else if (savExpr != expr)
198c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor      // The type was promoted, update initializer list.
199c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor      IList->setInit(Index, expr);
200c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    ++Index;
201eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor  } else {
202eeb15d499f032bb89773ddaca2d17475122a37bbDouglas Gregor    SemaRef->Diag(IList->getLocStart(), diag::err_empty_scalar_initializer)
203c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor      << IList->getSourceRange();
204c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    hadError = true;
205c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    return;
206c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor  }
207c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor}
2089e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregor
2099e80f7252ec1b91142e41790e4491c61e14b9472Douglas Gregorvoid InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
210c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor                                      unsigned &Index) {
211c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor  if (Index < IList->getNumInits()) {
212c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor    const VectorType *VT = DeclType->getAsVectorType();
213930d8b5ecc074cca01ecd9a522a55f55f3b72396Douglas Gregor    int maxElements = VT->getNumElements();
214d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    QualType elementType = VT->getElementType();
215d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor
216d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    for (int i = 0; i < maxElements; ++i) {
217cb57fb9f91e0976f4a3382b89a2734ffa50eb6fbDouglas Gregor      // Don't attempt to go past the end of the init list
218cb57fb9f91e0976f4a3382b89a2734ffa50eb6fbDouglas Gregor      if (Index >= IList->getNumInits())
219c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor        break;
220cb57fb9f91e0976f4a3382b89a2734ffa50eb6fbDouglas Gregor      CheckSubElementType(IList, elementType, Index);
221cb57fb9f91e0976f4a3382b89a2734ffa50eb6fbDouglas Gregor    }
222c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor  }
223c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor}
224c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor
225c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregorvoid InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
226c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor                                     unsigned &Index) {
227c34ee5ef2b267a683c432ba0c342f7c3a14889d6Douglas Gregor  // Check for the special-case of initializing an array with a string.
2288b419b9b5f21cf948cf6fe788f67bf1efd97524cChris Lattner  if (Index < IList->getNumInits()) {
22968355a57bb9d5daccd3fc73e92370ba2b1a6eafbChris Lattner    if (StringLiteral *lit =
230d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor        SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
231d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor      SemaRef->CheckStringLiteralInit(lit, DeclType);
232d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor      ++Index;
233d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor      return;
234d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    }
235d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  }
236d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  if (const VariableArrayType *VAT =
237d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor        SemaRef->Context.getAsVariableArrayType(DeclType)) {
238d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    // Check for VLAs; in standard C it would be possible to check this
239d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    // earlier, but I don't know where clang accepts VLAs (gcc accepts
240d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    // them in all sorts of strange places).
241d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
242d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor                  diag::err_variable_object_no_init)
243d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor      << VAT->getSizeExpr()->getSourceRange();
244d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    hadError = true;
245d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    return;
246d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  }
247d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor
248d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  int maxElements = numArrayElements(DeclType);
249d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  QualType elementType = SemaRef->Context.getAsArrayType(DeclType)
250d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor                             ->getElementType();
251d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  int numElements = 0;
252d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  for (int i = 0; i < maxElements; ++i, ++numElements) {
253d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    // Don't attempt to go past the end of the init list
254d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    if (Index >= IList->getNumInits())
255d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor      break;
256d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    CheckSubElementType(IList, elementType, Index);
257d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  }
258d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  if (DeclType->isIncompleteArrayType()) {
259d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    // If this is an incomplete array type, the actual type needs to
260d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    // be calculated here.
261d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    if (numElements == 0) {
262d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor      // Sizing an array implicitly to zero is not allowed by ISO C,
263d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor      // but is supported by GNU.
264d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor      SemaRef->Diag(IList->getLocStart(),
265d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor                    diag::ext_typecheck_zero_array_size);
266d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    }
267d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor
268d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    llvm::APSInt ConstVal(32);
269d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    ConstVal = numElements;
270d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
271d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor                                                     ArrayType::Normal, 0);
272d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  }
273d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor}
274d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor
275d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregorvoid InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
276d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor                                            QualType DeclType,
277d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor                                            unsigned &Index) {
278d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
279d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor
280d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  // If the record is invalid, some of it's members are invalid. To avoid
281d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  // confusion, we forgo checking the intializer for the entire record.
282d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  if (structDecl->isInvalidDecl()) {
283d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    hadError = true;
284d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor    return;
285d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  }
286d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  // If structDecl is a forward declaration, this loop won't do anything;
287d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  // That's okay, because an error should get printed out elsewhere. It
288d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  // might be worthwhile to skip over the rest of the initializer, though.
289d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  int numMembers = DeclType->getAsRecordType()->getDecl()->getNumMembers() -
290d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor                   structDecl->hasFlexibleArrayMember();
291d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  for (int i = 0; i < numMembers; i++) {
2924c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor    // Don't attempt to go past the end of the init list
2934c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor    if (Index >= IList->getNumInits())
2944c67834407ca6ab344dcf44fc599ad4938cfa96dDouglas Gregor      break;
295cb57fb9f91e0976f4a3382b89a2734ffa50eb6fbDouglas Gregor    FieldDecl * curField = structDecl->getMember(i);
296cb57fb9f91e0976f4a3382b89a2734ffa50eb6fbDouglas Gregor    if (!curField->getIdentifier()) {
297cb57fb9f91e0976f4a3382b89a2734ffa50eb6fbDouglas Gregor      // Don't initialize unnamed fields, e.g. "int : 20;"
298cb57fb9f91e0976f4a3382b89a2734ffa50eb6fbDouglas Gregor      continue;
2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
300930d8b5ecc074cca01ecd9a522a55f55f3b72396Douglas Gregor    CheckSubElementType(IList, curField->getType(), Index);
30187fd703e097c27d63479cb83b687d4000a22bbb1Douglas Gregor    if (DeclType->isUnionType())
30287fd703e097c27d63479cb83b687d4000a22bbb1Douglas Gregor      break;
30387fd703e097c27d63479cb83b687d4000a22bbb1Douglas Gregor  }
3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // FIXME: Implement flexible array initialization GCC extension (it's a
3056217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  // really messy extension to implement, unfortunately...the necessary
306d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor  // information isn't actually even here!)
307d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor}
308d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor} // end namespace clang
309d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor
310d6d37dee48cfc5bbcc998bd9d151e4fb3a9437e8Douglas Gregor