Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -2829,10 +2829,24 @@ LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C); LLVMBuilderRef LLVMCreateBuilder(void); +/** Deprecated: Use LLVMPositionBuilder2 instead. */ void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, LLVMValueRef Instr); +/** Deprecated: Use LLVMPositionBuilderBefore2 instead. */ void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr); +/** Deprecated: Use LLVMPositionBuilderAtEnd2 instead. */ void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block); +void LLVMPositionBuilder2(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, + LLVMValueRef Instr, LLVMValueRef Loc); +void LLVMPositionBuilderBefore2(LLVMBuilderRef Builder, LLVMValueRef Instr, + LLVMValueRef Loc); +void LLVMPositionBuilderAtEnd2(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, + LLVMValueRef Loc); +LLVMValueRef LLVMGetUnknownDebugLocation(LLVMBuilderRef Builder, + LLVMBasicBlockRef Block, + LLVMValueRef Instr); +LLVMValueRef LLVMGetUnknownDebugLocationBefore(LLVMBuilderRef Builder, + LLVMValueRef Instr); LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder); void LLVMClearInsertionPosition(LLVMBuilderRef Builder); void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr); Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -125,13 +125,27 @@ /// \brief This specifies that created instructions should be appended to the /// end of the specified block. + /// + /// Note: This method is deprecated. Please use: + /// setInsertPoint(BasicBlock *, const DebugLoc &) void SetInsertPoint(BasicBlock *TheBB) { BB = TheBB; InsertPt = BB->end(); } + /// This specifies that created instructions should be appended to the end + /// of the specified block, and should have the given debug location. + void setInsertPoint(BasicBlock *TheBB, const DebugLoc &Loc) { + BB = TheBB; + InsertPt = BB->end(); + SetCurrentDebugLocation(Loc); + } + /// \brief This specifies that created instructions should be inserted before /// the specified instruction. + /// + /// Note: This method is deprecated. Please use: + /// setInsertPoint(Instruction *, const DebugLoc &) void SetInsertPoint(Instruction *I) { BB = I->getParent(); InsertPt = I->getIterator(); @@ -139,8 +153,19 @@ SetCurrentDebugLocation(I->getDebugLoc()); } + /// This specifies that created instructions should be inserted before the + /// specified instruction, and should have the given debug location. + void setInsertPoint(Instruction *I, const DebugLoc &Loc) { + BB = I->getParent(); + InsertPt = I->getIterator(); + SetCurrentDebugLocation(Loc); + } + /// \brief This specifies that created instructions should be inserted at the /// specified point. + /// + /// Note: This method is deprecated. Please use either: + /// setInsertPoint(BasicBlock *, BasicBlock::iterator, const DebugLoc &) void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { BB = TheBB; InsertPt = IP; @@ -148,6 +173,24 @@ SetCurrentDebugLocation(IP->getDebugLoc()); } + /// This specifies that created instructions should be inserted at the + /// specified point, and should have the given debug location. + void setInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP, + const DebugLoc &Loc) { + BB = TheBB; + InsertPt = IP; + SetCurrentDebugLocation(Loc); + } + + /// Get the debug location which should be used for instructions without + /// a clear correspondence to a source location. This returns an empty debug + /// location when the specified insertion point is null or has no debug info + /// attached to it. Otherwise, this returns a :0:0 location with the + /// DIScope set to the current inline scope. + DebugLoc getUnknownDebugLocation(Instruction *InsertPt = nullptr) const; + DebugLoc getUnknownDebugLocation(BasicBlock *ForBB, + BasicBlock::iterator IP) const; + /// \brief Set location information used by debugging information. void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); } Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -706,6 +706,12 @@ return MDNode::get(MAV->getContext(), MD); } +/// Convert an LLVMValueRef to a DebugLoc. +static DebugLoc getValueRefAsDebugLoc(LLVMValueRef L) { + return DebugLoc(L ? cast(unwrap(L)->getMetadata()) + : nullptr); +} + void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) { MDNode *N = Val ? extractMDNode(unwrap(Val)) : nullptr; @@ -2384,6 +2390,48 @@ unwrap(Builder)->SetInsertPoint(BB); } +void LLVMPositionBuilder2(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, + LLVMValueRef Instr, LLVMValueRef Loc) { + BasicBlock *BB = unwrap(Block); + auto I = Instr ? unwrap(Instr)->getIterator() : BB->end(); + DebugLoc DL = getValueRefAsDebugLoc(Loc); + unwrap(Builder)->setInsertPoint(BB, I, DL); +} + +void LLVMPositionBuilderBefore2(LLVMBuilderRef Builder, LLVMValueRef Instr, + LLVMValueRef Loc) { + Instruction *I = unwrap(Instr); + DebugLoc DL = getValueRefAsDebugLoc(Loc); + unwrap(Builder)->setInsertPoint(I->getParent(), I->getIterator(), DL); +} + +void LLVMPositionBuilderAtEnd2(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, + LLVMValueRef Loc) { + BasicBlock *BB = unwrap(Block); + DebugLoc DL = getValueRefAsDebugLoc(Loc); + unwrap(Builder)->setInsertPoint(BB, DL); +} + +LLVMValueRef LLVMGetUnknownDebugLocation(LLVMBuilderRef Builder, + LLVMBasicBlockRef Block, + LLVMValueRef Instr) { + auto *IRB = unwrap(Builder); + DebugLoc DL = IRB->getUnknownDebugLocation( + unwrap(Block), ((Instruction *)unwrap(Instr))->getIterator()); + if (DL) + return wrap(MetadataAsValue::get(IRB->getContext(), DL.getAsMDNode())); + return nullptr; +} + +LLVMValueRef LLVMGetUnknownDebugLocationBefore(LLVMBuilderRef Builder, + LLVMValueRef Instr) { + auto *IRB = unwrap(Builder); + DebugLoc DL = IRB->getUnknownDebugLocation((Instruction *)unwrap(Instr)); + if (DL) + return wrap(MetadataAsValue::get(IRB->getContext(), DL.getAsMDNode())); + return nullptr; +} + LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder) { return wrap(unwrap(Builder)->GetInsertBlock()); } @@ -2408,9 +2456,7 @@ /*--.. Metadata builders ...................................................--*/ void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) { - MDNode *Loc = - L ? cast(unwrap(L)->getMetadata()) : nullptr; - unwrap(Builder)->SetCurrentDebugLocation(DebugLoc(Loc)); + unwrap(Builder)->SetCurrentDebugLocation(getValueRefAsDebugLoc(L)); } LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) { Index: lib/IR/IRBuilder.cpp =================================================================== --- lib/IR/IRBuilder.cpp +++ lib/IR/IRBuilder.cpp @@ -20,6 +20,26 @@ #include "llvm/IR/Statepoint.h" using namespace llvm; +DebugLoc IRBuilderBase::getUnknownDebugLocation(Instruction *InsertPt) const { + DebugLoc CurrentLoc = + InsertPt ? InsertPt->getDebugLoc() : getCurrentDebugLocation(); + + // If the function has debug info, create a zero location in the closest + // scope we can find. + if (CurrentLoc) + return DebugLoc::get(0, 0, CurrentLoc.getInlinedAtScope()); + + // Use an empty location. + return DebugLoc(); +} + +DebugLoc IRBuilderBase::getUnknownDebugLocation(BasicBlock *ForBB, + BasicBlock::iterator IP) const { + if (IP != ForBB->end()) + return getUnknownDebugLocation(&*IP); + return getUnknownDebugLocation((Instruction *)nullptr); +} + /// CreateGlobalString - Make a new global variable with an initializer that /// has array of i8 type filled in with the nul terminated string value /// specified. If Name is specified, it is the name of the global variable Index: tools/llvm-c-test/calc.c =================================================================== --- tools/llvm-c-test/calc.c +++ tools/llvm-c-test/calc.c @@ -122,7 +122,8 @@ LLVMValueRef F = LLVMAddFunction(M, name, Fty); LLVMBuilderRef builder = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry")); + LLVMPositionBuilderAtEnd2(builder, LLVMAppendBasicBlock(F, "entry"), + LLVMGetUnknownDebugLocationBefore(builder, NULL)); LLVMGetParams(F, ¶m); LLVMSetValueName(param, "in"); Index: tools/llvm-c-test/echo.cpp =================================================================== --- tools/llvm-c-test/echo.cpp +++ tools/llvm-c-test/echo.cpp @@ -369,7 +369,8 @@ auto Ctx = LLVMGetModuleContext(M); auto Builder = LLVMCreateBuilderInContext(Ctx); auto BB = DeclareBB(LLVMGetInstructionParent(Src)); - LLVMPositionBuilderAtEnd(Builder, BB); + LLVMPositionBuilderAtEnd2( + Builder, BB, LLVMGetUnknownDebugLocationBefore(Builder, nullptr)); auto Dst = CloneInstruction(Src, Builder); LLVMDisposeBuilder(Builder); return Dst; @@ -701,7 +702,8 @@ auto Ctx = LLVMGetModuleContext(M); LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx); - LLVMPositionBuilderAtEnd(Builder, BB); + LLVMPositionBuilderAtEnd2( + Builder, BB, LLVMGetUnknownDebugLocationBefore(Builder, nullptr)); LLVMValueRef Cur = First; LLVMValueRef Next = nullptr; Index: unittests/IR/IRBuilderTest.cpp =================================================================== --- unittests/IR/IRBuilderTest.cpp +++ unittests/IR/IRBuilderTest.cpp @@ -483,6 +483,7 @@ DIB.createFunction(CU, "foo", "foo", File, 1, SPType, false, true, 1); DebugLoc DL1 = DILocation::get(Ctx, 2, 0, SP); DebugLoc DL2 = DILocation::get(Ctx, 3, 0, SP); + DebugLoc DLZero = DILocation::get(Ctx, 0, 0, SP); auto BB2 = BasicBlock::Create(Ctx, "bb2", F); auto Br = BranchInst::Create(BB2, BB); @@ -500,6 +501,29 @@ auto Call2 = Builder.CreateCall(Callee, None); EXPECT_EQ(DL2, Call2->getDebugLoc()); + // Test the new setInsertPoint() API's. + IRBuilder<> Builder2(Ctx); + EXPECT_EQ(Builder2.getCurrentDebugLocation(), DebugLoc()); + + Builder2.setInsertPoint(BB, DL1); + EXPECT_EQ(Builder2.getCurrentDebugLocation(), DL1); + + Builder2.setInsertPoint(Br, DL2); + EXPECT_EQ(Builder2.getCurrentDebugLocation(), DL2); + + Builder2.setInsertPoint(BB, BB->begin(), DL1); + EXPECT_EQ(Builder2.getCurrentDebugLocation(), DL1); + + // If the insertion point has debug info, the unknown location should be + // :0:0. + EXPECT_EQ(Builder2.getUnknownDebugLocation(), DLZero); + EXPECT_EQ(Builder2.getUnknownDebugLocation(Br), DLZero); + + // If the insertion point has no known debug info, the unknown location + // should be empty. + Br->setDebugLoc(DebugLoc()); + EXPECT_EQ(Builder2.getUnknownDebugLocation(Br), DebugLoc()); + DIB.finalize(); }