SemaInit.cpp revision 396f0bfd4b2189452914893ce69f5fb068d0ec22
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//
100cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//  This file implements semantic analysis for initializers.
110cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//
120cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff//===----------------------------------------------------------------------===//
130cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
140cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff#include "Sema.h"
150cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff#include "clang/AST/ASTContext.h"
160cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff#include "clang/AST/Expr.h"
1712bc692a78582f1cc32791325981aadcffb04c5eDaniel Dunbar#include "clang/Basic/Diagnostic.h"
180cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
190cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroffnamespace clang {
200cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
210cca749f64ff54476df3a4fc084821b8a8d712d5Steve NaroffInitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
220cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  hadError = false;
230cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  SemaRef = S;
24c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman
25b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  unsigned newIndex = 0;
26c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman
27b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  CheckExplicitInitList(IL, T, newIndex);
280cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
290cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
300cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroffint InitListChecker::numArrayElements(QualType DeclType) {
31638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman  // FIXME: use a proper constant
32638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman  int maxElements = 0x7FFFFFFF;
33c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const ConstantArrayType *CAT =
34c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner        SemaRef->Context.getAsConstantArrayType(DeclType)) {
350cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    maxElements = static_cast<int>(CAT->getSize().getZExtValue());
360cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
370cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  return maxElements;
380cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
390cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
400cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroffint InitListChecker::numStructUnionElements(QualType DeclType) {
410cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
42f84eda37251c679e2f20343c47a4a3586d9a8e21Eli Friedman  int InitializableMembers = 0;
43f84eda37251c679e2f20343c47a4a3586d9a8e21Eli Friedman  for (int i = 0; i < structDecl->getNumMembers(); i++)
44f84eda37251c679e2f20343c47a4a3586d9a8e21Eli Friedman    if (structDecl->getMember(i)->getIdentifier())
45f84eda37251c679e2f20343c47a4a3586d9a8e21Eli Friedman      ++InitializableMembers;
4639ba4aeca296b1c9f04bde7d9d3cbbf129f1abd3Argyrios Kyrtzidis  if (structDecl->isUnion())
47f84eda37251c679e2f20343c47a4a3586d9a8e21Eli Friedman    return std::min(InitializableMembers, 1);
48f84eda37251c679e2f20343c47a4a3586d9a8e21Eli Friedman  return InitializableMembers - structDecl->hasFlexibleArrayMember();
490cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
500cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
510cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroffvoid InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
520cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff                                            QualType T, unsigned &Index) {
530cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  llvm::SmallVector<Expr*, 4> InitExprs;
540cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  int maxElements = 0;
550cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
560cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  if (T->isArrayType())
570cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    maxElements = numArrayElements(T);
580cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  else if (T->isStructureType() || T->isUnionType())
590cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    maxElements = numStructUnionElements(T);
60b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  else if (T->isVectorType())
61b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    maxElements = T->getAsVectorType()->getNumElements();
620cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  else
630cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    assert(0 && "CheckImplicitInitList(): Illegal type");
64b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman
65402256fc665ba179873ffcb4d630e28cbea42f27Eli Friedman  if (maxElements == 0) {
66402256fc665ba179873ffcb4d630e28cbea42f27Eli Friedman    SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(),
67402256fc665ba179873ffcb4d630e28cbea42f27Eli Friedman                  diag::err_implicit_empty_initializer);
68402256fc665ba179873ffcb4d630e28cbea42f27Eli Friedman    hadError = true;
69402256fc665ba179873ffcb4d630e28cbea42f27Eli Friedman    return;
70402256fc665ba179873ffcb4d630e28cbea42f27Eli Friedman  }
71402256fc665ba179873ffcb4d630e28cbea42f27Eli Friedman
72b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // Check the element types *before* we create the implicit init list;
73b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // otherwise, we might end up taking the wrong number of elements
74b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  unsigned NewIndex = Index;
75b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  CheckListElementTypes(ParentIList, T, NewIndex);
76b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman
770cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  for (int i = 0; i < maxElements; ++i) {
780cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    // Don't attempt to go past the end of the init list
790cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    if (Index >= ParentIList->getNumInits())
800cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      break;
810cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    Expr* expr = ParentIList->getInit(Index);
820cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
830cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    // Add the expr to the new implicit init list and remove if from the old.
840cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    InitExprs.push_back(expr);
850cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    ParentIList->removeInit(Index);
860cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
870cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
880cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  InitListExpr *ILE = new InitListExpr(SourceLocation(),
890cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff                                       &InitExprs[0], InitExprs.size(),
900cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff                                       SourceLocation());
910cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  ILE->setType(T);
92c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman
930cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  // Modify the parent InitListExpr to point to the implicit InitListExpr.
940cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  ParentIList->addInit(Index, ILE);
950cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
960cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
97a647caad2dec67ac25b763f06237cfe3c3968b51Steve Naroffvoid InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
980cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff                                            unsigned &Index) {
99c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman  assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
100c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman
101b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  CheckListElementTypes(IList, T, Index);
102a647caad2dec67ac25b763f06237cfe3c3968b51Steve Naroff  IList->setType(T);
103638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman  if (hadError)
104638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman    return;
105c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman
106638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman  if (Index < IList->getNumInits()) {
107c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    // We have leftover initializers
108c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    if (IList->getNumInits() > 0 &&
109c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman        SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) {
110bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman      // Special-case
111c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman      SemaRef->Diag(IList->getInit(Index)->getLocStart(),
112c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman                    diag::err_excess_initializers_in_char_array_initializer,
113c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman                    IList->getInit(Index)->getSourceRange());
114c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman      hadError = true;
115d8dc2100487640d8f5ce53201fdcfac7b5ca32b2Eli Friedman    } else if (!T->isIncompleteType()) {
116d8dc2100487640d8f5ce53201fdcfac7b5ca32b2Eli Friedman      // Don't warn for incomplete types, since we'll get an error elsewhere
117c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman      SemaRef->Diag(IList->getInit(Index)->getLocStart(),
118c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman                    diag::warn_excess_initializers,
119c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman                    IList->getInit(Index)->getSourceRange());
120c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    }
121c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman  }
122cda25a977e4b7fe4e080b87586410eaeab7b62f6Eli Friedman
123638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman  if (T->isScalarType())
124cda25a977e4b7fe4e080b87586410eaeab7b62f6Eli Friedman    SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init,
125cda25a977e4b7fe4e080b87586410eaeab7b62f6Eli Friedman                  IList->getSourceRange());
1260cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
1270cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
128b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedmanvoid InitListChecker::CheckListElementTypes(InitListExpr *IList,
129b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman                                            QualType &DeclType,
130b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman                                            unsigned &Index) {
131c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman  if (DeclType->isScalarType()) {
1320cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    CheckScalarType(IList, DeclType, Index);
133c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman  } else if (DeclType->isVectorType()) {
1340cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    CheckVectorType(IList, DeclType, Index);
135c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman  } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
1360cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    if (DeclType->isStructureType() || DeclType->isUnionType())
1370cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      CheckStructUnionTypes(IList, DeclType, Index);
1380cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    else if (DeclType->isArrayType())
1390cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      CheckArrayType(IList, DeclType, Index);
1400cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    else
1410cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      assert(0 && "Aggregate that isn't a function or array?!");
142613535273b90dc5cbd0f9fa056dedc93801ea35aSteve Naroff  } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
143613535273b90dc5cbd0f9fa056dedc93801ea35aSteve Naroff    // This type is invalid, issue a diagnostic.
144d8dc2100487640d8f5ce53201fdcfac7b5ca32b2Eli Friedman    Index++;
145613535273b90dc5cbd0f9fa056dedc93801ea35aSteve Naroff    SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type,
146613535273b90dc5cbd0f9fa056dedc93801ea35aSteve Naroff                  DeclType.getAsString());
147d8dc2100487640d8f5ce53201fdcfac7b5ca32b2Eli Friedman    hadError = true;
1480cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  } else {
1490cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    // In C, all types are either scalars or aggregates, but
1500cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    // additional handling is needed here for C++ (and possibly others?).
1510cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    assert(0 && "Unsupported initializer type");
1520cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
1530cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
1540cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
155b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedmanvoid InitListChecker::CheckSubElementType(InitListExpr *IList,
156b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman                                          QualType ElemType,
157b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman                                          unsigned &Index) {
158b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  Expr* expr = IList->getInit(Index);
159c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman  if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
160c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    unsigned newIndex = 0;
161c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    CheckExplicitInitList(SubInitList, ElemType, newIndex);
162c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    Index++;
163b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  } else if (StringLiteral *lit =
164b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman             SemaRef->IsStringLiteralInit(expr, ElemType)) {
165b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    SemaRef->CheckStringLiteralInit(lit, ElemType);
166b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    Index++;
167c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman  } else if (ElemType->isScalarType()) {
168c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    CheckScalarType(IList, ElemType, Index);
169b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  } else if (expr->getType()->getAsRecordType() &&
170c92e5e4e4d632343b1f5b34cbd1d583666b1f4f8Eli Friedman             SemaRef->Context.typesAreCompatible(
171c92e5e4e4d632343b1f5b34cbd1d583666b1f4f8Eli Friedman               expr->getType().getUnqualifiedType(),
172c92e5e4e4d632343b1f5b34cbd1d583666b1f4f8Eli Friedman               ElemType.getUnqualifiedType())) {
173b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    Index++;
174b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    // FIXME: Add checking
175b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  } else {
176b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    CheckImplicitInitList(IList, ElemType, Index);
177b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    Index++;
178b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  }
179b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman}
180b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman
1810cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroffvoid InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
1820cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff                                      unsigned &Index) {
1830cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  if (Index < IList->getNumInits()) {
1840cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    Expr* expr = IList->getInit(Index);
185c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    if (isa<InitListExpr>(expr)) {
186bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman      SemaRef->Diag(IList->getLocStart(),
187bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman                    diag::err_many_braces_around_scalar_init,
188bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman                    IList->getSourceRange());
189bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman      hadError = true;
190bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman      ++Index;
191bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman      return;
1920cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    }
193c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer.
194c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    if (SemaRef->CheckSingleInitializer(expr, DeclType))
195bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman      hadError = true; // types weren't compatible.
196c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman    else if (savExpr != expr)
197c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman      // The type was promoted, update initializer list.
198c9c0ea6576666eb7e96508f6b8ce2b4d33af3f02Eli Friedman      IList->setInit(Index, expr);
1990cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    ++Index;
200bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman  } else {
201bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman    SemaRef->Diag(IList->getLocStart(),
202bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman                  diag::err_empty_scalar_initializer,
203bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman                  IList->getSourceRange());
204bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman    hadError = true;
205bb504d3a63e0e4b2439900ba6d77b620fb6de857Eli Friedman    return;
2060cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
2070cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
2080cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
2090cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroffvoid InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
2100cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff                                      unsigned &Index) {
2110cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  if (Index < IList->getNumInits()) {
2120cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    const VectorType *VT = DeclType->getAsVectorType();
2130cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    int maxElements = VT->getNumElements();
2140cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    QualType elementType = VT->getElementType();
2150cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
2160cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    for (int i = 0; i < maxElements; ++i) {
2170cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      // Don't attempt to go past the end of the init list
2180cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      if (Index >= IList->getNumInits())
2190cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff        break;
220b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman      CheckSubElementType(IList, elementType, Index);
2210cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    }
2220cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
2230cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
2240cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
2250cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroffvoid InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
2260cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff                                     unsigned &Index) {
2270cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  // Check for the special-case of initializing an array with a string.
2280cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  if (Index < IList->getNumInits()) {
2290cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    if (StringLiteral *lit =
2300cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff        SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
2310cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      SemaRef->CheckStringLiteralInit(lit, DeclType);
2320cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      ++Index;
2330cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      return;
2340cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    }
2350cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
236c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  if (const VariableArrayType *VAT =
237c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner        SemaRef->Context.getAsVariableArrayType(DeclType)) {
238638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman    // Check for VLAs; in standard C it would be possible to check this
239638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman    // earlier, but I don't know where clang accepts VLAs (gcc accepts
240638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman    // them in all sorts of strange places).
241638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman    SemaRef->Diag(VAT->getSizeExpr()->getLocStart(),
242638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman                  diag::err_variable_object_no_init,
243638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman                  VAT->getSizeExpr()->getSourceRange());
244638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman    hadError = true;
245638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman    return;
246638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman  }
247638e14413a4557c399fa2b7da2be5e4e9c1330a2Eli Friedman
2480cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  int maxElements = numArrayElements(DeclType);
249c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner  QualType elementType = SemaRef->Context.getAsArrayType(DeclType)
250c63a1f276f7b324fd9a4be82098b1c8f7bf30733Chris Lattner                             ->getElementType();
2510cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  int numElements = 0;
2520cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  for (int i = 0; i < maxElements; ++i, ++numElements) {
2530cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    // Don't attempt to go past the end of the init list
2540cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    if (Index >= IList->getNumInits())
2550cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      break;
256b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    CheckSubElementType(IList, elementType, Index);
2570cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
2580cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  if (DeclType->isIncompleteArrayType()) {
2590cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    // If this is an incomplete array type, the actual type needs to
260396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar    // be calculated here.
2610cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    if (numElements == 0) {
262396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar      // Sizing an array implicitly to zero is not allowed by ISO C,
263396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar      // but is supported by GNU.
2640cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff      SemaRef->Diag(IList->getLocStart(),
265396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar                    diag::ext_typecheck_zero_array_size);
2660cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    }
267396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar
268396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar    llvm::APSInt ConstVal(32);
269396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar    ConstVal = numElements;
270396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar    DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal,
271396f0bfd4b2189452914893ce69f5fb068d0ec22Daniel Dunbar                                                     ArrayType::Normal, 0);
2720cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
2730cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
2740cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
2750cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroffvoid InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
2760cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff                                            QualType DeclType,
277b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman                                            unsigned &Index) {
278b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
2790cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
280b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // If the record is invalid, some of it's members are invalid. To avoid
281b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // confusion, we forgo checking the intializer for the entire record.
282b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  if (structDecl->isInvalidDecl()) {
283b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    hadError = true;
284b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    return;
285b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  }
286b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // If structDecl is a forward declaration, this loop won't do anything;
287b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // That's okay, because an error should get printed out elsewhere. It
288b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // might be worthwhile to skip over the rest of the initializer, though.
2891bb516c8615714317c72ec8065cc3177714d336eEli Friedman  int numMembers = DeclType->getAsRecordType()->getDecl()->getNumMembers() -
2901bb516c8615714317c72ec8065cc3177714d336eEli Friedman                   structDecl->hasFlexibleArrayMember();
291b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  for (int i = 0; i < numMembers; i++) {
292b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    // Don't attempt to go past the end of the init list
293b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    if (Index >= IList->getNumInits())
294b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman      break;
295b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    FieldDecl * curField = structDecl->getMember(i);
296b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    if (!curField->getIdentifier()) {
297b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman      // Don't initialize unnamed fields, e.g. "int : 20;"
298b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman      continue;
2990cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff    }
300b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    CheckSubElementType(IList, curField->getType(), Index);
301b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman    if (DeclType->isUnionType())
302b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman      break;
3030cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff  }
304b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // FIXME: Implement flexible array initialization GCC extension (it's a
305b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // really messy extension to implement, unfortunately...the necessary
306b85f70719da9ce5a3ca9c801ee0748732e2660eeEli Friedman  // information isn't actually even here!)
3070cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff}
3080cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff} // end namespace clang
3090cca749f64ff54476df3a4fc084821b8a8d712d5Steve Naroff
310