diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp | 184 |
1 files changed, 107 insertions, 77 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp index 62c3a97..a6147ea 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CGDecl.cpp @@ -14,6 +14,7 @@ #include "CGDebugInfo.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "CGOpenCLRuntime.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" @@ -46,7 +47,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::Field: case Decl::IndirectField: case Decl::ObjCIvar: - case Decl::ObjCAtDefsField: + case Decl::ObjCAtDefsField: case Decl::ParmVar: case Decl::ImplicitParam: case Decl::ClassTemplate: @@ -70,7 +71,8 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::Friend: case Decl::FriendTemplate: case Decl::Block: - assert(0 && "Declaration should not be in declstmts!"); + case Decl::ClassScopeFunctionSpecialization: + llvm_unreachable("Declaration should not be in declstmts!"); case Decl::Function: // void X(); case Decl::Record: // struct/union/class X; case Decl::Enum: // enum X; @@ -112,7 +114,7 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) { case SC_Register: return EmitAutoVarDecl(D); case SC_Static: { - llvm::GlobalValue::LinkageTypes Linkage = + llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::InternalLinkage; // If the function definition has some sort of weak linkage, its @@ -123,26 +125,28 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) { if (getContext().getLangOptions().CPlusPlus) if (llvm::GlobalValue::isWeakForLinker(CurFn->getLinkage())) Linkage = CurFn->getLinkage(); - + return EmitStaticVarDecl(D, Linkage); } case SC_Extern: case SC_PrivateExtern: // Don't emit it now, allow it to be emitted lazily on its first use. return; + case SC_OpenCLWorkGroupLocal: + return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D); } - assert(0 && "Unknown storage class"); + llvm_unreachable("Unknown storage class"); } static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D, const char *Separator) { CodeGenModule &CGM = CGF.CGM; if (CGF.getContext().getLangOptions().CPlusPlus) { - llvm::StringRef Name = CGM.getMangledName(&D); + StringRef Name = CGM.getMangledName(&D); return Name.str(); } - + std::string ContextName; if (!CGF.CurFuncDecl) { // Better be in a block declared in global scope. @@ -154,15 +158,15 @@ static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D, ContextName = Name.getString(); } else - assert(0 && "Unknown context for block static var decl"); + llvm_unreachable("Unknown context for block static var decl"); } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) { - llvm::StringRef Name = CGM.getMangledName(FD); + StringRef Name = CGM.getMangledName(FD); ContextName = Name.str(); } else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl)) ContextName = CGF.CurFn->getName(); else - assert(0 && "Unknown context for static var decl"); - + llvm_unreachable("Unknown context for static var decl"); + return ContextName + Separator + D.getNameAsString(); } @@ -175,7 +179,7 @@ CodeGenFunction::CreateStaticVarDecl(const VarDecl &D, std::string Name = GetStaticDeclName(*this, D, Separator); - const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty); + llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty); llvm::GlobalVariable *GV = new llvm::GlobalVariable(CGM.getModule(), LTy, Ty.isConstant(getContext()), Linkage, @@ -203,7 +207,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, if (!getContext().getLangOptions().CPlusPlus) CGM.ErrorUnsupported(D.getInit(), "constant l-value expression"); else if (Builder.GetInsertBlock()) { - // Since we have a static initializer, this global variable can't + // Since we have a static initializer, this global variable can't // be constant. GV->setConstant(false); @@ -218,7 +222,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, // in the LLVM type system.) if (GV->getType()->getElementType() != Init->getType()) { llvm::GlobalVariable *OldGV = GV; - + GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), OldGV->isConstant(), OldGV->getLinkage(), Init, "", @@ -226,19 +230,19 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, D.isThreadSpecified(), CGM.getContext().getTargetAddressSpace(D.getType())); GV->setVisibility(OldGV->getVisibility()); - + // Steal the name of the old global GV->takeName(OldGV); - + // Replace all uses of the old global with the new global llvm::Constant *NewPtrForOldDecl = llvm::ConstantExpr::getBitCast(GV, OldGV->getType()); OldGV->replaceAllUsesWith(NewPtrForOldDecl); - + // Erase the old global, since it is no longer used. OldGV->eraseFromParent(); } - + GV->setInitializer(Init); return GV; } @@ -259,7 +263,7 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, // Make sure to evaluate VLA bounds now so that we have them for later. if (D.getType()->isVariablyModifiedType()) EmitVariablyModifiedType(D.getType()); - + // Local static block variables must be treated as globals as they may be // referenced in their RHS initializer block-literal expresion. CGM.setStaticLocalDeclAddress(&D, GV); @@ -270,14 +274,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, GV->setAlignment(getContext().getDeclAlign(&D).getQuantity()); - // FIXME: Merge attribute handling. - if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) { - SourceManager &SM = CGM.getContext().getSourceManager(); - llvm::Constant *Ann = - CGM.EmitAnnotateAttr(GV, AA, - SM.getInstantiationLineNumber(D.getLocation())); - CGM.AddAnnotation(Ann); - } + if (D.hasAttr<AnnotateAttr>()) + CGM.AddGlobalAnnotations(&D, GV); if (const SectionAttr *SA = D.getAttr<SectionAttr>()) GV->setSection(SA->getName()); @@ -290,8 +288,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, // // FIXME: It is really dangerous to store this in the map; if anyone // RAUW's the GV uses of this constant will be invalid. - const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType()); - const llvm::Type *LPtrTy = + llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType()); + llvm::Type *LPtrTy = LTy->getPointerTo(CGM.getContext().getTargetAddressSpace(D.getType())); DMEntry = llvm::ConstantExpr::getBitCast(GV, LPtrTy); @@ -348,7 +346,7 @@ namespace { CGF.Builder.CreateCondBr(DidNRVO, SkipDtorBB, RunDtorBB); CGF.EmitBlock(RunDtorBB); } - + CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, Loc); @@ -360,7 +358,7 @@ namespace { llvm::Value *Stack; CallStackRestore(llvm::Value *Stack) : Stack(Stack) {} void Emit(CodeGenFunction &CGF, Flags flags) { - llvm::Value *V = CGF.Builder.CreateLoad(Stack, "tmp"); + llvm::Value *V = CGF.Builder.CreateLoad(Stack); llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore); CGF.Builder.CreateCall(F, V); } @@ -384,7 +382,7 @@ namespace { llvm::Constant *CleanupFn; const CGFunctionInfo &FnInfo; const VarDecl &Var; - + CallCleanupFunction(llvm::Constant *CleanupFn, const CGFunctionInfo *Info, const VarDecl *Var) : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {} @@ -441,7 +439,7 @@ static void EmitAutoVarWithLifetime(CodeGenFunction &CGF, const VarDecl &var, case Qualifiers::OCL_Autoreleasing: // nothing to do break; - + case Qualifiers::OCL_Weak: // __weak objects always get EH cleanups; otherwise, exceptions // could cause really nasty crashes instead of mere leaks. @@ -508,7 +506,7 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, // actually perform the initialization with an assign. bool accessedByInit = false; if (lifetime != Qualifiers::OCL_ExplicitNone) - accessedByInit = isAccessedBy(D, init); + accessedByInit = (capturedByInit || isAccessedBy(D, init)); if (accessedByInit) { LValue tempLV = lvalue; // Drill down to the __block object if necessary. @@ -519,12 +517,12 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, getByRefValueLLVMField(cast<VarDecl>(D)))); } - const llvm::PointerType *ty + llvm::PointerType *ty = cast<llvm::PointerType>(tempLV.getAddress()->getType()); ty = cast<llvm::PointerType>(ty->getElementType()); llvm::Value *zero = llvm::ConstantPointerNull::get(ty); - + // If __weak, we want to use a barrier under certain conditions. if (lifetime == Qualifiers::OCL_Weak) EmitARCInitWeak(tempLV.getAddress(), zero); @@ -613,7 +611,7 @@ void CodeGenFunction::EmitScalarInit(llvm::Value *init, LValue lvalue) { break; } - EmitStoreOfScalar(init, lvalue); + EmitStoreOfScalar(init, lvalue); } /// canEmitInitWithFewStoresAfterMemset - Decide whether we can emit the @@ -640,7 +638,7 @@ static bool canEmitInitWithFewStoresAfterMemset(llvm::Constant *Init, } return true; } - + // Anything else is hard and scary. return false; } @@ -655,7 +653,7 @@ static void emitStoresForInitAfterMemset(llvm::Constant *Init, llvm::Value *Loc, isa<llvm::ConstantPointerNull>(Init) || isa<llvm::UndefValue>(Init)) return; - + if (isa<llvm::ConstantInt>(Init) || isa<llvm::ConstantFP>(Init) || isa<llvm::ConstantVector>(Init) || isa<llvm::BlockAddress>(Init) || isa<llvm::ConstantExpr>(Init)) { @@ -663,14 +661,14 @@ static void emitStoresForInitAfterMemset(llvm::Constant *Init, llvm::Value *Loc, Builder.CreateStore(Init, Loc, isVolatile); return; } - + assert((isa<llvm::ConstantStruct>(Init) || isa<llvm::ConstantArray>(Init)) && "Unknown value type!"); - + for (unsigned i = 0, e = Init->getNumOperands(); i != e; ++i) { llvm::Constant *Elt = cast<llvm::Constant>(Init->getOperand(i)); if (Elt->isNullValue()) continue; - + // Otherwise, get a pointer to the element and emit it. emitStoresForInitAfterMemset(Elt, Builder.CreateConstGEP2_32(Loc, 0, i), isVolatile, Builder); @@ -694,8 +692,8 @@ static bool shouldUseMemSetPlusStoresToInitialize(llvm::Constant *Init, // plopping in more stores. unsigned StoreBudget = 6; uint64_t SizeLimit = 32; - - return GlobalSize > SizeLimit && + + return GlobalSize > SizeLimit && canEmitInitWithFewStoresAfterMemset(Init, StoreBudget); } @@ -730,7 +728,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { llvm::Value *DeclPtr; if (Ty->isConstantSizeType()) { if (!Target.useGlobalsForAutomaticVariables()) { - bool NRVO = getContext().getLangOptions().ElideConstructors && + bool NRVO = getContext().getLangOptions().ElideConstructors && D.isNRVOVariable(); // If this value is a POD array or struct with a statically @@ -740,7 +738,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // arrays as long as the initialization is trivial (e.g. if they // have a non-trivial destructor, but not a non-trivial constructor). if (D.getInit() && - (Ty->isArrayType() || Ty->isRecordType()) && + (Ty->isArrayType() || Ty->isRecordType()) && (Ty.isPODType(getContext()) || getContext().getBaseElementType(Ty)->isObjCObjectPointerType()) && D.getInit()->isConstantInitializer(getContext(), false)) { @@ -759,27 +757,27 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // Otherwise, tell the initialization code that we're in this case. emission.IsConstantAggregate = true; } - + // A normal fixed sized variable becomes an alloca in the entry block, // unless it's an NRVO variable. - const llvm::Type *LTy = ConvertTypeForMem(Ty); - + llvm::Type *LTy = ConvertTypeForMem(Ty); + if (NRVO) { // The named return value optimization: allocate this variable in the // return slot, so that we can elide the copy when returning this // variable (C++0x [class.copy]p34). DeclPtr = ReturnValue; - + if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { if (!cast<CXXRecordDecl>(RecordTy->getDecl())->hasTrivialDestructor()) { // Create a flag that is used to indicate when the NRVO was applied - // to this variable. Set it to zero to indicate that NRVO was not + // to this variable. Set it to zero to indicate that NRVO was not // applied. llvm::Value *Zero = Builder.getFalse(); llvm::Value *NRVOFlag = CreateTempAlloca(Zero->getType(), "nrvo"); EnsureInsertPoint(); Builder.CreateStore(Zero, NRVOFlag); - + // Record the NRVO flag for this variable. NRVOFlags[&D] = NRVOFlag; emission.NRVOFlag = NRVOFlag; @@ -788,13 +786,13 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { } else { if (isByRef) LTy = BuildByRefType(&D); - + llvm::AllocaInst *Alloc = CreateTempAlloca(LTy); Alloc->setName(D.getNameAsString()); CharUnits allocaAlignment = alignment; if (isByRef) - allocaAlignment = std::max(allocaAlignment, + allocaAlignment = std::max(allocaAlignment, getContext().toCharUnitsFromBits(Target.getPointerAlign(0))); Alloc->setAlignment(allocaAlignment.getQuantity()); DeclPtr = Alloc; @@ -829,7 +827,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { QualType elementType; llvm::tie(elementCount, elementType) = getVLASize(Ty); - const llvm::Type *llvmTy = ConvertTypeForMem(elementType); + llvm::Type *llvmTy = ConvertTypeForMem(elementType); // Allocate memory for the array. llvm::AllocaInst *vla = Builder.CreateAlloca(llvmTy, elementCount, "vla"); @@ -853,6 +851,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder); } + if (D.hasAttr<AnnotateAttr>()) + EmitVarAnnotations(&D, emission.Address); + return emission; } @@ -875,6 +876,32 @@ static bool isCapturedBy(const VarDecl &var, const Expr *e) { return false; } + if (const StmtExpr *SE = dyn_cast<StmtExpr>(e)) { + const CompoundStmt *CS = SE->getSubStmt(); + for (CompoundStmt::const_body_iterator BI = CS->body_begin(), + BE = CS->body_end(); BI != BE; ++BI) + if (Expr *E = dyn_cast<Expr>((*BI))) { + if (isCapturedBy(var, E)) + return true; + } + else if (DeclStmt *DS = dyn_cast<DeclStmt>((*BI))) { + // special case declarations + for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); + I != E; ++I) { + if (VarDecl *VD = dyn_cast<VarDecl>((*I))) { + Expr *Init = VD->getInit(); + if (Init && isCapturedBy(var, Init)) + return true; + } + } + } + else + // FIXME. Make safe assumption assuming arbitrary statements cause capturing. + // Later, provide code to poke into statements for capture analysis. + return true; + return false; + } + for (Stmt::const_child_range children = e->children(); children; ++children) if (isCapturedBy(var, cast<Expr>(*children))) return true; @@ -887,14 +914,14 @@ static bool isCapturedBy(const VarDecl &var, const Expr *e) { static bool isTrivialInitializer(const Expr *Init) { if (!Init) return true; - + if (const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) if (CXXConstructorDecl *Constructor = Construct->getConstructor()) if (Constructor->isTrivial() && Constructor->isDefaultConstructor() && !Construct->requiresZeroInitialization()) return true; - + return false; } void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { @@ -922,7 +949,6 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { if (isTrivialInitializer(Init)) return; - CharUnits alignment = emission.Alignment; @@ -950,16 +976,16 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { assert(constant != 0 && "Wasn't a simple constant init?"); llvm::Value *SizeVal = - llvm::ConstantInt::get(IntPtrTy, + llvm::ConstantInt::get(IntPtrTy, getContext().getTypeSizeInChars(type).getQuantity()); - const llvm::Type *BP = Int8PtrTy; + llvm::Type *BP = Int8PtrTy; if (Loc->getType() != BP) - Loc = Builder.CreateBitCast(Loc, BP, "tmp"); + Loc = Builder.CreateBitCast(Loc, BP); // If the initializer is all or mostly zeros, codegen with memset then do // a few stores afterward. - if (shouldUseMemSetPlusStoresToInitialize(constant, + if (shouldUseMemSetPlusStoresToInitialize(constant, CGM.getTargetData().getTypeAllocSize(constant->getType()))) { Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal, alignment.getQuantity(), isVolatile); @@ -968,19 +994,19 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { emitStoresForInitAfterMemset(constant, Loc, isVolatile, Builder); } } else { - // Otherwise, create a temporary global with the initializer then + // Otherwise, create a temporary global with the initializer then // memcpy from the global to the alloca. std::string Name = GetStaticDeclName(*this, D, "."); llvm::GlobalVariable *GV = new llvm::GlobalVariable(CGM.getModule(), constant->getType(), true, - llvm::GlobalValue::InternalLinkage, + llvm::GlobalValue::PrivateLinkage, constant, Name, 0, false, 0); GV->setAlignment(alignment.getQuantity()); GV->setUnnamedAddr(true); - + llvm::Value *SrcPtr = GV; if (SrcPtr->getType() != BP) - SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp"); + SrcPtr = Builder.CreateBitCast(SrcPtr, BP); Builder.CreateMemCpy(Loc, SrcPtr, SizeVal, alignment.getQuantity(), isVolatile); @@ -1007,7 +1033,7 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init, if (type->isReferenceType()) { RValue rvalue = EmitReferenceBindingToExpr(init, D); - if (capturedByInit) + if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D)); EmitStoreThroughLValue(rvalue, lvalue); } else if (!hasAggregateLLVMType(type)) { @@ -1019,7 +1045,10 @@ void CodeGenFunction::EmitExprAsInit(const Expr *init, StoreComplexToAddr(complex, lvalue.getAddress(), lvalue.isVolatile()); } else { // TODO: how can we delay here if D is captured by its initializer? - EmitAggExpr(init, AggValueSlot::forLValue(lvalue, true, false)); + EmitAggExpr(init, AggValueSlot::forLValue(lvalue, + AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers, + AggValueSlot::IsNotAliased)); } } @@ -1058,7 +1087,7 @@ void CodeGenFunction::emitAutoVarTypeCleanup( case QualType::DK_objc_strong_lifetime: // Suppress cleanups for pseudo-strong variables. if (var->isARCPseudoStrong()) return; - + // Otherwise, consider whether to use an EH cleanup or not. cleanupKind = getARCCleanupKind(); @@ -1094,7 +1123,7 @@ void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) { emitAutoVarTypeCleanup(emission, dtorKind); // In GC mode, honor objc_precise_lifetime. - if (getLangOptions().getGCMode() != LangOptions::NonGC && + if (getLangOptions().getGC() != LangOptions::NonGC && D.hasAttr<ObjCPreciseLifetimeAttr>()) { EHStack.pushCleanup<ExtendGCLifetime>(NormalCleanup, &D); } @@ -1267,11 +1296,9 @@ static void emitPartialArrayDestroy(CodeGenFunction &CGF, if (arrayDepth) { llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, arrayDepth+1); - llvm::SmallVector<llvm::Value*,4> gepIndices(arrayDepth, zero); - begin = CGF.Builder.CreateInBoundsGEP(begin, gepIndices.begin(), - gepIndices.end(), "pad.arraybegin"); - end = CGF.Builder.CreateInBoundsGEP(end, gepIndices.begin(), - gepIndices.end(), "pad.arrayend"); + SmallVector<llvm::Value*,4> gepIndices(arrayDepth, zero); + begin = CGF.Builder.CreateInBoundsGEP(begin, gepIndices, "pad.arraybegin"); + end = CGF.Builder.CreateInBoundsGEP(end, gepIndices, "pad.arrayend"); } // Destroy the array. We don't ever need an EH cleanup because we @@ -1330,7 +1357,7 @@ namespace { /// pushIrregularPartialArrayCleanup - Push an EH cleanup to destroy /// already-constructed elements of the given array. The cleanup /// may be popped with DeactivateCleanupBlock or PopCleanupBlock. -/// +/// /// \param elementType - the immediate element type of the array; /// possibly still an array type /// \param array - a value of type elementType* @@ -1349,7 +1376,7 @@ void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, /// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy /// already-constructed elements of the given array. The cleanup /// may be popped with DeactivateCleanupBlock or PopCleanupBlock. -/// +/// /// \param elementType - the immediate element type of the array; /// possibly still an array type /// \param array - a value of type elementType* @@ -1476,4 +1503,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg, // Emit debug info for param declaration. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitDeclareOfArgVariable(&D, DeclPtr, ArgNo, Builder); + + if (D.hasAttr<AnnotateAttr>()) + EmitVarAnnotations(&D, DeclPtr); } |