diff --git a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst index 221732775e74c..6fcf8423e8125 100644 --- a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst +++ b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst @@ -13,11 +13,10 @@ SYNOPSIS DESCRIPTION ----------- :program:`llvm-debuginfo-analyzer` parses debug and text sections in -binary object files or LLVM IR textual / bitcode representation and prints -their contents in a logical view, which is a human readable representation -that closely matches the structure of the original user source code. -Supported object file formats include ELF, Mach-O, WebAssembly, PDB, -COFF and IR (textual representation and bitcode). +binary object files and prints their contents in a logical view, which +is a human-readable representation that closely matches the structure +of the original user source code. Supported object file formats include +ELF, Mach-O, WebAssembly, PDB and COFF. The **logical view** abstracts the complexity associated with the different low-level representations of the debugging information that @@ -2132,95 +2131,143 @@ layout and given the number of matches. ----------------------------- Total 71 8 -LLVM IR (textual / bitcode representation) SUPPORT -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The below example is used to show the IR output generated by -:program:`llvm-debuginfo-analyzer`. We compiled the example for a -IR 64-bit target with Clang (-O0 -g --target=x86_64-linux): +COMPARISON MODE +^^^^^^^^^^^^^^^ +Given the previous example we found the above debug information issue +(related to the previous invalid scope location for the **'typedef int +INTEGER'**) by comparing against another compiler. -.. code-block:: c++ +Using GCC to generate test-dwarf-gcc.o, we can apply a selection pattern +with the printing mode to obtain the following logical view output. - 1 using INTPTR = const int *; - 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { - 3 if (ParamBool) { - 4 typedef int INTEGER; - 5 const INTEGER CONSTANT = 7; - 6 return CONSTANT; - 7 } - 8 return ParamUnsigned; - 9 } +.. code-block:: none -PRINT BASIC DETAILS -^^^^^^^^^^^^^^^^^^^ -The following command prints basic details for all the logical elements -sorted by the debug information internal offset; it includes its lexical -level and debug info format. + llvm-debuginfo-analyzer --attribute=level + --select-regex --select-nocase --select=INTe + --report=list + --print=symbols,types + test-clang.o test-dwarf-gcc.o + + Logical View: + [000] {File} 'test-clang.o' + + [001] {CompileUnit} 'test.cpp' + [003] 4 {TypeAlias} 'INTEGER' -> 'int' + [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' + + Logical View: + [000] {File} 'test-dwarf-gcc.o' + + [001] {CompileUnit} 'test.cpp' + [004] 4 {TypeAlias} 'INTEGER' -> 'int' + [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' + +The output shows that both objects contain the same elements. But the +**'typedef INTEGER'** is located at different scope level. The GCC +generated object, shows **'4'**, which is the correct value. + +There are 2 comparison methods: logical view and logical elements. + +LOGICAL VIEW +"""""""""""" +It compares the logical view as a whole unit; for a match, each compared +logical element must have the same parents and children. + +The output shows in view form the **missing (-), added (+)** elements, +giving more context by swapping the reference and target object files. .. code-block:: none - llvm-debuginfo-analyzer --attribute=level,format - --output-sort=offset - --print=scopes,symbols,types,lines,instructions - test-clang.ll + llvm-debuginfo-analyzer --attribute=level + --compare=types + --report=view + --print=symbols,types + test-clang.o test-dwarf-gcc.o -or + Reference: 'test-clang.o' + Target: 'test-dwarf-gcc.o' + + Logical View: + [000] {File} 'test-clang.o' + + [001] {CompileUnit} 'test.cpp' + [002] 1 {TypeAlias} 'INTPTR' -> '* const int' + [002] 2 {Function} extern not_inlined 'foo' -> 'int' + [003] {Block} + [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' + +[004] 4 {TypeAlias} 'INTEGER' -> 'int' + [003] 2 {Parameter} 'ParamBool' -> 'bool' + [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' + [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' + -[003] 4 {TypeAlias} 'INTEGER' -> 'int' + +The output shows the merging view path (reference and target) with the +missing and added elements. + +LOGICAL ELEMENTS +"""""""""""""""" +It compares individual logical elements without considering if their +parents are the same. For both comparison methods, the equal criteria +includes the name, source code location, type, lexical scope level. .. code-block:: none - llvm-debuginfo-analyzer --attribute=level,format - --output-sort=offset - --print=elements - test-clang.ll + llvm-debuginfo-analyzer --attribute=level + --compare=types + --report=list + --print=symbols,types,summary + test-clang.o test-dwarf-gcc.o -Each row represents an element that is present within the debug -information. The first column represents the scope level, followed by -the associated line number (if any), and finally the description of -the element. + Reference: 'test-clang.o' + Target: 'test-dwarf-gcc.o' + + (1) Missing Types: + -[003] 4 {TypeAlias} 'INTEGER' -> 'int' + + (1) Added Types: + +[004] 4 {TypeAlias} 'INTEGER' -> 'int' + + ---------------------------------------- + Element Expected Missing Added + ---------------------------------------- + Scopes 4 0 0 + Symbols 0 0 0 + Types 2 1 1 + Lines 0 0 0 + ---------------------------------------- + Total 6 1 1 + +Changing the *Reference* and *Target* order: .. code-block:: none - Logical View: - [000] {File} 'test-clang.ll' -> Textual IR + llvm-debuginfo-analyzer --attribute=level + --compare=types + --report=list + --print=symbols,types,summary + test-dwarf-gcc.o test-clang.o - [001] {CompileUnit} 'test.cpp' - [002] 2 {Function} extern not_inlined 'foo' -> 'int' - [003] {Block} - [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' - [004] 5 {Line} - [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32' - [004] 6 {Line} - [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33' - [004] 6 {Line} - [004] {Code} 'br label %return, !dbg !33' - [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' - [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' - [003] 2 {Parameter} 'ParamBool' -> 'bool' - [003] 4 {TypeAlias} 'INTEGER' -> 'int' - [003] 2 {Line} - [003] {Code} '%retval = alloca i32, align 4' - [003] {Code} '%ParamPtr.addr = alloca ptr, align 8' - [003] {Code} '%ParamUnsigned.addr = alloca i32, align 4' - [003] {Code} '%ParamBool.addr = alloca i8, align 1' - [003] {Code} '%CONSTANT = alloca i32, align 4' - [003] {Code} 'store ptr %ParamPtr, ptr %ParamPtr.addr, align 8' - [003] {Code} 'store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4' - [003] {Code} '%storedv = zext i1 %ParamBool to i8' - [003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1' - [003] 8 {Line} - [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34' - [003] 8 {Line} - [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35' - [003] 8 {Line} - [003] {Code} 'br label %return, !dbg !35' - [003] 9 {Line} - [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36' - [003] 9 {Line} - [003] {Code} 'ret i32 %2, !dbg !36' - [003] 3 {Line} - [003] 3 {Line} - [003] 3 {Line} - [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26' - [002] 1 {TypeAlias} 'INTPTR' -> '* const int' + Reference: 'test-dwarf-gcc.o' + Target: 'test-clang.o' + + (1) Missing Types: + -[004] 4 {TypeAlias} 'INTEGER' -> 'int' + + (1) Added Types: + +[003] 4 {TypeAlias} 'INTEGER' -> 'int' + + ---------------------------------------- + Element Expected Missing Added + ---------------------------------------- + Scopes 4 0 0 + Symbols 0 0 0 + Types 2 1 1 + Lines 0 0 0 + ---------------------------------------- + Total 6 1 1 + +As the *Reference* and *Target* are switched, the *Added Types* from +the first case now are listed as *Missing Types*. EXIT STATUS ----------- diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h index 793a66e40b02b..34bace886a15f 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVElement.h @@ -374,13 +374,6 @@ class LLVM_ABI LVElement : public LVObject { // Report the current element as missing or added during comparison. virtual void report(LVComparePass Pass) {} - // Print the basic and extra information. Used mainly to debug IR. - void printCommon(raw_ostream &OS, bool Full = true) const; - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - void dumpCommon() const { printCommon(dbgs(), /*Full=*/true); } -#endif - static LVElementDispatch &getDispatch() { return Dispatch; } }; diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h index 6bf7f9d2105f8..090af54cd1b85 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h @@ -159,13 +159,6 @@ class LLVM_ABI LVLocation : public LVObject { void print(raw_ostream &OS, bool Full = true) const override; void printExtra(raw_ostream &OS, bool Full = true) const override; - - // Print the basic and extra information. Used mainly to debug IR. - void printCommon(raw_ostream &OS, bool Full = true) const; - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - void dumpCommon() const { printCommon(dbgs(), /*Full=*/true); } -#endif }; class LLVM_ABI LVLocationSymbol final : public LVLocation { diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h index 774318cb3c53e..371bffb2ed163 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVReader.h @@ -193,9 +193,6 @@ class LLVM_ABI LVReader { virtual Error printMatchedElements(bool UseMatchedElements); virtual void sortScopes() {} - void printCollectedElements(LVScope *Root); - bool checkIntegrityScopesTree(LVScope *Root); - public: LVReader() = delete; LVReader(StringRef InputFilename, StringRef FileFormatName, ScopedPrinter &W, diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h index 756bb18aeff12..eec5df19ff843 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Core/LVSupport.h @@ -119,20 +119,7 @@ template class LVProperties { #define KIND_3(ENUM, FIELD, F1, F2, F3) \ BOOL_BIT_3(Kinds, ENUM, FIELD, F1, F2, F3) -static constexpr int DEC_WIDTH = 8; -inline FormattedNumber decValue(uint64_t N, unsigned Width = DEC_WIDTH) { - return format_decimal(N, Width); -} - -// Output the decimal representation of 'Value'. -inline std::string decString(uint64_t Value, size_t Width = DEC_WIDTH) { - std::string String; - raw_string_ostream Stream(String); - Stream << decValue(Value, Width); - return String; -} - -static constexpr int HEX_WIDTH = 12; +const int HEX_WIDTH = 12; inline FormattedNumber hexValue(uint64_t N, unsigned Width = HEX_WIDTH, bool Upper = false) { return format_hex(N, Width, Upper); diff --git a/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h b/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h index 3336c9415927c..f6dc65f39c7ac 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h @@ -17,7 +17,6 @@ #include "llvm/DebugInfo/LogicalView/Core/LVReader.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/Object/Archive.h" -#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Compiler.h" @@ -31,9 +30,7 @@ namespace logicalview { using LVReaders = std::vector>; using ArgVector = std::vector; -using InputHandle = - PointerUnion; +using PdbOrObj = PointerUnion; // This class performs the following tasks: // - Creates a logical reader for every binary file in the command line, @@ -64,10 +61,8 @@ class LVReaderHandler { object::Binary &Binary); Error handleObject(LVReaders &Readers, StringRef Filename, StringRef Buffer, StringRef ExePath); - Error handleObject(LVReaders &Readers, StringRef Filename, - MemoryBufferRef Buffer); - Error createReader(StringRef Filename, LVReaders &Readers, InputHandle &Input, + Error createReader(StringRef Filename, LVReaders &Readers, PdbOrObj &Input, StringRef FileFormatName, StringRef ExePath = {}); public: diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h index f5590ad40c993..64389902ea6fd 100644 --- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h +++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h @@ -26,7 +26,6 @@ #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/COFF.h" -#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/ObjectFile.h" namespace llvm { diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVIRReader.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVIRReader.h deleted file mode 100644 index bb5fe7c7a4076..0000000000000 --- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVIRReader.h +++ /dev/null @@ -1,302 +0,0 @@ -//===-- LVIRReader.h --------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the LVIRReader class, which is used to describe a -// LLVM IR reader. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H -#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H - -#include "llvm/DebugInfo/LogicalView/Core/LVReader.h" -#include "llvm/Transforms/Utils/DebugSSAUpdater.h" - -namespace llvm { -class DIFile; -class DINode; -class DILocation; -class DIScope; -class DISubprogram; -class DIVariable; -class BasicBlock; -class Module; - -namespace object { -class IRObjectFile; -} - -namespace logicalview { - -class LVElement; -class LVLine; -class LVScopeCompileUnit; -class LVSymbol; -class LVType; -struct LVSourceLanguage; - -class LVIRReader final : public LVReader { - PointerUnion InputFile; - - // Used by the metadata 'dump' functions, so the metadata nodes will be - // numbered canonically; otherwise, pointer addresses are substituted. - Module *TheModule = nullptr; - - // Symbols with locations for current compile unit. - LVSymbols SymbolsWithLocations; - - const DICompileUnit *CUNode = nullptr; - - // The Dwarf version (from the module flags). - unsigned DwarfVersion = 0; - - // Location index for global variables. - uint64_t PoolAddressIndex = 0; - - // Default lower bound for arrays. - int64_t DefaultLowerBound = 0; - - // Whether to emit all linkage names, or just abstract subprograms. - bool UseAllLinkageNames = true; - - SSAValueNameMap ValueNameMap; - DenseMap InstrLineAddrMap; - std::unique_ptr DbgValueRanges; - - // Record the last assigned file index for each compile unit. - // This data structure is to aid mapping DIFiles onto a DWARF-like file table. - using LVIndexFiles = std::unordered_map; - LVIndexFiles IndexFiles; - - // Store a FileID number for each DIFile seen. - using LVCompileUnitFiles = std::unordered_map; - LVCompileUnitFiles CompileUnitFiles; - - // Associate the metadata objects to logical elements. - using LVMDObjects = std::unordered_map; - LVMDObjects MDObjects; - - // An anonymous type for index type. - LVType *NodeIndexType = nullptr; - - // Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only - // difference is setting the 'DICompileUnit::splitDebugFilename' to the - // name of the split filename: "xxx.dwo". - bool includeMinimalInlineScopes() const; - bool useAllLinkageNames() const { return UseAllLinkageNames; } - - int64_t getDefaultLowerBound() const { return DefaultLowerBound; } - void setDefaultLowerBound(LVSourceLanguage *SL); - - // We assume a constant instruction-size increase between instructions. - static constexpr unsigned OFFSET_INCREASE = 4; - void updateLineOffset() { CurrentOffset += OFFSET_INCREASE; } - - void updateFileIndex(LVScopeCompileUnit *CompileUnit, size_t FileIndex) { - auto [Iter, Inserted] = IndexFiles.try_emplace(CompileUnit, FileIndex); - if (!Inserted) - Iter->second = FileIndex; - } - - // Get the current assigned index file for the given compile unit. - size_t getFileIndex(LVScopeCompileUnit *CompileUnit) { - LVIndexFiles::iterator Iter = IndexFiles.find(CompileUnit); - return Iter != IndexFiles.end() ? Iter->second : 0; - } - - // For the given 'DIFile', generate a 1-based index to indicate the - // source file where the logical element is declared. - // The IR reader expects the indexes to be 1-based. - // Each compile unit, keeps track of the last assigned index. - size_t getOrCreateSourceID(const DIFile *File); - - void addMD(const MDNode *MD, LVElement *Element) { - MDObjects.try_emplace(MD, Element); - } - LVElement *getElementForSeenMD(const MDNode *MD) const { - LVMDObjects::const_iterator Iter = MDObjects.find(MD); - return Iter != MDObjects.end() ? Iter->second : nullptr; - } - LVScope *getScopeForSeenMD(const MDNode *MD) const { - return static_cast(getElementForSeenMD(MD)); - } - LVSymbol *getSymbolForSeenMD(const MDNode *MD) const { - return static_cast(getElementForSeenMD(MD)); - } - LVType *getTypeForSeenMD(const MDNode *MD) const { - return static_cast(getElementForSeenMD(MD)); - } - LVLine *getLineForSeenMD(const MDNode *MD) const { - return static_cast(getElementForSeenMD(MD)); - } - - const DIFile *getMDFile(const MDNode *MD) const; - StringRef getMDName(const DINode *DN) const; - const DIScope *getMDScope(const DINode *DN) const; - - LVType *getIndexType(); - - // Get current metadata DICompileUnit object. - const DICompileUnit *getCUNode() const { return CUNode; } - - // Get the parent scope for the given metadata object. - LVScope *getParentScopeImpl(const DIScope *Context); - LVScope *getParentScope(const DINode *DN); - LVScope *getParentScope(const DILocation *DL); - - // Traverse the scope hierarchy and create each node in the hierarchy. - LVScope *traverseParentScope(const DIScope *Context); - - // Create the location ranges for the given scope and in the case of - // functions, generate an entry in the public names set. - void constructRange(LVScope *Scope, LVAddress LowPC, LVAddress HighPC); - void constructRange(LVScope *Scope); - - // Generate debug logical lines for the given function. - void processBasicBlocks(Function &F); - - // Add accessibility information if available. - void addAccess(LVElement *Element, DINode::DIFlags Flags); - - // Add a constant value to a logical element. - void addConstantValue(LVElement *Element, const DIExpression *DIExpr); - void addConstantValue(LVElement *Element, const ConstantFP *CFP); - void addConstantValue(LVElement *Element, const ConstantInt *CI, - const DIType *Ty); - void addConstantValue(LVElement *Element, const APInt &Value, - const DIType *Ty); - void addConstantValue(LVElement *Element, const APInt &Value, bool Unsigned); - void addConstantValue(LVElement *Element, uint64_t Value, const DIType *Ty); - void addConstantValue(LVElement *Element, uint64_t Value, bool Unsigned); - - // Add template parameters to logical element. - void addTemplateParams(LVElement *Element, const DINodeArray TParams); - - // Add location information to specified logical element. - void addSourceLine(LVElement *Element, unsigned Line, const DIFile *File); - void addSourceLine(LVElement *Element, const DIGlobalVariable *GV); - void addSourceLine(LVElement *Element, const DIImportedEntity *IE); - void addSourceLine(LVElement *Element, const DILabel *L); - void addSourceLine(LVElement *Element, const DILocalVariable *LV); - void addSourceLine(LVElement *Element, const DILocation *DL); - void addSourceLine(LVElement *Element, const DIObjCProperty *OP); - void addSourceLine(LVElement *Element, const DISubprogram *SP); - void addSourceLine(LVElement *Element, const DIType *Ty); - - void applySubprogramAttributes(LVScope *Function, const DISubprogram *SP, - bool SkipSPAttributes = false); - bool applySubprogramDefinitionAttributes(LVScope *Function, - const DISubprogram *SP, - bool Minimal = false); - - void constructAggregate(LVScopeAggregate *Aggregate, - const DICompositeType *CTy); - void constructArray(LVScopeArray *Array, const DICompositeType *CTy); - void constructEnum(LVScopeEnumeration *Enumeration, - const DICompositeType *CTy); - void constructGenericSubrange(LVScopeArray *Array, - const DIGenericSubrange *GSR, - LVType *IndexType); - void constructImportedEntity(LVElement *Element, const DIImportedEntity *IE); - - void constructLine(LVScope *Scope, const DISubprogram *SP, Instruction &I, - bool &GenerateLineBeforePrologue); - - LVSymbol *getOrCreateMember(LVScope *Aggregate, const DIDerivedType *DT); - LVSymbol *getOrCreateStaticMember(LVScope *Aggregate, - const DIDerivedType *DT); - - LVScope *getOrCreateNamespace(const DINamespace *NS); - LVScope *getOrCreateScope(const DIScope *Context); - void constructScope(LVElement *Element, const DIScope *Context); - - LVScope *getOrCreateSubprogram(const DISubprogram *SP); - LVScope *getOrCreateSubprogram(LVScope *Function, const DISubprogram *SP, - bool Minimal = false); - void constructSubprogramArguments(LVScope *Function, const DITypeArray Args); - - LVScope *getOrCreateAbstractScope(const DILocation *DL); - LVScope *getOrCreateInlinedScope(const DILocation *DL); - - void constructSubrange(LVScopeArray *Array, const DISubrange *SR, - LVType *IndexType); - - void constructTemplateTypeParameter(LVElement *Element, - const DITemplateTypeParameter *TTP); - void constructTemplateValueParameter(LVElement *Element, - const DITemplateValueParameter *TVP); - - LVElement *getOrCreateType(const DIType *Ty) { - return getOrCreateType(/*Scope=*/nullptr, Ty); - } - LVElement *getOrCreateType(LVScope *Scope, const DIType *Ty); - void constructType(LVScope *Scope, const DICompositeType *CTy); - void constructType(LVElement *Element, const DIDerivedType *DT); - void constructType(LVScope *Function, const DISubroutineType *SPTy); - - LVSymbol *getOrCreateVariable(const DIGlobalVariableExpression *GVE); - LVSymbol *getOrCreateVariable(const DIVariable *Var, - const DILocation *DL = nullptr); - LVSymbol *getOrCreateInlinedVariable(LVSymbol *OriginSymbol, - const DILocation *DL); - - LVElement *constructElement(const DINode *DN); - - // After the scopes have been created, remove empty ones. - void removeEmptyScopes(); - - // Adjust the inlined lexical scopes to their correct scope. - void resolveInlinedLexicalScopes(); - - void processLocationGaps(); - void processScopes(); - - // Check if the scopes have been properly constructed (finalized). - void checkScopes(LVScope *Scope); - -protected: - Error createScopes() override; - void sortScopes() override; - -public: - LVIRReader() = delete; - LVIRReader(StringRef Filename, StringRef FileFormatName, - object::IRObjectFile *Obj, ScopedPrinter &W) - : LVReader(Filename, FileFormatName, W, LVBinaryType::ELF), - InputFile(Obj), DbgValueRanges(new DbgValueRangeTable()) {} - LVIRReader(StringRef Filename, StringRef FileFormatName, MemoryBufferRef *Obj, - ScopedPrinter &W) - : LVReader(Filename, FileFormatName, W, LVBinaryType::ELF), - InputFile(Obj), DbgValueRanges(new DbgValueRangeTable()) {} - LVIRReader(const LVIRReader &) = delete; - LVIRReader &operator=(const LVIRReader &) = delete; - ~LVIRReader() = default; - - const LVSymbols &GetSymbolsWithLocations() const { - return SymbolsWithLocations; - } - - std::string getRegisterName(LVSmall Opcode, - ArrayRef Operands) override; - - void print(raw_ostream &OS) const; -#ifdef LLVM_DEBUG - void printAllInstructions(BasicBlock *BB); -#else - void printAllInstructions(BasicBlock *BB) {}; -#endif - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - void dump() const { print(dbgs()); } -#endif -}; - -} // end namespace logicalview -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVIRREADER_H diff --git a/llvm/lib/DebugInfo/LogicalView/CMakeLists.txt b/llvm/lib/DebugInfo/LogicalView/CMakeLists.txt index 0ad95dc05c12e..462857ef93063 100644 --- a/llvm/lib/DebugInfo/LogicalView/CMakeLists.txt +++ b/llvm/lib/DebugInfo/LogicalView/CMakeLists.txt @@ -26,7 +26,6 @@ add_lv_impl_folder(Readers Readers/LVCodeViewReader.cpp Readers/LVCodeViewVisitor.cpp Readers/LVDWARFReader.cpp - Readers/LVIRReader.cpp ) list(APPEND LIBLV_ADDITIONAL_HEADER_DIRS @@ -42,7 +41,6 @@ add_llvm_component_library(LLVMDebugInfoLogicalView ${LIBLV_ADDITIONAL_HEADER_DIRS} LINK_COMPONENTS - AsmPrinter BinaryFormat Demangle Object diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp index c2cf6d0f3e0da..d805b44c6ca36 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp @@ -555,20 +555,11 @@ void LVElement::printLinkageName(raw_ostream &OS, bool Full, void LVElement::printLinkageName(raw_ostream &OS, bool Full, LVElement *Parent, LVScope *Scope) const { if (options().getPrintFormatting() && options().getAttributeLinkage()) { - // Include the section index only if '--attribute=offset', as the - // index can be different depending on the specific reader. - std::string Text; - if (options().getAttributeOffset()) { - LVSectionIndex SectionIndex = getReader().getSectionIndex(Scope); - Text = Twine(" 0x" + Twine::utohexstr(SectionIndex) + " ").str(); - } - Text += Twine("'" + getLinkageName() + "'").str(); + LVSectionIndex SectionIndex = getReader().getSectionIndex(Scope); + std::string Text = (Twine(" 0x") + Twine::utohexstr(SectionIndex) + + Twine(" '") + Twine(getLinkageName()) + Twine("'")) + .str(); printAttributes(OS, Full, "{Linkage} ", Parent, Text, /*UseQuotes=*/false, /*PrintRef=*/false); } } - -void LVElement::printCommon(raw_ostream &OS, bool Full) const { - LVElement::print(OS, Full); - printExtra(OS, Full); -} diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp index 5606e3b12a72c..99b571996f235 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVLocation.cpp @@ -608,11 +608,6 @@ void LVLocation::setKind() { getParentSymbol()->setFillGaps(); } -void LVLocation::printCommon(raw_ostream &OS, bool Full) const { - print(OS, Full); - printExtra(OS, Full); -} - void LVLocationSymbol::updateKind() { // Update the location type for simple ones. if (Entries && Entries->size() == 1) { diff --git a/llvm/lib/DebugInfo/LogicalView/Core/LVReader.cpp b/llvm/lib/DebugInfo/LogicalView/Core/LVReader.cpp index da0cbf2f98ca7..6c4f803d93c8b 100644 --- a/llvm/lib/DebugInfo/LogicalView/Core/LVReader.cpp +++ b/llvm/lib/DebugInfo/LogicalView/Core/LVReader.cpp @@ -22,35 +22,10 @@ using namespace llvm::logicalview; #define DEBUG_TYPE "Reader" -// Traverse all the logical elements and print their basic information. -void LVReader::printCollectedElements(LVScope *Root) { - std::function TraverseScope = [&](LVScope *Parent) { - // Print the elements. - auto Print = [&](const auto &Set) { - if (Set) - for (const auto &Entry : *Set) - Entry->printCommon(dbgs()); - }; - - for (LVElement *Element : Parent->getChildren()) - Element->print(dbgs()); - Print(Parent->getLines()); - Print(Parent->getRanges()); - if (const LVScopes *Scopes = Parent->getScopes()) - for (LVScope *Scope : *Scopes) - TraverseScope(Scope); - }; - - // Start traversing the scopes root. - dbgs() << "\n** Collected logical elements **\n"; - Root->print(dbgs()); - TraverseScope(Root); -} - // Detect elements that are inserted more than once at different scopes, // causing a crash on the reader destruction, as the element is already // deleted from other scope. Helper for CodeView reader. -bool LVReader::checkIntegrityScopesTree(LVScope *Root) { +bool checkIntegrityScopesTree(LVScope *Root) { using LVDuplicateEntry = std::tuple; using LVDuplicate = std::vector; LVDuplicate Duplicate; @@ -86,9 +61,6 @@ bool LVReader::checkIntegrityScopesTree(LVScope *Root) { Traverse(Parent->getLines()); }; - // Print collected elements. - printCollectedElements(Root); - // Start traversing the scopes root and print any duplicates. TraverseScope(Root); bool PassIntegrity = true; diff --git a/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp b/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp index f95c0920783d6..69513f2b9882c 100644 --- a/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp +++ b/llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp @@ -14,10 +14,8 @@ #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h" #include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h" #include "llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h" -#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" #include "llvm/DebugInfo/PDB/Native/NativeSession.h" #include "llvm/DebugInfo/PDB/PDB.h" -#include "llvm/IR/LLVMContext.h" #include "llvm/Object/COFF.h" using namespace llvm; @@ -27,8 +25,6 @@ using namespace llvm::logicalview; #define DEBUG_TYPE "ReaderHandler" -static constexpr StringRef IRFileFormatName = "LLVM IR"; - Error LVReaderHandler::process() { if (Error Err = createReaders()) return Err; @@ -41,8 +37,7 @@ Error LVReaderHandler::process() { } Error LVReaderHandler::createReader(StringRef Filename, LVReaders &Readers, - InputHandle &Input, - StringRef FileFormatName, + PdbOrObj &Input, StringRef FileFormatName, StringRef ExePath) { auto CreateOneReader = [&]() -> std::unique_ptr { if (isa(Input)) { @@ -61,16 +56,6 @@ Error LVReaderHandler::createReader(StringRef Filename, LVReaders &Readers, return std::make_unique(Filename, FileFormatName, Pdb, W, ExePath); } - if (IRObjectFile *Ir = dyn_cast(Input)) { - return std::make_unique(Filename, FileFormatName, Ir, W); - } - if (MemoryBufferRef *MemBuf = dyn_cast(Input)) { - // If the filename extension is '.ll' create an IR reader. - const StringRef IRFileExt = ".ll"; - if (llvm::sys::path::extension(Filename) == IRFileExt) - return std::make_unique(Filename, IRFileFormatName, MemBuf, - W); - } return nullptr; }; @@ -205,11 +190,11 @@ Error LVReaderHandler::handleBuffer(LVReaders &Readers, StringRef Filename, return handleFile(Readers, PdbPath.get(), Filename); } - LLVMContext Context; - Expected> BinOrErr = createBinary(Buffer, &Context); + Expected> BinOrErr = createBinary(Buffer); if (errorToErrorCode(BinOrErr.takeError())) { - // Assume it is LLVM IR. - return handleObject(Readers, Filename, Buffer); + return createStringError(errc::not_supported, + "Binary object format in '%s' is not supported.", + Filename.str().c_str()); } return handleObject(Readers, Filename, *BinOrErr.get()); } @@ -239,7 +224,7 @@ Error LVReaderHandler::handleMach(LVReaders &Readers, StringRef Filename, if (Expected> MachOOrErr = ObjForArch.getAsObjectFile()) { MachOObjectFile &Obj = **MachOOrErr; - InputHandle Input = &Obj; + PdbOrObj Input = &Obj; if (Error Err = createReader(Filename, Readers, Input, Obj.getFileFormatName())) return Err; @@ -259,7 +244,7 @@ Error LVReaderHandler::handleMach(LVReaders &Readers, StringRef Filename, Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename, Binary &Binary) { - if (InputHandle Input = dyn_cast(&Binary)) + if (PdbOrObj Input = dyn_cast(&Binary)) return createReader(Filename, Readers, Input, cast(Input)->getFileFormatName()); @@ -269,9 +254,6 @@ Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename, if (Archive *Arch = dyn_cast(&Binary)) return handleArchive(Readers, Filename, *Arch); - if (InputHandle Input = dyn_cast(&Binary)) - return createReader(Filename, Readers, Input, "Bitcode IR"); - return createStringError(errc::not_supported, "Binary object format in '%s' is not supported.", Filename.str().c_str()); @@ -286,7 +268,7 @@ Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename, std::unique_ptr PdbSession; PdbSession.reset(static_cast(Session.release())); - InputHandle Input = &PdbSession->getPDBFile(); + PdbOrObj Input = &PdbSession->getPDBFile(); StringRef FileFormatName; size_t Pos = Buffer.find_first_of("\r\n"); if (Pos) @@ -294,12 +276,6 @@ Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename, return createReader(Filename, Readers, Input, FileFormatName, ExePath); } -Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename, - MemoryBufferRef Buffer) { - InputHandle Input = cast(&Buffer); - return createReader(Filename, Readers, Input, IRFileFormatName); -} - Error LVReaderHandler::createReaders() { LLVM_DEBUG(dbgs() << "createReaders\n"); for (std::string &Object : Objects) { diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp deleted file mode 100644 index bbc8dd81d9eab..0000000000000 --- a/llvm/lib/DebugInfo/LogicalView/Readers/LVIRReader.cpp +++ /dev/null @@ -1,2630 +0,0 @@ -//===-- LVIRReader.cpp ----------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This implements the LVIRReader class. -// It supports LLVM textual and bitcode IR format. -// -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/LogicalView/Readers/LVIRReader.h" -#include "llvm/ADT/ScopeExit.h" -#include "llvm/CodeGen/DebugHandlerBase.h" -#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" -#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" -#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" -#include "llvm/DebugInfo/LogicalView/Core/LVType.h" -#include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/Module.h" -#include "llvm/IRReader/IRReader.h" -#include "llvm/Object/Error.h" -#include "llvm/Object/IRObjectFile.h" -#include "llvm/Support/FormatAdapters.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/SourceMgr.h" - -using namespace llvm; -using namespace llvm::object; -using namespace llvm::logicalview; - -#define DEBUG_TYPE "IRReader" - -namespace { - -// Abstract scopes mapped to the associated inlined scopes. -// When creating inlined scopes, there is no direct information to find -// the correct lexical scope. -using LVScopeEntry = std::pair; -using LVInlinedScopes = - std::unordered_map>; -LVInlinedScopes InlinedScopes; - -void addInlinedScope(const DILocalScope *OriginContext, - const DILocation *InlinedAt, LVScope *InlinedScope) { - auto Entry = LVScopeEntry(OriginContext, InlinedAt); - InlinedScopes.try_emplace(Entry, InlinedScope); -} -LVScope *getInlinedScope(const DILocalScope *OriginContext, - const DILocation *InlinedAt) { - auto Entry = LVScopeEntry(OriginContext, InlinedAt); - LVInlinedScopes::const_iterator Iter = InlinedScopes.find(Entry); - return Iter != InlinedScopes.end() ? Iter->second : nullptr; -} - -// Used to find the correct location for the inlined lexical blocks that -// are allocated at their enclosing function level. -// Keep a link between the inlined scope and its associated origin scope. -using LVInlinedToOrigin = std::unordered_map; -LVInlinedToOrigin InlinedToOrigin; - -// Keep a list of inlined scopes created from the same origin scope. -// The original scope can be inlined multiple times. -using LVList = llvm::SmallVector; -using LVInlinedList = std::unordered_map; -LVInlinedList InlinedList; - -void addInlinedInfo(LVScope *Origin, LVScope *Inlined) { - // Add the link between the inlined and the origin scopes. - InlinedToOrigin.try_emplace(Inlined, Origin); - - // For the given origin scope, add the inlined scope to its inlined list. - auto [It, _] = InlinedList.try_emplace(Origin, LVList{}); - LVList &List = It->second; - List.push_back(Inlined); -} - -LVList &getInlinedList(LVScope *Origin) { - static LVList EmptyList; - auto It = InlinedList.find(Origin); - return (It == InlinedList.end()) ? EmptyList : It->second; -} - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -void dumpInlinedInfo(const char *Text, bool Full = false) { - // Use 17 as the field length; it corresponds to '{InlinedFunction}' - constexpr unsigned LEN = 17; - - auto PrintEntry = [&](auto Text, LVScope *Scope) { - std::stringstream SS; - SS << Text << hexSquareString(Scope->getID()) - << hexSquareString(Scope->getParentScope()->getID()) << " " - << std::setw(LEN) << std::left << formattedKind(Scope->kind()); - dbgs() << SS.str(); - }; - auto PrintExtra = [&](auto Text, LVScope *Scope) { - dbgs() << Text; - Scope->dumpCommon(); - }; - - // For each origin scope prints its associated inlined scopes. - dbgs() << "\nOrigin -> Inlined list: " << Text << "\n\n"; - for (auto &Entry : InlinedList) { - LVScope *OriginScope = Entry.first; - LVList &List = Entry.second; - PrintEntry("", OriginScope); - dbgs() << "\n"; - unsigned Count = 0; - for (auto &Scope : List) { - dbgs() << decString(++Count, /*Width=*/2); - PrintEntry(" ", Scope); - dbgs() << "\n"; - } - } - - dbgs() << "\nOrigin -> Inlined: " << Text << "\n\n"; - for (auto &Entry : InlinedToOrigin) { - LVScope *InlinedScope = Entry.first; - LVScope *OriginScope = Entry.second; - PrintEntry("", InlinedScope); - dbgs() << " -> "; - PrintEntry("", OriginScope); - dbgs() << "\n"; - } - - if (Full) { - dbgs() << "\n"; - for (auto &Entry : InlinedToOrigin) { - LVScope *InlinedScope = Entry.first; - LVScope *OriginScope = Entry.second; - PrintExtra("OriginParent: ", OriginScope->getParentScope()); - PrintExtra("Origin: ", OriginScope); - PrintExtra("InlinedParent: ", InlinedScope->getParentScope()); - PrintExtra("Inlined: ", InlinedScope); - dbgs() << "\n"; - } - } -} -#endif - -} // namespace - -// These flavours of 'DINode's are not implemented but technically possible: -// DW_TAG_APPLE_property = 0x4200 -// DW_TAG_atomic_type = 0x0047 -// DW_TAG_common_block = 0x001a -// DW_TAG_file_type = 0x0029 -// DW_TAG_friend = 0x002a -// DW_TAG_generic_subrange = 0x0045 -// DW_TAG_immutable_type = 0x004b -// DW_TAG_module = 0x001e -// DW_TAG_variant_part = 0x0033 - -// Create a logical element and setup the following information: -// - Name, DWARF tag, line -// - Collect any file information -LVElement *LVIRReader::constructElement(const DINode *DN) { - dwarf::Tag Tag = DN->getTag(); - LVElement *Element = createElement(Tag); - if (Element) { - Element->setTag(Tag); - addMD(DN, Element); - - if (StringRef Name = getMDName(DN); !Name.empty()) - Element->setName(Name); - - // Record any file information. - if (const DIFile *File = getMDFile(DN)) - getOrCreateSourceID(File); - } - return Element; -} - -void LVIRReader::setDefaultLowerBound(LVSourceLanguage *SL) { - assert(SL && "Invalid language ID."); - StringRef LanguageName = SL->getName(); - - // Fortran uses 1 as the default lowerbound; other languages use 0. - DefaultLowerBound = LanguageName.contains("fortran") ? 1 : 0; - - LLVM_DEBUG({ dbgs() << "Language Name: " << LanguageName << "\n"; }); -} - -bool LVIRReader::includeMinimalInlineScopes() const { - return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly; -} - -size_t LVIRReader::getOrCreateSourceID(const DIFile *File) { - if (!File) - return 0; - - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateSourceID]\n"; - dbgs() << "File: "; - File->dump(TheModule); - }); - addMD(File, CompileUnit); - - LLVM_DEBUG({ - dbgs() << "Directory: '" << File->getDirectory() << "'\n"; - dbgs() << "Filename: '" << File->getFilename() << "'\n"; - }); - - size_t FileIndex = getFileIndex(CompileUnit); - auto [Iter, Inserted] = CompileUnitFiles.try_emplace(File, ++FileIndex); - if (Inserted) { - std::string Directory(File->getDirectory()); - if (Directory.empty()) - Directory = std::string(CompileUnit->getCompilationDirectory()); - - std::string FullName; - raw_string_ostream Out(FullName); - Out << Directory << "/" << llvm::sys::path::filename(File->getFilename()); - CompileUnit->addFilename(transformPath(FullName)); - updateFileIndex(CompileUnit, FileIndex); - } else { - FileIndex = Iter->second; - } - - LLVM_DEBUG({ dbgs() << "FileIndex: " << FileIndex << "\n"; }); - return FileIndex; -} - -void LVIRReader::addSourceLine(LVElement *Element, unsigned Line, - const DIFile *File) { - if (Line == 0) - return; - - // After the scopes are created, the generic reader traverses the 'Children' - // and performs additional setting tasks (resolve types names, references, - // etc.). One of those tasks is select the correct string pool index based on - // the commmand line options: --attribute=filename or --attribute=pathname. - // As the 'Children' do not include logical lines, do that selection now, - // by calling 'setFilename' if the logical element is a line. - size_t FileID = getOrCreateSourceID(File); - if (Element->getIsLine()) - Element->setFilename(CompileUnit->getFilename(FileID)); - else - Element->setFilenameIndex(FileID); - Element->setLineNumber(Line); - - LLVM_DEBUG({ - dbgs() << "\n[addSourceLine]\n"; - File->dump(TheModule); - dbgs() << "FileIndex: " << Element->getFilenameIndex() << ", "; - dbgs() << "ID: " << Element->getID() << ", "; - dbgs() << "Kind: " << Element->kind() << ", "; - dbgs() << "Line: " << Element->getLineNumber() << ", "; - dbgs() << "Name: " << Element->getName() << "\n"; - }); -} - -void LVIRReader::addSourceLine(LVElement *Element, const DIGlobalVariable *G) { - assert(G); - addSourceLine(Element, G->getLine(), G->getFile()); -} - -void LVIRReader::addSourceLine(LVElement *Element, const DIImportedEntity *IE) { - assert(IE); - addSourceLine(Element, IE->getLine(), IE->getFile()); -} - -void LVIRReader::addSourceLine(LVElement *Element, const DILabel *L) { - assert(L); - addSourceLine(Element, L->getLine(), L->getFile()); -} - -void LVIRReader::addSourceLine(LVElement *Element, const DILocalVariable *V) { - assert(V); - addSourceLine(Element, V->getLine(), V->getFile()); -} - -void LVIRReader::addSourceLine(LVElement *Element, const DILocation *DL) { - assert(DL); - addSourceLine(Element, DL->getLine(), DL->getFile()); -} - -void LVIRReader::addSourceLine(LVElement *Element, const DIObjCProperty *OP) { - assert(OP); - addSourceLine(Element, OP->getLine(), OP->getFile()); -} - -void LVIRReader::addSourceLine(LVElement *Element, const DISubprogram *SP) { - assert(SP); - addSourceLine(Element, SP->getLine(), SP->getFile()); -} - -void LVIRReader::addSourceLine(LVElement *Element, const DIType *Ty) { - assert(Ty); - addSourceLine(Element, Ty->getLine(), Ty->getFile()); -} - -void LVIRReader::addConstantValue(LVElement *Element, - const DIExpression *DIExpr) { - std::optional Constant = - DIExpr->isConstant(); - if (Constant == std::nullopt) - return; - std::stringstream Stream; - uint64_t Value = DIExpr->getElement(1); - if (DIExpression::SignedOrUnsignedConstant::SignedConstant == Constant) { - if (int64_t SignedValue = static_cast(Value); SignedValue < 0) { - Stream << "-"; - Value = static_cast(-SignedValue); - } - } - Stream << hexString(Value, 2); - Element->setValue(Stream.str()); -} - -void LVIRReader::addConstantValue(LVElement *Element, const ConstantFP *CFP) { - addConstantValue(Element, CFP->getValueAPF().bitcastToAPInt(), true); -} - -void LVIRReader::addConstantValue(LVElement *Element, const ConstantInt *CI, - const DIType *Ty) { - addConstantValue(Element, CI->getValue(), Ty); -} - -void LVIRReader::addConstantValue(LVElement *Element, uint64_t Val, - const DIType *Ty) { - addConstantValue(Element, DebugHandlerBase::isUnsignedDIType(Ty), Val); -} - -void LVIRReader::addConstantValue(LVElement *Element, uint64_t Val, - bool Unsigned) { - addConstantValue(Element, llvm::APInt(64, Val, Unsigned), Unsigned); -} - -void LVIRReader::addConstantValue(LVElement *Element, const APInt &Val, - const DIType *Ty) { - addConstantValue(Element, Val, DebugHandlerBase::isUnsignedDIType(Ty)); -} - -void LVIRReader::addConstantValue(LVElement *Element, const APInt &Value, - bool Unsigned) { - SmallString<128> StringValue; - Value.toString(StringValue, /*Radix=*/16, /*Signed=*/!Unsigned, - /*formatAsCLiteral=*/true, /*UpperCase=*/false, - /*InsertSeparators=*/false); - Element->setValue(StringValue.str()); -} - -void LVIRReader::processLocationGaps() { - if (options().getAttributeAnyLocation()) - for (LVSymbol *Symbol : SymbolsWithLocations) - Symbol->fillLocationGaps(); -} - -void LVIRReader::processScopes() { - // - Calculate their location ranges. - // - Assign unique offset to the logical scopes, symbols and types, - // as the code the handles public names, expects them to have one. - // Use an arbitrary increment of 4. - // - Resolve any line pattern match. - // At this stage the compile unit and the root scopes they have the - // same offset, which is incorrect. Update the compile unit offset. - LVOffset Offset = OFFSET_INCREASE; - auto SetOffset = [&](LVElement *Element) { - Element->setOffset(Offset); - Offset += OFFSET_INCREASE; - }; - - std::function TraverseScope = [&](LVScope *Current) { - LVOffset Lower = Offset; - SetOffset(Current); - constructRange(Current); - - if (const LVScopes *Scopes = Current->getScopes()) - for (LVScope *Scope : *Scopes) - TraverseScope(Scope); - - // Set an arbitrary, but strictly-increasing 'Offset' for symbols and types. - if (const LVSymbols *Symbols = Current->getSymbols()) - for (LVSymbol *Symbol : *Symbols) - SetOffset(Symbol); - if (const LVTypes *Types = Current->getTypes()) - for (LVType *Type : *Types) - SetOffset(Type); - - // Resolve any given pattern. - if (const LVLines *Lines = Current->getLines()) - for (LVLine *Line : *Lines) - patterns().resolvePatternMatch(Line); - - // Calculate contributions to the debug info. - LVOffset Upper = Offset; - if (options().getPrintSizes()) - CompileUnit->addSize(Current, Lower, Upper); - }; - - TraverseScope(CompileUnit); -} - -std::string LVIRReader::getRegisterName(LVSmall Opcode, - ArrayRef Operands) { - // At this point we are operating on a logical view item, with no access - // to the underlying DWARF data used by LLVM. - // We do not support DW_OP_regval_type here. - if (Opcode == dwarf::DW_OP_regval_type) - return {}; - - if (Opcode == dwarf::DW_OP_regx || Opcode == dwarf::DW_OP_bregx) { - // If the following trace is enabled, its output will be intermixed - // with the logical view output, causing some confusion. - // Leaving it here, just for any specific needs. - // LLVM_DEBUG({ - // dbgs() << "Printing Value: " << Operands[0] << " - " - // << ValueNameMap.getName(Operands[0]) << "\n"; - // }); - // Add an extra space for a better layout when printing locations. - return " " + ValueNameMap.getName(Operands[0]); - } - - llvm_unreachable("We shouldn't actually have any other reg types here!"); -} - -LVScope *LVIRReader::getParentScopeImpl(const DIScope *Context) { - if (!Context) - return CompileUnit; - - LLVM_DEBUG({ - dbgs() << "\n[getParentScopeImpl]\n"; - dbgs() << "Context: "; - Context->dump(TheModule); - }); - - // Check for an already seen scope parent. - if (LVScope *Parent = getScopeForSeenMD(Context)) - return Parent; - - // Traverse the scope hierarchy and construct the required scopes. - return traverseParentScope(Context); -} - -// Get the logical parent for the given metadata node. -LVScope *LVIRReader::getParentScope(const DILocation *DL) { - assert(DL && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getParentScope]\n"; - dbgs() << "DL: "; - DL->dump(TheModule); - }); - - return getParentScopeImpl(cast(DL->getScope())); -} - -// Get the logical parent for the given metadata node. -LVScope *LVIRReader::getParentScope(const DINode *DN) { - assert(DN && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getParentScope]\n"; - dbgs() << "DN: "; - DN->dump(TheModule); - }); - - return getParentScopeImpl(getMDScope(DN)); -} - -LVScope *LVIRReader::traverseParentScope(const DIScope *Context) { - if (!Context) - return CompileUnit; - - LLVM_DEBUG({ - dbgs() << "\n[traverseParentScope]\n"; - dbgs() << "Context: \n"; - Context->dump(TheModule); - }); - - // Check if the metadata is already seen. - if (LVScope *Parent = getScopeForSeenMD(Context)) - return Parent; - - // Create the scope parent. - LVElement *Element = constructElement(Context); - if (Element) { - const DIScope *ParentContext = nullptr; - if (const auto *SP = dyn_cast(Context)) { - // Check for a specific 'Unit'. - if (DICompileUnit *CU = SP->getUnit()) - ParentContext = getMDScope(SP->getDeclaration() ? CU : Context); - } else { - ParentContext = getMDScope(Context); - } - LVScope *Parent = traverseParentScope(ParentContext); - if (Parent) { - Parent->addElement(Element); - constructScope(Element, Context); - } - } - - return static_cast(Element); -} - -// DW_TAG_base_type -// DW_AT_name ("__ARRAY_SIZE_TYPE__") -// DW_AT_byte_size (0x08) -// DW_AT_encoding (DW_ATE_unsigned) -LVType *LVIRReader::getIndexType() { - // This function is not meant to be called from multiple threads. - if (NodeIndexType) - return NodeIndexType; - - // Construct an integer type to use for indexes. - NodeIndexType = static_cast(createElement(dwarf::DW_TAG_base_type)); - if (NodeIndexType) { - NodeIndexType->setIsFinalized(); - NodeIndexType->setName("__ARRAY_SIZE_TYPE__"); - CompileUnit->addElement(NodeIndexType); - } - - return NodeIndexType; -} - -void LVIRReader::addAccess(LVElement *Element, DINode::DIFlags Flags) { - assert(Element && "Invalid logical element."); - LLVM_DEBUG({ - dbgs() << "\n[addAccess]\n"; - dbgs() << "Flags: " << Flags << "\n"; - }); - - const unsigned Accessibility = (Flags & DINode::FlagAccessibility); - switch (Accessibility) { - case DINode::FlagProtected: - Element->setAccessibilityCode(dwarf::DW_ACCESS_protected); - return; - case DINode::FlagPrivate: - Element->setAccessibilityCode(dwarf::DW_ACCESS_private); - return; - case DINode::FlagPublic: - Element->setAccessibilityCode(dwarf::DW_ACCESS_public); - return; - case DINode::FlagZero: - // If no explicit access control, provide the default for the parent. - LVScope *Parent = Element->getParentScope(); - if (Parent->getIsClass()) { - Element->setAccessibilityCode(dwarf::DW_ACCESS_private); - return; - } - if (Parent->getIsStructure() || Parent->getIsUnion()) { - Element->setAccessibilityCode(dwarf::DW_ACCESS_public); - return; - } - } -} - -// getFile() -// DIScope -// DILocation -// DIVariable -// DICommonBlock -// DILabel -// DIObjCProperty -// DIImportedEntity -// DIMacroFile -const DIFile *LVIRReader::getMDFile(const MDNode *MD) const { - assert(MD && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getMDFile]\n"; - dbgs() << "MD: "; - MD->dump(TheModule); - }); - - if (auto *T = dyn_cast(MD)) - return T->getFile(); - - if (auto *T = dyn_cast(MD)) - return T->getFile(); - - if (auto *T = dyn_cast(MD)) - return T->getFile(); - - if (auto *T = dyn_cast(MD)) - return T->getFile(); - - if (auto *T = dyn_cast(MD)) - return T->getFile(); - - if (auto *T = dyn_cast(MD)) - return T->getFile(); - - if (auto *T = dyn_cast(MD)) - return T->getFile(); - - if (auto *T = dyn_cast(MD)) - return T->getFile(); - - return nullptr; -} - -// getMDName() -// DIScope -// DIType -// DISubprogram -// DINamespace -// DIModule -// DITemplateParameter -// DIVariable -// DICommonBlock -// DILabel -// DIObjCProperty -// DIImportedEntity -// DIMacro -// DIEnumerator -StringRef LVIRReader::getMDName(const DINode *DN) const { - assert(DN && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getMDName]\n"; - dbgs() << "DN: "; - DN->dump(TheModule); - }); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - if (auto *T = dyn_cast(DN)) - return T->getName(); - - assert((isa(DN) || isa(DN) || isa(DN)) && - "Unhandled DINode."); - return StringRef(); -} - -const DIScope *LVIRReader::getMDScope(const DINode *DN) const { - assert(DN && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getMDScope]\n"; - dbgs() << "DN: "; - DN->dump(TheModule); - }); - - if (dyn_cast(DN)) - return getCUNode(); - - if (auto *T = dyn_cast(DN)) { - // The scope for global namespaces is nullptr. - const DIScope *Context = T->getScope(); - if (!Context) - Context = getCUNode(); - return Context; - } - - if (auto *T = dyn_cast(DN)) - return T->getScope(); - - if (auto *T = dyn_cast(DN)) - return T->getScope(); - - if (auto *T = dyn_cast(DN)) - return T->getScope(); - - assert((isa(DN) || isa(DN)) && "Unhandled DINode."); - - // Assume the scope to be the compile unit. - return getCUNode(); -} - -//===----------------------------------------------------------------------===// -// Logical elements construction using IR metadata. -//===----------------------------------------------------------------------===// -void LVIRReader::addTemplateParams(LVElement *Element, - const DINodeArray TParams) { - assert(Element && "Invalid logical element"); - // assert(TParams && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[addTemplateParams]\n"; - for (const auto *Entry : TParams) { - dbgs() << "Entry: "; - Entry->dump(TheModule); - } - }); - - // Add template parameters. - for (const auto *Entry : TParams) { - if (const auto *TTP = dyn_cast(Entry)) - constructTemplateTypeParameter(Element, TTP); - else if (const auto *TVP = dyn_cast(Entry)) - constructTemplateValueParameter(Element, TVP); - } -} - -// DISubprogram -void LVIRReader::applySubprogramAttributes(LVScope *Function, - const DISubprogram *SP, - bool SkipSPAttributes) { - assert(Function && "Invalid logical element"); - assert(SP && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[applySubprogramAttributes]\n"; - dbgs() << "SP: "; - SP->dump(TheModule); - }); - - // If -fdebug-info-for-profiling is enabled, need to emit the subprogram - // and its source location. - bool SkipSPSourceLocation = - SkipSPAttributes && !getCUNode()->getDebugInfoForProfiling(); - if (!SkipSPSourceLocation) - if (applySubprogramDefinitionAttributes(Function, SP, SkipSPAttributes)) - return; - - if (!SkipSPSourceLocation) - addSourceLine(Function, SP); - - // Skip the rest of the attributes under -gmlt to save space. - if (SkipSPAttributes) - return; - - DITypeArray Args; - if (const DISubroutineType *SPTy = SP->getType()) - Args = SPTy->getTypeArray(); - - // Construct subprogram return type. - if (Args.size()) { - LVElement *ElementType = getOrCreateType(Args[0]); - Function->setType(ElementType); - } - - // Add virtuality info if available. - Function->setVirtualityCode(SP->getVirtuality()); - - if (!SP->isDefinition()) { - // Add arguments. Do not add arguments for subprogram definition. They will - // be handled while processing variables. - constructSubprogramArguments(Function, Args); - } - - if (SP->isArtificial()) - Function->setIsArtificial(); - - if (!SP->isLocalToUnit()) - Function->setIsExternal(); - - // Add accessibility info if available. - addAccess(Function, SP->getFlags()); -} - -// DISubprogram -bool LVIRReader::applySubprogramDefinitionAttributes(LVScope *Function, - const DISubprogram *SP, - bool Minimal) { - assert(Function && "Invalid logical element"); - assert(SP && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[applySubprogramDefinitionAttributes]\n"; - dbgs() << "SP: "; - SP->dump(TheModule); - }); - - LVScope *Reference = nullptr; - StringRef DeclLinkageName; - if (const DISubprogram *SPDecl = SP->getDeclaration()) { - if (!Minimal) { - DITypeArray DeclArgs, DefinitionArgs; - DeclArgs = SPDecl->getType()->getTypeArray(); - DefinitionArgs = SP->getType()->getTypeArray(); - - // The element zero in 'DefinitionArgs' and 'DeclArgs' arrays is - // the subprogram return type. A 'void' return does not have a - // type and it is represented by a 'nullptr' value. - // For the given test case and its IR: - // - // 1 struct Bar { - // 2 bool foo(int a); - // 3 }; - // 4 - // 5 bool Bar::foo(int a) { - // 6 return false; - // 7 } - // - // !10 = !DISubprogram(name: "foo", line: 5, type: !14, - // spFlags: DISPFlagDefinition) - // !13 = !DISubprogram(name: "foo", line: 2, type: !14, spFlags: 0) - // !14 = !DISubroutineType(types: !15) - // !15 = !{!16, !17, !18} - // !16 = !DIBasicType(name: "bool", ...) - // - // '!15' represents both 'DefinitionArgs' and 'DeclArgs' arrays. - // For cases where they have a different metadata node, use the - // type from the 'DefinitionArgs' array as the correct type. - if (DeclArgs.size() && DefinitionArgs.size()) - if (DefinitionArgs[0] != nullptr && DeclArgs[0] != DefinitionArgs[0]) { - LVElement *ElementType = getOrCreateType(DefinitionArgs[0]); - Function->setType(ElementType); - } - - Reference = getScopeForSeenMD(SPDecl); - assert(Reference && "Scope should've already been constructed."); - // Look at the Decl's linkage name only if we emitted it. - if (useAllLinkageNames()) - DeclLinkageName = SPDecl->getLinkageName(); - unsigned DeclID = getOrCreateSourceID(SPDecl->getFile()); - unsigned DefID = getOrCreateSourceID(SP->getFile()); - if (DeclID != DefID) - Function->setFilenameIndex(DefID); - - if (SP->getLine() != SPDecl->getLine()) - Function->setLineNumber(SP->getLine()); - } - } - - // Add function template parameters. - addTemplateParams(Function, SP->getTemplateParams()); - - // Add the linkage name if we have one and it isn't in the Decl. - StringRef LinkageName = SP->getLinkageName(); - // Always emit it for abstract subprograms. - if (DeclLinkageName != LinkageName && (useAllLinkageNames())) - Function->setLinkageName(LinkageName); - - if (!Reference) - return false; - - // Refer to the function declaration where all the other attributes - // will be found. - Function->setReference(Reference); - Function->setHasReferenceSpecification(); - - return true; -} - -// DICompositeType -void LVIRReader::constructAggregate(LVScopeAggregate *Aggregate, - const DICompositeType *CTy) { - assert(Aggregate && "Invalid logical element"); - assert(CTy && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructAggregate]\n"; - dbgs() << "CTy: "; - CTy->dump(TheModule); - }); - - if (Aggregate->getIsFinalized()) - return; - Aggregate->setIsFinalized(); - - dwarf::Tag Tag = Aggregate->getTag(); - - // Add template parameters to a class, structure or union types. - if (Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type || - Tag == dwarf::DW_TAG_union_type) - addTemplateParams(Aggregate, CTy->getTemplateParams()); - - // Add elements to aggregate type. - for (const auto *Member : CTy->getElements()) { - if (!Member) - continue; - LLVM_DEBUG({ - dbgs() << "\nMember: "; - Member->dump(TheModule); - }); - if (const auto *SP = dyn_cast(Member)) - getOrCreateSubprogram(SP); - else if (const DIDerivedType *DT = dyn_cast(Member)) { - dwarf::Tag Tag = Member->getTag(); - if (Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_variable) { - if (DT->isStaticMember()) - getOrCreateStaticMember(Aggregate, DT); - else - getOrCreateMember(Aggregate, DT); - } else { - getOrCreateType(Aggregate, DT); - } - } - } -} - -// DICompositeType -void LVIRReader::constructArray(LVScopeArray *Array, - const DICompositeType *CTy) { - assert(Array && "Invalid logical element"); - assert(CTy && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructArray]\n"; - dbgs() << "CTy: "; - CTy->dump(TheModule); - }); - - if (Array->getIsFinalized()) - return; - Array->setIsFinalized(); - - if (LVElement *BaseType = getOrCreateType(CTy->getBaseType())) - Array->setType(BaseType); - - // Get an anonymous type for index type. - LVType *IndexType = getIndexType(); - - // Add subranges to array type. - DINodeArray Entries = CTy->getElements(); - for (DINode *DN : Entries) { - if (auto *SR = dyn_cast_or_null(DN)) { - if (SR->getTag() == dwarf::DW_TAG_subrange_type) - constructSubrange(Array, cast(SR), IndexType); - else if (SR->getTag() == dwarf::DW_TAG_generic_subrange) - constructGenericSubrange(Array, cast(SR), IndexType); - } - } -} - -// DICompositeType -void LVIRReader::constructEnum(LVScopeEnumeration *Enumeration, - const DICompositeType *CTy) { - assert(Enumeration && "Invalid logical element"); - assert(CTy && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructEnum]\n"; - dbgs() << "CTy: "; - CTy->dump(TheModule); - }); - - if (Enumeration->getIsFinalized()) - return; - Enumeration->setIsFinalized(); - - const DIType *Ty = CTy->getBaseType(); - bool IsUnsigned = Ty && DebugHandlerBase::isUnsignedDIType(Ty); - - if (LVElement *BaseType = getOrCreateType(Ty)) - Enumeration->setType(BaseType); - - if (CTy->getFlags() & DINode::FlagEnumClass) - Enumeration->setIsEnumClass(); - - // Add enumerators to enumeration type. - DINodeArray Entries = CTy->getElements(); - for (const DINode *DN : Entries) { - if (auto *Enum = dyn_cast_or_null(DN)) { - if (LVElement *Enumerator = constructElement(Enum)) { - Enumerator->setIsFinalized(); - Enumeration->addElement(Enumerator); - addConstantValue(Enumerator, Enum->getValue(), IsUnsigned); - } - } - } -} - -void LVIRReader::constructGenericSubrange(LVScopeArray *Array, - const DIGenericSubrange *GSR, - LVType *IndexType) { - assert(Array && "Invalid logical element"); - assert(GSR && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructGenericSubrange]\n"; - dbgs() << "GSR: "; - GSR->dump(TheModule); - }); - - LLVM_DEBUG({ dbgs() << "\nNot implemented\n"; }); -} - -// DIImportedEntity -void LVIRReader::constructImportedEntity(LVElement *Element, - const DIImportedEntity *IE) { - assert(Element && "Invalid logical element"); - assert(IE && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructImportedEntity]\n"; - dbgs() << "IE: "; - IE->dump(TheModule); - }); - - if (LVElement *Import = constructElement(IE)) { - Import->setIsFinalized(); - addSourceLine(Import, IE); - LVScope *Parent = getParentScope(IE); - Parent->addElement(Import); - - const DINode *Entity = IE->getEntity(); - LVElement *Target = getElementForSeenMD(Entity); - if (!Target) { - if (const auto *Ty = dyn_cast(Entity)) - Target = getOrCreateType(Ty); - else if (const auto *SP = dyn_cast(Entity)) - Target = getOrCreateSubprogram(SP); - else if (const auto *NS = dyn_cast(Entity)) - Target = getOrCreateNamespace(NS); - else if (const auto *M = dyn_cast(Entity)) - Target = getOrCreateScope(M); - } - Import->setType(Target); - } -} - -// Traverse the 'inlinedAt' chain and create their associated inlined scopes. -LVScope *LVIRReader::getOrCreateInlinedScope(const DILocation *DL) { - assert(DL && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateInlinedScope]\n"; - dbgs() << "DL: "; - DL->dump(TheModule); - }); - - const DILocalScope *OriginContext = DL->getScope(); - LLVM_DEBUG({ - dbgs() << "OriginContext: "; - OriginContext->dump(TheModule); - }); - - auto CreateScope = [&](const DILocalScope *Context) -> LVScope * { - LVScope *Scope = nullptr; - if (const auto *SP = dyn_cast(Context)) - Scope = getOrCreateSubprogram(SP); - else - Scope = getOrCreateScope(Context); - LLVM_DEBUG({ - dbgs() << "Scope: "; - Scope->dumpCommon(); - }); - - return Scope; - }; - - const DILocation *InlinedAt = DL->getInlinedAt(); - if (!InlinedAt) - return CreateScope(OriginContext); - - LLVM_DEBUG({ - dbgs() << "InlinedAt: "; - InlinedAt->dump(TheModule); - }); - - // Check if the inlined scope is already created. - if (LVScope *InlinedScope = getInlinedScope(OriginContext, InlinedAt)) - return InlinedScope; - - // Get or create the original context, which will be the seed for the - // inlined scope that we intend to create. - LVScope *OriginScope = CreateScope(OriginContext); - - dwarf::Tag Tag = OriginScope->getTag(); - if (OriginScope->getIsFunction() || OriginScope->getIsInlinedFunction()) { - Tag = dwarf::DW_TAG_inlined_subroutine; - OriginScope->setInlineCode(dwarf::DW_INL_inlined); - } - LVScope *InlinedScope = static_cast(createElement(Tag)); - if (InlinedScope) { - addInlinedScope(OriginContext, InlinedAt, InlinedScope); - InlinedScope->setTag(Tag); - InlinedScope->setIsFinalized(); - InlinedScope->setName(OriginScope->getName()); - InlinedScope->setType(OriginScope->getType()); - - InlinedScope->setCallLineNumber(InlinedAt->getLine()); - InlinedScope->setCallFilenameIndex( - getOrCreateSourceID(InlinedAt->getFile())); - - InlinedScope->setReference(OriginScope); - InlinedScope->setHasReferenceAbstract(); - - // Record the link between the origin and the inlined scope, to be - // used to get the correct parent scope for logical lexical scopes. - LLVM_DEBUG({ - dbgs() << "Linking\n"; - OriginScope->dumpCommon(); - InlinedScope->dumpCommon(); - }); - addInlinedInfo(OriginScope, InlinedScope); - - DILocalScope *AbstractContext = InlinedAt->getScope(); - LLVM_DEBUG({ - dbgs() << "AbstractContext: "; - AbstractContext->dump(TheModule); - }); - - LVScope *AbstractScope = getOrCreateInlinedScope(InlinedAt); - assert(AbstractScope && "Logical scope is NULL."); - LLVM_DEBUG({ - dbgs() << "AbstractScope: "; - AbstractScope->dumpCommon(); - }); - - // Add the created inlined scope. - AbstractScope->addElement(InlinedScope); - - LLVM_DEBUG({ - dbgs() << "InlinedScope: "; - InlinedScope->dumpCommon(); - }); - } - - return InlinedScope; -} - -LVScope *LVIRReader::getOrCreateAbstractScope(const DILocation *DL) { - assert(DL && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateAbstractScope]\n"; - dbgs() << "DL: "; - DL->dump(TheModule); - }); - - // Create the 'inlined' scope. - LVScope *InlinedScope = getOrCreateInlinedScope(DL); - assert(InlinedScope && "InlinedScope is null."); - return InlinedScope; -} - -void LVIRReader::constructLine(LVScope *Scope, const DISubprogram *SP, - Instruction &I, - bool &GenerateLineBeforePrologue) { - assert(Scope && "Invalid logical element"); - assert(SP && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructLine]\n"; - dbgs() << "Instruction: "; - I.dump(); - dbgs() << "Logical Scope: "; - Scope->dumpCommon(); - }); - - auto AddDebugLine = [&](LVScope *Parent, unsigned ID) -> LVLine * { - assert(Parent && "Invalid logical element"); - assert(ID == Metadata::DILocationKind && "Invalid Metadata Object"); - LLVM_DEBUG({ - dbgs() << "\n[AddDebugLine]\n"; - dbgs() << "Parent: "; - Parent->dumpCommon(); - }); - - LVLine *Line = createLineDebug(); - if (Line) { - Parent->addElement(Line); - - Line->setIsFinalized(); - Line->setAddress(CurrentOffset); - - // FIXME: How to get discrimination flags: - // IsStmt, BasicBlock, EndSequence, EpilogueBegin, PrologueEnd. - // - // Explore the 'Key Instructions' information added to the metadata: - // !DILocation(line: ..., scope: ..., atomGroup: ..., atomRank: ...) - - // Add mapping for this debug line. - CompileUnit->addMapping(Line, /*SectionIndex=*/0); - - // Replicate the DWARF reader functionality of adding a linkage - // name to a function with ranges (logical lines), regardless if - // the declaration has already one. - if (!Parent->getLinkageNameIndex() && - Parent->getHasReferenceSpecification()) { - Parent->setLinkageName(Parent->getReference()->getLinkageName()); - } - GenerateLineBeforePrologue = false; - } - - return Line; - }; - - auto AddAssemblerLine = [&](LVScope *Parent) { - assert(Parent && "Invalid logical element"); - - static const char *WhiteSpace = " \t\n\r\f\v"; - static std::string Metadata("metadata "); - - auto RemoveAll = [](std::string &Input, std::string &Pattern) { - std::string::size_type Len = Pattern.length(); - for (std::string::size_type Index = Input.find(Pattern); - Index != std::string::npos; Index = Input.find(Pattern)) - Input.erase(Index, Len); - }; - - std::string InstructionText; - raw_string_ostream Stream(InstructionText); - Stream << I; - // Remove the 'metadata ' pattern from the instruction text. - RemoveAll(InstructionText, Metadata); - std::string_view Text(InstructionText); - const auto pos(Text.find_first_not_of(WhiteSpace)); - Text.remove_prefix(std::min(pos, Text.length())); - - // Create an instruction line at the given scope. - if (LVLineAssembler *Line = createLineAssembler()) { - Line->setIsFinalized(); - Line->setAddress(CurrentOffset); - Line->setName(Text); - Parent->addElement(Line); - } - }; - - LVScope *Parent = Scope; - if (const DebugLoc DbgLoc = I.getDebugLoc()) { - const DILocation *DL = DbgLoc.get(); - LLVM_DEBUG({ - dbgs() << "DL: "; - DL->dump(TheModule); - }); - - Parent = getOrCreateAbstractScope(DL); - assert(Parent && "Invalid logical element"); - LLVM_DEBUG({ - dbgs() << "Parent: "; - Parent->dumpCommon(); - }); - - if (options().getPrintLines() && DL->getLine()) { - if (LVLine *Line = AddDebugLine(Parent, DL->getMetadataID())) { - addMD(DL, Line); - addSourceLine(Line, DL); - GenerateLineBeforePrologue = false; - } - } - } - - // Generate a logical line before the function prologue. - if (options().getPrintLines() && GenerateLineBeforePrologue) { - if (LVLine *Line = AddDebugLine(Parent, Metadata::DILocationKind)) { - addSourceLine(Line, SP); - GenerateLineBeforePrologue = false; - } - } - - // Create assembler line. - if (options().getPrintInstructions()) - AddAssemblerLine(Parent); -} - -LVSymbol *LVIRReader::getOrCreateMember(LVScope *Aggregate, - const DIDerivedType *DT) { - assert(Aggregate && "Invalid logical element"); - assert(DT && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateMember]\n"; - dbgs() << "DT: "; - DT->dump(TheModule); - }); - - LVSymbol *Member = getSymbolForSeenMD(DT); - if (Member && Member->getIsFinalized()) - return Member; - - if (!options().getPrintSymbols()) { - // Just create the symbol type. - getOrCreateType(DT->getBaseType()); - return nullptr; - } - - if (!Member) - Member = static_cast(getOrCreateType(Aggregate, DT)); - if (Member) { - Member->setIsFinalized(); - addSourceLine(Member, DT); - if (DT->getTag() == dwarf::DW_TAG_inheritance && DT->isVirtual()) { - Member->addLocation(dwarf::DW_AT_data_member_location, /*LowPC=*/0, - /*HighPC=*/-1, /*SectionOffset=*/0, - /*OffsetOnEntry=*/0); - } else { - uint64_t OffsetInBytes = 0; - - bool IsBitfield = DT->isBitField(); - if (IsBitfield) { - Member->setBitSize(DT->getSizeInBits()); - } else { - // This is not a bitfield. - OffsetInBytes = DT->getOffsetInBits() / 8; - } - - if (DwarfVersion <= 2) { - // DW_AT_data_member_location: - // DW_FORM_data1, DW_OP_plus_uconst, DW_FORM_udata, OffsetInBytes - Member->addLocation(dwarf::DW_AT_data_member_location, /*LowPC=*/0, - /*HighPC=*/-1, /*SectionOffset=*/0, - /*OffsetOnEntry=*/0); - Member->addLocationOperands(dwarf::DW_OP_plus_uconst, {OffsetInBytes}); - } else if (!IsBitfield || DwarfVersion < 4) { - // DW_AT_data_member_location: - // DW_FORM_udata, OffsetInBytes - Member->addLocationConstant(dwarf::DW_AT_data_member_location, - OffsetInBytes, - /*OffsetOnEntry=*/0); - } - } - } - - // Add accessibility info if available. - if (!DT->isStaticMember()) - addAccess(Member, DT->getFlags()); - - if (DT->isVirtual()) - Member->setVirtualityCode(dwarf::DW_VIRTUALITY_virtual); - - if (DT->isArtificial()) - Member->setIsArtificial(); - - return Member; -} - -// DIBasicType -// DICommonBlock -// DICompileUnit -// DICompositeType -// DIDerivedType -// DIFile -// DILexicalBlock -// DILexicalBlockFile -// DIModule -// DINamespace -// DISubprogram -// DISubroutineType -// DIStringType -void LVIRReader::constructScope(LVElement *Element, const DIScope *Context) { - assert(Element && "Invalid logical element"); - assert(Context && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructScope]\n"; - dbgs() << "Context: "; - Context->dump(TheModule); - }); - - if (const DICompositeType *CTy = - dyn_cast_if_present(Context)) { - constructType(static_cast(Element), CTy); - } else if (const DIDerivedType *DT = - dyn_cast_if_present(Context)) { - constructType(Element, DT); - } else if (const DISubprogram *SP = - dyn_cast_if_present(Context)) { - getOrCreateSubprogram(static_cast(Element), SP); - } else if (dyn_cast_if_present(Context)) { - Element->setIsFinalized(); - } else if (dyn_cast_if_present(Context)) { - Element->setIsFinalized(); - } -} - -LVSymbol *LVIRReader::getOrCreateStaticMember(LVScope *Aggregate, - const DIDerivedType *DT) { - assert(Aggregate && "Invalid logical element"); - assert(DT && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateStaticMember]\n"; - dbgs() << "DT: "; - DT->dump(TheModule); - }); - - LVSymbol *Member = getSymbolForSeenMD(DT); - if (Member && Member->getIsFinalized()) - return Member; - - if (!options().getPrintSymbols()) { - // Just create the symbol type. - getOrCreateType(DT->getBaseType()); - return nullptr; - } - - if (!Member) - Member = static_cast(getOrCreateType(Aggregate, DT)); - if (Member) { - Member->setIsFinalized(); - addSourceLine(Member, DT); - Member->setIsExternal(); - } - - return Member; -} - -// DISubprogram -LVScope *LVIRReader::getOrCreateSubprogram(const DISubprogram *SP) { - assert(SP && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateSubprogram]\n"; - dbgs() << "SP: "; - SP->dump(TheModule); - }); - - LVScope *Function = getScopeForSeenMD(SP); - if (Function && Function->getIsFinalized()) - return Function; - - if (!Function) - Function = static_cast(constructElement(SP)); - if (Function) { - // For both member functions (declaration and definition) its parent - // is the containing class. The 'definition' points back to its - // 'declaration' via the 'getDeclaration' return value. - LVScope *Parent = SP->getDeclaration() - ? SP->isLocalToUnit() || SP->isDefinition() - ? CompileUnit - : getParentScope(SP)->getParentScope() - : getParentScope(SP); - // The 'getParentScope' traverses the scope hierarchy and it creates - // the scope chain and any associated types. - // Check that the 'Function' is not already in the parent. - if (!Function->getParent()) - Parent->addElement(Function); - - getOrCreateSubprogram(Function, SP, includeMinimalInlineScopes()); - } - - return Function; -} - -// DISubprogram -LVScope *LVIRReader::getOrCreateSubprogram(LVScope *Function, - const DISubprogram *SP, - bool Minimal) { - assert(Function && "Invalid logical element"); - assert(SP && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateSubprogram]\n"; - dbgs() << "SP: "; - SP->dump(TheModule); - }); - - if (Function->getIsFinalized()) - return Function; - Function->setIsFinalized(); - - // Get 'declaration' node in order to generate the DW_AT_specification. - if (const DISubprogram *SPDecl = SP->getDeclaration()) { - if (!Minimal) { - // Build the declaration now to ensure it precedes the definition. - getOrCreateSubprogram(SPDecl); - } - } - - // Check for additional retained nodes. - for (const DINode *DN : SP->getRetainedNodes()) { - if (const auto *IE = dyn_cast(DN)) - constructImportedEntity(Function, IE); - else if (const auto *TTP = dyn_cast(DN)) - constructTemplateTypeParameter(Function, TTP); - else if (const auto *TVP = dyn_cast(DN)) - constructTemplateValueParameter(Function, TVP); - } - - applySubprogramAttributes(Function, SP); - - // Check if we are dealing with the Global Init/Cleanup Function. - if (SP->isArtificial() && SP->isLocalToUnit() && SP->isDefinition() && - SP->getName().empty()) - Function->setName(SP->getLinkageName()); - - return Function; -} - -void LVIRReader::constructSubprogramArguments(LVScope *Function, - const DITypeArray Args) { - assert(Function && "Invalid logical element"); - LLVM_DEBUG({ - dbgs() << "\n[constructSubprogramArguments]\n"; - for (unsigned i = 1, N = Args.size(); i < N; ++i) { - if (const DIType *Ty = Args[i]) { - dbgs() << "Ty: "; - Ty->dump(TheModule); - } - } - }); - - for (unsigned I = 1, N = Args.size(); I < N; ++I) { - const DIType *Ty = Args[I]; - LVElement *Parameter = nullptr; - if (Ty) { - // Create a formal parameter. - LVElement *ParameterType = getOrCreateType(Ty); - Parameter = createElement(dwarf::DW_TAG_formal_parameter); - if (Parameter) { - Parameter->setType(ParameterType); - if (Ty->isArtificial()) - Parameter->setIsArtificial(); - } - } else { - // Add an unspecified parameter. - Parameter = createElement(dwarf::DW_TAG_unspecified_parameters); - } - if (Parameter) { - Function->addElement(Parameter); - Parameter->setIsFinalized(); - } - } -} - -// DISubrange -void LVIRReader::constructSubrange(LVScopeArray *Array, const DISubrange *SR, - LVType *IndexType) { - assert(Array && "Invalid logical element"); - assert(SR && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructSubrange]\n"; - dbgs() << "SR: "; - SR->dump(TheModule); - }); - - // The DISubrange can be shared between different arrays, when they are - // the same. We need to create independent logical elements for each one, - // as they are going to be added to different arrays. - if (LVTypeSubrange *Subrange = - static_cast(constructElement(SR))) { - Subrange->setIsFinalized(); - Array->addElement(Subrange); - Subrange->setType(IndexType); - - int64_t Count = 0; - // If Subrange has a Count field, use it. - // Otherwise, if it has an upperboud, use (upperbound - lowerbound + 1), - // where lowerbound is from the LowerBound field of the Subrange, - // or the language default lowerbound if that field is unspecified. - if (auto *CI = dyn_cast_if_present(SR->getCount())) - Count = CI->getSExtValue(); - else if (auto *UI = - dyn_cast_if_present(SR->getUpperBound())) { - // Fortran uses 1 as the default lowerbound; other languages use 0. - int64_t Lowerbound = getDefaultLowerBound(); - auto *LI = dyn_cast_if_present(SR->getLowerBound()); - Lowerbound = (LI) ? LI->getSExtValue() : Lowerbound; - Count = UI->getSExtValue() - Lowerbound + 1; - } - - Subrange->setCount(Count); - } -} - -// DITemplateTypeParameter -void LVIRReader::constructTemplateTypeParameter( - LVElement *Element, const DITemplateTypeParameter *TTP) { - assert(Element && "Invalid logical element"); - assert(TTP && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructTemplateTypeParameter]\n"; - dbgs() << "TTP: "; - TTP->dump(TheModule); - }); - - // The DITemplateTypeParameter can be shared between different subprogram - // in their DITemplateParameterArray describing the template parameters. - // We need to create independent logical elements for each one, as they are - // going to be added to different function. - if (LVElement *Parameter = constructElement(TTP)) { - Parameter->setIsFinalized(); - // Add element to parent (always the given Element). - LVScope *Parent = static_cast(Element); - Parent->addElement(Parameter); - // Mark the parent as template. - Parent->setIsTemplate(); - - // Add the type if it exists, it could be void and therefore no type. - if (const DIType *Ty = TTP->getType()) { - LVElement *Type = getElementForSeenMD(Ty); - if (!Type) - Type = getOrCreateType(Ty); - Parameter->setType(Type); - } - } -} - -// DITemplateValueParameter -void LVIRReader::constructTemplateValueParameter( - LVElement *Element, const DITemplateValueParameter *TVP) { - assert(Element && "Invalid logical element"); - assert(TVP && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructTemplateValueParameter]\n"; - dbgs() << "TVP: "; - TVP->dump(TheModule); - }); - - // The DITemplateValueParameter can be shared between different subprogram - // in their DITemplateParameterArray describing the template parameters. - // We need to create independent logical elements for each one, as they are - // going to be added to different function. - if (LVElement *Parameter = constructElement(TVP)) { - Parameter->setIsFinalized(); - // Add element to parent (always the given Element). - LVScope *Parent = static_cast(Element); - Parent->addElement(Parameter); - // Mark the parent as template. - Parent->setIsTemplate(); - - // Add the type if there is one, template template and template parameter - // packs will not have a type. - if (TVP->getTag() == dwarf::DW_TAG_template_value_parameter) { - LVElement *Type = getOrCreateType(TVP->getType()); - Parameter->setType(Type); - } - if (Metadata *Value = TVP->getValue()) { - if (ConstantInt *CI = mdconst::dyn_extract(Value)) - addConstantValue(Parameter, CI, TVP->getType()); - else if (ConstantFP *CF = mdconst::dyn_extract(Value)) - addConstantValue(Parameter, CF); - else if (mdconst::dyn_extract(Value)) { - // We cannot describe the location of dllimport'd entities: the - // computation of their address requires loads from the IAT. - Parameter->setValue("Unable to describe global value"); - } else if (TVP->getTag() == dwarf::DW_TAG_GNU_template_template_param) { - assert(isa(Value)); - // Add the value for dwarf::DW_AT_GNU_template_name. - Parameter->setValue(cast(Value)->getString()); - } else if (TVP->getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) { - addTemplateParams(Parameter, cast(Value)); - } - } - } -} - -// DICompositeType -// DW_TAG_array_type -// DW_TAG_class_type -// DW_TAG_enumeration_type -// DW_TAG_structure_type -// DW_TAG_union_type -void LVIRReader::constructType(LVScope *Scope, const DICompositeType *CTy) { - assert(Scope && "Invalid logical element"); - assert(CTy && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructType]\n"; - dbgs() << "CTy: "; - CTy->dump(TheModule); - }); - - dwarf::Tag Tag = Scope->getTag(); - switch (Tag) { - case dwarf::DW_TAG_array_type: - constructArray(static_cast(Scope), CTy); - break; - case dwarf::DW_TAG_enumeration_type: - constructEnum(static_cast(Scope), CTy); - break; - // FIXME: Not implemented. - case dwarf::DW_TAG_variant_part: - case dwarf::DW_TAG_namelist: - break; - case dwarf::DW_TAG_structure_type: - case dwarf::DW_TAG_union_type: - case dwarf::DW_TAG_class_type: { - constructAggregate(static_cast(Scope), CTy); - break; - } - default: - break; - } - - if (Tag == dwarf::DW_TAG_enumeration_type || - Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type || - Tag == dwarf::DW_TAG_union_type) { - // Add accessibility info if available. - addAccess(Scope, CTy->getFlags()); - - // Add source line info if available. - if (!CTy->isForwardDecl()) - addSourceLine(Scope, CTy); - } -} - -// DIDerivedType -// DW_TAG_atomic_type -// DW_TAG_const_type -// DW_TAG_friend -// DW_TAG_inheritance -// DW_TAG_member -// DW_TAG_immutable_type -// DW_TAG_pointer_type -// DW_TAG_ptr_to_member_type -// DW_TAG_reference_type -// DW_TAG_restrict_type -// DW_TAG_typedef -// DW_TAG_volatile_type -void LVIRReader::constructType(LVElement *Element, const DIDerivedType *DT) { - assert(Element && "Invalid logical element"); - assert(DT && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructType]\n"; - dbgs() << "DT: "; - DT->dump(TheModule); - }); - - // For DW_TAG_member, the flag is set during the construction of the - // aggregate type (DICompositeType). - if (DT->getTag() != dwarf::DW_TAG_member) - Element->setIsFinalized(); - - LVElement *BaseType = getOrCreateType(DT->getBaseType()); - Element->setType(BaseType); - - // Add accessibility info if available. - if (!DT->isStaticMember()) - addAccess(Element, DT->getFlags()); - - if (DT->isVirtual()) - Element->setVirtualityCode(dwarf::DW_VIRTUALITY_virtual); - - if (DT->isArtificial()) - Element->setIsArtificial(); - - // Add source line info if available and TyDesc is not a forward declaration. - if (!DT->isForwardDecl()) - addSourceLine(Element, DT); -} - -// DISubroutineType -void LVIRReader::constructType(LVScope *Function, - const DISubroutineType *SPTy) { - assert(Function && "Invalid logical element"); - assert(SPTy && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[constructType]\n"; - dbgs() << "SPTy: "; - SPTy->dump(TheModule); - }); - - if (Function->getIsFinalized()) - return; - Function->setIsFinalized(); - - // For DISubprogram, the DISubroutineType contains the types for: - // return type, param 1 type, ..., param n type - DITypeArray Args = SPTy->getTypeArray(); - if (Args.size()) { - LVElement *ElementType = getOrCreateType(Args[0]); - Function->setType(ElementType); - } - - constructSubprogramArguments(Function, Args); -} - -// DINamespace -LVScope *LVIRReader::getOrCreateNamespace(const DINamespace *NS) { - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateNamespace]\n"; - dbgs() << "NS: "; - NS->dump(TheModule); - }); - - LVScope *Scope = getOrCreateScope(NS); - if (Scope) { - StringRef Name = NS->getName(); - if (Name.empty()) - Scope->setName("(anonymous namespace)"); - } - - return Scope; -} - -LVScope *LVIRReader::getOrCreateScope(const DIScope *Context) { - assert(Context && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateScope]\n"; - dbgs() << "Context: "; - Context->dump(TheModule); - }); - - // Check if the scope is already created. - LVScope *Scope = getScopeForSeenMD(Context); - if (Scope) - return Scope; - - Scope = static_cast(constructElement(Context)); - if (Scope) { - // Add element to parent. - LVScope *Parent = getParentScope(Context); - Parent->addElement(Scope); - } - - return Scope; -} - -// DICompositeType -// DIDerivedType -// DISubroutineType -LVElement *LVIRReader::getOrCreateType(LVScope *Scope, const DIType *Ty) { - if (!Ty) - return nullptr; - - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateType]\n"; - dbgs() << "Ty :"; - Ty->dump(TheModule); - }); - - // Check if the element is already created. - LVElement *Element = getElementForSeenMD(Ty); - if (Element) - return Element; - - Element = constructElement(Ty); - if (Element) { - // Add element to parent. - LVScope *Parent = Scope ? Scope : getParentScope(Ty); - Parent->addElement(Element); - - if (isa(Ty)) { - Element->setIsFinalized(); - } else if (const DIDerivedType *DT = dyn_cast(Ty)) { - constructType(Element, DT); - } else if (const DICompositeType *CTy = dyn_cast(Ty)) { - constructType(static_cast(Element), CTy); - } else if (const DISubroutineType *SPTy = dyn_cast(Ty)) { - constructType(static_cast(Element), SPTy); - } - } - - return Element; -} - -// DIGlobalVariableExpression -LVSymbol * -LVIRReader::getOrCreateVariable(const DIGlobalVariableExpression *GVE) { - assert(GVE && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateVariable]\n"; - dbgs() << "GVE: "; - GVE->dump(TheModule); - }); - - const DIGlobalVariable *DIGV = GVE->getVariable(); - LVSymbol *Symbol = getSymbolForSeenMD(DIGV); - if (!Symbol) - Symbol = getOrCreateVariable(DIGV); - - if (Symbol) { - // Add location and operation entries. - Symbol->addLocation(dwarf::DW_AT_location, /*LowPC=*/0, /*HighPC=*/-1, - /*SectionOffset=*/0, /*OffsetOnEntry=*/0); - Symbol->addLocationOperands(dwarf::DW_OP_addrx, PoolAddressIndex++); - if (const DIExpression *DIExpr = GVE->getExpression()) - addConstantValue(Symbol, DIExpr); - } - return Symbol; -} - -LVSymbol *LVIRReader::getOrCreateInlinedVariable(LVSymbol *OriginSymbol, - const DILocation *DL) { - assert(OriginSymbol && "Invalid logical element"); - assert(DL && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateInlinedVariable]\n"; - dbgs() << "DL: "; - DL->dump(TheModule); - }); - - const DILocation *InlinedAt = DL->getInlinedAt(); - if (!InlinedAt) { - return nullptr; - } - - dwarf::Tag Tag = OriginSymbol->getTag(); - LVSymbol *InlinedSymbol = static_cast(createElement(Tag)); - if (InlinedSymbol) { - InlinedSymbol->setTag(Tag); - InlinedSymbol->setIsFinalized(); - InlinedSymbol->setName(OriginSymbol->getName()); - InlinedSymbol->setType(OriginSymbol->getType()); - - InlinedSymbol->setCallLineNumber(InlinedAt->getLine()); - InlinedSymbol->setCallFilenameIndex( - getOrCreateSourceID(InlinedAt->getFile())); - - OriginSymbol->setInlineCode(dwarf::DW_INL_inlined); - InlinedSymbol->setReference(OriginSymbol); - InlinedSymbol->setHasReferenceAbstract(); - - if (OriginSymbol->getIsParameter()) - InlinedSymbol->setIsParameter(); - - // Get or create the local scope associated with the location. - LVScope *InlinedScope = getOrCreateInlinedScope(DL); - assert(InlinedScope && "Invalid logical element"); - - // Add the created inlined scope. - InlinedScope->addElement(InlinedSymbol); - } - - return InlinedSymbol; -} - -// DIGlobalVariable -// DILocalVariable -LVSymbol *LVIRReader::getOrCreateVariable(const DIVariable *Var, - const DILocation *DL) { - assert(Var && "Invalid metadata node."); - LLVM_DEBUG({ - dbgs() << "\n[getOrCreateVariable]\n"; - dbgs() << "Var: "; - Var->dump(TheModule); - if (DL) { - dbgs() << "DL: "; - DL->dump(TheModule); - } - }); - - // Use the 'InlinedAt' information to identify a symbol that is being - // inlined. Its abstract representation is created just once. - const DILocation *InlinedAt = DL ? DL->getInlinedAt() : nullptr; - - LVSymbol *Symbol = getSymbolForSeenMD(Var); - if (Symbol && Symbol->getIsFinalized() && !InlinedAt) - return Symbol; - - if (!options().getPrintSymbols()) { - // Just create the symbol type. - getOrCreateType(Var->getType()); - if (const DIGlobalVariable *GV = dyn_cast(Var)) { - if (MDTuple *TP = GV->getTemplateParams()) - addTemplateParams(Symbol, DINodeArray(TP)); - } - return nullptr; - } - - if (!Symbol) - Symbol = static_cast(constructElement(Var)); - if (Symbol && !Symbol->getIsFinalized()) { - Symbol->setIsFinalized(); - LVScope *Parent = getParentScope(Var); - Parent->addElement(Symbol); - - Symbol->setName(Var->getName()); - - // Create symbol type. - if (LVElement *SymbolType = getOrCreateType(Var->getType())) - Symbol->setType(SymbolType); - - if (const DILocalVariable *LV = dyn_cast(Var)) { - // Add line number info. - addSourceLine(Symbol, LV); - if (LV->isParameter()) { - Symbol->setIsParameter(); - if (LV->isArtificial()) - Symbol->setIsArtificial(); - } - } else { - const DIGlobalVariable *GV = dyn_cast(Var); - if (useAllLinkageNames()) - Symbol->setLinkageName(GV->getLinkageName()); - - // Get 'declaration' node in order to generate the DW_AT_specification. - if (const DIDerivedType *GVDecl = GV->getStaticDataMemberDeclaration()) { - LVSymbol *Reference = static_cast(getOrCreateType(GVDecl)); - if (Reference) { - Symbol->setReference(Reference); - Symbol->setHasReferenceSpecification(); - } - } else { - if (!GV->isLocalToUnit()) - Symbol->setIsExternal(); - // Add line number info. - addSourceLine(Symbol, GV); - } - - if (MDTuple *TP = GV->getTemplateParams()) - addTemplateParams(Symbol, DINodeArray(TP)); - } - } - - // Create the 'inlined' symbol. - if (DL) - getOrCreateInlinedVariable(Symbol, DL); - - return Symbol; -} - -#ifdef LLVM_DEBUG -void LVIRReader::printAllInstructions(BasicBlock *BB) { - const Function *F = BB->getParent(); - if (!F) - return; - const DISubprogram *SP = cast(F->getSubprogram()); - LLVM_DEBUG({ - dbgs() << "\nBegin all instructions: '" << SP->getName() << "'\n"; - for (Instruction &I : *BB) { - dbgs() << "I: '" << I << "'\n"; - for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) { - dbgs() << " Var: "; - DVR.getVariable()->dump(TheModule); - } - if (const auto *DL = - cast_or_null(I.getMetadata(LLVMContext::MD_dbg))) { - dbgs() << " DL: "; - DL->dump(TheModule); - } - } - dbgs() << "End all instructions: '" << SP->getName() << "'\n\n"; - }); -} -#endif - -void LVIRReader::processBasicBlocks(Function &F) { - const DISubprogram *SP = cast_or_null(F.getSubprogram()); - if (!SP) - return; - - LLVM_DEBUG({ - dbgs() << "\n[processBasicBlocks]\n"; - dbgs() << "SP: "; - SP->dump(TheModule); - }); - - // Check if we need to add a dwarf::DW_TAG_unspecified_parameters. - bool AddUnspecifiedParameters = false; - if (const DISubroutineType *SPTy = SP->getType()) { - DITypeArray Args = SPTy->getTypeArray(); - unsigned N = Args.size(); - if (N > 1) { - const DIType *Ty = Args[N - 1]; - if (!Ty) - AddUnspecifiedParameters = true; - } - } - - LVScope *Scope = getOrCreateSubprogram(SP); - - SmallVector SeenVars; - - // Handle dbg.values and dbg.declare. - auto HandleDbgVariable = [&](auto *DbgVar) { - LLVM_DEBUG({ - dbgs() << "\n[HandleDbgVariable]\n"; - dbgs() << "DbgVar: "; - DbgVar->dump(); - }); - - DebugVariableAggregate DVA(DbgVar); - if (!DbgValueRanges->hasVariableEntry(DVA)) { - DbgValueRanges->addVariable(&F, DVA); - SeenVars.push_back(DVA); - } - - // Skip undefined values. - if (!DbgVar->isKillLocation()) - getOrCreateVariable(DbgVar->getVariable(), DbgVar->getDebugLoc().get()); - }; - - // Generate logical debug line before prologue. - bool GenerateLineBeforePrologue = true; - for (BasicBlock &BB : F) { - printAllInstructions(&BB); - - for (Instruction &I : BB) { - LLVM_DEBUG(dbgs() << "\nInstruction: '" << I << "'\n"); - - if (const auto *DL = - cast_or_null(I.getMetadata(LLVMContext::MD_dbg))) { - LLVM_DEBUG({ - dbgs() << " Location: "; - DL->dump(TheModule); - }); - getOrCreateAbstractScope(DL); - } - - for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) - HandleDbgVariable(&DVR); - - if (options().getPrintAnyLine()) - constructLine(Scope, SP, I, GenerateLineBeforePrologue); - - InstrLineAddrMap[I.getIterator().getNodePtr()] = CurrentOffset; - - // Update code offset. - updateLineOffset(); - } - InstrLineAddrMap[BB.end().getNodePtr()] = CurrentOffset; - } - GenerateLineBeforePrologue = false; - - if (AddUnspecifiedParameters) { - LVElement *Parameter = createElement(dwarf::DW_TAG_unspecified_parameters); - if (Parameter) { - Parameter->setIsFinalized(); - Scope->addElement(Parameter); - } - } - - LLVM_DEBUG({ dbgs() << "\nTraverse seen debug variables\n"; }); - for (const DebugVariableAggregate &DVA : SeenVars) { - LLVM_DEBUG({ DbgValueRanges->printValues(DVA, dbgs()); }); - DILocalVariable *LV = const_cast(DVA.getVariable()); - LVSymbol *Symbol = getSymbolForSeenMD(LV); - // Undefined only value, ignore. - if (!Symbol) - continue; - - LLVM_DEBUG({ - DIType *Ty = LV->getType(); - uint64_t Size = Ty ? Ty->getSizeInBits() / CHAR_BIT : 1; - LV->dump(TheModule); - Ty->dump(TheModule); - dbgs() << "Type size: " << Size << "\n"; - }); - - auto AddLocationOp = [&](Value *V, bool IsMem) { - uint64_t RegValue = ValueNameMap.addValue(V); - if (IsMem) - Symbol->addLocationOperands(dwarf::DW_OP_bregx, {RegValue, 0}); - else - Symbol->addLocationOperands(dwarf::DW_OP_regx, RegValue); - }; - - auto AddLocation = [&](DbgValueDef DV) { - bool IsMem = DV.IsMemory; - DIExpression *CanonicalExpr = const_cast( - DIExpression::convertToVariadicExpression(DV.Expression)); - RawLocationWrapper Locations(DV.Locations); - for (DIExpression::ExprOperand ExprOp : CanonicalExpr->expr_ops()) { - if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg) { - AddLocationOp(Locations.getVariableLocationOp(ExprOp.getArg(0)), - IsMem); - } else { - if (ExprOp.getOp() > std::numeric_limits::max()) - LLVM_DEBUG(dbgs() << "Bad DWARF op: " << ExprOp.getOp() << "\n"); - uint8_t ShortOp = (uint8_t)ExprOp.getOp(); - Symbol->addLocationOperands( - ShortOp, - ArrayRef(std::next(ExprOp.get()), ExprOp.getNumArgs())); - } - } - }; - - if (DbgValueRanges->hasSingleLocEntry(DVA)) { - DbgValueDef DV = DbgValueRanges->getSingleLoc(DVA); - Symbol->addLocation(llvm::dwarf::DW_AT_location, /*LowPC=*/0, - /*HighPC=*/-1, /*SectionOffset=*/0, - /*OffsetOnEntry=*/0); - assert(DV.IsMemory && "Single location should be memory!"); - AddLocation(DV); - } else { - for (const DbgRangeEntry &Entry : - DbgValueRanges->getVariableRanges(DVA)) { - // These line addresses should have already been inserted into the - // InstrLineAddrMap, so we assume they are present here. - LVOffset Start = InstrLineAddrMap.at(Entry.Start.getNodePtr()); - LVOffset End = InstrLineAddrMap.at(Entry.End.getNodePtr()); - Symbol->addLocation(llvm::dwarf::DW_AT_location, Start, End, - /*SectionOffset=*/0, /*OffsetOnEntry=*/0); - DbgValueDef DV = Entry.Value; - AddLocation(DV); - } - } - } -} - -//===----------------------------------------------------------------------===// -// IR Reader entry point. -//===----------------------------------------------------------------------===// -Error LVIRReader::createScopes() { - LLVM_DEBUG({ - W.startLine() << "\n"; - W.printString("File", getFilename()); - W.printString("Format", FileFormatName); - }); - - // The IR Reader supports only debug records. - // We identify the debug input format and if it is intrinsics, it is - // converted to the debug records. - if (Error Err = LVReader::createScopes()) - return Err; - - LLVMContext Context; - SMDiagnostic Err; - std::unique_ptr M = - parseIR(isa(InputFile) - ? cast(InputFile)->getMemoryBufferRef() - : *(cast(InputFile)), - Err, Context); - if (!M) { - // Print explanatory error message. - if (options().getWarningAll()) - Err.print("", outs()); - return createStringError(errc::invalid_argument, - "Could not create IR module for: %s", - getFilename().str().c_str()); - } - - TheModule = M.get(); - if (!TheModule->getNamedMetadata("llvm.dbg.cu")) { - LLVM_DEBUG(dbgs() << "Skipping module without debug info\n"); - return Error::success(); - } - - DwarfVersion = TheModule->getDwarfVersion(); - - LLVM_DEBUG({ dbgs() << "\nProcess CompileUnits\n"; }); - for (const DICompileUnit *CU : TheModule->debug_compile_units()) { - LLVM_DEBUG({ - dbgs() << "\nCU: "; - CU->dump(TheModule); - }); - - CompileUnit = static_cast(constructElement(CU)); - CUNode = const_cast(CU); - - const DIFile *File = CU->getFile(); - CompileUnit->setName(File->getFilename()); - CompileUnit->setCompilationDirectory(File->getDirectory()); - CompileUnit->setIsFinalized(); - - Root->addElement(CompileUnit); - - // As the IR format uses the DWARF symbolic constants, the setting - // of the source language must use the DWARF language definitions. - uint16_t LanguageName = CU->getSourceLanguage().getName(); - LVSourceLanguage SL = LVSourceLanguage( - static_cast(LanguageName)); - setDefaultLowerBound(&SL); - - if (options().getAttributeLanguage()) - CompileUnit->setSourceLanguage(SL); - - if (options().getAttributeProducer()) - CompileUnit->setProducer(CU->getProducer()); - - // Global Variables. - LLVM_DEBUG({ dbgs() << "\nGlobal Variables\n"; }); - for (const DIGlobalVariableExpression *GVE : CU->getGlobalVariables()) - getOrCreateVariable(GVE); - - // The enumeration types need to be created, regardless if they are - // nested to any other aggregate type, as they are not included in - // their elements. But their scope is correct (aggregate). - LLVM_DEBUG({ dbgs() << "\nEnumeration Types\n"; }); - for (auto *ET : CU->getEnumTypes()) - getOrCreateType(ET); - - // Retained types. - LLVM_DEBUG({ dbgs() << "\nRetained Types\n"; }); - for (const auto *RT : CU->getRetainedTypes()) { - if (const auto *Ty = dyn_cast(RT)) { - getOrCreateType(Ty); - } else { - getOrCreateSubprogram(cast(RT)); - } - } - - // Imported entities. - LLVM_DEBUG({ dbgs() << "\nImported Entities\n"; }); - for (const auto *IE : CU->getImportedEntities()) - constructImportedEntity(CompileUnit, IE); - } - - // Traverse Functions. - LLVM_DEBUG({ - dbgs() << "\nFunctions\n"; - for (Function &F : M->getFunctionList()) - if (const auto *SP = cast_or_null(F.getSubprogram())) - SP->dump(TheModule); - }); - - for (Function &F : M->getFunctionList()) - processBasicBlocks(F); - - // Perform extra tasks on the created scopes. - resolveInlinedLexicalScopes(); - removeEmptyScopes(); - - processLocationGaps(); - processScopes(); - - if (options().getInternalIntegrity()) - checkScopes(CompileUnit); - - TheModule = nullptr; - return Error::success(); -} - -void LVIRReader::constructRange(LVScope *Scope, LVAddress LowPC, - LVAddress HighPC) { - assert(Scope && "Invalid logical element"); - LLVM_DEBUG({ - dbgs() << "\n[constructRange]\n"; - dbgs() << "ID: " << hexString(Scope->getID()) << " "; - dbgs() << "LowPC: " << hexString(LowPC) << " "; - dbgs() << "HighPC: " << hexString(HighPC) << " "; - dbgs() << "Name: " << Scope->getName() << "\n"; - }); - - // Process ranges base on logical lines. - Scope->addObject(LowPC, HighPC); - if (!Scope->getIsCompileUnit()) { - // If the scope is a function, add it to the public names. - if ((options().getAttributePublics() || options().getPrintAnyLine()) && - Scope->getIsFunction() && !Scope->getIsInlinedFunction()) - CompileUnit->addPublicName(Scope, LowPC, HighPC); - } - addSectionRange(/*SectionIndex=*/0, Scope, LowPC, HighPC); - - // Replicate DWARF reader funtionality of processing DW_AT_ranges for - // the compilation unit. - CompileUnit->addObject(LowPC, HighPC); - addSectionRange(/*SectionIndex=*/0, CompileUnit, LowPC, HighPC); -} - -// Create the location ranges for the given scope and in the case of -// functions, generate an entry in the public names set. -void LVIRReader::constructRange(LVScope *Scope) { - LLVM_DEBUG({ - dbgs() << "\n[constructRange]\n"; - dbgs() << "ID: " << hexString(Scope->getID()) << " "; - dbgs() << "Name: " << Scope->getName() << "\n\n"; - }); - - auto NextRange = [&](LVAddress Offset) -> LVAddress { - return Offset + OFFSET_INCREASE - 1; - }; - - // Get any logical lines. - const LVLines *Lines = Scope->getLines(); - if (!Lines) - return; - - // Traverse the logical lines and build the logical ranges. - LVAddress Lower = 0; - LVAddress Upper = 0; - LVAddress Current = 0; - LVAddress Previous = 0; - for (const LVLine *Line : *Lines) { - LLVM_DEBUG({ - dbgs() << "[" << hexString(Line->getAddress()) << "] "; - dbgs() << "LineNo: " << decString(Line->getLineNumber()) << "\n"; - dbgs() << "Lower: " << hexString(Lower) << " "; - dbgs() << "Upper: " << hexString(Upper) << " "; - dbgs() << "Previous: " << hexString(Previous) << " "; - dbgs() << "Current: " << hexString(Current) << "\n"; - }); - if (!Upper) { - // First line in range. - Lower = Line->getAddress(); - Upper = NextRange(Lower); - Current = Lower; - continue; - } - Previous = Current; - Current = Line->getAddress(); - if (Current == Previous) { - // Contiguous lines at the same address (Debug and its assembler). - continue; - } - if (Current == Upper + 1) { - // There is no gap. - Upper = NextRange(Current); - } else { - // There is a gap. - constructRange(Scope, Lower, Upper); - Lower = Current; - Upper = NextRange(Lower); - } - } - constructRange(Scope, Lower, Upper); -} - -// At this point, all scopes for the compile unit have been created. -// The following aditional steps need to be performed on them: -// - If the lexical block doesn't have non-scope children, skip its -// emission and put its children directly to the parent scope. -// The '--internal=id' is turned on just for debugging traces. Then -// it is turned to its previous state. -void LVIRReader::removeEmptyScopes() { - LLVM_DEBUG({ dbgs() << "\n[removeEmptyScopes]\n"; }); - - SmallVector EmptyScopes; - - // Delete lexically empty scopes. - auto DeleteEmptyScopes = [&]() { - if (EmptyScopes.empty()) - return; - - LLVM_DEBUG({ - dbgs() << "\n** Collected empty scopes **\n"; - for (auto Scope : EmptyScopes) - Scope->print(dbgs()); - }); - - LVScope *Parent = nullptr; - for (auto Scope : EmptyScopes) { - Parent = Scope->getParentScope(); - LLVM_DEBUG({ - dbgs() << "Scope: " << Scope->getID() << ", "; - dbgs() << "Parent: " << Parent->getID() << "\n"; - }); - - // If the target scope has lines, move them to the scope parent. - const LVLines *Lines = Scope->getLines(); - if (Lines) { - LVLines Pack; - std::copy(Lines->begin(), Lines->end(), std::back_inserter(Pack)); - for (LVLine *Line : Pack) { - if (Scope->removeElement(Line)) { - LLVM_DEBUG({ dbgs() << "Line: " << Line->getID() << "\n"; }); - Line->resetParent(); - Parent->addElement(Line); - Line->updateLevel(Parent, /*Moved=*/false); - } - } - } - - if (Parent->removeElement(Scope)) { - const LVScopes *Scopes = Scope->getScopes(); - if (Scopes) { - for (LVScope *Child : *Scopes) { - LLVM_DEBUG({ dbgs() << "Child: " << Child->getID() << "\n"; }); - Child->resetParent(); - Parent->addElement(Child); - Child->updateLevel(Parent, /*Moved=*/false); - } - } - } - } - }; - - // Traverse the scopes tree and collect those lexical blocks that do not - // have non-scope children. Do not include the lines as they are included - // in the logical view as a way to show their associated logical scope. - std::function TraverseScope = [&](LVScope *Current) { - auto IsEmpty = [](LVScope *Scope) -> bool { - return !Scope->getSymbols() && !Scope->getTypes() && !Scope->getRanges(); - }; - - if (const LVScopes *Scopes = Current->getScopes()) { - for (LVScope *Scope : *Scopes) { - if (Scope->getIsLexicalBlock() && IsEmpty(Scope)) - EmptyScopes.push_back(Scope); - TraverseScope(Scope); - } - } - }; - - // Preserve current setting for '--internal=id'. - bool InternalID = options().getInternalID(); - llvm::scope_exit ResetSetting([&] { - // Restore setting for '--internal=id'. - if (!InternalID) - options().resetInternalID(); - }); - options().setInternalID(); - - LLVM_DEBUG({ - dbgs() << "\nBefore - RemoveEmptyScopes\n"; - printCollectedElements(Root); - }); - - TraverseScope(CompileUnit); - DeleteEmptyScopes(); - - LLVM_DEBUG({ - dbgs() << "\nAfter - RemoveEmptyScopes\n"; - printCollectedElements(Root); - }); -} - -// The IR generated by Clang, allocates the inlined lexical scopes -// at the enclosing function level. Move them to the correct scope. -void LVIRReader::resolveInlinedLexicalScopes() { - LLVM_DEBUG({ dbgs() << "\n[resolveInlinedLexicalScopes]\n"; }); - LLVM_DEBUG({ dumpInlinedInfo("Before", /*Full=*/false); }); - - std::function TraverseChildren = [&](LVScope *Parent) { - LLVM_DEBUG({ - dbgs() << "\nParent Scope: "; - Parent->dumpCommon(); - }); - - // Get associated inlined scopes for the parent scope. - LVList &ParentInlinedList = getInlinedList(Parent); - - // Check if the inlined scope parent is in the ParentInlinedList. - auto CheckInlinedScope = [&](LVList &ScopeInlinedList) -> bool { - bool Matched = true; - for (auto &InlinedScope : ScopeInlinedList) { - LLVM_DEBUG({ - dbgs() << "Inlined Scope: "; - InlinedScope->dumpCommon(); - }); - LVScope *ParentScope = InlinedScope->getParentScope(); - for (auto &ParentInlinedScope : ParentInlinedList) { - if (ParentInlinedScope != ParentScope) { - // If the parent for the inlined scope is not the Parent Inlined - // list, it means the lexical scope is incorrect. - // Stop the traversal as the other inlined scopes will have the - // same problem as they were created from the same original scope. - LLVM_DEBUG({ - dbgs() << "\nIncorrect parent scope\n"; - dbgs() << "ParentInlinedScope: "; - ParentInlinedScope->dumpCommon(); - dbgs() << "ParentScope: "; - ParentScope->dumpCommon(); - dbgs() << "\n"; - }); - Matched = false; - break; - } - } - if (!Matched) - break; - } - return Matched; - }; - - // Adjust the inlined scopes based on the ParentInlinedList. - auto AdjustInlinedScope = [&](LVList &ScopeInlinedList) { - assert(ScopeInlinedList.size() == ParentInlinedList.size() && - "Scope list do not have same number of items."); - - LLVM_DEBUG({ dbgs() << "Begin scope adjustment\n"; }); - LVScope *CurrentParent = nullptr; - LVScope *TargetParent = nullptr; - LVScope *InlinedScope = nullptr; - auto ItInlined = ScopeInlinedList.begin(); - auto ItParent = ParentInlinedList.begin(); - while (ItInlined != ScopeInlinedList.end()) { - TargetParent = *ItParent; - InlinedScope = *ItInlined; - CurrentParent = InlinedScope->getParentScope(); - - LLVM_DEBUG({ - dbgs() << "Target Parent: "; - TargetParent->dumpCommon(); - dbgs() << "Current Parent: "; - CurrentParent->dumpCommon(); - dbgs() << "Inlined: "; - InlinedScope->dumpCommon(); - }); - - // Correct lexical scope. - if (CurrentParent->removeElement(InlinedScope)) { - TargetParent->addElement(InlinedScope); - InlinedScope->updateLevel(TargetParent, /*Moved=*/false); - } - ++ItInlined; - ++ItParent; - } - LLVM_DEBUG({ dbgs() << "End scope adjustment\n"; }); - }; - - // Traverse the scope children. - if (const LVScopes *Children = Parent->getScopes()) - for (LVScope *Scope : *Children) { - LLVM_DEBUG({ - dbgs() << "\nOrigin Scope: "; - Scope->dumpCommon(); - }); - - // Get associated inlined scopes for the scope. - LVList &ScopeInlinedList = getInlinedList(Scope); - if (!CheckInlinedScope(ScopeInlinedList)) { - // AdjustInlinedScope to the correct lexical scope. - AdjustInlinedScope(ScopeInlinedList); - } - TraverseChildren(Scope); - } - }; - - // Traverse the origin scopes and for each function scope, analyze their - // associated inlined scopes to see if they have to be move to their - // correct lexical scope. - for (auto &Entry : InlinedList) { - LVScope *OriginScope = Entry.first; - if (OriginScope->getIsFunction()) - TraverseChildren(OriginScope); - } - - LLVM_DEBUG({ dumpInlinedInfo("After", /*Full=*/false); }); -} - -// During the IR-to-logical-view construction, traverse all the logical -// elements to check if they have been properly constructed (finalized). -void LVIRReader::checkScopes(LVScope *Scope) { - LLVM_DEBUG({ dbgs() << "\n[checkScopes]\n"; }); - - auto PrintElement = [](LVElement *Element) { - LLVM_DEBUG({ - dwarf::Tag Tag = Element->getTag(); - size_t ID = Element->getID(); - const char *Kind = Element->kind(); - StringRef Name = Element->getName(); - uint32_t LineNumber = Element->getLineNumber(); - dbgs() << "Tag: " - << formatv("{0} ", fmt_align(Tag, AlignStyle::Left, 35)); - dbgs() << "ID: " << formatv("{0} ", fmt_align(ID, AlignStyle::Left, 5)); - dbgs() << "Kind: " - << formatv("{0} ", fmt_align(Kind, AlignStyle::Left, 15)); - dbgs() << "Line: " - << formatv("{0} ", fmt_align(LineNumber, AlignStyle::Left, 5)); - dbgs() << "Name: '" << std::string(Name) << "' "; - dbgs() << "\n"; - }); - }; - - std::function Traverse = [&](LVScope *Current) { - auto Check = [&](auto *Entry) { - if (Entry) - if (!Entry->getIsFinalized()) - PrintElement(Entry); - }; - - for (LVElement *Element : Current->getChildren()) - Check(Element); - - if (Current->getScopes()) - for (LVScope *Scope : *Current->getScopes()) - Traverse(Scope); - }; - - // Start traversing the scopes root and check its integrity. - Traverse(Scope); -} - -void LVIRReader::sortScopes() { Root->sort(); } - -void LVIRReader::print(raw_ostream &OS) const { - OS << "LVIRReader\n"; - LLVM_DEBUG(dbgs() << "CreateReaders\n"); -} diff --git a/llvm/lib/Transforms/Utils/DebugSSAUpdater.cpp b/llvm/lib/Transforms/Utils/DebugSSAUpdater.cpp index 43f6854e6db17..cceabd891d72c 100644 --- a/llvm/lib/Transforms/Utils/DebugSSAUpdater.cpp +++ b/llvm/lib/Transforms/Utils/DebugSSAUpdater.cpp @@ -281,17 +281,10 @@ void DbgValueRangeTable::addVariable(Function *F, DebugVariableAggregate DVA) { // which case we need a complete SSA liveness analysis to determine live-in // values per-block, or a variable has a single #dbg_declare. if (DeclareRecordFound) { - // Rust generates multiple #dbg_declare's. - // %self.dbg.spill = alloca [8 x i8], align 8 - // store ptr %self, ptr %self.dbg.spill, align 8 - // #dbg_declare(ptr %self.dbg.spill, !892, !DIExpression(), !894) - // #dbg_declare(ptr %self.dbg.spill, !895, !DIExpression(), !905) - if (NumRecordsFound != 1) { - LLVM_DEBUG(dbgs() << "Multiple records for a #dbg_declare!\n"); - return; - } // FIXME: This should be changed for fragments! LLVM_DEBUG(dbgs() << "Single location found for variable!\n"); + assert(NumRecordsFound == 1 && + "Found multiple records for a #dbg_declare variable!"); OrigSingleLocVariableValueTable[DVA] = DbgValueDef(LastRecordFound); return; } diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-compare-logical-elements.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-compare-logical-elements.test deleted file mode 100644 index 4d28ab844b767..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-compare-logical-elements.test +++ /dev/null @@ -1,121 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 1 - General options - -; test.cpp -; 1 using INTPTR = const int *; -; 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { -; 3 if (ParamBool) { -; 4 typedef int INTEGER; -; 5 const INTEGER CONSTANT = 7; -; 6 return CONSTANT; -; 7 } -; 8 return ParamUnsigned; -; 9 } - -; Compare mode - Logical view. -; The output shows in view form the 'missing (-), added (+)' elements, -; giving more context by swapping the reference and target object files. - -; RUN: llvm-debuginfo-analyzer --attribute=level \ -; RUN: --compare=types \ -; RUN: --report=view \ -; RUN: --print=symbols,types \ -; RUN: %p/Inputs/test-clang.ll \ -; RUN: %p/../DWARF/Inputs/test-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Reference: 'test-clang.ll' -; ONE-NEXT: Target: 'test-dwarf-gcc.o' -; ONE-EMPTY: -; ONE-NEXT: Logical View: -; ONE-NEXT: [000] {File} 'test-clang.ll' -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'test.cpp' -; ONE-NEXT: [002] 1 {TypeAlias} 'INTPTR' -> '* const int' -; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo' -> 'int' -; ONE-NEXT: [003] {Block} -; ONE-NEXT: +[004] 4 {TypeAlias} 'INTEGER' -> 'int' -; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' -; ONE-NEXT: [003] 2 {Parameter} 'ParamBool' -> 'bool' -; ONE-NEXT: [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' -; ONE-NEXT: [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' -; ONE-NEXT: -[003] 4 {TypeAlias} 'INTEGER' -> 'int' - -; Compare mode - Logical elements. -; The output shows in tabular form the 'missing (-), added (+)' elements, -; giving more context by swapping the reference and target object files. - -; RUN: llvm-as %p/Inputs/test-clang.ll -o %t.test-clang.bc - -; RUN: llvm-debuginfo-analyzer --attribute=level \ -; RUN: --compare=types \ -; RUN: --report=list \ -; RUN: --print=symbols,types,summary \ -; RUN: %t.test-clang.bc \ -; RUN: %p/../DWARF/Inputs/test-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=TWO %s - -; TWO: Reference: '{{.*}}test-clang.bc' -; TWO-NEXT: Target: 'test-dwarf-gcc.o' -; TWO-EMPTY: -; TWO-NEXT: (1) Missing Scopes: -; TWO-NEXT: -[003] {Block} -; TWO-EMPTY: -; TWO-NEXT: (1) Missing Types: -; TWO-NEXT: -[003] 4 {TypeAlias} 'INTEGER' -> 'int' -; TWO-EMPTY: -; TWO-NEXT: (1) Added Types: -; TWO-NEXT: +[004] 4 {TypeAlias} 'INTEGER' -> 'int' -; TWO-EMPTY: -; TWO-NEXT: ---------------------------------------- -; TWO-NEXT: Element Expected Missing Added -; TWO-NEXT: ---------------------------------------- -; TWO-NEXT: Scopes 6 1 0 -; TWO-NEXT: Symbols 0 0 0 -; TWO-NEXT: Types 2 1 1 -; TWO-NEXT: Lines 0 0 0 -; TWO-NEXT: ---------------------------------------- -; TWO-NEXT: Total 8 2 1 - -; Changing the 'Reference' and 'Target' order: - -; RUN: llvm-debuginfo-analyzer --attribute=level \ -; RUN: --compare=types \ -; RUN: --report=list \ -; RUN: --print=symbols,types,summary \ -; RUN: %p/../DWARF/Inputs/test-dwarf-gcc.o \ -; RUN: %p/Inputs/test-clang.ll 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=THREE %s - -; THREE: Reference: 'test-dwarf-gcc.o' -; THREE-NEXT: Target: 'test-clang.ll' -; THREE-EMPTY: -; THREE-NEXT: (1) Missing Types: -; THREE-NEXT: -[004] 4 {TypeAlias} 'INTEGER' -> 'int' -; THREE-EMPTY: -; THREE-NEXT: (1) Added Scopes: -; THREE-NEXT: +[003] {Block} -; THREE-EMPTY: -; THREE-NEXT: (1) Added Types: -; THREE-NEXT: +[003] 4 {TypeAlias} 'INTEGER' -> 'int' -; THREE-EMPTY: -; THREE-NEXT: ---------------------------------------- -; THREE-NEXT: Element Expected Missing Added -; THREE-NEXT: ---------------------------------------- -; THREE-NEXT: Scopes 4 0 1 -; THREE-NEXT: Symbols 0 0 0 -; THREE-NEXT: Types 2 1 1 -; THREE-NEXT: Lines 0 0 0 -; THREE-NEXT: ---------------------------------------- -; THREE-NEXT: Total 6 1 2 - -; Comparing IR and DWARF: - -; RUN: llvm-debuginfo-analyzer --attribute=level \ -; RUN: --compare=types \ -; RUN: --report=list \ -; RUN: --print=symbols,types,summary \ -; RUN: %p/../DWARF/Inputs/test-dwarf-gcc.o \ -; RUN: %p/Inputs/test-clang.ll 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=THREE %s diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test deleted file mode 100644 index 51a807942c48e..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test +++ /dev/null @@ -1,78 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 1 - General options. - -; test.cpp -; 1 using INTPTR = const int *; -; 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { -; 3 if (ParamBool) { -; 4 typedef int INTEGER; -; 5 const INTEGER CONSTANT = 7; -; 6 return CONSTANT; -; 7 } -; 8 return ParamUnsigned; -; 9 } - -; Print basic details. -; The following command prints basic details for all the logical elements -; sorted by the debug information internal offset; it includes its lexical -; level and debug info format. - -; RUN: llvm-as %p/Inputs/test-clang.ll -o %t.test-clang.bc - -; RUN: llvm-debuginfo-analyzer --attribute=level,format \ -; RUN: --output-sort=offset \ -; RUN: --print=scopes,symbols,types,lines,instructions \ -; RUN: %t.test-clang.bc 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; RUN: llvm-debuginfo-analyzer --attribute=level,format \ -; RUN: --output-sort=offset \ -; RUN: --print=elements \ -; RUN: %t.test-clang.bc 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Logical View: -; ONE-NEXT: [000] {File} '{{.*}}test-clang.bc' -> Bitcode IR -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'test.cpp' -; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo' -> 'int' -; ONE-NEXT: [003] {Block} -; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' -; ONE-NEXT: [004] 5 {Line} -; ONE-NEXT: [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32' -; ONE-NEXT: [004] 6 {Line} -; ONE-NEXT: [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33' -; ONE-NEXT: [004] 6 {Line} -; ONE-NEXT: [004] {Code} 'br label %return, !dbg !33' -; ONE-NEXT: [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' -; ONE-NEXT: [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' -; ONE-NEXT: [003] 2 {Parameter} 'ParamBool' -> 'bool' -; ONE-NEXT: [003] 4 {TypeAlias} 'INTEGER' -> 'int' -; ONE-NEXT: [003] 2 {Line} -; ONE-NEXT: [003] {Code} '%retval = alloca i32, align 4' -; ONE-NEXT: [003] {Code} '%ParamPtr.addr = alloca ptr, align 8' -; ONE-NEXT: [003] {Code} '%ParamUnsigned.addr = alloca i32, align 4' -; ONE-NEXT: [003] {Code} '%ParamBool.addr = alloca i8, align 1' -; ONE-NEXT: [003] {Code} '%CONSTANT = alloca i32, align 4' -; ONE-NEXT: [003] {Code} 'store ptr %ParamPtr, ptr %ParamPtr.addr, align 8' -; ONE-NEXT: [003] {Code} 'store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4' -; ONE-NEXT: [003] {Code} '%storedv = zext i1 %ParamBool to i8' -; ONE-NEXT: [003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1' -; ONE-NEXT: [003] 8 {Line} -; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34' -; ONE-NEXT: [003] 8 {Line} -; ONE-NEXT: [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35' -; ONE-NEXT: [003] 8 {Line} -; ONE-NEXT: [003] {Code} 'br label %return, !dbg !35' -; ONE-NEXT: [003] 9 {Line} -; ONE-NEXT: [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36' -; ONE-NEXT: [003] 9 {Line} -; ONE-NEXT: [003] {Code} 'ret i32 %2, !dbg !36' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !26' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26' -; ONE-NEXT: [002] 1 {TypeAlias} 'INTPTR' -> '* const int' diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test deleted file mode 100644 index 51bbb30c1d97e..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test +++ /dev/null @@ -1,151 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 1 - General options - -; test.cpp -; 1 using INTPTR = const int *; -; 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { -; 3 if (ParamBool) { -; 4 typedef int INTEGER; -; 5 const INTEGER CONSTANT = 7; -; 6 return CONSTANT; -; 7 } -; 8 return ParamUnsigned; -; 9 } - -; Select logical elements. -; The following prints all 'instructions', 'symbols' and 'types' that -; contain 'LOAD' or 'store' in their names or types, using a tab layout -; and given the number of matches. - -; RUN: llvm-debuginfo-analyzer --attribute=level \ -; RUN: --select-nocase --select-regex \ -; RUN: --select=LOAD --select=store \ -; RUN: --report=list \ -; RUN: --print=symbols,types,instructions,summary \ -; RUN: %p/Inputs/test-clang.ll 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Logical View: -; ONE-NEXT: [000] {File} 'test-clang.ll' -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'test.cpp' -; ONE-NEXT: [003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26' -; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34' -; ONE-NEXT: [003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36' -; ONE-NEXT: [003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !26' -; ONE-NEXT: [003] {Code} '%storedv = zext i1 %ParamBool to i8' -; ONE-NEXT: [003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26' -; ONE-NEXT: [003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35' -; ONE-NEXT: [003] {Code} 'store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4' -; ONE-NEXT: [004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32' -; ONE-NEXT: [004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33' -; ONE-NEXT: [003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1' -; ONE-NEXT: [003] {Code} 'store ptr %ParamPtr, ptr %ParamPtr.addr, align 8' -; ONE-EMPTY: -; ONE-NEXT: ----------------------------- -; ONE-NEXT: Element Total Printed -; ONE-NEXT: ----------------------------- -; ONE-NEXT: Scopes 5 0 -; ONE-NEXT: Symbols 4 0 -; ONE-NEXT: Types 2 0 -; ONE-NEXT: Lines 23 12 -; ONE-NEXT: ----------------------------- -; ONE-NEXT: Total 34 12 - -; RUN: llvm-as %p/Inputs/test-clang.ll -o %t.test-clang.bc - -; RUN: llvm-debuginfo-analyzer --attribute=level \ -; RUN: --select-regex --select-nocase \ -; RUN: --select=INTe \ -; RUN: --report=list \ -; RUN: --print=symbols,types \ -; RUN: %t.test-clang.bc \ -; RUN: %p/../DWARF/Inputs/test-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=TWO %s - -; TWO: Logical View: -; TWO-NEXT: [000] {File} '{{.*}}test-clang.bc' -; TWO-EMPTY: -; TWO-NEXT: [001] {CompileUnit} 'test.cpp' -; TWO-NEXT: [003] 4 {TypeAlias} 'INTEGER' -> 'int' -; TWO-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' -; TWO-EMPTY: -; TWO-NEXT: Logical View: -; TWO-NEXT: [000] {File} 'test-dwarf-gcc.o' -; TWO-EMPTY: -; TWO-NEXT: [001] {CompileUnit} 'test.cpp' -; TWO-NEXT: [004] 4 {TypeAlias} 'INTEGER' -> 'int' -; TWO-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' - -; Select logical elements based on linkage names. -; The following prints all symbols that contain "_Z3fooPKijb" in their -; linkage names, using a tab layout and given the number of matches. - -; RUN: llvm-debuginfo-analyzer --attribute=level \ -; RUN: --select=_Z3fooPKijb \ -; RUN: --report=list \ -; RUN: --print=symbols,summary \ -; RUN: %p/Inputs/test-clang.ll \ -; RUN: %p/../DWARF/Inputs/test-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=THREE %s - -; THREE: Logical View: -; THREE-NEXT: [000] {File} 'test-clang.ll' -; THREE-EMPTY: -; THREE-NEXT: [001] {CompileUnit} 'test.cpp' -; THREE-NEXT: [002] 2 {Function} extern not_inlined 'foo' -> 'int' -; THREE-EMPTY: -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Element Total Printed -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Scopes 5 1 -; THREE-NEXT: Symbols 4 0 -; THREE-NEXT: Types 2 0 -; THREE-NEXT: Lines 0 0 -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Total 11 1 -; THREE-EMPTY: -; THREE-NEXT: Logical View: -; THREE-NEXT: [000] {File} 'test-dwarf-gcc.o' -; THREE-EMPTY: -; THREE-NEXT: [001] {CompileUnit} 'test.cpp' -; THREE-NEXT: [002] 2 {Function} extern not_inlined 'foo' -> 'int' -; THREE-EMPTY: -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Element Total Printed -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Scopes 3 1 -; THREE-NEXT: Symbols 4 0 -; THREE-NEXT: Types 2 0 -; THREE-NEXT: Lines 0 0 -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Total 9 1 - -; Select logical elements using exact match. -; The following prints all 'symbols' and 'types' that contain 'INTPTR' in -; their names or types, using a tab layout and given the number of matches. - -; RUN: llvm-debuginfo-analyzer --attribute=level \ -; RUN: --select=INTPTR \ -; RUN: --report=list \ -; RUN: --print=symbols,types,instructions,summary \ -; RUN: %p/Inputs/test-clang.ll 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=FOUR %s - -; FOUR: Logical View: -; FOUR-NEXT: [000] {File} 'test-clang.ll' -; FOUR-EMPTY: -; FOUR-NEXT: [001] {CompileUnit} 'test.cpp' -; FOUR-NEXT: [002] 1 {TypeAlias} 'INTPTR' -> '* const int' -; FOUR-NEXT: [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' -; FOUR-EMPTY: -; FOUR-NEXT: ----------------------------- -; FOUR-NEXT: Element Total Printed -; FOUR-NEXT: ----------------------------- -; FOUR-NEXT: Scopes 5 0 -; FOUR-NEXT: Symbols 4 1 -; FOUR-NEXT: Types 2 1 -; FOUR-NEXT: Lines 23 0 -; FOUR-NEXT: ----------------------------- -; FOUR-NEXT: Total 34 2 diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test deleted file mode 100644 index 76272e3f677ea..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test +++ /dev/null @@ -1,60 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 2 - Assembler instructions. - -; hello-world.cpp -; 1 extern int printf(const char * format, ... ); -; 2 -; 3 int main() -; 4 { -; 5 printf("Hello, World\n"); -; 6 return 0; -; 7 } - -; Logical lines. -; The logical views shows the intermixed lines and assembler instructions, -; allowing to compare the code generated at different stages. - -; RUN: llvm-as %p/Inputs/hello-world-clang.ll -o %t.hello-world-clang.bc - -; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \ -; RUN: --print=lines,instructions \ -; RUN: %t.hello-world-clang.bc \ -; RUN: %p/../DWARF/Inputs/hello-world-dwarf-clang.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Logical View: -; ONE-NEXT: [000] {File} '{{.*}}hello-world-clang.bc' -> Bitcode IR -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'hello-world.cpp' -; ONE-NEXT: [002] {Producer} 'clang version 20{{.*}}' -; ONE-NEXT: [002] 3 {Function} extern not_inlined 'main' -> 'int' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} '%retval = alloca i32, align 4' -; ONE-NEXT: [003] {Code} 'store i32 0, ptr %retval, align 4' -; ONE-NEXT: [003] 5 {Line} -; ONE-NEXT: [003] {Code} '%call = call noundef i32 (ptr, ...) @_Z6printfPKcz(ptr noundef @.str), !dbg !22' -; ONE-NEXT: [003] 6 {Line} -; ONE-NEXT: [003] {Code} 'ret i32 0, !dbg !23' -; ONE-EMPTY: -; ONE-NEXT: Logical View: -; ONE-NEXT: [000] {File} 'hello-world-dwarf-clang.o' -> elf64-x86-64 -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'hello-world.cpp' -; ONE-NEXT: [002] {Producer} 'clang version 15{{.*}}' -; ONE-NEXT: [002] 3 {Function} extern not_inlined 'main' -> 'int' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} 'pushq %rbp' -; ONE-NEXT: [003] {Code} 'movq %rsp, %rbp' -; ONE-NEXT: [003] {Code} 'subq $0x10, %rsp' -; ONE-NEXT: [003] {Code} 'movl $0x0, -0x4(%rbp)' -; ONE-NEXT: [003] 5 {Line} -; ONE-NEXT: [003] {Code} 'leaq (%rip), %rdi' -; ONE-NEXT: [003] {Code} 'movb $0x0, %al' -; ONE-NEXT: [003] {Code} 'callq 0x0' -; ONE-NEXT: [003] 6 {Line} -; ONE-NEXT: [003] {Code} 'xorl %eax, %eax' -; ONE-NEXT: [003] {Code} 'addq $0x10, %rsp' -; ONE-NEXT: [003] {Code} 'popq %rbp' -; ONE-NEXT: [003] {Code} 'retq' -; ONE-NEXT: [002] 6 {Line} diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/03-ir-incorrect-lexical-scope-typedef.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/03-ir-incorrect-lexical-scope-typedef.test deleted file mode 100644 index 174994af9eb50..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/03-ir-incorrect-lexical-scope-typedef.test +++ /dev/null @@ -1,131 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 3 - Incorrect lexical scope for typedef. - -; pr-44884.cpp -; 1 int bar(float Input) { return (int)Input; } -; 2 -; 3 unsigned foo(char Param) { -; 4 typedef int INT; // ** Definition for INT ** -; 5 INT Value = Param; -; 6 { -; 7 typedef float FLOAT; // ** Definition for FLOAT ** -; 8 { -; 9 FLOAT Added = Value + Param; -; 10 Value = bar(Added); -; 11 } -; 12 } -; 13 return Value + Param; -; 14 } - -; The lines 4 and 7 contains 2 typedefs, defined at different lexical -; scopes. - -; The above test is used to illustrates a scope issue found in the -; Clang compiler. -; PR44884: https://bugs.llvm.org/show_bug.cgi?id=44884 -; PR44229: https://github.com/llvm/llvm-project/issues/44229 - -; In the following logical views, we can see that the Clang compiler -; emits both typedefs at the same lexical scope (3), which is wrong. -; GCC emit correct lexical scope for both typedefs. - -; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \ -; RUN: --output-sort=kind \ -; RUN: --print=symbols,types,lines \ -; RUN: %p/Inputs/pr-44884-clang.ll \ -; RUN: %p/../DWARF/Inputs/pr-44884-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Logical View: -; ONE-NEXT: [000] {File} 'pr-44884-clang.ll' -> LLVM IR -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'pr-44884.cpp' -; ONE-NEXT: [002] {Producer} 'clang version 20{{.*}}' -; ONE-NEXT: [002] 1 {Function} extern not_inlined 'bar' -> 'int' -; ONE-NEXT: [003] 1 {Parameter} 'Input' -> 'float' -; ONE-NEXT: [003] 1 {Line} -; ONE-NEXT: [003] 1 {Line} -; ONE-NEXT: [003] 1 {Line} -; ONE-NEXT: [003] 1 {Line} -; ONE-NEXT: [002] 3 {Function} extern not_inlined 'foo' -> 'unsigned int' -; ONE-NEXT: [003] {Block} -; ONE-NEXT: [004] 9 {Variable} 'Added' -> 'FLOAT' -; ONE-NEXT: [004] 9 {Line} -; ONE-NEXT: [004] 9 {Line} -; ONE-NEXT: [004] 9 {Line} -; ONE-NEXT: [004] 9 {Line} -; ONE-NEXT: [004] 9 {Line} -; ONE-NEXT: [004] 9 {Line} -; ONE-NEXT: [004] 10 {Line} -; ONE-NEXT: [004] 10 {Line} -; ONE-NEXT: [004] 10 {Line} -; ONE-NEXT: [003] 3 {Parameter} 'Param' -> 'char' -; ONE-NEXT: [003] 7 {TypeAlias} 'FLOAT' -> 'float' -; ONE-NEXT: [003] 4 {TypeAlias} 'INT' -> 'int' -; ONE-NEXT: [003] 5 {Variable} 'Value' -> 'INT' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] 5 {Line} -; ONE-NEXT: [003] 5 {Line} -; ONE-NEXT: [003] 5 {Line} -; ONE-NEXT: [003] 13 {Line} -; ONE-NEXT: [003] 13 {Line} -; ONE-NEXT: [003] 13 {Line} -; ONE-NEXT: [003] 13 {Line} -; ONE-NEXT: [003] 13 {Line} -; ONE-EMPTY: -; ONE-NEXT: Logical View: -; ONE-NEXT: [000] {File} 'pr-44884-dwarf-gcc.o' -> elf64-x86-64 -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'pr-44884.cpp' -; ONE-NEXT: [002] {Producer} 'GNU C++14{{.*}}' -; ONE-NEXT: [002] 1 {Function} extern not_inlined 'bar' -> 'int' -; ONE-NEXT: [003] 1 {Parameter} 'Input' -> 'float' -; ONE-NEXT: [003] 1 {Line} -; ONE-NEXT: [003] 1 {Line} -; ONE-NEXT: [003] 1 {Line} -; ONE-NEXT: [002] 3 {Function} extern not_inlined 'foo' -> 'unsigned int' -; ONE-NEXT: [003] {Block} -; ONE-NEXT: [004] {Block} -; ONE-NEXT: [005] 9 {Variable} 'Added' -> 'FLOAT' -; ONE-NEXT: [005] 9 {Line} -; ONE-NEXT: [005] 9 {Line} -; ONE-NEXT: [005] 9 {Line} -; ONE-NEXT: [005] 10 {Line} -; ONE-NEXT: [004] 7 {TypeAlias} 'FLOAT' -> 'float' -; ONE-NEXT: [003] 3 {Parameter} 'Param' -> 'char' -; ONE-NEXT: [003] 4 {TypeAlias} 'INT' -> 'int' -; ONE-NEXT: [003] 5 {Variable} 'Value' -> 'INT' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] 5 {Line} -; ONE-NEXT: [003] 13 {Line} -; ONE-NEXT: [003] 13 {Line} -; ONE-NEXT: [003] 14 {Line} -; ONE-NEXT: [002] 14 {Line} - -; Using the selection facilities, we can produce a simple tabular -; output showing just the logical types that are 'Typedef'. - -; RUN: llvm-as %p/Inputs/pr-44884-clang.ll -o %t.pr-44884-clang.bc - -; RUN: llvm-debuginfo-analyzer --attribute=level,format \ -; RUN: --output-sort=name \ -; RUN: --select-types=Typedef \ -; RUN: --report=list \ -; RUN: --print=types \ -; RUN: %t.pr-44884-clang.bc %p/Inputs/pr-44884-clang.ll 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=TWO %s - -; TWO: Logical View: -; TWO-NEXT: [000] {File} '{{.*}}pr-44884-clang.bc' -> Bitcode IR -; TWO-EMPTY: -; TWO-NEXT: [001] {CompileUnit} 'pr-44884.cpp' -; TWO-NEXT: [003] 7 {TypeAlias} 'FLOAT' -> 'float' -; TWO-NEXT: [003] 4 {TypeAlias} 'INT' -> 'int' -; TWO-EMPTY: -; TWO-NEXT: Logical View: -; TWO-NEXT: [000] {File} 'pr-44884-clang.ll' -> LLVM IR -; TWO-EMPTY: -; TWO-NEXT: [001] {CompileUnit} 'pr-44884.cpp' -; TWO-NEXT: [003] 7 {TypeAlias} 'FLOAT' -> 'float' -; TWO-NEXT: [003] 4 {TypeAlias} 'INT' -> 'int' diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/04-ir-missing-nested-enumerators.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/04-ir-missing-nested-enumerators.test deleted file mode 100644 index ff1b1545a2e16..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/04-ir-missing-nested-enumerators.test +++ /dev/null @@ -1,144 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 4 - Missing nested enumerations. - -; pr-46466.cpp -; 1 struct Struct { -; 2 union Union { -; 3 enum NestedEnum { RED, BLUE }; -; 4 }; -; 5 Union U; -; 6 }; -; 7 -; 8 Struct S; -; 9 int test() { -; 10 return S.U.BLUE; -; 11 } - -; The above test is used to illustrate a scope issue found in the Clang -; compiler. -; PR46466: https://bugs.llvm.org/show_bug.cgi?id=46466 -; PR45811: https://github.com/llvm/llvm-project/issues/45811 - -; In the following logical views, we can see that the debug -; information generated by the Clang compiler does not include any -; references to the enumerators 'RED' and 'BLUE'. The DWARF generated -; by GCC, does include such references. - -; RUN: llvm-as %p/Inputs/pr-46466-clang.ll -o %t.pr-46466-clang.bc - -; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \ -; RUN: --output-sort=name \ -; RUN: --print=symbols,types \ -; RUN: %t.pr-46466-clang.bc \ -; RUN: %p/../DWARF/Inputs/pr-46466-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Logical View: -; ONE-NEXT: [000] {File} '{{.*}}pr-46466-clang.bc' -> Bitcode IR -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp' -; ONE-NEXT: [002] {Producer} 'clang version 20{{.*}}' -; ONE-NEXT: [002] 8 {Variable} extern 'S' -> 'Struct' -; ONE-NEXT: [002] 1 {Struct} 'Struct' -; ONE-NEXT: [003] 5 {Member} public 'U' -> 'Union' -; ONE-EMPTY: -; ONE-NEXT: Logical View: -; ONE-NEXT: [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64 -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'pr-46466.cpp' -; ONE-NEXT: [002] {Producer} 'GNU C++14{{.*}}' -; ONE-NEXT: [002] 8 {Variable} extern 'S' -> 'Struct' -; ONE-NEXT: [002] 1 {Struct} 'Struct' -; ONE-NEXT: [003] 5 {Member} public 'U' -> 'Union' -; ONE-NEXT: [003] 2 {Union} 'Union' -; ONE-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int' -; ONE-NEXT: [005] {Enumerator} 'BLUE' = '0x1' -; ONE-NEXT: [005] {Enumerator} 'RED' = '0x0' - -; Using the selection facilities, we can produce a logical view -; showing just the logical types that are 'Enumerator' and its -; parents. The logical view is sorted by the types name. - -; RUN: llvm-debuginfo-analyzer --attribute=level,format \ -; RUN: --output-sort=name \ -; RUN: --select-types=Enumerator \ -; RUN: --report=parents \ -; RUN: --print=types \ -; RUN: %p/Inputs/pr-46466-clang.ll \ -; RUN: %p/../DWARF/Inputs/pr-46466-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=TWO %s - -; TWO: Logical View: -; TWO-NEXT: [000] {File} 'pr-46466-clang.ll' -> LLVM IR -; TWO-EMPTY: -; TWO-NEXT: [001] {CompileUnit} 'pr-46466.cpp' -; TWO-EMPTY: -; TWO-NEXT: Logical View: -; TWO-NEXT: [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64 -; TWO-EMPTY: -; TWO-NEXT: [001] {CompileUnit} 'pr-46466.cpp' -; TWO-NEXT: [002] 1 {Struct} 'Struct' -; TWO-NEXT: [003] 2 {Union} 'Union' -; TWO-NEXT: [004] 3 {Enumeration} 'NestedEnum' -> 'unsigned int' -; TWO-NEXT: [005] {Enumerator} 'BLUE' = '0x1' -; TWO-NEXT: [005] {Enumerator} 'RED' = '0x0' - -; Using the selection facilities, we can produce a simple tabular output -; including a summary for the logical types that are 'Enumerator'. The -; logical view is sorted by the types name. - -; RUN: llvm-debuginfo-analyzer --attribute=level,format \ -; RUN: --output-sort=name \ -; RUN: --select-types=Enumerator \ -; RUN: --print=types,summary \ -; RUN: %t.pr-46466-clang.bc %p/Inputs/pr-46466-clang.ll \ -; RUN: %p/../DWARF/Inputs/pr-46466-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=THREE %s - -; THREE: Logical View: -; THREE-NEXT: [000] {File} '{{.*}}pr-46466-clang.bc' -> Bitcode IR -; THREE-EMPTY: -; THREE-NEXT: [001] {CompileUnit} 'pr-46466.cpp' -; THREE-EMPTY: -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Element Total Printed -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Scopes 4 0 -; THREE-NEXT: Symbols 0 0 -; THREE-NEXT: Types 0 0 -; THREE-NEXT: Lines 0 0 -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Total 4 0 -; THREE-EMPTY: -; THREE-NEXT: Logical View: -; THREE-NEXT: [000] {File} 'pr-46466-clang.ll' -> LLVM IR -; THREE-EMPTY: -; THREE-NEXT: [001] {CompileUnit} 'pr-46466.cpp' -; THREE-EMPTY: -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Element Total Printed -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Scopes 4 0 -; THREE-NEXT: Symbols 0 0 -; THREE-NEXT: Types 0 0 -; THREE-NEXT: Lines 0 0 -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Total 4 0 -; THREE-EMPTY: -; THREE-NEXT: Logical View: -; THREE-NEXT: [000] {File} 'pr-46466-dwarf-gcc.o' -> elf64-x86-64 -; THREE-EMPTY: -; THREE-NEXT: [001] {CompileUnit} 'pr-46466.cpp' -; THREE-NEXT: [005] {Enumerator} 'BLUE' = '0x1' -; THREE-NEXT: [005] {Enumerator} 'RED' = '0x0' -; THREE-EMPTY: -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Element Total Printed -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Scopes 5 0 -; THREE-NEXT: Symbols 0 0 -; THREE-NEXT: Types 2 2 -; THREE-NEXT: Lines 0 0 -; THREE-NEXT: ----------------------------- -; THREE-NEXT: Total 7 2 diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/05-ir-incorrect-lexical-scope-variable.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/05-ir-incorrect-lexical-scope-variable.test deleted file mode 100644 index dad694b197266..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/05-ir-incorrect-lexical-scope-variable.test +++ /dev/null @@ -1,113 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 5 - Incorrect lexical scope variable. - -; pr-43860.cpp -; 1 #include "definitions.h" -; 2 forceinline int InlineFunction(int Param) { -; 3 int Var_1 = Param; -; 4 { -; 5 int Var_2 = Param + Var_1; -; 6 Var_1 = Var_2; -; 7 } -; 8 return Var_1; -; 9 } -; 10 -; 11 int test(int Param_1, int Param_2) { -; 12 int A = Param_1; -; 13 A += InlineFunction(Param_2); -; 14 return A; -; 15 } - -; The above test was used to illustrate a variable issue found in the -; Clang compiler. -; PR43860: https://bugs.llvm.org/show_bug.cgi?id=43860 -; PR43205: https://github.com/llvm/llvm-project/issues/43205 - -; Now the issue is fixed in Clang. - -; In the following logical views, we can see that the debug -; information generated by the Clang compiler shows the variables -; 'Var_1' and 'Var_2' at the same lexical scope as GCC in the function -; 'InlineFuction': '3' and '4' respectively. - -; RUN: llvm-as %p/Inputs/pr-43860-clang.ll -o %t.pr-43860-clang.bc - -; RUN: llvm-debuginfo-analyzer --attribute=level,format,producer \ -; RUN: --output-sort=name \ -; RUN: --print=symbols \ -; RUN: %t.pr-43860-clang.bc \ -; RUN: %p/../DWARF/Inputs/pr-43860-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Logical View: -; ONE-NEXT: [000] {File} '{{.*}}pr-43860-clang.bc' -> Bitcode IR -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'pr-43860.cpp' -; ONE-NEXT: [002] {Producer} 'clang version 20{{.*}}' -; ONE-NEXT: [002] 2 {Function} extern inlined 'InlineFunction' -> 'int' -; ONE-NEXT: [003] {Block} -; ONE-NEXT: [004] 5 {Variable} 'Var_2' -> 'int' -; ONE-NEXT: [003] 2 {Parameter} 'Param' -> 'int' -; ONE-NEXT: [003] 3 {Variable} 'Var_1' -> 'int' -; ONE-NEXT: [002] 11 {Function} extern not_inlined 'test' -> 'int' -; ONE-NEXT: [003] 12 {Variable} 'A' -> 'int' -; ONE-NEXT: [003] 13 {InlinedFunction} inlined 'InlineFunction' -> 'int' -; ONE-NEXT: [004] {Block} -; ONE-NEXT: [005] {Variable} 'Var_2' -> 'int' -; ONE-NEXT: [004] {Parameter} 'Param' -> 'int' -; ONE-NEXT: [004] {Variable} 'Var_1' -> 'int' -; ONE-NEXT: [003] 11 {Parameter} 'Param_1' -> 'int' -; ONE-NEXT: [003] 11 {Parameter} 'Param_2' -> 'int' -; ONE-EMPTY: -; ONE-NEXT: Logical View: -; ONE-NEXT: [000] {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64 -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'pr-43860.cpp' -; ONE-NEXT: [002] {Producer} 'GNU C++14{{.*}}' -; ONE-NEXT: [002] 2 {Function} extern declared_inlined 'InlineFunction' -> 'int' -; ONE-NEXT: [003] {Block} -; ONE-NEXT: [004] 5 {Variable} 'Var_2' -> 'int' -; ONE-NEXT: [003] 2 {Parameter} 'Param' -> 'int' -; ONE-NEXT: [003] 3 {Variable} 'Var_1' -> 'int' -; ONE-NEXT: [002] 11 {Function} extern not_inlined 'test' -> 'int' -; ONE-NEXT: [003] 12 {Variable} 'A' -> 'int' -; ONE-NEXT: [003] 13 {InlinedFunction} declared_inlined 'InlineFunction' -> 'int' -; ONE-NEXT: [004] {Block} -; ONE-NEXT: [005] {Variable} 'Var_2' -> 'int' -; ONE-NEXT: [004] {Parameter} 'Param' -> 'int' -; ONE-NEXT: [004] {Variable} 'Var_1' -> 'int' -; ONE-NEXT: [003] 11 {Parameter} 'Param_1' -> 'int' -; ONE-NEXT: [003] 11 {Parameter} 'Param_2' -> 'int' - -; Using the selection facilities, we can produce a simple tabular output -; showing just the logical elements that have in their name the 'var' -; pattern. The logical view is sorted by the variables name. - -; RUN: llvm-debuginfo-analyzer --attribute=level,format \ -; RUN: --output-sort=name \ -; RUN: --select-regex --select-nocase \ -; RUN: --select=Var \ -; RUN: --report=list \ -; RUN: --print=symbols \ -; RUN: %p/Inputs/pr-43860-clang.ll \ -; RUN: %p/../DWARF/Inputs/pr-43860-dwarf-gcc.o 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=TWO %s - -; TWO: Logical View: -; TWO-NEXT: [000] {File} 'pr-43860-clang.ll' -> LLVM IR -; TWO-EMPTY: -; TWO-NEXT: [001] {CompileUnit} 'pr-43860.cpp' -; TWO-NEXT: [004] {Variable} 'Var_1' -> 'int' -; TWO-NEXT: [003] 3 {Variable} 'Var_1' -> 'int' -; TWO-NEXT: [005] {Variable} 'Var_2' -> 'int' -; TWO-NEXT: [004] 5 {Variable} 'Var_2' -> 'int' -; TWO-EMPTY: -; TWO-NEXT: Logical View: -; TWO-NEXT: [000] {File} 'pr-43860-dwarf-gcc.o' -> elf64-x86-64 -; TWO-EMPTY: -; TWO-NEXT: [001] {CompileUnit} 'pr-43860.cpp' -; TWO-NEXT: [004] {Variable} 'Var_1' -> 'int' -; TWO-NEXT: [003] 3 {Variable} 'Var_1' -> 'int' -; TWO-NEXT: [005] {Variable} 'Var_2' -> 'int' -; TWO-NEXT: [004] 5 {Variable} 'Var_2' -> 'int' diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test deleted file mode 100644 index 3f6db431a676c..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test +++ /dev/null @@ -1,121 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 6 - Full logical view - -; test.cpp -; 1 using INTPTR = const int *; -; 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { -; 3 if (ParamBool) { -; 4 typedef int INTEGER; -; 5 const INTEGER CONSTANT = 7; -; 6 return CONSTANT; -; 7 } -; 8 return ParamUnsigned; -; 9 } - -; Print low level details. -; The following command prints low level information that includes -; offsets within the debug information, debug location operands, -; linkage names, etc. - -; RUN: llvm-debuginfo-analyzer --attribute=all \ -; RUN: --output-sort=offset \ -; RUN: --print=all \ -; RUN: %p/Inputs/test-clang.ll 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Logical View: -; ONE-NEXT: [0x0000000000][000] {File} '{{.*}}test-clang{{.*}}.ll' -> LLVM IR -; ONE-EMPTY: -; ONE-NEXT: [0x0000000004][001] {CompileUnit} 'test.cpp' -; ONE-NEXT: [0x0000000004][002] {Producer} 'clang version 20{{.*}}' -; ONE-NEXT: [0x0000000004][002] {Language} 'DW_LANG_C_plus_plus_14' -; ONE-NEXT: {Directory} '{{.*}}/general' -; ONE-NEXT: {File} 'test.cpp' -; ONE-NEXT: {Public} 'foo' [0x0000000000:0x0000000023] -; ONE-NEXT: [0x0000000004][002] {Range} Lines 2:2 [0x0000000000:0x0000000023] -; ONE-NEXT: [0x0000000004][002] {Range} Lines 3:3 [0x0000000024:0x000000002f] -; ONE-NEXT: [0x0000000004][002] {Range} Lines 5:6 [0x0000000030:0x000000003b] -; ONE-NEXT: [0x0000000004][002] {Range} Lines 8:9 [0x000000003c:0x000000004f] -; ONE-EMPTY: -; ONE-NEXT: [0x0000000008][002] {Source} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000008][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000024]'int' -; ONE-NEXT: [0x0000000008][003] {Range} Lines 2:2 [0x0000000000:0x0000000023] -; ONE-NEXT: [0x0000000008][003] {Range} Lines 3:3 [0x0000000024:0x000000002f] -; ONE-NEXT: [0x0000000008][003] {Range} Lines 8:9 [0x000000003c:0x000000004f] -; ONE-NEXT: [0x0000000008][003] {Linkage} 0x0 '_Z3fooPKijb' -; ONE-NEXT: [0x000000000c][003] {Block} -; ONE-NEXT: [0x000000000c][004] {Range} Lines 5:6 [0x0000000030:0x000000003b] -; ONE-NEXT: [0x0000000010][004] 5 {Variable} 'CONSTANT' -> [0x000000003c]'const INTEGER' -; ONE-NEXT: [0x0000000010][005] {Coverage} 100.00% -; ONE-NEXT: [0x0000000000][006] {Location} -; ONE-NEXT: [0x0000000000][007] {Entry} bregx 3 ptr %CONSTANT+0 -; ONE-NEXT: [0x0000000030][004] 5 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000030][004] {Code} 'store i32 7, ptr %CONSTANT, align 4, !dbg !32' -; ONE-NEXT: [0x0000000034][004] 6 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000034][004] {Code} 'store i32 7, ptr %retval, align 4, !dbg !33' -; ONE-NEXT: [0x0000000038][004] 6 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000038][004] {Code} 'br label %return, !dbg !33' -; ONE-NEXT: [0x0000000014][003] 2 {Parameter} 'ParamPtr' -> [0x0000000028]'INTPTR' -; ONE-NEXT: [0x0000000014][004] {Coverage} 100.00% -; ONE-NEXT: [0x0000000000][004] {Location} -; ONE-NEXT: [0x0000000000][005] {Entry} bregx 0 ptr %ParamPtr.addr+0 -; ONE-NEXT: [0x0000000018][003] 2 {Parameter} 'ParamUnsigned' -> [0x0000000034]'unsigned int' -; ONE-NEXT: [0x0000000018][004] {Coverage} 100.00% -; ONE-NEXT: [0x0000000000][004] {Location} -; ONE-NEXT: [0x0000000000][005] {Entry} bregx 1 ptr %ParamUnsigned.addr+0 -; ONE-NEXT: [0x000000001c][003] 2 {Parameter} 'ParamBool' -> [0x0000000038]'bool' -; ONE-NEXT: [0x000000001c][004] {Coverage} 100.00% -; ONE-NEXT: [0x0000000000][004] {Location} -; ONE-NEXT: [0x0000000000][005] {Entry} bregx 2 ptr %ParamBool.addr+0 -; ONE-NEXT: [0x0000000020][003] 4 {TypeAlias} 'INTEGER' -> [0x0000000024]'int' -; ONE-NEXT: [0x0000000000][003] 2 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000000][003] {Code} '%retval = alloca i32, align 4' -; ONE-NEXT: [0x0000000004][003] {Code} '%ParamPtr.addr = alloca ptr, align 8' -; ONE-NEXT: [0x0000000008][003] {Code} '%ParamUnsigned.addr = alloca i32, align 4' -; ONE-NEXT: [0x000000000c][003] {Code} '%ParamBool.addr = alloca i8, align 1' -; ONE-NEXT: [0x0000000010][003] {Code} '%CONSTANT = alloca i32, align 4' -; ONE-NEXT: [0x0000000014][003] {Code} 'store ptr %ParamPtr, ptr %ParamPtr.addr, align 8' -; ONE-NEXT: [0x0000000018][003] {Code} 'store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4' -; ONE-NEXT: [0x000000001c][003] {Code} '%storedv = zext i1 %ParamBool to i8' -; ONE-NEXT: [0x0000000020][003] {Code} 'store i8 %storedv, ptr %ParamBool.addr, align 1' -; ONE-NEXT: [0x000000003c][003] 8 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x000000003c][003] {Code} '%1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34' -; ONE-NEXT: [0x0000000040][003] 8 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000040][003] {Code} 'store i32 %1, ptr %retval, align 4, !dbg !35' -; ONE-NEXT: [0x0000000044][003] 8 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000044][003] {Code} 'br label %return, !dbg !35' -; ONE-NEXT: [0x0000000048][003] 9 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000048][003] {Code} '%2 = load i32, ptr %retval, align 4, !dbg !36' -; ONE-NEXT: [0x000000004c][003] 9 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x000000004c][003] {Code} 'ret i32 %2, !dbg !36' -; ONE-NEXT: [0x0000000024][003] 3 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000024][003] {Code} '%0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26' -; ONE-NEXT: [0x0000000028][003] 3 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x0000000028][003] {Code} '%loadedv = trunc i8 %0 to i1, !dbg !26' -; ONE-NEXT: [0x000000002c][003] 3 {Line} '{{.*}}/general/test.cpp' -; ONE-NEXT: [0x000000002c][003] {Code} 'br i1 %loadedv, label %if.then, label %if.end, !dbg !26' -; ONE-NEXT: [0x0000000024][002] {BaseType} 'int' -; ONE-NEXT: [0x0000000028][002] 1 {TypeAlias} 'INTPTR' -> [0x000000002c]'* const int' -; ONE-NEXT: [0x0000000034][002] {BaseType} 'unsigned int' -; ONE-NEXT: [0x0000000038][002] {BaseType} 'bool' -; ONE-EMPTY: -; ONE-NEXT: ----------------------------- -; ONE-NEXT: Element Total Printed -; ONE-NEXT: ----------------------------- -; ONE-NEXT: Scopes 5 3 -; ONE-NEXT: Symbols 4 4 -; ONE-NEXT: Types 5 5 -; ONE-NEXT: Lines 38 32 -; ONE-NEXT: ----------------------------- -; ONE-NEXT: Total 52 44 -; ONE-EMPTY: -; ONE-NEXT: Scope Sizes: -; ONE-NEXT: 60 (100.00%) : [0x0000000004][001] {CompileUnit} 'test.cpp' -; ONE-NEXT: 28 ( 46.67%) : [0x0000000008][002] 2 {Function} extern not_inlined 'foo' -> [0x0000000024]'int' -; ONE-NEXT: 8 ( 13.33%) : [0x000000000c][003] {Block} -; ONE-EMPTY: -; ONE-NEXT: Totals by lexical level: -; ONE-NEXT: [001]: 60 (100.00%) -; ONE-NEXT: [002]: 28 ( 46.67%) -; ONE-NEXT: [003]: 8 ( 13.33%) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/07-ir-debug-formats.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/07-ir-debug-formats.test deleted file mode 100644 index a3b08d5a6d01a..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/07-ir-debug-formats.test +++ /dev/null @@ -1,48 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 7 - Logical view for debug-records and debug-intrinsics format. - -; test.cpp -; 1 using INTPTR = const int *; -; 2 int foo(INTPTR ParamPtr, unsigned ParamUnsigned, bool ParamBool) { -; 3 if (ParamBool) { -; 4 typedef int INTEGER; -; 5 const INTEGER CONSTANT = 7; -; 6 return CONSTANT; -; 7 } -; 8 return ParamUnsigned; -; 9 } - -; The following command prints the debug locations for both formats: -; debug-records and debug-intrinsics format. - -; RUN: llvm-debuginfo-analyzer --attribute=level,location \ -; RUN: --output-sort=name \ -; RUN: --print=symbols \ -; RUN: %p/Inputs/test-clang.ll 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; RUN: llvm-debuginfo-analyzer --attribute=level,location \ -; RUN: --output-sort=name \ -; RUN: --print=symbols \ -; RUN: %p/Inputs/test-clang-intrinsics.ll 2>&1 | \ -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s - -; ONE: Logical View: -; ONE-NEXT: [000] {File} '{{.*}}test-clang{{.*}}.ll' -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'test.cpp' -; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo' -> 'int' -; ONE-NEXT: [003] 2 {Parameter} 'ParamBool' -> 'bool' -; ONE-NEXT: [004] {Location} -; ONE-NEXT: [005] {Entry} bregx 2 ptr %ParamBool.addr+0 -; ONE-NEXT: [003] 2 {Parameter} 'ParamPtr' -> 'INTPTR' -; ONE-NEXT: [004] {Location} -; ONE-NEXT: [005] {Entry} bregx 0 ptr %ParamPtr.addr+0 -; ONE-NEXT: [003] 2 {Parameter} 'ParamUnsigned' -> 'unsigned int' -; ONE-NEXT: [004] {Location} -; ONE-NEXT: [005] {Entry} bregx 1 ptr %ParamUnsigned.addr+0 -; ONE-NEXT: [003] {Block} -; ONE-NEXT: [004] 5 {Variable} 'CONSTANT' -> 'const INTEGER' -; ONE-NEXT: [006] {Location} -; ONE-NEXT: [007] {Entry} bregx 3 ptr %CONSTANT+0 diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/08-ir-multiple-compile-units.test b/llvm/test/tools/llvm-debuginfo-analyzer/IR/08-ir-multiple-compile-units.test deleted file mode 100644 index b666c7ba3d666..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/08-ir-multiple-compile-units.test +++ /dev/null @@ -1,168 +0,0 @@ -; REQUIRES: x86-registered-target - -; Test case 8 - Multiple compile units. - -; Using the following input files: - -; compile-unit-1.cpp -; 1 int Var_1 = 1; -; 2 int foo_1(int P1) { -; 3 int V1 = P1; -; 4 return V1 + Var_1; -; 5 } -; 6 -; 7 void f1() { -; 8 foo_1(111); -; 9 } - -; compile-unit-2.cpp -; 1 int Var_2 = 1; -; 2 int foo_2(int P2) { -; 3 int V2 = P2; -; 4 return V2 + Var_2; -; 5 } -; 6 -; 7 void f2() { -; 8 foo_2(222); -; 9 } - -; compile-unit-3.cpp -; 1 int Var_3 = 1; -; 2 int foo_3(int P3) { -; 3 int V3 = P3; -; 4 return V3 + Var_3; -; 5 } -; 6 -; 7 void f3() { -; 8 foo_3(333); -; 9 } - -; compile-unit.cpp -; 1 void f1(); -; 2 void f2(); -; 3 void f3(); -; 4 -; 5 void foo() { -; 6 f1(); -; 7 f2(); -; 8 f3(); -; 9 } - -; Generate a combined IR (bitcode) and print its basic details. -; The following command prints basic details for all the logical-- elements -; sorted by the debug information internal offset; it includes its lexical -; level and debug info format. - -; Generate individual bitcode files -; RUN: llvm-as %p/Inputs/compile-unit-1.ll -o %t.compile-unit-1.bc -; RUN: llvm-as %p/Inputs/compile-unit-2.ll -o %t.compile-unit-2.bc -; RUN: llvm-as %p/Inputs/compile-unit-3.ll -o %t.compile-unit-3.bc -; RUN: llvm-as %p/Inputs/compile-unit.ll -o %t.compile-unit.bc - -; Combine the individual bitcode files -; RUN: llvm-link %t.compile-unit-1.bc %t.compile-unit-2.bc \ -; RUN: %t.compile-unit-3.bc %t.compile-unit.bc \ -; RUN: -o %t.compile-unit-combined.bc - -; RUN: llvm-debuginfo-analyzer --attribute=level,format \ -; RUN: --output-sort=offset \ -; RUN: --print=scopes,symbols,types,lines,instructions \ -; RUN: %t.compile-unit-combined.bc \ -; RUN: 2>&1 > %t.compile-unit-combined.view - -; RUN: FileCheck --strict-whitespace -check-prefix=ONE %s < %t.compile-unit-combined.view - -; ONE: Logical View: -; ONE-NEXT: [000] {File} '{{.*}}compile-unit-combined.bc' -> Bitcode IR -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'compile-unit-1.cpp' -; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo_1' -> 'int' -; ONE-NEXT: [003] 2 {Parameter} 'P1' -> 'int' -; ONE-NEXT: [003] 3 {Variable} 'V1' -> 'int' -; ONE-NEXT: [003] 2 {Line} -; ONE-NEXT: [003] {Code} '%P1.addr = alloca i32, align 4' -; ONE-NEXT: [003] {Code} '%V1 = alloca i32, align 4' -; ONE-NEXT: [003] {Code} 'store i32 %P1, ptr %P1.addr, align 4' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} '%0 = load i32, ptr %P1.addr, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} 'store i32 %0, ptr %V1, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %V1, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%2 = load i32, ptr @Var_1, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%add = add nsw i32 %1, %2, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} 'ret i32 %add, !dbg !{{.*}}' -; ONE-NEXT: [002] 7 {Function} extern not_inlined 'f1' -> 'void' -; ONE-NEXT: [003] 8 {Line} -; ONE-NEXT: [003] {Code} '%call = call noundef i32 @_Z5foo_1i(i32 noundef 111), !dbg !{{.*}}' -; ONE-NEXT: [003] 9 {Line} -; ONE-NEXT: [003] {Code} 'ret void, !dbg !{{.*}}' -; ONE-NEXT: [002] 1 {Variable} extern 'Var_1' -> 'int' -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'compile-unit-2.cpp' -; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo_2' -> 'int' -; ONE-NEXT: [003] 2 {Parameter} 'P2' -> 'int' -; ONE-NEXT: [003] 3 {Variable} 'V2' -> 'int' -; ONE-NEXT: [003] 2 {Line} -; ONE-NEXT: [003] {Code} '%P2.addr = alloca i32, align 4' -; ONE-NEXT: [003] {Code} '%V2 = alloca i32, align 4' -; ONE-NEXT: [003] {Code} 'store i32 %P2, ptr %P2.addr, align 4' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} '%0 = load i32, ptr %P2.addr, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} 'store i32 %0, ptr %V2, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %V2, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%2 = load i32, ptr @Var_2, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%add = add nsw i32 %1, %2, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} 'ret i32 %add, !dbg !{{.*}}' -; ONE-NEXT: [002] 7 {Function} extern not_inlined 'f2' -> 'void' -; ONE-NEXT: [003] 8 {Line} -; ONE-NEXT: [003] {Code} '%call = call noundef i32 @_Z5foo_2i(i32 noundef 222), !dbg !{{.*}}' -; ONE-NEXT: [003] 9 {Line} -; ONE-NEXT: [003] {Code} 'ret void, !dbg !{{.*}}' -; ONE-NEXT: [002] 1 {Variable} extern 'Var_2' -> 'int' -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'compile-unit-3.cpp' -; ONE-NEXT: [002] 2 {Function} extern not_inlined 'foo_3' -> 'int' -; ONE-NEXT: [003] 2 {Parameter} 'P3' -> 'int' -; ONE-NEXT: [003] 3 {Variable} 'V3' -> 'int' -; ONE-NEXT: [003] 2 {Line} -; ONE-NEXT: [003] {Code} '%P3.addr = alloca i32, align 4' -; ONE-NEXT: [003] {Code} '%V3 = alloca i32, align 4' -; ONE-NEXT: [003] {Code} 'store i32 %P3, ptr %P3.addr, align 4' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} '%0 = load i32, ptr %P3.addr, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 3 {Line} -; ONE-NEXT: [003] {Code} 'store i32 %0, ptr %V3, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%1 = load i32, ptr %V3, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%2 = load i32, ptr @Var_3, align 4, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} '%add = add nsw i32 %1, %2, !dbg !{{.*}}' -; ONE-NEXT: [003] 4 {Line} -; ONE-NEXT: [003] {Code} 'ret i32 %add, !dbg !{{.*}}' -; ONE-NEXT: [002] 7 {Function} extern not_inlined 'f3' -> 'void' -; ONE-NEXT: [003] 8 {Line} -; ONE-NEXT: [003] {Code} '%call = call noundef i32 @_Z5foo_3i(i32 noundef 333), !dbg !{{.*}}' -; ONE-NEXT: [003] 9 {Line} -; ONE-NEXT: [003] {Code} 'ret void, !dbg !{{.*}}' -; ONE-NEXT: [002] 1 {Variable} extern 'Var_3' -> 'int' -; ONE-EMPTY: -; ONE-NEXT: [001] {CompileUnit} 'compile-unit.cpp' -; ONE-NEXT: [002] 5 {Function} extern not_inlined 'foo' -> 'void' -; ONE-NEXT: [003] 6 {Line} -; ONE-NEXT: [003] {Code} 'call void @_Z2f1v(), !dbg !{{.*}}' -; ONE-NEXT: [003] 7 {Line} -; ONE-NEXT: [003] {Code} 'call void @_Z2f2v(), !dbg !{{.*}}' -; ONE-NEXT: [003] 8 {Line} -; ONE-NEXT: [003] {Code} 'call void @_Z2f3v(), !dbg !{{.*}}' -; ONE-NEXT: [003] 9 {Line} -; ONE-NEXT: [003] {Code} 'ret void, !dbg !{{.*}}' diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-1.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-1.ll deleted file mode 100644 index cee8fb4683d54..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-1.ll +++ /dev/null @@ -1,58 +0,0 @@ -source_filename = "compile-unit-1.cpp" -target triple = "x86_64-unknown-linux" - -@Var_1 = dso_local global i32 1, align 4, !dbg !0 - -define dso_local noundef i32 @_Z5foo_1i(i32 noundef %P1) !dbg !14 { -entry: - %P1.addr = alloca i32, align 4 - %V1 = alloca i32, align 4 - store i32 %P1, ptr %P1.addr, align 4 - #dbg_declare(ptr %P1.addr, !18, !DIExpression(), !19) - #dbg_declare(ptr %V1, !20, !DIExpression(), !21) - %0 = load i32, ptr %P1.addr, align 4, !dbg !22 - store i32 %0, ptr %V1, align 4, !dbg !21 - %1 = load i32, ptr %V1, align 4, !dbg !23 - %2 = load i32, ptr @Var_1, align 4, !dbg !24 - %add = add nsw i32 %1, %2, !dbg !25 - ret i32 %add, !dbg !26 -} - -define dso_local void @_Z2f1v() !dbg !27 { -entry: - %call = call noundef i32 @_Z5foo_1i(i32 noundef 111), !dbg !30 - ret void, !dbg !31 -} - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!6, !7, !8} -!llvm.ident = !{!13} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "Var_1", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 23.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "compile-unit-1.cpp", directory: "", checksumkind: CSK_MD5, checksum: "13624fbfa5a73fa5a878920cde9f37b6") -!4 = !{!0} -!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!13 = !{!"clang version 23.0.0"} -!14 = distinct !DISubprogram(name: "foo_1", linkageName: "_Z5foo_1i", scope: !3, file: !3, line: 2, type: !15, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "P1", arg: 1, scope: !14, file: !3, line: 2, type: !5) -!19 = !DILocation(line: 2, column: 15, scope: !14) -!20 = !DILocalVariable(name: "V1", scope: !14, file: !3, line: 3, type: !5) -!21 = !DILocation(line: 3, column: 7, scope: !14) -!22 = !DILocation(line: 3, column: 12, scope: !14) -!23 = !DILocation(line: 4, column: 10, scope: !14) -!24 = !DILocation(line: 4, column: 15, scope: !14) -!25 = !DILocation(line: 4, column: 13, scope: !14) -!26 = !DILocation(line: 4, column: 3, scope: !14) -!27 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !3, file: !3, line: 7, type: !28, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2) -!28 = !DISubroutineType(types: !29) -!29 = !{null} -!30 = !DILocation(line: 8, column: 3, scope: !27) -!31 = !DILocation(line: 9, column: 1, scope: !27) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-2.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-2.ll deleted file mode 100644 index 43cf375d07db0..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-2.ll +++ /dev/null @@ -1,58 +0,0 @@ -source_filename = "compile-unit-2.cpp" -target triple = "x86_64-unknown-linux" - -@Var_2 = dso_local global i32 1, align 4, !dbg !0 - -define dso_local noundef i32 @_Z5foo_2i(i32 noundef %P2) !dbg !14 { -entry: - %P2.addr = alloca i32, align 4 - %V2 = alloca i32, align 4 - store i32 %P2, ptr %P2.addr, align 4 - #dbg_declare(ptr %P2.addr, !18, !DIExpression(), !19) - #dbg_declare(ptr %V2, !20, !DIExpression(), !21) - %0 = load i32, ptr %P2.addr, align 4, !dbg !22 - store i32 %0, ptr %V2, align 4, !dbg !21 - %1 = load i32, ptr %V2, align 4, !dbg !23 - %2 = load i32, ptr @Var_2, align 4, !dbg !24 - %add = add nsw i32 %1, %2, !dbg !25 - ret i32 %add, !dbg !26 -} - -define dso_local void @_Z2f2v() !dbg !27 { -entry: - %call = call noundef i32 @_Z5foo_2i(i32 noundef 222), !dbg !30 - ret void, !dbg !31 -} - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!6, !7, !8} -!llvm.ident = !{!13} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "Var_2", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 23.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "compile-unit-2.cpp", directory: "", checksumkind: CSK_MD5, checksum: "dd97ef1e977b3c5b03e5686f919327a5") -!4 = !{!0} -!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!13 = !{!"clang version 23.0.0"} -!14 = distinct !DISubprogram(name: "foo_2", linkageName: "_Z5foo_2i", scope: !3, file: !3, line: 2, type: !15, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "P2", arg: 1, scope: !14, file: !3, line: 2, type: !5) -!19 = !DILocation(line: 2, column: 15, scope: !14) -!20 = !DILocalVariable(name: "V2", scope: !14, file: !3, line: 3, type: !5) -!21 = !DILocation(line: 3, column: 7, scope: !14) -!22 = !DILocation(line: 3, column: 12, scope: !14) -!23 = !DILocation(line: 4, column: 10, scope: !14) -!24 = !DILocation(line: 4, column: 15, scope: !14) -!25 = !DILocation(line: 4, column: 13, scope: !14) -!26 = !DILocation(line: 4, column: 3, scope: !14) -!27 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !3, file: !3, line: 7, type: !28, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2) -!28 = !DISubroutineType(types: !29) -!29 = !{null} -!30 = !DILocation(line: 8, column: 3, scope: !27) -!31 = !DILocation(line: 9, column: 1, scope: !27) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-3.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-3.ll deleted file mode 100644 index 400f4c8cc130d..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit-3.ll +++ /dev/null @@ -1,58 +0,0 @@ -source_filename = "compile-unit-3.cpp" -target triple = "x86_64-unknown-linux" - -@Var_3 = dso_local global i32 1, align 4, !dbg !0 - -define dso_local noundef i32 @_Z5foo_3i(i32 noundef %P3) !dbg !14 { -entry: - %P3.addr = alloca i32, align 4 - %V3 = alloca i32, align 4 - store i32 %P3, ptr %P3.addr, align 4 - #dbg_declare(ptr %P3.addr, !18, !DIExpression(), !19) - #dbg_declare(ptr %V3, !20, !DIExpression(), !21) - %0 = load i32, ptr %P3.addr, align 4, !dbg !22 - store i32 %0, ptr %V3, align 4, !dbg !21 - %1 = load i32, ptr %V3, align 4, !dbg !23 - %2 = load i32, ptr @Var_3, align 4, !dbg !24 - %add = add nsw i32 %1, %2, !dbg !25 - ret i32 %add, !dbg !26 -} - -define dso_local void @_Z2f3v() !dbg !27 { -entry: - %call = call noundef i32 @_Z5foo_3i(i32 noundef 333), !dbg !30 - ret void, !dbg !31 -} - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!6, !7, !8} -!llvm.ident = !{!13} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "Var_3", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 23.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "compile-unit-3.cpp", directory: "", checksumkind: CSK_MD5, checksum: "fcd53200d3096d44f8a8308b6ed33c23") -!4 = !{!0} -!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!6 = !{i32 7, !"Dwarf Version", i32 5} -!7 = !{i32 2, !"Debug Info Version", i32 3} -!8 = !{i32 1, !"wchar_size", i32 4} -!13 = !{!"clang version 23.0.0"} -!14 = distinct !DISubprogram(name: "foo_3", linkageName: "_Z5foo_3i", scope: !3, file: !3, line: 2, type: !15, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !17) -!15 = !DISubroutineType(types: !16) -!16 = !{!5, !5} -!17 = !{} -!18 = !DILocalVariable(name: "P3", arg: 1, scope: !14, file: !3, line: 2, type: !5) -!19 = !DILocation(line: 2, column: 15, scope: !14) -!20 = !DILocalVariable(name: "V3", scope: !14, file: !3, line: 3, type: !5) -!21 = !DILocation(line: 3, column: 7, scope: !14) -!22 = !DILocation(line: 3, column: 12, scope: !14) -!23 = !DILocation(line: 4, column: 10, scope: !14) -!24 = !DILocation(line: 4, column: 15, scope: !14) -!25 = !DILocation(line: 4, column: 13, scope: !14) -!26 = !DILocation(line: 4, column: 3, scope: !14) -!27 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !3, file: !3, line: 7, type: !28, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2) -!28 = !DISubroutineType(types: !29) -!29 = !{null} -!30 = !DILocation(line: 8, column: 3, scope: !27) -!31 = !DILocation(line: 9, column: 1, scope: !27) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit.ll deleted file mode 100644 index cb47b96eccdfe..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/compile-unit.ll +++ /dev/null @@ -1,34 +0,0 @@ -source_filename = "compile-unit.cpp" -target triple = "x86_64-unknown-linux" - -define dso_local void @_Z3foov() !dbg !10 { -entry: - call void @_Z2f1v(), !dbg !13 - call void @_Z2f2v(), !dbg !14 - call void @_Z2f3v(), !dbg !15 - ret void, !dbg !16 -} - -declare void @_Z2f1v() - -declare void @_Z2f2v() - -declare void @_Z2f3v() - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!2, !3, !4} -!llvm.ident = !{!9} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 23.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "compile-unit.cpp", directory: "", checksumkind: CSK_MD5, checksum: "d340f597b69d89b7c542f22ce3d36231") -!2 = !{i32 7, !"Dwarf Version", i32 5} -!3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = !{i32 1, !"wchar_size", i32 4} -!9 = !{!"clang version 23.0.0"} -!10 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 5, type: !11, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0) -!11 = !DISubroutineType(types: !12) -!12 = !{null} -!13 = !DILocation(line: 6, column: 3, scope: !10) -!14 = !DILocation(line: 7, column: 3, scope: !10) -!15 = !DILocation(line: 8, column: 3, scope: !10) -!16 = !DILocation(line: 9, column: 1, scope: !10) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/hello-world-clang.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/hello-world-clang.ll deleted file mode 100644 index e1d918bae9c80..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/hello-world-clang.ll +++ /dev/null @@ -1,49 +0,0 @@ -; ModuleID = 'hello-world.cpp' -source_filename = "hello-world.cpp" -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux" - -@.str = private unnamed_addr constant [14 x i8] c"Hello, World\0A\00", align 1, !dbg !0 - -; Function Attrs: mustprogress noinline norecurse optnone uwtable -define dso_local noundef i32 @main() #0 !dbg !18 { -entry: - %retval = alloca i32, align 4 - store i32 0, ptr %retval, align 4 - %call = call noundef i32 (ptr, ...) @_Z6printfPKcz(ptr noundef @.str), !dbg !22 - ret i32 0, !dbg !23 -} - -declare noundef i32 @_Z6printfPKcz(ptr noundef, ...) #1 - -attributes #0 = { mustprogress noinline norecurse optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } - -!llvm.dbg.cu = !{!8} -!llvm.module.flags = !{!10, !11, !12, !13, !14, !15, !16} -!llvm.ident = !{!17} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(scope: null, file: !2, line: 5, type: !3, isLocal: true, isDefinition: true) -!2 = !DIFile(filename: "hello-world.cpp", directory: "/data/projects/scripts/regression-suite/input/general") -!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 112, elements: !6) -!4 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !5) -!5 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -!6 = !{!7} -!7 = !DISubrange(count: 14) -!8 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !2, producer: "clang version 20.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None) -!9 = !{!0} -!10 = !{i32 7, !"Dwarf Version", i32 5} -!11 = !{i32 2, !"Debug Info Version", i32 3} -!12 = !{i32 1, !"wchar_size", i32 4} -!13 = !{i32 8, !"PIC Level", i32 2} -!14 = !{i32 7, !"PIE Level", i32 2} -!15 = !{i32 7, !"uwtable", i32 2} -!16 = !{i32 7, !"frame-pointer", i32 2} -!17 = !{!"clang version 20.0.0"} -!18 = distinct !DISubprogram(name: "main", scope: !2, file: !2, line: 3, type: !19, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !8) -!19 = !DISubroutineType(types: !20) -!20 = !{!21} -!21 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!22 = !DILocation(line: 5, column: 3, scope: !18) -!23 = !DILocation(line: 6, column: 3, scope: !18) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-43860-clang.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-43860-clang.ll deleted file mode 100644 index 5c68979f49a00..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-43860-clang.ll +++ /dev/null @@ -1,92 +0,0 @@ -; ModuleID = 'pr-43860.cpp' -source_filename = "pr-43860.cpp" -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux" - -; Function Attrs: mustprogress noinline optnone uwtable -define dso_local noundef i32 @_Z4testii(i32 noundef %Param_1, i32 noundef %Param_2) #0 !dbg !10 { -entry: - %Param.addr.i = alloca i32, align 4 - %Var_1.i = alloca i32, align 4 - %Var_2.i = alloca i32, align 4 - %Param_1.addr = alloca i32, align 4 - %Param_2.addr = alloca i32, align 4 - %A = alloca i32, align 4 - store i32 %Param_1, ptr %Param_1.addr, align 4 - #dbg_declare(ptr %Param_1.addr, !15, !DIExpression(), !16) - store i32 %Param_2, ptr %Param_2.addr, align 4 - #dbg_declare(ptr %Param_2.addr, !17, !DIExpression(), !18) - #dbg_declare(ptr %A, !19, !DIExpression(), !20) - %0 = load i32, ptr %Param_1.addr, align 4, !dbg !21 - store i32 %0, ptr %A, align 4, !dbg !20 - %1 = load i32, ptr %Param_2.addr, align 4, !dbg !22 - store i32 %1, ptr %Param.addr.i, align 4 - #dbg_declare(ptr %Param.addr.i, !23, !DIExpression(), !27) - #dbg_declare(ptr %Var_1.i, !29, !DIExpression(), !30) - %2 = load i32, ptr %Param.addr.i, align 4, !dbg !31 - store i32 %2, ptr %Var_1.i, align 4, !dbg !30 - #dbg_declare(ptr %Var_2.i, !32, !DIExpression(), !34) - %3 = load i32, ptr %Param.addr.i, align 4, !dbg !35 - %4 = load i32, ptr %Var_1.i, align 4, !dbg !36 - %add.i = add nsw i32 %3, %4, !dbg !37 - store i32 %add.i, ptr %Var_2.i, align 4, !dbg !34 - %5 = load i32, ptr %Var_2.i, align 4, !dbg !38 - store i32 %5, ptr %Var_1.i, align 4, !dbg !39 - %6 = load i32, ptr %Var_1.i, align 4, !dbg !40 - %7 = load i32, ptr %A, align 4, !dbg !41 - %add = add nsw i32 %7, %6, !dbg !41 - store i32 %add, ptr %A, align 4, !dbg !41 - %8 = load i32, ptr %A, align 4, !dbg !42 - ret i32 %8, !dbg !43 -} - -attributes #0 = { mustprogress noinline optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} -!llvm.ident = !{!9} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "pr-43860.cpp", directory: "/data/projects/scripts/regression-suite/input/general") -!2 = !{i32 7, !"Dwarf Version", i32 5} -!3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = !{i32 1, !"wchar_size", i32 4} -!5 = !{i32 8, !"PIC Level", i32 2} -!6 = !{i32 7, !"PIE Level", i32 2} -!7 = !{i32 7, !"uwtable", i32 2} -!8 = !{i32 7, !"frame-pointer", i32 2} -!9 = !{!"clang version 20.0.0"} -!10 = distinct !DISubprogram(name: "test", linkageName: "_Z4testii", scope: !1, file: !1, line: 11, type: !11, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14) -!11 = !DISubroutineType(types: !12) -!12 = !{!13, !13, !13} -!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!14 = !{} -!15 = !DILocalVariable(name: "Param_1", arg: 1, scope: !10, file: !1, line: 11, type: !13) -!16 = !DILocation(line: 11, column: 14, scope: !10) -!17 = !DILocalVariable(name: "Param_2", arg: 2, scope: !10, file: !1, line: 11, type: !13) -!18 = !DILocation(line: 11, column: 27, scope: !10) -!19 = !DILocalVariable(name: "A", scope: !10, file: !1, line: 12, type: !13) -!20 = !DILocation(line: 12, column: 7, scope: !10) -!21 = !DILocation(line: 12, column: 11, scope: !10) -!22 = !DILocation(line: 13, column: 23, scope: !10) -!23 = !DILocalVariable(name: "Param", arg: 1, scope: !24, file: !1, line: 2, type: !13) -!24 = distinct !DISubprogram(name: "InlineFunction", linkageName: "_Z14InlineFunctioni", scope: !1, file: !1, line: 2, type: !25, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14) -!25 = !DISubroutineType(types: !26) -!26 = !{!13, !13} -!27 = !DILocation(line: 2, column: 36, scope: !24, inlinedAt: !28) -!28 = distinct !DILocation(line: 13, column: 8, scope: !10) -!29 = !DILocalVariable(name: "Var_1", scope: !24, file: !1, line: 3, type: !13) -!30 = !DILocation(line: 3, column: 7, scope: !24, inlinedAt: !28) -!31 = !DILocation(line: 3, column: 15, scope: !24, inlinedAt: !28) -!32 = !DILocalVariable(name: "Var_2", scope: !33, file: !1, line: 5, type: !13) -!33 = distinct !DILexicalBlock(scope: !24, file: !1, line: 4, column: 3) -!34 = !DILocation(line: 5, column: 9, scope: !33, inlinedAt: !28) -!35 = !DILocation(line: 5, column: 17, scope: !33, inlinedAt: !28) -!36 = !DILocation(line: 5, column: 25, scope: !33, inlinedAt: !28) -!37 = !DILocation(line: 5, column: 23, scope: !33, inlinedAt: !28) -!38 = !DILocation(line: 6, column: 13, scope: !33, inlinedAt: !28) -!39 = !DILocation(line: 6, column: 11, scope: !33, inlinedAt: !28) -!40 = !DILocation(line: 8, column: 10, scope: !24, inlinedAt: !28) -!41 = !DILocation(line: 13, column: 5, scope: !10) -!42 = !DILocation(line: 14, column: 10, scope: !10) -!43 = !DILocation(line: 14, column: 3, scope: !10) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-44884-clang.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-44884-clang.ll deleted file mode 100644 index 3521346cd5c4c..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-44884-clang.ll +++ /dev/null @@ -1,98 +0,0 @@ -; ModuleID = 'pr-44884.cpp' -source_filename = "pr-44884.cpp" -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux" - -; Function Attrs: mustprogress noinline nounwind optnone uwtable -define dso_local noundef i32 @_Z3barf(float noundef %Input) #0 !dbg !12 { -entry: - %Input.addr = alloca float, align 4 - store float %Input, ptr %Input.addr, align 4 - #dbg_declare(ptr %Input.addr, !17, !DIExpression(), !18) - %0 = load float, ptr %Input.addr, align 4, !dbg !19 - %conv = fptosi float %0 to i32, !dbg !19 - ret i32 %conv, !dbg !20 -} - -; Function Attrs: mustprogress noinline nounwind optnone uwtable -define dso_local noundef i32 @_Z3fooc(i8 noundef signext %Param) #0 !dbg !21 { -entry: - %Param.addr = alloca i8, align 1 - %Value = alloca i32, align 4 - %Added = alloca float, align 4 - store i8 %Param, ptr %Param.addr, align 1 - #dbg_declare(ptr %Param.addr, !26, !DIExpression(), !27) - #dbg_declare(ptr %Value, !28, !DIExpression(), !30) - %0 = load i8, ptr %Param.addr, align 1, !dbg !31 - %conv = sext i8 %0 to i32, !dbg !31 - store i32 %conv, ptr %Value, align 4, !dbg !30 - #dbg_declare(ptr %Added, !32, !DIExpression(), !36) - %1 = load i32, ptr %Value, align 4, !dbg !37 - %2 = load i8, ptr %Param.addr, align 1, !dbg !38 - %conv1 = sext i8 %2 to i32, !dbg !38 - %add = add nsw i32 %1, %conv1, !dbg !39 - %conv2 = sitofp i32 %add to float, !dbg !37 - store float %conv2, ptr %Added, align 4, !dbg !36 - %3 = load float, ptr %Added, align 4, !dbg !40 - %call = call noundef i32 @_Z3barf(float noundef %3), !dbg !41 - store i32 %call, ptr %Value, align 4, !dbg !42 - %4 = load i32, ptr %Value, align 4, !dbg !43 - %5 = load i8, ptr %Param.addr, align 1, !dbg !44 - %conv3 = sext i8 %5 to i32, !dbg !44 - %add4 = add nsw i32 %4, %conv3, !dbg !45 - ret i32 %add4, !dbg !46 -} - -attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!4, !5, !6, !7, !8, !9, !10} -!llvm.ident = !{!11} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "pr-44884.cpp", directory: "/data/projects/scripts/regression-suite/input/general") -!2 = !{!3} -!3 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!4 = !{i32 7, !"Dwarf Version", i32 5} -!5 = !{i32 2, !"Debug Info Version", i32 3} -!6 = !{i32 1, !"wchar_size", i32 4} -!7 = !{i32 8, !"PIC Level", i32 2} -!8 = !{i32 7, !"PIE Level", i32 2} -!9 = !{i32 7, !"uwtable", i32 2} -!10 = !{i32 7, !"frame-pointer", i32 2} -!11 = !{!"clang version 20.0.0"} -!12 = distinct !DISubprogram(name: "bar", linkageName: "_Z3barf", scope: !1, file: !1, line: 1, type: !13, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !16) -!13 = !DISubroutineType(types: !14) -!14 = !{!3, !15} -!15 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float) -!16 = !{} -!17 = !DILocalVariable(name: "Input", arg: 1, scope: !12, file: !1, line: 1, type: !15) -!18 = !DILocation(line: 1, column: 15, scope: !12) -!19 = !DILocation(line: 1, column: 36, scope: !12) -!20 = !DILocation(line: 1, column: 24, scope: !12) -!21 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooc", scope: !1, file: !1, line: 3, type: !22, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !16) -!22 = !DISubroutineType(types: !23) -!23 = !{!24, !25} -!24 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!25 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) -!26 = !DILocalVariable(name: "Param", arg: 1, scope: !21, file: !1, line: 3, type: !25) -!27 = !DILocation(line: 3, column: 19, scope: !21) -!28 = !DILocalVariable(name: "Value", scope: !21, file: !1, line: 5, type: !29) -!29 = !DIDerivedType(tag: DW_TAG_typedef, name: "INT", scope: !21, file: !1, line: 4, baseType: !3) -!30 = !DILocation(line: 5, column: 7, scope: !21) -!31 = !DILocation(line: 5, column: 15, scope: !21) -!32 = !DILocalVariable(name: "Added", scope: !33, file: !1, line: 9, type: !35) -!33 = distinct !DILexicalBlock(scope: !34, file: !1, line: 8, column: 5) -!34 = distinct !DILexicalBlock(scope: !21, file: !1, line: 6, column: 3) -!35 = !DIDerivedType(tag: DW_TAG_typedef, name: "FLOAT", scope: !21, file: !1, line: 7, baseType: !15) -!36 = !DILocation(line: 9, column: 13, scope: !33) -!37 = !DILocation(line: 9, column: 21, scope: !33) -!38 = !DILocation(line: 9, column: 29, scope: !33) -!39 = !DILocation(line: 9, column: 27, scope: !33) -!40 = !DILocation(line: 10, column: 19, scope: !33) -!41 = !DILocation(line: 10, column: 15, scope: !33) -!42 = !DILocation(line: 10, column: 13, scope: !33) -!43 = !DILocation(line: 13, column: 10, scope: !21) -!44 = !DILocation(line: 13, column: 18, scope: !21) -!45 = !DILocation(line: 13, column: 16, scope: !21) -!46 = !DILocation(line: 13, column: 3, scope: !21) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-46466-clang.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-46466-clang.ll deleted file mode 100644 index ab4002d52e146..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/pr-46466-clang.ll +++ /dev/null @@ -1,44 +0,0 @@ -; ModuleID = 'pr-46466.cpp' -source_filename = "pr-46466.cpp" -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux" - -%struct.Struct = type { i8 } - -@S = dso_local global %struct.Struct zeroinitializer, align 1, !dbg !0 - -; Function Attrs: mustprogress noinline nounwind optnone uwtable -define dso_local noundef i32 @_Z4testv() #0 !dbg !18 { -entry: - ret i32 1, !dbg !22 -} - -attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } - -!llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!10, !11, !12, !13, !14, !15, !16} -!llvm.ident = !{!17} - -!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) -!1 = distinct !DIGlobalVariable(name: "S", scope: !2, file: !3, line: 8, type: !5, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 20.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "pr-46466.cpp", directory: "/data/projects/scripts/regression-suite/input/general") -!4 = !{!0} -!5 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Struct", file: !3, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !6, identifier: "_ZTS6Struct") -!6 = !{!7} -!7 = !DIDerivedType(tag: DW_TAG_member, name: "U", scope: !5, file: !3, line: 5, baseType: !8, size: 8) -!8 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "Union", scope: !5, file: !3, line: 2, size: 8, flags: DIFlagTypePassByValue, elements: !9, identifier: "_ZTSN6Struct5UnionE") -!9 = !{} -!10 = !{i32 7, !"Dwarf Version", i32 5} -!11 = !{i32 2, !"Debug Info Version", i32 3} -!12 = !{i32 1, !"wchar_size", i32 4} -!13 = !{i32 8, !"PIC Level", i32 2} -!14 = !{i32 7, !"PIE Level", i32 2} -!15 = !{i32 7, !"uwtable", i32 2} -!16 = !{i32 7, !"frame-pointer", i32 2} -!17 = !{!"clang version 20.0.0"} -!18 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !3, file: !3, line: 9, type: !19, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2) -!19 = !DISubroutineType(types: !20) -!20 = !{!21} -!21 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!22 = !DILocation(line: 10, column: 3, scope: !18) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/test-clang-intrinsics.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/test-clang-intrinsics.ll deleted file mode 100644 index ae48abf25647c..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/test-clang-intrinsics.ll +++ /dev/null @@ -1,87 +0,0 @@ -; ModuleID = 'test.cpp' -source_filename = "test.cpp" -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux" - -; Function Attrs: mustprogress noinline nounwind optnone uwtable -define dso_local noundef i32 @_Z3fooPKijb(ptr noundef %ParamPtr, i32 noundef %ParamUnsigned, i1 noundef zeroext %ParamBool) #0 !dbg !10 { -entry: - %retval = alloca i32, align 4 - %ParamPtr.addr = alloca ptr, align 8 - %ParamUnsigned.addr = alloca i32, align 4 - %ParamBool.addr = alloca i8, align 1 - %CONSTANT = alloca i32, align 4 - store ptr %ParamPtr, ptr %ParamPtr.addr, align 8 - tail call void @llvm.dbg.declare(metadata ptr %ParamPtr.addr, metadata !20, metadata !DIExpression()), !dbg !21 - store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4 - tail call void @llvm.dbg.declare(metadata ptr %ParamUnsigned.addr, metadata !22, metadata !DIExpression()), !dbg !23 - %storedv = zext i1 %ParamBool to i8 - store i8 %storedv, ptr %ParamBool.addr, align 1 - tail call void @llvm.dbg.declare(metadata ptr %ParamBool.addr, metadata !24, metadata !DIExpression()), !dbg !25 - %0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26 - %loadedv = trunc i8 %0 to i1, !dbg !26 - br i1 %loadedv, label %if.then, label %if.end, !dbg !26 - -if.then: ; preds = %entry - tail call void @llvm.dbg.declare(metadata ptr %CONSTANT, metadata !28, metadata !DIExpression()), !dbg !32 - store i32 7, ptr %CONSTANT, align 4, !dbg !32 - store i32 7, ptr %retval, align 4, !dbg !33 - br label %return, !dbg !33 - -if.end: ; preds = %entry - %1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34 - store i32 %1, ptr %retval, align 4, !dbg !35 - br label %return, !dbg !35 - -return: ; preds = %if.end, %if.then - %2 = load i32, ptr %retval, align 4, !dbg !36 - ret i32 %2, !dbg !36 -} - -; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - -attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } -attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} -!llvm.ident = !{!9} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "test.cpp", directory: "/data/projects/scripts/regression-suite/input/general") -!2 = !{i32 7, !"Dwarf Version", i32 5} -!3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = !{i32 1, !"wchar_size", i32 4} -!5 = !{i32 8, !"PIC Level", i32 2} -!6 = !{i32 7, !"PIE Level", i32 2} -!7 = !{i32 7, !"uwtable", i32 2} -!8 = !{i32 7, !"frame-pointer", i32 2} -!9 = !{!"clang version 20.0.0"} -!10 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooPKijb", scope: !1, file: !1, line: 2, type: !11, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !19) -!11 = !DISubroutineType(types: !12) -!12 = !{!13, !14, !17, !18} -!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "INTPTR", file: !1, line: 1, baseType: !15) -!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) -!16 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13) -!17 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!18 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean) -!19 = !{} -!20 = !DILocalVariable(name: "ParamPtr", arg: 1, scope: !10, file: !1, line: 2, type: !14) -!21 = !DILocation(line: 2, column: 16, scope: !10) -!22 = !DILocalVariable(name: "ParamUnsigned", arg: 2, scope: !10, file: !1, line: 2, type: !17) -!23 = !DILocation(line: 2, column: 35, scope: !10) -!24 = !DILocalVariable(name: "ParamBool", arg: 3, scope: !10, file: !1, line: 2, type: !18) -!25 = !DILocation(line: 2, column: 55, scope: !10) -!26 = !DILocation(line: 3, column: 7, scope: !27) -!27 = distinct !DILexicalBlock(scope: !10, file: !1, line: 3, column: 7) -!28 = !DILocalVariable(name: "CONSTANT", scope: !29, file: !1, line: 5, type: !30) -!29 = distinct !DILexicalBlock(scope: !27, file: !1, line: 3, column: 18) -!30 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !31) -!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "INTEGER", scope: !10, file: !1, line: 4, baseType: !13) -!32 = !DILocation(line: 5, column: 19, scope: !29) -!33 = !DILocation(line: 6, column: 5, scope: !29) -!34 = !DILocation(line: 8, column: 10, scope: !10) -!35 = !DILocation(line: 8, column: 3, scope: !10) -!36 = !DILocation(line: 9, column: 1, scope: !10) diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/test-clang.ll b/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/test-clang.ll deleted file mode 100644 index 610be460b9fa9..0000000000000 --- a/llvm/test/tools/llvm-debuginfo-analyzer/IR/Inputs/test-clang.ll +++ /dev/null @@ -1,83 +0,0 @@ -; ModuleID = 'test.cpp' -source_filename = "test.cpp" -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux" - -; Function Attrs: mustprogress noinline nounwind optnone uwtable -define dso_local noundef i32 @_Z3fooPKijb(ptr noundef %ParamPtr, i32 noundef %ParamUnsigned, i1 noundef zeroext %ParamBool) #0 !dbg !10 { -entry: - %retval = alloca i32, align 4 - %ParamPtr.addr = alloca ptr, align 8 - %ParamUnsigned.addr = alloca i32, align 4 - %ParamBool.addr = alloca i8, align 1 - %CONSTANT = alloca i32, align 4 - store ptr %ParamPtr, ptr %ParamPtr.addr, align 8 - #dbg_declare(ptr %ParamPtr.addr, !20, !DIExpression(), !21) - store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4 - #dbg_declare(ptr %ParamUnsigned.addr, !22, !DIExpression(), !23) - %storedv = zext i1 %ParamBool to i8 - store i8 %storedv, ptr %ParamBool.addr, align 1 - #dbg_declare(ptr %ParamBool.addr, !24, !DIExpression(), !25) - %0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26 - %loadedv = trunc i8 %0 to i1, !dbg !26 - br i1 %loadedv, label %if.then, label %if.end, !dbg !26 - -if.then: ; preds = %entry - #dbg_declare(ptr %CONSTANT, !28, !DIExpression(), !32) - store i32 7, ptr %CONSTANT, align 4, !dbg !32 - store i32 7, ptr %retval, align 4, !dbg !33 - br label %return, !dbg !33 - -if.end: ; preds = %entry - %1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34 - store i32 %1, ptr %retval, align 4, !dbg !35 - br label %return, !dbg !35 - -return: ; preds = %if.end, %if.then - %2 = load i32, ptr %retval, align 4, !dbg !36 - ret i32 %2, !dbg !36 -} - -attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} -!llvm.ident = !{!9} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "test.cpp", directory: "/data/projects/scripts/regression-suite/input/general") -!2 = !{i32 7, !"Dwarf Version", i32 5} -!3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = !{i32 1, !"wchar_size", i32 4} -!5 = !{i32 8, !"PIC Level", i32 2} -!6 = !{i32 7, !"PIE Level", i32 2} -!7 = !{i32 7, !"uwtable", i32 2} -!8 = !{i32 7, !"frame-pointer", i32 2} -!9 = !{!"clang version 20.0.0"} -!10 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooPKijb", scope: !1, file: !1, line: 2, type: !11, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !19) -!11 = !DISubroutineType(types: !12) -!12 = !{!13, !14, !17, !18} -!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "INTPTR", file: !1, line: 1, baseType: !15) -!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) -!16 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13) -!17 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!18 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean) -!19 = !{} -!20 = !DILocalVariable(name: "ParamPtr", arg: 1, scope: !10, file: !1, line: 2, type: !14) -!21 = !DILocation(line: 2, column: 16, scope: !10) -!22 = !DILocalVariable(name: "ParamUnsigned", arg: 2, scope: !10, file: !1, line: 2, type: !17) -!23 = !DILocation(line: 2, column: 35, scope: !10) -!24 = !DILocalVariable(name: "ParamBool", arg: 3, scope: !10, file: !1, line: 2, type: !18) -!25 = !DILocation(line: 2, column: 55, scope: !10) -!26 = !DILocation(line: 3, column: 7, scope: !27) -!27 = distinct !DILexicalBlock(scope: !10, file: !1, line: 3, column: 7) -!28 = !DILocalVariable(name: "CONSTANT", scope: !29, file: !1, line: 5, type: !30) -!29 = distinct !DILexicalBlock(scope: !27, file: !1, line: 3, column: 18) -!30 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !31) -!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "INTEGER", scope: !10, file: !1, line: 4, baseType: !13) -!32 = !DILocation(line: 5, column: 19, scope: !29) -!33 = !DILocation(line: 6, column: 5, scope: !29) -!34 = !DILocation(line: 8, column: 10, scope: !10) -!35 = !DILocation(line: 8, column: 3, scope: !10) -!36 = !DILocation(line: 9, column: 1, scope: !10) diff --git a/llvm/tools/llvm-debuginfo-analyzer/CMakeLists.txt b/llvm/tools/llvm-debuginfo-analyzer/CMakeLists.txt index 31b3157ec85e6..3e16d81abe35c 100644 --- a/llvm/tools/llvm-debuginfo-analyzer/CMakeLists.txt +++ b/llvm/tools/llvm-debuginfo-analyzer/CMakeLists.txt @@ -3,7 +3,6 @@ set(LLVM_LINK_COMPONENTS AllTargetsDisassemblers AllTargetsInfos BinaryFormat - Core DebugInfoCodeView DebugInfoLogicalView DebugInfoPDB @@ -11,7 +10,6 @@ set(LLVM_LINK_COMPONENTS MCDisassembler Object Support - TransformUtils ) add_llvm_tool(llvm-debuginfo-analyzer diff --git a/llvm/unittests/DebugInfo/LogicalView/CMakeLists.txt b/llvm/unittests/DebugInfo/LogicalView/CMakeLists.txt index 5507e8261a418..a8fd83e9b7b6e 100644 --- a/llvm/unittests/DebugInfo/LogicalView/CMakeLists.txt +++ b/llvm/unittests/DebugInfo/LogicalView/CMakeLists.txt @@ -1,7 +1,6 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} AsmPrinter - Core DebugInfoDWARF DebugInfoLogicalView MC @@ -9,7 +8,6 @@ set(LLVM_LINK_COMPONENTS Object ObjectYAML TargetParser - TransformUtils ) add_llvm_unittest_with_input_files(DebugInfoLogicalViewTests @@ -20,7 +18,6 @@ add_llvm_unittest_with_input_files(DebugInfoLogicalViewTests CompareElementsTest.cpp DWARFGeneratedTest.cpp DWARFReaderTest.cpp - IRReaderTest.cpp SelectElementsTest.cpp LocationRangesTest.cpp LogicalElementsTest.cpp diff --git a/llvm/unittests/DebugInfo/LogicalView/IRReaderTest.cpp b/llvm/unittests/DebugInfo/LogicalView/IRReaderTest.cpp deleted file mode 100644 index ad389df01d97a..0000000000000 --- a/llvm/unittests/DebugInfo/LogicalView/IRReaderTest.cpp +++ /dev/null @@ -1,362 +0,0 @@ -//===- llvm/unittest/DebugInfo/LogicalView/IRReaderTest.cpp ---------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/DebugInfo/LogicalView/Core/LVCompare.h" -#include "llvm/DebugInfo/LogicalView/Core/LVLine.h" -#include "llvm/DebugInfo/LogicalView/Core/LVScope.h" -#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" -#include "llvm/DebugInfo/LogicalView/Core/LVType.h" -#include "llvm/DebugInfo/LogicalView/LVReaderHandler.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Support/InitLLVM.h" -#include "llvm/Support/ScopedPrinter.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/ToolOutputFile.h" -#include "llvm/Testing/Support/Error.h" - -#include "gtest/gtest.h" - -using namespace llvm; -using namespace llvm::logicalview; - -extern const char *TestMainArgv0; - -namespace { - -const char *IrClang = "test-clang.ll"; -const char *BcClang = "test-clang.bc"; -const char *DwarfGcc = "test-dwarf-gcc.o"; - -// Helper function to get the first compile unit. -LVScopeCompileUnit *getFirstCompileUnit(LVScopeRoot *Root) { - EXPECT_NE(Root, nullptr); - const LVScopes *CompileUnits = Root->getScopes(); - EXPECT_NE(CompileUnits, nullptr); - EXPECT_EQ(CompileUnits->size(), 1u); - - LVScopes::const_iterator Iter = CompileUnits->begin(); - EXPECT_NE(Iter, nullptr); - LVScopeCompileUnit *CompileUnit = static_cast(*Iter); - EXPECT_NE(CompileUnit, nullptr); - return CompileUnit; -} - -// Helper function to create a reader. -std::unique_ptr createReader(LVReaderHandler &ReaderHandler, - SmallString<128> &InputsDir, - StringRef Filename) { - SmallString<128> ObjectName(InputsDir); - llvm::sys::path::append(ObjectName, Filename); - - Expected> ReaderOrErr = - ReaderHandler.createReader(std::string(ObjectName)); - EXPECT_THAT_EXPECTED(ReaderOrErr, Succeeded()); - std::unique_ptr Reader = std::move(*ReaderOrErr); - EXPECT_NE(Reader, nullptr); - return Reader; -} - -// Check the logical elements basic properties. -void checkElementProperties(LVReader *Reader) { - LVScopeRoot *Root = Reader->getScopesRoot(); - LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root); - - EXPECT_EQ(Root->getFileFormatName(), "LLVM IR"); - EXPECT_EQ(Root->getName(), IrClang); - - EXPECT_EQ(CompileUnit->getBaseAddress(), 0u); - EXPECT_TRUE(CompileUnit->getProducer().starts_with("clang")); - EXPECT_EQ(CompileUnit->getName(), "test.cpp"); - - EXPECT_EQ(CompileUnit->lineCount(), 0u); - EXPECT_EQ(CompileUnit->scopeCount(), 1u); - EXPECT_EQ(CompileUnit->symbolCount(), 0u); - EXPECT_EQ(CompileUnit->typeCount(), 7u); - EXPECT_EQ(CompileUnit->rangeCount(), 4u); - - const LVLocations *Ranges = CompileUnit->getRanges(); - ASSERT_NE(Ranges, nullptr); - ASSERT_EQ(Ranges->size(), 4u); - LVLocations::const_iterator IterLocation = Ranges->begin(); - LVLocation *Location = (*IterLocation); - EXPECT_STREQ(Location->getIntervalInfo().c_str(), - "{Range} Lines 2:2 [0x0000000000:0x0000000023]"); - - LVRange RangeList; - CompileUnit->getRanges(RangeList); - - const LVRangeEntries &RangeEntries = RangeList.getEntries(); - ASSERT_EQ(RangeEntries.size(), 4u); - LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin(); - LVRangeEntry RangeEntry = *IterRanges; - EXPECT_EQ(RangeEntry.lower(), 0u); - EXPECT_EQ(RangeEntry.upper(), 0x23u); - EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u); - EXPECT_EQ(RangeEntry.scope()->getName(), "test.cpp"); - EXPECT_EQ(RangeEntry.scope()->getOffset(), 0x04u); - - ++IterRanges; - RangeEntry = *IterRanges; - EXPECT_EQ(RangeEntry.lower(), 0x3cu); - EXPECT_EQ(RangeEntry.upper(), 0x4fu); - EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u); - EXPECT_EQ(RangeEntry.scope()->getName(), "test.cpp"); - EXPECT_EQ(RangeEntry.scope()->getOffset(), 0x04u); - - const LVPublicNames &PublicNames = CompileUnit->getPublicNames(); - ASSERT_EQ(PublicNames.size(), 1u); - LVPublicNames::const_iterator IterNames = PublicNames.cbegin(); - LVScope *Function = (*IterNames).first; - EXPECT_EQ(Function->getName(), "foo"); - EXPECT_EQ(Function->getLineNumber(), 2u); - LVNameInfo NameInfo = (*IterNames).second; - EXPECT_EQ(NameInfo.first, 0u); - EXPECT_EQ(NameInfo.second, 0x23u); - - // Lines (debug and assembler) for 'foo'. - const LVLines *Lines = Function->getLines(); - ASSERT_NE(Lines, nullptr); - ASSERT_EQ(Lines->size(), 0x1au); -} - -// Check the logical elements selection. -void checkElementSelection(LVReader *Reader) { - LVScopeRoot *Root = Reader->getScopesRoot(); - LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root); - - // Get the matched elements. - LVElements MatchedElements = CompileUnit->getMatchedElements(); - std::map MapElements; - for (LVElement *Element : MatchedElements) - MapElements[Element->getOffset()] = Element; - ASSERT_EQ(MapElements.size(), 0x0du); - - LVElement *Element = MapElements[0x0000000008]; // 'foo' - ASSERT_NE(Element, nullptr); - EXPECT_NE(Element->getName().find("foo"), StringRef::npos); - EXPECT_EQ(Element->getIsScope(), 1); - - Element = MapElements[0x0000000010]; // 'CONSTANT' - ASSERT_NE(Element, nullptr); - EXPECT_NE(Element->getName().find("CONSTANT"), StringRef::npos); - EXPECT_EQ(Element->getIsSymbol(), 1); - - Element = MapElements[0x0000000028]; // 'INTPTR' - ASSERT_NE(Element, nullptr); - EXPECT_NE(Element->getName().find("INTPTR"), StringRef::npos); - EXPECT_EQ(Element->getIsType(), 1); - - Element = MapElements[0x0000000020]; // 'INTEGER' - ASSERT_NE(Element, nullptr); - EXPECT_NE(Element->getName().find("INTEGER"), StringRef::npos); - EXPECT_EQ(Element->getIsType(), 1); - - Element = MapElements[0x0000000040]; // 'store i32 %1, ptr %retval ...' - ASSERT_NE(Element, nullptr); - EXPECT_NE(Element->getName().find("store i32"), StringRef::npos); - EXPECT_EQ(Element->getIsLine(), 1); - - // Get the parents for the matched elements. - LVScopes MatchedScopes = CompileUnit->getMatchedScopes(); - std::set SetScopes; - for (LVScope *Scope : MatchedScopes) - SetScopes.insert(Scope->getOffset()); - std::set::iterator Iter; - ASSERT_EQ(SetScopes.size(), 3u); - - Iter = SetScopes.find(0x0000000004); // CompileUnit <- 'foo' - EXPECT_NE(Iter, SetScopes.end()); - Iter = SetScopes.find(0x0000000008); // Function <- 'store i32 %1, ptr ...' - EXPECT_NE(Iter, SetScopes.end()); - Iter = SetScopes.find(0x000000000c); // LexicalScope <- 'INTEGER' - EXPECT_NE(Iter, SetScopes.end()); -} - -// Check the logical elements comparison. -void checkElementComparison(LVReader *Reference, LVReader *Target) { - LVCompare Compare(nulls()); - Error Err = Compare.execute(Reference, Target); - ASSERT_THAT_ERROR(std::move(Err), Succeeded()); - - // Get comparison table. - LVPassTable PassTable = Compare.getPassTable(); - ASSERT_EQ(PassTable.size(), 6u); - - LVReader *Reader; - LVElement *Element; - LVComparePass Pass; - - // Reference: Missing DebugLine - std::tie(Reader, Element, Pass) = PassTable[0]; - ASSERT_NE(Reader, nullptr); - ASSERT_NE(Element, nullptr); - EXPECT_EQ(Reader, Reference); - EXPECT_EQ(Element->getLevel(), 3u); - EXPECT_EQ(Element->getLineNumber(), 0u); - EXPECT_EQ(Element->getName(), ""); - EXPECT_EQ(Pass, LVComparePass::Missing); - - // Reference: Missing Variable 'CONSTANT' - std::tie(Reader, Element, Pass) = PassTable[1]; - ASSERT_NE(Reader, nullptr); - ASSERT_NE(Element, nullptr); - EXPECT_EQ(Reader, Reference); - EXPECT_EQ(Element->getLevel(), 4u); - EXPECT_EQ(Element->getLineNumber(), 5u); - EXPECT_EQ(Element->getName(), "CONSTANT"); - EXPECT_EQ(Pass, LVComparePass::Missing); - - // Reference: Missing TypeDefinition 'INTEGER' - std::tie(Reader, Element, Pass) = PassTable[2]; - ASSERT_NE(Reader, nullptr); - ASSERT_NE(Element, nullptr); - EXPECT_EQ(Reader, Reference); - EXPECT_EQ(Element->getLevel(), 3u); - EXPECT_EQ(Element->getLineNumber(), 4u); - EXPECT_EQ(Element->getName(), "INTEGER"); - EXPECT_EQ(Pass, LVComparePass::Missing); - - // Target: Added Variable 'CONSTANT' - std::tie(Reader, Element, Pass) = PassTable[3]; - ASSERT_NE(Reader, nullptr); - ASSERT_NE(Element, nullptr); - EXPECT_EQ(Reader, Target); - EXPECT_EQ(Element->getLevel(), 4u); - EXPECT_EQ(Element->getLineNumber(), 5u); - EXPECT_EQ(Element->getName(), "CONSTANT"); - EXPECT_EQ(Pass, LVComparePass::Added); - - // Target: Added TypeDefinition 'INTEGER' - std::tie(Reader, Element, Pass) = PassTable[4]; - ASSERT_NE(Reader, nullptr); - ASSERT_NE(Element, nullptr); - EXPECT_EQ(Reader, Target); - EXPECT_EQ(Element->getLevel(), 4u); - EXPECT_EQ(Element->getLineNumber(), 4u); - EXPECT_EQ(Element->getName(), "INTEGER"); - EXPECT_EQ(Pass, LVComparePass::Added); - - // Target: Added DebugLine - std::tie(Reader, Element, Pass) = PassTable[5]; - ASSERT_NE(Reader, nullptr); - ASSERT_NE(Element, nullptr); - EXPECT_EQ(Reader, Target); - EXPECT_EQ(Element->getLevel(), 2u); - EXPECT_EQ(Element->getLineNumber(), 9u); - EXPECT_EQ(Element->getName(), ""); - EXPECT_EQ(Pass, LVComparePass::Added); -} - -// Logical elements properties. -void elementProperties(SmallString<128> &InputsDir) { - // Reader options. - LVOptions ReaderOptions; - ReaderOptions.setAttributeOffset(); - ReaderOptions.setAttributeFormat(); - ReaderOptions.setAttributeFilename(); - ReaderOptions.setAttributeProducer(); - ReaderOptions.setAttributePublics(); - ReaderOptions.setAttributeRange(); - ReaderOptions.setAttributeLocation(); - ReaderOptions.setPrintAll(); - ReaderOptions.resolveDependencies(); - - std::vector Objects; - ScopedPrinter W(outs()); - LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); - - // Check logical elements properties. - std::unique_ptr Reader = - createReader(ReaderHandler, InputsDir, IrClang); - checkElementProperties(Reader.get()); -} - -// Logical elements selection. -void elementSelection(SmallString<128> &InputsDir) { - // Reader options. - LVOptions ReaderOptions; - ReaderOptions.setAttributeOffset(); - ReaderOptions.setPrintAll(); - - ReaderOptions.setSelectIgnoreCase(); - ReaderOptions.setSelectUseRegex(); - - ReaderOptions.setReportList(); // Matched elements. - ReaderOptions.setReportView(); // Parents for matched elements. - - // Add patterns. - ReaderOptions.Select.Generic.insert("foo"); - ReaderOptions.Select.Generic.insert("store i32 %"); - ReaderOptions.Select.Generic.insert("INT[a-z]*"); - ReaderOptions.Select.Generic.insert("CONSTANT"); - - ReaderOptions.resolveDependencies(); - - std::vector Objects; - ScopedPrinter W(outs()); - LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); - - // Check logical elements selection. - std::unique_ptr Reader = - createReader(ReaderHandler, InputsDir, BcClang); - checkElementSelection(Reader.get()); -} - -// Compare logical elements. -void compareElements(SmallString<128> &InputsDir) { - // Reader options. - LVOptions ReaderOptions; - ReaderOptions.setAttributeOffset(); - ReaderOptions.setPrintLines(); - ReaderOptions.setPrintSymbols(); - ReaderOptions.setPrintTypes(); - ReaderOptions.setCompareLines(); - ReaderOptions.setCompareSymbols(); - ReaderOptions.setCompareTypes(); - - ReaderOptions.resolveDependencies(); - - std::vector Objects; - ScopedPrinter W(outs()); - LVReaderHandler ReaderHandler(Objects, W, ReaderOptions); - - // Check logical comparison. - std::unique_ptr Reference = - createReader(ReaderHandler, InputsDir, BcClang); - std::unique_ptr Target = - createReader(ReaderHandler, InputsDir, DwarfGcc); - checkElementComparison(Reference.get(), Target.get()); -} - -TEST(LogicalViewTest, IRReader) { - // Initialize targets and assembly printers/parsers. - llvm::InitializeAllTargetInfos(); - llvm::InitializeAllTargetMCs(); - InitializeAllDisassemblers(); - - // This test requires a x86-registered-target. - Triple TT; - TT.setArch(Triple::x86_64); - TT.setVendor(Triple::UnknownVendor); - TT.setOS(Triple::UnknownOS); - - std::string TargetLookupError; - if (!TargetRegistry::lookupTarget(TT, TargetLookupError)) - GTEST_SKIP(); - - SmallString<128> InputsDir = unittest::getInputFileDirectory(TestMainArgv0); - - // Logical elements general properties and selection. - elementProperties(InputsDir); - elementSelection(InputsDir); - - // Compare logical elements. - compareElements(InputsDir); -} - -} // namespace diff --git a/llvm/unittests/DebugInfo/LogicalView/Inputs/README.md b/llvm/unittests/DebugInfo/LogicalView/Inputs/README.md index e3d1d27ebb77a..ab194ffc1010c 100644 --- a/llvm/unittests/DebugInfo/LogicalView/Inputs/README.md +++ b/llvm/unittests/DebugInfo/LogicalView/Inputs/README.md @@ -45,15 +45,3 @@ This file is a static library embedding the **test-codeview-msvc.o** object file It is generated by the "lib.exe" tool shipped with MSVC compiler. ```lib.exe /OUT:test-codeview-msvc.lib test-codeview-msvc.o``` - -# IR textual representation (.ll) and bitcode (.bc) files (x86_64-unknown-linux): - -## test-clang.ll - -```clang --target=x86_64-linux -S -w -emit-llvm -g test.cpp -o test-clang.ll``` - -## test-clang.bc - -```clang --target=x86_64-linux -S -w -emit-llvm -g test.cpp -o test-clang.ll``` - -```llvm-as test-clang.ll -o test-clang.bc``` diff --git a/llvm/unittests/DebugInfo/LogicalView/Inputs/test-clang.bc b/llvm/unittests/DebugInfo/LogicalView/Inputs/test-clang.bc deleted file mode 100644 index 841c6b0ddcf13..0000000000000 Binary files a/llvm/unittests/DebugInfo/LogicalView/Inputs/test-clang.bc and /dev/null differ diff --git a/llvm/unittests/DebugInfo/LogicalView/Inputs/test-clang.ll b/llvm/unittests/DebugInfo/LogicalView/Inputs/test-clang.ll deleted file mode 100644 index a2277f5554232..0000000000000 --- a/llvm/unittests/DebugInfo/LogicalView/Inputs/test-clang.ll +++ /dev/null @@ -1,83 +0,0 @@ -; ModuleID = 'test.cpp' -source_filename = "test.cpp" -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux" - -; Function Attrs: mustprogress noinline nounwind optnone uwtable -define dso_local noundef i32 @_Z3fooPKijb(ptr noundef %ParamPtr, i32 noundef %ParamUnsigned, i1 noundef zeroext %ParamBool) #0 !dbg !10 { -entry: - %retval = alloca i32, align 4 - %ParamPtr.addr = alloca ptr, align 8 - %ParamUnsigned.addr = alloca i32, align 4 - %ParamBool.addr = alloca i8, align 1 - %CONSTANT = alloca i32, align 4 - store ptr %ParamPtr, ptr %ParamPtr.addr, align 8 - #dbg_declare(ptr %ParamPtr.addr, !20, !DIExpression(), !21) - store i32 %ParamUnsigned, ptr %ParamUnsigned.addr, align 4 - #dbg_declare(ptr %ParamUnsigned.addr, !22, !DIExpression(), !23) - %storedv = zext i1 %ParamBool to i8 - store i8 %storedv, ptr %ParamBool.addr, align 1 - #dbg_declare(ptr %ParamBool.addr, !24, !DIExpression(), !25) - %0 = load i8, ptr %ParamBool.addr, align 1, !dbg !26 - %loadedv = trunc i8 %0 to i1, !dbg !26 - br i1 %loadedv, label %if.then, label %if.end, !dbg !26 - -if.then: ; preds = %entry - #dbg_declare(ptr %CONSTANT, !28, !DIExpression(), !32) - store i32 7, ptr %CONSTANT, align 4, !dbg !32 - store i32 7, ptr %retval, align 4, !dbg !33 - br label %return, !dbg !33 - -if.end: ; preds = %entry - %1 = load i32, ptr %ParamUnsigned.addr, align 4, !dbg !34 - store i32 %1, ptr %retval, align 4, !dbg !35 - br label %return, !dbg !35 - -return: ; preds = %if.end, %if.then - %2 = load i32, ptr %retval, align 4, !dbg !36 - ret i32 %2, !dbg !36 -} - -attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} -!llvm.ident = !{!9} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0git (https://github.com/llvm/llvm-project.git 16e45b8fac797c6d4ba161228b54665492204a9d)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "test.cpp", directory: "X:\\scripts\\regression-suite\\input\\general", checksumkind: CSK_MD5, checksum: "969bd5763e7769d696eb29bdc55331d7") -!2 = !{i32 7, !"Dwarf Version", i32 5} -!3 = !{i32 2, !"Debug Info Version", i32 3} -!4 = !{i32 1, !"wchar_size", i32 4} -!5 = !{i32 8, !"PIC Level", i32 2} -!6 = !{i32 7, !"PIE Level", i32 2} -!7 = !{i32 7, !"uwtable", i32 2} -!8 = !{i32 7, !"frame-pointer", i32 2} -!9 = !{!"clang version 20.0.0git (https://github.com/llvm/llvm-project.git 16e45b8fac797c6d4ba161228b54665492204a9d)"} -!10 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooPKijb", scope: !1, file: !1, line: 2, type: !11, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !19) -!11 = !DISubroutineType(types: !12) -!12 = !{!13, !14, !17, !18} -!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "INTPTR", file: !1, line: 1, baseType: !15) -!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) -!16 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !13) -!17 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) -!18 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean) -!19 = !{} -!20 = !DILocalVariable(name: "ParamPtr", arg: 1, scope: !10, file: !1, line: 2, type: !14) -!21 = !DILocation(line: 2, column: 16, scope: !10) -!22 = !DILocalVariable(name: "ParamUnsigned", arg: 2, scope: !10, file: !1, line: 2, type: !17) -!23 = !DILocation(line: 2, column: 35, scope: !10) -!24 = !DILocalVariable(name: "ParamBool", arg: 3, scope: !10, file: !1, line: 2, type: !18) -!25 = !DILocation(line: 2, column: 55, scope: !10) -!26 = !DILocation(line: 3, column: 7, scope: !27) -!27 = distinct !DILexicalBlock(scope: !10, file: !1, line: 3, column: 7) -!28 = !DILocalVariable(name: "CONSTANT", scope: !29, file: !1, line: 5, type: !30) -!29 = distinct !DILexicalBlock(scope: !27, file: !1, line: 3, column: 18) -!30 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !31) -!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "INTEGER", scope: !10, file: !1, line: 4, baseType: !13) -!32 = !DILocation(line: 5, column: 19, scope: !29) -!33 = !DILocation(line: 6, column: 5, scope: !29) -!34 = !DILocation(line: 8, column: 10, scope: !10) -!35 = !DILocation(line: 8, column: 3, scope: !10) -!36 = !DILocation(line: 9, column: 1, scope: !10)