[DebugInfo] Refactoring DIType::setFlags to DIType::cloneWithFlags, NFC

and using the latter in DIBuilder::createArtificialType and
DIBuilder::createObjectPointerType methods as well as introducing
mirroring DISubprogram::cloneWithFlags and
DIBuilder::createArtificialSubprogram methods.

The primary goal here is to add createArtificialSubprogram to support
a pass downstream while keeping the method consistent with the
existing ones and making sure we don't encourage changing already
created DI-nodes.

Reviewed By: aprantl

Differential Revision: https://reviews.llvm.org/D47615

llvm-svn: 333806
This commit is contained in:
Roman Tereshin 2018-06-01 23:15:09 +00:00
parent 4b3701a7a7
commit cf88ffaaf9
6 changed files with 92 additions and 23 deletions

View File

@ -678,8 +678,7 @@ LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder,
LLVMMetadataRef Ty); LLVMMetadataRef Ty);
/** /**
* Create a new DIType* with the "object pointer" * Create a uniqued DIType* clone with FlagObjectPointer and FlagArtificial set.
* flag set.
* \param Builder The DIBuilder. * \param Builder The DIBuilder.
* \param Type The underlying type to which this pointer points. * \param Type The underlying type to which this pointer points.
*/ */
@ -851,7 +850,7 @@ LLVMMetadataRef LLVMDIBuilderCreateClassType(LLVMDIBuilderRef Builder,
const char *UniqueIdentifier, size_t UniqueIdentifierLen); const char *UniqueIdentifier, size_t UniqueIdentifierLen);
/** /**
* Create a new DIType* with "artificial" flag set. * Create a uniqued DIType* clone with FlagArtificial set.
* \param Builder The DIBuilder. * \param Builder The DIBuilder.
* \param Type The underlying type. * \param Type The underlying type.
*/ */

View File

