awpandey updated this revision to Diff 243509.
awpandey added a comment.
Herald added a subscriber: ormris.

@probinson I have reimplemented the feature by using DIFlags.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73261/new/

https://reviews.llvm.org/D73261

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/test/CodeGenCXX/constExpr.cpp
  llvm/include/llvm/IR/DIBuilder.h
  llvm/include/llvm/IR/DebugInfoFlags.def
  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/test/DebugInfo/X86/constExpr.ll

Index: llvm/test/DebugInfo/X86/constExpr.ll
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/X86/constExpr.ll
@@ -0,0 +1,118 @@
+; 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 !13 {
+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 !19, metadata !DIExpression()), !dbg !20
+  store i8** %argv, i8*** %argv.addr, align 8
+  call void @llvm.dbg.declare(metadata i8*** %argv.addr, metadata !21, metadata !DIExpression()), !dbg !22
+  call void @llvm.dbg.declare(metadata i32* %foo, metadata !23, metadata !DIExpression()), !dbg !24
+  store i32 10, i32* %foo, align 4, !dbg !24
+  call void @llvm.dbg.declare(metadata i32* %baz, metadata !25, metadata !DIExpression()), !dbg !26
+  store i32 10, i32* %baz, align 4, !dbg !26
+  call void @llvm.dbg.declare(metadata i32* %constVal, metadata !27, metadata !DIExpression()), !dbg !28
+  %call = call i32 @_Z3funi(i32 10), !dbg !29
+  store i32 %call, i32* %constVal, align 4, !dbg !28
+  ret i32 0, !dbg !30
+}
+; 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 !31 {
+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 !34, metadata !DIExpression()), !dbg !35
+  %0 = load i32, i32* %x.addr, align 4, !dbg !36
+  %mul = mul nsw i32 %0, 2, !dbg !37
+  ret i32 %mul, !dbg !38
+}
+
+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 = !{!9, !10, !11}
+!llvm.ident = !{!12}
+
+!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: "b973c468913ba52f145c9b21705fe0e0")
+!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: !6, line: 13, type: !7, isLocal: true, isDefinition: true, flags: DIFlagConstExpr)
+!6 = !DIFile(filename: "/dir/test.cpp", directory: "/dir", checksumkind: CSK_MD5, checksum: "b973c468913ba52f145c9b21705fe0e0")
+!7 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !8)
+!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!9 = !{i32 7, !"Dwarf Version", i32 5}
+!10 = !{i32 2, !"Debug Info Version", i32 3}
+!11 = !{i32 1, !"wchar_size", i32 4}
+!12 = !{!"clang version 11.0.0 "}
+!13 = distinct !DISubprogram(name: "main", scope: !6, file: !6, line: 17, type: !14, scopeLine: 17, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
+!14 = !DISubroutineType(types: !15)
+!15 = !{!8, !8, !16}
+!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64)
+!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64)
+!18 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+!19 = !DILocalVariable(name: "argc", arg: 1, scope: !13, file: !6, line: 17, type: !8)
+!20 = !DILocation(line: 17, column: 14, scope: !13)
+!21 = !DILocalVariable(name: "argv", arg: 2, scope: !13, file: !6, line: 17, type: !16)
+!22 = !DILocation(line: 17, column: 27, scope: !13)
+!23 = !DILocalVariable(name: "foo", scope: !13, file: !6, line: 18, type: !8)
+!24 = !DILocation(line: 18, column: 7, scope: !13)
+!25 = !DILocalVariable(name: "baz", scope: !13, file: !6, line: 19, type: !7, flags: DIFlagConstExpr)
+!26 = !DILocation(line: 19, column: 17, scope: !13)
+!27 = !DILocalVariable(name: "constVal", scope: !13, file: !6, line: 20, type: !8)
+!28 = !DILocation(line: 20, column: 7, scope: !13)
+!29 = !DILocation(line: 20, column: 18, scope: !13)
+!30 = !DILocation(line: 21, column: 3, scope: !13)
+!31 = distinct !DISubprogram(name: "fun", linkageName: "_Z3funi", scope: !6, file: !6, line: 15, type: !32, scopeLine: 15, flags: DIFlagPrototyped | DIFlagConstExpr, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
+!32 = !DISubroutineType(types: !33)
+!33 = !{!8, !8}
+!34 = !DILocalVariable(name: "x", arg: 1, scope: !31, file: !6, line: 15, type: !8)
+!35 = !DILocation(line: 15, column: 23, scope: !31)
+!36 = !DILocation(line: 15, column: 35, scope: !31)
+!37 = !DILocation(line: 15, column: 37, scope: !31)
+!38 = !DILocation(line: 15, column: 28, scope: !31)
Index: llvm/lib/IR/LLVMContextImpl.h
===================================================================
--- llvm/lib/IR/LLVMContextImpl.h
+++ llvm/lib/IR/LLVMContextImpl.h
@@ -886,25 +886,27 @@
   bool IsDefinition;
   Metadata *StaticDataMemberDeclaration;
   Metadata *TemplateParams;
+  unsigned Flags;
   uint32_t AlignInBits;
 
   MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
                 Metadata *File, unsigned Line, Metadata *Type,
                 bool IsLocalToUnit, bool IsDefinition,
                 Metadata *StaticDataMemberDeclaration, Metadata *TemplateParams,
-                uint32_t AlignInBits)
+                unsigned Flags, uint32_t AlignInBits)
       : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
         Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
         IsDefinition(IsDefinition),
         StaticDataMemberDeclaration(StaticDataMemberDeclaration),
