Chirag updated this revision to Diff 245809.
Chirag added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Moved five of the DIFlags to DISPFlags. (updated few clang testcases)
DIFlagExplicit -> DISPFlagExplicit
DIFlagPrototyped -> DISPFlagPrototyped
DIFlagNoReturn -> DISPFlagNoReturn
DIFlagThunk -> DISPFlagThunk
DIFlagAllCallsDescribed -> DISPFlagAllCallsDescribed

Note: currently llvm ir parser still needs the DIFlags, once the llvm ir format 
gets updated(with all the relevant testcases) the entries from 
DebugInfoFlags.def will be removed and moveDItoSP should only be used for 
bitcode read and C-API.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D74470

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp
  clang/test/CodeGenCXX/debug-info-access.cpp
  clang/test/CodeGenCXX/debug-info-cxx1y.cpp
  clang/test/CodeGenCXX/debug-info-decl-nested.cpp
  clang/test/CodeGenCXX/debug-info-deleted.cpp
  clang/test/CodeGenCXX/debug-info-ms-abi.cpp
  clang/test/CodeGenCXX/debug-info-noreturn.cpp
  clang/test/CodeGenCXX/debug-info-qualifiers.cpp
  clang/test/CodeGenCXX/debug-info-thunk.cpp
  clang/test/CodeGenObjC/debug-info-category.m
  llvm/include/llvm/IR/DIBuilder.h
  llvm/include/llvm/IR/DebugInfoFlags.def
  llvm/include/llvm/IR/DebugInfoMetadata.h
  llvm/lib/AsmParser/LLLexer.cpp
  llvm/lib/AsmParser/LLParser.cpp
  llvm/lib/AsmParser/LLToken.h
  llvm/lib/Bitcode/Reader/MetadataLoader.cpp
  llvm/lib/Bitcode/Writer/BitcodeWriter.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/Assembler/debug-info.ll
  llvm/test/Assembler/disubprogram.ll
  llvm/test/Bitcode/DIBasicType.ll
  llvm/test/Bitcode/DIBasicType.ll.bc
  llvm/test/Bitcode/DISubprogram-v5.ll
  llvm/test/DebugInfo/COFF/thunk.ll
  llvm/unittests/IR/MetadataTest.cpp

Index: llvm/unittests/IR/MetadataTest.cpp
===================================================================
--- llvm/unittests/IR/MetadataTest.cpp
+++ llvm/unittests/IR/MetadataTest.cpp
@@ -1202,9 +1202,8 @@
 typedef MetadataTest DIBasicTypeTest;
 
 TEST_F(DIBasicTypeTest, get) {
-  auto *N =
-      DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 26, 7,
-                        DINode::FlagZero);
+  auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
+                             26, 7, DIBasicType::BTFlagZero);
   EXPECT_EQ(dwarf::DW_TAG_base_type, N->getTag());
   EXPECT_EQ("special", N->getName());
   EXPECT_EQ(33u, N->getSizeInBits());
@@ -1213,31 +1212,31 @@
   EXPECT_EQ(0u, N->getLine());
   EXPECT_EQ(DINode::FlagZero, N->getFlags());
   EXPECT_EQ(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
-                                26, 7, DINode::FlagZero));
+                                26, 7, DIBasicType::BTFlagZero));
 
   EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type,
-                                "special", 33, 26, 7, DINode::FlagZero));
-  EXPECT_NE(N,
-            DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7,
-                              DINode::FlagZero));
+                                "special", 33, 26, 7, DIBasicType::BTFlagZero));
+  EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26,
+                                7, DIBasicType::BTFlagZero));
   EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32,
-                                26, 7, DINode::FlagZero));
+                                26, 7, DIBasicType::BTFlagZero));
   EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
-                                25, 7, DINode::FlagZero));
+                                25, 7, DIBasicType::BTFlagZero));
   EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
-                                26, 6, DINode::FlagZero));
+                                26, 6, DIBasicType::BTFlagZero));
   EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
-                                26, 7, DINode::FlagBigEndian));
+                                26, 7, DIBasicType::BTFlagBigEndian));
   EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
-                                26, 7, DINode::FlagLittleEndian));
+                                26, 7, DIBasicType::BTFlagLittleEndian));
 
   TempDIBasicType Temp = N->clone();
   EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
 }
 
 TEST_F(DIBasicTypeTest, getWithLargeValues) {
-  auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special",
-                             UINT64_MAX, UINT32_MAX - 1, 7, DINode::FlagZero);
+  auto *N =
+      DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", UINT64_MAX,
+                       UINT32_MAX - 1, 7, DIBasicType::BTFlagZero);
   EXPECT_EQ(UINT64_MAX, N->getSizeInBits());
   EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits());
 }
@@ -1251,7 +1250,7 @@
   EXPECT_EQ(0u, N->getAlignInBits());
   EXPECT_EQ(0u, N->getEncoding());
   EXPECT_EQ(0u, N->getLine());
-  EXPECT_EQ(DINode::FlagZero, N->getFlags());
+  EXPECT_EQ(DIBasicType::BTFlagZero, N->getBTFlags());
 }
 
 typedef MetadataTest DITypeTest;
@@ -1259,7 +1258,7 @@
 TEST_F(DITypeTest, clone) {
   // Check that DIType has a specialized clone that returns TempDIType.
   DIType *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32,
-                               dwarf::DW_ATE_signed, DINode::FlagZero);
+                               dwarf::DW_ATE_signed, DIBasicType::BTFlagZero);
 
   TempDIType Temp = N->clone();
   EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
Index: llvm/test/DebugInfo/COFF/thunk.ll
===================================================================
--- llvm/test/DebugInfo/COFF/thunk.ll
+++ llvm/test/DebugInfo/COFF/thunk.ll
@@ -94,7 +94,7 @@
 ; ASM-NEXT:   .short 2                        # Record length
 ; ASM-NEXT:   .short 4431                     # Record kind: S_PROC_ID_END 
 
-; OPT: DISubprogram(linkageName: "{{.*MyMethod.*C.*}}",{{.*}} line: 5,{{.*}} flags: DIFlagArtificial | DIFlagThunk{{.*}})
+; OPT: DISubprogram(linkageName: "{{.*MyMethod.*C.*}}",{{.*}} line: 5,{{.*}} flags: DIFlagArtificial, spFlags: {{.*}}DISPFlagThunk{{.*}})
 
 
 ; ModuleID = 'thunk.cpp'
Index: llvm/test/Bitcode/DISubprogram-v5.ll
===================================================================
--- llvm/test/Bitcode/DISubprogram-v5.ll
+++ llvm/test/Bitcode/DISubprogram-v5.ll
@@ -17,7 +17,7 @@
 !3 = !{i32 2, !"Dwarf Version", i32 4}
 !4 = !{i32 1, !"Debug Info Version", i32 3}
 !5 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !6, scopeLine: 6, virtualIndex: 6, flags: DIFlagPrototyped | DIFlagMainSubprogram, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
-; CHECK: !5 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !6, scopeLine: 6, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !0, retainedNodes: !2)
+; CHECK: !5 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 6, type: !6, scopeLine: 6, virtualIndex: 6, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram | DISPFlagPrototyped, unit: !0, retainedNodes: !2)
 !6 = !DISubroutineType(types: !7)
 !7 = !{!8}
 !8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
Index: llvm/test/Bitcode/DIBasicType.ll
===================================================================
--- /dev/null
+++ llvm/test/Bitcode/DIBasicType.ll
@@ -0,0 +1,34 @@
+; RUN: llvm-dis -o - %s.bc | FileCheck %s
+; CHECK:  = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: ![[#LETYPE:]], isLocal: false, isDefinition: true)
+; CHECK:  = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 1, type: ![[#BETYPE:]], isLocal: false, isDefinition: true)
+; CHECK: ![[#BETYPE]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, btFlags: DIBTFlagBigEndian)
+; CHECK: ![[#LETYPE]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, btFlags: DIBTFlagLittleEndian)
+
+@a = common dso_local global i32 0, align 4, !dbg !0
+@b = common dso_local global i32 0, align 4, !dbg !6
+
+define dso_local void @main() !dbg !12 {
+entry:
+  ret void, !dbg !15
+}
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!10, !11}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !9, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None)
+!3 = !DIFile(filename: "main.c", directory: "/dir")
+!4 = !{}
+!5 = !{!0, !6}
+!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression())
+!7 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true)
+!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, flags: DIFlagBigEndian)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, flags: DIFlagLittleEndian)
+!10 = !{i32 7, !"Dwarf Version", i32 4}
+!11 = !{i32 2, !"Debug Info Version", i32 3}
+!12 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 2, type: !13, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !4)
+!13 = !DISubroutineType(types: !14)
+!14 = !{null}
+!15 = !DILocation(line: 2, column: 14, scope: !12)
+
Index: llvm/test/Assembler/disubprogram.ll
===================================================================
--- llvm/test/Assembler/disubprogram.ll
+++ llvm/test/Assembler/disubprogram.ll
@@ -6,8 +6,8 @@
   ret void
 }
 
-; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19}
-!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !17, !19, !20, !21}
+; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20}
+!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !17, !19, !20, !21, !22}
 
 !0 = !{null}
 !1 = distinct !DICompositeType(tag: DW_TAG_structure_type)
@@ -28,7 +28,7 @@
 ; CHECK: !9 = !DISubprogram(scope: null, spFlags: 0)
 !9 = !DISubprogram(isDefinition: false)
 
-; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, scopeLine: 8, containingType: !4, virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !8, templateParams: !5, declaration: !9, retainedNodes: !6)
+; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, scopeLine: 8, containingType: !4, virtualIndex: 10, thisAdjustment: 3,  spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagNoReturn, unit: !8, templateParams: !5, declaration: !9, retainedNodes: !6)
 !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
                             file: !2, line: 7, type: !3, isLocal: true,
                             isDefinition: true, scopeLine: 8,
@@ -69,7 +69,7 @@
                             isDefinition: true, scopeLine: 2, isOptimized: false,
                             unit: !8, thrownTypes: !13)
 
-; CHECK: !15 = distinct !DISubprogram({{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized,
+; CHECK: !15 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped,
 !15 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1,
                              file: !2, line: 7, type: !3, scopeLine: 8,
 							 containingType: !4, virtualIndex: 0,
@@ -86,9 +86,11 @@
 ; CHECK: !DISubprogram({{.*}}subroutine2{{.*}}, spFlags: DISPFlagDefinition | DISPFlagElemental,
 ; CHECK: !DISubprogram({{.*}}subroutine3{{.*}}, spFlags: DISPFlagDefinition | DISPFlagRecursive,
 ; CHECK: !DISubprogram({{.*}}subroutine4{{.*}}, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive,
+; CHECK: !DISubprogram({{.*}}subroutine5{{.*}}, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive | DISPFlagNoReturn | DISPFlagThunk | DISPFlagAllCallsDescribed,
 
 !17 = distinct !DISubprogram(name: "subroutine1", scope: !1, file: !2, line: 1, type: !18, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagPure, unit: !8, retainedNodes: !6)
 !18 = !DISubroutineType(types: !0)
 !19 = distinct !DISubprogram(name: "subroutine2", scope: !1, file: !2, line: 5, type: !18, scopeLine: 6, spFlags: DISPFlagDefinition | DISPFlagElemental, unit: !8, retainedNodes: !6)
 !20 = distinct !DISubprogram(name: "subroutine3", scope: !1, file: !2, line: 9, type: !18, scopeLine: 10, spFlags: DISPFlagDefinition | DISPFlagRecursive, unit: !8, retainedNodes: !6)
 !21 = distinct !DISubprogram(name: "subroutine4", scope: !1, file: !2, line: 13, type: !18, scopeLine: 14, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, unit: !8, retainedNodes: !6)
+!22 = distinct !DISubprogram(name: "subroutine5", scope: !1, file: !2, line: 13, type: !18, scopeLine: 14, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive | DISPFlagThunk | DISPFlagNoReturn | DISPFlagAllCallsDescribed, unit: !8, retainedNodes: !6)
Index: llvm/test/Assembler/debug-info.ll
===================================================================
--- llvm/test/Assembler/debug-info.ll
+++ llvm/test/Assembler/debug-info.ll
@@ -95,7 +95,7 @@
 !39 = !DIFile(filename: "file", directory: "dir", source: "int source() { }\0A")
 !40 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "3a420e2646916a475e68de8d48f779f5", source: "int source() { }\0A")
 
-; CHECK-NEXT: !38 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagBigEndian)
-; CHECK-NEXT: !39 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian)
-!41 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagBigEndian)
-!42 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian)
+; CHECK-NEXT: !38 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, btFlags: DIBTFlagBigEndian)
+; CHECK-NEXT: !39 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, btFlags: DIBTFlagLittleEndian)
+!41 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, btFlags: DIBTFlagBigEndian)
+!42 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, btFlags: DIBTFlagLittleEndian)
Index: llvm/lib/IR/LLVMContextImpl.h
===================================================================
--- llvm/lib/IR/LLVMContextImpl.h
+++ llvm/lib/IR/LLVMContextImpl.h
@@ -379,22 +379,22 @@
   uint64_t SizeInBits;
   uint32_t AlignInBits;
   unsigned Encoding;
-  unsigned Flags;
+  unsigned BTFlags;
 
   MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
-                uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
+                uint32_t AlignInBits, unsigned Encoding, unsigned BTFlags)
       : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
-        Encoding(Encoding), Flags(Flags) {}
+        Encoding(Encoding), BTFlags(BTFlags) {}
   MDNodeKeyImpl(const DIBasicType *N)
       : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
-        AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), Flags(N->getFlags()) {}
+        AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()),
+        BTFlags(N->getBTFlags()) {}
 
   bool isKeyOf(const DIBasicType *RHS) const {
     return Tag == RHS->getTag() && Name == RHS->getRawName() &&
            SizeInBits == RHS->getSizeInBits() &&
            AlignInBits == RHS->getAlignInBits() &&
-           Encoding == RHS->getEncoding() &&
-           Flags == RHS->getFlags();
+           Encoding == RHS->getEncoding() && BTFlags == RHS->getBTFlags();
   }
 
   unsigned getHashValue() const {
Index: llvm/lib/IR/DebugInfoMetadata.cpp
===================================================================
--- llvm/lib/IR/DebugInfoMetadata.cpp
+++ llvm/lib/IR/DebugInfoMetadata.cpp
@@ -344,14 +344,46 @@
 DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
                                   MDString *Name, uint64_t SizeInBits,
                                   uint32_t AlignInBits, unsigned Encoding,
-                                  DIFlags Flags, StorageType Storage,
+                                  DIBTFlags BTFlags, StorageType Storage,
                                   bool ShouldCreate) {
   assert(isCanonical(Name) && "Expected canonical MDString");
-  DEFINE_GETIMPL_LOOKUP(DIBasicType,
-                        (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags));
+  DEFINE_GETIMPL_LOOKUP(
+      DIBasicType, (Tag, Name, SizeInBits, AlignInBits, Encoding, BTFlags));
   Metadata *Ops[] = {nullptr, nullptr, Name};
-  DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding,
-                      Flags), Ops);
+  DEFINE_GETIMPL_STORE(DIBasicType,
+                       (Tag, SizeInBits, AlignInBits, Encoding, BTFlags), Ops);
+}
+
+DIBasicType::DIBTFlags DIBasicType::getFlag(StringRef Flag) {
+  return StringSwitch<DIBTFlags>(Flag)
+#define HANDLE_DIBT_FLAG(ID, NAME) .Case("DIBTFlag" #NAME, BTFlag##NAME)
+#include "llvm/IR/DebugInfoFlags.def"
+      .Default(BTFlagZero);
+}
+
+StringRef DIBasicType::getFlagString(DIBTFlags Flag) {
+  switch (Flag) {
+    // Appease a warning.
+#define HANDLE_DIBT_FLAG(ID, NAME)                                             \
+  case BTFlag##NAME:                                                           \
+    return "DIBTFlag" #NAME;
+#include "llvm/IR/DebugInfoFlags.def"
+  }
+  return "";
+}
+
+DIBasicType::DIBTFlags
+DIBasicType::splitFlags(DIBTFlags Flags,
+                        SmallVectorImpl<DIBTFlags> &SplitFlags) {
+  // Multi-bit fields can require special handling. In our case all its values
+  // happen to be single-bit values.
+#define HANDLE_DIBT_FLAG(ID, NAME)                                             \
+  if (DIBTFlags Bit = Flags & BTFlag##NAME) {                                  \
+    SplitFlags.push_back(Bit);                                                 \
+    Flags &= ~Bit;                                                             \
+  }
+#include "llvm/IR/DebugInfoFlags.def"
+  return Flags;
 }
 
 Optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
Index: llvm/lib/IR/DebugInfo.cpp
===================================================================
--- llvm/lib/IR/DebugInfo.cpp
+++ llvm/lib/IR/DebugInfo.cpp
@@ -726,6 +726,11 @@
   return static_cast<LLVMDIFlags>(Flags);
 }
 
