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