-        TemplateParams(TemplateParams), AlignInBits(AlignInBits) {}
+        TemplateParams(TemplateParams), Flags(Flags), AlignInBits(AlignInBits) {
+  }
   MDNodeKeyImpl(const DIGlobalVariable *N)
       : Scope(N->getRawScope()), Name(N->getRawName()),
         LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
         Line(N->getLine()), Type(N->getRawType()),
         IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()),
         StaticDataMemberDeclaration(N->getRawStaticDataMemberDeclaration()),
-        TemplateParams(N->getRawTemplateParams()),
+        TemplateParams(N->getRawTemplateParams()), Flags(N->getFlags()),
         AlignInBits(N->getAlignInBits()) {}
 
   bool isKeyOf(const DIGlobalVariable *RHS) const {
@@ -916,7 +918,7 @@
            StaticDataMemberDeclaration ==
                RHS->getRawStaticDataMemberDeclaration() &&
            TemplateParams == RHS->getRawTemplateParams() &&
-           AlignInBits == RHS->getAlignInBits();
+           Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits();
   }
 
   unsigned getHashValue() const {
@@ -929,7 +931,7 @@
     // TODO: make hashing work fine with such situations
     return hash_combine(Scope, Name, LinkageName, File, Line, Type,
                         IsLocalToUnit, IsDefinition, /* AlignInBits, */
-                        StaticDataMemberDeclaration);
+                        StaticDataMemberDeclaration, Flags);
   }
 };
 
Index: llvm/lib/IR/DebugInfoMetadata.cpp
===================================================================
--- llvm/lib/IR/DebugInfoMetadata.cpp
+++ llvm/lib/IR/DebugInfoMetadata.cpp
@@ -749,14 +749,15 @@
                           MDString *LinkageName, Metadata *File, unsigned Line,
                           Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
                           Metadata *StaticDataMemberDeclaration,
-                          Metadata *TemplateParams, uint32_t AlignInBits,
-                          StorageType Storage, bool ShouldCreate) {
+                          Metadata *TemplateParams, DIFlags Flags,
+                          uint32_t AlignInBits, 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));
+                                           TemplateParams, Flags, AlignInBits));
   Metadata *Ops[] = {Scope,
                      Name,
                      File,
@@ -766,7 +767,8 @@
                      StaticDataMemberDeclaration,
                      TemplateParams};
   DEFINE_GETIMPL_STORE(DIGlobalVariable,
-                       (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
+                       (Line, IsLocalToUnit, IsDefinition, Flags, AlignInBits),
+                       Ops);
 }
 
 DILocalVariable *DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope,
@@ -781,9 +783,8 @@
 
   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));
   Metadata *Ops[] = {Scope, Name, File, Type};
   DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);
 }