+static DIBasicType::DIBTFlags pack_into_DIBTFlags(bool IsBigEndian,
+                                                  bool IsLittleEndian) {
+  return DIBasicType::toBTFlags(IsBigEndian, IsLittleEndian);
+}
+
 static DISubprogram::DISPFlags
 pack_into_DISPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized) {
   return DISubprogram::toSPFlags(IsLocalToUnit, IsDefinition, IsOptimized);
@@ -811,12 +816,16 @@
     LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,
     LLVMBool IsLocalToUnit, LLVMBool IsDefinition,
     unsigned ScopeLine, LLVMDIFlags Flags, LLVMBool IsOptimized) {
+  auto DIFlags = map_from_llvmDIFlags(Flags);
+  auto SPDIFlags =
+      pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized);
+  // some Flags were moved from DIFlag to SPFlag.
+  DISubprogram::moveDItoSPFlags(DIFlags, SPDIFlags);
+
   return wrap(unwrap(Builder)->createFunction(
       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));
+      DIFlags, SPDIFlags, nullptr, nullptr, nullptr));
 }
 
 
@@ -1018,9 +1027,10 @@
                              size_t NameLen, uint64_t SizeInBits,
                              LLVMDWARFTypeEncoding Encoding,
                              LLVMDIFlags Flags) {
-  return wrap(unwrap(Builder)->createBasicType({Name, NameLen},
-                                               SizeInBits, Encoding,
-                                               map_from_llvmDIFlags(Flags)));
+  auto BTFlags = pack_into_DIBTFlags(Flags & LLVMDIFlagBigEndian,
+                                     Flags & LLVMDIFlagLittleEndian);
+  return wrap(unwrap(Builder)->createBasicType({Name, NameLen}, SizeInBits,
+                                               Encoding, BTFlags));
 }
 
 LLVMMetadataRef LLVMDIBuilderCreatePointerType(
Index: llvm/lib/IR/DIBuilder.cpp
===================================================================
--- llvm/lib/IR/DIBuilder.cpp
+++ llvm/lib/IR/DIBuilder.cpp
@@ -260,7 +260,7 @@
 
 DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
                                         unsigned Encoding,
-                                        DINode::DIFlags Flags) {
+                                        DIBasicType::DIBTFlags Flags) {
   assert(!Name.empty() && "Unable to create type without name");
   return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits,
                           0, Encoding, Flags);
Index: llvm/lib/IR/AsmWriter.cpp
===================================================================
--- llvm/lib/IR/AsmWriter.cpp
+++ llvm/lib/IR/AsmWriter.cpp
@@ -1619,6 +1619,7 @@
   void printBool(StringRef Name, bool Value, Optional<bool> Default = None);
   void printDIFlags(StringRef Name, DINode::DIFlags Flags);
   void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags);
+  void printDIBTFlags(StringRef Name, DIBasicType::DIBTFlags Flags);
   template <class IntTy, class Stringifier>
   void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString,
                       bool ShouldSkipZero = true);
@@ -1717,6 +1718,26 @@
     Out << FlagsFS << Extra;
 }
 
+void MDFieldPrinter::printDIBTFlags(StringRef Name,
+                                    DIBasicType::DIBTFlags Flags) {
+  if (!Flags) {
+    return;
+  }
+
+  Out << FS << Name << ": ";
+  SmallVector<DIBasicType::DIBTFlags, 8> SplitFlags;
+  auto Extra = DIBasicType::splitFlags(Flags, SplitFlags);
+
+  FieldSeparator FlagsFS(" | ");
+  for (auto F : SplitFlags) {
+    auto StringF = DIBasicType::getFlagString(F);
+    assert(!StringF.empty() && "Expected valid flag");
+    Out << FlagsFS << StringF;
+  }
+  if (Extra || SplitFlags.empty())
+    Out << FlagsFS << Extra;
+}
+
 void MDFieldPrinter::printDISPFlags(StringRef Name,
                                     DISubprogram::DISPFlags Flags) {
   // Always print this field, because no flags in the IR at all will be
@@ -1841,7 +1862,7 @@
   Printer.printInt("align", N->getAlignInBits());
   Printer.printDwarfEnum("encoding", N->getEncoding(),
                          dwarf::AttributeEncodingString);
-  Printer.printDIFlags("flags", N->getFlags());
+  Printer.printDIBTFlags("btFlags", N->getBTFlags());
   Out << ")";
 }
 
Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1540,13 +1540,14 @@
 void ModuleBitcodeWriter::writeDIBasicType(const DIBasicType *N,
                                            SmallVectorImpl<uint64_t> &Record,
                                            unsigned Abbrev) {
-  Record.push_back(N->isDistinct());
+  const uint64_t HasBTFlagsFlag = 1 << 1;
+  Record.push_back(uint64_t(N->isDistinct()) | HasBTFlagsFlag);
   Record.push_back(N->getTag());
   Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
   Record.push_back(N->getSizeInBits());
   Record.push_back(N->getAlignInBits());
   Record.push_back(N->getEncoding());
-  Record.push_back(N->getFlags());
+  Record.push_back(N->getBTFlags());
 
   Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev);
   Record.clear();
Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp
===================================================================
--- llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -1293,14 +1293,27 @@
     if (Record.size() < 6 || Record.size() > 7)
       return error("Invalid record");
 
-    IsDistinct = Record[0];
-    DINode::DIFlags Flags = (Record.size() > 6) ?
-                    static_cast<DINode::DIFlags>(Record[6]) : DINode::FlagZero;
+    IsDistinct = Record[0] & 1;
+    bool HasBTFlags = Record[0] & 2;
+    DIBasicType::DIBTFlags BTFlags = DIBasicType::BTFlagZero;
+
+    // BasicType-specific flags in DIFlag were moved to DIBTFlags.
+    const unsigned DIFlagBigEndian = (1 << 27);
+    const unsigned DIFlagLittleEndian = (1 << 28);
+    if (Record.size() > 6) {
+      if (HasBTFlags)
+        BTFlags = static_cast<DIBasicType::DIBTFlags>(Record[6]);
+      else {
+        DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[6]);
+        BTFlags = DIBasicType::toBTFlags(Flags & DIFlagBigEndian,
+                                         Flags & DIFlagLittleEndian);
+      }
+    }
 
     MetadataList.assignValue(
         GET_OR_DISTINCT(DIBasicType,
                         (Context, Record[1], getMDString(Record[2]), Record[3],
-                         Record[4], Record[5], Flags)),
+                         Record[4], Record[5], BTFlags)),
         NextMetadataNo);
     NextMetadataNo++;
     break;
@@ -1489,9 +1502,8 @@
       return error("Invalid record");
 
     bool HasSPFlags = Record[0] & 4;
-
     DINode::DIFlags Flags;
-    DISubprogram::DISPFlags SPFlags;
+    DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagZero;
     if (!HasSPFlags)
       Flags = static_cast<DINode::DIFlags>(Record[11 + 2]);
     else {
@@ -1499,6 +1511,9 @@
       SPFlags = static_cast<DISubprogram::DISPFlags>(Record[9]);
     }
 
+    // Some flags were moved from DIFlags to SPFlags
+    DISubprogram::moveDItoSPFlags(Flags, SPFlags);
+
     // Support for old metadata when
     // subprogram specific flags are placed in DIFlags.
     const unsigned DIFlagMainSubprogram = 1 << 21;
Index: llvm/lib/AsmParser/LLToken.h
===================================================================
--- llvm/lib/AsmParser/LLToken.h
+++ llvm/lib/AsmParser/LLToken.h
@@ -462,6 +462,7 @@
   DwarfOp,          // DW_OP_foo
   DIFlag,           // DIFlagFoo
   DISPFlag,         // DISPFlagFoo
+  DIBTFlag,         // DIBTFlagFoo
   DwarfMacinfo,     // DW_MACINFO_foo
   ChecksumKind,     // CSK_foo
 
Index: llvm/lib/AsmParser/LLParser.cpp
===================================================================
--- llvm/lib/AsmParser/LLParser.cpp
+++ llvm/lib/AsmParser/LLParser.cpp
@@ -3870,6 +3870,10 @@
   DISPFlagField() : MDFieldImpl(DISubprogram::SPFlagZero) {}
 };
 
+struct DIBTFlagField : public MDFieldImpl<DIBasicType::DIBTFlags> {
+  DIBTFlagField() : MDFieldImpl(DIBasicType::BTFlagZero) {}
+};
+
 struct MDSignedField : public MDFieldImpl<int64_t> {
   int64_t Min;
   int64_t Max;
@@ -4162,6 +4166,46 @@
   return false;
 }
 
