awpandey created this revision.
awpandey added reviewers: dblaikie, aprantl, probinson, jini.susan.george.
awpandey added projects: debug-info, LLVM, clang.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya.

This patch adds //dw_at_const_expr// flag for the constant variable or 
functions in C++


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73261

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/test/CodeGenCXX/constExpr.cpp
  clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp
  llvm/include/llvm/IR/DIBuilder.h
  llvm/include/llvm/IR/DebugInfoMetadata.h
  llvm/lib/AsmParser/LLParser.cpp
  llvm/lib/Bitcode/Reader/MetadataLoader.cpp
  llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
  llvm/lib/IR/AsmWriter.cpp
  llvm/lib/IR/DIBuilder.cpp
  llvm/lib/IR/DebugInfo.cpp
  llvm/lib/IR/DebugInfoMetadata.cpp
  llvm/lib/IR/LLVMContextImpl.h
  llvm/unittests/CodeGen/MachineInstrTest.cpp
  llvm/unittests/IR/IRBuilderTest.cpp
  llvm/unittests/IR/MetadataTest.cpp

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<DINode::DIFlags>(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<DIDerivedType>(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<DIDerivedType>(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<DINode::DIFlags>(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);
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/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/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 isConstant;
 
   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 isConstant)
       : 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),
+        isConstant(isConstant) {}
   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()) /*, isConstant(N->isConstant())*/ {}
 
   bool isKeyOf(const DIGlobalVariable *RHS) const {
     return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
@@ -916,7 +920,9 @@
            StaticDataMemberDeclaration ==
                RHS->getRawStaticDataMemberDeclaration() &&
            TemplateParams == RHS->getRawTemplateParams() &&
-           AlignInBits == RHS->getAlignInBits();
+           AlignInBits == RHS->getAlignInBits() /*&&
+           isConstant == RHS->isConstant()*/
+        ;                                       /*TODO*/
   }
 
   unsigned getHashValue() const {
@@ -942,22 +948,26 @@
   unsigned Arg;
   unsigned Flags;
   uint32_t AlignInBits;
+  bool isConstant;
 
   MDNodeKeyImpl(Metadata *Scope, MDString *Name, Metadata *File, unsigned Line,
                 Metadata *Type, unsigned Arg, unsigned Flags,
-                uint32_t AlignInBits)
+                uint32_t AlignInBits, bool isConstant)
       : 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()) /*, isConstant(N->isConstant())*/ {}
 
   bool isKeyOf(const DILocalVariable *RHS) const {
     return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
            File == RHS->getRawFile() && Line == RHS->getLine() &&
            Type == RHS->getRawType() && Arg == RHS->getArg() &&
-           Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits();
+           Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits() /*&&
+           isConstant == RHS->isConstant()*/
+        ;
   }
 
   unsigned getHashValue() const {
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<Metadata *, 11> 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 isConstant, 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, isConstant));
   Metadata *Ops[] = {Scope,
                      Name,
                      File,
@@ -765,15 +767,16 @@
                      LinkageName,
                      StaticDataMemberDeclaration,
                      TemplateParams};
-  DEFINE_GETIMPL_STORE(DIGlobalVariable,
-                       (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
+  DEFINE_GETIMPL_STORE(
+      DIGlobalVariable,
+      (Line, IsLocalToUnit, IsDefinition, AlignInBits, isConstant), Ops);
 }
 
 DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope,
                                           MDString *Name, Metadata *File,
                                           unsigned Line, Metadata *Type,
                                           unsigned Arg, DIFlags Flags,
-                                          uint32_t AlignInBits,
+                                          uint32_t AlignInBits, bool isConstant,
                                           StorageType Storage,
                                           bool ShouldCreate) {
   // 64K ought to be enough for any frontend.
@@ -781,11 +784,11 @@
 
   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, isConstant));
   Metadata *Ops[] = {Scope, Name, File, Type};
-  DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);
+  DEFINE_GETIMPL_STORE(DILocalVariable,
+                       (Line, Arg, Flags, AlignInBits, isConstant), Ops);
 }
 
 Optional<uint64_t> DIVariable::getSizeInBits() const {
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, /*todo*/ Unit,
+          TemplateParams, Declaration, Variables);
     };
 
     if (MDS->isDistinct())