Index: llvm/lib/IR/DebugInfo.cpp
===================================================================
--- llvm/lib/IR/DebugInfo.cpp
+++ llvm/lib/IR/DebugInfo.cpp
@@ -1309,12 +1309,13 @@
     LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File,
     unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
-    LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits) {
+    LLVMMetadataRef Expr, LLVMMetadataRef Decl, LLVMDIFlags Flags,
+    uint32_t AlignInBits) {
   return wrap(unwrap(Builder)->createGlobalVariableExpression(
       unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LinkLen},
-      unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,
-      true, unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl),
-      nullptr, AlignInBits));
+      unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit, true,
+      unwrap<DIExpression>(Expr), unwrapDI<MDNode>(Decl), nullptr,
+      map_from_llvmDIFlags(Flags), AlignInBits));
 }
 
 LLVMMetadataRef LLVMDIGlobalVariableExpressionGetVariable(LLVMMetadataRef GVE) {
@@ -1359,11 +1360,12 @@
     LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
     size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File,
     unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
-    LLVMMetadataRef Decl, uint32_t AlignInBits) {
+    LLVMMetadataRef Decl, LLVMDIFlags Flags, uint32_t AlignInBits) {
   return wrap(unwrap(Builder)->createTempGlobalVariableFwdDecl(
       unwrapDI<DIScope>(Scope), {Name, NameLen}, {Linkage, LnkLen},
       unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), LocalToUnit,
-      unwrapDI<MDNode>(Decl), nullptr, AlignInBits));
+      unwrapDI<MDNode>(Decl), nullptr, map_from_llvmDIFlags(Flags),
+      AlignInBits));
 }
 
 LLVMValueRef
Index: llvm/lib/IR/DIBuilder.cpp
===================================================================
--- llvm/lib/IR/DIBuilder.cpp
+++ llvm/lib/IR/DIBuilder.cpp
@@ -641,15 +641,15 @@
 
 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,
+    DINode::DIFlags Flags, uint32_t AlignInBits) {
   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, Flags, AlignInBits);
   if (!Expr)
     Expr = createExpression();
   auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr);
@@ -660,13 +660,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, DINode::DIFlags Flags, uint32_t AlignInBits) {
   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, Flags,
+             AlignInBits)
       .release();
 }
 
@@ -712,7 +713,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);
 }
 
 DILabel *DIBuilder::createLabel(
Index: llvm/lib/IR/AsmWriter.cpp
===================================================================
--- llvm/lib/IR/AsmWriter.cpp
+++ llvm/lib/IR/AsmWriter.cpp
@@ -2104,6 +2104,7 @@
   Printer.printBool("isDefinition", N->isDefinition());
   Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
   Printer.printMetadata("templateParams", N->getRawTemplateParams());
+  Printer.printDIFlags("flags", N->getFlags());
   Printer.printInt("align", N->getAlignInBits());
   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->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/Bitcode/Reader/MetadataLoader.cpp
===================================================================
--- llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -1549,24 +1549,24 @@
     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
+         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++;
@@ -1699,28 +1699,31 @@
 
     IsDistinct = Record[0] & 1;
     unsigned Version = Record[0] >> 1;
+    DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7]);
 
     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]),
+                           Flags, Record[12])),
           NextMetadataNo);
 
       NextMetadataNo++;
     } else if (Version == 1) {
       // 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, Flags, Record[12])),
           NextMetadataNo);
 
       NextMetadataNo++;
@@ -1730,10 +1733,10 @@
       NeedUpgradeToDIGlobalVariableExpression = true;
       Metadata *Expr = getMDOrNull(Record[9]);
       uint32_t AlignInBits = 0;
-      if (Record.size() > 11) {
+      if (Record.size() > 12) {
         if (Record[11] > (uint64_t)std::numeric_limits<uint32_t>::max())
           return error("Alignment value is too large");
-        AlignInBits = Record[11];
+        AlignInBits = Record[12];
       }
       GlobalVariable *Attach = nullptr;
       if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(Expr)) {
@@ -1748,12 +1751,13 @@
           Expr = nullptr;
         }
       }
+      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[11]);
       DIGlobalVariable *DGV = 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, AlignInBits));