+/// DIBTFlagField
+///  ::= uint32
+///  ::= DIBTFlagBigEndian
+///  ::= DIBTFlagBigEndian '|' DIBTFlag* '|' uint32
+template <>
+bool LLParser::ParseMDField(LocTy Loc, StringRef Name, DIBTFlagField &Result) {
+
+  // Parser for a single flag.
+  auto parseFlag = [&](DIBasicType::DIBTFlags &Val) {
+    if (Lex.getKind() == lltok::APSInt && !Lex.getAPSIntVal().isSigned()) {
+      uint32_t TempVal = static_cast<uint32_t>(Val);
+      bool Res = ParseUInt32(TempVal);
+      Val = static_cast<DIBasicType::DIBTFlags>(TempVal);
+      return Res;
+    }
+
+    if (Lex.getKind() != lltok::DIBTFlag)
+      return TokError("expected debug info flag");
+
+    Val = DIBasicType::getFlag(Lex.getStrVal());
+    if (!Val)
+      return TokError(Twine("invalid basicType debug info flag '") +
+                      Lex.getStrVal() + "'");
+    Lex.Lex();
+    return false;
+  };
+
+  // Parse the flags and combine them together.
+  DIBasicType::DIBTFlags Combined = DIBasicType::BTFlagZero;
+  do {
+    DIBasicType::DIBTFlags Val;
+    if (parseFlag(Val))
+      return true;
+    Combined |= Val;
+  } while (EatIfPresent(lltok::bar));
+
+  Result.assign(Combined);
+  return false;
+}
+
 /// DISPFlagField
 ///  ::= uint32
 ///  ::= DISPFlagVector
@@ -4490,9 +4534,8 @@
   return false;
 }
 
-/// ParseDIBasicType:
 ///   ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32,
-///                    encoding: DW_ATE_encoding, flags: 0)
+///                    encoding: DW_ATE_encoding, btFlags: DIBTFlagBigEndian)
 bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) {
 #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED)                                    \
   OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type));                     \
@@ -4500,12 +4543,11 @@
   OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX));                            \
   OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX));                           \
   OPTIONAL(encoding, DwarfAttEncodingField, );                                 \
-  OPTIONAL(flags, DIFlagField, );
+  OPTIONAL(btFlags, DIBTFlagField, );
   PARSE_MD_FIELDS();
 #undef VISIT_MD_FIELDS
-
   Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val,
-                                         align.Val, encoding.Val, flags.Val));
+                                         align.Val, encoding.Val, btFlags.Val));
   return false;
 }
 
@@ -4715,10 +4757,14 @@
       spFlags.Seen ? spFlags.Val
                    : DISubprogram::toSPFlags(isLocal.Val, isDefinition.Val,
                                              isOptimized.Val, virtuality.Val);
+  // some of the DIFlags were moved to SPFlags
+  DISubprogram::moveDItoSPFlags(flags.Val, SPFlags);
+
   if ((SPFlags & DISubprogram::SPFlagDefinition) && !IsDistinct)
     return Lex.Error(
         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,
Index: llvm/lib/AsmParser/LLLexer.cpp
===================================================================
--- llvm/lib/AsmParser/LLLexer.cpp
+++ llvm/lib/AsmParser/LLLexer.cpp
@@ -928,6 +928,11 @@
     return lltok::DISPFlag;
   }
 
+  if (Keyword.startswith("DIBTFlag")) {
+    StrVal.assign(Keyword.begin(), Keyword.end());
+    return lltok::DIBTFlag;
+  }
+
   if (Keyword.startswith("CSK_")) {
     StrVal.assign(Keyword.begin(), Keyword.end());
     return lltok::ChecksumKind;
Index: llvm/include/llvm/IR/DebugInfoMetadata.h
===================================================================
--- llvm/include/llvm/IR/DebugInfoMetadata.h
+++ llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -665,8 +665,6 @@
   bool isTypePassByReference() const {
     return getFlags() & FlagTypePassByReference;
   }
-  bool isBigEndian() const { return getFlags() & FlagBigEndian; }
-  bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
   bool getExportSymbols() const { return getFlags() & FlagExportSymbols; }
 
   static bool classof(const Metadata *MD) {
@@ -690,50 +688,79 @@
   friend class LLVMContextImpl;
   friend class MDNode;
 
+public:
+  /// Debug BasicType flags.
+  enum DIBTFlags : uint32_t {
+#define HANDLE_DIBT_FLAG(ID, NAME) BTFlag##NAME = ID,
+#define DIBT_FLAG_LARGEST_NEEDED
+#include "llvm/IR/DebugInfoFlags.def"
+    LLVM_MARK_AS_BITMASK_ENUM(BTFlagLargest)
+  };
+
+  static DIBTFlags getFlag(StringRef Flag);
+  static StringRef getFlagString(DIBTFlags Flag);
+
+  /// Split up a flags bitfield for easier printing.
+  ///
+  /// Split \c Flags into \c SplitFlags, a vector of its components.  Returns
+  /// any remaining (unrecognized) bits.
+  static DIBTFlags splitFlags(DIBTFlags Flags,
+                              SmallVectorImpl<DIBTFlags> &SplitFlags);
+
+  // Helper for converting old bitfields to new flags word.
+  static DIBTFlags toBTFlags(bool IsBigEndian, bool IsLittleEndian) {
+    return static_cast<DIBTFlags>(
+        (IsBigEndian ? BTFlagBigEndian : BTFlagZero) |
+        (IsLittleEndian ? BTFlagLittleEndian : BTFlagZero));
+  }
+
+private:
+  DIBTFlags BTFlags;
   unsigned Encoding;
 
   DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
               uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
-              DIFlags Flags, ArrayRef<Metadata *> Ops)
+              DIBTFlags BTFlags, ArrayRef<Metadata *> Ops)
       : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
-               Flags, Ops),
-        Encoding(Encoding) {}
+               FlagZero, Ops),
+        BTFlags(BTFlags), Encoding(Encoding) {}
   ~DIBasicType() = default;
 
   static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
                               StringRef Name, uint64_t SizeInBits,
                               uint32_t AlignInBits, unsigned Encoding,
-                              DIFlags Flags, StorageType Storage,
+                              DIBTFlags BTFlags, StorageType Storage,
                               bool ShouldCreate = true) {
     return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
-                   SizeInBits, AlignInBits, Encoding, Flags, Storage,
+                   SizeInBits, AlignInBits, Encoding, BTFlags, Storage,
                    ShouldCreate);
   }
+
   static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
                               MDString *Name, uint64_t SizeInBits,
                               uint32_t AlignInBits, unsigned Encoding,
-                              DIFlags Flags, StorageType Storage,
+                              DIBTFlags BTFlags, StorageType Storage,
                               bool ShouldCreate = true);
 
   TempDIBasicType cloneImpl() const {
     return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
-                        getAlignInBits(), getEncoding(), getFlags());
+                        getAlignInBits(), getEncoding(), getBTFlags());
   }
 
 public:
   DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
