diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -5200,21 +5200,22 @@ DICompileUnit """"""""""""" -``DICompileUnit`` nodes represent a compile unit. The ``enums:``, -``retainedTypes:``, ``globals:``, ``imports:`` and ``macros:`` fields are tuples -containing the debug info to be emitted along with the compile unit, regardless -of code optimizations (some nodes are only emitted if there are references to -them from instructions). The ``debugInfoForProfiling:`` field is a boolean -indicating whether or not line-table discriminators are updated to provide -more-accurate debug info for profiling results. +``DICompileUnit`` nodes represent a compile unit. ``DICompileUnit`` nodes must +be ``distinct``. The ``enums:``, ``retainedTypes:``, ``globals:``, ``imports:`` +and ``macros:`` fields are tuples containing the debug info to be emitted along +with the compile unit, regardless of code optimizations (some nodes are only +emitted if there are references to them from instructions). The +``debugInfoForProfiling:`` field is a boolean indicating whether or not +line-table discriminators are updated to provide more-accurate debug info for +profiling results. .. code-block:: text - !0 = !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", - isOptimized: true, flags: "-O2", runtimeVersion: 2, - splitDebugFilename: "abc.debug", emissionKind: FullDebug, - enums: !2, retainedTypes: !3, globals: !4, imports: !5, - macros: !6, dwoId: 0x0abcd) + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", + isOptimized: true, flags: "-O2", runtimeVersion: 2, + splitDebugFilename: "abc.debug", emissionKind: FullDebug, + enums: !2, retainedTypes: !3, globals: !4, imports: !5, + macros: !6, dwoId: 0x0abcd) Compile unit descriptors provide the root scope for objects declared in a specific compilation unit. File descriptors are defined using this scope. These @@ -5625,12 +5626,14 @@ """""""""""" ``DIExpression`` nodes represent expressions that are inspired by the DWARF -expression language. They are used in :ref:`debug intrinsics` -(such as ``llvm.dbg.declare`` and ``llvm.dbg.value``) to describe how the -referenced LLVM variable relates to the source language variable. Debug -intrinsics are interpreted left-to-right: start by pushing the value/address -operand of the intrinsic onto a stack, then repeatedly push and evaluate -opcodes from the DIExpression until the final variable description is produced. +expression language. ``DIExpression`` nodes must not be ``distinct``, and are +canonically printed inline at each use. They are used in :ref:`debug +intrinsics` (such as ``llvm.dbg.declare`` and +``llvm.dbg.value``) to describe how the referenced LLVM variable relates to the +source language variable. Debug intrinsics are interpreted left-to-right: start +by pushing the value/address operand of the intrinsic onto a stack, then +repeatedly push and evaluate opcodes from the DIExpression until the final +variable description is produced. The current supported opcode vocabulary is limited: @@ -5708,23 +5711,23 @@ IR for "*ptr = 4;" -------------- - call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !20) + call void @llvm.dbg.value(metadata i32 4, metadata !17, + metadata !DIExpression(DW_OP_LLVM_implicit_pointer))) !17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5, type: !18) !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) !19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !20 = !DIExpression(DW_OP_LLVM_implicit_pointer)) IR for "**ptr = 4;" -------------- - call void @llvm.dbg.value(metadata i32 4, metadata !17, metadata !21) + call void @llvm.dbg.value(metadata i32 4, metadata !17, + metadata !DIExpression(DW_OP_LLVM_implicit_pointer, + DW_OP_LLVM_implicit_pointer))) !17 = !DILocalVariable(name: "ptr1", scope: !12, file: !3, line: 5, type: !18) !18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) !19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !21 = !DIExpression(DW_OP_LLVM_implicit_pointer, - DW_OP_LLVM_implicit_pointer)) DWARF specifies three kinds of simple location descriptions: Register, memory, and implicit location descriptions. Note that a location description is @@ -5765,12 +5768,13 @@ DIArgList """""""""""" -``DIArgList`` nodes hold a list of constant or SSA value references. These are -used in :ref:`debug intrinsics` (currently only in +``DIArgList`` nodes hold a list of constant or SSA value references. +``DIArgList`` must not be ``distinct``, must only be used as an argument to a +function call, and must appear inline at each use. ``DIArgList`` may refer to +function-local values of the containing function. ``DIArgList`` nodes are used +in :ref:`debug intrinsics` (currently only in ``llvm.dbg.value``) in combination with a ``DIExpression`` that uses the -``DW_OP_LLVM_arg`` operator. Because a DIArgList may refer to local values -within a function, it must only be used as a function argument, must always be -inlined, and cannot appear in named metadata. +``DW_OP_LLVM_arg`` operator. .. code-block:: text diff --git a/llvm/docs/SourceLevelDebugging.rst b/llvm/docs/SourceLevelDebugging.rst --- a/llvm/docs/SourceLevelDebugging.rst +++ b/llvm/docs/SourceLevelDebugging.rst @@ -291,17 +291,17 @@ %X = alloca i32, align 4 %Y = alloca i32, align 4 %Z = alloca i32, align 4 - call void @llvm.dbg.declare(metadata i32* %X, metadata !11, metadata !13), !dbg !14 - store i32 21, i32* %X, align 4, !dbg !14 - call void @llvm.dbg.declare(metadata i32* %Y, metadata !15, metadata !13), !dbg !16 - store i32 22, i32* %Y, align 4, !dbg !16 - call void @llvm.dbg.declare(metadata i32* %Z, metadata !17, metadata !13), !dbg !19 - store i32 23, i32* %Z, align 4, !dbg !19 - %0 = load i32, i32* %X, align 4, !dbg !20 - store i32 %0, i32* %Z, align 4, !dbg !21 - %1 = load i32, i32* %Y, align 4, !dbg !22 - store i32 %1, i32* %X, align 4, !dbg !23 - ret void, !dbg !24 + call void @llvm.dbg.declare(metadata i32* %X, metadata !11, metadata !DIExpression()), !dbg !13 + store i32 21, i32* %X, align 4, !dbg !13 + call void @llvm.dbg.declare(metadata i32* %Y, metadata !14, metadata !DIExpression()), !dbg !15 + store i32 22, i32* %Y, align 4, !dbg !15 + call void @llvm.dbg.declare(metadata i32* %Z, metadata !16, metadata !DIExpression()), !dbg !18 + store i32 23, i32* %Z, align 4, !dbg !18 + %0 = load i32, i32* %X, align 4, !dbg !19 + store i32 %0, i32* %Z, align 4, !dbg !20 + %1 = load i32, i32* %Y, align 4, !dbg !21 + store i32 %1, i32* %X, align 4, !dbg !22 + ret void, !dbg !23 } ; Function Attrs: nounwind readnone @@ -327,18 +327,17 @@ !10 = !{!"clang version 3.7.0 (trunk 231150) (llvm/trunk 231154)"} !11 = !DILocalVariable(name: "X", scope: !4, file: !1, line: 2, type: !12) !12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) - !13 = !DIExpression() - !14 = !DILocation(line: 2, column: 9, scope: !4) - !15 = !DILocalVariable(name: "Y", scope: !4, file: !1, line: 3, type: !12) - !16 = !DILocation(line: 3, column: 9, scope: !4) - !17 = !DILocalVariable(name: "Z", scope: !18, file: !1, line: 5, type: !12) - !18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5) - !19 = !DILocation(line: 5, column: 11, scope: !18) - !20 = !DILocation(line: 6, column: 11, scope: !18) - !21 = !DILocation(line: 6, column: 9, scope: !18) - !22 = !DILocation(line: 8, column: 9, scope: !4) - !23 = !DILocation(line: 8, column: 7, scope: !4) - !24 = !DILocation(line: 9, column: 3, scope: !4) + !13 = !DILocation(line: 2, column: 9, scope: !4) + !14 = !DILocalVariable(name: "Y", scope: !4, file: !1, line: 3, type: !12) + !15 = !DILocation(line: 3, column: 9, scope: !4) + !16 = !DILocalVariable(name: "Z", scope: !17, file: !1, line: 5, type: !12) + !17 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5) + !18 = !DILocation(line: 5, column: 11, scope: !17) + !19 = !DILocation(line: 6, column: 11, scope: !17) + !20 = !DILocation(line: 6, column: 9, scope: !17) + !21 = !DILocation(line: 8, column: 9, scope: !4) + !22 = !DILocation(line: 8, column: 7, scope: !4) + !23 = !DILocation(line: 9, column: 3, scope: !4) This example illustrates a few important details about LLVM debugging @@ -349,21 +348,21 @@ .. code-block:: llvm - call void @llvm.dbg.declare(metadata i32* %X, metadata !11, metadata !13), !dbg !14 + call void @llvm.dbg.declare(metadata i32* %X, metadata !11, metadata !DIExpression()), !dbg !13 ; [debug line = 2:7] [debug variable = X] The first intrinsic ``%llvm.dbg.declare`` encodes debugging information for the -variable ``X``. The metadata ``!dbg !14`` attached to the intrinsic provides +variable ``X``. The metadata ``!dbg !13`` attached to the intrinsic provides scope information for the variable ``X``. .. code-block:: text - !14 = !DILocation(line: 2, column: 9, scope: !4) + !13 = !DILocation(line: 2, column: 9, scope: !4) !4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, retainedNodes: !2) -Here ``!14`` is metadata providing `location information +Here ``!13`` is metadata providing `location information `_. In this example, scope is encoded by ``!4``, a `subprogram descriptor `_. This way the location information attached to the intrinsics indicates that the variable ``X`` is @@ -373,20 +372,20 @@ .. code-block:: llvm - call void @llvm.dbg.declare(metadata i32* %Z, metadata !17, metadata !13), !dbg !19 + call void @llvm.dbg.declare(metadata i32* %Z, metadata !16, metadata !DIExpression()), !dbg !18 ; [debug line = 5:9] [debug variable = Z] The third intrinsic ``%llvm.dbg.declare`` encodes debugging information for -variable ``Z``. The metadata ``!dbg !19`` attached to the intrinsic provides +variable ``Z``. The metadata ``!dbg !18`` attached to the intrinsic provides scope information for the variable ``Z``. .. code-block:: text - !18 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5) - !19 = !DILocation(line: 5, column: 11, scope: !18) + !17 = distinct !DILexicalBlock(scope: !4, file: !1, line: 4, column: 5) + !18 = !DILocation(line: 5, column: 11, scope: !17) -Here ``!19`` indicates that ``Z`` is declared at line number 5 and column -number 11 inside of lexical scope ``!18``. The lexical scope itself resides +Here ``!18`` indicates that ``Z`` is declared at line number 5 and column +number 11 inside of lexical scope ``!17``. The lexical scope itself resides inside of subprogram ``!4`` described above. The scope information attached with each instruction provides a straightforward @@ -802,14 +801,14 @@ br label %exit, !dbg !26 truebr: - call void @llvm.dbg.value(metadata i32 %input, metadata !30, metadata !DIExpression()), !dbg !24 - call void @llvm.dbg.value(metadata i32 1, metadata !23, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.value(metadata i32 %input, metadata !30, metadata !DIExpression()), !dbg !23 + call void @llvm.dbg.value(metadata i32 1, metadata !22, metadata !DIExpression()), !dbg !23 %value1 = add i32 %input, 1 br label %bb1 falsebr: - call void @llvm.dbg.value(metadata i32 %input, metadata !30, metadata !DIExpression()), !dbg !24 - call void @llvm.dbg.value(metadata i32 2, metadata !23, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.value(metadata i32 %input, metadata !30, metadata !DIExpression()), !dbg !23 + call void @llvm.dbg.value(metadata i32 2, metadata !22, metadata !DIExpression()), !dbg !23 %value = add i32 %input, 2 br label %bb1 @@ -820,7 +819,7 @@ Here the difficulties are: * The control flow is roughly the opposite of basic block order -* The value of the ``!23`` variable merges into ``%bb1``, but there is no PHI +* The value of the ``!22`` variable merges into ``%bb1``, but there is no PHI node As mentioned above, the ``llvm.dbg.value`` intrinsics essentially form an @@ -833,9 +832,9 @@ generated. Examining the example above, variable ``!30`` is assigned ``%input`` on both -conditional paths through the function, while ``!23`` is assigned differing +conditional paths through the function, while ``!22`` is assigned differing constant values on either path. Where control flow merges in ``%bb1`` we would -want ``!30`` to keep its location (``%input``), but ``!23`` to become undefined +want ``!30`` to keep its location (``%input``), but ``!22`` to become undefined as we cannot determine at runtime what value it should have in %bb1 without inserting a PHI node. mem2reg does not insert the PHI node to avoid changing codegen when debugging is enabled, and does not insert the other dbg.values @@ -854,7 +853,7 @@ valid variable location, without the need to consider control flow. From the example above, it is otherwise difficult to determine that the location of variable ``!30`` should flow "up" into block ``%bb1``, but that the location -of variable ``!23`` should not flow "down" into the ``%exit`` block. +of variable ``!22`` should not flow "down" into the ``%exit`` block. .. _ccxx_frontend: diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h --- a/llvm/include/llvm/AsmParser/LLParser.h +++ b/llvm/include/llvm/AsmParser/LLParser.h @@ -520,7 +520,8 @@ template bool parseMDFieldsImplBody(ParserTy ParseField); template bool parseMDFieldsImpl(ParserTy ParseField, LocTy &ClosingLoc); - bool parseSpecializedMDNode(MDNode *&N, bool IsDistinct = false); + bool parseSpecializedMDNode(MDNode *&N, bool IsDistinct = false, + LocTy DistinctLoc = LocTy()); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \ bool parse##CLASS(MDNode *&Result, bool IsDistinct); diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -39,26 +39,39 @@ // Helper macros for defining get() overrides. #define DEFINE_MDNODE_GET_UNPACK_IMPL(...) __VA_ARGS__ #define DEFINE_MDNODE_GET_UNPACK(ARGS) DEFINE_MDNODE_GET_UNPACK_IMPL ARGS -#define DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) \ +#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \ + static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ + return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \ + } +#define DEFINE_MDNODE_GET_IF_EXISTS(CLASS, FORMAL, ARGS) \ + static CLASS *getIfExists(LLVMContext &Context, \ + DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ + return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \ + /* ShouldCreate */ false); \ + } +#define DEFINE_MDNODE_GET_DISTINCT(CLASS, FORMAL, ARGS) \ static CLASS *getDistinct(LLVMContext &Context, \ DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Distinct); \ - } \ + } +#define DEFINE_MDNODE_GET_TEMPORARY(CLASS, FORMAL, ARGS) \ static Temp##CLASS getTemporary(LLVMContext &Context, \ DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ return Temp##CLASS( \ getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Temporary)); \ } -#define DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \ - static CLASS *get(LLVMContext &Context, DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ - return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued); \ - } \ - static CLASS *getIfExists(LLVMContext &Context, \ - DEFINE_MDNODE_GET_UNPACK(FORMAL)) { \ - return getImpl(Context, DEFINE_MDNODE_GET_UNPACK(ARGS), Uniqued, \ - /* ShouldCreate */ false); \ - } \ - DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(CLASS, FORMAL, ARGS) +#define DEFINE_ALL_MDNODE_GET_METHODS(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET_IF_EXISTS(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET_DISTINCT(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET_TEMPORARY(CLASS, FORMAL, ARGS) +#define DEFINE_ALWAYS_DISTINCT_MDNODE_GET_METHODS(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET_DISTINCT(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET_TEMPORARY(CLASS, FORMAL, ARGS) +#define DEFINE_ALWAYS_UNIQUED_MDNODE_GET_METHODS(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET_IF_EXISTS(CLASS, FORMAL, ARGS) \ + DEFINE_MDNODE_GET_TEMPORARY(CLASS, FORMAL, ARGS) namespace llvm { @@ -256,12 +269,14 @@ public: unsigned getHash() const { return SubclassData32; } - DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, StringRef Header, - ArrayRef DwarfOps), - (Tag, Header, DwarfOps)) - DEFINE_MDNODE_GET(GenericDINode, (unsigned Tag, MDString *Header, - ArrayRef DwarfOps), - (Tag, Header, DwarfOps)) + DEFINE_ALL_MDNODE_GET_METHODS(GenericDINode, + (unsigned Tag, StringRef Header, + ArrayRef DwarfOps), + (Tag, Header, DwarfOps)) + DEFINE_ALL_MDNODE_GET_METHODS(GenericDINode, + (unsigned Tag, MDString *Header, + ArrayRef DwarfOps), + (Tag, Header, DwarfOps)) /// Return a (temporary) clone of this. TempGenericDINode clone() const { return cloneImpl(); } @@ -321,16 +336,18 @@ } public: - DEFINE_MDNODE_GET(DISubrange, (int64_t Count, int64_t LowerBound = 0), - (Count, LowerBound)) + DEFINE_ALL_MDNODE_GET_METHODS(DISubrange, + (int64_t Count, int64_t LowerBound = 0), + (Count, LowerBound)) - DEFINE_MDNODE_GET(DISubrange, (Metadata *CountNode, int64_t LowerBound = 0), - (CountNode, LowerBound)) + DEFINE_ALL_MDNODE_GET_METHODS(DISubrange, + (Metadata * CountNode, int64_t LowerBound = 0), + (CountNode, LowerBound)) - DEFINE_MDNODE_GET(DISubrange, - (Metadata * CountNode, Metadata *LowerBound, - Metadata *UpperBound, Metadata *Stride), - (CountNode, LowerBound, UpperBound, Stride)) + DEFINE_ALL_MDNODE_GET_METHODS(DISubrange, + (Metadata * CountNode, Metadata *LowerBound, + Metadata *UpperBound, Metadata *Stride), + (CountNode, LowerBound, UpperBound, Stride)) TempDISubrange clone() const { return cloneImpl(); } @@ -381,10 +398,10 @@ } public: - DEFINE_MDNODE_GET(DIGenericSubrange, - (Metadata * CountNode, Metadata *LowerBound, - Metadata *UpperBound, Metadata *Stride), - (CountNode, LowerBound, UpperBound, Stride)) + DEFINE_ALL_MDNODE_GET_METHODS(DIGenericSubrange, + (Metadata * CountNode, Metadata *LowerBound, + Metadata *UpperBound, Metadata *Stride), + (CountNode, LowerBound, UpperBound, Stride)) TempDIGenericSubrange clone() const { return cloneImpl(); } @@ -441,18 +458,18 @@ } public: - DEFINE_MDNODE_GET(DIEnumerator, - (int64_t Value, bool IsUnsigned, StringRef Name), - (APInt(64, Value, !IsUnsigned), IsUnsigned, Name)) - DEFINE_MDNODE_GET(DIEnumerator, - (int64_t Value, bool IsUnsigned, MDString *Name), - (APInt(64, Value, !IsUnsigned), IsUnsigned, Name)) - DEFINE_MDNODE_GET(DIEnumerator, - (APInt Value, bool IsUnsigned, StringRef Name), - (Value, IsUnsigned, Name)) - DEFINE_MDNODE_GET(DIEnumerator, - (APInt Value, bool IsUnsigned, MDString *Name), - (Value, IsUnsigned, Name)) + DEFINE_ALL_MDNODE_GET_METHODS( + DIEnumerator, (int64_t Value, bool IsUnsigned, StringRef Name), + (APInt(64, Value, !IsUnsigned), IsUnsigned, Name)) + DEFINE_ALL_MDNODE_GET_METHODS( + DIEnumerator, (int64_t Value, bool IsUnsigned, MDString *Name), + (APInt(64, Value, !IsUnsigned), IsUnsigned, Name)) + DEFINE_ALL_MDNODE_GET_METHODS(DIEnumerator, + (APInt Value, bool IsUnsigned, StringRef Name), + (Value, IsUnsigned, Name)) + DEFINE_ALL_MDNODE_GET_METHODS(DIEnumerator, + (APInt Value, bool IsUnsigned, MDString *Name), + (Value, IsUnsigned, Name)) TempDIEnumerator clone() const { return cloneImpl(); } @@ -600,14 +617,16 @@ } public: - DEFINE_MDNODE_GET(DIFile, (StringRef Filename, StringRef Directory, - Optional> CS = None, - Optional Source = None), - (Filename, Directory, CS, Source)) - DEFINE_MDNODE_GET(DIFile, (MDString * Filename, MDString *Directory, - Optional> CS = None, - Optional Source = None), - (Filename, Directory, CS, Source)) + DEFINE_ALL_MDNODE_GET_METHODS(DIFile, + (StringRef Filename, StringRef Directory, + Optional> CS = None, + Optional Source = None), + (Filename, Directory, CS, Source)) + DEFINE_ALL_MDNODE_GET_METHODS(DIFile, + (MDString * Filename, MDString *Directory, + Optional> CS = None, + Optional Source = None), + (Filename, Directory, CS, Source)) TempDIFile clone() const { return cloneImpl(); } @@ -801,22 +820,28 @@ } public: - DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name), - (Tag, Name, 0, 0, 0, FlagZero)) - DEFINE_MDNODE_GET(DIBasicType, - (unsigned Tag, StringRef Name, uint64_t SizeInBits), - (Tag, Name, SizeInBits, 0, 0, FlagZero)) - DEFINE_MDNODE_GET(DIBasicType, - (unsigned Tag, MDString *Name, uint64_t SizeInBits), - (Tag, Name, SizeInBits, 0, 0, FlagZero)) - DEFINE_MDNODE_GET(DIBasicType, - (unsigned Tag, StringRef Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, DIFlags Flags), - (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)) - DEFINE_MDNODE_GET(DIBasicType, - (unsigned Tag, MDString *Name, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding, DIFlags Flags), - (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags)) + DEFINE_ALL_MDNODE_GET_METHODS(DIBasicType, (unsigned Tag, StringRef Name), + (Tag, Name, 0, 0, 0, FlagZero)) + DEFINE_ALL_MDNODE_GET_METHODS(DIBasicType, + (unsigned Tag, StringRef Name, + uint64_t SizeInBits), + (Tag, Name, SizeInBits, 0, 0, FlagZero)) + DEFINE_ALL_MDNODE_GET_METHODS(DIBasicType, + (unsigned Tag, MDString *Name, + uint64_t SizeInBits), + (Tag, Name, SizeInBits, 0, 0, FlagZero)) + DEFINE_ALL_MDNODE_GET_METHODS(DIBasicType, + (unsigned Tag, StringRef Name, + uint64_t SizeInBits, uint32_t AlignInBits, + unsigned Encoding, DIFlags Flags), + (Tag, Name, SizeInBits, AlignInBits, Encoding, + Flags)) + DEFINE_ALL_MDNODE_GET_METHODS(DIBasicType, + (unsigned Tag, MDString *Name, + uint64_t SizeInBits, uint32_t AlignInBits, + unsigned Encoding, DIFlags Flags), + (Tag, Name, SizeInBits, AlignInBits, Encoding, + Flags)) TempDIBasicType clone() const { return cloneImpl(); } @@ -870,22 +895,25 @@ } public: - DEFINE_MDNODE_GET(DIStringType, - (unsigned Tag, StringRef Name, uint64_t SizeInBits, - uint32_t AlignInBits), - (Tag, Name, nullptr, nullptr, SizeInBits, AlignInBits, 0)) - DEFINE_MDNODE_GET(DIStringType, - (unsigned Tag, MDString *Name, Metadata *StringLength, - Metadata *StringLengthExp, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding), - (Tag, Name, StringLength, StringLengthExp, SizeInBits, - AlignInBits, Encoding)) - DEFINE_MDNODE_GET(DIStringType, - (unsigned Tag, StringRef Name, Metadata *StringLength, - Metadata *StringLengthExp, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned Encoding), - (Tag, Name, StringLength, StringLengthExp, SizeInBits, - AlignInBits, Encoding)) + DEFINE_ALL_MDNODE_GET_METHODS(DIStringType, + (unsigned Tag, StringRef Name, + uint64_t SizeInBits, uint32_t AlignInBits), + (Tag, Name, nullptr, nullptr, SizeInBits, + AlignInBits, 0)) + DEFINE_ALL_MDNODE_GET_METHODS(DIStringType, + (unsigned Tag, MDString *Name, + Metadata *StringLength, + Metadata *StringLengthExp, uint64_t SizeInBits, + uint32_t AlignInBits, unsigned Encoding), + (Tag, Name, StringLength, StringLengthExp, + SizeInBits, AlignInBits, Encoding)) + DEFINE_ALL_MDNODE_GET_METHODS(DIStringType, + (unsigned Tag, StringRef Name, + Metadata *StringLength, + Metadata *StringLengthExp, uint64_t SizeInBits, + uint32_t AlignInBits, unsigned Encoding), + (Tag, Name, StringLength, StringLengthExp, + SizeInBits, AlignInBits, Encoding)) TempDIStringType clone() const { return cloneImpl(); } @@ -959,27 +987,24 @@ } public: - DEFINE_MDNODE_GET(DIDerivedType, - (unsigned Tag, MDString *Name, Metadata *File, - unsigned Line, Metadata *Scope, Metadata *BaseType, - uint64_t SizeInBits, uint32_t AlignInBits, - uint64_t OffsetInBits, - Optional DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData = nullptr, - Metadata *Annotations = nullptr), - (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData, Annotations)) - DEFINE_MDNODE_GET(DIDerivedType, - (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, - DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, - Optional DWARFAddressSpace, DIFlags Flags, - Metadata *ExtraData = nullptr, - DINodeArray Annotations = nullptr), - (Tag, Name, File, Line, Scope, BaseType, SizeInBits, - AlignInBits, OffsetInBits, DWARFAddressSpace, Flags, - ExtraData, Annotations)) + DEFINE_ALL_MDNODE_GET_METHODS( + DIDerivedType, + (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, + Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + Optional DWARFAddressSpace, DIFlags Flags, + Metadata *ExtraData = nullptr, Metadata *Annotations = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, DWARFAddressSpace, Flags, ExtraData, Annotations)) + DEFINE_ALL_MDNODE_GET_METHODS( + DIDerivedType, + (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, + DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, + uint32_t AlignInBits, uint64_t OffsetInBits, + Optional DWARFAddressSpace, DIFlags Flags, + Metadata *ExtraData = nullptr, DINodeArray Annotations = nullptr), + (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, + OffsetInBits, DWARFAddressSpace, Flags, ExtraData, Annotations)) TempDIDerivedType clone() const { return cloneImpl(); } @@ -1120,7 +1145,7 @@ } public: - DEFINE_MDNODE_GET( + DEFINE_ALL_MDNODE_GET_METHODS( DICompositeType, (unsigned Tag, StringRef Name, DIFile *File, unsigned Line, DIScope *Scope, DIType *BaseType, uint64_t SizeInBits, @@ -1135,7 +1160,7 @@ OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, Identifier, Discriminator, DataLocation, Associated, Allocated, Rank, Annotations)) - DEFINE_MDNODE_GET( + DEFINE_ALL_MDNODE_GET_METHODS( DICompositeType, (unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, @@ -1309,12 +1334,14 @@ } public: - DEFINE_MDNODE_GET(DISubroutineType, - (DIFlags Flags, uint8_t CC, DITypeRefArray TypeArray), - (Flags, CC, TypeArray)) - DEFINE_MDNODE_GET(DISubroutineType, - (DIFlags Flags, uint8_t CC, Metadata *TypeArray), - (Flags, CC, TypeArray)) + DEFINE_ALL_MDNODE_GET_METHODS(DISubroutineType, + (DIFlags Flags, uint8_t CC, + DITypeRefArray TypeArray), + (Flags, CC, TypeArray)) + DEFINE_ALL_MDNODE_GET_METHODS(DISubroutineType, + (DIFlags Flags, uint8_t CC, + Metadata *TypeArray), + (Flags, CC, TypeArray)) TempDISubroutineType clone() const { return cloneImpl(); } @@ -1429,7 +1456,7 @@ static void get() = delete; static void getIfExists() = delete; - DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( + DEFINE_ALWAYS_DISTINCT_MDNODE_GET_METHODS( DICompileUnit, (unsigned SourceLanguage, DIFile *File, StringRef Producer, bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, @@ -1445,7 +1472,7 @@ GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress, SysRoot, SDK)) - DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( + DEFINE_ALWAYS_DISTINCT_MDNODE_GET_METHODS( DICompileUnit, (unsigned SourceLanguage, Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, @@ -1609,15 +1636,17 @@ // Disallow replacing operands. void replaceOperandWith(unsigned I, Metadata *New) = delete; - DEFINE_MDNODE_GET(DILocation, - (unsigned Line, unsigned Column, Metadata *Scope, - Metadata *InlinedAt = nullptr, bool ImplicitCode = false), - (Line, Column, Scope, InlinedAt, ImplicitCode)) - DEFINE_MDNODE_GET(DILocation, - (unsigned Line, unsigned Column, DILocalScope *Scope, - DILocation *InlinedAt = nullptr, - bool ImplicitCode = false), - (Line, Column, Scope, InlinedAt, ImplicitCode)) + DEFINE_ALL_MDNODE_GET_METHODS(DILocation, + (unsigned Line, unsigned Column, + Metadata *Scope, Metadata *InlinedAt = nullptr, + bool ImplicitCode = false), + (Line, Column, Scope, InlinedAt, ImplicitCode)) + DEFINE_ALL_MDNODE_GET_METHODS(DILocation, + (unsigned Line, unsigned Column, + DILocalScope *Scope, + DILocation *InlinedAt = nullptr, + bool ImplicitCode = false), + (Line, Column, Scope, InlinedAt, ImplicitCode)) /// Return a (temporary) clone of this. TempDILocation clone() const { return cloneImpl(); } @@ -1922,7 +1951,7 @@ } public: - DEFINE_MDNODE_GET( + DEFINE_ALL_MDNODE_GET_METHODS( DISubprogram, (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, DISubroutineType *Type, unsigned ScopeLine, @@ -1935,7 +1964,7 @@ VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes, Annotations)) - DEFINE_MDNODE_GET( + DEFINE_ALL_MDNODE_GET_METHODS( DISubprogram, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, unsigned ScopeLine, @@ -2139,12 +2168,14 @@ } public: - DEFINE_MDNODE_GET(DILexicalBlock, (DILocalScope * Scope, DIFile *File, - unsigned Line, unsigned Column), - (Scope, File, Line, Column)) - DEFINE_MDNODE_GET(DILexicalBlock, (Metadata * Scope, Metadata *File, - unsigned Line, unsigned Column), - (Scope, File, Line, Column)) + DEFINE_ALL_MDNODE_GET_METHODS(DILexicalBlock, + (DILocalScope * Scope, DIFile *File, + unsigned Line, unsigned Column), + (Scope, File, Line, Column)) + DEFINE_ALL_MDNODE_GET_METHODS(DILexicalBlock, + (Metadata * Scope, Metadata *File, + unsigned Line, unsigned Column), + (Scope, File, Line, Column)) TempDILexicalBlock clone() const { return cloneImpl(); } @@ -2188,12 +2219,14 @@ } public: - DEFINE_MDNODE_GET(DILexicalBlockFile, (DILocalScope * Scope, DIFile *File, - unsigned Discriminator), - (Scope, File, Discriminator)) - DEFINE_MDNODE_GET(DILexicalBlockFile, - (Metadata * Scope, Metadata *File, unsigned Discriminator), - (Scope, File, Discriminator)) + DEFINE_ALL_MDNODE_GET_METHODS(DILexicalBlockFile, + (DILocalScope * Scope, DIFile *File, + unsigned Discriminator), + (Scope, File, Discriminator)) + DEFINE_ALL_MDNODE_GET_METHODS(DILexicalBlockFile, + (Metadata * Scope, Metadata *File, + unsigned Discriminator), + (Scope, File, Discriminator)) TempDILexicalBlockFile clone() const { return cloneImpl(); } unsigned getDiscriminator() const { return Discriminator; } @@ -2302,12 +2335,14 @@ } public: - DEFINE_MDNODE_GET(DINamespace, - (DIScope *Scope, StringRef Name, bool ExportSymbols), - (Scope, Name, ExportSymbols)) - DEFINE_MDNODE_GET(DINamespace, - (Metadata *Scope, MDString *Name, bool ExportSymbols), - (Scope, Name, ExportSymbols)) + DEFINE_ALL_MDNODE_GET_METHODS(DINamespace, + (DIScope * Scope, StringRef Name, + bool ExportSymbols), + (Scope, Name, ExportSymbols)) + DEFINE_ALL_MDNODE_GET_METHODS(DINamespace, + (Metadata * Scope, MDString *Name, + bool ExportSymbols), + (Scope, Name, ExportSymbols)) TempDINamespace clone() const { return cloneImpl(); } @@ -2361,20 +2396,20 @@ } public: - DEFINE_MDNODE_GET(DIModule, - (DIFile * File, DIScope *Scope, StringRef Name, - StringRef ConfigurationMacros, StringRef IncludePath, - StringRef APINotesFile, unsigned LineNo, - bool IsDecl = false), - (File, Scope, Name, ConfigurationMacros, IncludePath, - APINotesFile, LineNo, IsDecl)) - DEFINE_MDNODE_GET(DIModule, - (Metadata * File, Metadata *Scope, MDString *Name, - MDString *ConfigurationMacros, MDString *IncludePath, - MDString *APINotesFile, unsigned LineNo, - bool IsDecl = false), - (File, Scope, Name, ConfigurationMacros, IncludePath, - APINotesFile, LineNo, IsDecl)) + DEFINE_ALL_MDNODE_GET_METHODS(DIModule, + (DIFile * File, DIScope *Scope, StringRef Name, + StringRef ConfigurationMacros, + StringRef IncludePath, StringRef APINotesFile, + unsigned LineNo, bool IsDecl = false), + (File, Scope, Name, ConfigurationMacros, + IncludePath, APINotesFile, LineNo, IsDecl)) + DEFINE_ALL_MDNODE_GET_METHODS(DIModule, + (Metadata * File, Metadata *Scope, + MDString *Name, MDString *ConfigurationMacros, + MDString *IncludePath, MDString *APINotesFile, + unsigned LineNo, bool IsDecl = false), + (File, Scope, Name, ConfigurationMacros, + IncludePath, APINotesFile, LineNo, IsDecl)) TempDIModule clone() const { return cloneImpl(); } @@ -2451,12 +2486,13 @@ } public: - DEFINE_MDNODE_GET(DITemplateTypeParameter, - (StringRef Name, DIType *Type, bool IsDefault), - (Name, Type, IsDefault)) - DEFINE_MDNODE_GET(DITemplateTypeParameter, - (MDString *Name, Metadata *Type, bool IsDefault), - (Name, Type, IsDefault)) + DEFINE_ALL_MDNODE_GET_METHODS(DITemplateTypeParameter, + (StringRef Name, DIType *Type, bool IsDefault), + (Name, Type, IsDefault)) + DEFINE_ALL_MDNODE_GET_METHODS(DITemplateTypeParameter, + (MDString * Name, Metadata *Type, + bool IsDefault), + (Name, Type, IsDefault)) TempDITemplateTypeParameter clone() const { return cloneImpl(); } @@ -2496,14 +2532,14 @@ } public: - DEFINE_MDNODE_GET(DITemplateValueParameter, - (unsigned Tag, StringRef Name, DIType *Type, bool IsDefault, - Metadata *Value), - (Tag, Name, Type, IsDefault, Value)) - DEFINE_MDNODE_GET(DITemplateValueParameter, - (unsigned Tag, MDString *Name, Metadata *Type, - bool IsDefault, Metadata *Value), - (Tag, Name, Type, IsDefault, Value)) + DEFINE_ALL_MDNODE_GET_METHODS(DITemplateValueParameter, + (unsigned Tag, StringRef Name, DIType *Type, + bool IsDefault, Metadata *Value), + (Tag, Name, Type, IsDefault, Value)) + DEFINE_ALL_MDNODE_GET_METHODS(DITemplateValueParameter, + (unsigned Tag, MDString *Name, Metadata *Type, + bool IsDefault, Metadata *Value), + (Tag, Name, Type, IsDefault, Value)) TempDITemplateValueParameter clone() const { return cloneImpl(); } @@ -2603,7 +2639,9 @@ } public: - DEFINE_MDNODE_GET(DIExpression, (ArrayRef Elements), (Elements)) + DEFINE_ALWAYS_UNIQUED_MDNODE_GET_METHODS(DIExpression, + (ArrayRef Elements), + (Elements)) TempDIExpression clone() const { return cloneImpl(); } @@ -2987,26 +3025,22 @@ } public: - DEFINE_MDNODE_GET(DIGlobalVariable, - (DIScope * Scope, StringRef Name, StringRef LinkageName, - DIFile *File, unsigned Line, DIType *Type, - bool IsLocalToUnit, bool IsDefinition, - DIDerivedType *StaticDataMemberDeclaration, - MDTuple *TemplateParams, uint32_t AlignInBits, - DINodeArray Annotations), - (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, TemplateParams, - AlignInBits, Annotations)) - DEFINE_MDNODE_GET(DIGlobalVariable, - (Metadata * Scope, MDString *Name, MDString *LinkageName, - Metadata *File, unsigned Line, Metadata *Type, - bool IsLocalToUnit, bool IsDefinition, - Metadata *StaticDataMemberDeclaration, - Metadata *TemplateParams, uint32_t AlignInBits, - Metadata *Annotations), - (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, TemplateParams, - AlignInBits, Annotations)) + DEFINE_ALL_MDNODE_GET_METHODS( + DIGlobalVariable, + (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File, + unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, + DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, + uint32_t AlignInBits, DINodeArray Annotations), + (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)) + DEFINE_ALL_MDNODE_GET_METHODS( + DIGlobalVariable, + (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, + unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, + Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, + uint32_t AlignInBits, Metadata *Annotations), + (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations)) TempDIGlobalVariable clone() const { return cloneImpl(); } @@ -3062,14 +3096,15 @@ } public: - DEFINE_MDNODE_GET(DICommonBlock, - (DIScope *Scope, DIGlobalVariable *Decl, StringRef Name, - DIFile *File, unsigned LineNo), - (Scope, Decl, Name, File, LineNo)) - DEFINE_MDNODE_GET(DICommonBlock, - (Metadata *Scope, Metadata *Decl, MDString *Name, - Metadata *File, unsigned LineNo), - (Scope, Decl, Name, File, LineNo)) + DEFINE_ALL_MDNODE_GET_METHODS(DICommonBlock, + (DIScope * Scope, DIGlobalVariable *Decl, + StringRef Name, DIFile *File, unsigned LineNo), + (Scope, Decl, Name, File, LineNo)) + DEFINE_ALL_MDNODE_GET_METHODS(DICommonBlock, + (Metadata * Scope, Metadata *Decl, + MDString *Name, Metadata *File, + unsigned LineNo), + (Scope, Decl, Name, File, LineNo)) TempDICommonBlock clone() const { return cloneImpl(); } @@ -3132,18 +3167,20 @@ } public: - DEFINE_MDNODE_GET(DILocalVariable, - (DILocalScope * Scope, StringRef Name, DIFile *File, - unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags, - uint32_t AlignInBits, DINodeArray Annotations), - (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits, - Annotations)) - DEFINE_MDNODE_GET(DILocalVariable, - (Metadata * Scope, MDString *Name, Metadata *File, - unsigned Line, Metadata *Type, unsigned Arg, - DIFlags Flags, uint32_t AlignInBits, Metadata *Annotations), - (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits, - Annotations)) + DEFINE_ALL_MDNODE_GET_METHODS(DILocalVariable, + (DILocalScope * Scope, StringRef Name, + DIFile *File, unsigned Line, DIType *Type, + unsigned Arg, DIFlags Flags, + uint32_t AlignInBits, DINodeArray Annotations), + (Scope, Name, File, Line, Type, Arg, Flags, + AlignInBits, Annotations)) + DEFINE_ALL_MDNODE_GET_METHODS(DILocalVariable, + (Metadata * Scope, MDString *Name, + Metadata *File, unsigned Line, Metadata *Type, + unsigned Arg, DIFlags Flags, + uint32_t AlignInBits, Metadata *Annotations), + (Scope, Name, File, Line, Type, Arg, Flags, + AlignInBits, Annotations)) TempDILocalVariable clone() const { return cloneImpl(); } @@ -3211,14 +3248,14 @@ } public: - DEFINE_MDNODE_GET(DILabel, - (DILocalScope * Scope, StringRef Name, DIFile *File, - unsigned Line), - (Scope, Name, File, Line)) - DEFINE_MDNODE_GET(DILabel, - (Metadata * Scope, MDString *Name, Metadata *File, - unsigned Line), - (Scope, Name, File, Line)) + DEFINE_ALL_MDNODE_GET_METHODS(DILabel, + (DILocalScope * Scope, StringRef Name, + DIFile *File, unsigned Line), + (Scope, Name, File, Line)) + DEFINE_ALL_MDNODE_GET_METHODS(DILabel, + (Metadata * Scope, MDString *Name, + Metadata *File, unsigned Line), + (Scope, Name, File, Line)) TempDILabel clone() const { return cloneImpl(); } @@ -3286,18 +3323,18 @@ } public: - DEFINE_MDNODE_GET(DIObjCProperty, - (StringRef Name, DIFile *File, unsigned Line, - StringRef GetterName, StringRef SetterName, - unsigned Attributes, DIType *Type), - (Name, File, Line, GetterName, SetterName, Attributes, - Type)) - DEFINE_MDNODE_GET(DIObjCProperty, - (MDString * Name, Metadata *File, unsigned Line, - MDString *GetterName, MDString *SetterName, - unsigned Attributes, Metadata *Type), - (Name, File, Line, GetterName, SetterName, Attributes, - Type)) + DEFINE_ALL_MDNODE_GET_METHODS(DIObjCProperty, + (StringRef Name, DIFile *File, unsigned Line, + StringRef GetterName, StringRef SetterName, + unsigned Attributes, DIType *Type), + (Name, File, Line, GetterName, SetterName, + Attributes, Type)) + DEFINE_ALL_MDNODE_GET_METHODS(DIObjCProperty, + (MDString * Name, Metadata *File, unsigned Line, + MDString *GetterName, MDString *SetterName, + unsigned Attributes, Metadata *Type), + (Name, File, Line, GetterName, SetterName, + Attributes, Type)) TempDIObjCProperty clone() const { return cloneImpl(); } @@ -3364,16 +3401,16 @@ } public: - DEFINE_MDNODE_GET(DIImportedEntity, - (unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File, - unsigned Line, StringRef Name = "", - DINodeArray Elements = nullptr), - (Tag, Scope, Entity, File, Line, Name, Elements)) - DEFINE_MDNODE_GET(DIImportedEntity, - (unsigned Tag, Metadata *Scope, Metadata *Entity, - Metadata *File, unsigned Line, MDString *Name, - Metadata *Elements = nullptr), - (Tag, Scope, Entity, File, Line, Name, Elements)) + DEFINE_ALL_MDNODE_GET_METHODS( + DIImportedEntity, + (unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File, + unsigned Line, StringRef Name = "", DINodeArray Elements = nullptr), + (Tag, Scope, Entity, File, Line, Name, Elements)) + DEFINE_ALL_MDNODE_GET_METHODS( + DIImportedEntity, + (unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File, + unsigned Line, MDString *Name, Metadata *Elements = nullptr), + (Tag, Scope, Entity, File, Line, Name, Elements)) TempDIImportedEntity clone() const { return cloneImpl(); } @@ -3416,9 +3453,9 @@ } public: - DEFINE_MDNODE_GET(DIGlobalVariableExpression, - (Metadata * Variable, Metadata *Expression), - (Variable, Expression)) + DEFINE_ALL_MDNODE_GET_METHODS(DIGlobalVariableExpression, + (Metadata * Variable, Metadata *Expression), + (Variable, Expression)) TempDIGlobalVariableExpression clone() const { return cloneImpl(); } @@ -3515,12 +3552,14 @@ } public: - DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, StringRef Name, - StringRef Value = ""), - (MIType, Line, Name, Value)) - DEFINE_MDNODE_GET(DIMacro, (unsigned MIType, unsigned Line, MDString *Name, - MDString *Value), - (MIType, Line, Name, Value)) + DEFINE_ALL_MDNODE_GET_METHODS(DIMacro, + (unsigned MIType, unsigned Line, StringRef Name, + StringRef Value = ""), + (MIType, Line, Name, Value)) + DEFINE_ALL_MDNODE_GET_METHODS(DIMacro, + (unsigned MIType, unsigned Line, MDString *Name, + MDString *Value), + (MIType, Line, Name, Value)) TempDIMacro clone() const { return cloneImpl(); } @@ -3566,12 +3605,14 @@ } public: - DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, DIFile *File, - DIMacroNodeArray Elements), - (MIType, Line, File, Elements)) - DEFINE_MDNODE_GET(DIMacroFile, (unsigned MIType, unsigned Line, - Metadata *File, Metadata *Elements), - (MIType, Line, File, Elements)) + DEFINE_ALL_MDNODE_GET_METHODS(DIMacroFile, + (unsigned MIType, unsigned Line, DIFile *File, + DIMacroNodeArray Elements), + (MIType, Line, File, Elements)) + DEFINE_ALL_MDNODE_GET_METHODS(DIMacroFile, + (unsigned MIType, unsigned Line, Metadata *File, + Metadata *Elements), + (MIType, Line, File, Elements)) TempDIMacroFile clone() const { return cloneImpl(); } @@ -3629,7 +3670,9 @@ void dropAllReferences(); public: - DEFINE_MDNODE_GET(DIArgList, (ArrayRef Args), (Args)) + DEFINE_ALWAYS_UNIQUED_MDNODE_GET_METHODS(DIArgList, + (ArrayRef Args), + (Args)) TempDIArgList clone() const { return cloneImpl(); } @@ -3733,5 +3776,11 @@ #undef DEFINE_MDNODE_GET_UNPACK_IMPL #undef DEFINE_MDNODE_GET_UNPACK #undef DEFINE_MDNODE_GET +#undef DEFINE_MDNODE_GET_IF_EXISTS +#undef DEFINE_MDNODE_GET_DISTINCT +#undef DEFINE_MDNODE_GET_TEMPORARY +#undef DEFINE_ALL_MDNODE_GET_METHODS +#undef DEFINE_ALWAYS_DISTINCT_MDNODE_GET_METHODS +#undef DEFINE_ALWAYS_UNIQUED_MDNODE_GET_METHODS #endif // LLVM_IR_DEBUGINFOMETADATA_H diff --git a/llvm/include/llvm/IR/Metadata.def b/llvm/include/llvm/IR/Metadata.def --- a/llvm/include/llvm/IR/Metadata.def +++ b/llvm/include/llvm/IR/Metadata.def @@ -8,12 +8,39 @@ // // Macros for running through all types of metadata. // +// Definitions for terms used to describe metadata include: +// +// * BRANCH: refers to an "abstract" metadata kind, which exists only in the +// C++ class hierarchy. These cannot appear directly in IR/bitcode. +// * LEAF: refers to a "concrete" metadata kind. These can appear directly in +// IR/bitcode. +// * SPECIALIZED: refers to non-MDTuple MDNodes, i.e. those that use the +// syntax "!CLASS(...)" in IR. +// * UNIQUABLE: refers to nodes which can use uniqued, distinct, or temporary +// storage without any restrictions. +// * UNIQUED: refers to nodes which must use uniqued or temporary storage. +// * DISTINCT: refers to nodes which must use distinct or temporary storage. +// +// In LLVM IR, UNIQUABLE and DISTINCT nodes must be referred to by MDNode ID, +// as in `!0`, whereas UNIQUED nodes canonically appear inline at each use, as +// in `DIExpression(...)`. This is because `distinct` nodes maintain their +// identity irrespective of contents, making the inline syntax ambiguous in +// some cases. +// +// Note: UNIQUABLE, UNIQUED, and DISTINCT are mutually exclusive. For example, +// code which intends to consider all nodes which can use uniqued storage must +// consider both UNIQUABLE and UNIQUED nodes. +// //===----------------------------------------------------------------------===// #if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \ defined HANDLE_METADATA_BRANCH || defined HANDLE_MDNODE_LEAF || \ - defined HANDLE_MDNODE_LEAF_UNIQUABLE || defined HANDLE_MDNODE_BRANCH || \ + defined HANDLE_MDNODE_LEAF_UNIQUABLE || \ + defined HANDLE_MDNODE_LEAF_UNIQUED || \ + defined HANDLE_MDNODE_LEAF_DISTINCT || defined HANDLE_MDNODE_BRANCH || \ defined HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE || \ + defined HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED || \ + defined HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT || \ defined HANDLE_SPECIALIZED_MDNODE_LEAF || \ defined HANDLE_SPECIALIZED_MDNODE_BRANCH) #error "Missing macro definition of HANDLE_METADATA*" @@ -34,7 +61,7 @@ #define HANDLE_METADATA_BRANCH(CLASS) HANDLE_METADATA(CLASS) #endif -// Handler for specialized and uniquable leaf nodes under MDNode. Defers to +// Handler for specialized and uniquable leaf nodes under MDNode. Defers to // HANDLE_MDNODE_LEAF_UNIQUABLE if it's defined, otherwise to // HANDLE_SPECIALIZED_MDNODE_LEAF. #ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE @@ -47,11 +74,47 @@ #endif #endif -// Handler for leaf nodes under MDNode. +// Handler for specialized and always-uniqued leaf nodes under MDNode. Defers to +// HANDLE_MDNODE_LEAF_UNIQUED if it's defined, otherwise to +// HANDLE_SPECIALIZED_MDNODE_LEAF. +#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED +#ifdef HANDLE_MDNODE_LEAF_UNIQUED +#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(CLASS) \ + HANDLE_MDNODE_LEAF_UNIQUED(CLASS) +#else +#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(CLASS) \ + HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) +#endif +#endif + +// Handler for specialized and always-distinct leaf nodes under MDNode. Defers +// to HANDLE_MDNODE_LEAF_DISTINCT if it's defined, otherwise to +// HANDLE_SPECIALIZED_MDNODE_LEAF. +#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT +#ifdef HANDLE_MDNODE_LEAF_DISTINCT +#define HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT(CLASS) \ + HANDLE_MDNODE_LEAF_DISTINCT(CLASS) +#else +#define HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT(CLASS) \ + HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) +#endif +#endif + +// Handler for uniquable leaf nodes under MDNode. #ifndef HANDLE_MDNODE_LEAF_UNIQUABLE #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) HANDLE_MDNODE_LEAF(CLASS) #endif +// Handler for uniqued leaf nodes under MDNode. +#ifndef HANDLE_MDNODE_LEAF_UNIQUED +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF(CLASS) +#endif + +// Handler for distinct leaf nodes under MDNode. +#ifndef HANDLE_MDNODE_LEAF_DISTINCT +#define HANDLE_MDNODE_LEAF_DISTINCT(CLASS) HANDLE_MDNODE_LEAF(CLASS) +#endif + // Handler for leaf nodes under MDNode. #ifndef HANDLE_MDNODE_LEAF #define HANDLE_MDNODE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS) @@ -80,7 +143,7 @@ HANDLE_MDNODE_BRANCH(MDNode) HANDLE_MDNODE_LEAF_UNIQUABLE(MDTuple) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocation) -HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIExpression) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(DIExpression) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGlobalVariableExpression) HANDLE_SPECIALIZED_MDNODE_BRANCH(DINode) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(GenericDINode) @@ -93,7 +156,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICompositeType) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubroutineType) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIFile) -HANDLE_SPECIALIZED_MDNODE_LEAF(DICompileUnit) +HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT(DICompileUnit) HANDLE_SPECIALIZED_MDNODE_BRANCH(DILocalScope) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubprogram) HANDLE_SPECIALIZED_MDNODE_BRANCH(DILexicalBlockBase) @@ -114,7 +177,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICommonBlock) -HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIArgList) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(DIArgList) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGenericSubrange) @@ -123,7 +186,11 @@ #undef HANDLE_METADATA_BRANCH #undef HANDLE_MDNODE_LEAF #undef HANDLE_MDNODE_LEAF_UNIQUABLE +#undef HANDLE_MDNODE_LEAF_UNIQUED +#undef HANDLE_MDNODE_LEAF_DISTINCT #undef HANDLE_MDNODE_BRANCH #undef HANDLE_SPECIALIZED_MDNODE_LEAF #undef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE +#undef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED +#undef HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT #undef HANDLE_SPECIALIZED_MDNODE_BRANCH diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -742,27 +742,29 @@ return true; NamedMDNode *NMD = M->getOrInsertNamedMetadata(Name); - if (Lex.getKind() != lltok::rbrace) - do { - MDNode *N = nullptr; - // parse DIExpressions inline as a special case. They are still MDNodes, - // so they can still appear in named metadata. Remove this logic if they - // become plain Metadata. - if (Lex.getKind() == lltok::MetadataVar && - Lex.getStrVal() == "DIExpression") { - if (parseDIExpression(N, /*IsDistinct=*/false)) - return true; - // DIArgLists should only appear inline in a function, as they may - // contain LocalAsMetadata arguments which require a function context. - } else if (Lex.getKind() == lltok::MetadataVar && - Lex.getStrVal() == "DIArgList") { - return tokError("found DIArgList outside of function"); - } else if (parseToken(lltok::exclaim, "Expected '!' here") || - parseMDNodeID(N)) { - return true; - } - NMD->addOperand(N); - } while (EatIfPresent(lltok::comma)); + + if (Lex.getKind() == lltok::rbrace) { + Lex.Lex(); + return false; + } + + do { + MDNode *N = nullptr; + // Parse uniqued MDNodes inline as a special case. +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \ + if (Lex.getKind() == lltok::MetadataVar && Lex.getStrVal() == #CLASS) { \ + if (parse##CLASS(N, /*IsDistinct=*/false)) \ + return true; \ + NMD->addOperand(N); \ + continue; \ + } +#include "llvm/IR/Metadata.def" + // Parse all other MDNodes as an MDNodeID. + if (parseToken(lltok::exclaim, "Expected '!' here") || parseMDNodeID(N)) { + return true; + } + NMD->addOperand(N); + } while (EatIfPresent(lltok::comma)); return parseToken(lltok::rbrace, "expected end of metadata node"); } @@ -782,9 +784,10 @@ if (Lex.getKind() == lltok::Type) return tokError("unexpected type in metadata definition"); + auto DistinctLoc = Lex.getLoc(); bool IsDistinct = EatIfPresent(lltok::kw_distinct); if (Lex.getKind() == lltok::MetadataVar) { - if (parseSpecializedMDNode(Init, IsDistinct)) + if (parseSpecializedMDNode(Init, IsDistinct, DistinctLoc)) return true; } else if (parseToken(lltok::exclaim, "Expected '!' here") || parseMDTuple(Init, IsDistinct)) @@ -4332,12 +4335,25 @@ return parseMDField(Loc, Name, Result); } -bool LLParser::parseSpecializedMDNode(MDNode *&N, bool IsDistinct) { +bool LLParser::parseSpecializedMDNode(MDNode *&N, bool IsDistinct, + LocTy DistinctLoc) { assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); -#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \ +#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(CLASS) \ if (Lex.getStrVal() == #CLASS) \ return parse##CLASS(N, IsDistinct); +#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUED(CLASS) \ + if (Lex.getStrVal() == #CLASS) { \ + if (IsDistinct) \ + return error(DistinctLoc, "'distinct' not allowed for !" #CLASS); \ + return parse##CLASS(N, IsDistinct); \ + } +#define HANDLE_SPECIALIZED_MDNODE_LEAF_DISTINCT(CLASS) \ + if (Lex.getStrVal() == #CLASS) { \ + if (!IsDistinct) \ + return error(DistinctLoc, "missing 'distinct', required for !" #CLASS); \ + return parse##CLASS(N, IsDistinct); \ + } #include "llvm/IR/Metadata.def" return tokError("expected metadata type"); @@ -4683,9 +4699,6 @@ /// globals: !4, imports: !5, macros: !6, dwoId: 0x0abcd, /// sysroot: "/", sdk: "MacOSX.sdk") bool LLParser::parseDICompileUnit(MDNode *&Result, bool IsDistinct) { - if (!IsDistinct) - return Lex.Error("missing 'distinct', required for !DICompileUnit"); - #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(language, DwarfLangField, ); \ REQUIRED(file, MDField, (/* AllowNull */ false)); \ @@ -5009,6 +5022,7 @@ /// parseDIExpression: /// ::= !DIExpression(0, 7, -1) bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) { + assert(!IsDistinct && "DIExpression must not be distinct"); assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); Lex.Lex(); @@ -5050,17 +5064,18 @@ if (parseToken(lltok::rparen, "expected ')' here")) return true; - Result = GET_OR_DISTINCT(DIExpression, (Context, Elements)); + Result = DIExpression::get(Context, Elements); return false; } bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct) { - return parseDIArgList(Result, IsDistinct, nullptr); + return tokError("!DIArgList cannot appear outside of a function"); } /// ParseDIArgList: /// ::= !DIArgList(i32 7, i64 %0) bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct, PerFunctionState *PFS) { + assert(!IsDistinct && "DIArgList must not be distinct"); assert(PFS && "Expected valid function state"); assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name"); Lex.Lex(); @@ -5080,7 +5095,7 @@ if (parseToken(lltok::rparen, "expected ')' here")) return true; - Result = GET_OR_DISTINCT(DIArgList, (Context, Args)); + Result = DIArgList::get(Context, Args); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -554,7 +554,7 @@ } /// Upgrade the expression from previous versions. - Error upgradeDIExpression(uint64_t FromVersion, + Error upgradeDIExpression(uint64_t FromVersion, bool &IsDistinct, MutableArrayRef &Expr, SmallVectorImpl &Buffer) { auto N = Expr.size(); @@ -628,6 +628,9 @@ LLVM_FALLTHROUGH; } case 3: + IsDistinct = false; + LLVM_FALLTHROUGH; + case 4: // Up-to-date! break; } @@ -2002,11 +2005,13 @@ auto Elts = MutableArrayRef(Record).slice(1); SmallVector Buffer; - if (Error Err = upgradeDIExpression(Version, Elts, Buffer)) + if (Error Err = upgradeDIExpression(Version, IsDistinct, Elts, Buffer)) return Err; - MetadataList.assignValue( - GET_OR_DISTINCT(DIExpression, (Context, Elts)), NextMetadataNo); + if (IsDistinct) + return error("Invalid record"); + + MetadataList.assignValue(DIExpression::get(Context, Elts), NextMetadataNo); NextMetadataNo++; break; } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1766,7 +1766,6 @@ void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N, SmallVectorImpl &Record, unsigned Abbrev) { - assert(N->isDistinct() && "Expected distinct compile units"); Record.push_back(/* IsDistinct */ true); Record.push_back(N->getSourceLanguage()); Record.push_back(VE.getMetadataOrNullID(N->getFile())); @@ -2020,7 +2019,7 @@ SmallVectorImpl &Record, unsigned Abbrev) { Record.reserve(N->getElements().size() + 1); - const uint64_t Version = 3 << 1; + const uint64_t Version = 4 << 1; Record.push_back((uint64_t)N->isDistinct() | Version); Record.append(N->elements_begin(), N->elements_end()); @@ -2166,6 +2165,20 @@ if (const MDNode *N = dyn_cast(MD)) { assert(N->isResolved() && "Expected forward references to be resolved"); +#ifndef NDEBUG + switch (N->getMetadataID()) { +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \ + case Metadata::CLASS##Kind: \ + assert(!N->isDistinct() && "Expected non-distinct " #CLASS); \ + break; +#define HANDLE_MDNODE_LEAF_DISTINCT(CLASS) \ + case Metadata::CLASS##Kind: \ + assert(N->isDistinct() && "Expected distinct " #CLASS); \ + break; +#include "llvm/IR/Metadata.def" + } +#endif + switch (N->getMetadataID()) { default: llvm_unreachable("Invalid MDNode subclass"); diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -1184,6 +1184,7 @@ if (parseMDNode(Node)) return true; } else if (Token.is(MIToken::md_diexpr)) { + // FIXME: This should be driven off of the UNIQUED property in Metadata.def if (parseDIExpression(Node)) return true; } else if (Token.is(MIToken::md_dilocation)) { @@ -2327,6 +2328,7 @@ if (parseMDNode(Node)) return true; } else if (Token.is(MIToken::md_diexpr)) { + // FIXME: This should be driven off of the UNIQUED property in Metadata.def if (parseDIExpression(Node)) return true; } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1236,10 +1236,11 @@ void SlotTracker::CreateMetadataSlot(const MDNode *N) { assert(N && "Can't insert a null Value into SlotTracker!"); - // Don't make slots for DIExpressions or DIArgLists. We just print them inline - // everywhere. - if (isa(N) || isa(N)) + // Don't make slots for uniqued nodes. We just print them inline everywhere. +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \ + if (isa(N)) \ return; +#include "llvm/IR/Metadata.def" unsigned DestSlot = mdnNext; if (!mdnMap.insert(std::make_pair(N, DestSlot)).second) @@ -2332,10 +2333,7 @@ } static void writeDIArgList(raw_ostream &Out, const DIArgList *N, - AsmWriterContext &WriterCtx, - bool FromValue = false) { - assert(FromValue && - "Unexpected DIArgList metadata outside of value argument"); + AsmWriterContext &WriterCtx) { Out << "!DIArgList("; FieldSeparator FS; MDFieldPrinter Printer(Out, WriterCtx); @@ -2486,16 +2484,16 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD, AsmWriterContext &WriterCtx, bool FromValue) { - // Write DIExpressions and DIArgLists inline when used as a value. Improves - // readability of debug info intrinsics. - if (const DIExpression *Expr = dyn_cast(MD)) { - writeDIExpression(Out, Expr, WriterCtx); - return; - } - if (const DIArgList *ArgList = dyn_cast(MD)) { - writeDIArgList(Out, ArgList, WriterCtx, FromValue); - return; + assert((FromValue || !(isa(MD) || isa(MD))) && + "Unexpected function-local metadata outside of value argument"); + + // Write uniqued MDNodes inline when used as a value. +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \ + if (const CLASS *N = dyn_cast(MD)) { \ + write##CLASS(Out, N, WriterCtx); \ + return; \ } +#include "llvm/IR/Metadata.def" if (const MDNode *N = dyn_cast(MD)) { std::unique_ptr MachineStorage; @@ -2527,9 +2525,6 @@ auto *V = cast(MD); assert(WriterCtx.TypePrinter && "TypePrinter required for metadata values"); - assert((FromValue || !isa(V)) && - "Unexpected function-local metadata outside of value argument"); - WriterCtx.TypePrinter->print(V->getValue()->getType(), Out); Out << ' '; WriteAsOperandInternal(Out, V->getValue(), WriterCtx); @@ -3416,15 +3411,17 @@ if (i) Out << ", "; - // Write DIExpressions inline. + // Write UNIQUED nodes inline. // FIXME: Ban DIExpressions in NamedMDNodes, they will serve no purpose. MDNode *Op = NMD->getOperand(i); assert(!isa(Op) && "DIArgLists should not appear in NamedMDNodes"); - if (auto *Expr = dyn_cast(Op)) { - writeDIExpression(Out, Expr, AsmWriterContext::getEmpty()); - continue; - } +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \ + if (auto *N = dyn_cast(Op)) { \ + write##CLASS(Out, N, AsmWriterContext::getEmpty()); \ + continue; \ + } +#include "llvm/IR/Metadata.def" int Slot = Machine.getMetadataSlot(Op); if (Slot == -1) @@ -4773,8 +4770,15 @@ WriteAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true); auto *N = dyn_cast(&MD); - if (OnlyAsOperand || !N || isa(MD) || isa(MD)) + if (OnlyAsOperand || !N) { + return; + } + // Uniqued MDNodes are always treated as if OnlyAsOperand, as they are + // printed inline. +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) \ + if (isa(MD)) \ return; +#include "llvm/IR/Metadata.def" OS << " = "; WriteMDNodeBodyInternal(OS, N, *WriterCtx); diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -1071,6 +1071,7 @@ DIExpression *DIExpression::getImpl(LLVMContext &Context, ArrayRef Elements, StorageType Storage, bool ShouldCreate) { + assert(Storage != Distinct && "DIExpression cannot be distinct"); DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements)); DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements)); } @@ -1641,6 +1642,7 @@ DIArgList *DIArgList::getImpl(LLVMContext &Context, ArrayRef Args, StorageType Storage, bool ShouldCreate) { + assert(Storage != Distinct && "DIArgList cannot be distinct"); DEFINE_GETIMPL_LOOKUP(DIArgList, (Args)); DEFINE_GETIMPL_STORE_NO_OPS(DIArgList, (Args)); } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -1398,6 +1398,7 @@ #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \ DenseSet CLASS##s; +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) #include "llvm/IR/Metadata.def" // Optional map for looking up composite types by identifier. diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp --- a/llvm/lib/IR/LLVMContextImpl.cpp +++ b/llvm/lib/IR/LLVMContextImpl.cpp @@ -65,6 +65,7 @@ #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \ for (auto *I : CLASS##s) \ I->dropAllReferences(); +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) #include "llvm/IR/Metadata.def" // Also drop references that come from the Value bridges. @@ -79,6 +80,7 @@ #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \ for (CLASS * I : CLASS##s) \ delete I; +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) #include "llvm/IR/Metadata.def" // Free the constants. diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp --- a/llvm/lib/IR/Metadata.cpp +++ b/llvm/lib/IR/Metadata.cpp @@ -672,6 +672,7 @@ #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \ case CLASS##Kind: \ break; +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) #include "llvm/IR/Metadata.def" } @@ -812,6 +813,7 @@ dispatchRecalculateHash(SubclassThis, ShouldRecalculateHash); \ return uniquifyImpl(SubclassThis, getContext().pImpl->CLASS##s); \ } +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) #include "llvm/IR/Metadata.def" } } @@ -824,6 +826,7 @@ case CLASS##Kind: \ getContext().pImpl->CLASS##s.erase(cast(this)); \ break; +#define HANDLE_MDNODE_LEAF_UNIQUED(CLASS) HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) #include "llvm/IR/Metadata.def" } } diff --git a/llvm/test/Assembler/invalid-diarglist-outside-function.ll b/llvm/test/Assembler/invalid-diarglist-outside-function.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/invalid-diarglist-outside-function.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s + +; CHECK: :[[@LINE+1]]:6: error: !DIArgList cannot appear outside of a function +!0 = !DIArgList() diff --git a/llvm/test/Assembler/invalid-diexpression-distinct.ll b/llvm/test/Assembler/invalid-diexpression-distinct.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/invalid-diexpression-distinct.ll @@ -0,0 +1,4 @@ +; RUN: not llvm-as < %s -disable-output 2>&1 | FileCheck %s + +; CHECK: :[[@LINE+1]]:6: error: 'distinct' not allowed for !DIExpression +!0 = distinct !DIExpression() diff --git a/llvm/test/Bitcode/DIExpression-is-distinct-upgrade.ll b/llvm/test/Bitcode/DIExpression-is-distinct-upgrade.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bitcode/DIExpression-is-distinct-upgrade.ll @@ -0,0 +1,16 @@ +; RUN: llvm-dis -o - %s.bc | FileCheck %s + +!llvm.dbg.cu = !{!1} +!llvm.module.flags = !{!8, !9} + +!0 = distinct !DIGlobalVariable(name: "g", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true) +!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4) +!2 = !DIFile(filename: "a.c", directory: "/") +!3 = !{} +!4 = !{!7} +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +; CHECK: expr: !DIExpression() +!6 = distinct !DIExpression() +!7 = !DIGlobalVariableExpression(var: !0, expr: !6) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/llvm/test/Bitcode/DIExpression-is-distinct-upgrade.ll.bc b/llvm/test/Bitcode/DIExpression-is-distinct-upgrade.ll.bc new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@