/// GetNumNonZeroBytesInInit - Get an approximate count of the number of /// non-zero bytes that will be stored when outputting the initializer for the /// specified initializer expression. static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { E = E->IgnoreParens(); // 0 and 0.0 won't require any non-zero stores! if (isSimpleZero(E, CGF)) return CharUnits::Zero(); // If this is an initlist expr, sum up the size of sizes of the (present) // elements. If this is something weird, assume the whole thing is non-zero. const InitListExpr *ILE = dyn_cast<InitListExpr>(E); if (ILE == 0 || !CGF.getTypes().isZeroInitializable(ILE->getType())) return CGF.getContext().getTypeSizeInChars(E->getType()); // InitListExprs for structs have to be handled carefully. If there are // reference members, we need to consider the size of the reference, not the // referencee. InitListExprs for unions and arrays can't have references. if (const RecordType *RT = E->getType()->getAs<RecordType>()) { if (!RT->isUnionType()) { RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl(); CharUnits NumNonZeroBytes = CharUnits::Zero(); unsigned ILEElement = 0; for (RecordDecl::field_iterator Field = SD->field_begin(), FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) { // We're done once we hit the flexible array member or run out of // InitListExpr elements. if (Field->getType()->isIncompleteArrayType() || ILEElement == ILE->getNumInits()) break; if (Field->isUnnamedBitfield()) continue; const Expr *E = ILE->getInit(ILEElement++); // Reference values are always non-null and have the width of a pointer. if (Field->getType()->isReferenceType()) NumNonZeroBytes += CGF.getContext().toCharUnitsFromBits( CGF.getContext().getTargetInfo().getPointerWidth(0)); else NumNonZeroBytes += GetNumNonZeroBytesInInit(E, CGF); } return NumNonZeroBytes; } } CharUnits NumNonZeroBytes = CharUnits::Zero(); for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF); return NumNonZeroBytes; }
//--------------------------------------------------------- void VisitInitListExpr(InitListExpr *RHS) { unsigned elementNo = 0; for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i) { // how to handle? if (i->isUnnamedBitfield()) continue; compoundStmts.push_back(Assign_( MemberPoint_(Paren_(Clone_(LHS)), *i), elementNo < RHS->getNumInits() ? Clone_ (RHS->getInit(elementNo)) : Int_(0))); elementNo++; } }
void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { #if 0 // FIXME: Assess perf here? Figure out what cases are worth optimizing here // (Length of globals? Chunks of zeroed-out space?). // // If we can, prefer a copy from a global; this is a lot less code for long // globals, and it's easier for the current optimizers to analyze. if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) { llvm::GlobalVariable* GV = new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true, llvm::GlobalValue::InternalLinkage, C, ""); EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType())); return; } #endif if (E->hadArrayRangeDesignator()) CGF.ErrorUnsupported(E, "GNU array range designator extension"); llvm::Value *DestPtr = Dest.getAddr(); // Handle initialization of an array. if (E->getType()->isArrayType()) { llvm::PointerType *APType = cast<llvm::PointerType>(DestPtr->getType()); llvm::ArrayType *AType = cast<llvm::ArrayType>(APType->getElementType()); uint64_t NumInitElements = E->getNumInits(); if (E->getNumInits() > 0) { QualType T1 = E->getType(); QualType T2 = E->getInit(0)->getType(); if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) { EmitAggLoadOfLValue(E->getInit(0)); return; } } uint64_t NumArrayElements = AType->getNumElements(); assert(NumInitElements <= NumArrayElements); QualType elementType = E->getType().getCanonicalType(); elementType = CGF.getContext().getQualifiedType( cast<ArrayType>(elementType)->getElementType(), elementType.getQualifiers() + Dest.getQualifiers()); // DestPtr is an array*. Construct an elementType* by drilling // down a level. llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); llvm::Value *indices[] = { zero, zero }; llvm::Value *begin = Builder.CreateInBoundsGEP(DestPtr, indices, "arrayinit.begin"); // Exception safety requires us to destroy all the // already-constructed members if an initializer throws. // For that, we'll need an EH cleanup. QualType::DestructionKind dtorKind = elementType.isDestructedType(); llvm::AllocaInst *endOfInit = 0; EHScopeStack::stable_iterator cleanup; llvm::Instruction *cleanupDominator = 0; if (CGF.needsEHCleanup(dtorKind)) { // In principle we could tell the cleanup where we are more // directly, but the control flow can get so varied here that it // would actually be quite complex. Therefore we go through an // alloca. endOfInit = CGF.CreateTempAlloca(begin->getType(), "arrayinit.endOfInit"); cleanupDominator = Builder.CreateStore(begin, endOfInit); CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType, CGF.getDestroyer(dtorKind)); cleanup = CGF.EHStack.stable_begin(); // Otherwise, remember that we didn't need a cleanup. } else { dtorKind = QualType::DK_none; } llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1); // The 'current element to initialize'. The invariants on this // variable are complicated. Essentially, after each iteration of // the loop, it points to the last initialized element, except // that it points to the beginning of the array before any // elements have been initialized. llvm::Value *element = begin; // Emit the explicit initializers. for (uint64_t i = 0; i != NumInitElements; ++i) { // Advance to the next element. if (i > 0) { element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element"); // Tell the cleanup that it needs to destroy up to this // element. TODO: some of these stores can be trivially // observed to be unnecessary. if (endOfInit) Builder.CreateStore(element, endOfInit); } LValue elementLV = CGF.MakeAddrLValue(element, elementType); EmitInitializationToLValue(E->getInit(i), elementLV); } // Check whether there's a non-trivial array-fill expression. // Note that this will be a CXXConstructExpr even if the element // type is an array (or array of array, etc.) of class type. Expr *filler = E->getArrayFiller(); bool hasTrivialFiller = true; if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) { assert(cons->getConstructor()->isDefaultConstructor()); hasTrivialFiller = cons->getConstructor()->isTrivial(); } // Any remaining elements need to be zero-initialized, possibly // using the filler expression. We can skip this if the we're // emitting to zeroed memory. if (NumInitElements != NumArrayElements && !(Dest.isZeroed() && hasTrivialFiller && CGF.getTypes().isZeroInitializable(elementType))) { // Use an actual loop. This is basically // do { *array++ = filler; } while (array != end); // Advance to the start of the rest of the array. if (NumInitElements) { element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start"); if (endOfInit) Builder.CreateStore(element, endOfInit); } // Compute the end of the array. llvm::Value *end = Builder.CreateInBoundsGEP(begin, llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements), "arrayinit.end"); llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body"); // Jump into the body. CGF.EmitBlock(bodyBB); llvm::PHINode *currentElement = Builder.CreatePHI(element->getType(), 2, "arrayinit.cur"); currentElement->addIncoming(element, entryBB); // Emit the actual filler expression. LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType); if (filler) EmitInitializationToLValue(filler, elementLV); else EmitNullInitializationToLValue(elementLV); // Move on to the next element. llvm::Value *nextElement = Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next"); // Tell the EH cleanup that we finished with the last element. if (endOfInit) Builder.CreateStore(nextElement, endOfInit); // Leave the loop if we're done. llvm::Value *done = Builder.CreateICmpEQ(nextElement, end, "arrayinit.done"); llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end"); Builder.CreateCondBr(done, endBB, bodyBB); currentElement->addIncoming(nextElement, Builder.GetInsertBlock()); CGF.EmitBlock(endBB); } // Leave the partial-array cleanup if we entered one. if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator); return; } assert(E->getType()->isRecordType() && "Only support structs/unions here!"); // Do struct initialization; this code just sets each individual member // to the approprate value. This makes bitfield support automatic; // the disadvantage is that the generated code is more difficult for // the optimizer, especially with bitfields. unsigned NumInitElements = E->getNumInits(); RecordDecl *record = E->getType()->castAs<RecordType>()->getDecl(); if (record->isUnion()) { // Only initialize one field of a union. The field itself is // specified by the initializer list. if (!E->getInitializedFieldInUnion()) { // Empty union; we have nothing to do. #ifndef NDEBUG // Make sure that it's really an empty and not a failure of // semantic analysis. for (RecordDecl::field_iterator Field = record->field_begin(), FieldEnd = record->field_end(); Field != FieldEnd; ++Field) assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed"); #endif return; } // FIXME: volatility FieldDecl *Field = E->getInitializedFieldInUnion(); LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0); if (NumInitElements) { // Store the initializer into the field EmitInitializationToLValue(E->getInit(0), FieldLoc); } else { // Default-initialize to null. EmitNullInitializationToLValue(FieldLoc); } return; } // We'll need to enter cleanup scopes in case any of the member // initializers throw an exception. SmallVector<EHScopeStack::stable_iterator, 16> cleanups; llvm::Instruction *cleanupDominator = 0; // Here we iterate over the fields; this makes it simpler to both // default-initialize fields and skip over unnamed fields. unsigned curInitIndex = 0; for (RecordDecl::field_iterator field = record->field_begin(), fieldEnd = record->field_end(); field != fieldEnd; ++field) { // We're done once we hit the flexible array member. if (field->getType()->isIncompleteArrayType()) break; // Always skip anonymous bitfields. if (field->isUnnamedBitfield()) continue; // We're done if we reach the end of the explicit initializers, we // have a zeroed object, and the rest of the fields are // zero-initializable. if (curInitIndex == NumInitElements && Dest.isZeroed() && CGF.getTypes().isZeroInitializable(E->getType())) break; // FIXME: volatility LValue LV = CGF.EmitLValueForFieldInitialization(DestPtr, *field, 0); // We never generate write-barries for initialized fields. LV.setNonGC(true); if (curInitIndex < NumInitElements) { // Store the initializer into the field. EmitInitializationToLValue(E->getInit(curInitIndex++), LV); } else { // We're out of initalizers; default-initialize to null EmitNullInitializationToLValue(LV); } // Push a destructor if necessary. // FIXME: if we have an array of structures, all explicitly // initialized, we can end up pushing a linear number of cleanups. bool pushedCleanup = false; if (QualType::DestructionKind dtorKind = field->getType().isDestructedType()) { assert(LV.isSimple()); if (CGF.needsEHCleanup(dtorKind)) { if (!cleanupDominator) cleanupDominator = CGF.Builder.CreateUnreachable(); // placeholder CGF.pushDestroy(EHCleanup, LV.getAddress(), field->getType(), CGF.getDestroyer(dtorKind), false); cleanups.push_back(CGF.EHStack.stable_begin()); pushedCleanup = true; } } // If the GEP didn't get used because of a dead zero init or something // else, clean it up for -O0 builds and general tidiness. if (!pushedCleanup && LV.isSimple()) if (llvm::GetElementPtrInst *GEP = dyn_cast<llvm::GetElementPtrInst>(LV.getAddress())) if (GEP->use_empty()) GEP->eraseFromParent(); } // Deactivate all the partial cleanups in reverse order, which // generally means popping them. for (unsigned i = cleanups.size(); i != 0; --i) CGF.DeactivateCleanupBlock(cleanups[i-1], cleanupDominator); // Destroy the placeholder if we made one. if (cleanupDominator) cleanupDominator->eraseFromParent(); }
void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { #if 0 // FIXME: Assess perf here? Figure out what cases are worth optimizing here // (Length of globals? Chunks of zeroed-out space?). // // If we can, prefer a copy from a global; this is a lot less code for long // globals, and it's easier for the current optimizers to analyze. if (llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, E->getType(), &CGF)) { llvm::GlobalVariable* GV = new llvm::GlobalVariable(CGF.CGM.getModule(), C->getType(), true, llvm::GlobalValue::InternalLinkage, C, ""); EmitFinalDestCopy(E, CGF.MakeAddrLValue(GV, E->getType())); return; } #endif if (E->hadArrayRangeDesignator()) { CGF.ErrorUnsupported(E, "GNU array range designator extension"); } // Handle initialization of an array. if (E->getType()->isArrayType()) { const llvm::PointerType *APType = cast<llvm::PointerType>(DestPtr->getType()); const llvm::ArrayType *AType = cast<llvm::ArrayType>(APType->getElementType()); uint64_t NumInitElements = E->getNumInits(); if (E->getNumInits() > 0) { QualType T1 = E->getType(); QualType T2 = E->getInit(0)->getType(); if (CGF.getContext().hasSameUnqualifiedType(T1, T2)) { EmitAggLoadOfLValue(E->getInit(0)); return; } } uint64_t NumArrayElements = AType->getNumElements(); QualType ElementType = CGF.getContext().getCanonicalType(E->getType()); ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType(); // FIXME: were we intentionally ignoring address spaces and GC attributes? for (uint64_t i = 0; i != NumArrayElements; ++i) { llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array"); LValue LV = CGF.MakeAddrLValue(NextVal, ElementType); if (i < NumInitElements) EmitInitializationToLValue(E->getInit(i), LV, ElementType); else EmitNullInitializationToLValue(LV, ElementType); } return; } assert(E->getType()->isRecordType() && "Only support structs/unions here!"); // Do struct initialization; this code just sets each individual member // to the approprate value. This makes bitfield support automatic; // the disadvantage is that the generated code is more difficult for // the optimizer, especially with bitfields. unsigned NumInitElements = E->getNumInits(); RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl(); // If we're initializing the whole aggregate, just do it in place. // FIXME: This is a hack around an AST bug (PR6537). if (NumInitElements == 1 && E->getType() == E->getInit(0)->getType()) { EmitInitializationToLValue(E->getInit(0), CGF.MakeAddrLValue(DestPtr, E->getType()), E->getType()); return; } if (E->getType()->isUnionType()) { // Only initialize one field of a union. The field itself is // specified by the initializer list. if (!E->getInitializedFieldInUnion()) { // Empty union; we have nothing to do. #ifndef NDEBUG // Make sure that it's really an empty and not a failure of // semantic analysis. for (RecordDecl::field_iterator Field = SD->field_begin(), FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed"); #endif return; } // FIXME: volatility FieldDecl *Field = E->getInitializedFieldInUnion(); LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0); if (NumInitElements) { // Store the initializer into the field EmitInitializationToLValue(E->getInit(0), FieldLoc, Field->getType()); } else { // Default-initialize to null EmitNullInitializationToLValue(FieldLoc, Field->getType()); } return; } // Here we iterate over the fields; this makes it simpler to both // default-initialize fields and skip over unnamed fields. unsigned CurInitVal = 0; for (RecordDecl::field_iterator Field = SD->field_begin(), FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) { // We're done once we hit the flexible array member if (Field->getType()->isIncompleteArrayType()) break; if (Field->isUnnamedBitfield()) continue; // FIXME: volatility LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, *Field, 0); // We never generate write-barries for initialized fields. FieldLoc.setNonGC(true); if (CurInitVal < NumInitElements) { // Store the initializer into the field. EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc, Field->getType()); } else { // We're out of initalizers; default-initialize to null EmitNullInitializationToLValue(FieldLoc, Field->getType()); } } }
void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{ switch (getKind()) { case APValue::Uninitialized: Out << "<uninitialized>"; return; case APValue::Int: if (Ty->isBooleanType()) Out << (getInt().getBoolValue() ? "true" : "false"); else Out << getInt(); return; case APValue::Float: Out << GetApproxValue(getFloat()); return; case APValue::Vector: { Out << '{'; QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); getVectorElt(0).printPretty(Out, Ctx, ElemTy); for (unsigned i = 1; i != getVectorLength(); ++i) { Out << ", "; getVectorElt(i).printPretty(Out, Ctx, ElemTy); } Out << '}'; return; } case APValue::ComplexInt: Out << getComplexIntReal() << "+" << getComplexIntImag() << "i"; return; case APValue::ComplexFloat: Out << GetApproxValue(getComplexFloatReal()) << "+" << GetApproxValue(getComplexFloatImag()) << "i"; return; case APValue::LValue: { LValueBase Base = getLValueBase(); if (!Base) { Out << "0"; return; } bool IsReference = Ty->isReferenceType(); QualType InnerTy = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType(); if (InnerTy.isNull()) InnerTy = Ty; if (!hasLValuePath()) { // No lvalue path: just print the offset. CharUnits O = getLValueOffset(); CharUnits S = Ctx.getTypeSizeInChars(InnerTy); if (!O.isZero()) { if (IsReference) Out << "*("; if (O % S) { Out << "(char*)"; S = CharUnits::One(); } Out << '&'; } else if (!IsReference) Out << '&'; if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) Out << *VD; else Base.get<const Expr*>()->printPretty(Out, 0, Ctx.getPrintingPolicy()); if (!O.isZero()) { Out << " + " << (O / S); if (IsReference) Out << ')'; } return; } // We have an lvalue path. Print it out nicely. if (!IsReference) Out << '&'; else if (isLValueOnePastTheEnd()) Out << "*(&"; QualType ElemTy; if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) { Out << *VD; ElemTy = VD->getType(); } else { const Expr *E = Base.get<const Expr*>(); E->printPretty(Out, 0, Ctx.getPrintingPolicy()); ElemTy = E->getType(); } ArrayRef<LValuePathEntry> Path = getLValuePath(); const CXXRecordDecl *CastToBase = 0; for (unsigned I = 0, N = Path.size(); I != N; ++I) { if (ElemTy->getAs<RecordType>()) { // The lvalue refers to a class type, so the next path entry is a base // or member. const Decl *BaseOrMember = BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer(); if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) { CastToBase = RD; ElemTy = Ctx.getRecordType(RD); } else { const ValueDecl *VD = cast<ValueDecl>(BaseOrMember); Out << "."; if (CastToBase) Out << *CastToBase << "::"; Out << *VD; ElemTy = VD->getType(); } } else { // The lvalue must refer to an array. Out << '[' << Path[I].ArrayIndex << ']'; ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType(); } } // Handle formatting of one-past-the-end lvalues. if (isLValueOnePastTheEnd()) { // FIXME: If CastToBase is non-0, we should prefix the output with // "(CastToBase*)". Out << " + 1"; if (IsReference) Out << ')'; } return; } case APValue::Array: { const ArrayType *AT = Ctx.getAsArrayType(Ty); QualType ElemTy = AT->getElementType(); Out << '{'; if (unsigned N = getArrayInitializedElts()) { getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy); for (unsigned I = 1; I != N; ++I) { Out << ", "; if (I == 10) { // Avoid printing out the entire contents of large arrays. Out << "..."; break; } getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy); } } Out << '}'; return; } case APValue::Struct: { Out << '{'; const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl(); bool First = true; if (unsigned N = getStructNumBases()) { const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD); CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin(); for (unsigned I = 0; I != N; ++I, ++BI) { assert(BI != CD->bases_end()); if (!First) Out << ", "; getStructBase(I).printPretty(Out, Ctx, BI->getType()); First = false; } } for (RecordDecl::field_iterator FI = RD->field_begin(); FI != RD->field_end(); ++FI) { if (!First) Out << ", "; if (FI->isUnnamedBitfield()) continue; getStructField(FI->getFieldIndex()). printPretty(Out, Ctx, FI->getType()); First = false; } Out << '}'; return; } case APValue::Union: Out << '{'; if (const FieldDecl *FD = getUnionField()) { Out << "." << *FD << " = "; getUnionValue().printPretty(Out, Ctx, FD->getType()); } Out << '}'; return; case APValue::MemberPointer: // FIXME: This is not enough to unambiguously identify the member in a // multiple-inheritance scenario. if (const ValueDecl *VD = getMemberPointerDecl()) { Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD; return; } Out << "0"; return; case APValue::AddrLabelDiff: Out << "&&" << getAddrLabelDiffLHS()->getLabel()->getName(); Out << " - "; Out << "&&" << getAddrLabelDiffRHS()->getLabel()->getName(); return; } llvm_unreachable("Unknown APValue kind!"); }