-                    (Tag, Name, 0, 0, 0, FlagZero))
+                    (Tag, Name, 0, 0, 0, BTFlagZero))
   DEFINE_MDNODE_GET(DIBasicType,
                     (unsigned Tag, StringRef Name, uint64_t SizeInBits,
-                     uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
+                     uint32_t AlignInBits, unsigned Encoding, DIBTFlags Flags),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
   DEFINE_MDNODE_GET(DIBasicType,
                     (unsigned Tag, MDString *Name, uint64_t SizeInBits,
-                     uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
+                     uint32_t AlignInBits, unsigned Encoding, DIBTFlags Flags),
                     (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
 
   TempDIBasicType clone() const { return cloneImpl(); }
-
+  DIBTFlags getBTFlags() const { return BTFlags; }
   unsigned getEncoding() const { return Encoding; }
 
   enum class Signedness { Signed, Unsigned };
@@ -741,6 +768,8 @@
   /// Return the signedness of this type, or None if this type is neither
   /// signed nor unsigned.
   Optional<Signedness> getSignedness() const;
+  bool isBigEndian() const { return getBTFlags() & BTFlagBigEndian; }
+  bool isLittleEndian() const { return getBTFlags() & BTFlagLittleEndian; }
 
   static bool classof(const Metadata *MD) {
     return MD->getMetadataID() == DIBasicTypeKind;
@@ -1643,6 +1672,28 @@
         (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
   }
 
+  static void moveDItoSPFlags(DIFlags &Flags, DISPFlags &SPFlags) {
+    const uint32_t DIFlagExplicit = 1 << 7;
+    const uint32_t DIFlagPrototyped = 1 << 8;
+    const uint32_t DIFlagNoReturn = 1 << 20;
+    const uint32_t DIFlagThunk = 1 << 25;
+    const uint32_t DIFlagAllCallsDescribed = 1 << 29;
+    if (Flags & DIFlagExplicit)
+      SPFlags |= SPFlagExplicit;
+    if (Flags & DIFlagPrototyped)
+      SPFlags |= SPFlagPrototyped;
+    if (Flags & DIFlagNoReturn)
+      SPFlags |= SPFlagNoReturn;
+    if (Flags & DIFlagThunk)
+      SPFlags |= SPFlagThunk;
+    if (Flags & DIFlagAllCallsDescribed)
+      SPFlags |= SPFlagAllCallsDescribed;
+
+    Flags = static_cast<DINode::DIFlags>(
+        Flags & ~(DIFlagExplicit | DIFlagPrototyped | DIFlagNoReturn |
+                  DIFlagThunk | DIFlagAllCallsDescribed));
+  }
+
 private:
   DIFlags Flags;
   DISPFlags SPFlags;
@@ -1751,10 +1802,10 @@
   bool isPublic() const {
     return (getFlags() & FlagAccessibility) == FlagPublic;
   }
-  bool isExplicit() const { return getFlags() & FlagExplicit; }
-  bool isPrototyped() const { return getFlags() & FlagPrototyped; }
+  bool isExplicit() const { return getSPFlags() & SPFlagExplicit; }
+  bool isPrototyped() const { return getSPFlags() & SPFlagPrototyped; }
   bool areAllCallsDescribed() const {
-    return getFlags() & FlagAllCallsDescribed;
+    return getSPFlags() & SPFlagAllCallsDescribed;
   }
   bool isPure() const { return getSPFlags() & SPFlagPure; }
   bool isElemental() const { return getSPFlags() & SPFlagElemental; }
@@ -1782,12 +1833,12 @@
   /// Check if this is marked as noreturn.
   ///
   /// Return true if this subprogram is C++11 noreturn or C11 _Noreturn
-  bool isNoReturn() const { return getFlags() & FlagNoReturn; }
+  bool isNoReturn() const { return getSPFlags() & SPFlagNoReturn; }
 
   // Check if this routine is a compiler-generated thunk.
   //
   // Returns true if this subprogram is a thunk generated by the compiler.
-  bool isThunk() const { return getFlags() & FlagThunk; }
+  bool isThunk() const { return getSPFlags() & SPFlagThunk; }
 
   DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
 
Index: llvm/include/llvm/IR/DebugInfoFlags.def
===================================================================
--- llvm/include/llvm/IR/DebugInfoFlags.def
+++ llvm/include/llvm/IR/DebugInfoFlags.def
@@ -10,7 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#if !(defined HANDLE_DI_FLAG || defined HANDLE_DISP_FLAG)
+#if !(defined HANDLE_DI_FLAG || defined HANDLE_DISP_FLAG ||                    \
+      defined HANDLE_DIBT_FLAG || defined HANDLE_DIVAR_FLAG)
 #error "Missing macro definition of HANDLE_DI*"
 #endif
 
@@ -22,6 +23,14 @@
 #define HANDLE_DISP_FLAG(ID, NAME)
 #endif
 
+#ifndef HANDLE_DIBT_FLAG
+#define HANDLE_DIBT_FLAG(ID, NAME)
+#endif
+
+#ifndef HANDLE_DIVAR_FLAG
+#define HANDLE_DIVAR_FLAG(ID, NAME)
+#endif
+
 // General flags kept in DINode.
 
 HANDLE_DI_FLAG(0, Zero) // Use it as zero value.
@@ -55,8 +64,6 @@
 HANDLE_DI_FLAG((1 << 24), EnumClass)
 HANDLE_DI_FLAG((1 << 25), Thunk)
 HANDLE_DI_FLAG((1 << 26), NonTrivial)
-HANDLE_DI_FLAG((1 << 27), BigEndian)
-HANDLE_DI_FLAG((1 << 28), LittleEndian)
 HANDLE_DI_FLAG((1 << 29), AllCallsDescribed)
 
 // To avoid needing a dedicated value for IndirectVirtualBase, we use
@@ -91,13 +98,50 @@
 // for defaulted functions
 HANDLE_DISP_FLAG((1u << 9), Deleted)
 HANDLE_DISP_FLAG((1u << 11), ObjCDirect)
+HANDLE_DISP_FLAG((1u << 12), Explicit)
+HANDLE_DISP_FLAG((1u << 13), Prototyped)
+HANDLE_DISP_FLAG((1u << 14), NoReturn)
+HANDLE_DISP_FLAG((1u << 15), Thunk)
+HANDLE_DISP_FLAG((1u << 16), AllCallsDescribed)
 
 #ifdef DISP_FLAG_LARGEST_NEEDED
 // Intended to be used with ADT/BitmaskEnum.h.
 // NOTE: Always must be equal to largest flag, check this when adding new flags.
-HANDLE_DISP_FLAG((1 << 11), Largest)
+HANDLE_DISP_FLAG((1 << 16), Largest)
 #undef DISP_FLAG_LARGEST_NEEDED
 #endif
 
+// BasicType flags kept in DIBasicType.
+
+// Use this as a zero/initialization value.
+// For example: void foo(DIBTFlags Flags = BTFlagZero).
+HANDLE_DIBT_FLAG(0, Zero)
+HANDLE_DIBT_FLAG(1u, LittleEndian)
+HANDLE_DIBT_FLAG(2u, BigEndian)
+
+#ifdef DIBT_FLAG_LARGEST_NEEDED
+// Intended to be used with ADT/BitmaskEnum.h.
+// NOTE: Always must be equal to largest flag, check this when adding new flags.
+HANDLE_DIBT_FLAG(2u, Largest)
+#undef DIBT_FLAG_LARGEST_NEEDED
+#endif
+
+// LocalVariable flags kept in DILocalVariable.
+
+// Use this as a zero/initialization value.
+// For example: void foo(DIVARFlags Flags = VARFlagZero).
+HANDLE_DIVAR_FLAG(0, Zero)
+HANDLE_DIVAR_FLAG(1u, FlagArtificial)
+HANDLE_DIVAR_FLAG(2u, FlagObjectPointer)
+
+#ifdef DIVAR_FLAG_LARGEST_NEEDED
+// Intended to be used with ADT/BitmaskEnum.h.
+// NOTE: Always must be equal to largest flag, check this when adding new flags.
+HANDLE_DIVAR_FLAG(2u, Largest)
+#undef DIVAR_FLAG_LARGEST_NEEDED
+#endif
+
 #undef HANDLE_DI_FLAG
 #undef HANDLE_DISP_FLAG
+#undef HANDLE_DIBT_FLAG
+#undef HANDLE_DIVAR_FLAG
Index: llvm/include/llvm/IR/DIBuilder.h
===================================================================
--- llvm/include/llvm/IR/DIBuilder.h
+++ llvm/include/llvm/IR/DIBuilder.h
@@ -192,9 +192,9 @@
     /// \param SizeInBits  Size of the type.
     /// \param Encoding    DWARF encoding code, e.g., dwarf::DW_ATE_float.
     /// \param Flags       Optional DWARF attributes, e.g., DW_AT_endianity.
-    DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits,
-                                 unsigned Encoding,
-                                 DINode::DIFlags Flags = DINode::FlagZero);
+    DIBasicType *
+    createBasicType(StringRef Name, uint64_t SizeInBits, unsigned Encoding,
+                    DIBasicType::DIBTFlags Flags = DIBasicType::BTFlagZero);
 
     /// Create debugging information entry for a qualified
     /// type, e.g. 'const int'.
Index: clang/test/CodeGenObjC/debug-info-category.m
===================================================================
--- clang/test/CodeGenObjC/debug-info-category.m
+++ clang/test/CodeGenObjC/debug-info-category.m
@@ -37,15 +37,15 @@
 // CHECK: ![[STRUCT:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo"
 
 // Verify "not a definition" by showing spFlags doesn't have DISPFlagDefinition.
-// DWARF5: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
-// DWARF5: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
-// DWARF5: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
-// DWARF5: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
-
-// DWARF4-NOT: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
-// DWARF4-NOT: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
-// DWARF4-NOT: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
-// DWARF4-NOT: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit,
+// DWARF5: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped,
+// DWARF5: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped,
+// DWARF5: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped,
+// DWARF5: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped,
+
+// DWARF4-NOT: !DISubprogram(name: "-[Foo integer]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped,
+// DWARF4-NOT: !DISubprogram(name: "-[Foo integer:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped,
+// DWARF4-NOT: !DISubprogram(name: "+[Foo(Bar) zero:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped,
+// DWARF4-NOT: !DISubprogram(name: "-[Foo(Bar) add:]", scope: ![[STRUCT]], {{.*}} spFlags: DISPFlagLocalToUnit | DISPFlagPrototyped,
 
 // CHECK: = distinct !DISubprogram(name: "-[Foo integer]"{{.*}} DISPFlagDefinition
 // CHECK: = distinct !DISubprogram(name: "-[Foo integer:]"{{.*}} DISPFlagDefinition
Index: clang/test/CodeGenCXX/debug-info-thunk.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-thunk.cpp
+++ clang/test/CodeGenCXX/debug-info-thunk.cpp
@@ -28,8 +28,8 @@
     
     virtual void f();
   };
-  
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test1@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test1@@W7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   void C::f() { }
 }
 
