Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -3397,13 +3397,13 @@ return DBuilder.createFunction( DContext, Name, LinkageName, Unit, Line, getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags, - TParamsArray.get(), getFunctionDeclaration(FD)); + FD->isConstexpr(), TParamsArray.get(), getFunctionDeclaration(FD)); } llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl( DContext, Name, LinkageName, Unit, Line, getOrCreateFunctionType(GD.getDecl(), FnType, Unit), 0, Flags, SPFlags, - TParamsArray.get(), getFunctionDeclaration(FD)); + false, TParamsArray.get(), getFunctionDeclaration(FD)); const FunctionDecl *CanonDecl = FD->getCanonicalDecl(); FwdDeclReplaceMap.emplace_back(std::piecewise_construct, std::make_tuple(CanonDecl), @@ -3434,7 +3434,8 @@ auto Align = getDeclAlignIfRequired(VD, CGM.getContext()); auto *GV = DBuilder.createTempGlobalVariableFwdDecl( DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit), - !VD->isExternallyVisible(), nullptr, TemplateParameters, Align); + !VD->isExternallyVisible(), nullptr, TemplateParameters, Align, + VD->isConstexpr()); FwdDeclReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(cast(VD->getCanonicalDecl())), @@ -3694,9 +3695,13 @@ // FunctionDecls. When/if we fix this we can have FDContext be TheCU/null for // all subprograms instead of the actual context since subprogram definitions // are emitted as CU level entities by the backend. + + auto *FD = dyn_cast_or_null(GD.getDecl()); + llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine, - FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl); + FlagsForDef, SPFlagsForDef, FD ? FD->isConstexpr() : false, + TParamsArray.get(), Decl); 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 @@ -3759,11 +3764,12 @@ llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero; if (CGM.getLangOpts().Optimize) SPFlags |= llvm::DISubprogram::SPFlagOptimized; - + auto *FD = dyn_cast_or_null(GD.getDecl()); llvm::DISubprogram *SP = DBuilder.createFunction( FDContext, Name, LinkageName, Unit, LineNo, getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags, - TParamsArray.get(), getFunctionDeclaration(D)); + FD ? FD->isConstexpr() : false, TParamsArray.get(), + getFunctionDeclaration(D)); if (IsDeclForCallSite) Fn->setSubprogram(SP); @@ -4073,7 +4079,6 @@ auto *D = DBuilder.createAutoVariable( Scope, FieldName, Unit, Line, FieldTy, CGM.getLangOpts().Optimize, Flags | llvm::DINode::FlagArtificial, FieldAlign); - // Insert an llvm.dbg.declare into the current block. DBuilder.insertDeclare( Storage, D, DBuilder.createExpression(Expr), @@ -4094,12 +4099,13 @@ } // Create the descriptor for the variable. - auto *D = ArgNo ? DBuilder.createParameterVariable( - Scope, Name, *ArgNo, Unit, Line, Ty, - CGM.getLangOpts().Optimize, Flags) - : DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty, - CGM.getLangOpts().Optimize, - Flags, Align); + auto *D = + ArgNo ? DBuilder.createParameterVariable(Scope, Name, *ArgNo, Unit, Line, + Ty, CGM.getLangOpts().Optimize, + Flags) + : DBuilder.createAutoVariable(Scope, Name, Unit, Line, Ty, + CGM.getLangOpts().Optimize, Flags, + Align, VD->isConstexpr()); // Insert an llvm.dbg.declare into the current block. DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr), @@ -4510,7 +4516,7 @@ Var->hasLocalLinkage(), true, Expr.empty() ? nullptr : DBuilder.createExpression(Expr), getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters, - Align); + Align, D->isConstexpr()); Var->addDebugInfo(GVE); } DeclCache[D->getCanonicalDecl()].reset(GVE); @@ -4611,7 +4617,7 @@ GV.reset(DBuilder.createGlobalVariableExpression( DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty, true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD), - TemplateParameters, Align)); + TemplateParameters, Align, VarD ? VarD->isConstexpr() : false)); } void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var, Index: clang/test/CodeGenCXX/constExpr.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/constExpr.cpp @@ -0,0 +1,22 @@ +// Test for DebugInfo for constexpr for C++ variables +// +// RUN: %clang_cc1 -dwarf-version=5 -emit-llvm -triple x86_64-linux-gnu %s -o - \ +// RUN: -O0 -disable-llvm-passes \ +// RUN: -debug-info-kind=standalone \ +// RUN: | FileCheck %s +// +// CHECK: DIGlobalVariable(name: "bar", {{.*}} constExpr: true) +// CHECK: DISubprogram(name: "main", {{.*}} constExpr: false{{.*}} +// CHECK: DILocalVariable(name: "baz", {{.*}} constExpr: true) +// CHECK: DISubprogram(name: "fun", {{.*}} constExpr: true{{.*}} + +constexpr int bar = 10; + +constexpr int fun(int x) { return x * 2; } + +int main(int argc, char **argv) { + int foo = bar; + constexpr int baz = 10; + int constVal = fun(10); + return 0; +} Index: clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp =================================================================== --- clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp +++ clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp @@ -58,7 +58,7 @@ // HAS-ATTR-DAG: DISubprogram(name: "declaration1", {{.*}}, flags: DIFlagPrototyped // HAS-ATTR-DAG: DISubprogram(name: "declaration2", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition -// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized) +// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized // HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition // HAS-ATTR-DAG: DISubprogram(name: "method1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition // HAS-ATTR-DAG: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition Index: llvm/include/llvm/IR/DIBuilder.h =================================================================== --- llvm/include/llvm/IR/DIBuilder.h +++ llvm/include/llvm/IR/DIBuilder.h @@ -582,18 +582,22 @@ /// \param Decl Reference to the corresponding declaration. /// \param AlignInBits Variable alignment(or 0 if no alignment attr was /// specified) + /// \param isConstExpr Boolean flag indicating whether this variable is + /// constexpr or not DIGlobalVariableExpression *createGlobalVariableExpression( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, bool IsLocalToUnit, bool isDefined = true, DIExpression *Expr = nullptr, MDNode *Decl = nullptr, - MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0); + MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0, + bool isConstExpr = false); /// Identical to createGlobalVariable /// except that the resulting DbgNode is temporary and meant to be RAUWed. DIGlobalVariable *createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DIType *Ty, bool IsLocalToUnit, MDNode *Decl = nullptr, - MDTuple *TemplateParams= nullptr, uint32_t AlignInBits = 0); + MDTuple *TemplateParams = nullptr, uint32_t AlignInBits = 0, + bool isConstExpr = false); /// Create a new descriptor for an auto variable. This is a local variable /// that is not a subprogram parameter. @@ -607,7 +611,7 @@ createAutoVariable(DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, DIType *Ty, bool AlwaysPreserve = false, DINode::DIFlags Flags = DINode::FlagZero, - uint32_t AlignInBits = 0); + uint32_t AlignInBits = 0, bool isConstExpr = false); /// Create a new descriptor for an label. /// @@ -659,16 +663,17 @@ /// \param Flags e.g. is this function prototyped or not. /// These flags are used to emit dwarf attributes. /// \param SPFlags Additional flags specific to subprograms. + /// \param isConstExpr Boolean flag indicating whether this function + /// returns constexpr or not /// \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, - unsigned ScopeLine, DINode::DIFlags Flags = DINode::FlagZero, - DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero, - 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, + bool isConstExpr = false, DITemplateParameterArray TParams = nullptr, + DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr); /// Identical to createFunction, /// except that the resulting DbgNode is meant to be RAUWed. @@ -677,7 +682,7 @@ unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags = DINode::FlagZero, DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero, - DITemplateParameterArray TParams = nullptr, + bool isConstExpr = false, DITemplateParameterArray TParams = nullptr, DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr); /// Create a new descriptor for the specified C++ method. @@ -697,17 +702,18 @@ /// \param Flags e.g. is this function prototyped or not. /// This flags are used to emit dwarf attributes. /// \param SPFlags Additional flags specific to subprograms. + /// \param isConstExpr Boolean flag indicating whether this function + /// returns constexpr or not /// \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, - 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); + 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, + bool isConstExpr = false, DITemplateParameterArray TParams = nullptr, + DITypeArray ThrownTypes = nullptr); /// Create common block entry for a Fortran common block. /// \param Scope Scope of this common block. Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1646,14 +1646,17 @@ private: DIFlags Flags; DISPFlags SPFlags; + bool ConstExpr; DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line, unsigned ScopeLine, unsigned VirtualIndex, int ThisAdjustment, - DIFlags Flags, DISPFlags SPFlags, ArrayRef Ops) + DIFlags Flags, DISPFlags SPFlags, bool ConstExpr, + ArrayRef Ops) : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops), Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex), - ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) { + ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags), + ConstExpr(ConstExpr) { static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range"); } ~DISubprogram() = default; @@ -1663,34 +1666,33 @@ StringRef LinkageName, DIFile *File, unsigned Line, DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, - DISPFlags SPFlags, DICompileUnit *Unit, + DISPFlags SPFlags, bool isConstExpr, 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, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, - Flags, SPFlags, Unit, TemplateParams.get(), Declaration, - RetainedNodes.get(), ThrownTypes.get(), Storage, + Flags, SPFlags, isConstExpr, 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, - 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); + 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, + bool isConstExpr, 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(), getScopeLine(), getContainingType(), getVirtualIndex(), getThisAdjustment(), getFlags(), getSPFlags(), - getUnit(), getTemplateParams(), getDeclaration(), - getRetainedNodes(), getThrownTypes()); + isConstExpr(), getUnit(), getTemplateParams(), + getDeclaration(), getRetainedNodes(), getThrownTypes()); } public: @@ -1699,25 +1701,25 @@ (DIScope * Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned Line, DISubroutineType *Type, unsigned ScopeLine, DIType *ContainingType, unsigned VirtualIndex, int ThisAdjustment, - DIFlags Flags, DISPFlags SPFlags, DICompileUnit *Unit, + DIFlags Flags, DISPFlags SPFlags, bool isConstExpr, 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)) + VirtualIndex, ThisAdjustment, Flags, SPFlags, isConstExpr, Unit, + TemplateParams, Declaration, RetainedNodes, ThrownTypes)) DEFINE_MDNODE_GET( DISubprogram, (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, + DIFlags Flags, DISPFlags SPFlags, bool isConstExpr, 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)) + VirtualIndex, ThisAdjustment, Flags, SPFlags, isConstExpr, Unit, + TemplateParams, Declaration, RetainedNodes, ThrownTypes)) TempDISubprogram clone() const { return cloneImpl(); } @@ -1730,6 +1732,7 @@ public: unsigned getLine() const { return Line; } + bool isConstExpr() const { return ConstExpr; } unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; } unsigned getVirtualIndex() const { return VirtualIndex; } int getThisAdjustment() const { return ThisAdjustment; } @@ -2235,12 +2238,14 @@ class DIVariable : public DINode { unsigned Line; uint32_t AlignInBits; + bool ConstExpr; protected: DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line, - ArrayRef Ops, uint32_t AlignInBits = 0) + ArrayRef Ops, uint32_t AlignInBits = 0, + bool ConstExpr = false) : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line), - AlignInBits(AlignInBits) {} + AlignInBits(AlignInBits), ConstExpr(ConstExpr) {} ~DIVariable() = default; public: @@ -2284,6 +2289,7 @@ MDString *getRawName() const { return getOperandAs(1); } Metadata *getRawFile() const { return getOperand(2); } Metadata *getRawType() const { return getOperand(3); } + bool isConstExpr() const { return ConstExpr; } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DILocalVariableKind || @@ -2625,8 +2631,9 @@ DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line, bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits, - ArrayRef Ops) - : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits), + bool IsConstExpr, ArrayRef Ops) + : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits, + IsConstExpr), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {} ~DIGlobalVariable() = default; @@ -2635,46 +2642,46 @@ StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type, bool IsLocalToUnit, bool IsDefinition, DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams, - uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) { + uint32_t AlignInBits, bool IsConstExpr, StorageType Storage, + bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - cast_or_null(TemplateParams), AlignInBits, Storage, - ShouldCreate); + cast_or_null(TemplateParams), AlignInBits, + IsConstExpr, Storage, ShouldCreate); } static DIGlobalVariable * getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, - uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true); + uint32_t AlignInBits, bool IsConstExpr, StorageType Storage, + bool ShouldCreate = true); TempDIGlobalVariable cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), getLinkageName(), getFile(), getLine(), getType(), isLocalToUnit(), isDefinition(), getStaticDataMemberDeclaration(), - getTemplateParams(), getAlignInBits()); + getTemplateParams(), getAlignInBits(), isConstExpr()); } 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), - (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, TemplateParams, - AlignInBits)) - 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), - (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, TemplateParams, - AlignInBits)) + 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, bool IsConstExpr), + (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, TemplateParams, AlignInBits, IsConstExpr)) + 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, bool IsConstExpr), + (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, TemplateParams, AlignInBits, IsConstExpr)) TempDIGlobalVariable clone() const { return cloneImpl(); } @@ -2767,8 +2774,9 @@ DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line, unsigned Arg, DIFlags Flags, uint32_t AlignInBits, - ArrayRef Ops) - : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits), + bool IsConstExpr, ArrayRef Ops) + : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits, + IsConstExpr), Arg(Arg), Flags(Flags) { assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range"); } @@ -2777,34 +2785,39 @@ static DILocalVariable *getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name, DIFile *File, unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags, - uint32_t AlignInBits, StorageType Storage, + uint32_t AlignInBits, bool IsConstExpr, + StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), File, - Line, Type, Arg, Flags, AlignInBits, Storage, ShouldCreate); + Line, Type, Arg, Flags, AlignInBits, IsConstExpr, Storage, + ShouldCreate); } static DILocalVariable *getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, Metadata *Type, unsigned Arg, DIFlags Flags, - uint32_t AlignInBits, StorageType Storage, + uint32_t AlignInBits, bool IsConstExpr, + StorageType Storage, bool ShouldCreate = true); TempDILocalVariable cloneImpl() const { return getTemporary(getContext(), getScope(), getName(), getFile(), getLine(), getType(), getArg(), getFlags(), - getAlignInBits()); + getAlignInBits(), isConstExpr()); } public: DEFINE_MDNODE_GET(DILocalVariable, (DILocalScope * Scope, StringRef Name, DIFile *File, unsigned Line, DIType *Type, unsigned Arg, DIFlags Flags, - uint32_t AlignInBits), - (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits)) + uint32_t AlignInBits, bool IsConstExpr), + (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits, + IsConstExpr)) DEFINE_MDNODE_GET(DILocalVariable, (Metadata * Scope, MDString *Name, Metadata *File, - unsigned Line, Metadata *Type, unsigned Arg, - DIFlags Flags, uint32_t AlignInBits), - (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits)) + unsigned Line, Metadata *Type, unsigned Arg, DIFlags Flags, + uint32_t AlignInBits, bool IsConstExpr), + (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits, + IsConstExpr)) TempDILocalVariable clone() const { return cloneImpl(); } Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -4677,8 +4677,9 @@ /// isDefinition: true, scopeLine: 8, containingType: !3, /// virtuality: DW_VIRTUALTIY_pure_virtual, /// virtualIndex: 10, thisAdjustment: 4, flags: 11, -/// spFlags: 10, isOptimized: false, templateParams: !4, -/// declaration: !5, retainedNodes: !6, thrownTypes: !7) +/// spFlags: 10, constExpr: false, isOptimized: false, +/// templateParams: !4, declaration: !5, retainedNodes: !6, +/// thrownTypes: !7) bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { auto Loc = Lex.getLoc(); #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ @@ -4697,6 +4698,7 @@ OPTIONAL(thisAdjustment, MDSignedField, (0, INT32_MIN, INT32_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(spFlags, DISPFlagField, ); \ + OPTIONAL(constExpr, MDBoolField, ); \ OPTIONAL(isOptimized, MDBoolField, ); \ OPTIONAL(unit, MDField, ); \ OPTIONAL(templateParams, MDField, ); \ @@ -4717,11 +4719,11 @@ Loc, "missing 'distinct', required for !DISubprogram that is a Definition"); Result = GET_OR_DISTINCT( - DISubprogram, - (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, - type.Val, scopeLine.Val, containingType.Val, virtualIndex.Val, - thisAdjustment.Val, flags.Val, SPFlags, unit.Val, templateParams.Val, - declaration.Val, retainedNodes.Val, thrownTypes.Val)); + DISubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val, + line.Val, type.Val, scopeLine.Val, containingType.Val, + virtualIndex.Val, thisAdjustment.Val, flags.Val, SPFlags, + constExpr.Val, unit.Val, templateParams.Val, + declaration.Val, retainedNodes.Val, thrownTypes.Val)); return false; } @@ -4873,7 +4875,7 @@ /// ::= !DIGlobalVariable(scope: !0, name: "foo", linkageName: "foo", /// file: !1, line: 7, type: !2, isLocal: false, /// isDefinition: true, templateParams: !3, -/// declaration: !4, align: 8) +/// declaration: !4, align: 8, constExpr: false) bool LLParser::ParseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \ @@ -4886,25 +4888,26 @@ OPTIONAL(isDefinition, MDBoolField, (true)); \ OPTIONAL(templateParams, MDField, ); \ OPTIONAL(declaration, MDField, ); \ - OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); + OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(constExpr, MDBoolField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = - GET_OR_DISTINCT(DIGlobalVariable, - (Context, scope.Val, name.Val, linkageName.Val, file.Val, - line.Val, type.Val, isLocal.Val, isDefinition.Val, - declaration.Val, templateParams.Val, align.Val)); + Result = GET_OR_DISTINCT(DIGlobalVariable, + (Context, scope.Val, name.Val, linkageName.Val, + file.Val, line.Val, type.Val, isLocal.Val, + isDefinition.Val, declaration.Val, + templateParams.Val, align.Val, constExpr.Val)); return false; } /// ParseDILocalVariable: /// ::= !DILocalVariable(arg: 7, scope: !0, name: "foo", /// file: !1, line: 7, type: !2, arg: 2, flags: 7, -/// align: 8) +/// align: 8, constExpr: false) /// ::= !DILocalVariable(scope: !0, name: "foo", /// file: !1, line: 7, type: !2, arg: 2, flags: 7, -/// align: 8) +/// align: 8, constExpr: false) bool LLParser::ParseDILocalVariable(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ REQUIRED(scope, MDField, (/* AllowNull */ false)); \ @@ -4914,13 +4917,15 @@ OPTIONAL(line, LineField, ); \ OPTIONAL(type, MDField, ); \ OPTIONAL(flags, DIFlagField, ); \ - OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); + OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(constExpr, MDBoolField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS - Result = GET_OR_DISTINCT(DILocalVariable, - (Context, scope.Val, name.Val, file.Val, line.Val, - type.Val, arg.Val, flags.Val, align.Val)); + Result = + GET_OR_DISTINCT(DILocalVariable, + (Context, scope.Val, name.Val, file.Val, line.Val, + type.Val, arg.Val, flags.Val, align.Val, constExpr.Val)); return false; } Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1549,24 +1549,25 @@ DISubprogram *SP = GET_OR_DISTINCT( DISubprogram, (Context, - getDITypeRefOrNull(Record[1]), // scope - getMDString(Record[2]), // name - getMDString(Record[3]), // linkageName - getMDOrNull(Record[4]), // file - Record[5], // line - getMDOrNull(Record[6]), // type - Record[7 + OffsetA], // scopeLine - getDITypeRefOrNull(Record[8 + OffsetA]), // containingType - Record[10 + OffsetA], // virtualIndex - HasThisAdj ? Record[16 + OffsetB] : 0, // thisAdjustment - Flags, // flags - SPFlags, // SPFlags - HasUnit ? CUorFn : nullptr, // unit - getMDOrNull(Record[13 + OffsetB]), // templateParams - getMDOrNull(Record[14 + OffsetB]), // declaration - getMDOrNull(Record[15 + OffsetB]), // retainedNodes + getDITypeRefOrNull(Record[1]), // scope + getMDString(Record[2]), // name + getMDString(Record[3]), // linkageName + getMDOrNull(Record[4]), // file + Record[5], // line + getMDOrNull(Record[6]), // type + Record[7 + OffsetA], // scopeLine + getDITypeRefOrNull(Record[8 + OffsetA]), // containingType + Record[10 + OffsetA], // virtualIndex + HasThisAdj ? Record[16 + OffsetB] : 0, // thisAdjustment + Flags, // flags + SPFlags, // SPFlags + false, + HasUnit ? CUorFn : nullptr, // unit + getMDOrNull(Record[13 + OffsetB]), // templateParams + getMDOrNull(Record[14 + OffsetB]), // declaration + getMDOrNull(Record[15 + OffsetB]), // retainedNodes HasThrownTypes ? getMDOrNull(Record[17 + OffsetB]) - : nullptr // thrownTypes + : nullptr // thrownTypes )); MetadataList.assignValue(SP, NextMetadataNo); NextMetadataNo++; @@ -1702,12 +1703,13 @@ if (Version == 2) { MetadataList.assignValue( - GET_OR_DISTINCT( - DIGlobalVariable, - (Context, getMDOrNull(Record[1]), getMDString(Record[2]), - getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], - getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[9]), getMDOrNull(Record[10]), Record[11])), + GET_OR_DISTINCT(DIGlobalVariable, + (Context, getMDOrNull(Record[1]), + getMDString(Record[2]), getMDString(Record[3]), + getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), + Record[11], false)), NextMetadataNo); NextMetadataNo++; @@ -1715,12 +1717,12 @@ // No upgrade necessary. A null field will be introduced to indicate // that no parameter information is available. MetadataList.assignValue( - GET_OR_DISTINCT(DIGlobalVariable, - (Context, getMDOrNull(Record[1]), - getMDString(Record[2]), getMDString(Record[3]), - getMDOrNull(Record[4]), Record[5], - getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), nullptr, Record[11])), + GET_OR_DISTINCT( + DIGlobalVariable, + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[10]), nullptr, Record[11], false)), NextMetadataNo); NextMetadataNo++; @@ -1753,7 +1755,7 @@ (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), nullptr, AlignInBits)); + getMDOrNull(Record[10]), nullptr, AlignInBits, false)); DIGlobalVariableExpression *DGVE = nullptr; if (Attach || Expr) @@ -1794,7 +1796,7 @@ getMDString(Record[2 + HasTag]), getMDOrNull(Record[3 + HasTag]), Record[4 + HasTag], getDITypeRefOrNull(Record[5 + HasTag]), - Record[6 + HasTag], Flags, AlignInBits)), + Record[6 + HasTag], Flags, AlignInBits, false)), NextMetadataNo); NextMetadataNo++; break; Index: llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -179,6 +179,9 @@ // Add location. addLocationAttribute(VariableDIE, GV, GlobalExprs); + if (GV->isConstExpr()) + addFlag(*VariableDIE, dwarf::DW_AT_const_expr); + return VariableDIE; } @@ -432,6 +435,8 @@ } } + if (SP->isConstExpr()) + addFlag(*SPDie, dwarf::DW_AT_const_expr); // Add name to the name table, we do this here because we're guaranteed // to have concrete versions of our DW_TAG_subprogram nodes. DD->addSubprogramNames(*CUNode, SP, *SPDie); @@ -717,6 +722,8 @@ NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space); } addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); + if (DV.getVariable()->isConstExpr()) + addFlag(*VariableDie, dwarf::DW_AT_const_expr); if (DwarfExpr.TagOffset) addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, *DwarfExpr.TagOffset); Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -1968,6 +1968,8 @@ Printer.printInt("thisAdjustment", N->getThisAdjustment()); Printer.printDIFlags("flags", N->getFlags()); Printer.printDISPFlags("spFlags", N->getSPFlags()); + if (Context->getDwarfVersion() >= 5) + Printer.printBool("constExpr", N->isConstExpr()); Printer.printMetadata("unit", N->getRawUnit()); Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printMetadata("declaration", N->getRawDeclaration()); @@ -2105,6 +2107,8 @@ Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration()); Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printInt("align", N->getAlignInBits()); + if (Context->getDwarfVersion() >= 5) + Printer.printBool("constExpr", N->isConstExpr()); Out << ")"; } @@ -2121,6 +2125,8 @@ Printer.printMetadata("type", N->getRawType()); Printer.printDIFlags("flags", N->getFlags()); Printer.printInt("align", N->getAlignInBits()); + if (Context->getDwarfVersion() >= 5) + Printer.printBool("constExpr", N->isConstExpr()); Out << ")"; } Index: llvm/lib/IR/DIBuilder.cpp =================================================================== --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -641,15 +641,16 @@ DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, - unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, - bool isDefined, DIExpression *Expr, - MDNode *Decl, MDTuple *TemplateParams, uint32_t AlignInBits) { + unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, bool isDefined, + DIExpression *Expr, MDNode *Decl, MDTuple *TemplateParams, + uint32_t AlignInBits, bool isConstExpr) { checkGlobalVariableScope(Context); auto *GV = DIGlobalVariable::getDistinct( VMContext, cast_or_null(Context), Name, LinkageName, F, - LineNumber, Ty, IsLocalToUnit, isDefined, cast_or_null(Decl), - TemplateParams, AlignInBits); + LineNumber, Ty, IsLocalToUnit, isDefined, + cast_or_null(Decl), TemplateParams, AlignInBits, + isConstExpr); if (!Expr) Expr = createExpression(); auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); @@ -660,13 +661,14 @@ DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl, - MDTuple *TemplateParams, uint32_t AlignInBits) { + MDTuple *TemplateParams, uint32_t AlignInBits, bool isConstExpr) { checkGlobalVariableScope(Context); return DIGlobalVariable::getTemporary( VMContext, cast_or_null(Context), Name, LinkageName, F, LineNumber, Ty, IsLocalToUnit, false, - cast_or_null(Decl), TemplateParams, AlignInBits) + cast_or_null(Decl), TemplateParams, AlignInBits, + isConstExpr) .release(); } @@ -675,16 +677,16 @@ DenseMap> &PreservedVariables, DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File, unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags, - uint32_t AlignInBits) { + uint32_t AlignInBits, bool isConstExpr) { // FIXME: Why getNonCompileUnitScope()? // FIXME: Why is "!Context" okay here? // FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT // the only valid scopes)? DIScope *Context = getNonCompileUnitScope(Scope); - auto *Node = - DILocalVariable::get(VMContext, cast_or_null(Context), Name, - File, LineNo, Ty, ArgNo, Flags, AlignInBits); + auto *Node = DILocalVariable::get( + VMContext, cast_or_null(Context), Name, File, LineNo, Ty, + ArgNo, Flags, AlignInBits, isConstExpr); if (AlwaysPreserve) { // The optimizer may remove local variables. If there is an interest // to preserve variable info in such situation then stash it in a @@ -700,10 +702,11 @@ DIFile *File, unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags, - uint32_t AlignInBits) { + uint32_t AlignInBits, + bool isConstExpr) { return createLocalVariable(VMContext, PreservedVariables, Scope, Name, /* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve, - Flags, AlignInBits); + Flags, AlignInBits, isConstExpr); } DILocalVariable *DIBuilder::createParameterVariable( @@ -712,7 +715,7 @@ assert(ArgNo && "Expected non-zero argument number for parameter"); return createLocalVariable(VMContext, PreservedVariables, Scope, Name, ArgNo, File, LineNo, Ty, AlwaysPreserve, Flags, - /* AlignInBits */0); + /* AlignInBits */ 0, /* isConstExpr */ false); } DILabel *DIBuilder::createLabel( @@ -755,14 +758,14 @@ DISubprogram *DIBuilder::createFunction( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, - DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, + DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, bool isConstExpr, DITemplateParameterArray TParams, DISubprogram *Decl, DITypeArray ThrownTypes) { bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition; auto *Node = getSubprogram( /*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context), Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags, - SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, + SPFlags, isConstExpr, IsDefinition ? CUNode : nullptr, TParams, Decl, MDTuple::getTemporary(VMContext, None).release(), ThrownTypes); if (IsDefinition) @@ -774,15 +777,15 @@ DISubprogram *DIBuilder::createTempFunctionFwdDecl( DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, - DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, + DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, bool isConstExpr, DITemplateParameterArray TParams, DISubprogram *Decl, DITypeArray 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) + return DISubprogram::getTemporary( + VMContext, getNonCompileUnitScope(Context), Name, LinkageName, + File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags, SPFlags, + isConstExpr, IsDefinition ? CUNode : nullptr, TParams, Decl, + nullptr, ThrownTypes) .release(); } @@ -790,8 +793,8 @@ DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment, DIType *VTableHolder, DINode::DIFlags Flags, - DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams, - DITypeArray ThrownTypes) { + DISubprogram::DISPFlags SPFlags, bool isConstExpr, + DITemplateParameterArray TParams, DITypeArray ThrownTypes) { assert(getNonCompileUnitScope(Context) && "Methods should have both a Context and a context that isn't " "the compile unit."); @@ -800,8 +803,8 @@ auto *SP = getSubprogram( /*IsDistinct=*/IsDefinition, VMContext, cast(Context), Name, LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment, - Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr, - nullptr, ThrownTypes); + Flags, SPFlags, isConstExpr, IsDefinition ? CUNode : nullptr, TParams, + nullptr, nullptr, ThrownTypes); if (IsDefinition) AllSubprograms.push_back(SP); Index: llvm/lib/IR/DebugInfo.cpp =================================================================== --- llvm/lib/IR/DebugInfo.cpp +++ llvm/lib/IR/DebugInfo.cpp @@ -465,8 +465,8 @@ MDS->getContext(), FileAndScope, MDS->getName(), LinkageName, FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(), ContainingType, MDS->getVirtualIndex(), MDS->getThisAdjustment(), - MDS->getFlags(), MDS->getSPFlags(), Unit, TemplateParams, Declaration, - Variables); + MDS->getFlags(), MDS->getSPFlags(), false, Unit, TemplateParams, + Declaration, Variables); }; if (MDS->isDistinct()) @@ -476,7 +476,7 @@ MDS->getContext(), FileAndScope, MDS->getName(), LinkageName, FileAndScope, MDS->getLine(), Type, MDS->getScopeLine(), ContainingType, MDS->getVirtualIndex(), MDS->getThisAdjustment(), MDS->getFlags(), - MDS->getSPFlags(), Unit, TemplateParams, Declaration, Variables); + MDS->getSPFlags(), false, Unit, TemplateParams, Declaration, Variables); StringRef OldLinkageName = MDS->getLinkageName(); @@ -832,8 +832,8 @@ unwrapDI(Scope), {Name, NameLen}, {LinkageName, LinkageNameLen}, unwrapDI(File), LineNo, unwrapDI(Ty), ScopeLine, map_from_llvmDIFlags(Flags), - pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized), nullptr, - nullptr, nullptr)); + pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized), false, + nullptr, nullptr, nullptr)); } Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -631,16 +631,17 @@ 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) { + int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, bool isConstExpr, + 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, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, - SPFlags, Unit, TemplateParams, Declaration, - RetainedNodes, ThrownTypes)); + SPFlags, isConstExpr, Unit, TemplateParams, + Declaration, RetainedNodes, ThrownTypes)); SmallVector Ops = { File, Scope, Name, LinkageName, Type, Unit, Declaration, RetainedNodes, ContainingType, TemplateParams, ThrownTypes}; @@ -652,10 +653,10 @@ Ops.pop_back(); } } - DEFINE_GETIMPL_STORE_N( - DISubprogram, - (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops, - Ops.size()); + DEFINE_GETIMPL_STORE_N(DISubprogram, + (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, + SPFlags, isConstExpr), + Ops, Ops.size()); } bool DISubprogram::describes(const Function *F) const { @@ -750,13 +751,14 @@ Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, uint32_t AlignInBits, - StorageType Storage, bool ShouldCreate) { + bool isConstExpr, StorageType Storage, + bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DIGlobalVariable, (Scope, Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, - TemplateParams, AlignInBits)); + DEFINE_GETIMPL_LOOKUP( + DIGlobalVariable, + (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, TemplateParams, AlignInBits, isConstExpr)); Metadata *Ops[] = {Scope, Name, File, @@ -765,8 +767,9 @@ LinkageName, StaticDataMemberDeclaration, TemplateParams}; - DEFINE_GETIMPL_STORE(DIGlobalVariable, - (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops); + DEFINE_GETIMPL_STORE( + DIGlobalVariable, + (Line, IsLocalToUnit, IsDefinition, AlignInBits, isConstExpr), Ops); } DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, @@ -774,18 +777,18 @@ unsigned Line, Metadata *Type, unsigned Arg, DIFlags Flags, uint32_t AlignInBits, - StorageType Storage, + bool isConstExpr, StorageType Storage, bool ShouldCreate) { // 64K ought to be enough for any frontend. assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits"); assert(Scope && "Expected scope"); assert(isCanonical(Name) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DILocalVariable, - (Scope, Name, File, Line, Type, Arg, Flags, - AlignInBits)); + DEFINE_GETIMPL_LOOKUP(DILocalVariable, (Scope, Name, File, Line, Type, Arg, + Flags, AlignInBits, isConstExpr)); Metadata *Ops[] = {Scope, Name, File, Type}; - DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops); + DEFINE_GETIMPL_STORE(DILocalVariable, + (Line, Arg, Flags, AlignInBits, isConstExpr), Ops); } Optional DIVariable::getSizeInBits() const { Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -618,6 +618,7 @@ int ThisAdjustment; unsigned Flags; unsigned SPFlags; + bool isConstExpr; Metadata *Unit; Metadata *TemplateParams; Metadata *Declaration; @@ -628,15 +629,16 @@ Metadata *File, unsigned Line, Metadata *Type, unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, - unsigned SPFlags, Metadata *Unit, Metadata *TemplateParams, - Metadata *Declaration, Metadata *RetainedNodes, - Metadata *ThrownTypes) + unsigned SPFlags, bool isConstExpr, Metadata *Unit, + Metadata *TemplateParams, Metadata *Declaration, + Metadata *RetainedNodes, Metadata *ThrownTypes) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), 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) {} + isConstExpr(isConstExpr), 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()), @@ -887,17 +889,19 @@ Metadata *StaticDataMemberDeclaration; Metadata *TemplateParams; uint32_t AlignInBits; + bool isConstExpr; MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams, - uint32_t AlignInBits) + uint32_t AlignInBits, bool isConstExpr) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), StaticDataMemberDeclaration(StaticDataMemberDeclaration), - TemplateParams(TemplateParams), AlignInBits(AlignInBits) {} + TemplateParams(TemplateParams), AlignInBits(AlignInBits), + isConstExpr(isConstExpr) {} MDNodeKeyImpl(const DIGlobalVariable *N) : Scope(N->getRawScope()), Name(N->getRawName()), LinkageName(N->getRawLinkageName()), File(N->getRawFile()), @@ -905,7 +909,7 @@ IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()), TemplateParams(N->getRawTemplateParams()), - AlignInBits(N->getAlignInBits()) {} + AlignInBits(N->getAlignInBits()), isConstExpr(N->isConstExpr()) {} bool isKeyOf(const DIGlobalVariable *RHS) const { return Scope == RHS->getRawScope() && Name == RHS->getRawName() && @@ -916,7 +920,8 @@ StaticDataMemberDeclaration == RHS->getRawStaticDataMemberDeclaration() && TemplateParams == RHS->getRawTemplateParams() && - AlignInBits == RHS->getAlignInBits(); + AlignInBits == RHS->getAlignInBits() && + isConstExpr == RHS->isConstExpr(); } unsigned getHashValue() const { @@ -942,16 +947,18 @@ unsigned Arg; unsigned Flags; uint32_t AlignInBits; + bool isConstExpr; MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line, Metadata *Type, unsigned Arg, unsigned Flags, - uint32_t AlignInBits) + uint32_t AlignInBits, bool isConstExpr) : Scope(Scope), Name(Name), File(File), Line(Line), Type(Type), Arg(Arg), Flags(Flags), AlignInBits(AlignInBits) {} MDNodeKeyImpl(const DILocalVariable *N) : Scope(N->getRawScope()), Name(N->getRawName()), File(N->getRawFile()), Line(N->getLine()), Type(N->getRawType()), Arg(N->getArg()), - Flags(N->getFlags()), AlignInBits(N->getAlignInBits()) {} + Flags(N->getFlags()), AlignInBits(N->getAlignInBits()), + isConstExpr(N->isConstExpr()) {} bool isKeyOf(const DILocalVariable *RHS) const { return Scope == RHS->getRawScope() && Name == RHS->getRawName() && Index: llvm/test/DebugInfo/X86/constExpr.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/constExpr.ll @@ -0,0 +1,116 @@ +; RUN: %llc_dwarf %s -filetype=obj -o - | llvm-dwarfdump -v - | FileCheck %s + +; CHECK: .debug_info contents: + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_name {{.*}} "bar" +; CHECK: DW_AT_const_expr {{.*}} (true) + +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_const_expr {{.*}} (true) +; CHECK: DW_AT_linkage_name {{.*}} "_Z3funi" + + +; C++ source to regenerate: + +;constexpr int bar = 10; +; +;constexpr int fun(int x) { return x * 2; } +; +;int main(int argc, char **argv) { +; int foo = bar; +; constexpr int baz = 10; +; int constVal = fun(10); +; return 0; +;} + +; $ clang++ -O0 -g -gdwarf-5 debug-info-template-align.cpp -c + +; ModuleID = '/dir/test.cpp' +source_filename = "/dir/test.cpp" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +$_Z3funi = comdat any +; Function Attrs: noinline norecurse optnone uwtable +define dso_local i32 @main(i32 %argc, i8** %argv) #0 !dbg !12 { +entry: + %retval = alloca i32, align 4 + %argc.addr = alloca i32, align 4 + %argv.addr = alloca i8**, align 8 + %foo = alloca i32, align 4 + %baz = alloca i32, align 4 + %constVal = alloca i32, align 4 + store i32 0, i32* %retval, align 4 + store i32 %argc, i32* %argc.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %argc.addr, metadata !18, metadata !DIExpression()), !dbg !19 + store i8** %argv, i8*** %argv.addr, align 8 + call void @llvm.dbg.declare(metadata i8*** %argv.addr, metadata !20, metadata !DIExpression()), !dbg !21 + call void @llvm.dbg.declare(metadata i32* %foo, metadata !22, metadata !DIExpression()), !dbg !23 + store i32 10, i32* %foo, align 4, !dbg !23 + call void @llvm.dbg.declare(metadata i32* %baz, metadata !24, metadata !DIExpression()), !dbg !25 + store i32 10, i32* %baz, align 4, !dbg !25 + call void @llvm.dbg.declare(metadata i32* %constVal, metadata !26, metadata !DIExpression()), !dbg !27 + %call = call i32 @_Z3funi(i32 10), !dbg !28 + store i32 %call, i32* %constVal, align 4, !dbg !27 + ret i32 0, !dbg !29 +} +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local i32 @_Z3funi(i32 %x) #2 comdat !dbg !30 { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %x.addr, metadata !33, metadata !DIExpression()), !dbg !34 + %0 = load i32, i32* %x.addr, align 4, !dbg !35 + %mul = mul nsw i32 %0, 2, !dbg !36 + ret i32 %mul, !dbg !37 +} + +attributes #0 = { noinline norecurse optnone uwtable } +attributes #1 = { nounwind readnone speculatable willreturn } +attributes #2 = { noinline nounwind optnone uwtable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "/dir/test.cpp", directory: "/dir/", checksumkind: CSK_MD5, checksum: "df685baf7d28c3d60d0da999770e6270") +!2 = !{} +!3 = !{!4} +!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression(DW_OP_constu, 10, DW_OP_stack_value)) +!5 = distinct !DIGlobalVariable(name: "bar", scope: !0, file: !1, line: 13, type: !6, isLocal: true, isDefinition: true, constExpr: true) +!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{i32 7, !"Dwarf Version", i32 5} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 11.0.0"} +!12 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 17, type: !13, scopeLine: 17, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, constExpr: false, unit: !0, retainedNodes: !2) +!13 = !DISubroutineType(types: !14) +!14 = !{!7, !7, !15} +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) +!17 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!18 = !DILocalVariable(name: "argc", arg: 1, scope: !12, file: !1, line: 17, type: !7, constExpr: false) +!19 = !DILocation(line: 17, column: 14, scope: !12) +!20 = !DILocalVariable(name: "argv", arg: 2, scope: !12, file: !1, line: 17, type: !15, constExpr: false) +!21 = !DILocation(line: 17, column: 27, scope: !12) +!22 = !DILocalVariable(name: "foo", scope: !12, file: !1, line: 18, type: !7, constExpr: false) +!23 = !DILocation(line: 18, column: 7, scope: !12) +!24 = !DILocalVariable(name: "baz", scope: !12, file: !1, line: 19, type: !6, constExpr: true) +!25 = !DILocation(line: 19, column: 17, scope: !12) +!26 = !DILocalVariable(name: "constVal", scope: !12, file: !1, line: 20, type: !7, constExpr: false) +!27 = !DILocation(line: 20, column: 7, scope: !12) +!28 = !DILocation(line: 20, column: 18, scope: !12) +!29 = !DILocation(line: 21, column: 3, scope: !12) +!30 = distinct !DISubprogram(name: "fun", linkageName: "_Z3funi", scope: !1, file: !1, line: 15, type: !31, scopeLine: 15, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, constExpr: true, unit: !0, retainedNodes: !2) +!31 = !DISubroutineType(types: !32) +!32 = !{!7, !7} +!33 = !DILocalVariable(name: "x", arg: 1, scope: !30, file: !1, line: 15, type: !7, constExpr: false) +!34 = !DILocation(line: 15, column: 23, scope: !30) +!35 = !DILocation(line: 15, column: 35, scope: !30) +!36 = !DILocation(line: 15, column: 37, scope: !30) +!37 = !DILocation(line: 15, column: 28, scope: !30) Index: llvm/unittests/CodeGen/MachineInstrTest.cpp =================================================================== --- llvm/unittests/CodeGen/MachineInstrTest.cpp +++ llvm/unittests/CodeGen/MachineInstrTest.cpp @@ -322,7 +322,7 @@ DIFile *DIF = DIFile::getDistinct(Ctx, "filename", ""); DISubprogram *DIS = DISubprogram::getDistinct( Ctx, nullptr, "", "", DIF, 0, nullptr, 0, nullptr, 0, 0, DINode::FlagZero, - DISubprogram::SPFlagZero, nullptr); + DISubprogram::SPFlagZero, false, 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 @@ -695,8 +695,8 @@ auto Error = DIB.getOrCreateArray({Int}); auto Err = DIB.createFunction( CU, "err", "", File, 1, Type, 1, DINode::FlagZero, - DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized, nullptr, - nullptr, Error.get()); + DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized, false, + nullptr, nullptr, Error.get()); EXPECT_TRUE(Err->getThrownTypes().get() == Error.get()); DIB.finalize(); } Index: llvm/unittests/IR/MetadataTest.cpp =================================================================== --- llvm/unittests/IR/MetadataTest.cpp +++ llvm/unittests/IR/MetadataTest.cpp @@ -86,7 +86,7 @@ DISubprogram *getSubprogram() { return DISubprogram::getDistinct( Context, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0, - DINode::FlagZero, DISubprogram::SPFlagZero, nullptr); + DINode::FlagZero, DISubprogram::SPFlagZero, false, nullptr); } DIFile *getFile() { return DIFile::getDistinct(Context, "file.c", "/path/to/dir"); @@ -927,12 +927,12 @@ { // Different function, same inlined-at. auto *F = getFile(); - auto *SP1 = DISubprogram::getDistinct(Context, F, "a", "a", F, 0, nullptr, - 0, nullptr, 0, 0, DINode::FlagZero, - DISubprogram::SPFlagZero, nullptr); - auto *SP2 = DISubprogram::getDistinct(Context, F, "b", "b", F, 0, nullptr, - 0, nullptr, 0, 0, DINode::FlagZero, - DISubprogram::SPFlagZero, nullptr); + auto *SP1 = DISubprogram::getDistinct( + Context, F, "a", "a", F, 0, nullptr, 0, nullptr, 0, 0, DINode::FlagZero, + DISubprogram::SPFlagZero, false, nullptr); + auto *SP2 = DISubprogram::getDistinct( + Context, F, "b", "b", F, 0, nullptr, 0, nullptr, 0, 0, DINode::FlagZero, + DISubprogram::SPFlagZero, false, nullptr); auto *I = DILocation::get(Context, 2, 7, N); auto *A = DILocation::get(Context, 1, 6, SP1, I); @@ -1168,7 +1168,7 @@ DIType *Type = getDerivedType(); DINode::DIFlags Flags = static_cast(7); auto *VlaExpr = DILocalVariable::get(Context, Scope, "vla_expr", File, 8, - Type, 2, Flags, 8); + Type, 2, Flags, 8, false); auto *N = DISubrange::get(Context, VlaExpr, 0); auto Count = N->getCount(); @@ -1822,7 +1822,7 @@ auto *N = DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, - ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit, + ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, false, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes); EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag()); @@ -1848,97 +1848,98 @@ EXPECT_EQ(ThrownTypes, N->getThrownTypes().get()); EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, - ThisAdjustment, Flags, SPFlags, Unit, + ThisAdjustment, Flags, SPFlags, false, 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, + false, 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, + false, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line, Type, ScopeLine, ContainingType, VirtualIndex, - ThisAdjustment, Flags, SPFlags, Unit, + ThisAdjustment, Flags, SPFlags, false, 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, + false, 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, + false, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, getSubroutineType(), ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, - Unit, TemplateParams, Declaration, + false, Unit, TemplateParams, Declaration, + RetainedNodes, ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, + SPFlags ^ DISubprogram::SPFlagLocalToUnit, + false, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, 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, - ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, - Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit, + Flags, SPFlags ^ DISubprogram::SPFlagDefinition, false, 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, + false, 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, + false, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, - Flags, SPFlags ^ DISubprogram::SPFlagVirtual, Unit, + Flags, SPFlags ^ DISubprogram::SPFlagVirtual, false, 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)); + SPFlags, false, Unit, TemplateParams, + Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get( Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, ThisAdjustment, - Flags, SPFlags ^ DISubprogram::SPFlagOptimized, Unit, + Flags, SPFlags ^ DISubprogram::SPFlagOptimized, false, Unit, TemplateParams, Declaration, RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, - ThisAdjustment, Flags, SPFlags, nullptr, + ThisAdjustment, Flags, SPFlags, false, nullptr, TemplateParams, 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, ScopeLine, ContainingType, VirtualIndex, - ThisAdjustment, Flags, SPFlags, Unit, + ThisAdjustment, Flags, SPFlags, false, Unit, + getTuple(), Declaration, RetainedNodes, + ThrownTypes)); + EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, + Type, ScopeLine, ContainingType, VirtualIndex, + ThisAdjustment, Flags, SPFlags, false, Unit, TemplateParams, getSubprogram(), RetainedNodes, ThrownTypes)); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, - ThisAdjustment, Flags, SPFlags, Unit, + ThisAdjustment, Flags, SPFlags, false, Unit, TemplateParams, Declaration, getTuple())); EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine, ContainingType, VirtualIndex, - ThisAdjustment, Flags, SPFlags, Unit, + ThisAdjustment, Flags, SPFlags, false, Unit, TemplateParams, Declaration, RetainedNodes, getTuple())); @@ -2138,9 +2139,10 @@ uint32_t AlignInBits = 8; - auto *N = DIGlobalVariable::get( - Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); + auto *N = DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, + Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, templateParams, + AlignInBits, false); EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag()); EXPECT_EQ(Scope, N->getScope()); @@ -2157,52 +2159,53 @@ EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); - EXPECT_NE(N, DIGlobalVariable::get( - Context, getSubprogram(), Name, LinkageName, File, Line, - Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, templateParams, AlignInBits)); + EXPECT_NE(N, + DIGlobalVariable::get(Context, getSubprogram(), Name, LinkageName, + File, Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, templateParams, + AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, getFile(), Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line + 1, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, getDerivedType(), IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, !IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, !IsDefinition, StaticDataMemberDeclaration, - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, cast(getDerivedType()), - templateParams, AlignInBits)); + templateParams, AlignInBits, false)); EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, nullptr, - AlignInBits)); - EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, - Line, Type, IsLocalToUnit, IsDefinition, - StaticDataMemberDeclaration, - templateParams, (AlignInBits << 1))); + AlignInBits, false)); + EXPECT_NE(N, DIGlobalVariable::get( + Context, Scope, Name, LinkageName, File, Line, Type, + IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration, + templateParams, (AlignInBits << 1), false)); TempDIGlobalVariable Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); @@ -2226,12 +2229,14 @@ cast(getDerivedType()); uint32_t AlignInBits = 8; - auto *Var = DIGlobalVariable::get( - Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); - auto *Var2 = DIGlobalVariable::get( - Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit, - IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits); + auto *Var = DIGlobalVariable::get(Context, Scope, Name, LinkageName, File, + Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, templateParams, + AlignInBits, false); + auto *Var2 = DIGlobalVariable::get(Context, Scope, "other", LinkageName, File, + Line, Type, IsLocalToUnit, IsDefinition, + StaticDataMemberDeclaration, + templateParams, AlignInBits, false); auto *N = DIGlobalVariableExpression::get(Context, Var, Expr); EXPECT_EQ(Var, N->getVariable()); @@ -2256,9 +2261,8 @@ DINode::DIFlags Flags = static_cast(7); uint32_t AlignInBits = 8; - auto *N = - DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, Flags, - AlignInBits); + auto *N = DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, + Flags, AlignInBits, false); EXPECT_TRUE(N->isParameter()); EXPECT_EQ(Scope, N->getScope()); EXPECT_EQ(Name, N->getName()); @@ -2269,44 +2273,49 @@ EXPECT_EQ(Flags, N->getFlags()); EXPECT_EQ(AlignInBits, N->getAlignInBits()); EXPECT_EQ(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, - Flags, AlignInBits)); + Flags, AlignInBits, false)); - EXPECT_FALSE( - DILocalVariable::get(Context, Scope, Name, File, Line, Type, 0, Flags, - AlignInBits)->isParameter()); + EXPECT_FALSE(DILocalVariable::get(Context, Scope, Name, File, Line, Type, 0, + Flags, AlignInBits, false) + ->isParameter()); EXPECT_NE(N, DILocalVariable::get(Context, getSubprogram(), Name, File, Line, - Type, Arg, Flags, AlignInBits)); + Type, Arg, Flags, AlignInBits, false)); EXPECT_NE(N, DILocalVariable::get(Context, Scope, "other", File, Line, Type, - Arg, Flags, AlignInBits)); + Arg, Flags, AlignInBits, false)); EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, getFile(), Line, Type, - Arg, Flags, AlignInBits)); + Arg, Flags, AlignInBits, false)); EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line + 1, Type, - Arg, Flags, AlignInBits)); + Arg, Flags, AlignInBits, false)); EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, - getDerivedType(), Arg, Flags, AlignInBits)); - EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, - Arg + 1, Flags, AlignInBits)); + getDerivedType(), Arg, Flags, AlignInBits, + false)); EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, - Arg, Flags, (AlignInBits << 1))); + Arg + 1, Flags, AlignInBits, false)); + EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, + Flags, (AlignInBits << 1), false)); TempDILocalVariable Temp = N->clone(); EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp))); } TEST_F(DILocalVariableTest, getArg256) { - EXPECT_EQ(255u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), - 0, nullptr, 255, DINode::FlagZero, 0) - ->getArg()); - EXPECT_EQ(256u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), - 0, nullptr, 256, DINode::FlagZero, 0) - ->getArg()); - EXPECT_EQ(257u, DILocalVariable::get(Context, getSubprogram(), "", getFile(), - 0, nullptr, 257, DINode::FlagZero, 0) - ->getArg()); + EXPECT_EQ(255u, + DILocalVariable::get(Context, getSubprogram(), "", getFile(), 0, + nullptr, 255, DINode::FlagZero, 0, false) + ->getArg()); + EXPECT_EQ(256u, + DILocalVariable::get(Context, getSubprogram(), "", getFile(), 0, + nullptr, 256, DINode::FlagZero, 0, false) + ->getArg()); + EXPECT_EQ(257u, + DILocalVariable::get(Context, getSubprogram(), "", getFile(), 0, + nullptr, 257, DINode::FlagZero, 0, false) + ->getArg()); unsigned Max = UINT16_MAX; - EXPECT_EQ(Max, DILocalVariable::get(Context, getSubprogram(), "", getFile(), - 0, nullptr, Max, DINode::FlagZero, 0) - ->getArg()); + EXPECT_EQ(Max, + DILocalVariable::get(Context, getSubprogram(), "", getFile(), 0, + nullptr, Max, DINode::FlagZero, 0, false) + ->getArg()); } typedef MetadataTest DIExpressionTest; @@ -2903,10 +2912,10 @@ DILocation *InlinedLoc = DILocation::get(Context, 2, 7, Scope); - DILocalVariable *VarA = - DILocalVariable::get(Context, Scope, "A", File, 5, Type, 2, Flags, 8); - DILocalVariable *VarB = - DILocalVariable::get(Context, Scope, "B", File, 7, Type, 3, Flags, 8); + DILocalVariable *VarA = DILocalVariable::get(Context, Scope, "A", File, 5, + Type, 2, Flags, 8, false); + DILocalVariable *VarB = DILocalVariable::get(Context, Scope, "B", File, 7, + Type, 3, Flags, 8, false); DebugVariable DebugVariableA(VarA, NoneType(), nullptr); DebugVariable DebugVariableInlineA(VarA, NoneType(), InlinedLoc);