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