Index: include/llvm/IR/DIBuilder.h =================================================================== --- include/llvm/IR/DIBuilder.h +++ include/llvm/IR/DIBuilder.h @@ -46,6 +46,7 @@ SmallVector AllSubprograms; SmallVector AllGVs; SmallVector AllImportedModules; + DenseMap> AllMacrosPerParent; /// Track nodes that may be unresolved. SmallVector UnresolvedNodes; @@ -114,6 +115,23 @@ /// for a file. DIFile *createFile(StringRef Filename, StringRef Directory); + /// Create debugging information entry for a macro. + /// \param Parent Macro parent (could be null). + /// \param LineNumber Source line where the macro is defined. + /// \param IsUndef True for undef macro, false for definition macro. + /// \param Name Macro name. + /// \param Value Macro value. + DIMacro *createMacro(DIMacroFile *Parent, unsigned LineNumber, bool IsUndef, + StringRef Name, StringRef Value = ""); + + /// Create debugging information entry for a macro file. + /// \param Parent Macro file parent (could be null). + /// \param LineNumber Source line where the macro file is included. + /// \param File File descriptor containing the name of the macro file. + /// \param Elements List of macro node direct children. + DIMacroFile *createMacroFile(DIMacroFile *Parent, unsigned LineNumber, + DIFile *File, DIMacroNodeArray Elements); + /// Create a single enumerator value. DIEnumerator *createEnumerator(StringRef Name, int64_t Val); @@ -424,6 +442,9 @@ /// Get a DINodeArray, create one if required. DINodeArray getOrCreateArray(ArrayRef Elements); + /// Get a DIMacroNodeArray, create one if required. + DIMacroNodeArray getOrCreateMacroArray(ArrayRef Elements); + /// Get a DITypeRefArray, create one if required. DITypeRefArray getOrCreateTypeArray(ArrayRef Elements); @@ -704,6 +725,13 @@ void replaceArrays(DICompositeType *&T, DINodeArray Elements, DINodeArray TParams = DINodeArray()); + /// Replace macro node arrays on a macro file. + /// + /// If \c F is resolved, but the arrays aren't -- which can happen if \c F + /// has a self-reference -- \a DIBuilder needs to track the array to + /// resolve cycles. + void replaceArrays(DIMacroFile *&F, DIMacroNodeArray Elements); + /// Replace a temporary node. /// /// Call \a MDNode::replaceAllUsesWith() on \c N, replacing it with \c Index: lib/IR/DIBuilder.cpp =================================================================== --- lib/IR/DIBuilder.cpp +++ lib/IR/DIBuilder.cpp @@ -115,6 +115,15 @@ VMContext, SmallVector(AllImportedModules.begin(), AllImportedModules.end()))); + for (const auto &I : AllMacrosPerParent) { + if (I.first == nullptr) { + CUNode->replaceMacros(MDTuple::get(VMContext, I.second)); + continue; + } + DIMacroFile *MF = cast(I.first); + MF->replaceElements(getOrCreateMacroArray(I.second)); + } + // Now that all temp nodes have been replaced or deleted, resolve remaining // cycles. for (const auto &N : UnresolvedNodes) @@ -208,6 +217,27 @@ return DIFile::get(VMContext, Filename, Directory); } +DIMacro *DIBuilder::createMacro(DIMacroFile *Parent, unsigned LineNumber, + bool IsUndef, StringRef Name, + StringRef Value) { + assert(!Name.empty() && "Unable to create macro without name"); + auto MIType = IsUndef ? dwarf::DW_MACINFO_undef : dwarf::DW_MACINFO_define; + auto *M = DIMacro::get(VMContext, MIType, LineNumber, Name, Value); + AllMacrosPerParent[Parent].push_back(M); + trackIfUnresolved(M); + return M; +} + +DIMacroFile *DIBuilder::createMacroFile(DIMacroFile *Parent, + unsigned LineNumber, DIFile *File, + DIMacroNodeArray Elements) { + auto *MF = DIMacroFile::get(VMContext, dwarf::DW_MACINFO_start_file, + LineNumber, File, Elements); + AllMacrosPerParent[Parent].push_back(MF); + trackIfUnresolved(MF); + return MF; +} + DIEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val) { assert(!Name.empty() && "Unable to create enumerator without name"); return DIEnumerator::get(VMContext, Val, Name); @@ -552,6 +582,10 @@ return MDTuple::get(VMContext, Elements); } +DIMacroNodeArray DIBuilder::getOrCreateMacroArray(ArrayRef Elements) { + return MDTuple::get(VMContext, Elements); +} + DITypeRefArray DIBuilder::getOrCreateTypeArray(ArrayRef Elements) { SmallVector Elts; for (unsigned i = 0, e = Elements.size(); i != e; ++i) { @@ -905,3 +939,23 @@ if (TParams) trackIfUnresolved(TParams.get()); } + +void DIBuilder::replaceArrays(DIMacroFile *&F, DIMacroNodeArray Elements) { + { + TypedTrackingMDRef N(F); + if (Elements) + N->replaceElements(Elements); + F = N.get(); + } + + // If F isn't resolved, there's no problem. + if (!F->isResolved()) + return; + + // If F is resolved, it may be due to a self-reference cycle. Track the + // arrays explicitly if they're unresolved, or else the cycles will be + // orphaned. + if (Elements) + trackIfUnresolved(Elements.get()); +} +