SemaInit.cpp revision 4bfd223a74022ce30ac1b86683bac054ab5fac34
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/Basic/Diagnostic.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 ParentIList->hadDesignators()); 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 if (hadError) 105 return; 106 107 if (Index < IList->getNumInits()) { 108 // We have leftover initializers 109 if (IList->getNumInits() > 0 && 110 SemaRef->IsStringLiteralInit(IList->getInit(Index), T)) { 111 // Special-case 112 SemaRef->Diag(IList->getInit(Index)->getLocStart(), 113 diag::err_excess_initializers_in_char_array_initializer) 114 << IList->getInit(Index)->getSourceRange(); 115 hadError = true; 116 } else if (!T->isIncompleteType()) { 117 // Don't warn for incomplete types, since we'll get an error elsewhere 118 SemaRef->Diag(IList->getInit(Index)->getLocStart(), 119 diag::warn_excess_initializers) 120 << IList->getInit(Index)->getSourceRange(); 121 } 122 } 123 124 if (T->isScalarType()) 125 SemaRef->Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init) 126 << IList->getSourceRange(); 127} 128 129void InitListChecker::CheckListElementTypes(InitListExpr *IList, 130 QualType &DeclType, 131 unsigned &Index) { 132 if (DeclType->isScalarType()) { 133 CheckScalarType(IList, DeclType, Index); 134 } else if (DeclType->isVectorType()) { 135 CheckVectorType(IList, DeclType, Index); 136 } else if (DeclType->isAggregateType() || DeclType->isUnionType()) { 137 if (DeclType->isStructureType() || DeclType->isUnionType()) 138 CheckStructUnionTypes(IList, DeclType, Index); 139 else if (DeclType->isArrayType()) 140 CheckArrayType(IList, DeclType, Index); 141 else 142 assert(0 && "Aggregate that isn't a function or array?!"); 143 } else if (DeclType->isVoidType() || DeclType->isFunctionType()) { 144 // This type is invalid, issue a diagnostic. 145 Index++; 146 SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type) 147 << DeclType; 148 hadError = true; 149 } else { 150 // In C, all types are either scalars or aggregates, but 151 // additional handling is needed here for C++ (and possibly others?). 152 assert(0 && "Unsupported initializer type"); 153 } 154} 155 156void InitListChecker::CheckSubElementType(InitListExpr *IList, 157 QualType ElemType, 158 unsigned &Index) { 159 Expr* expr = IList->getInit(Index); 160 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) { 161 unsigned newIndex = 0; 162 CheckExplicitInitList(SubInitList, ElemType, newIndex); 163 Index++; 164 } else if (StringLiteral *lit = 165 SemaRef->IsStringLiteralInit(expr, ElemType)) { 166 SemaRef->CheckStringLiteralInit(lit, ElemType); 167 Index++; 168 } else if (ElemType->isScalarType()) { 169 CheckScalarType(IList, ElemType, Index); 170 } else if (expr->getType()->getAsRecordType() && 171 SemaRef->Context.typesAreCompatible( 172 expr->getType().getUnqualifiedType(), 173 ElemType.getUnqualifiedType())) { 174 Index++; 175 // FIXME: Add checking 176 } else { 177 CheckImplicitInitList(IList, ElemType, Index); 178 Index++; 179 } 180} 181 182void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType, 183 unsigned &Index) { 184 if (Index < IList->getNumInits()) { 185 Expr* expr = IList->getInit(Index); 186 if (isa<InitListExpr>(expr)) { 187 SemaRef->Diag(IList->getLocStart(), 188 diag::err_many_braces_around_scalar_init) 189 << IList->getSourceRange(); 190 hadError = true; 191 ++Index; 192 return; 193 } 194 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer. 195 if (SemaRef->CheckSingleInitializer(expr, DeclType)) 196 hadError = true; // types weren't compatible. 197 else if (savExpr != expr) 198 // The type was promoted, update initializer list. 199 IList->setInit(Index, expr); 200 ++Index; 201 } else { 202 SemaRef->Diag(IList->getLocStart(), diag::err_empty_scalar_initializer) 203 << IList->getSourceRange(); 204 hadError = true; 205 return; 206 } 207} 208 209void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType, 210 unsigned &Index) { 211 if (Index < IList->getNumInits()) { 212 const VectorType *VT = DeclType->getAsVectorType(); 213 int maxElements = VT->getNumElements(); 214 QualType elementType = VT->getElementType(); 215 216 for (int i = 0; i < maxElements; ++i) { 217 // Don't attempt to go past the end of the init list 218 if (Index >= IList->getNumInits()) 219 break; 220 CheckSubElementType(IList, elementType, Index); 221 } 222 } 223} 224 225void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, 226 unsigned &Index) { 227 // Check for the special-case of initializing an array with a string. 228 if (Index < IList->getNumInits()) { 229 if (StringLiteral *lit = 230 SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) { 231 SemaRef->CheckStringLiteralInit(lit, DeclType); 232 ++Index; 233 return; 234 } 235 } 236 if (const VariableArrayType *VAT = 237 SemaRef->Context.getAsVariableArrayType(DeclType)) { 238 // Check for VLAs; in standard C it would be possible to check this 239 // earlier, but I don't know where clang accepts VLAs (gcc accepts 240 // them in all sorts of strange places). 241 SemaRef->Diag(VAT->getSizeExpr()->getLocStart(), 242 diag::err_variable_object_no_init) 243 << VAT->getSizeExpr()->getSourceRange(); 244 hadError = true; 245 return; 246 } 247 248 int maxElements = numArrayElements(DeclType); 249 QualType elementType = SemaRef->Context.getAsArrayType(DeclType) 250 ->getElementType(); 251 int numElements = 0; 252 for (int i = 0; i < maxElements; ++i, ++numElements) { 253 // Don't attempt to go past the end of the init list 254 if (Index >= IList->getNumInits()) 255 break; 256 CheckSubElementType(IList, elementType, Index); 257 } 258 if (DeclType->isIncompleteArrayType()) { 259 // If this is an incomplete array type, the actual type needs to 260 // be calculated here. 261 if (numElements == 0) { 262 // Sizing an array implicitly to zero is not allowed by ISO C, 263 // but is supported by GNU. 264 SemaRef->Diag(IList->getLocStart(), 265 diag::ext_typecheck_zero_array_size); 266 } 267 268 llvm::APSInt ConstVal(32); 269 ConstVal = numElements; 270 DeclType = SemaRef->Context.getConstantArrayType(elementType, ConstVal, 271 ArrayType::Normal, 0); 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 = DeclType->getAsRecordType()->getDecl()->getNumMembers() - 290 structDecl->hasFlexibleArrayMember(); 291 for (int i = 0; i < numMembers; i++) { 292 // Don't attempt to go past the end of the init list 293 if (Index >= IList->getNumInits()) 294 break; 295 FieldDecl * curField = structDecl->getMember(i); 296 if (!curField->getIdentifier()) { 297 // Don't initialize unnamed fields, e.g. "int : 20;" 298 continue; 299 } 300 CheckSubElementType(IList, curField->getType(), Index); 301 if (DeclType->isUnionType()) 302 break; 303 } 304 // FIXME: Implement flexible array initialization GCC extension (it's a 305 // really messy extension to implement, unfortunately...the necessary 306 // information isn't actually even here!) 307} 308} // end namespace clang 309 310