@@ -46,8 +46,8 @@
     
     virtual V2 *f();
   };
-  
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@B@Test2@@QEAAPEAUV1@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@B@Test2@@QEAAPEAUV1@2@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   V2 *B::f() { return 0; }
 }
 
@@ -65,8 +65,8 @@
     
     virtual void f();
   };
-  
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test3@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test3@@W7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   void C::f() { }
 }
 
@@ -86,7 +86,7 @@
     };
   }
   void C::c() {}
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A0x{{[^@]*}}@Test4@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A0x{{[^@]*}}@Test4@@W7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   void C::f() {}
 
   // Force C::f to be used.
@@ -132,7 +132,7 @@
     virtual X f();
   };
 
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@Thunks@Test5@@WBA@EAA?AUX@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@Thunks@Test5@@WBA@EAA?AUX@2@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   X Thunks::f() { return X(); }
 }
 
@@ -166,7 +166,7 @@
 
   class D : public B,
             public C {
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@D@Test6@@G7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+    // CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@D@Test6@@G7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
     void foo() {}
     void bar() {}
     void baz(X, X&, _Complex float, Small, Small&, Large);
@@ -180,7 +180,7 @@
 namespace Test7 {
   struct A { virtual void foo(); };
   struct B { virtual void foo(); };
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@C@Test7@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo@C@Test7@@W7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   struct C : A, B { void foo() {} };
 
   // Test later.
@@ -193,7 +193,7 @@
   struct A {             virtual A* f(); };
   struct B : virtual A { virtual A* f(); };
   struct C : B         { virtual C* f(); };
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test8@@QEAAPEAUA@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test8@@QEAAPEAUA@2@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   C* C::f() { return 0; }
 }
 
@@ -211,8 +211,8 @@
     virtual ~D();
     virtual D &foo1();
   };
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAUB1@2@XZ"{{.*}} flags: {{.*}}DIFlagThunk
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAU12@XZ"{{.*}} flags: {{.*}}DIFlagThunk
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAUB1@2@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?foo1@D@Test9@@$4PPPPPPPE@A@EAAAEAU12@XZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   D& D::foo1() {
     return *this;
   }
@@ -228,7 +228,7 @@
   class C : public A, public B  {
     virtual void f();
   };
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test10@@G7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+  // CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@Test10@@G7EAAXXZ"{{.*}} spFlags: {{.*}}DISPFlagThunk
   void C::f() {
   }
 }
@@ -240,7 +240,7 @@
   };
 
   void test() {
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "??_9A@Test11@@$BA@AA"{{.*}} flags: {{.*}}DIFlagThunk
+    // CHECK-DAG: DISubprogram{{.*}}linkageName: "??_9A@Test11@@$BA@AA"{{.*}} spFlags: {{.*}}DISPFlagThunk
     void (A::*p)() = &A::f;
   }
 }
@@ -269,8 +269,8 @@
   // ITANIUM: ![[SP]] = distinct !DISubprogram(linkageName: "_ZThn{{[48]}}_N6Test121C1fEv"
   // ITANIUM-SAME:          line: 261
   // ITANIUM-SAME:          DIFlagArtificial
-  // ITANIUM-SAME:          DIFlagThunk
   // ITANIUM-SAME:          DISPFlagDefinition
+  // ITANIUM-SAME:          DISPFlagThunk
   // ITANIUM-SAME:          ){{$}}
   //
   // ITANIUM: ![[DBG]] = !DILocation(line: 0
Index: clang/test/CodeGenCXX/debug-info-qualifiers.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-qualifiers.cpp
+++ clang/test/CodeGenCXX/debug-info-qualifiers.cpp
@@ -3,18 +3,20 @@
 class A {
 public:
   // CHECK: !DISubprogram(name: "l",
-  // CHECK-SAME:          line: [[@LINE+4]]
+  // CHECK-SAME:          line: [[@LINE+5]]
   // CHECK-SAME:          type: ![[PLSR:[0-9]+]]
-  // CHECK-SAME:          flags: DIFlagPublic | DIFlagPrototyped | DIFlagLValueReference,
+  // CHECK-SAME:          flags: DIFlagPublic | DIFlagLValueReference,
+  // CHECK-SAME:          spFlags: DISPFlagPrototyped)
   // CHECK: ![[PLSR]] = !DISubroutineType(flags: DIFlagLValueReference, types: ![[ARGS:[0-9]+]])
   void l() const &;
   // CHECK: ![[ARGS]] = !{null, ![[THIS:[0-9]+]]}
   // CHECK: ![[THIS]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[CONST_A:[0-9]+]]
   // CHECK: ![[CONST_A]] = !DIDerivedType(tag: DW_TAG_const_type
   // CHECK: !DISubprogram(name: "r"
-  // CHECK-SAME:          line: [[@LINE+4]]
+  // CHECK-SAME:          line: [[@LINE+5]]
   // CHECK-SAME:          type: ![[PRSR:[0-9]+]]
-  // CHECK-SAME:          flags: DIFlagPublic | DIFlagPrototyped | DIFlagRValueReference,
+  // CHECK-SAME:          flags: DIFlagPublic | DIFlagRValueReference,
+  // CHECK-SAME:          spFlags: DISPFlagPrototyped)
   // CHECK: ![[PRSR]] = !DISubroutineType(flags: DIFlagRValueReference, types: ![[ARGS]])
   void r() const &&;
 };
Index: clang/test/CodeGenCXX/debug-info-noreturn.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-noreturn.cpp
+++ clang/test/CodeGenCXX/debug-info-noreturn.cpp
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -std=c++11 -emit-llvm -fcxx-exceptions -debug-info-kind=standalone  %s -o - | FileCheck %s
 // Test for NoReturn flags in debug info.
 
-// CHECK: DISubprogram(name: "f", {{.*}}, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagDefinition
-// CHECK: DISubprogram(name: "foo_member", {{.*}}, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: 0
-// CHECK-NOT: DISubprogram(name: "func",{{.*}}, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagDefinition
+// CHECK: DISubprogram(name: "f", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagPrototyped | DISPFlagNoReturn,
+// CHECK: DISubprogram(name: "foo_member", {{.*}}, spFlags: DISPFlagPrototyped | DISPFlagNoReturn)
+// CHECK-NOT: DISubprogram(name: "func",{{.*}}, spFlags: DISPFlagDefinition | DISPFlagPrototyped | DISPFlagNoReturn
 
 class foo {
 
Index: clang/test/CodeGenCXX/debug-info-ms-abi.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-ms-abi.cpp
+++ clang/test/CodeGenCXX/debug-info-ms-abi.cpp
@@ -31,21 +31,22 @@
 
 // CHECK: ![[f]] = !DISubprogram(name: "f",
 // CHECK-SAME: containingType: ![[Foo]], virtualIndex: 0,
-// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
-// CHECK-SAME: spFlags: DISPFlagVirtual
+// CHECK-SAME: flags: DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual | DISPFlagPrototyped
 
 // CHECK: ![[g]] = !DISubprogram(name: "g",
 // CHECK-SAME: containingType: ![[Foo]], virtualIndex: 1,
-// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
-// CHECK-SAME: spFlags: DISPFlagVirtual
+// CHECK-SAME: flags: DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual | DISPFlagPrototyped
 
 // CHECK: ![[h]] = !DISubprogram(name: "h",
 // CHECK-SAME: containingType: ![[Foo]], virtualIndex: 2,
-// CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
-// CHECK-SAME: spFlags: DISPFlagVirtual
+// CHECK-SAME: flags: DIFlagIntroducedVirtual,
+// CHECK-SAME: spFlags: DISPFlagVirtual | DISPFlagPrototyped
 
 // CHECK: ![[i]] = !DISubprogram(name: "i",
-// CHECK-SAME: flags: DIFlagPrototyped | DIFlagStaticMember
+// CHECK-SAME: flags: DIFlagStaticMember
+// CHECK-SAME: spFlags: DISPFlagPrototyped
 // CHECK-NEXT: ![[dummy:[0-9]+]] = !DISubroutineType(types: ![[Signature:[0-9]+]])
 // CHECK: ![[Signature]] = !{null, ![[BasicInt:[0-9]+]], ![[BasicInt]]}
 // CHECK: ![[BasicInt]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
Index: clang/test/CodeGenCXX/debug-info-deleted.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-deleted.cpp
+++ clang/test/CodeGenCXX/debug-info-deleted.cpp
@@ -6,12 +6,12 @@
 // RUN:   -debug-info-kind=standalone \
 // RUN: | FileCheck %s -check-prefix=ATTR
 
-// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped,
-// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
-// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSERKS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
-// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
-// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSEOS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
-// ATTR: DISubprogram(name: "~deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped,
+// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagPrototyped
+// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagDeleted | DISPFlagPrototyped
+// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSERKS_", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagDeleted | DISPFlagPrototyped
+// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagDeleted | DISPFlagPrototyped
+// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSEOS_", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagDeleted | DISPFlagPrototyped
+// ATTR: DISubprogram(name: "~deleted", {{.*}}, flags: DIFlagPublic, spFlags: DISPFlagPrototyped
 class deleted {
 public:
   // Defaulted on purpose, so as to facilitate object creation
Index: clang/test/CodeGenCXX/debug-info-decl-nested.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-decl-nested.cpp
+++ clang/test/CodeGenCXX/debug-info-decl-nested.cpp
@@ -17,9 +17,9 @@
   public:
     InnerClass(); // Here createContextChain() generates a limited type for OuterClass.
   } theInnerClass;
-// CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass"
-// CHECK0-SAME: line: [[@LINE+2]]
-// CHECK0-SAME: spFlags: 0
+  // CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass"
+  // CHECK0-SAME: line: [[@LINE+2]]
+  // CHECK0-SAME: spFlags: DISPFlagPrototyped
   OuterClass(const Foo *); // line 10
 };
 OuterClass::InnerClass OuterClass::theInnerClass; // This toplevel decl causes InnerClass to be generated.