+           getMDOrNull(Record[10]), nullptr, Flags, AlignInBits));
 
       DIGlobalVariableExpression *DGVE = nullptr;
       if (Attach || Expr)
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, 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)                                    \
@@ -4886,15 +4887,16 @@
   OPTIONAL(isDefinition, MDBoolField, (true));                                 \
   OPTIONAL(templateParams, MDField, );                                         \
   OPTIONAL(declaration, MDField, );                                            \
+  OPTIONAL(flags, DIFlagField, );                                              \
   OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));
   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, flags.Val, align.Val));
   return false;
 }
 
Index: llvm/include/llvm/IR/DebugInfoMetadata.h
===================================================================
--- llvm/include/llvm/IR/DebugInfoMetadata.h
+++ llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -1789,6 +1789,11 @@
   // Returns true if this subprogram is a thunk generated by the compiler.
   bool isThunk() const { return getFlags() & FlagThunk; }
 
+  // Check if this routine return type is const expression .
+  //
+  // Returns true if this subprogram returns const expression.
+  bool isConstExpr() const { return getFlags() & FlagConstExpr; }
+
   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
 
   StringRef getName() const { return getStringOperand(2); }
@@ -2622,59 +2627,62 @@
 
   bool IsLocalToUnit;
   bool IsDefinition;
+  DIFlags Flags;
 
   DIGlobalVariable(LLVMContext &C, StorageType Storage, unsigned Line,
-                   bool IsLocalToUnit, bool IsDefinition, uint32_t AlignInBits,
-                   ArrayRef<Metadata *> Ops)
+                   bool IsLocalToUnit, bool IsDefinition, DIFlags Flags,
+                   uint32_t AlignInBits, ArrayRef<Metadata *> Ops)
       : DIVariable(C, DIGlobalVariableKind, Storage, Line, Ops, AlignInBits),
-        IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition) {}
+        IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), Flags(Flags) {
+  }
   ~DIGlobalVariable() = default;
 
-  static DIGlobalVariable *
-  getImpl(LLVMContext &Context, DIScope *Scope, StringRef Name,
-          StringRef LinkageName, DIFile *File, unsigned Line, DIType *Type,
-          bool IsLocalToUnit, bool IsDefinition,
-          DIDerivedType *StaticDataMemberDeclaration, MDTuple *TemplateParams,
-          uint32_t AlignInBits, StorageType Storage, bool ShouldCreate = true) {
+  static DIGlobalVariable *getImpl(LLVMContext &Context, DIScope *Scope,
+                                   StringRef Name, StringRef LinkageName,
+                                   DIFile *File, unsigned Line, DIType *Type,
+                                   bool IsLocalToUnit, bool IsDefinition,
+                                   DIDerivedType *StaticDataMemberDeclaration,
+                                   MDTuple *TemplateParams, DIFlags Flags,
+                                   uint32_t AlignInBits, 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), Flags, AlignInBits,
+                   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);
+          DIFlags Flags, uint32_t AlignInBits, StorageType Storage,
+          bool ShouldCreate = true);
 
   TempDIGlobalVariable cloneImpl() const {
     return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
                         getFile(), getLine(), getType(), isLocalToUnit(),
                         isDefinition(), getStaticDataMemberDeclaration(),
-                        getTemplateParams(), getAlignInBits());
+                        getTemplateParams(), getFlags(), getAlignInBits());
   }
 
 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,
+       DIFlags Flags, uint32_t AlignInBits),
+      (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
+       StaticDataMemberDeclaration, TemplateParams, Flags, 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,
+       DIFlags Flags, uint32_t AlignInBits),
+      (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
+       StaticDataMemberDeclaration, TemplateParams, Flags, AlignInBits))
 
   TempDIGlobalVariable clone() const { return cloneImpl(); }
 
@@ -2685,6 +2693,8 @@
   DIDerivedType *getStaticDataMemberDeclaration() const {
     return cast_or_null<DIDerivedType>(getRawStaticDataMemberDeclaration());
   }
+  DIFlags getFlags() const { return Flags; }
+  bool isConstExpr() const { return getFlags() & FlagConstExpr; }
 
   MDString *getRawLinkageName() const { return getOperandAs<MDString>(5); }
   Metadata *getRawStaticDataMemberDeclaration() const { return getOperand(6); }