@ -515,12 +515,15 @@ namespace llvm {
DINode::DIFlags Flags = DINode::FlagZero, DINode::DIFlags Flags = DINode::FlagZero,
unsigned CC = 0); unsigned CC = 0);
/// Create a new DIType* with "artificial" flag set. /// Create a distinct clone of \p SP with FlagArtificial set.
DIType *createArtificialType(DIType *Ty); static DISubprogram *createArtificialSubprogram(DISubprogram *SP);
/// Create a new DIType* with the "object pointer" /// Create a uniqued clone of \p Ty with FlagArtificial set.
/// flag set. static DIType *createArtificialType(DIType *Ty);
DIType *createObjectPointerType(DIType *Ty);
/// Create a uniqued clone of \p Ty with FlagObjectPointer and
/// FlagArtificial set.
static DIType *createObjectPointerType(DIType *Ty);
/// Create a permanent forward-declared type. /// Create a permanent forward-declared type.
DICompositeType *createForwardDecl(unsigned Tag, StringRef Name, DICompositeType *createForwardDecl(unsigned Tag, StringRef Name,

View File

@ -679,9 +679,11 @@ public:
Metadata *getRawScope() const { return getOperand(1); } Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); } MDString *getRawName() const { return getOperandAs<MDString>(2); }
void setFlags(DIFlags NewFlags) { /// Returns a new temporary DIType with updated Flags
assert(!isUniqued() && "Cannot set flags on uniqued nodes"); TempDIType cloneWithFlags(DIFlags NewFlags) const {
Flags = NewFlags; auto NewTy = clone();
NewTy->Flags = NewFlags;
return NewTy;
} }
bool isPrivate() const { bool isPrivate() const {
@ -1679,6 +1681,13 @@ public:
TempDISubprogram clone() const { return cloneImpl(); } TempDISubprogram clone() const { return cloneImpl(); }
/// Returns a new temporary DISubprogram with updated Flags
TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
auto NewSP = clone();
NewSP->Flags = NewFlags;
return NewSP;
}
public: public:
unsigned getLine() const { return Line; } unsigned getLine() const { return Line; }
unsigned getVirtuality() const { return Virtuality; } unsigned getVirtuality() const { return Virtuality; }

View File

@ -535,10 +535,14 @@ DICompositeType *DIBuilder::createVectorType(uint64_t Size,
return R; return R;
} }
static DIType *createTypeWithFlags(LLVMContext &Context, DIType *Ty, DISubprogram *DIBuilder::createArtificialSubprogram(DISubprogram *SP) {
auto NewSP = SP->cloneWithFlags(SP->getFlags() | DINode::FlagArtificial);
return MDNode::replaceWithDistinct(std::move(NewSP));
}
static DIType *createTypeWithFlags(const DIType *Ty,
DINode::DIFlags FlagsToSet) { DINode::DIFlags FlagsToSet) {
auto NewTy = Ty->clone(); auto NewTy = Ty->cloneWithFlags(Ty->getFlags() | FlagsToSet);
NewTy->setFlags(NewTy->getFlags() | FlagsToSet);
return MDNode::replaceWithUniqued(std::move(NewTy)); return MDNode::replaceWithUniqued(std::move(NewTy));
} }
@ -546,7 +550,7 @@ DIType *DIBuilder::createArtificialType(DIType *Ty) {
// FIXME: Restrict this to the nodes where it's valid. // FIXME: Restrict this to the nodes where it's valid.
if (Ty->isArtificial()) if (Ty->isArtificial())
return Ty; return Ty;
return createTypeWithFlags(VMContext, Ty, DINode::FlagArtificial); return createTypeWithFlags(Ty, DINode::FlagArtificial);
} }
DIType *DIBuilder::createObjectPointerType(DIType *Ty) { DIType *DIBuilder::createObjectPointerType(DIType *Ty) {
@ -554,7 +558,7 @@ DIType *DIBuilder::createObjectPointerType(DIType *Ty) {
if (Ty->isObjectPointer()) if (Ty->isObjectPointer())
return Ty; return Ty;
DINode::DIFlags Flags = DINode::FlagObjectPointer | DINode::FlagArtificial; DINode::DIFlags Flags = DINode::FlagObjectPointer | DINode::FlagArtificial;
return createTypeWithFlags(VMContext, Ty, Flags); return createTypeWithFlags(Ty, Flags);
} }
void DIBuilder::retainType(DIScope *T) { void DIBuilder::retainType(DIScope *T) {

View File

@ -459,6 +459,62 @@ TEST_F(IRBuilderTest, DIBuilder) {
EXPECT_TRUE(verifyModule(*M)); EXPECT_TRUE(verifyModule(*M));
} }
TEST_F(IRBuilderTest, createArtificialSubprogram) {
IRBuilder<> Builder(BB);
DIBuilder DIB(*M);
auto File = DIB.createFile("main.c", "/");
auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "clang",
/*isOptimized=*/true, /*Flags=*/"",
/*Runtime Version=*/0);
auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
auto SP = DIB.createFunction(CU, "foo", /*LinkageName=*/"", File,
/*LineNo=*/1, Type, /*isLocalToUnit=*/false,
/*isDefinition=*/true, /*ScopeLine=*/2,
DINode::FlagZero, /*isOptimized=*/true);
EXPECT_TRUE(SP->isDistinct());
F->setSubprogram(SP);
AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
ReturnInst *R = Builder.CreateRetVoid();
I->setDebugLoc(DebugLoc::get(3, 2, SP));
R->setDebugLoc(DebugLoc::get(4, 2, SP));
DIB.finalize();
EXPECT_FALSE(verifyModule(*M));
Function *G = Function::Create(F->getFunctionType(),
Function::ExternalLinkage, "", M.get());
BasicBlock *GBB = BasicBlock::Create(Ctx, "", G);
Builder.SetInsertPoint(GBB);
I->removeFromParent();
Builder.Insert(I);
Builder.CreateRetVoid();
EXPECT_FALSE(verifyModule(*M));
DISubprogram *GSP = DIBuilder::createArtificialSubprogram(F->getSubprogram());
EXPECT_EQ(SP->getFile(), GSP->getFile());
EXPECT_EQ(SP->getType(), GSP->getType());
EXPECT_EQ(SP->getLine(), GSP->getLine());
EXPECT_EQ(SP->getScopeLine(), GSP->getScopeLine());
EXPECT_TRUE(GSP->isDistinct());
G->setSubprogram(GSP);
EXPECT_TRUE(verifyModule(*M));
auto *InlinedAtNode =
DILocation::getDistinct(Ctx, GSP->getScopeLine(), 0, GSP);
DebugLoc DL = I->getDebugLoc();
DenseMap<const MDNode *, MDNode *> IANodes;
auto IA = DebugLoc::appendInlinedAt(DL, InlinedAtNode, Ctx, IANodes);
auto NewDL = DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(), IA);
I->setDebugLoc(NewDL);
EXPECT_FALSE(verifyModule(*M));
EXPECT_EQ("foo", SP->getName());
EXPECT_EQ("foo", GSP->getName());
EXPECT_FALSE(SP->isArtificial());
EXPECT_TRUE(GSP->isArtificial());
}
TEST_F(IRBuilderTest, InsertExtractElement) { TEST_F(IRBuilderTest, InsertExtractElement) {
IRBuilder<> Builder(BB); IRBuilder<> Builder(BB);

View File

@ -1051,7 +1051,7 @@ TEST_F(DITypeTest, clone) {
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
} }
TEST_F(DITypeTest, setFlags) { TEST_F(DITypeTest, cloneWithFlags) {
// void (void) // void (void)
Metadata *TypesOps[] = {nullptr}; Metadata *TypesOps[] = {nullptr};
Metadata *Types = MDTuple::get(Context, TypesOps); Metadata *Types = MDTuple::get(Context, TypesOps);
@ -1059,17 +1059,15 @@ TEST_F(DITypeTest, setFlags) {
DIType *D = DIType *D =
DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, Types); DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, Types);
EXPECT_EQ(DINode::FlagZero, D->getFlags()); EXPECT_EQ(DINode::FlagZero, D->getFlags());
D->setFlags(DINode::FlagRValueReference); TempDIType D2 = D->cloneWithFlags(DINode::FlagRValueReference);
EXPECT_EQ(DINode::FlagRValueReference, D->getFlags()); EXPECT_EQ(DINode::FlagRValueReference, D2->getFlags());
D->setFlags(DINode::FlagZero);
EXPECT_EQ(DINode::FlagZero, D->getFlags()); EXPECT_EQ(DINode::FlagZero, D->getFlags());
TempDIType T = TempDIType T =
DISubroutineType::getTemporary(Context, DINode::FlagZero, 0, Types); DISubroutineType::getTemporary(Context, DINode::FlagZero, 0, Types);
EXPECT_EQ(DINode::FlagZero, T->getFlags()); EXPECT_EQ(DINode::FlagZero, T->getFlags());
T->setFlags(DINode::FlagRValueReference); TempDIType T2 = T->cloneWithFlags(DINode::FlagRValueReference);
EXPECT_EQ(DINode::FlagRValueReference, T->getFlags()); EXPECT_EQ(DINode::FlagRValueReference, T2->getFlags());
T->setFlags(DINode::FlagZero);
EXPECT_EQ(DINode::FlagZero, T->getFlags()); EXPECT_EQ(DINode::FlagZero, T->getFlags());
} }