Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -1494,16 +1494,16 @@ // Collect virtual method info. llvm::DIType *ContainingType = nullptr; - unsigned Virtuality = 0; unsigned VIndex = 0; llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero; int ThisAdjustment = 0; if (Method->isVirtual()) { if (Method->isPure()) - Virtuality = llvm::dwarf::DW_VIRTUALITY_pure_virtual; + SPFlags |= llvm::DISubprogram::SPFlagPureVirtual; else - Virtuality = llvm::dwarf::DW_VIRTUALITY_virtual; + SPFlags |= llvm::DISubprogram::SPFlagVirtual; if (CGM.getTarget().getCXXABI().isItaniumFamily()) { // It doesn't make sense to give a virtual destructor a vtable index, @@ -1555,12 +1555,13 @@ Flags |= llvm::DINode::FlagLValueReference; if (Method->getRefQualifier() == RQ_RValue) Flags |= llvm::DINode::FlagRValueReference; + if (CGM.getLangOpts().Optimize) + SPFlags |= llvm::DISubprogram::SPFlagOptimized; llvm::DINodeArray TParamsArray = CollectFunctionTemplateParams(Method, Unit); llvm::DISubprogram *SP = DBuilder.createMethod( RecordTy, MethodName, MethodLinkageName, MethodDefUnit, MethodLine, - MethodTy, /*isLocalToUnit=*/false, /*isDefinition=*/false, Virtuality, - VIndex, ThisAdjustment, ContainingType, Flags, CGM.getLangOpts().Optimize, + MethodTy, VIndex, ThisAdjustment, ContainingType, Flags, SPFlags, TParamsArray.get()); SPCache[Method->getCanonicalDecl()].reset(SP); @@ -3168,6 +3169,7 @@ llvm::DINodeArray TParamsArray; StringRef Name, LinkageName; llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero; SourceLocation Loc = GD.getDecl()->getLocation(); llvm::DIFile *Unit = getOrCreateFile(Loc); llvm::DIScope *DContext = Unit; @@ -3184,21 +3186,23 @@ CallingConv CC = FD->getType()->castAs()->getCallConv(); QualType FnType = CGM.getContext().getFunctionType( FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC)); + if (!FD->isExternallyVisible()) + SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit; + if (CGM.getLangOpts().Optimize) + SPFlags |= llvm::DISubprogram::SPFlagOptimized; + if (Stub) { Flags |= getCallSiteRelatedAttrs(); + SPFlags |= llvm::DISubprogram::SPFlagDefinition; return DBuilder.createFunction( DContext, Name, LinkageName, Unit, Line, - getOrCreateFunctionType(GD.getDecl(), FnType, Unit), - !FD->isExternallyVisible(), - /* isDefinition = */ true, 0, Flags, CGM.getLangOpts().Optimize, + getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags, TParamsArray.get(), getFunctionDeclaration(FD)); } llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl( DContext, Name, LinkageName, Unit, Line, - getOrCreateFunctionType(GD.getDecl(), FnType, Unit), - !FD->isExternallyVisible(), - /* isDefinition = */ false, 0, Flags, CGM.getLangOpts().Optimize, + getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags, TParamsArray.get(), getFunctionDeclaration(FD)); const FunctionDecl *CanonDecl = FD->getCanonicalDecl(); FwdDeclReplaceMap.emplace_back(std::piecewise_construct, @@ -3386,6 +3390,7 @@ bool HasDecl = (D != nullptr); llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero; + llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero; llvm::DIFile *Unit = getOrCreateFile(Loc); llvm::DIScope *FDContext = Unit; llvm::DINodeArray TParamsArray; @@ -3425,7 +3430,14 @@ if (CurFuncIsThunk) Flags |= llvm::DINode::FlagThunk; + if (Fn->hasLocalLinkage()) + SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit; + if (CGM.getLangOpts().Optimize) + SPFlags |= llvm::DISubprogram::SPFlagOptimized; + llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs(); + llvm::DISubprogram::DISPFlags SPFlagsForDef = + SPFlags | llvm::DISubprogram::SPFlagDefinition; unsigned LineNo = getLineNumber(Loc); unsigned ScopeLine = getLineNumber(ScopeLoc); @@ -3437,9 +3449,8 @@ // are emitted as CU level entities by the backend. llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, - getOrCreateFunctionType(D, FnType, Unit), Fn->hasLocalLinkage(), - true /*definition*/, ScopeLine, FlagsForDef, CGM.getLangOpts().Optimize, - TParamsArray.get(), getFunctionDeclaration(D)); + getOrCreateFunctionType(D, FnType, Unit), ScopeLine, FlagsForDef, + SPFlagsForDef, TParamsArray.get(), getFunctionDeclaration(D)); Fn->setSubprogram(SP); // We might get here with a VarDecl in the case we're generating // code for the initialization of globals. Do not record these decls @@ -3459,8 +3470,7 @@ cast(It->second); llvm::DISubprogram *FD = DBuilder.createFunction( InterfaceDecl, Name, LinkageName, Unit, LineNo, - getOrCreateFunctionType(D, FnType, Unit), Fn->hasLocalLinkage(), - false /*definition*/, ScopeLine, Flags, CGM.getLangOpts().Optimize, + getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags, TParamsArray.get()); DBuilder.finalizeSubprogram(FD); ObjCMethodCache[ID].push_back(FD); @@ -3509,11 +3519,13 @@ } unsigned LineNo = getLineNumber(Loc); unsigned ScopeLine = 0; + llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero; + if (CGM.getLangOpts().Optimize) + SPFlags |= llvm::DISubprogram::SPFlagOptimized; DBuilder.retainType(DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, - getOrCreateFunctionType(D, FnType, Unit), false /*internalLinkage*/, - false /*definition*/, ScopeLine, Flags, CGM.getLangOpts().Optimize, + getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags, TParamsArray.get(), getFunctionDeclaration(D))); } Index: llvm/include/llvm/IR/DIBuilder.h =================================================================== --- llvm/include/llvm/IR/DIBuilder.h +++ llvm/include/llvm/IR/DIBuilder.h @@ -653,29 +653,28 @@ /// \param File File where this variable is defined. /// \param LineNo Line number. /// \param Ty Function type. - /// \param isLocalToUnit True if this function is not externally visible. - /// \param isDefinition True if this is a function definition. /// \param ScopeLine Set to the beginning of the scope this starts /// \param Flags e.g. is this function prototyped or not. /// These flags are used to emit dwarf attributes. - /// \param isOptimized True if optimization is ON. + /// \param SPFlags Additional flags specific to subprograms. /// \param TParams Function template parameters. /// \param ThrownTypes Exception types this function may throw. - DISubprogram *createFunction( - DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, - bool isDefinition, unsigned ScopeLine, - DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false, - DITemplateParameterArray TParams = nullptr, - DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr); + DISubprogram * + createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, + DIFile *File, unsigned LineNo, DISubroutineType *Ty, + unsigned ScopeLine, DINode::DIFlags Flags = DINode::FlagZero, + DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero, + DITemplateParameterArray TParams = nullptr, + DISubprogram *Decl = nullptr, + DITypeArray ThrownTypes = nullptr); /// Identical to createFunction, /// 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, - bool isDefinition, unsigned ScopeLine, - DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false, + unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, + DINode::DIFlags Flags = DINode::FlagZero, + DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero, DITemplateParameterArray TParams = nullptr, DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr); @@ -687,10 +686,6 @@ /// \param File File where this variable is defined. /// \param LineNo Line number. /// \param Ty Function type. - /// \param isLocalToUnit True if this function is not externally visible.. - /// \param isDefinition True if this is a function definition. - /// \param Virtuality Attributes describing virtualness. e.g. pure - /// virtual function. /// \param VTableIndex Index no of this method in virtual table, or -1u if /// unrepresentable. /// \param ThisAdjustment @@ -699,17 +694,18 @@ /// \param VTableHolder Type that holds vtable. /// \param Flags e.g. is this function prototyped or not. /// This flags are used to emit dwarf attributes. - /// \param isOptimized True if optimization is ON. + /// \param SPFlags Additional flags specific to subprograms. /// \param TParams Function template parameters. /// \param ThrownTypes Exception types this function may throw. - DISubprogram *createMethod( - DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, - bool isDefinition, unsigned Virtuality = 0, unsigned VTableIndex = 0, - int ThisAdjustment = 0, DIType *VTableHolder = nullptr, - DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false, - DITemplateParameterArray TParams = nullptr, - DITypeArray ThrownTypes = nullptr); + DISubprogram * + createMethod(DIScope *Scope, StringRef Name, StringRef LinkageName, + DIFile *File, unsigned LineNo, DISubroutineType *Ty, + unsigned VTableIndex = 0, int ThisAdjustment = 0, + DIType *VTableHolder = nullptr, + DINode::DIFlags Flags = DINode::FlagZero, + DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero, + DITemplateParameterArray TParams = nullptr, + DITypeArray ThrownTypes = nullptr); /// This creates new descriptor for a namespace with the specified /// parent scope. Index: llvm/include/llvm/IR/DebugInfoFlags.def =================================================================== --- llvm/include/llvm/IR/DebugInfoFlags.def +++ llvm/include/llvm/IR/DebugInfoFlags.def @@ -12,10 +12,20 @@ //===----------------------------------------------------------------------===// // TODO: Add other DW-based macros. +#if !(defined HANDLE_DI_FLAG || defined HANDLE_DISP_FLAG) +#error "Missing macro definition of HANDLE_DI*" +#endif + #ifndef HANDLE_DI_FLAG -#error "Missing macro definition of HANDLE_DI_FLAG" +#define HANDLE_DI_FLAG(ID, NAME) #endif +#ifndef HANDLE_DISP_FLAG +#define HANDLE_DISP_FLAG(ID, NAME) +#endif + +// General flags kept in DINode. + HANDLE_DI_FLAG(0, Zero) // Use it as zero value. // For example: void foo(DIFlags Flags = FlagZero). HANDLE_DI_FLAG(1, Private) @@ -64,4 +74,25 @@ #undef DI_FLAG_LARGEST_NEEDED #endif +// Subprogram-specific flags kept in DISubprogram. + +// Use this as a zero/initialization value. +// For example: void foo(DISPFlags Flags = SPFlagZero). +HANDLE_DISP_FLAG(0, Zero) +// Virtuality is a two-bit valued field. +HANDLE_DISP_FLAG(0u, Nonvirtual) +HANDLE_DISP_FLAG(1u, Virtual) +HANDLE_DISP_FLAG(2u, PureVirtual) +HANDLE_DISP_FLAG((1u << 2), LocalToUnit) +HANDLE_DISP_FLAG((1u << 3), Definition) +HANDLE_DISP_FLAG((1u << 4), Optimized) + +#ifdef DISP_FLAG_LARGEST_NEEDED +// Intended to be used with ADT/BitmaskEnum.h. +// NOTE: Always must be equal to largest flag, check this when adding new flags. +HANDLE_DISP_FLAG((1 << 4), Largest) +#undef DISP_FLAG_LARGEST_NEEDED +#endif + #undef HANDLE_DI_FLAG +#undef HANDLE_DISP_FLAG Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1614,102 +1614,104 @@ /// negative. int ThisAdjustment; - // Virtuality can only assume three values, so we can pack - // in 2 bits (none/pure/pure_virtual). - unsigned Virtuality : 2; - - // These are boolean flags so one bit is enough. - // MSVC starts a new container field every time the base - // type changes so we can't use 'bool' to ensure these bits - // are packed. - unsigned IsLocalToUnit : 1; - unsigned IsDefinition : 1; - unsigned IsOptimized : 1; - - unsigned Padding : 3; +public: + /// Debug info subprogram flags. + enum DISPFlags : uint32_t { +#define HANDLE_DISP_FLAG(ID, NAME) SPFlag##NAME = ID, +#define DISP_FLAG_LARGEST_NEEDED +#include "llvm/IR/DebugInfoFlags.def" + SPFlagVirtuality = SPFlagNonvirtual | SPFlagVirtual | SPFlagPureVirtual, + LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest) + }; + // Helper for converting old bitfields to new flags word. + static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, + bool IsOptimized, + unsigned Virtuality = SPFlagNonvirtual) { + // We're assuming virtuality is the low-order field. + static_assert(SPFlagVirtual == dwarf::DW_VIRTUALITY_virtual && + SPFlagPureVirtual == dwarf::DW_VIRTUALITY_pure_virtual, + "Virtuality constant mismatch"); + return static_cast((Virtuality & SPFlagVirtuality) | + (IsLocalToUnit ? SPFlagLocalToUnit : 0) | + (IsDefinition ? SPFlagDefinition : 0) | + (IsOptimized ? SPFlagOptimized : 0)); + } +private: DIFlags Flags; + DISPFlags SPFlags; DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line, - unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex, - int ThisAdjustment, DIFlags Flags, bool IsLocalToUnit, - bool IsDefinition, bool IsOptimized, ArrayRef Ops) + unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment, + DIFlags Flags, DISPFlags SPFlags, ArrayRef Ops) : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops), Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex), - ThisAdjustment(ThisAdjustment), Virtuality(Virtuality), - IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), - IsOptimized(IsOptimized), Flags(Flags) { + ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) { static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range"); - assert(Virtuality < 4 && "Virtuality out of range"); } ~DISubprogram() = default; static DISubprogram * getImpl(LLVMContext &Context, DIScopeRef Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, - DISubroutineType *Type, bool IsLocalToUnit, bool IsDefinition, - unsigned ScopeLine, DITypeRef ContainingType, unsigned Virtuality, + DISubroutineType *Type, unsigned ScopeLine, DITypeRef ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, - bool IsOptimized, DICompileUnit *Unit, + DISPFlags SPFlags, DICompileUnit *Unit, DITemplateParameterArray TemplateParams, DISubprogram *Declaration, DINodeArray RetainedNodes, DITypeArray ThrownTypes, StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams.get(), Declaration, RetainedNodes.get(), - ThrownTypes.get(), Storage, ShouldCreate); + ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, + Flags, SPFlags, Unit, TemplateParams.get(), Declaration, + RetainedNodes.get(), ThrownTypes.get(), Storage, + ShouldCreate); } - static DISubprogram * - getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, - MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, - bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, - Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, - int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit, - Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, - Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate = true); + static DISubprogram *getImpl(LLVMContext &Context, Metadata *Scope, + MDString *Name, MDString *LinkageName, + Metadata *File, unsigned Line, Metadata *Type, + unsigned ScopeLine, Metadata *ContainingType, + unsigned VirtualIndex, int ThisAdjustment, + DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, + Metadata *TemplateParams, Metadata *Declaration, + Metadata *RetainedNodes, Metadata *ThrownTypes, + StorageType Storage, bool ShouldCreate = true); TempDISubprogram cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), getLinkageName(), - getFile(), getLine(), getType(), isLocalToUnit(), - isDefinition(), getScopeLine(), getContainingType(), - getVirtuality(), getVirtualIndex(), getThisAdjustment(), - getFlags(), isOptimized(), getUnit(), - getTemplateParams(), getDeclaration(), getRetainedNodes(), - getThrownTypes()); + getFile(), getLine(), getType(), getScopeLine(), + getContainingType(), getVirtualIndex(), + getThisAdjustment(), getFlags(), getSPFlags(), + getUnit(), getTemplateParams(), getDeclaration(), + getRetainedNodes(), getThrownTypes()); } public: - DEFINE_MDNODE_GET(DISubprogram, - (DIScopeRef Scope, StringRef Name, StringRef LinkageName, - DIFile *File, unsigned Line, DISubroutineType *Type, - bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, - DITypeRef ContainingType, unsigned Virtuality, - unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, - bool IsOptimized, DICompileUnit *Unit, - DITemplateParameterArray TemplateParams = nullptr, - DISubprogram *Declaration = nullptr, - DINodeArray RetainedNodes = nullptr, - DITypeArray ThrownTypes = nullptr), - (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, ScopeLine, ContainingType, Virtuality, - VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes)) + DEFINE_MDNODE_GET( + DISubprogram, + (DIScopeRef Scope, StringRef Name, StringRef LinkageName, DIFile *File, + unsigned Line, DISubroutineType *Type, unsigned ScopeLine, + DITypeRef ContainingType, unsigned VirtualIndex, int ThisAdjustment, + DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, + DITemplateParameterArray TemplateParams = nullptr, + DISubprogram *Declaration = nullptr, DINodeArray RetainedNodes = nullptr, + DITypeArray ThrownTypes = nullptr), + (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, + VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, + Declaration, RetainedNodes, ThrownTypes)) + DEFINE_MDNODE_GET( DISubprogram, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, - unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, - unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, - unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, - bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr, - Metadata *Declaration = nullptr, Metadata *RetainedNodes = nullptr, - Metadata *ThrownTypes = nullptr), - (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, - ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, - Flags, IsOptimized, Unit, TemplateParams, Declaration, RetainedNodes, - ThrownTypes)) + unsigned Line, Metadata *Type, unsigned ScopeLine, + Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, + DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, + Metadata *TemplateParams = nullptr, Metadata *Declaration = nullptr, + Metadata *RetainedNodes = nullptr, Metadata *ThrownTypes = nullptr), + (Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, + VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, + Declaration, RetainedNodes, ThrownTypes)) TempDISubprogram clone() const { return cloneImpl(); } @@ -1722,14 +1724,15 @@ public: unsigned getLine() const { return Line; } - unsigned getVirtuality() const { return Virtuality; } + unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; } unsigned getVirtualIndex() const { return VirtualIndex; } int getThisAdjustment() const { return ThisAdjustment; } unsigned getScopeLine() const { return ScopeLine; } DIFlags getFlags() const { return Flags; } - bool isLocalToUnit() const { return IsLocalToUnit; } - bool isDefinition() const { return IsDefinition; } - bool isOptimized() const { return IsOptimized; } + DISPFlags getSPFlags() const { return SPFlags; } + bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; } + bool isDefinition() const { return getSPFlags() & SPFlagDefinition; } + bool isOptimized() const { return getSPFlags() & SPFlagOptimized; } bool isArtificial() const { return getFlags() & FlagArtificial; } bool isPrivate() const { Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -4549,13 +4549,13 @@ return Lex.Error( Loc, "missing 'distinct', required for !DISubprogram when 'isDefinition'"); - + DISubprogram::DISPFlags SPFlags = DISubprogram::toSPFlags( + isLocal.Val, isDefinition.Val, isOptimized.Val, virtuality.Val); Result = GET_OR_DISTINCT( DISubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, - type.Val, isLocal.Val, isDefinition.Val, scopeLine.Val, - containingType.Val, virtuality.Val, virtualIndex.Val, thisAdjustment.Val, - flags.Val, isOptimized.Val, unit.Val, templateParams.Val, + type.Val, scopeLine.Val, containingType.Val, virtualIndex.Val, + thisAdjustment.Val, flags.Val, SPFlags, unit.Val, templateParams.Val, declaration.Val, retainedNodes.Val, thrownTypes.Val)); return false; } Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1420,6 +1420,9 @@ bool HasFn = Offset && !HasUnit; bool HasThisAdj = Record.size() >= 20; bool HasThrownTypes = Record.size() >= 21; + DISubprogram::DISPFlags SPFlags = DISubprogram::toSPFlags( + /*IsLocalToUnit=*/Record[7], /*IsDefinition=*/Record[8], + /*IsOptimized=*/Record[14], /*Virtuality=*/Record[11]); DISubprogram *SP = GET_OR_DISTINCT( DISubprogram, (Context, @@ -1429,15 +1432,12 @@ getMDOrNull(Record[4]), // file Record[5], // line getMDOrNull(Record[6]), // type - Record[7], // isLocal - Record[8], // isDefinition Record[9], // scopeLine getDITypeRefOrNull(Record[10]), // containingType - Record[11], // virtuality Record[12], // virtualIndex HasThisAdj ? Record[19] : 0, // thisAdjustment static_cast(Record[13]), // flags - Record[14], // isOptimized + SPFlags, // SPFlags HasUnit ? CUorFn : nullptr, // unit getMDOrNull(Record[15 + Offset]), // templateParams getMDOrNull(Record[16 + Offset]), // declaration Index: llvm/lib/CodeGen/MachineOutliner.cpp =================================================================== --- llvm/lib/CodeGen/MachineOutliner.cpp +++ llvm/lib/CodeGen/MachineOutliner.cpp @@ -1395,9 +1395,10 @@ Unit /* File */, 0 /* Line 0 is reserved for compiler-generated code. */, DB.createSubroutineType(DB.getOrCreateTypeArray(None)), /* void type */ - false, true, 0, /* Line 0 is reserved for compiler-generated code. */ + 0, /* Line 0 is reserved for compiler-generated code. */ DINode::DIFlags::FlagArtificial /* Compiler-generated code. */, - true /* Outlined code is optimized code by definition. */); + /* Outlined code is optimized code by definition. */ + DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized); // Don't add any new variables to the subprogram. DB.finalizeSubprogram(OutlinedSP); Index: llvm/lib/IR/DIBuilder.cpp =================================================================== --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -751,18 +751,18 @@ DISubprogram *DIBuilder::createFunction( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, - bool isDefinition, unsigned ScopeLine, DINode::DIFlags Flags, - bool isOptimized, DITemplateParameterArray TParams, DISubprogram *Decl, + unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, + DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, + DITemplateParameterArray TParams, DISubprogram *Decl, DITypeArray ThrownTypes) { + bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition; auto *Node = getSubprogram( - /* IsDistinct = */ isDefinition, VMContext, - getNonCompileUnitScope(Context), Name, LinkageName, File, LineNo, Ty, - isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, 0, Flags, - isOptimized, isDefinition ? CUNode : nullptr, TParams, Decl, + /*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context), + Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags, + SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, MDTuple::getTemporary(VMContext, None).release(), ThrownTypes); - if (isDefinition) + if (IsDefinition) AllSubprograms.push_back(Node); trackIfUnresolved(Node); return Node; @@ -770,35 +770,37 @@ DISubprogram *DIBuilder::createTempFunctionFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, - bool isDefinition, unsigned ScopeLine, DINode::DIFlags Flags, - bool isOptimized, DITemplateParameterArray TParams, DISubprogram *Decl, + unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, + DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, + DITemplateParameterArray TParams, DISubprogram *Decl, DITypeArray ThrownTypes) { - return DISubprogram::getTemporary( - VMContext, getNonCompileUnitScope(Context), Name, LinkageName, - File, LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, nullptr, - 0, 0, 0, Flags, isOptimized, isDefinition ? CUNode : nullptr, - TParams, Decl, nullptr, ThrownTypes) + bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition; + return DISubprogram::getTemporary(VMContext, getNonCompileUnitScope(Context), + Name, LinkageName, File, LineNo, Ty, + ScopeLine, nullptr, 0, 0, Flags, SPFlags, + IsDefinition ? CUNode : nullptr, TParams, + Decl, nullptr, ThrownTypes) .release(); } DISubprogram *DIBuilder::createMethod( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, - unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, - bool isDefinition, unsigned VK, unsigned VIndex, int ThisAdjustment, - DIType *VTableHolder, DINode::DIFlags Flags, bool isOptimized, - DITemplateParameterArray TParams, DITypeArray ThrownTypes) { + unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment, + DIType *VTableHolder, DINode::DIFlags Flags, + DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams, + DITypeArray ThrownTypes) { assert(getNonCompileUnitScope(Context) && "Methods should have both a Context and a context that isn't " "the compile unit."); // FIXME: Do we want to use different scope/lines? + bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition; auto *SP = getSubprogram( - /* IsDistinct = */ isDefinition, VMContext, cast(Context), Name, - LinkageName, F, LineNo, Ty, isLocalToUnit, isDefinition, LineNo, - VTableHolder, VK, VIndex, ThisAdjustment, Flags, isOptimized, - isDefinition ? CUNode : nullptr, TParams, nullptr, nullptr, ThrownTypes); + /*IsDistinct=*/IsDefinition, VMContext, cast(Context), Name, + LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment, + Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr, + nullptr, ThrownTypes); - if (isDefinition) + if (IsDefinition) AllSubprograms.push_back(SP); trackIfUnresolved(SP); return SP; Index: llvm/lib/IR/DebugInfo.cpp =================================================================== --- llvm/lib/IR/DebugInfo.cpp +++ llvm/lib/IR/DebugInfo.cpp @@ -438,11 +438,10 @@ auto distinctMDSubprogram = [&]() { return DISubprogram::getDistinct( MDS->getContext(), FileAndScope, MDS->getName(), LinkageName, - FileAndScope, MDS->getLine(), Type, MDS->isLocalToUnit(), - MDS->isDefinition(), MDS->getScopeLine(), ContainingType, - MDS->getVirtuality(), MDS->getVirtualIndex(), - MDS->getThisAdjustment(), MDS->getFlags(), MDS->isOptimized(), Unit, - TemplateParams, Declaration, Variables); + FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(), + ContainingType, MDS->getVirtualIndex(), MDS->getThisAdjustment(), + MDS->getFlags(), MDS->getSPFlags(), Unit, TemplateParams, Declaration, + Variables); }; if (MDS->isDistinct()) @@ -450,11 +449,9 @@ auto *NewMDS = DISubprogram::get( MDS->getContext(), FileAndScope, MDS->getName(), LinkageName, - FileAndScope, MDS->getLine(), Type, MDS->isLocalToUnit(), - MDS->isDefinition(), MDS->getScopeLine(), ContainingType, - MDS->getVirtuality(), MDS->getVirtualIndex(), MDS->getThisAdjustment(), - MDS->getFlags(), MDS->isOptimized(), Unit, TemplateParams, Declaration, - Variables); + FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(), ContainingType, + MDS->getVirtualIndex(), MDS->getThisAdjustment(), MDS->getFlags(), + MDS->getSPFlags(), Unit, TemplateParams, Declaration, Variables); StringRef OldLinkageName = MDS->getLinkageName(); @@ -720,6 +717,11 @@ return static_cast(Flags); } +static DISubprogram::DISPFlags +pack_into_DISPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized) { + return DISubprogram::toSPFlags(IsLocalToUnit, IsDefinition, IsOptimized); +} + unsigned LLVMDebugMetadataVersion() { return DEBUG_METADATA_VERSION; } @@ -803,9 +805,10 @@ unsigned ScopeLine, LLVMDIFlags Flags, LLVMBool IsOptimized) { return wrap(unwrap(Builder)->createFunction( unwrapDI(Scope), {Name, NameLen}, {LinkageName, LinkageNameLen}, - unwrapDI(File), LineNo, unwrapDI(Ty), - IsLocalToUnit, IsDefinition, ScopeLine, map_from_llvmDIFlags(Flags), - IsOptimized, nullptr, nullptr, nullptr)); + unwrapDI(File), LineNo, unwrapDI(Ty), ScopeLine, + map_from_llvmDIFlags(Flags), + pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized), nullptr, + nullptr, nullptr)); } Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -545,18 +545,17 @@ DISubprogram *DISubprogram::getImpl( LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, - bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, - Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, - int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit, + unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, + int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP( - DISubprogram, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, ScopeLine, ContainingType, Virtuality, - VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, - TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + DEFINE_GETIMPL_LOOKUP(DISubprogram, + (Scope, Name, LinkageName, File, Line, Type, ScopeLine, + ContainingType, VirtualIndex, ThisAdjustment, Flags, + SPFlags, Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); SmallVector Ops = { File, Scope, Name, LinkageName, Type, Unit, Declaration, RetainedNodes, ContainingType, TemplateParams, ThrownTypes}; @@ -568,11 +567,10 @@ Ops.pop_back(); } } - DEFINE_GETIMPL_STORE_N(DISubprogram, - (Line, ScopeLine, Virtuality, VirtualIndex, - ThisAdjustment, Flags, IsLocalToUnit, IsDefinition, - IsOptimized), - Ops, Ops.size()); + DEFINE_GETIMPL_STORE_N( + DISubprogram, + (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops, + Ops.size()); } bool DISubprogram::describes(const Function *F) const { Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -612,15 +612,12 @@ Metadata *File; unsigned Line; Metadata *Type; - bool IsLocalToUnit; - bool IsDefinition; unsigned ScopeLine; Metadata *ContainingType; - unsigned Virtuality; unsigned VirtualIndex; int ThisAdjustment; unsigned Flags; - bool IsOptimized; + unsigned SPFlags; Metadata *Unit; Metadata *TemplateParams; Metadata *Declaration; @@ -629,45 +626,39 @@ MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, - bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, - Metadata *ContainingType, unsigned Virtuality, + unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, - bool IsOptimized, Metadata *Unit, Metadata *TemplateParams, + unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes, Metadata *ThrownTypes) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), - Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), - IsDefinition(IsDefinition), ScopeLine(ScopeLine), - ContainingType(ContainingType), Virtuality(Virtuality), - VirtualIndex(VirtualIndex), ThisAdjustment(ThisAdjustment), - Flags(Flags), IsOptimized(IsOptimized), Unit(Unit), - TemplateParams(TemplateParams), Declaration(Declaration), + Line(Line), Type(Type), ScopeLine(ScopeLine), + ContainingType(ContainingType), VirtualIndex(VirtualIndex), + ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags), + Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration), RetainedNodes(RetainedNodes), ThrownTypes(ThrownTypes) {} MDNodeKeyImpl(const DISubprogram *N) : Scope(N->getRawScope()), Name(N->getRawName()), LinkageName(N->getRawLinkageName()), File(N->getRawFile()), - Line(N->getLine()), Type(N->getRawType()), - IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), - ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()), - Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()), + Line(N->getLine()), Type(N->getRawType()), ScopeLine(N->getScopeLine()), + ContainingType(N->getRawContainingType()), + VirtualIndex(N->getVirtualIndex()), ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()), - IsOptimized(N->isOptimized()), Unit(N->getRawUnit()), + SPFlags(N->getSPFlags()), Unit(N->getRawUnit()), TemplateParams(N->getRawTemplateParams()), - Declaration(N->getRawDeclaration()), RetainedNodes(N->getRawRetainedNodes()), + Declaration(N->getRawDeclaration()), + RetainedNodes(N->getRawRetainedNodes()), ThrownTypes(N->getRawThrownTypes()) {} bool isKeyOf(const DISubprogram *RHS) const { return Scope == RHS->getRawScope() && Name == RHS->getRawName() && LinkageName == RHS->getRawLinkageName() && File == RHS->getRawFile() && Line == RHS->getLine() && - Type == RHS->getRawType() && IsLocalToUnit == RHS->isLocalToUnit() && - IsDefinition == RHS->isDefinition() && - ScopeLine == RHS->getScopeLine() && + Type == RHS->getRawType() && ScopeLine == RHS->getScopeLine() && ContainingType == RHS->getRawContainingType() && - Virtuality == RHS->getVirtuality() && VirtualIndex == RHS->getVirtualIndex() && ThisAdjustment == RHS->getThisAdjustment() && - Flags == RHS->getFlags() && IsOptimized == RHS->isOptimized() && + Flags == RHS->getFlags() && SPFlags == RHS->getSPFlags() && Unit == RHS->getUnit() && TemplateParams == RHS->getRawTemplateParams() && Declaration == RHS->getRawDeclaration() && @@ -675,11 +666,13 @@ ThrownTypes == RHS->getRawThrownTypes(); } + bool isDefinition() const { return SPFlags & DISubprogram::SPFlagDefinition; } + unsigned getHashValue() const { // If this is a declaration inside an ODR type, only hash the type and the // name. Otherwise the hash will be stronger than // MDNodeSubsetEqualImpl::isDeclarationOfODRMember(). - if (!IsDefinition && LinkageName) + if (!isDefinition() && LinkageName) if (auto *CT = dyn_cast_or_null(Scope)) if (CT->getRawIdentifier()) return hash_combine(LinkageName, Scope); @@ -696,7 +689,7 @@ using KeyTy = MDNodeKeyImpl; static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) { - return isDeclarationOfODRMember(LHS.IsDefinition, LHS.Scope, + return isDeclarationOfODRMember(LHS.isDefinition(), LHS.Scope, LHS.LinkageName, LHS.TemplateParams, RHS); } Index: llvm/tools/opt/Debugify.cpp =================================================================== --- llvm/tools/opt/Debugify.cpp +++ llvm/tools/opt/Debugify.cpp @@ -96,11 +96,12 @@ continue; auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); - bool IsLocalToUnit = F.hasPrivateLinkage() || F.hasInternalLinkage(); - auto SP = - DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, SPType, - IsLocalToUnit, /*isDefinition=*/true, NextLine, - DINode::FlagZero, /*isOptimized=*/true); + DISubprogram::DISPFlags SPFlags = + DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized; + if (F.hasPrivateLinkage() || F.hasInternalLinkage()) + SPFlags |= DISubprogram::SPFlagLocalToUnit; + auto SP = DIB.createFunction(CU, F.getName(), F.getName(), File, NextLine, + SPType, NextLine, DINode::FlagZero, SPFlags); F.setSubprogram(SP); for (BasicBlock &BB : F) { // Attach debug locations. Index: llvm/unittests/CodeGen/MachineInstrTest.cpp =================================================================== --- llvm/unittests/CodeGen/MachineInstrTest.cpp +++ llvm/unittests/CodeGen/MachineInstrTest.cpp @@ -257,8 +257,8 @@ LLVMContext Ctx; DIFile *DIF = DIFile::getDistinct(Ctx, "filename", ""); DISubprogram *DIS = DISubprogram::getDistinct( - Ctx, nullptr, "", "", DIF, 0, nullptr, false, false, 0, nullptr, 0, 0, 0, - DINode::FlagZero, false, nullptr); + Ctx, nullptr, "", "", DIF, 0, nullptr, 0, nullptr, 0, 0, DINode::FlagZero, + DISubprogram::SPFlagZero, nullptr); DILocation *DIL = DILocation::get(Ctx, 1, 5, DIS); DebugLoc DL(DIL); MachineInstr *MI = MF->CreateMachineInstr(MCID, DL); Index: llvm/unittests/IR/IRBuilderTest.cpp =================================================================== --- llvm/unittests/IR/IRBuilderTest.cpp +++ llvm/unittests/IR/IRBuilderTest.cpp @@ -481,14 +481,16 @@ auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Swift, File, "swiftc", true, "", 0); auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); - auto NoErr = DIB.createFunction(CU, "noerr", "", File, 1, Type, false, true, 1, - DINode::FlagZero, true); + auto NoErr = DIB.createFunction( + CU, "noerr", "", File, 1, Type, 1, DINode::FlagZero, + DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized); EXPECT_TRUE(!NoErr->getThrownTypes()); auto Int = DIB.createBasicType("Int", 64, dwarf::DW_ATE_signed); auto Error = DIB.getOrCreateArray({Int}); - auto Err = - DIB.createFunction(CU, "err", "", File, 1, Type, false, true, 1, - DINode::FlagZero, true, nullptr, nullptr, Error.get()); + auto Err = DIB.createFunction( + CU, "err", "", File, 1, Type, 1, DINode::FlagZero, + DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized, nullptr, + nullptr, Error.get()); EXPECT_TRUE(Err->getThrownTypes().get() == Error.get()); DIB.finalize(); } @@ -501,12 +503,14 @@ DIB.createFile("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, - DINode::FlagZero, true); + auto SP = DIB.createFunction( + CU, "foo", "", File, 1, Type, 1, DINode::FlagZero, + DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized); F->setSubprogram(SP); AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty()); - auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1, - DINode::FlagZero, true); + auto BarSP = DIB.createFunction( + CU, "bar", "", File, 1, Type, 1, DINode::FlagZero, + DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized); auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0); I->setDebugLoc(DebugLoc::get(2, 0, BadScope)); DIB.finalize(); @@ -521,10 +525,10 @@ /*isOptimized=*/true, /*Flags=*/"", /*Runtime Version=*/0); auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); - auto SP = DIB.createFunction(CU, "foo", /*LinkageName=*/"", File, - /*LineNo=*/1, Type, /*isLocalToUnit=*/false, - /*isDefinition=*/true, /*ScopeLine=*/2, - DINode::FlagZero, /*isOptimized=*/true); + auto SP = DIB.createFunction( + CU, "foo", /*LinkageName=*/"", File, + /*LineNo=*/1, Type, /*ScopeLine=*/2, DINode::FlagZero, + DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized); EXPECT_TRUE(SP->isDistinct()); F->setSubprogram(SP); @@ -611,7 +615,8 @@ 0); auto SPType = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None)); auto SP = - DIB.createFunction(CU, "foo", "foo", File, 1, SPType, false, true, 1); + DIB.createFunction(CU, "foo", "foo", File, 1, SPType, 1, DINode::FlagZero, + DISubprogram::SPFlagDefinition); DebugLoc DL1 = DILocation::get(Ctx, 2, 0, SP); DebugLoc DL2 = DILocation::get(Ctx, 3, 0, SP); Index: llvm/unittests/IR/MetadataTest.cpp =================================================================== --- llvm/unittests/IR/MetadataTest.cpp +++ llvm/unittests/IR/MetadataTest.cpp @@ -84,9 +84,9 @@ getNode(nullptr)); } DISubprogram *getSubprogram() { - return DISubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0, - nullptr, false, false, 0, nullptr, 0, 0, 0, - DINode::FlagZero, false, nullptr); + return DISubprogram::getDistinct( + Context, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0, + DINode::FlagZero, DISubprogram::SPFlagZero, nullptr); } DIFile *getFile() { return DIFile::getDistinct(Context, "file.c", "/path/to/dir"); @@ -929,11 +929,11 @@ // Different function, same inlined-at. auto *F = getFile(); auto *SP1 = DISubprogram::getDistinct(Context, F, "a", "a", F, 0, nullptr, - false, false, 0, nullptr, 0, 0, 0, - DINode::FlagZero, false, nullptr); + 0, nullptr, 0, 0, DINode::FlagZero, + DISubprogram::SPFlagZero, nullptr); auto *SP2 = DISubprogram::getDistinct(Context, F, "b", "b", F, 0, nullptr, - false, false, 0, nullptr, 0, 0, 0, - DINode::FlagZero, false, nullptr); + 0, nullptr, 0, 0, DINode::FlagZero, + DISubprogram::SPFlagZero, nullptr); auto *I = DILocation::get(Context, 2, 7, N); auto *A = DILocation::get(Context, 1, 6, SP1, I); @@ -1705,12 +1705,16 @@ MDTuple *RetainedNodes = getTuple(); MDTuple *ThrownTypes = getTuple(); DICompileUnit *Unit = getUnit(); + DISubprogram::DISPFlags SPFlags = + static_cast(Virtuality); + assert(!IsLocalToUnit && IsDefinition && !IsOptimized && + "bools and SPFlags have to match"); + SPFlags |= DISubprogram::SPFlagDefinition; auto *N = DISubprogram::get( - Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, - ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes); + Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, + ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, + TemplateParams, Declaration, RetainedNodes, ThrownTypes); EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -1733,108 +1737,101 @@ EXPECT_EQ(Declaration, N->getDeclaration()); EXPECT_EQ(RetainedNodes, N->getRetainedNodes().get()); EXPECT_EQ(ThrownTypes, N->getThrownTypes().get()); - EXPECT_EQ(N, DISubprogram::get( - Context, Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, + TemplateParams, Declaration, RetainedNodes, + ThrownTypes)); - EXPECT_NE(N, DISubprogram::get( - Context, getCompositeType(), Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); - EXPECT_NE(N, DISubprogram::get( - Context, Scope, "other", LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); - EXPECT_NE(N, DISubprogram::get( - Context, Scope, Name, "other", File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); - EXPECT_NE(N, DISubprogram::get( - Context, Scope, Name, LinkageName, getFile(), Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); - EXPECT_NE(N, DISubprogram::get( - Context, Scope, Name, LinkageName, File, Line + 1, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName, + File, Line, Type, ScopeLine, ContainingType, + VirtualIndex, ThisAdjustment, Flags, SPFlags, + Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File, + Line, Type, ScopeLine, ContainingType, + VirtualIndex, ThisAdjustment, Flags, SPFlags, + Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, + TemplateParams, Declaration, RetainedNodes, + ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(), + Line, Type, ScopeLine, ContainingType, + VirtualIndex, ThisAdjustment, Flags, SPFlags, + Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, + Line + 1, Type, ScopeLine, ContainingType, + VirtualIndex, ThisAdjustment, Flags, SPFlags, + Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - getSubroutineType(), IsLocalToUnit, - IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, - Flags, IsOptimized, Unit, TemplateParams, - Declaration, RetainedNodes, ThrownTypes)); + getSubroutineType(), ScopeLine, ContainingType, + VirtualIndex, ThisAdjustment, Flags, SPFlags, + Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, - !IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, + Flags, SPFlags ^ DISubprogram::SPFlagLocalToUnit, Unit, + TemplateParams, Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, !IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, + Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit, + TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine + 1, ContainingType, + VirtualIndex, ThisAdjustment, Flags, SPFlags, + Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, getCompositeType(), + VirtualIndex, ThisAdjustment, Flags, SPFlags, + Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine + 1, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, + Flags, SPFlags ^ DISubprogram::SPFlagVirtual, Unit, + TemplateParams, Declaration, RetainedNodes, ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, + VirtualIndex + 1, ThisAdjustment, Flags, + SPFlags, Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, getCompositeType(), - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality + 1, VirtualIndex, - ThisAdjustment, Flags, IsOptimized, Unit, - TemplateParams, Declaration, RetainedNodes, - ThrownTypes)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex + 1, - ThisAdjustment, Flags, IsOptimized, Unit, - TemplateParams, Declaration, RetainedNodes, - ThrownTypes)); - EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, - ThisAdjustment, Flags, !IsOptimized, Unit, - TemplateParams, Declaration, RetainedNodes, - ThrownTypes)); + ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, + Flags, SPFlags ^ DISubprogram::SPFlagOptimized, Unit, + TemplateParams, Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, - ThisAdjustment, Flags, IsOptimized, nullptr, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, nullptr, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); - EXPECT_NE(N, DISubprogram::get( - Context, Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, getTuple(), Declaration, RetainedNodes, ThrownTypes)); + EXPECT_NE(N, + DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, getTuple(), + Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, - ThisAdjustment, Flags, IsOptimized, Unit, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, getSubprogram(), RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, ScopeLine, - ContainingType, Virtuality, VirtualIndex, - ThisAdjustment, Flags, IsOptimized, Unit, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, TemplateParams, Declaration, getTuple())); - EXPECT_NE(N, DISubprogram::get( - Context, Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, - Unit, TemplateParams, Declaration, RetainedNodes, getTuple())); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, Unit, + TemplateParams, Declaration, RetainedNodes, + getTuple())); TempDISubprogram Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); Index: llvm/unittests/IR/VerifierTest.cpp =================================================================== --- llvm/unittests/IR/VerifierTest.cpp +++ llvm/unittests/IR/VerifierTest.cpp @@ -178,9 +178,10 @@ "f", FunctionType::get(Type::getVoidTy(C), false))); IRBuilder<> Builder(BasicBlock::Create(C, "", F)); Builder.CreateUnreachable(); - F->setSubprogram(DIB.createFunction(CU, "f", "f", - DIB.createFile("broken.c", "/"), 1, - nullptr, true, true, 1)); + F->setSubprogram(DIB.createFunction( + CU, "f", "f", DIB.createFile("broken.c", "/"), 1, nullptr, 1, + DINode::FlagZero, + DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition)); DIB.finalize(); EXPECT_FALSE(verifyModule(M)); Index: llvm/unittests/Transforms/Utils/CloningTest.cpp =================================================================== --- llvm/unittests/Transforms/Utils/CloningTest.cpp +++ llvm/unittests/Transforms/Utils/CloningTest.cpp @@ -391,9 +391,9 @@ "/file/dir"), "CloneFunc", false, "", 0); - auto *Subprogram = - DBuilder.createFunction(CU, "f", "f", File, 4, FuncType, true, true, 3, - DINode::FlagZero, false); + auto *Subprogram = DBuilder.createFunction( + CU, "f", "f", File, 4, FuncType, 3, DINode::FlagZero, + DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition); OldFunc->setSubprogram(Subprogram); // Function body @@ -421,9 +421,9 @@ auto *StructType = DICompositeType::getDistinct( C, dwarf::DW_TAG_structure_type, "some_struct", nullptr, 0, nullptr, nullptr, 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr); - auto *InlinedSP = - DBuilder.createFunction(CU, "inlined", "inlined", File, 8, FuncType, - true, true, 9, DINode::FlagZero, false); + auto *InlinedSP = DBuilder.createFunction( + CU, "inlined", "inlined", File, 8, FuncType, 9, DINode::FlagZero, + DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition); auto *InlinedVar = DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, StructType, true); auto *Scope = DBuilder.createLexicalBlock( @@ -606,9 +606,9 @@ "/file/dir"), "CloneModule", false, "", 0); // Function DI - auto *Subprogram = - DBuilder.createFunction(CU, "f", "f", File, 4, DFuncType, true, true, 3, - DINode::FlagZero, false); + auto *Subprogram = DBuilder.createFunction( + CU, "f", "f", File, 4, DFuncType, 3, DINode::FlagZero, + DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition); F->setSubprogram(Subprogram); // Create and assign DIGlobalVariableExpression to gv