Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -4154,6 +4154,8 @@ !0 = !DINamespace(name: "myawesomeproject", scope: !1, file: !2, line: 7) +.. _DIGlobalVariable: + DIGlobalVariable """""""""""""""" @@ -4336,6 +4338,23 @@ !2 = !DIMacroFile(macinfo: DW_MACINFO_start_file, line: 7, file: !2, nodes: !3) +DITypeIndex +""""""""""" + +``DITypeIndex`` nodes represent a single 32-bit number that stands in place of +a type. It can be used in the ``type:`` fields of :ref:`DISubprogram`, +:ref:`DILocalVariable`, and :ref:`DIGlobalVariable`. The index is an opaque +number referring to data in a separate, per-``DICompileUnit`` type information +blob provided by the frontend. The contents of that blob and how it is stored +in the metadata are format-specific. ``DITypeIndex`` is used primarily to +implement CodeView type information, but in the future it could be used to +represent a DWARF DIE offset. + +.. code-block:: llvm + !0 = !DISubprogram(name: !"foo", type: !DITypeIndex(u0x1000), ...) + !1 = !DILocalVariable(name: !"x", type: !DITypeIndex(u0x74), ...) + !2 = !DIGlobalVariable(name: !"y", type: !DITypeIndex(u0x74), ...) + '``tbaa``' Metadata ^^^^^^^^^^^^^^^^^^^ Index: include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- include/llvm/Bitcode/LLVMBitCodes.h +++ include/llvm/Bitcode/LLVMBitCodes.h @@ -257,6 +257,7 @@ METADATA_MACRO = 33, // [distinct, macinfo, line, name, value] METADATA_MACRO_FILE = 34, // [distinct, macinfo, line, file, ...] METADATA_STRINGS = 35, // [count, offset] blob([lengths][chars]) + METADATA_TYPE_INDEX = 36, // [index] }; // The constants block (CONSTANTS_BLOCK_ID) describes emission for each Index: include/llvm/IR/DIBuilder.h =================================================================== --- include/llvm/IR/DIBuilder.h +++ include/llvm/IR/DIBuilder.h @@ -512,7 +512,7 @@ /// \param TParams Function template parameters. DISubprogram *createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, + unsigned LineNo, DITypeRef Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags = 0, bool isOptimized = false, @@ -523,7 +523,7 @@ /// except that the resulting DbgNode is meant to be RAUWed. DISubprogram *createTempFunctionFwdDecl( DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, + unsigned LineNo, DITypeRef Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags = 0, bool isOptimized = false, DITemplateParameterArray TParams = nullptr, DISubprogram *Decl = nullptr); @@ -549,7 +549,7 @@ /// \param TParams Function template parameters. DISubprogram * createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName, - DIFile *File, unsigned LineNo, DISubroutineType *Ty, + DIFile *File, unsigned LineNo, DITypeRef Ty, bool isLocalToUnit, bool isDefinition, unsigned Virtuality = 0, unsigned VTableIndex = 0, DIType *VTableHolder = nullptr, unsigned Flags = 0, bool isOptimized = false, Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -61,7 +61,8 @@ TypedDINodeRef(const T *MD) : MD(MD) {} explicit TypedDINodeRef(const Metadata *MD) : MD(MD) { - assert((!MD || isa(MD)) && "Expected valid type ref"); + assert((!MD || isa(MD) || isa(MD)) && + "Expected valid type ref"); } template @@ -1294,7 +1295,7 @@ static DISubprogram * getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, - DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition, + DITypeRef Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsOptimized, DICompileUnit *Unit, DITemplateParameterArray TemplateParams, @@ -1328,7 +1329,7 @@ public: DEFINE_MDNODE_GET(DISubprogram, (DIScopeRef Scope, StringRef Name, StringRef LinkageName, - DIFile *File, unsigned Line, DISubroutineType *Type, + DIFile *File, unsigned Line, DITypeRef Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality, unsigned VirtualIndex, unsigned Flags, bool IsOptimized, @@ -1402,9 +1403,7 @@ MDString *getRawName() const { return getOperandAs(2); } MDString *getRawLinkageName() const { return getOperandAs(4); } - DISubroutineType *getType() const { - return cast_or_null(getRawType()); - } + DITypeRef getType() const { return DITypeRef(getRawType()); } DITypeRef getContainingType() const { return DITypeRef(getRawContainingType()); } @@ -2428,6 +2427,25 @@ } }; +/// Represents a type in a type stream at the given index. The type stream is +/// associated with the DICompileUnit containing the type index reference. This +/// doesn't contain metadata operands, so it inherits directly from Metadata. +class DITypeIndex : public Metadata { + DITypeIndex(unsigned Index) : Metadata(DITypeIndexKind, Uniqued) { + SubclassData32 = Index; + } + ~DITypeIndex() = default; + +public: + unsigned getIndex() const { return SubclassData32; } + + static DITypeIndex *get(LLVMContext &Context, unsigned Index); + + static bool classof(const Metadata *MD) { + return MD->getMetadataID() == DITypeIndexKind; + } +}; + } // end namespace llvm #undef DEFINE_MDNODE_GET_UNPACK_IMPL Index: include/llvm/IR/Metadata.def =================================================================== --- include/llvm/IR/Metadata.def +++ include/llvm/IR/Metadata.def @@ -112,6 +112,7 @@ HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile) +HANDLE_METADATA_LEAF(DITypeIndex) #undef HANDLE_METADATA #undef HANDLE_METADATA_LEAF Index: lib/AsmParser/LLParser.h =================================================================== --- lib/AsmParser/LLParser.h +++ lib/AsmParser/LLParser.h @@ -287,6 +287,7 @@ bool ParseStandaloneMetadata(); bool ParseNamedMetadata(); bool ParseMDString(MDString *&Result); + bool ParseDITypeIndex(DITypeIndex *&Result); bool ParseMDNodeID(MDNode *&Result); bool ParseUnnamedAttrGrp(); bool ParseFnAttributeValuePairs(AttrBuilder &B, Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -598,6 +598,19 @@ return false; } +// DITypeIndex: +// ::= '!DITypeIndex' '(' uint32 ')' +bool LLParser::ParseDITypeIndex(DITypeIndex *&Result) { + assert(Lex.getKind() == lltok::MetadataVar); + Lex.Lex(); + unsigned Index; + if (ParseToken(lltok::lparen, "Expected '(' here") || ParseUInt32(Index) || + ParseToken(lltok::rparen, "Expected ')' here")) + return true; + Result = DITypeIndex::get(Context, Index); + return false; +} + // MDNode: // ::= '!' MDNodeNumber bool LLParser::ParseMDNodeID(MDNode *&Result) { @@ -4272,8 +4285,19 @@ /// ::= !{...} /// ::= !"string" /// ::= !DILocation(...) +/// ::= !DITypeIndex(...) bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) { if (Lex.getKind() == lltok::MetadataVar) { + // Handle type indices similar to MDString. They appear as literals, and are + // not referred to by number as is done for MDNodes. + if (Lex.getStrVal() == "DITypeIndex") { + DITypeIndex *TI; + if (ParseDITypeIndex(TI)) + return true; + MD = TI; + return false; + } + MDNode *N; if (ParseSpecializedMDNode(N)) return true; Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -2676,6 +2676,14 @@ MetadataList.assignValue(MD, NextMetadataNo++); break; } + case bitc::METADATA_TYPE_INDEX: { + if (Record.size() != 1 || Record[0] > UINT_MAX) + return error("Invalid record"); + uint32_t Index = Record[0]; + Metadata *MD = DITypeIndex::get(Context, Index); + MetadataList.assignValue(MD, NextMetadataNo++); + break; + } case bitc::METADATA_STRINGS: if (std::error_code EC = parseMetadataStrings(Record, Blob, NextMetadataNo)) Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -155,6 +155,8 @@ void writeModuleInfo(); void writeValueAsMetadata(const ValueAsMetadata *MD, SmallVectorImpl &Record); + void writeDITypeIndex(const DITypeIndex *N, + SmallVectorImpl &Record); void writeMDTuple(const MDTuple *N, SmallVectorImpl &Record, unsigned Abbrev); unsigned createDILocationAbbrev(); @@ -1141,6 +1143,13 @@ Record.clear(); } +void ModuleBitcodeWriter::writeDITypeIndex(const DITypeIndex *TI, + SmallVectorImpl &Record) { + Record.push_back(TI->getIndex()); + Stream.EmitRecord(bitc::METADATA_TYPE_INDEX, Record, 0); + Record.clear(); +} + void ModuleBitcodeWriter::writeMDTuple(const MDTuple *N, SmallVectorImpl &Record, unsigned Abbrev) { @@ -1647,6 +1656,9 @@ continue; #include "llvm/IR/Metadata.def" } + } else if (const DITypeIndex *TI = dyn_cast(MD)) { + writeDITypeIndex(TI, Record); + continue; } writeValueAsMetadata(cast(MD), Record); } Index: lib/Bitcode/Writer/ValueEnumerator.cpp =================================================================== --- lib/Bitcode/Writer/ValueEnumerator.cpp +++ lib/Bitcode/Writer/ValueEnumerator.cpp @@ -618,9 +618,9 @@ if (!MD) return nullptr; - assert( - (isa(MD) || isa(MD) || isa(MD)) && - "Invalid metadata kind"); + assert((isa(MD) || isa(MD) || isa(MD) || + isa(MD)) || + isa(MD) && "Invalid metadata kind"); auto Insertion = MetadataMap.insert(std::make_pair(MD, MDIndex(F))); MDIndex &Entry = Insertion.first->second; Index: lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -709,6 +709,12 @@ OS.AddComment("Record kind: S_LOCAL"); OS.EmitIntValue(unsigned(SymbolRecordKind::S_LOCAL), 2); + // Pull the type index out of the type field. If the frontend did not provide + // a DITypeIndex, emit zero for "no type". + unsigned TI = unsigned(SimpleTypeKind::None); + if (auto *DTI = dyn_cast_or_null(Var.DIVar->getType())) + TI = DTI->getIndex(); + uint16_t Flags = 0; if (Var.DIVar->isParameter()) Flags |= LocalSym::IsParameter; @@ -716,7 +722,7 @@ Flags |= LocalSym::IsOptimizedOut; OS.AddComment("TypeIndex"); - OS.EmitIntValue(TypeIndex::Int32().getIndex(), 4); + OS.EmitIntValue(TI, 4); OS.AddComment("Flags"); OS.EmitIntValue(Flags, 2); // Truncate the name so we won't overflow the record length field. Index: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -587,7 +587,10 @@ DIE &ScopeDIE = updateSubprogramScopeDIE(Sub); // If this is a variadic function, add an unspecified parameter. - DITypeRefArray FnArgs = Sub->getType()->getTypeArray(); + DITypeRefArray FnArgs; + if (DISubroutineType *FnTy = + cast_or_null(resolve(Sub->getType()))) + FnArgs = FnTy->getTypeArray(); // Collect lexical scope children first. // ObjectPointer might be a local (non-argument) local variable if it's a Index: lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1206,7 +1206,7 @@ addFlag(SPDie, dwarf::DW_AT_prototyped); DITypeRefArray Args; - if (const DISubroutineType *SPTy = SP->getType()) + if (const auto *SPTy = cast_or_null(resolve(SP->getType()))) Args = SPTy->getTypeArray(); // Add a return type. If this is a type like a C/C++ void type we don't add a Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -2032,6 +2032,16 @@ return; } + if (const auto *TI = dyn_cast(MD)) { + Out << "!DITypeIndex("; + if (TI->getIndex() == 0) + Out << '0'; + else + Out << 'u' << format_hex(TI->getIndex(), 0, /*Upper=*/true); + Out << ')'; + return; + } + auto *V = cast(MD); assert(TypePrinter && "TypePrinter required for metadata values"); assert((FromValue || !isa(V)) && Index: lib/IR/DIBuilder.cpp =================================================================== --- lib/IR/DIBuilder.cpp +++ lib/IR/DIBuilder.cpp @@ -648,7 +648,7 @@ DISubprogram *DIBuilder::createFunction( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, + unsigned LineNo, DITypeRef Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized, DITemplateParameterArray TParams, DISubprogram *Decl) { auto *Node = getSubprogram( @@ -666,7 +666,7 @@ DISubprogram *DIBuilder::createTempFunctionFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, + unsigned LineNo, DITypeRef Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized, DITemplateParameterArray TParams, DISubprogram *Decl) { return DISubprogram::getTemporary( @@ -679,7 +679,7 @@ DISubprogram * DIBuilder::createMethod(DIScope *Context, StringRef Name, StringRef LinkageName, - DIFile *F, unsigned LineNo, DISubroutineType *Ty, + DIFile *F, unsigned LineNo, DITypeRef Ty, bool isLocalToUnit, bool isDefinition, unsigned VK, unsigned VIndex, DIType *VTableHolder, unsigned Flags, bool isOptimized, DITemplateParameterArray TParams) { Index: lib/IR/DebugInfo.cpp =================================================================== --- lib/IR/DebugInfo.cpp +++ lib/IR/DebugInfo.cpp @@ -144,7 +144,7 @@ if (!addSubprogram(SP)) return; processScope(SP->getScope().resolve()); - processType(SP->getType()); + processType(SP->getType().resolve()); for (auto *Element : SP->getTemplateParams()) { if (auto *TType = dyn_cast(Element)) { processType(TType->getType().resolve()); Index: lib/IR/DebugInfoMetadata.cpp =================================================================== --- lib/IR/DebugInfoMetadata.cpp +++ lib/IR/DebugInfoMetadata.cpp @@ -633,3 +633,12 @@ DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops); } +DITypeIndex *DITypeIndex::get(LLVMContext &Context, unsigned Index) { + DITypeIndex *&Slot = Context.pImpl->TypeIndexCache[Index]; + if (!Slot) { + void *Mem = Context.pImpl->TypeAllocator.Allocate(sizeof(DITypeIndex), + alignof(DITypeIndex)); + Slot = new (Mem) DITypeIndex(Index); + } + return Slot; +} Index: lib/IR/LLVMContextImpl.h =================================================================== --- lib/IR/LLVMContextImpl.h +++ lib/IR/LLVMContextImpl.h @@ -1026,6 +1026,7 @@ StringMap MDStringCache; DenseMap ValuesAsMetadata; DenseMap MetadataAsValues; + DenseMap TypeIndexCache; DenseMap ValueNames; @@ -1077,7 +1078,8 @@ /// TypeAllocator - All dynamically allocated types are allocated from this. - /// They live forever until the context is torn down. + /// They live forever until the context is torn down. Also used to store + /// DITypeIndex objects, which have the same lifetime. BumpPtrAllocator TypeAllocator; DenseMap IntegerTypes; Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -742,7 +742,9 @@ visitValueAsMetadata(*V, F); } -static bool isType(const Metadata *MD) { return !MD || isa(MD); } +static bool isType(const Metadata *MD) { + return !MD || isa(MD) || isa(MD); +} static bool isScope(const Metadata *MD) { return !MD || isa(MD); } static bool isDINode(const Metadata *MD) { return !MD || isa(MD); } @@ -948,7 +950,8 @@ if (auto *F = N.getRawFile()) Assert(isa(F), "invalid file", &N, F); if (auto *T = N.getRawType()) - Assert(isa(T), "invalid subroutine type", &N, T); + Assert(isa(T) || isa(T), + "invalid subroutine type", &N, T); Assert(isType(N.getRawContainingType()), "invalid containing type", &N, N.getRawContainingType()); if (auto *Params = N.getRawTemplateParams()) Index: lib/Transforms/Utils/ValueMapper.cpp =================================================================== --- lib/Transforms/Utils/ValueMapper.cpp +++ lib/Transforms/Utils/ValueMapper.cpp @@ -529,7 +529,8 @@ M.getVM().getMappedMD(Op)) && "Expected Value to be memoized"); else - assert((isa(Op) || M.getVM().getMappedMD(Op)) && + assert((isa(Op) || isa(Op) || + M.getVM().getMappedMD(Op)) && "Expected result to be memoized"); #endif return *MappedOp; @@ -565,7 +566,7 @@ if (Optional MappedOp = M.getVM().getMappedMD(Op)) return *MappedOp; - if (isa(Op)) + if (isa(Op) || isa(Op)) return const_cast(Op); if (auto *CMD = dyn_cast(Op)) @@ -784,7 +785,7 @@ if (Optional NewMD = getVM().getMappedMD(MD)) return *NewMD; - if (isa(MD)) + if (isa(MD) || isa(MD)) return const_cast(MD); // This is a module-level metadata. If nothing at the module level is Index: test/Assembler/ditypeindex.ll =================================================================== --- /dev/null +++ test/Assembler/ditypeindex.ll @@ -0,0 +1,46 @@ +; RUN: llvm-as < %s | llvm-dis | FileCheck %s + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +@y = global i32 3, align 4 + +; Function Attrs: nounwind +define void @f() #0 !dbg !4 { +entry: + %x = alloca i32, align 4 + call void @llvm.dbg.declare(metadata i32* %x, metadata !13, metadata !14), !dbg !15 + %0 = load i32, i32* @y, align 4, !dbg !15 + store i32 %0, i32* %x, align 4, !dbg !15 + ret void, !dbg !15 +} + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!11} +!llvm.ident = !{!12} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !8) +!1 = !DIFile(filename: "", directory: "D:\5Csrc\5Cllvm\5Cbuild") +!2 = !{} +!3 = !{!4} +!4 = distinct !DISubprogram(name: "f", scope: !5, file: !5, line: 2, type: !DITypeIndex(u0x74), isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, variables: !2) +!5 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild") +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !{!9} +!9 = !DIGlobalVariable(name: "y", scope: !0, file: !5, line: 1, type: !DITypeIndex(u0x74), isLocal: false, isDefinition: true, variable: i32* @y) +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{!"clang version 3.9.0 "} +!13 = !DILocalVariable(name: "x", scope: !4, file: !5, line: 2, type: !DITypeIndex(u0x74)) +!14 = !DIExpression() +!15 = !DILocation(line: 2, scope: !4) + +; CHECK-DAG: distinct !DISubprogram(name: "f", {{.*}}, type: !DITypeIndex(u0x74){{.*}}) +; CHECK-DAG: !DIGlobalVariable(name: "y", {{.*}}, type: !DITypeIndex(u0x74){{.*}}) +; CHECK-DAG: !DILocalVariable(name: "x", {{.*}}, type: !DITypeIndex(u0x74){{.*}}) Index: test/DebugInfo/COFF/local-constant.ll =================================================================== --- test/DebugInfo/COFF/local-constant.ll +++ test/DebugInfo/COFF/local-constant.ll @@ -58,7 +58,7 @@ !5 = !DISubroutineType(types: !6) !6 = !{null} !7 = !{!8} -!8 = !DILocalVariable(name: "x", scope: !4, file: !1, line: 3, type: !9) +!8 = !DILocalVariable(name: "x", scope: !4, file: !1, line: 3, type: !DITypeIndex(u0x74)) !9 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) !10 = !{i32 2, !"CodeView", i32 1} !11 = !{i32 2, !"Debug Info Version", i32 3} Index: test/DebugInfo/COFF/local-variables.ll =================================================================== --- test/DebugInfo/COFF/local-variables.ll +++ test/DebugInfo/COFF/local-variables.ll @@ -9,13 +9,13 @@ ; 4: int v = 3; ; 5: capture(&v); ; 6: } -; 7: extern "C" void f(int param) { +; 7: extern "C" void f(unsigned param) { ; 8: if (param) { ; 9: int a = 42; ; 10: will_be_inlined(); ; 11: capture(&a); ; 12: } else { -; 13: int b = 42; +; 13: unsigned b = 42; ; 14: will_be_inlined(); ; 15: capture(&b); ; 16: } @@ -72,7 +72,7 @@ ; ASM: [[param_end:\.Ltmp.*]]: ; ASM: .short 4414 # Record kind: S_LOCAL -; ASM: .long 116 # TypeIndex +; ASM: .long 117 # TypeIndex ; ASM: .short 1 # Flags ; ASM: .asciz "param" ; ASM: .cv_def_range [[prologue_end]] [[param_end]], "E\021O\001\000\000,\000\000\000" @@ -82,7 +82,7 @@ ; ASM: .asciz "a" ; ASM: .cv_def_range [[if_start]] [[else_start]], "E\021O\001\000\000(\000\000\000" ; ASM: .short 4414 # Record kind: S_LOCAL -; ASM: .long 116 # TypeIndex +; ASM: .long 117 # TypeIndex ; ASM: .short 0 # Flags ; ASM: .asciz "b" ; ASM: .cv_def_range [[else_start]] [[else_end]], "E\021O\001\000\000$\000\000\000" @@ -108,7 +108,7 @@ ; OBJ: LinkageName: f ; OBJ: } ; OBJ: Local { -; OBJ: Type: int (0x74) +; OBJ: Type: unsigned (0x75) ; OBJ: Flags [ (0x1) ; OBJ: IsParameter (0x1) ; OBJ: ] @@ -143,7 +143,7 @@ ; OBJ: } ; OBJ: } ; OBJ: Local { -; OBJ: Type: int (0x74) +; OBJ: Type: unsigned (0x75) ; OBJ: Flags [ (0x0) ; OBJ: ] ; OBJ: VarName: b @@ -279,18 +279,13 @@ !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.9.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) !1 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild") !2 = !{} -!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 7, type: !5, isLocal: false, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) -!5 = !DISubroutineType(types: !6) -!6 = !{null, !7} -!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) -!8 = distinct !DISubprogram(name: "will_be_inlined", linkageName: "\01?will_be_inlined@@YAXXZ", scope: !1, file: !1, line: 3, type: !9, isLocal: true, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) -!9 = !DISubroutineType(types: !10) -!10 = !{null} +!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 7, type: !DITypeIndex(u0x1003), isLocal: false, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!8 = distinct !DISubprogram(name: "will_be_inlined", linkageName: "\01?will_be_inlined@@YAXXZ", scope: !1, file: !1, line: 3, type: !DITypeIndex(u0x1003), isLocal: true, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) !11 = !{i32 2, !"CodeView", i32 1} !12 = !{i32 2, !"Debug Info Version", i32 3} !13 = !{i32 1, !"PIC Level", i32 2} !14 = !{!"clang version 3.9.0 "} -!15 = !DILocalVariable(name: "v", scope: !8, file: !1, line: 4, type: !7) +!15 = !DILocalVariable(name: "v", scope: !8, file: !1, line: 4, type: !DITypeIndex(u0x74)) !16 = !DIExpression() !17 = !DILocation(line: 4, column: 7, scope: !8, inlinedAt: !18) !18 = distinct !DILocation(line: 14, column: 5, scope: !19) @@ -299,16 +294,16 @@ !21 = !DILocation(line: 4, column: 7, scope: !8, inlinedAt: !22) !22 = distinct !DILocation(line: 10, column: 5, scope: !23) !23 = distinct !DILexicalBlock(scope: !20, file: !1, line: 8, column: 14) -!24 = !DILocalVariable(name: "param", arg: 1, scope: !4, file: !1, line: 7, type: !7) +!24 = !DILocalVariable(name: "param", arg: 1, scope: !4, file: !1, line: 7, type: !DITypeIndex(u0x75)) !25 = !DILocation(line: 7, column: 23, scope: !4) !26 = !DILocation(line: 8, column: 7, scope: !20) !27 = !DILocation(line: 8, column: 7, scope: !4) -!28 = !DILocalVariable(name: "a", scope: !23, file: !1, line: 9, type: !7) +!28 = !DILocalVariable(name: "a", scope: !23, file: !1, line: 9, type: !DITypeIndex(u0x74)) !29 = !DILocation(line: 9, column: 9, scope: !23) !30 = !DILocation(line: 5, column: 3, scope: !8, inlinedAt: !22) !31 = !DILocation(line: 11, column: 5, scope: !23) !32 = !DILocation(line: 12, column: 3, scope: !23) -!33 = !DILocalVariable(name: "b", scope: !19, file: !1, line: 13, type: !7) +!33 = !DILocalVariable(name: "b", scope: !19, file: !1, line: 13, type: !DITypeIndex(u0x75)) !34 = !DILocation(line: 13, column: 9, scope: !19) !35 = !DILocation(line: 5, column: 3, scope: !8, inlinedAt: !18) !36 = !DILocation(line: 15, column: 5, scope: !19) Index: test/DebugInfo/COFF/register-variables.ll =================================================================== --- test/DebugInfo/COFF/register-variables.ll +++ test/DebugInfo/COFF/register-variables.ll @@ -242,27 +242,21 @@ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 260617) (llvm/trunk 260619)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !22) !1 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvm\5Cbuild") !2 = !{} -!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 9, type: !5, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !8) -!5 = !DISubroutineType(types: !6) -!6 = !{null, !7} -!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 9, type: !DITypeIndex(u0x1003), isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !8) !8 = !{!9, !10, !13, !14} -!9 = !DILocalVariable(name: "p", arg: 1, scope: !4, file: !1, line: 9, type: !7) -!10 = !DILocalVariable(name: "a", scope: !11, file: !1, line: 11, type: !7) +!9 = !DILocalVariable(name: "p", arg: 1, scope: !4, file: !1, line: 9, type: !DITypeIndex(u0x74)) +!10 = !DILocalVariable(name: "a", scope: !11, file: !1, line: 11, type: !DITypeIndex(u0x74)) !11 = distinct !DILexicalBlock(scope: !12, file: !1, line: 10, column: 10) !12 = distinct !DILexicalBlock(scope: !4, file: !1, line: 10, column: 7) -!13 = !DILocalVariable(name: "b", scope: !11, file: !1, line: 12, type: !7) -!14 = !DILocalVariable(name: "c", scope: !15, file: !1, line: 15, type: !7) +!13 = !DILocalVariable(name: "b", scope: !11, file: !1, line: 12, type: !DITypeIndex(u0x74)) +!14 = !DILocalVariable(name: "c", scope: !15, file: !1, line: 15, type: !DITypeIndex(u0x74)) !15 = distinct !DILexicalBlock(scope: !12, file: !1, line: 14, column: 10) -!16 = distinct !DISubprogram(name: "inlineinc", scope: !1, file: !1, line: 4, type: !17, isLocal: true, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !19) -!17 = !DISubroutineType(types: !18) -!18 = !{!7, !7} +!16 = distinct !DISubprogram(name: "inlineinc", scope: !1, file: !1, line: 4, type: !DITypeIndex(u0x1003), isLocal: true, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !19) !19 = !{!20, !21} -!20 = !DILocalVariable(name: "a", arg: 1, scope: !16, file: !1, line: 4, type: !7) -!21 = !DILocalVariable(name: "b", scope: !16, file: !1, line: 5, type: !7) +!20 = !DILocalVariable(name: "a", arg: 1, scope: !16, file: !1, line: 4, type: !DITypeIndex(u0x74)) +!21 = !DILocalVariable(name: "b", scope: !16, file: !1, line: 5, type: !DITypeIndex(u0x74)) !22 = !{!23} -!23 = !DIGlobalVariable(name: "x", scope: !0, file: !1, line: 1, type: !24, isLocal: false, isDefinition: true, variable: i32* @x) -!24 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !7) +!23 = !DIGlobalVariable(name: "x", scope: !0, file: !1, line: 1, type: !DITypeIndex(u0x74), isLocal: false, isDefinition: true, variable: i32* @x) !25 = !{i32 2, !"CodeView", i32 1} !26 = !{i32 2, !"Debug Info Version", i32 3} !27 = !{i32 1, !"PIC Level", i32 2} Index: test/Linker/Inputs/ditypeindex.ll =================================================================== --- /dev/null +++ test/Linker/Inputs/ditypeindex.ll @@ -0,0 +1,17 @@ +@b = global i32 2 +@c = global i64 3 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3) +!1 = !DIFile(filename: "t.c", directory: "D:\5Csrc\5Cllvm\5Cbuild") +!2 = !{} +!3 = !{!4, !5} +!4 = !DIGlobalVariable(name: "b", scope: !0, file: !1, line: 1, type: !DITypeIndex(u0x74), isLocal: false, isDefinition: true, variable: i32* @b) +!5 = !DIGlobalVariable(name: "c", scope: !0, file: !1, line: 1, type: !DITypeIndex(u0x13), isLocal: false, isDefinition: true, variable: i64* @c) +!6 = !{i32 2, !"CodeView", i32 1} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"PIC Level", i32 2} +!9 = !{!"clang version 3.9.0 "} Index: test/Linker/ditypeindex.ll =================================================================== --- /dev/null +++ test/Linker/ditypeindex.ll @@ -0,0 +1,24 @@ +; RUN: llvm-link %s %S/Inputs/ditypeindex.ll -S -o - | FileCheck %s + +@a = global i32 1 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3) +!1 = !DIFile(filename: "t.c", directory: "D:\5Csrc\5Cllvm\5Cbuild") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariable(name: "a", scope: !0, file: !1, line: 1, type: !DITypeIndex(u0x74), isLocal: false, isDefinition: true, variable: i32* @a) +!6 = !{i32 2, !"CodeView", i32 1} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"PIC Level", i32 2} +!9 = !{!"clang version 3.9.0 "} + +; CHECK: @a = global i32 1 +; CHECK: @b = global i32 2 +; CHECK: @c = global i64 3 +; CHECK: !DIGlobalVariable(name: "a", {{.*}}type: !DITypeIndex(u0x74){{.*}}variable: i32* @a) +; CHECK: !DIGlobalVariable(name: "b", {{.*}}type: !DITypeIndex(u0x74){{.*}}variable: i32* @b) +; CHECK: !DIGlobalVariable(name: "c", {{.*}}type: !DITypeIndex(u0x13){{.*}}variable: i64* @c) Index: unittests/IR/IRBuilderTest.cpp =================================================================== --- unittests/IR/IRBuilderTest.cpp +++ unittests/IR/IRBuilderTest.cpp @@ -343,12 +343,12 @@ auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/", "llvm-cobol74", true, "", 0); auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); - auto SP = - DIB.createFunction(CU, "foo", "", File, 1, Type, false, true, 1, 0, true); + auto SP = DIB.createFunction(CU, "foo", "", File, 1, DITypeRef(Type), false, + true, 1, 0, true); F->setSubprogram(SP); AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty()); - auto BarSP = - DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1, 0, true); + auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, DITypeRef(Type), + false, true, 1, 0, true); auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0); I->setDebugLoc(DebugLoc::get(2, 0, BadScope)); DIB.finalize(); @@ -395,8 +395,8 @@ auto CU = DIB.createCompileUnit(dwarf::DW_LANG_C_plus_plus_11, "tmp.cpp", "/", "", true, "", 0); auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); - auto SP = - DIB.createFunction(CU, "foo", "foo", File, 1, SPType, false, true, 1); + auto SP = DIB.createFunction(CU, "foo", "foo", File, 1, DITypeRef(SPType), + false, true, 1); DebugLoc DL1 = DILocation::get(Ctx, 2, 0, SP); DebugLoc DL2 = DILocation::get(Ctx, 3, 0, SP); Index: unittests/IR/MetadataTest.cpp =================================================================== --- unittests/IR/MetadataTest.cpp +++ unittests/IR/MetadataTest.cpp @@ -79,8 +79,9 @@ } MDTuple *getTuple() { return MDTuple::getDistinct(Context, None); } - DISubroutineType *getSubroutineType() { - return DISubroutineType::getDistinct(Context, 0, getNode(nullptr)); + DITypeRef getSubroutineType() { + return DITypeRef( + DISubroutineType::getDistinct(Context, 0, getNode(nullptr))); } DISubprogram *getSubprogram() { return DISubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0, @@ -1400,7 +1401,7 @@ StringRef LinkageName = "linkage"; DIFile *File = getFile(); unsigned Line = 2; - DISubroutineType *Type = getSubroutineType(); + DITypeRef Type = getSubroutineType(); bool IsLocalToUnit = false; bool IsDefinition = true; unsigned ScopeLine = 3; Index: unittests/Transforms/Utils/Cloning.cpp =================================================================== --- unittests/Transforms/Utils/Cloning.cpp +++ unittests/Transforms/Utils/Cloning.cpp @@ -229,8 +229,7 @@ // Function DI auto *File = DBuilder.createFile("filename.c", "/file/dir/"); DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None); - DISubroutineType *FuncType = - DBuilder.createSubroutineType(ParamTypes); + DITypeRef FuncType(DBuilder.createSubroutineType(ParamTypes)); auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c", "/file/dir", "CloneFunc", false, "", 0); @@ -420,7 +419,7 @@ // Create debug info auto *File = DBuilder.createFile("filename.c", "/file/dir/"); DITypeRefArray ParamTypes = DBuilder.getOrCreateTypeArray(None); - DISubroutineType *DFuncType = DBuilder.createSubroutineType(ParamTypes); + DITypeRef DFuncType(DBuilder.createSubroutineType(ParamTypes)); auto *CU = DBuilder.createCompileUnit(dwarf::DW_LANG_C99, "filename.c", "/file/dir", "CloneModule", false, "", 0);