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