diff options
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 115 |
1 files changed, 92 insertions, 23 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index a01638f0b67b..5b3d39f20b41 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -99,6 +99,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::ConstructorUsingShadow: case Decl::ObjCTypeParam: case Decl::Binding: + case Decl::UnresolvedUsingIfExists: llvm_unreachable("Declaration should not be in declstmts!"); case Decl::Record: // struct/union/class X; case Decl::CXXRecord: // struct/union/class X; [C++] @@ -137,6 +138,10 @@ void CodeGenFunction::EmitDecl(const Decl &D) { if (CGDebugInfo *DI = getDebugInfo()) DI->EmitUsingDecl(cast<UsingDecl>(D)); return; + case Decl::UsingEnum: // using enum X; [C++] + if (CGDebugInfo *DI = getDebugInfo()) + DI->EmitUsingEnumDecl(cast<UsingEnumDecl>(D)); + return; case Decl::UsingPack: for (auto *Using : cast<UsingPackDecl>(D).expansions()) EmitDecl(*Using); @@ -441,8 +446,10 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, if (const SectionAttr *SA = D.getAttr<SectionAttr>()) var->setSection(SA->getName()); - if (D.hasAttr<UsedAttr>()) + if (D.hasAttr<RetainAttr>()) CGM.addUsedGlobal(var); + else if (D.hasAttr<UsedAttr>()) + CGM.addUsedOrCompilerUsedGlobal(var); // We may have to cast the constant because of the initializer // mismatch above. @@ -548,6 +555,7 @@ namespace { struct CallStackRestore final : EHScopeStack::Cleanup { Address Stack; CallStackRestore(Address Stack) : Stack(Stack) {} + bool isRedundantBeforeReturn() override { return true; } void Emit(CodeGenFunction &CGF, Flags flags) override { llvm::Value *V = CGF.Builder.CreateLoad(Stack); llvm::Function *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore); @@ -706,10 +714,10 @@ static bool tryEmitARCCopyWeakInit(CodeGenFunction &CGF, } // If it was an l-value, use objc_copyWeak. - if (srcExpr->getValueKind() == VK_LValue) { + if (srcExpr->isLValue()) { CGF.EmitARCCopyWeak(destLV.getAddress(CGF), srcAddr); } else { - assert(srcExpr->getValueKind() == VK_XValue); + assert(srcExpr->isXValue()); CGF.EmitARCMoveWeak(destLV.getAddress(CGF), srcAddr); } return true; @@ -769,9 +777,10 @@ void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D, // If we're emitting a value with lifetime, we have to do the // initialization *before* we leave the cleanup scopes. - if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(init)) - init = EWC->getSubExpr(); - CodeGenFunction::RunCleanupsScope Scope(*this); + if (auto *EWC = dyn_cast<ExprWithCleanups>(init)) { + CodeGenFunction::RunCleanupsScope Scope(*this); + return EmitScalarInit(EWC->getSubExpr(), D, lvalue, capturedByInit); + } // We have to maintain the illusion that the variable is // zero-initialized. If the variable might be accessed in its @@ -1119,7 +1128,7 @@ Address CodeGenModule::createUnnamedGlobalFrom(const VarDecl &D, bool isConstant = true; llvm::GlobalVariable *InsertBefore = nullptr; unsigned AS = - getContext().getTargetAddressSpace(getStringLiteralAddressSpace()); + getContext().getTargetAddressSpace(GetGlobalConstantAddressSpace()); std::string Name; if (D.hasGlobalStorage()) Name = getMangledName(&D).str() + ".const"; @@ -1313,7 +1322,7 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) { /// Emit a lifetime.begin marker if some criteria are satisfied. /// \return a pointer to the temporary size Value if a marker was emitted, null /// otherwise -llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size, +llvm::Value *CodeGenFunction::EmitLifetimeStart(llvm::TypeSize Size, llvm::Value *Addr) { if (!ShouldEmitLifetimeMarkers) return nullptr; @@ -1321,7 +1330,8 @@ llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size, assert(Addr->getType()->getPointerAddressSpace() == CGM.getDataLayout().getAllocaAddrSpace() && "Pointer should be in alloca address space"); - llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size); + llvm::Value *SizeV = llvm::ConstantInt::get( + Int64Ty, Size.isScalable() ? -1 : Size.getFixedValue()); Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy); llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr}); @@ -1544,12 +1554,9 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // is rare. if (!Bypasses.IsBypassed(&D) && !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) { - llvm::TypeSize size = - CGM.getDataLayout().getTypeAllocSize(allocaTy); + llvm::TypeSize Size = CGM.getDataLayout().getTypeAllocSize(allocaTy); emission.SizeForLifetimeMarkers = - size.isScalable() ? EmitLifetimeStart(-1, AllocaAddr.getPointer()) - : EmitLifetimeStart(size.getFixedSize(), - AllocaAddr.getPointer()); + EmitLifetimeStart(Size, AllocaAddr.getPointer()); } } else { assert(!emission.useLifetimeMarkers()); @@ -1765,8 +1772,8 @@ void CodeGenFunction::emitZeroOrPatternForAutoVarInit(QualType type, llvm::Value *BaseSizeInChars = llvm::ConstantInt::get(IntPtrTy, EltSize.getQuantity()); Address Begin = Builder.CreateElementBitCast(Loc, Int8Ty, "vla.begin"); - llvm::Value *End = - Builder.CreateInBoundsGEP(Begin.getPointer(), SizeVal, "vla.end"); + llvm::Value *End = Builder.CreateInBoundsGEP( + Begin.getElementType(), Begin.getPointer(), SizeVal, "vla.end"); llvm::BasicBlock *OriginBB = Builder.GetInsertBlock(); EmitBlock(LoopBB); llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur"); @@ -2194,7 +2201,8 @@ void CodeGenFunction::emitDestroy(Address addr, QualType type, } llvm::Value *begin = addr.getPointer(); - llvm::Value *end = Builder.CreateInBoundsGEP(begin, length); + llvm::Value *end = + Builder.CreateInBoundsGEP(addr.getElementType(), begin, length); emitArrayDestroy(begin, end, type, elementAlign, destroyer, checkZeroLength, useEHCleanupForArray); } @@ -2238,8 +2246,9 @@ void CodeGenFunction::emitArrayDestroy(llvm::Value *begin, // Shift the address back by one element. llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true); - llvm::Value *element = Builder.CreateInBoundsGEP(elementPast, negativeOne, - "arraydestroy.element"); + llvm::Value *element = Builder.CreateInBoundsGEP( + elementPast->getType()->getPointerElementType(), elementPast, negativeOne, + "arraydestroy.element"); if (useEHCleanup) pushRegularPartialArrayCleanup(begin, element, elementType, elementAlign, @@ -2279,8 +2288,11 @@ static void emitPartialArrayDestroy(CodeGenFunction &CGF, llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0); SmallVector<llvm::Value*,4> gepIndices(arrayDepth+1, zero); - begin = CGF.Builder.CreateInBoundsGEP(begin, gepIndices, "pad.arraybegin"); - end = CGF.Builder.CreateInBoundsGEP(end, gepIndices, "pad.arrayend"); + llvm::Type *elemTy = begin->getType()->getPointerElementType(); + begin = CGF.Builder.CreateInBoundsGEP( + elemTy, begin, gepIndices, "pad.arraybegin"); + end = CGF.Builder.CreateInBoundsGEP( + elemTy, end, gepIndices, "pad.arrayend"); } // Destroy the array. We don't ever need an EH cleanup because we @@ -2468,7 +2480,7 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, // Push a destructor cleanup for this parameter if the ABI requires it. // Don't push a cleanup in a thunk for a method that will also emit a // cleanup. - if (hasAggregateEvaluationKind(Ty) && !CurFuncIsThunk && + if (Ty->isRecordType() && !CurFuncIsThunk && Ty->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) { if (QualType::DestructionKind DtorKind = D.needsDestruction(getContext())) { @@ -2566,7 +2578,10 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, // Emit debug info for param declarations in non-thunk functions. if (CGDebugInfo *DI = getDebugInfo()) { if (CGM.getCodeGenOpts().hasReducedDebugInfo() && !CurFuncIsThunk) { - DI->EmitDeclareOfArgVariable(&D, DeclPtr.getPointer(), ArgNo, Builder); + llvm::DILocalVariable *DILocalVar = DI->EmitDeclareOfArgVariable( + &D, DeclPtr.getPointer(), ArgNo, Builder); + if (const auto *Var = dyn_cast_or_null<ParmVarDecl>(&D)) + DI->getParamDbgMappings().insert({Var, DILocalVar}); } } @@ -2605,3 +2620,57 @@ void CodeGenModule::EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D, void CodeGenModule::EmitOMPRequiresDecl(const OMPRequiresDecl *D) { getOpenMPRuntime().processRequiresDirective(D); } + +void CodeGenModule::EmitOMPAllocateDecl(const OMPAllocateDecl *D) { + for (const Expr *E : D->varlists()) { + const auto *DE = cast<DeclRefExpr>(E); + const auto *VD = cast<VarDecl>(DE->getDecl()); + + // Skip all but globals. + if (!VD->hasGlobalStorage()) + continue; + + // Check if the global has been materialized yet or not. If not, we are done + // as any later generation will utilize the OMPAllocateDeclAttr. However, if + // we already emitted the global we might have done so before the + // OMPAllocateDeclAttr was attached, leading to the wrong address space + // (potentially). While not pretty, common practise is to remove the old IR + // global and generate a new one, so we do that here too. Uses are replaced + // properly. + StringRef MangledName = getMangledName(VD); + llvm::GlobalValue *Entry = GetGlobalValue(MangledName); + if (!Entry) + continue; + + // We can also keep the existing global if the address space is what we + // expect it to be, if not, it is replaced. + QualType ASTTy = VD->getType(); + clang::LangAS GVAS = GetGlobalVarAddressSpace(VD); + auto TargetAS = getContext().getTargetAddressSpace(GVAS); + if (Entry->getType()->getAddressSpace() == TargetAS) + continue; + + // Make a new global with the correct type / address space. + llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy); + llvm::PointerType *PTy = llvm::PointerType::get(Ty, TargetAS); + + // Replace all uses of the old global with a cast. Since we mutate the type + // in place we neeed an intermediate that takes the spot of the old entry + // until we can create the cast. + llvm::GlobalVariable *DummyGV = new llvm::GlobalVariable( + getModule(), Entry->getValueType(), false, + llvm::GlobalValue::CommonLinkage, nullptr, "dummy", nullptr, + llvm::GlobalVariable::NotThreadLocal, Entry->getAddressSpace()); + Entry->replaceAllUsesWith(DummyGV); + + Entry->mutateType(PTy); + llvm::Constant *NewPtrForOldDecl = + llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast( + Entry, DummyGV->getType()); + + // Now we have a casted version of the changed global, the dummy can be + // replaced and deleted. + DummyGV->replaceAllUsesWith(NewPtrForOldDecl); + DummyGV->eraseFromParent(); + } +} |