@@ -476,7 +476,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->getSPFlags(), false /*todo*/, Unit, TemplateParams, Declaration,
+        Variables);
 
     StringRef OldLinkageName = MDS->getLinkageName();
 
@@ -832,8 +833,8 @@
       unwrapDI<DIScope>(Scope), {Name, NameLen}, {LinkageName, LinkageNameLen},
       unwrapDI<DIFile>(File), LineNo, unwrapDI<DISubroutineType>(Ty), ScopeLine,
       map_from_llvmDIFlags(Flags),
-      pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized), nullptr,
-      nullptr, nullptr));
+      pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized),
+      false /*todo*/, nullptr, nullptr, nullptr));
 }
 
 
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 isConstant) {
   checkGlobalVariableScope(Context);
 
   auto *GV = DIGlobalVariable::getDistinct(
       VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
-      LineNumber, Ty, IsLocalToUnit, isDefined, cast_or_null<DIDerivedType>(Decl),
-      TemplateParams, AlignInBits);
+      LineNumber, Ty, IsLocalToUnit, isDefined,
+      cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,
+      isConstant);
   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 isConstant) {
   checkGlobalVariableScope(Context);
 
   return DIGlobalVariable::getTemporary(
              VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
              LineNumber, Ty, IsLocalToUnit, false,
-             cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits)
+             cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,
+             isConstant)
       .release();
 }
 
@@ -675,16 +677,16 @@
     DenseMap<MDNode *, SmallVector<TrackingMDNodeRef, 1>> &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 isConstant) {
   // 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<DILocalScope>(Context), Name,
-                           File, LineNo, Ty, ArgNo, Flags, AlignInBits);
+  auto *Node = DILocalVariable::get(
+      VMContext, cast_or_null<DILocalScope>(Context), Name, File, LineNo, Ty,
+      ArgNo, Flags, AlignInBits, isConstant);
   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 isConstant) {
   return createLocalVariable(VMContext, PreservedVariables, Scope, Name,
                              /* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve,
-                             Flags, AlignInBits);
+                             Flags, AlignInBits, isConstant);
 }
 
 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, /* constexpr */ 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<DIScope>(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/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("const_expr", 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("const_expr", N->isConstant());
   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("const_expr", N->isConstant());
   Out << ")";
 }
 
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->isConstant())
+    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()->isConstant())
+    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/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,8 @@
                          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 /*Record[9 + HasTag]*/)),
         NextMetadataNo);
     NextMetadataNo++;
     break;
Index: llvm/lib/AsmParser/LLParser.cpp
===================================================================
--- llvm/lib/AsmParser/LLParser.cpp
+++ llvm/lib/AsmParser/LLParser.cpp
@@ -4697,6 +4697,7 @@
   OPTIONAL(thisAdjustment, MDSignedField, (0, INT32_MIN, INT32_MAX));          \
   OPTIONAL(flags, DIFlagField, );                                              \
   OPTIONAL(spFlags, DISPFlagField, );                                          \
+  OPTIONAL(const_expr, MDBoolField, );                                         \
   OPTIONAL(isOptimized, MDBoolField, );                                        \
   OPTIONAL(unit, MDField, );                                                   \
   OPTIONAL(templateParams, MDField, );                                         \
@@ -4717,11 +4718,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,
+                     const_expr.Val, unit.Val, templateParams.Val,
+                     declaration.Val, retainedNodes.Val, thrownTypes.Val));
   return false;
 }
 
@@ -4886,15 +4887,16 @@
   OPTIONAL(isDefinition, MDBoolField, (true));                                 \
   OPTIONAL(templateParams, MDField, );                                         \
   OPTIONAL(declaration, MDField, );                                            \
-  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
+  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
+  OPTIONAL(const_expr, 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, const_expr.Val));
   return false;
 }
 
@@ -4914,13 +4916,15 @@
   OPTIONAL(line, LineField, );                                                 \
   OPTIONAL(type, MDField, );                                                   \
   OPTIONAL(flags, DIFlagField, );                                              \
-  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
+  OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
+  OPTIONAL(const_expr, 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, const_expr.Val));
   return false;
 }
 
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<Metadata *> Ops)
+               DIFlags Flags, DISPFlags SPFlags, bool Constexpr,
+               ArrayRef<Metadata *> 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,32 +1666,32 @@
           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(),