@@ -41,9 +41,9 @@
   public:
     InnerClass1();
   } theInnerClass1;
-// CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar"
-// CHECK1-SAME: line: [[@LINE+2]]
-// CHECK1-SAME: spFlags: 0
+  // CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar"
+  // CHECK1-SAME: line: [[@LINE+2]]
+  // CHECK1-SAME: spFlags: DISPFlagPrototyped
   void Bar(const Foo1 *);
 };
 OuterClass1::InnerClass1 OuterClass1::theInnerClass1;
@@ -64,9 +64,9 @@
   public:
     InnerClass2();
   } theInnerClass2;
-// CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2"
-// CHECK2-SAME: line: [[@LINE+2]]
-// CHECK2-SAME: spFlags: 0
+  // CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2"
+  // CHECK2-SAME: line: [[@LINE+2]]
+  // CHECK2-SAME: spFlags: DISPFlagPrototyped
   ~OuterClass2(); // line 10
 };
 OuterClass2::InnerClass2 OuterClass2::theInnerClass2;
Index: clang/test/CodeGenCXX/debug-info-cxx1y.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-cxx1y.cpp
+++ clang/test/CodeGenCXX/debug-info-cxx1y.cpp
@@ -23,7 +23,7 @@
 // CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func",
 // CHECK-SAME:                          scope: [[FOO]]
 // CHECK-SAME:                          type: [[SUBROUTINE_TYPE]]
-// CHECK-SAME:                          spFlags: 0
+// CHECK-SAME:                          spFlags: DISPFlagPrototyped)
 
 struct foo {
   static auto func();
Index: clang/test/CodeGenCXX/debug-info-access.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-access.cpp
+++ clang/test/CodeGenCXX/debug-info-access.cpp
@@ -3,7 +3,7 @@
 struct A {
   // CHECK: ![[A:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A",
 
-  // CHECK-DAG: !DISubprogram(name: "pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped,
+  // CHECK-DAG: !DISubprogram(name: "pub_default",{{.*}} line: [[@LINE+1]],{{.*}} spFlags: DISPFlagPrototyped
   void pub_default();
   // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "pub_default_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagStaticMember)
   static int pub_default_static;
@@ -13,30 +13,28 @@
 // CHECK: !DIDerivedType(tag: DW_TAG_inheritance,{{.*}} baseType: ![[A]],{{.*}} flags: DIFlagPublic, extraData: i32 0)
 class B : public A {
 public:
-  // CHECK-DAG: !DISubprogram(name: "pub",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagPrototyped,
+  // CHECK-DAG: !DISubprogram(name: "pub",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic,{{.*}}spFlags: DISPFlagPrototyped
   void pub();
   // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "public_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagStaticMember)
   static int public_static;
 protected:
-  // CHECK: !DISubprogram(name: "prot",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected | DIFlagPrototyped,
+  // CHECK: !DISubprogram(name: "prot",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected,{{.*}}spFlags: DISPFlagPrototyped
   void prot();
 private:
-  // CHECK: !DISubprogram(name: "priv_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped,
+  // CHECK: !DISubprogram(name: "priv_default",{{.*}} line: [[@LINE+1]],{{.*}} spFlags: DISPFlagPrototyped
   void priv_default();
 };
 
 union U {
-  // CHECK-DAG: !DISubprogram(name: "union_pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped,
+  // CHECK-DAG: !DISubprogram(name: "union_pub_default",{{.*}} line: [[@LINE+1]],{{.*}} spFlags: DISPFlagPrototyped
   void union_pub_default();
 private:
   // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "union_priv",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrivate)
   int union_priv;
 };
 
-
 // CHECK: !DISubprogram(name: "free",
-// CHECK-SAME:          flags: DIFlagPrototyped,
-// CHECK-SAME:          spFlags: DISPFlagDefinition
+// CHECK-SAME:          spFlags: DISPFlagDefinition | DISPFlagPrototyped
 void free() {}
 
 U u;
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
@@ -5,7 +5,7 @@
 // RUN:   -O1 -disable-llvm-passes \
 // RUN:   -debug-info-kind=standalone -dwarf-version=5 \
 // RUN: | FileCheck %s -check-prefix=HAS-ATTR \
-// RUN:     -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed
+// RUN:     -implicit-check-not=DISubprogram -implicit-check-not=DISPFlagAllCallsDescribed
 
 // Supported: DWARF4 + LLDB tuning, -O1, limited DI
 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
@@ -13,7 +13,7 @@
 // RUN:   -debugger-tuning=lldb \
 // RUN:   -debug-info-kind=standalone -dwarf-version=4 \
 // RUN: | FileCheck %s -check-prefix=HAS-ATTR \
-// RUN:     -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed
+// RUN:     -implicit-check-not=DISubprogram -implicit-check-not=DISPFlagAllCallsDescribed
 
 // Supported: DWARF4 + GDB tuning, -O1
 // RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu \
@@ -56,14 +56,14 @@
 
 // NO-ATTR-NOT: FlagAllCallsDescribed
 
-// 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 | 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
+// HAS-ATTR-DAG: DISubprogram(name: "declaration1", {{.*}}, spFlags: DISPFlagOptimized | DISPFlagPrototyped
+// HAS-ATTR-DAG: DISubprogram(name: "declaration2", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed
+// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, spFlags: DISPFlagOptimized | DISPFlagPrototyped)
+// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed
+// HAS-ATTR-DAG: DISubprogram(name: "method1", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed
+// HAS-ATTR-DAG: DISubprogram(name: "force_irgen", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed
 
-// LINE-TABLES-ONLY: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
+// LINE-TABLES-ONLY: DISubprogram(name: "force_irgen", {{.*}}, spFlags: DISPFlagDefinition | DISPFlagOptimized | DISPFlagPrototyped | DISPFlagAllCallsDescribed
 
 void declaration1();
 
Index: clang/lib/CodeGen/CGDebugInfo.h
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -663,10 +663,9 @@
                          unsigned LineNo, StringRef LinkageName,
                          llvm::GlobalVariable *Var, llvm::DIScope *DContext);
 
-
-  /// Return flags which enable debug info emission for call sites, provided
+  /// Return SPFlags which enable debug info emission for call sites, provided
   /// that it is supported and enabled.
-  llvm::DINode::DIFlags getCallSiteRelatedAttrs() const;
+  llvm::DISubprogram::DISPFlags getCallSiteRelatedAttrs() const;
 
   /// Get the printing policy for producing names for debug info.
   PrintingPolicy getPrintingPolicy() const;
@@ -711,7 +710,7 @@
                                 StringRef &Name, StringRef &LinkageName,
                                 llvm::DIScope *&FDContext,
                                 llvm::DINodeArray &TParamsArray,
-                                llvm::DINode::DIFlags &Flags);
+                                llvm::DISubprogram::DISPFlags &SPFlags);
 
   /// Collect various properties of a VarDecl.
   void collectVarDeclProps(const VarDecl *VD, llvm::DIFile *&Unit,
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1639,7 +1639,7 @@
   }
 
   if (Method->isNoReturn())
