SemaInit.cpp revision 604dacf4819600ad0f1ba49c6e7ede0f9ae26963
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 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() || DeclType->isFunctionType()) { 143 // This type is invalid, issue a diagnostic. 144 Index++; 145 SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type, 146 DeclType.getAsString()); 147 hadError = true; 148 } else { 149 // In C, all types are either scalars or aggregates, but 150 // additional handling is needed here for C++ (and possibly others?). 151 assert(0 && "Unsupported initializer type"); 152 } 153} 154 155void InitListChecker::CheckSubElementType(InitListExpr *IList, 156 QualType ElemType, 157 unsigned &Index) { 158 Expr* expr = IList->getInit(Index); 159 if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) { 160 unsigned newIndex = 0; 161 CheckExplicitInitList(SubInitList, ElemType, newIndex); 162 Index++; 163 } else if (StringLiteral *lit = 164 SemaRef->IsStringLiteralInit(expr, ElemType)) { 165 SemaRef->CheckStringLiteralInit(lit, ElemType); 166 Index++; 167 } else if (ElemType->isScalarType()) { 168 CheckScalarType(IList, ElemType, Index); 169 } else if (expr->getType()->getAsRecordType() && 170 SemaRef->Context.typesAreCompatible( 171 expr->getType().getUnqualifiedType(), 172 ElemType.getUnqualifiedType())) { 173 Index++; 174 // FIXME: Add checking 175 } else { 176 CheckImplicitInitList(IList, ElemType, Index); 177 Index++; 178 } 179} 180 181void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType, 182 unsigned &Index) { 183 if (Index < IList->getNumInits()) { 184 Expr* expr = IList->getInit(Index); 185 if (isa<InitListExpr>(expr)) { 186 SemaRef->Diag(IList->getLocStart(), 187 diag::err_many_braces_around_scalar_init, 188 IList->getSourceRange()); 189 hadError = true; 190 ++Index; 191 return; 192 } 193 Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer. 194 if (SemaRef->CheckSingleInitializer(expr, DeclType)) 195 hadError = true; // types weren't compatible. 196 else if (savExpr != expr) 197 // The type was promoted, update initializer list. 198 IList->setInit(Index, expr); 199 ++Index; 200 } else { 201 SemaRef->Diag(IList->getLocStart(), 202 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