X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FDIBuilder.cpp;h=9ba2010916831cb20db7138a6a9b1336a92b1cbd;hb=2e25115e02eda8f47786bca06288917c4437c103;hp=a1af40546b7319318f5b83f0dba38eb09f3992ea;hpb=a30b342b77594b6a997bd9c0b585dc7b5f66cbcf;p=oota-llvm.git diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index a1af40546b7..9ba20109168 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -75,7 +75,7 @@ void DIBuilder::trackIfUnresolved(MDNode *N) { void DIBuilder::finalize() { DIArray Enums = getOrCreateArray(AllEnumTypes); - DIType(TempEnumTypes).replaceAllUsesWith(Enums); + TempEnumTypes->replaceAllUsesWith(Enums.get()); SmallVector RetainValues; // Declarations and definitions of the same type may be retained. Some @@ -87,29 +87,27 @@ void DIBuilder::finalize() { if (RetainSet.insert(AllRetainTypes[I]).second) RetainValues.push_back(AllRetainTypes[I]); DIArray RetainTypes = getOrCreateArray(RetainValues); - DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes); + TempRetainTypes->replaceAllUsesWith(RetainTypes.get()); DIArray SPs = getOrCreateArray(AllSubprograms); - DIType(TempSubprograms).replaceAllUsesWith(SPs); - for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { - DISubprogram SP(SPs.getElement(i)); - if (MDNode *Temp = SP.getVariablesNodes()) { - SmallVector Variables; - for (Metadata *V : PreservedVariables.lookup(SP)) - Variables.push_back(V); + TempSubprograms->replaceAllUsesWith(SPs.get()); + for (unsigned i = 0, e = SPs.size(); i != e; ++i) { + DISubprogram SP = cast(SPs[i]); + if (MDNode *Temp = SP.getVariables().get()) { + const auto &PV = PreservedVariables.lookup(SP); + SmallVector Variables(PV.begin(), PV.end()); DIArray AV = getOrCreateArray(Variables); - DIType(Temp).replaceAllUsesWith(AV); + Temp->replaceAllUsesWith(AV.get()); } } DIArray GVs = getOrCreateArray(AllGVs); - DIType(TempGVs).replaceAllUsesWith(GVs); + TempGVs->replaceAllUsesWith(GVs.get()); - SmallVector RetainValuesI; - for (unsigned I = 0, E = AllImportedModules.size(); I < E; I++) - RetainValuesI.push_back(AllImportedModules[I]); + SmallVector RetainValuesI(AllImportedModules.begin(), + AllImportedModules.end()); DIArray IMs = getOrCreateArray(RetainValuesI); - DIType(TempImportedModules).replaceAllUsesWith(IMs); + TempImportedModules->replaceAllUsesWith(IMs.get()); // Now that all temp nodes have been replaced or deleted, resolve remaining // cycles. @@ -123,18 +121,10 @@ void DIBuilder::finalize() { } /// If N is compile unit return NULL otherwise return N. -static MDNode *getNonCompileUnitScope(MDNode *N) { - if (DIDescriptor(N).isCompileUnit()) +static MDScope *getNonCompileUnitScope(MDNode *N) { + if (!N || isa(N)) return nullptr; - return N; -} - -static MDNode *createFilePathPair(LLVMContext &VMContext, StringRef Filename, - StringRef Directory) { - assert(!Filename.empty() && "Unable to create file without name"); - Metadata *Pair[] = {MDString::get(VMContext, Filename), - MDString::get(VMContext, Directory)}; - return MDNode::get(VMContext, Pair); + return cast(N); } DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, @@ -150,31 +140,21 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, "Invalid Language tag"); assert(!Filename.empty() && "Unable to create compile unit without filename"); - Metadata *TElts[] = {HeaderBuilder::get(DW_TAG_base_type).get(VMContext)}; - TempEnumTypes = MDNode::getTemporary(VMContext, TElts).release(); - - TempRetainTypes = MDNode::getTemporary(VMContext, TElts).release(); - - TempSubprograms = MDNode::getTemporary(VMContext, TElts).release(); - - TempGVs = MDNode::getTemporary(VMContext, TElts).release(); - TempImportedModules = MDNode::getTemporary(VMContext, TElts).release(); - - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_compile_unit) - .concat(Lang) - .concat(Producer) - .concat(isOptimized) - .concat(Flags) - .concat(RunTimeVer) - .concat(SplitName) - .concat(Kind) - .get(VMContext), - createFilePathPair(VMContext, Filename, Directory), - TempEnumTypes, TempRetainTypes, TempSubprograms, TempGVs, - TempImportedModules}; - - MDNode *CUNode = MDNode::get(VMContext, Elts); + // TODO: Once we make MDCompileUnit distinct, stop using temporaries here + // (just start with operands assigned to nullptr). + TempEnumTypes = MDTuple::getTemporary(VMContext, None).release(); + TempRetainTypes = MDTuple::getTemporary(VMContext, None).release(); + TempSubprograms = MDTuple::getTemporary(VMContext, None).release(); + TempGVs = MDTuple::getTemporary(VMContext, None).release(); + TempImportedModules = MDTuple::getTemporary(VMContext, None).release(); + + // TODO: Switch to getDistinct(). We never want to merge compile units based + // on contents. + MDCompileUnit *CUNode = MDCompileUnit::get( + VMContext, Lang, MDFile::get(VMContext, Filename, Directory), Producer, + isOptimized, Flags, RunTimeVer, SplitName, Kind, TempEnumTypes, + TempRetainTypes, TempSubprograms, TempGVs, TempImportedModules); // Create a named metadata so that it is easier to find cu in a module. // Note that we only generate this when the caller wants to actually @@ -187,19 +167,15 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, } trackIfUnresolved(CUNode); - return DICompileUnit(CUNode); + return CUNode; } static DIImportedEntity createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope Context, Metadata *NS, unsigned Line, StringRef Name, SmallVectorImpl &AllImportedModules) { - const MDNode *R; - Metadata *Elts[] = {HeaderBuilder::get(Tag).concat(Line).concat(Name).get(C), - Context, NS}; - R = MDNode::get(C, Elts); - DIImportedEntity M(R); - assert(M.Verify() && "Imported module should be valid"); + DIImportedEntity M = + MDImportedEntity::get(C, Tag, Context, DebugNodeRef(NS), Line, Name); AllImportedModules.emplace_back(M.get()); return M; } @@ -220,14 +196,14 @@ DIImportedEntity DIBuilder::createImportedModule(DIScope Context, DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, DIDescriptor Decl, - unsigned Line, StringRef Name) { + unsigned Line, + StringRef Name) { // Make sure to use the unique identifier based metadata reference for // types that have one. - Metadata *V = - Decl.isType() ? static_cast(DIType(Decl).getRef()) : Decl; - return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, - Context, V, Line, Name, - AllImportedModules); + return ::createImportedModule( + VMContext, dwarf::DW_TAG_imported_declaration, Context, + DebugNodeRef::get(cast_or_null(Decl.get())), Line, Name, + AllImportedModules); } DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, @@ -238,39 +214,17 @@ DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, } DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) { - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_file_type).get(VMContext), - createFilePathPair(VMContext, Filename, Directory)}; - return DIFile(MDNode::get(VMContext, Elts)); + return MDFile::get(VMContext, Filename, Directory); } DIEnumerator DIBuilder::createEnumerator(StringRef Name, int64_t Val) { assert(!Name.empty() && "Unable to create enumerator without name"); - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_enumerator) - .concat(Name) - .concat(Val) - .get(VMContext)}; - return DIEnumerator(MDNode::get(VMContext, Elts)); + return MDEnumerator::get(VMContext, Val, Name); } DIBasicType DIBuilder::createUnspecifiedType(StringRef Name) { assert(!Name.empty() && "Unable to create type without name"); - // Unspecified types are encoded in DIBasicType format. Line number, filename, - // size, alignment, offset and flags are always empty here. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_unspecified_type) - .concat(Name) - .concat(0) - .concat(0) - .concat(0) - .concat(0) - .concat(0) - .concat(0) - .get(VMContext), - nullptr, // Filename - nullptr // Unused - }; - return DIBasicType(MDNode::get(VMContext, Elts)); + return MDBasicType::get(VMContext, dwarf::DW_TAG_unspecified_type, Name); } DIBasicType DIBuilder::createNullPtrType() { @@ -281,141 +235,62 @@ DIBasicType DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding) { assert(!Name.empty() && "Unable to create type without name"); - // Basic types are encoded in DIBasicType format. Line number, filename, - // offset and flags are always empty here. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_base_type) - .concat(Name) - .concat(0) // Line - .concat(SizeInBits) - .concat(AlignInBits) - .concat(0) // Offset - .concat(0) // Flags - .concat(Encoding) - .get(VMContext), - nullptr, // Filename - nullptr // Unused - }; - return DIBasicType(MDNode::get(VMContext, Elts)); + return MDBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits, + AlignInBits, Encoding); } DIDerivedType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) { - // Qualified types are encoded in DIDerivedType format. - Metadata *Elts[] = {HeaderBuilder::get(Tag) - .concat(StringRef()) // Name - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, // Filename - nullptr, // Unused - FromTy.getRef()}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + return MDDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, + MDTypeRef::get(FromTy), 0, 0, 0, 0); } DIDerivedType DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits, uint64_t AlignInBits, StringRef Name) { - // Pointer types are encoded in DIDerivedType format. - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_pointer_type) - .concat(Name) - .concat(0) // Line - .concat(SizeInBits) - .concat(AlignInBits) - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, // Filename - nullptr, // Unused - PointeeTy.getRef()}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + // FIXME: Why is there a name here? + return MDDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name, + nullptr, 0, nullptr, MDTypeRef::get(PointeeTy), + SizeInBits, AlignInBits, 0, 0); } DIDerivedType DIBuilder::createMemberPointerType(DIType PointeeTy, DIType Base, uint64_t SizeInBits, uint64_t AlignInBits) { - // Pointer types are encoded in DIDerivedType format. - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_ptr_to_member_type) - .concat(StringRef()) - .concat(0) // Line - .concat(SizeInBits) // Size - .concat(AlignInBits) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, // Filename - nullptr, // Unused - PointeeTy.getRef(), Base.getRef()}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + return MDDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "", + nullptr, 0, nullptr, MDTypeRef::get(PointeeTy), + SizeInBits, AlignInBits, 0, 0, MDTypeRef::get(Base)); } DIDerivedType DIBuilder::createReferenceType(unsigned Tag, DIType RTy) { - assert(RTy.isType() && "Unable to create reference type"); - // References are encoded in DIDerivedType format. - Metadata *Elts[] = {HeaderBuilder::get(Tag) - .concat(StringRef()) // Name - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, // Filename - nullptr, // TheCU, - RTy.getRef()}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + assert(RTy && "Unable to create reference type"); + return MDDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, + MDTypeRef::get(RTy), 0, 0, 0, 0); } DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, unsigned LineNo, DIDescriptor Context) { - // typedefs are encoded in DIDerivedType format. - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_typedef) - .concat(Name) - .concat(LineNo) - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - File.getFileNode(), - DIScope(getNonCompileUnitScope(Context)).getRef(), - Ty.getRef()}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + return MDDerivedType::get( + VMContext, dwarf::DW_TAG_typedef, Name, File, LineNo, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Context))), + MDTypeRef::get(Ty), 0, 0, 0, 0); } DIDerivedType DIBuilder::createFriend(DIType Ty, DIType FriendTy) { // typedefs are encoded in DIDerivedType format. - assert(Ty.isType() && "Invalid type!"); - assert(FriendTy.isType() && "Invalid friend type!"); - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_friend) - .concat(StringRef()) // Name - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(0) // Flags - .get(VMContext), - nullptr, Ty.getRef(), FriendTy.getRef()}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + assert(Ty && "Invalid type!"); + assert(FriendTy && "Invalid friend type!"); + return MDDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, + MDTypeRef::get(Ty), MDTypeRef::get(FriendTy), 0, 0, + 0, 0); } DIDerivedType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset, unsigned Flags) { - assert(Ty.isType() && "Unable to create inheritance"); - // TAG_inheritance is encoded in DIDerivedType format. - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_inheritance) - .concat(StringRef()) // Name - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(BaseOffset) - .concat(Flags) - .get(VMContext), - nullptr, Ty.getRef(), BaseTy.getRef()}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + assert(Ty && "Unable to create inheritance"); + return MDDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr, + 0, MDTypeRef::get(Ty), MDTypeRef::get(BaseTy), 0, 0, + BaseOffset, Flags); } DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, @@ -424,22 +299,13 @@ DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType Ty) { - // TAG_member is encoded in DIDerivedType format. - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) - .concat(Name) - .concat(LineNumber) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(OffsetInBits) - .concat(Flags) - .get(VMContext), - File.getFileNode(), - DIScope(getNonCompileUnitScope(Scope)).getRef(), - Ty.getRef()}; - return DIDerivedType(MDNode::get(VMContext, Elts)); -} - -static Metadata *getConstantOrNull(Constant *C) { + return MDDerivedType::get( + VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Scope))), + MDTypeRef::get(Ty), SizeInBits, AlignInBits, OffsetInBits, Flags); +} + +static ConstantAsMetadata *getConstantOrNull(Constant *C) { if (C) return ConstantAsMetadata::get(C); return nullptr; @@ -452,18 +318,10 @@ DIDerivedType DIBuilder::createStaticMemberType(DIDescriptor Scope, llvm::Constant *Val) { // TAG_member is encoded in DIDerivedType format. Flags |= DIDescriptor::FlagStaticMember; - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) - .concat(Name) - .concat(LineNumber) - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(Flags) - .get(VMContext), - File.getFileNode(), - DIScope(getNonCompileUnitScope(Scope)).getRef(), - Ty.getRef(), getConstantOrNull(Val)}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + return MDDerivedType::get( + VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Scope))), + MDTypeRef::get(Ty), 0, 0, 0, Flags, getConstantOrNull(Val)); } DIDerivedType DIBuilder::createObjCIVar(StringRef Name, DIFile File, @@ -472,86 +330,60 @@ DIDerivedType DIBuilder::createObjCIVar(StringRef Name, DIFile File, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType Ty, MDNode *PropertyNode) { - // TAG_member is encoded in DIDerivedType format. - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) - .concat(Name) - .concat(LineNumber) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(OffsetInBits) - .concat(Flags) - .get(VMContext), - File.getFileNode(), getNonCompileUnitScope(File), Ty, - PropertyNode}; - return DIDerivedType(MDNode::get(VMContext, Elts)); + return MDDerivedType::get( + VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, + MDScopeRef::get(getNonCompileUnitScope(File)), MDTypeRef::get(Ty), + SizeInBits, AlignInBits, OffsetInBits, Flags, PropertyNode); } DIObjCProperty DIBuilder::createObjCProperty(StringRef Name, DIFile File, unsigned LineNumber, StringRef GetterName, StringRef SetterName, unsigned PropertyAttributes, DIType Ty) { - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_APPLE_property) - .concat(Name) - .concat(LineNumber) - .concat(GetterName) - .concat(SetterName) - .concat(PropertyAttributes) - .get(VMContext), - File, Ty}; - return DIObjCProperty(MDNode::get(VMContext, Elts)); + return MDObjCProperty::get(VMContext, Name, File, LineNumber, GetterName, + SetterName, PropertyAttributes, Ty); } DITemplateTypeParameter DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name, - DIType Ty, MDNode *File, unsigned LineNo, - unsigned ColumnNo) { - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_template_type_parameter) - .concat(Name) - .concat(LineNo) - .concat(ColumnNo) - .get(VMContext), - DIScope(getNonCompileUnitScope(Context)).getRef(), - Ty.getRef(), File}; - return DITemplateTypeParameter(MDNode::get(VMContext, Elts)); -} - -static DITemplateValueParameter createTemplateValueParameterHelper( - LLVMContext &VMContext, unsigned Tag, DIDescriptor Context, StringRef Name, - DIType Ty, Metadata *MD, MDNode *File, unsigned LineNo, unsigned ColumnNo) { - Metadata *Elts[] = { - HeaderBuilder::get(Tag).concat(Name).concat(LineNo).concat(ColumnNo).get( - VMContext), - DIScope(getNonCompileUnitScope(Context)).getRef(), Ty.getRef(), MD, File}; - return DITemplateValueParameter(MDNode::get(VMContext, Elts)); + DIType Ty) { + assert((!Context || isa(Context.get())) && + "Expected compile unit"); + return MDTemplateTypeParameter::get(VMContext, Name, MDTypeRef::get(Ty)); +} + +static DITemplateValueParameter +createTemplateValueParameterHelper(LLVMContext &VMContext, unsigned Tag, + DIDescriptor Context, StringRef Name, + DIType Ty, Metadata *MD) { + assert((!Context || isa(Context.get())) && + "Expected compile unit"); + return MDTemplateValueParameter::get(VMContext, Tag, Name, MDTypeRef::get(Ty), + MD); } DITemplateValueParameter DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name, - DIType Ty, Constant *Val, MDNode *File, - unsigned LineNo, unsigned ColumnNo) { + DIType Ty, Constant *Val) { return createTemplateValueParameterHelper( VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty, - getConstantOrNull(Val), File, LineNo, ColumnNo); + getConstantOrNull(Val)); } DITemplateValueParameter DIBuilder::createTemplateTemplateParameter(DIDescriptor Context, StringRef Name, - DIType Ty, StringRef Val, - MDNode *File, unsigned LineNo, - unsigned ColumnNo) { + DIType Ty, StringRef Val) { return createTemplateValueParameterHelper( VMContext, dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty, - MDString::get(VMContext, Val), File, LineNo, ColumnNo); + MDString::get(VMContext, Val)); } DITemplateValueParameter DIBuilder::createTemplateParameterPack(DIDescriptor Context, StringRef Name, - DIType Ty, DIArray Val, - MDNode *File, unsigned LineNo, - unsigned ColumnNo) { + DIType Ty, DIArray Val) { return createTemplateValueParameterHelper( VMContext, dwarf::DW_TAG_GNU_template_parameter_pack, Context, Name, Ty, - Val, File, LineNo, ColumnNo); + Val.get()); } DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, @@ -564,28 +396,18 @@ DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, DIType VTableHolder, MDNode *TemplateParams, StringRef UniqueIdentifier) { - assert((!Context || Context.isScope() || Context.isType()) && + assert((!Context || isa(Context)) && "createClassType should be called with a valid Context"); // TAG_class_type is encoded in DICompositeType format. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_class_type) - .concat(Name) - .concat(LineNumber) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(OffsetInBits) - .concat(Flags) - .concat(0) - .get(VMContext), - File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), - DerivedFrom.getRef(), Elements, VTableHolder.getRef(), TemplateParams, - UniqueIdentifier.empty() ? nullptr - : MDString::get(VMContext, UniqueIdentifier)}; - DICompositeType R(MDNode::get(VMContext, Elts)); - assert(R.isCompositeType() && - "createClassType should return a DICompositeType"); + DICompositeType R = MDCompositeType::get( + VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Context))), + MDTypeRef::get(DerivedFrom), SizeInBits, AlignInBits, OffsetInBits, Flags, + Elements, 0, MDTypeRef::get(VTableHolder), + cast_or_null(TemplateParams), UniqueIdentifier); if (!UniqueIdentifier.empty()) retainType(R); + trackIfUnresolved(R); return R; } @@ -599,26 +421,14 @@ DICompositeType DIBuilder::createStructType(DIDescriptor Context, unsigned RunTimeLang, DIType VTableHolder, StringRef UniqueIdentifier) { - // TAG_structure_type is encoded in DICompositeType format. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_structure_type) - .concat(Name) - .concat(LineNumber) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(0) - .concat(Flags) - .concat(RunTimeLang) - .get(VMContext), - File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), - DerivedFrom.getRef(), Elements, VTableHolder.getRef(), nullptr, - UniqueIdentifier.empty() ? nullptr - : MDString::get(VMContext, UniqueIdentifier)}; - DICompositeType R(MDNode::get(VMContext, Elts)); - assert(R.isCompositeType() && - "createStructType should return a DICompositeType"); + DICompositeType R = MDCompositeType::get( + VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Context))), + MDTypeRef::get(DerivedFrom), SizeInBits, AlignInBits, 0, Flags, Elements, + RunTimeLang, MDTypeRef::get(VTableHolder), nullptr, UniqueIdentifier); if (!UniqueIdentifier.empty()) retainType(R); + trackIfUnresolved(R); return R; } @@ -629,158 +439,84 @@ DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, DIArray Elements, unsigned RunTimeLang, StringRef UniqueIdentifier) { - // TAG_union_type is encoded in DICompositeType format. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_union_type) - .concat(Name) - .concat(LineNumber) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(0) // Offset - .concat(Flags) - .concat(RunTimeLang) - .get(VMContext), - File.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), - nullptr, Elements, nullptr, nullptr, - UniqueIdentifier.empty() ? nullptr - : MDString::get(VMContext, UniqueIdentifier)}; - DICompositeType R(MDNode::get(VMContext, Elts)); + DICompositeType R = MDCompositeType::get( + VMContext, dwarf::DW_TAG_union_type, Name, File, LineNumber, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Scope))), nullptr, + SizeInBits, AlignInBits, 0, Flags, Elements, RunTimeLang, nullptr, + nullptr, UniqueIdentifier); if (!UniqueIdentifier.empty()) retainType(R); + trackIfUnresolved(R); return R; } DISubroutineType DIBuilder::createSubroutineType(DIFile File, DITypeArray ParameterTypes, unsigned Flags) { - // TAG_subroutine_type is encoded in DICompositeType format. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_subroutine_type) - .concat(StringRef()) - .concat(0) // Line - .concat(0) // Size - .concat(0) // Align - .concat(0) // Offset - .concat(Flags) // Flags - .concat(0) - .get(VMContext), - nullptr, nullptr, nullptr, ParameterTypes, nullptr, nullptr, - nullptr // Type Identifer - }; - return DISubroutineType(MDNode::get(VMContext, Elts)); + return MDSubroutineType::get(VMContext, Flags, ParameterTypes); } DICompositeType DIBuilder::createEnumerationType( DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements, DIType UnderlyingType, StringRef UniqueIdentifier) { - // TAG_enumeration_type is encoded in DICompositeType format. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_enumeration_type) - .concat(Name) - .concat(LineNumber) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(0) // Offset - .concat(0) // Flags - .concat(0) - .get(VMContext), - File.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), - UnderlyingType.getRef(), Elements, nullptr, nullptr, - UniqueIdentifier.empty() ? nullptr - : MDString::get(VMContext, UniqueIdentifier)}; - DICompositeType CTy(MDNode::get(VMContext, Elts)); + DICompositeType CTy = MDCompositeType::get( + VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Scope))), + MDTypeRef::get(UnderlyingType), SizeInBits, AlignInBits, 0, 0, Elements, + 0, nullptr, nullptr, UniqueIdentifier); AllEnumTypes.push_back(CTy); if (!UniqueIdentifier.empty()) retainType(CTy); + trackIfUnresolved(CTy); return CTy; } DICompositeType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, DIType Ty, DIArray Subscripts) { - // TAG_array_type is encoded in DICompositeType format. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_array_type) - .concat(StringRef()) - .concat(0) // Line - .concat(Size) - .concat(AlignInBits) - .concat(0) // Offset - .concat(0) // Flags - .concat(0) - .get(VMContext), - nullptr, // Filename/Directory, - nullptr, // Unused - Ty.getRef(), Subscripts, nullptr, nullptr, - nullptr // Type Identifer - }; - return DICompositeType(MDNode::get(VMContext, Elts)); + auto *R = MDCompositeType::get(VMContext, dwarf::DW_TAG_array_type, "", + nullptr, 0, nullptr, MDTypeRef::get(Ty), Size, + AlignInBits, 0, 0, Subscripts, 0, nullptr); + trackIfUnresolved(R); + return R; } DICompositeType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, DIType Ty, DIArray Subscripts) { - // A vector is an array type with the FlagVector flag applied. - Metadata *Elts[] = { - HeaderBuilder::get(dwarf::DW_TAG_array_type) - .concat("") - .concat(0) // Line - .concat(Size) - .concat(AlignInBits) - .concat(0) // Offset - .concat(DIType::FlagVector) - .concat(0) - .get(VMContext), - nullptr, // Filename/Directory, - nullptr, // Unused - Ty.getRef(), Subscripts, nullptr, nullptr, - nullptr // Type Identifer - }; - return DICompositeType(MDNode::get(VMContext, Elts)); -} - -static HeaderBuilder setTypeFlagsInHeader(StringRef Header, - unsigned FlagsToSet) { - DIHeaderFieldIterator I(Header); - std::advance(I, 6); - - unsigned Flags; - if (I->getAsInteger(0, Flags)) - Flags = 0; - Flags |= FlagsToSet; - - return HeaderBuilder() - .concat(I.getPrefix()) - .concat(Flags) - .concat(I.getSuffix()); + auto *R = + MDCompositeType::get(VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0, + nullptr, MDTypeRef::get(Ty), Size, AlignInBits, 0, + DIType::FlagVector, Subscripts, 0, nullptr); + trackIfUnresolved(R); + return R; } static DIType createTypeWithFlags(LLVMContext &Context, DIType Ty, unsigned FlagsToSet) { - SmallVector Elts; - MDNode *N = Ty; - assert(N && "Unexpected input DIType!"); - // Update header field. - Elts.push_back(setTypeFlagsInHeader(Ty.getHeader(), FlagsToSet).get(Context)); - for (unsigned I = 1, E = N->getNumOperands(); I != E; ++I) - Elts.push_back(N->getOperand(I)); - - return DIType(MDNode::get(Context, Elts)); + TempMDType NewTy = cast(static_cast(Ty))->clone(); + NewTy->setFlags(NewTy->getFlags() | FlagsToSet); + return MDNode::replaceWithUniqued(std::move(NewTy)); } DIType DIBuilder::createArtificialType(DIType Ty) { + // FIXME: Restrict this to the nodes where it's valid. if (Ty.isArtificial()) return Ty; return createTypeWithFlags(VMContext, Ty, DIType::FlagArtificial); } DIType DIBuilder::createObjectPointerType(DIType Ty) { + // FIXME: Restrict this to the nodes where it's valid. if (Ty.isObjectPointer()) return Ty; unsigned Flags = DIType::FlagObjectPointer | DIType::FlagArtificial; return createTypeWithFlags(VMContext, Ty, Flags); } -void DIBuilder::retainType(DIType T) { AllRetainTypes.emplace_back(T); } +void DIBuilder::retainType(DIType T) { + assert(T.get() && "Expected non-null type"); + AllRetainTypes.emplace_back(T); +} DIBasicType DIBuilder::createUnspecifiedParameter() { return DIBasicType(); @@ -791,56 +527,33 @@ DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits, StringRef UniqueIdentifier) { - // Create a temporary MDNode. - Metadata *Elts[] = { - HeaderBuilder::get(Tag) - .concat(Name) - .concat(Line) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(0) // Offset - .concat(DIDescriptor::FlagFwdDecl) - .concat(RuntimeLang) - .get(VMContext), - F.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), nullptr, - DIArray(), nullptr, - nullptr, // TemplateParams - UniqueIdentifier.empty() ? nullptr - : MDString::get(VMContext, UniqueIdentifier)}; - MDNode *Node = MDNode::get(VMContext, Elts); - DICompositeType RetTy(Node); - assert(RetTy.isCompositeType() && - "createForwardDecl result should be a DIType"); + // FIXME: Define in terms of createReplaceableForwardDecl() by calling + // replaceWithUniqued(). + DICompositeType RetTy = MDCompositeType::get( + VMContext, Tag, Name, F, Line, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Scope))), nullptr, + SizeInBits, AlignInBits, 0, DIDescriptor::FlagFwdDecl, nullptr, + RuntimeLang, nullptr, nullptr, UniqueIdentifier); if (!UniqueIdentifier.empty()) retainType(RetTy); + trackIfUnresolved(RetTy); return RetTy; } -DICompositeType DIBuilder::createReplaceableForwardDecl( +DICompositeType DIBuilder::createReplaceableCompositeType( unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits, - StringRef UniqueIdentifier) { - // Create a temporary MDNode. - Metadata *Elts[] = { - HeaderBuilder::get(Tag) - .concat(Name) - .concat(Line) - .concat(SizeInBits) - .concat(AlignInBits) - .concat(0) // Offset - .concat(DIDescriptor::FlagFwdDecl) - .concat(RuntimeLang) - .get(VMContext), - F.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), nullptr, - DIArray(), nullptr, - nullptr, // TemplateParams - UniqueIdentifier.empty() ? nullptr - : MDString::get(VMContext, UniqueIdentifier)}; - DICompositeType RetTy(MDNode::getTemporary(VMContext, Elts).release()); - assert(RetTy.isCompositeType() && - "createReplaceableForwardDecl result should be a DIType"); + unsigned Flags, StringRef UniqueIdentifier) { + DICompositeType RetTy = + MDCompositeType::getTemporary( + VMContext, Tag, Name, F, Line, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Scope))), nullptr, + SizeInBits, AlignInBits, 0, Flags, nullptr, RuntimeLang, nullptr, + nullptr, UniqueIdentifier) + .release(); if (!UniqueIdentifier.empty()) retainType(RetTy); + trackIfUnresolved(RetTy); return RetTy; } @@ -852,7 +565,7 @@ DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef Elements) { SmallVector Elts; for (unsigned i = 0, e = Elements.size(); i != e; ++i) { if (Elements[i] && isa(Elements[i])) - Elts.push_back(DIType(cast(Elements[i])).getRef()); + Elts.push_back(MDTypeRef::get(cast(Elements[i]))); else Elts.push_back(Elements[i]); } @@ -860,79 +573,58 @@ DITypeArray DIBuilder::getOrCreateTypeArray(ArrayRef Elements) { } DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) { - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subrange_type) - .concat(Lo) - .concat(Count) - .get(VMContext)}; - - return DISubrange(MDNode::get(VMContext, Elts)); + return MDSubrange::get(VMContext, Count, Lo); } -static DIGlobalVariable createGlobalVariableHelper( - LLVMContext &VMContext, DIDescriptor Context, StringRef Name, - StringRef LinkageName, DIFile F, unsigned LineNumber, DITypeRef Ty, - bool isLocalToUnit, Constant *Val, MDNode *Decl, bool isDefinition, - std::function)> CreateFunc) { - - MDNode *TheCtx = getNonCompileUnitScope(Context); - if (DIScope(TheCtx).isCompositeType()) { - assert(!DICompositeType(TheCtx).getIdentifier() && +static void checkGlobalVariableScope(DIDescriptor Context) { +#ifndef NDEBUG + if (DICompositeType CT = + dyn_cast_or_null(getNonCompileUnitScope(Context))) + assert(!CT.getIdentifier() && "Context of a global variable should not be a type with identifier"); - } - - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_variable) - .concat(Name) - .concat(Name) - .concat(LinkageName) - .concat(LineNumber) - .concat(isLocalToUnit) - .concat(isDefinition) - .get(VMContext), - TheCtx, F, Ty, getConstantOrNull(Val), - DIDescriptor(Decl)}; - - return DIGlobalVariable(CreateFunc(Elts)); +#endif } DIGlobalVariable DIBuilder::createGlobalVariable( DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F, - unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val, + unsigned LineNumber, DIType Ty, bool isLocalToUnit, Constant *Val, MDNode *Decl) { - return createGlobalVariableHelper( - VMContext, Context, Name, LinkageName, F, LineNumber, Ty, isLocalToUnit, - Val, Decl, true, [&](ArrayRef Elts) -> MDNode *{ - MDNode *Node = MDNode::get(VMContext, Elts); - AllGVs.push_back(Node); - return Node; - }); + checkGlobalVariableScope(Context); + + auto *N = MDGlobalVariable::get( + VMContext, cast_or_null(Context.get()), Name, LinkageName, F, + LineNumber, MDTypeRef::get(Ty), isLocalToUnit, true, + getConstantOrNull(Val), cast_or_null(Decl)); + AllGVs.push_back(N); + return N; } DIGlobalVariable DIBuilder::createTempGlobalVariableFwdDecl( DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F, - unsigned LineNumber, DITypeRef Ty, bool isLocalToUnit, Constant *Val, + unsigned LineNumber, DIType Ty, bool isLocalToUnit, Constant *Val, MDNode *Decl) { - return createGlobalVariableHelper(VMContext, Context, Name, LinkageName, F, - LineNumber, Ty, isLocalToUnit, Val, Decl, - false, [&](ArrayRef Elts) { - return MDNode::getTemporary(VMContext, Elts).release(); - }); + checkGlobalVariableScope(Context); + + return MDGlobalVariable::getTemporary( + VMContext, cast_or_null(Context.get()), Name, LinkageName, + F, LineNumber, MDTypeRef::get(Ty), isLocalToUnit, false, getConstantOrNull(Val), + cast_or_null(Decl)).release(); } DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, StringRef Name, DIFile File, - unsigned LineNo, DITypeRef Ty, + unsigned LineNo, DIType Ty, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) { - DIDescriptor Context(getNonCompileUnitScope(Scope)); - assert((!Context || Context.isScope()) && - "createLocalVariable should be called with a valid Context"); - Metadata *Elts[] = {HeaderBuilder::get(Tag) - .concat(Name) - .concat(LineNo | (ArgNo << 24)) - .concat(Flags) - .get(VMContext), - getNonCompileUnitScope(Scope), File, Ty}; - MDNode *Node = MDNode::get(VMContext, Elts); + // FIXME: Why getNonCompileUnitScope()? + // FIXME: Why is "!Context" okay here? + // FIXME: WHy doesn't this check for a subprogram or lexical block (AFAICT + // the only valid scopes)? + DIScope Context = getNonCompileUnitScope(Scope); + + auto *Node = MDLocalVariable::get( + VMContext, Tag, cast_or_null(Context.get()), Name, File, + LineNo, MDTypeRef::get(Ty), ArgNo, Flags); if (AlwaysPreserve) { // The optimizer may remove local variable. If there is an interest // to preserve variable info in such situation then stash it in a @@ -941,18 +633,11 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, assert(Fn && "Missing subprogram for local variable"); PreservedVariables[Fn].emplace_back(Node); } - DIVariable RetVar(Node); - assert(RetVar.isVariable() && - "createLocalVariable should return a valid DIVariable"); - return RetVar; + return Node; } DIExpression DIBuilder::createExpression(ArrayRef Addr) { - auto Header = HeaderBuilder::get(DW_TAG_expression); - for (uint64_t I : Addr) - Header.concat(I); - Metadata *Elts[] = {Header.get(VMContext)}; - return DIExpression(MDNode::get(VMContext, Elts)); + return MDExpression::get(VMContext, Addr); } DIExpression DIBuilder::createExpression(ArrayRef Signed) { @@ -961,10 +646,10 @@ DIExpression DIBuilder::createExpression(ArrayRef Signed) { return createExpression(Addr); } -DIExpression DIBuilder::createPieceExpression(unsigned OffsetInBytes, - unsigned SizeInBytes) { - uint64_t Addr[] = {dwarf::DW_OP_piece, OffsetInBytes, SizeInBytes}; - return createExpression(Addr); +DIExpression DIBuilder::createBitPieceExpression(unsigned OffsetInBytes, + unsigned SizeInBytes) { + uint64_t Addr[] = {dwarf::DW_OP_bit_piece, OffsetInBytes, SizeInBytes}; + return MDExpression::get(VMContext, Addr); } DISubprogram DIBuilder::createFunction(DIScopeRef Context, StringRef Name, @@ -982,38 +667,6 @@ DISubprogram DIBuilder::createFunction(DIScopeRef Context, StringRef Name, Flags, isOptimized, Fn, TParams, Decl); } -static DISubprogram createFunctionHelper( - LLVMContext &VMContext, DIDescriptor Context, StringRef Name, - StringRef LinkageName, DIFile File, unsigned LineNo, DICompositeType Ty, - bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags, - bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl, MDNode *Vars, - std::function)> CreateFunc) { - assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && - "function types should be subroutines"); - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram) - .concat(Name) - .concat(Name) - .concat(LinkageName) - .concat(LineNo) - .concat(isLocalToUnit) - .concat(isDefinition) - .concat(0) - .concat(0) - .concat(Flags) - .concat(isOptimized) - .concat(ScopeLine) - .get(VMContext), - File.getFileNode(), - DIScope(getNonCompileUnitScope(Context)).getRef(), Ty, - nullptr, getConstantOrNull(Fn), TParams, Decl, Vars}; - - DISubprogram S(CreateFunc(Elts)); - assert(S.isSubprogram() && - "createFunction should return a valid DISubprogram"); - return S; -} - - DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile File, unsigned LineNo, DICompositeType Ty, @@ -1021,18 +674,20 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, unsigned ScopeLine, unsigned Flags, bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl) { - return createFunctionHelper(VMContext, Context, Name, LinkageName, File, - LineNo, Ty, isLocalToUnit, isDefinition, - ScopeLine, Flags, isOptimized, Fn, TParams, Decl, - MDNode::getTemporary(VMContext, None).release(), - [&](ArrayRef Elts) -> MDNode *{ - MDNode *Node = MDNode::get(VMContext, Elts); - // Create a named metadata so that we - // do not lose this mdnode. - if (isDefinition) - AllSubprograms.push_back(Node); - return Node; - }); + assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && + "function types should be subroutines"); + auto *Node = MDSubprogram::get( + VMContext, MDScopeRef::get(DIScope(getNonCompileUnitScope(Context))), + Name, LinkageName, File.get(), LineNo, + cast_or_null(Ty.get()), isLocalToUnit, isDefinition, + ScopeLine, nullptr, 0, 0, Flags, isOptimized, getConstantOrNull(Fn), + cast_or_null(TParams), cast_or_null(Decl), + MDTuple::getTemporary(VMContext, None).release()); + + if (isDefinition) + AllSubprograms.push_back(Node); + trackIfUnresolved(Node); + return Node; } DISubprogram @@ -1043,12 +698,15 @@ DIBuilder::createTempFunctionFwdDecl(DIDescriptor Context, StringRef Name, unsigned ScopeLine, unsigned Flags, bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl) { - return createFunctionHelper(VMContext, Context, Name, LinkageName, File, - LineNo, Ty, isLocalToUnit, isDefinition, - ScopeLine, Flags, isOptimized, Fn, TParams, Decl, - nullptr, [&](ArrayRef Elts) { - return MDNode::getTemporary(VMContext, Elts).release(); - }); + return MDSubprogram::getTemporary( + VMContext, + MDScopeRef::get(DIScope(getNonCompileUnitScope(Context))), Name, + LinkageName, File.get(), LineNo, + cast_or_null(Ty.get()), isLocalToUnit, + isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized, + getConstantOrNull(Fn), cast_or_null(TParams), + cast_or_null(Decl), nullptr) + .release(); } DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, @@ -1064,79 +722,39 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, assert(getNonCompileUnitScope(Context) && "Methods should have both a Context and a context that isn't " "the compile unit."); - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram) - .concat(Name) - .concat(Name) - .concat(LinkageName) - .concat(LineNo) - .concat(isLocalToUnit) - .concat(isDefinition) - .concat(VK) - .concat(VIndex) - .concat(Flags) - .concat(isOptimized) - .concat(LineNo) - // FIXME: Do we want to use different scope/lines? - .get(VMContext), - F.getFileNode(), DIScope(Context).getRef(), Ty, - VTableHolder.getRef(), getConstantOrNull(Fn), TParam, - nullptr, nullptr}; - MDNode *Node = MDNode::get(VMContext, Elts); + // FIXME: Do we want to use different scope/lines? + auto *SP = MDSubprogram::get( + VMContext, MDScopeRef::get(cast(Context)), Name, LinkageName, + F.get(), LineNo, cast_or_null(Ty.get()), isLocalToUnit, + isDefinition, LineNo, MDTypeRef::get(VTableHolder), VK, VIndex, Flags, + isOptimized, getConstantOrNull(Fn), cast_or_null(TParam), + nullptr, nullptr); + if (isDefinition) - AllSubprograms.push_back(Node); - DISubprogram S(Node); - assert(S.isSubprogram() && "createMethod should return a valid DISubprogram"); - return S; + AllSubprograms.push_back(SP); + trackIfUnresolved(SP); + return SP; } DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNo) { - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_namespace) - .concat(Name) - .concat(LineNo) - .get(VMContext), - File.getFileNode(), getNonCompileUnitScope(Scope)}; - DINameSpace R(MDNode::get(VMContext, Elts)); - assert(R.Verify() && - "createNameSpace should return a verifiable DINameSpace"); - return R; + return MDNamespace::get(VMContext, getNonCompileUnitScope(Scope), File, Name, + LineNo); } DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, DIFile File, unsigned Discriminator) { - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block) - .concat(Discriminator) - .get(VMContext), - File.getFileNode(), Scope}; - DILexicalBlockFile R(MDNode::get(VMContext, Elts)); - assert( - R.Verify() && - "createLexicalBlockFile should return a verifiable DILexicalBlockFile"); - return R; + return MDLexicalBlockFile::get(VMContext, Scope, File.getFileNode(), + Discriminator); } DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, unsigned Line, unsigned Col) { - // FIXME: This isn't thread safe nor the right way to defeat MDNode uniquing. - // I believe the right way is to have a self-referential element in the node. - // Also: why do we bother with line/column - they're not used and the - // documentation (SourceLevelDebugging.rst) claims the line/col are necessary - // for uniquing, yet then we have this other solution (because line/col were - // inadequate) anyway. Remove all 3 and replace them with a self-reference. - - // Defeat MDNode uniquing for lexical blocks by using unique id. - static unsigned int unique_id = 0; - Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block) - .concat(Line) - .concat(Col) - .concat(unique_id++) - .get(VMContext), - File.getFileNode(), getNonCompileUnitScope(Scope)}; - DILexicalBlock R(MDNode::get(VMContext, Elts)); - assert(R.Verify() && - "createLexicalBlock should return a verifiable DILexicalBlock"); - return R; + // Make these distinct, to avoid merging two lexical blocks on the same + // file/line/column. + return MDLexicalBlock::getDistinct(VMContext, getNonCompileUnitScope(Scope), + File.getFileNode(), Line, Col); } static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) { @@ -1147,8 +765,7 @@ static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) { Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, DIExpression Expr, Instruction *InsertBefore) { - assert(VarInfo.isVariable() && - "empty or invalid DIVariable passed to dbg.declare"); + assert(VarInfo && "empty or invalid DIVariable passed to dbg.declare"); if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); @@ -1163,8 +780,7 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, DIExpression Expr, BasicBlock *InsertAtEnd) { - assert(VarInfo.isVariable() && - "empty or invalid DIVariable passed to dbg.declare"); + assert(VarInfo && "empty or invalid DIVariable passed to dbg.declare"); if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); @@ -1187,8 +803,7 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, DIExpression Expr, Instruction *InsertBefore) { assert(V && "no value passed to dbg.value"); - assert(VarInfo.isVariable() && - "empty or invalid DIVariable passed to dbg.value"); + assert(VarInfo && "empty or invalid DIVariable passed to dbg.value"); if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); @@ -1206,8 +821,7 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, DIExpression Expr, BasicBlock *InsertAtEnd) { assert(V && "no value passed to dbg.value"); - assert(VarInfo.isVariable() && - "empty or invalid DIVariable passed to dbg.value"); + assert(VarInfo && "empty or invalid DIVariable passed to dbg.value"); if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); @@ -1221,23 +835,34 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, } void DIBuilder::replaceVTableHolder(DICompositeType &T, DICompositeType VTableHolder) { - T.setContainingType(VTableHolder); + { + TypedTrackingMDRef N(T); + N->replaceVTableHolder(MDTypeRef::get(VTableHolder)); + T = N.get(); + } // If this didn't create a self-reference, just return. if (T != VTableHolder) return; - // Look for unresolved operands. T has dropped RAUW support and is already - // marked resolved, orphaning any cycles underneath it. - assert(T->isResolved() && "Expected self-reference to be resolved"); - for (const MDOperand &O : T->operands()) - if (auto *N = dyn_cast_or_null(O)) - trackIfUnresolved(N); + // Look for unresolved operands. T will drop RAUW support, orphaning any + // cycles underneath it. + if (T->isResolved()) + for (const MDOperand &O : T->operands()) + if (auto *N = dyn_cast_or_null(O)) + trackIfUnresolved(N); } void DIBuilder::replaceArrays(DICompositeType &T, DIArray Elements, DIArray TParams) { - T.setArrays(Elements, TParams); + { + TypedTrackingMDRef N(T); + if (Elements) + N->replaceElements(Elements); + if (TParams) + N->replaceTemplateParams(MDTemplateParameterArray(TParams)); + T = N.get(); + } // If T isn't resolved, there's no problem. if (!T->isResolved()) @@ -1247,7 +872,7 @@ void DIBuilder::replaceArrays(DICompositeType &T, DIArray Elements, // arrays explicitly if they're unresolved, or else the cycles will be // orphaned. if (Elements) - trackIfUnresolved(Elements); + trackIfUnresolved(Elements.get()); if (TParams) - trackIfUnresolved(TParams); + trackIfUnresolved(TParams.get()); }