@@ -2802,8 +2812,8 @@
                     (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
   DEFINE_MDNODE_GET(DILocalVariable,
                     (Metadata * Scope, MDString *Name, Metadata *File,
-                     unsigned Line, Metadata *Type, unsigned Arg,
-                     DIFlags Flags, uint32_t AlignInBits),
+                     unsigned Line, Metadata *Type, unsigned Arg, DIFlags Flags,
+                     uint32_t AlignInBits),
                     (Scope, Name, File, Line, Type, Arg, Flags, AlignInBits))
 
   TempDILocalVariable clone() const { return cloneImpl(); }
@@ -2821,6 +2831,7 @@
 
   bool isArtificial() const { return getFlags() & FlagArtificial; }
   bool isObjectPointer() const { return getFlags() & FlagObjectPointer; }
+  bool isConstExpr() const { return getFlags() & FlagConstExpr; }
 
   /// Check that a location is valid for this variable.
   ///
Index: llvm/include/llvm/IR/DebugInfoFlags.def
===================================================================
--- llvm/include/llvm/IR/DebugInfoFlags.def
+++ llvm/include/llvm/IR/DebugInfoFlags.def
@@ -58,6 +58,7 @@
 HANDLE_DI_FLAG((1 << 27), BigEndian)
 HANDLE_DI_FLAG((1 << 28), LittleEndian)
 HANDLE_DI_FLAG((1 << 29), AllCallsDescribed)
+HANDLE_DI_FLAG((1 << 30), ConstExpr)
 
 // To avoid needing a dedicated value for IndirectVirtualBase, we use
 // the bitwise or of Virtual and FwdDecl, which does not otherwise
@@ -67,7 +68,7 @@
 #ifdef DI_FLAG_LARGEST_NEEDED
 // intended to be used with ADT/BitmaskEnum.h
 // NOTE: always must be equal to largest flag, check this when adding new flag
-HANDLE_DI_FLAG((1 << 29), Largest)
+HANDLE_DI_FLAG((1 << 30), Largest)
 #undef DI_FLAG_LARGEST_NEEDED
 #endif
 
Index: llvm/include/llvm/IR/DIBuilder.h
===================================================================
--- llvm/include/llvm/IR/DIBuilder.h
+++ llvm/include/llvm/IR/DIBuilder.h
@@ -586,14 +586,16 @@
         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,
+        DINode::DIFlags Flags = DINode::FlagZero, uint32_t AlignInBits = 0);
 
     /// 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,
+        DINode::DIFlags Flags = DINode::FlagZero, uint32_t AlignInBits = 0);
 
     /// Create a new descriptor for an auto variable.  This is a local variable
     /// that is not a subprogram parameter.
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", {{.*}} flags: DIFlagConstExpr)
+// CHECK: DISubprogram(name: "main", {{.*}} flags: DIFlagPrototyped, spFlags: DISPFlagDefinition,
+// CHECK: DILocalVariable(name: "baz", {{.*}}, flags: DIFlagConstExpr)
+// CHECK: DISubprogram(name: "fun", {{.*}}, flags: DIFlagPrototyped | DIFlagConstExpr
+
+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
@@ -3391,6 +3391,9 @@
   if (CGM.getLangOpts().Optimize)
     SPFlags |= llvm::DISubprogram::SPFlagOptimized;
 