+                        false, /*todo*/
                         getUnit(), getTemplateParams(), getDeclaration(),
                         getRetainedNodes(), getThrownTypes());
   }
@@ -1699,25 +1702,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 +1733,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 +2239,14 @@
 class DIVariable : public DINode {
   unsigned Line;
   uint32_t AlignInBits;
+  bool ConstExpr;
 
 protected:
   DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Line,
-             ArrayRef<Metadata *> Ops, uint32_t AlignInBits = 0)
+             ArrayRef<Metadata *> 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 +2290,7 @@
   MDString *getRawName() const { return getOperandAs<MDString>(1); }
   Metadata *getRawFile() const { return getOperand(2); }
   Metadata *getRawType() const { return getOperand(3); }
+  bool isConstant() const { return ConstExpr; }
 
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == DILocalVariableKind ||
@@ -2625,8 +2632,9 @@
 
   DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
                    bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
-                   ArrayRef<Metadata *> Ops)
-      : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
+                   bool IsConstant, ArrayRef<Metadata *> Ops)
+      : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits,
+                   IsConstant),
         IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
   ~DIGlobalVariable() = default;
 
@@ -2635,46 +2643,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 IsConstant, StorageType Storage,
+          bool ShouldCreate = true) {
     return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
                    getCanonicalMDString(Context, LinkageName), File, Line, Type,
                    IsLocalToUnit, IsDefinition, StaticDataMemberDeclaration,
-                   cast_or_null<Metadata>(TemplateParams), AlignInBits, Storage,
-                   ShouldCreate);
+                   cast_or_null<Metadata>(TemplateParams), AlignInBits,
+                   IsConstant, 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 IsConstant, StorageType Storage,
+          bool ShouldCreate = true);
 
   TempDIGlobalVariable cloneImpl() const {
     return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
                         getFile(), getLine(), getType(), isLocalToUnit(),
                         isDefinition(), getStaticDataMemberDeclaration(),
-                        getTemplateParams(), getAlignInBits());
+                        getTemplateParams(), getAlignInBits(), false /*TODO*/);
   }
 
 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 IsConstant),
+      (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
+       StaticDataMemberDeclaration, TemplateParams, AlignInBits, IsConstant))
+  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 IsConstant),
+      (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
+       StaticDataMemberDeclaration, TemplateParams, AlignInBits, IsConstant))
 
   TempDIGlobalVariable clone() const { return cloneImpl(); }
 
@@ -2767,8 +2775,9 @@
 
   DILocalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
                   unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
-                  ArrayRef<Metadata *> Ops)
-      : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits),
+                  bool IsConstant, ArrayRef<Metadata *> Ops)
+      : DIVariable(C, DILocalVariableKind, Storage, Line, Ops, AlignInBits,
+                   IsConstant),
         Arg(Arg), Flags(Flags) {
     assert(Arg < (1 << 16) && "DILocalVariable: Arg out of range");
   }
@@ -2777,34 +2786,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 IsConstant,
+                                  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, IsConstant, 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 IsConstant,
+                                  StorageType Storage,
                                   bool ShouldCreate = true);
 
   TempDILocalVariable cloneImpl() const {
     return getTemporary(getContext(), getScope(), getName(), getFile(),
                         getLine(), getType(), getArg(), getFlags(),
-                        getAlignInBits());
+                        getAlignInBits(), isConstant());
   }
 
 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 IsConstant),
+                    (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
+                     IsConstant))
   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 IsConstant),
+                    (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits,
+                     IsConstant))
 
   TempDILocalVariable clone() const { return cloneImpl(); }
 
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)
+    /// \isConstExpr       Boolean flag indicating wheather 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.
     ///
@@ -661,14 +665,13 @@
     /// \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,
-                   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 constExpr = 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 +680,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.
@@ -699,15 +702,14 @@
     /// \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,
-                 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: 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: 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", {{.*}} const_expr: true)
+// CHECK: DISubprogram(name: "main", {{.*}} const_expr: false{{.*}}
+// CHECK: DILocalVariable(name: "baz", {{.*}} const_expr: true)
+// CHECK: DISubprogram(name: "fun", {{.*}} const_expr: 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/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<VarDecl>(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<FunctionDecl>(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<FunctionDecl>(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,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to