-    Flags |= llvm::DINode::FlagNoReturn;
+    SPFlags |= llvm::DISubprogram::SPFlagNoReturn;
 
   if (Method->isStatic())
     Flags |= llvm::DINode::FlagStaticMember;
@@ -1648,13 +1648,13 @@
   Flags |= getAccessFlag(Method->getAccess(), Method->getParent());
   if (const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
     if (CXXC->isExplicit())
-      Flags |= llvm::DINode::FlagExplicit;
+      SPFlags |= llvm::DISubprogram::SPFlagExplicit;
   } else if (const auto *CXXC = dyn_cast<CXXConversionDecl>(Method)) {
     if (CXXC->isExplicit())
-      Flags |= llvm::DINode::FlagExplicit;
+      SPFlags |= llvm::DISubprogram::SPFlagExplicit;
   }
   if (Method->hasPrototype())
-    Flags |= llvm::DINode::FlagPrototyped;
+    SPFlags |= llvm::DISubprogram::SPFlagPrototyped;
   if (Method->getRefQualifier() == RQ_LValue)
     Flags |= llvm::DINode::FlagLValueReference;
   if (Method->getRefQualifier() == RQ_RValue)
@@ -3280,18 +3280,16 @@
   return Ty;
 }
 
-void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
-                                           StringRef &Name,
-                                           StringRef &LinkageName,
-                                           llvm::DIScope *&FDContext,
-                                           llvm::DINodeArray &TParamsArray,
-                                           llvm::DINode::DIFlags &Flags) {
+void CGDebugInfo::collectFunctionDeclProps(
+    GlobalDecl GD, llvm::DIFile *Unit, StringRef &Name, StringRef &LinkageName,
+    llvm::DIScope *&FDContext, llvm::DINodeArray &TParamsArray,
+    llvm::DISubprogram::DISPFlags &SPFlags) {
   const auto *FD = cast<FunctionDecl>(GD.getDecl());
   Name = getFunctionName(FD);
   // Use mangled name as linkage name for C/C++ functions.
   if (FD->hasPrototype()) {
     LinkageName = CGM.getMangledName(GD);
-    Flags |= llvm::DINode::FlagPrototyped;
+    SPFlags |= llvm::DISubprogram::SPFlagPrototyped;
   }
   // No need to replicate the linkage name if it isn't different from the
   // subprogram name, no need to have it at all unless coverage is enabled or
@@ -3313,7 +3311,7 @@
     }
     // Check if it is a noreturn-marked function
     if (FD->isNoReturn())
-      Flags |= llvm::DINode::FlagNoReturn;
+      SPFlags |= llvm::DISubprogram::SPFlagNoReturn;
     // Collect template parameters.
     TParamsArray = CollectFunctionTemplateParams(FD, Unit);
   }
@@ -3385,7 +3383,7 @@
   llvm::DIScope *DContext = Unit;
   unsigned Line = getLineNumber(Loc);
   collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext, TParamsArray,
-                           Flags);
+                           SPFlags);
   auto *FD = cast<FunctionDecl>(GD.getDecl());
 
   // Build function type.
@@ -3402,7 +3400,7 @@
     SPFlags |= llvm::DISubprogram::SPFlagOptimized;
 
   if (Stub) {
-    Flags |= getCallSiteRelatedAttrs();
+    SPFlags |= getCallSiteRelatedAttrs();
     SPFlags |= llvm::DISubprogram::SPFlagDefinition;
     return DBuilder.createFunction(
         DContext, Name, LinkageName, Unit, Line,
@@ -3655,10 +3653,10 @@
       }
     }
     collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
-                             TParamsArray, Flags);
+                             TParamsArray, SPFlags);
   } else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
     Name = getObjCMethodName(OMD);
-    Flags |= llvm::DINode::FlagPrototyped;
+    SPFlags |= llvm::DISubprogram::SPFlagPrototyped;
   } else if (isa<VarDecl>(D) &&
              GD.getDynamicInitKind() != DynamicInitKind::NoStub) {
     // This is a global initializer or atexit destructor for a global variable.
@@ -3670,7 +3668,7 @@
     if (isa<BlockDecl>(D))
       LinkageName = Name;
 
-    Flags |= llvm::DINode::FlagPrototyped;
+    SPFlags |= llvm::DISubprogram::SPFlagPrototyped;
   }
   if (Name.startswith("\01"))
     Name = Name.substr(1);
@@ -3682,16 +3680,17 @@
   }
 
   if (CurFuncIsThunk)
-    Flags |= llvm::DINode::FlagThunk;
+    SPFlags |= llvm::DISubprogram::SPFlagThunk;
 
   if (Fn->hasLocalLinkage())
     SPFlags |= llvm::DISubprogram::SPFlagLocalToUnit;
   if (CGM.getLangOpts().Optimize)
     SPFlags |= llvm::DISubprogram::SPFlagOptimized;
 
-  llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
+  llvm::DINode::DIFlags FlagsForDef = Flags;
   llvm::DISubprogram::DISPFlags SPFlagsForDef =
-      SPFlags | llvm::DISubprogram::SPFlagDefinition;
+      SPFlags | llvm::DISubprogram::SPFlagDefinition |
+      getCallSiteRelatedAttrs();
 
   unsigned LineNo = getLineNumber(Loc);
   unsigned ScopeLine = getLineNumber(ScopeLoc);
@@ -3748,13 +3747,14 @@
   llvm::DIScope *FDContext =
       IsDeclForCallSite ? Unit : getDeclContextDescriptor(D);
   llvm::DINodeArray TParamsArray;
+  llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
   if (isa<FunctionDecl>(D)) {
     // If there is a DISubprogram for this function available then use it.
     collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
-                             TParamsArray, Flags);
+                             TParamsArray, SPFlags);
   } else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
     Name = getObjCMethodName(OMD);
-    Flags |= llvm::DINode::FlagPrototyped;
+    SPFlags |= llvm::DISubprogram::SPFlagPrototyped;
   } else {
     llvm_unreachable("not a function or ObjC method");
   }
@@ -3769,7 +3769,6 @@
   }
   unsigned LineNo = getLineNumber(Loc);
   unsigned ScopeLine = 0;
-  llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::SPFlagZero;
   if (CGM.getLangOpts().Optimize)
     SPFlags |= llvm::DISubprogram::SPFlagOptimized;
 
@@ -3801,7 +3800,7 @@
   // compiler may emit calls to these functions without debug locations, which
   // makes the verifier complain).
   if (CalleeDecl->getBuiltinID() != 0 ||
-      getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
+      getCallSiteRelatedAttrs() == llvm::DISubprogram::SPFlagZero)
     return;
   if (const auto *Id = CalleeDecl->getIdentifier())
     if (Id->isReservedName())
@@ -4846,12 +4845,12 @@
   return llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc), Scope);
 }
 
-llvm::DINode::DIFlags CGDebugInfo::getCallSiteRelatedAttrs() const {
+llvm::DISubprogram::DISPFlags CGDebugInfo::getCallSiteRelatedAttrs() const {
   // Call site-related attributes are only useful in optimized programs, and
   // when there's a possibility of debugging backtraces.
   if (!CGM.getLangOpts().Optimize || DebugKind == codegenoptions::NoDebugInfo ||
       DebugKind == codegenoptions::LocTrackingOnly)
-    return llvm::DINode::FlagZero;
+    return llvm::DISubprogram::SPFlagZero;
 
   // Call site-related attributes are available in DWARF v5. Some debuggers,
   // while not fully DWARF v5-compliant, may accept these attributes as if they
@@ -4862,7 +4861,7 @@
        CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::GDB);
 
   if (!SupportsDWARFv4Ext && CGM.getCodeGenOpts().DwarfVersion < 5)
-    return llvm::DINode::FlagZero;
+    return llvm::DISubprogram::SPFlagZero;
 
-  return llvm::DINode::FlagAllCallsDescribed;
+  return llvm::DISubprogram::SPFlagAllCallsDescribed;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D74470: Seperated DI... Chirag Patel via Phabricator via cfe-commits

Reply via email to