llvm.org GIT mirror llvm / a82bdae
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333806 91177308-0d34-0410-b5e6-96231b3b80d8 Roman Tereshin 1 year, 3 months ago
6 changed file(s) with 93 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
514514 DINode::DIFlags Flags = DINode::FlagZero,
515515 unsigned CC = 0);
516516
517 /// Create a new DIType* with "artificial" flag set.
518 DIType *createArtificialType(DIType *Ty);
519
520 /// Create a new DIType* with the "object pointer"
521 /// flag set.
522 DIType *createObjectPointerType(DIType *Ty);
517 /// Create a distinct clone of \p SP with FlagArtificial set.
518 static DISubprogram *createArtificialSubprogram(DISubprogram *SP);
519
520 /// Create a uniqued clone of \p Ty with FlagArtificial set.
521 static DIType *createArtificialType(DIType *Ty);
522
523 /// Create a uniqued clone of \p Ty with FlagObjectPointer and
524 /// FlagArtificial set.
525 static DIType *createObjectPointerType(DIType *Ty);
523526
524527 /// Create a permanent forward-declared type.
525528 DICompositeType *createForwardDecl(unsigned Tag, StringRef Name,
678678 Metadata *getRawScope() const { return getOperand(1); }
679679 MDString *getRawName() const { return getOperandAs(2); }
680680
681 void setFlags(DIFlags NewFlags) {
682 assert(!isUniqued() && "Cannot set flags on uniqued nodes");
683 Flags = NewFlags;
681 /// Returns a new temporary DIType with updated Flags
682 TempDIType cloneWithFlags(DIFlags NewFlags) const {
683 auto NewTy = clone();
684 NewTy->Flags = NewFlags;
685 return NewTy;
684686 }
685687
686688 bool isPrivate() const {
16781680
16791681 TempDISubprogram clone() const { return cloneImpl(); }
16801682
1683 /// Returns a new temporary DISubprogram with updated Flags
1684 TempDISubprogram cloneWithFlags(DIFlags NewFlags) const {
1685 auto NewSP = clone();
1686 NewSP->Flags = NewFlags;
1687 return NewSP;
1688 }
1689
16811690 public:
16821691 unsigned getLine() const { return Line; }
16831692 unsigned getVirtuality() const { return Virtuality; }
677677 LLVMMetadataRef Ty);
678678
679679 /**
680 * Create a new DIType* with the "object pointer"
681 * flag set.
680 * Create a uniqued DIType* clone with FlagObjectPointer and FlagArtificial set.
682681 * \param Builder The DIBuilder.
683682 * \param Type The underlying type to which this pointer points.
684683 */
850849 const char *UniqueIdentifier, size_t UniqueIdentifierLen);
851850
852851 /**
853 * Create a new DIType* with "artificial" flag set.
852 * Create a uniqued DIType* clone with FlagArtificial set.
854853 * \param Builder The DIBuilder.
855854 * \param Type The underlying type.
856855 */
534534 return R;
535535 }
536536
537 static DIType *createTypeWithFlags(LLVMContext &Context, DIType *Ty,
537 DISubprogram *DIBuilder::createArtificialSubprogram(DISubprogram *SP) {
538 auto NewSP = SP->cloneWithFlags(SP->getFlags() | DINode::FlagArtificial);
539 return MDNode::replaceWithDistinct(std::move(NewSP));
540 }
541
542 static DIType *createTypeWithFlags(const DIType *Ty,
538543 DINode::DIFlags FlagsToSet) {
539 auto NewTy = Ty->clone();
540 NewTy->setFlags(NewTy->getFlags() | FlagsToSet);
544 auto NewTy = Ty->cloneWithFlags(Ty->getFlags() | FlagsToSet);
541545 return MDNode::replaceWithUniqued(std::move(NewTy));
542546 }
543547
545549 // FIXME: Restrict this to the nodes where it's valid.
546550 if (Ty->isArtificial())
547551 return Ty;
548 return createTypeWithFlags(VMContext, Ty, DINode::FlagArtificial);
552 return createTypeWithFlags(Ty, DINode::FlagArtificial);
549553 }
550554
551555 DIType *DIBuilder::createObjectPointerType(DIType *Ty) {
553557 if (Ty->isObjectPointer())
554558 return Ty;
555559 DINode::DIFlags Flags = DINode::FlagObjectPointer | DINode::FlagArtificial;
556 return createTypeWithFlags(VMContext, Ty, Flags);
560 return createTypeWithFlags(Ty, Flags);
557561 }
558562
559563 void DIBuilder::retainType(DIScope *T) {
458458 EXPECT_TRUE(verifyModule(*M));
459459 }
460460
461 TEST_F(IRBuilderTest, createArtificialSubprogram) {
462 IRBuilder<> Builder(BB);
463 DIBuilder DIB(*M);
464 auto File = DIB.createFile("main.c", "/");
465 auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C, File, "clang",
466 /*isOptimized=*/true, /*Flags=*/"",
467 /*Runtime Version=*/0);
468 auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
469 auto SP = DIB.createFunction(CU, "foo", /*LinkageName=*/"", File,
470 /*LineNo=*/1, Type, /*isLocalToUnit=*/false,
471 /*isDefinition=*/true, /*ScopeLine=*/2,
472 DINode::FlagZero, /*isOptimized=*/true);
473 EXPECT_TRUE(SP->isDistinct());
474
475 F->setSubprogram(SP);
476 AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
477 ReturnInst *R = Builder.CreateRetVoid();
478 I->setDebugLoc(DebugLoc::get(3, 2, SP));
479 R->setDebugLoc(DebugLoc::get(4, 2, SP));
480 DIB.finalize();
481 EXPECT_FALSE(verifyModule(*M));
482
483 Function *G = Function::Create(F->getFunctionType(),
484 Function::ExternalLinkage, "", M.get());
485 BasicBlock *GBB = BasicBlock::Create(Ctx, "", G);
486 Builder.SetInsertPoint(GBB);
487 I->removeFromParent();
488 Builder.Insert(I);
489 Builder.CreateRetVoid();
490 EXPECT_FALSE(verifyModule(*M));
491
492 DISubprogram *GSP = DIBuilder::createArtificialSubprogram(F->getSubprogram());
493 EXPECT_EQ(SP->getFile(), GSP->getFile());
494 EXPECT_EQ(SP->getType(), GSP->getType());
495 EXPECT_EQ(SP->getLine(), GSP->getLine());
496 EXPECT_EQ(SP->getScopeLine(), GSP->getScopeLine());
497 EXPECT_TRUE(GSP->isDistinct());
498
499 G->setSubprogram(GSP);
500 EXPECT_TRUE(verifyModule(*M));
501
502 auto *InlinedAtNode =
503 DILocation::getDistinct(Ctx, GSP->getScopeLine(), 0, GSP);
504 DebugLoc DL = I->getDebugLoc();
505 DenseMap IANodes;
506 auto IA = DebugLoc::appendInlinedAt(DL, InlinedAtNode, Ctx, IANodes);
507 auto NewDL = DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(), IA);
508 I->setDebugLoc(NewDL);
509 EXPECT_FALSE(verifyModule(*M));
510
511 EXPECT_EQ("foo", SP->getName());
512 EXPECT_EQ("foo", GSP->getName());
513 EXPECT_FALSE(SP->isArtificial());
514 EXPECT_TRUE(GSP->isArtificial());
515 }
516
461517 TEST_F(IRBuilderTest, InsertExtractElement) {
462518 IRBuilder<> Builder(BB);
463519
10501050 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
10511051 }
10521052
1053 TEST_F(DITypeTest, setFlags) {
1053 TEST_F(DITypeTest, cloneWithFlags) {
10541054 // void (void)
10551055 Metadata *TypesOps[] = {nullptr};
10561056 Metadata *Types = MDTuple::get(Context, TypesOps);
10581058 DIType *D =
10591059 DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, Types);
10601060 EXPECT_EQ(DINode::FlagZero, D->getFlags());
1061 D->setFlags(DINode::FlagRValueReference);
1062 EXPECT_EQ(DINode::FlagRValueReference, D->getFlags());
1063 D->setFlags(DINode::FlagZero);
1061 TempDIType D2 = D->cloneWithFlags(DINode::FlagRValueReference);
1062 EXPECT_EQ(DINode::FlagRValueReference, D2->getFlags());
10641063 EXPECT_EQ(DINode::FlagZero, D->getFlags());
10651064
10661065 TempDIType T =
10671066 DISubroutineType::getTemporary(Context, DINode::FlagZero, 0, Types);
10681067 EXPECT_EQ(DINode::FlagZero, T->getFlags());
1069 T->setFlags(DINode::FlagRValueReference);
1070 EXPECT_EQ(DINode::FlagRValueReference, T->getFlags());
1071 T->setFlags(DINode::FlagZero);
1068 TempDIType T2 = T->cloneWithFlags(DINode::FlagRValueReference);
1069 EXPECT_EQ(DINode::FlagRValueReference, T2->getFlags());
10721070 EXPECT_EQ(DINode::FlagZero, T->getFlags());
10731071 }
10741072