+  if (FD->isConstexpr())
+    Flags |= llvm::DINode::FlagConstExpr;
+
   if (Stub) {
     Flags |= getCallSiteRelatedAttrs();
     SPFlags |= llvm::DISubprogram::SPFlagDefinition;
@@ -3428,13 +3431,18 @@
   llvm::DIScope *DContext = Unit;
   unsigned Line = getLineNumber(Loc);
   llvm::MDTuple *TemplateParameters = nullptr;
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
 
   collectVarDeclProps(VD, Unit, Line, T, Name, LinkageName, TemplateParameters,
                       DContext);
   auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
+
+  if (VD->isConstexpr())
+    Flags |= llvm::DINode::FlagConstExpr;
+
   auto *GV = DBuilder.createTempGlobalVariableFwdDecl(
       DContext, Name, LinkageName, Unit, Line, getOrCreateType(T, Unit),
-      !VD->isExternallyVisible(), nullptr, TemplateParameters, Align);
+      !VD->isExternallyVisible(), nullptr, TemplateParameters, Flags, Align);
   FwdDeclReplaceMap.emplace_back(
       std::piecewise_construct,
       std::make_tuple(cast<VarDecl>(VD->getCanonicalDecl())),
@@ -3694,6 +3702,12 @@
   // 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());
+
+  if (FD && FD->isConstexpr())
+    FlagsForDef |= llvm::DINode::FlagConstExpr;
+
   llvm::DISubprogram *SP = DBuilder.createFunction(
       FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
       FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl);
@@ -3760,6 +3774,10 @@
   if (CGM.getLangOpts().Optimize)
     SPFlags |= llvm::DISubprogram::SPFlagOptimized;
 
+  auto *FD = dyn_cast_or_null<FunctionDecl>(GD.getDecl());
+  if (FD && FD->isConstexpr())
+    Flags |= llvm::DINode::FlagConstExpr;
+
   llvm::DISubprogram *SP = DBuilder.createFunction(
       FDContext, Name, LinkageName, Unit, LineNo,
       getOrCreateFunctionType(D, FnType, Unit), ScopeLine, Flags, SPFlags,
@@ -4073,7 +4091,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),
@@ -4093,6 +4110,9 @@
     Expr.push_back(llvm::dwarf::DW_OP_deref);
   }
 
+  if (VD && VD->isConstexpr())
+    Flags |= llvm::DINode::FlagConstExpr;
+
   // Create the descriptor for the variable.
   auto *D = ArgNo ? DBuilder.createParameterVariable(
                         Scope, Name, *ArgNo, Unit, Line, Ty,
@@ -4476,7 +4496,7 @@
   llvm::MDTuple *TemplateParameters = nullptr;
   collectVarDeclProps(D, Unit, LineNo, T, DeclName, LinkageName,
                       TemplateParameters, DContext);
-
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   // Attempt to store one global variable for the declaration - even if we
   // emit a lot of fields.
   llvm::DIGlobalVariableExpression *GVE = nullptr;
@@ -4505,12 +4525,15 @@
     }
     AppendAddressSpaceXDeref(AddressSpace, Expr);
 
+    if (D->isConstexpr())
+      Flags |= llvm::DINode::FlagConstExpr;
+
     GVE = DBuilder.createGlobalVariableExpression(
         DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
         Var->hasLocalLinkage(), true,
         Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
         getOrCreateStaticDataMemberDeclarationOrNull(D), TemplateParameters,
-        Align);
+        Flags, Align);
     Var->addDebugInfo(GVE);
   }
   DeclCache[D->getCanonicalDecl()].reset(GVE);
@@ -4518,6 +4541,7 @@
 
 void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
   assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   if (VD->hasAttr<NoDebugAttr>())
     return;
   llvm::TimeTraceScope TimeScope("DebugConstGlobalVariable", [&]() {
@@ -4608,15 +4632,19 @@
       TemplateParameters = parameterNodes.get();
     }
 
+  if (VarD && VarD->isConstexpr())
+    Flags |= llvm::DINode::FlagConstExpr;
+
   GV.reset(DBuilder.createGlobalVariableExpression(
       DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty,
       true, true, InitExpr, getOrCreateStaticDataMemberDeclarationOrNull(VarD),
-      TemplateParameters, Align));
+      TemplateParameters, Flags, Align));
 }
 
 void CGDebugInfo::EmitExternalVariable(llvm::GlobalVariable *Var,
                                        const VarDecl *D) {
   assert(CGM.getCodeGenOpts().hasReducedDebugInfo());
+  llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   if (D->hasAttr<NoDebugAttr>())
     return;
 
@@ -4629,7 +4657,7 @@
   llvm::DIGlobalVariableExpression *GVE =
       DBuilder.createGlobalVariableExpression(
           DContext, Name, StringRef(), Unit, getLineNumber(D->getLocation()),
-          Ty, false, false, nullptr, nullptr, nullptr, Align);
+          Ty, false, false, nullptr, nullptr, nullptr, Flags, Align);
   Var->addDebugInfo(GVE);
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to