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