[CodeView] Minimal support for S_UNAMESPACE records

Differential Revision: https://reviews.llvm.org/D50007

llvm-svn: 338417
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def b/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
index 41c5380..b5f1cc0 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
+++ b/llvm/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
@@ -143,7 +143,6 @@
 CV_SYMBOL(S_MANMANYREG    , 0x1121)
 CV_SYMBOL(S_MANREGREL     , 0x1122)
 CV_SYMBOL(S_MANMANYREG2   , 0x1123)
-CV_SYMBOL(S_UNAMESPACE    , 0x1124)
 CV_SYMBOL(S_DATAREF       , 0x1126)
 CV_SYMBOL(S_ANNOTATIONREF , 0x1128)
 CV_SYMBOL(S_TOKENREF      , 0x1129)
@@ -255,6 +254,7 @@
 SYMBOL_RECORD(S_LTHREAD32     , 0x1112, ThreadLocalDataSym)
 SYMBOL_RECORD_ALIAS(S_GTHREAD32     , 0x1113, GlobalTLS, ThreadLocalDataSym)
 
+SYMBOL_RECORD(S_UNAMESPACE    , 0x1124, UsingNamespaceSym)
 
 #undef CV_SYMBOL
 #undef SYMBOL_RECORD
diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index cf267f2..9330682 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -942,6 +942,19 @@
   uint32_t RecordOffset;
 };
 
+// S_UNAMESPACE
+class UsingNamespaceSym : public SymbolRecord {
+public:
+  explicit UsingNamespaceSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+  explicit UsingNamespaceSym(uint32_t RecordOffset)
+      : SymbolRecord(SymbolRecordKind::RegRelativeSym),
+        RecordOffset(RecordOffset) {}
+
+  StringRef Name;
+
+  uint32_t RecordOffset;
+};
+
 // S_ANNOTATION
 
 using CVSymbol = CVRecord<SymbolKind>;
diff --git a/llvm/lib/DebugInfo/CodeView/RecordName.cpp b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
index e50c43a..d868ae2 100644
--- a/llvm/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/llvm/lib/DebugInfo/CodeView/RecordName.cpp
@@ -307,6 +307,9 @@
   // See BPRelativeSym
   case SymbolKind::S_BPREL32:
     return 8;
+  // See UsingNamespaceSym
+  case SymbolKind::S_UNAMESPACE:
+    return 0;
   default:
     return -1;
   }
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index af249ad..f8bf961 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -611,6 +611,12 @@
   return Error::success();
 }
 
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+                                           UsingNamespaceSym &UN) {
+  W.printString("Namespace", UN.Name);
+  return Error::success();
+}
+
 Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
   W.printNumber("Length", CVR.length());
   return Error::success();
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
index 923837a..e77c8e8 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
@@ -463,3 +463,11 @@
 
   return Error::success();
 }
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+                                            UsingNamespaceSym &UN) {
+
+  error(IO.mapStringZ(UN.Name));
+
+  return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp b/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
index 95082d4..839ab6f 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
@@ -428,7 +428,7 @@
   case SymbolKind::S_DEFRANGE_SUBFIELD:
     break;
 
-  // No type refernces.
+  // No type references.
   case SymbolKind::S_LABEL32:
   case SymbolKind::S_OBJNAME:
   case SymbolKind::S_COMPILE:
@@ -439,6 +439,7 @@
   case SymbolKind::S_FRAMEPROC:
   case SymbolKind::S_THUNK32:
   case SymbolKind::S_FRAMECOOKIE:
+  case SymbolKind::S_UNAMESPACE:
     break;
   // Scope ending symbols.
   case SymbolKind::S_END:
diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
index f67a0db..745f79cd 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -550,6 +550,10 @@
   IO.mapRequired("DisplayName", Symbol.Name);
 }
 
+template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
+  IO.mapRequired("Namespace", Symbol.Name);
+}
+
 } // end namespace detail
 } // end namespace CodeViewYAML
 } // end namespace llvm
diff --git a/llvm/test/DebugInfo/PDB/using-namespace.test b/llvm/test/DebugInfo/PDB/using-namespace.test
new file mode 100644
index 0000000..77c3782
--- /dev/null
+++ b/llvm/test/DebugInfo/PDB/using-namespace.test
@@ -0,0 +1,51 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: llvm-readobj -codeview %t.obj | FileCheck %s
+
+# CHECK:         Kind: S_UNAMESPACE (0x1124)
+# CHECK-NEXT:    Namespace: __vc_attributes
+
+--- !COFF
+header:          
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:        
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Subsections:     
+      - !Symbols
+        Records:         
+          - Kind:            S_OBJNAME
+            ObjNameSym:      
+              Signature:       0
+              ObjectName:      'SimpleFunction.obj'
+          - Kind:            S_COMPILE3
+            Compile3Sym:     
+              Flags:           [ SecurityChecks, HotPatch ]
+              Machine:         X64
+              FrontendMajor:   19
+              FrontendMinor:   14
+              FrontendBuild:   26433
+              FrontendQFE:     0
+              BackendMajor:    19
+              BackendMinor:    14
+              BackendBuild:    26433
+              BackendQFE:      0
+              Version:         'Microsoft (R) Optimizing Compiler'
+          - Kind:            S_UNAMESPACE
+            UsingNamespaceSym: 
+              Namespace:       __vc_attributes
+          - Kind:            S_UNAMESPACE
+            UsingNamespaceSym: 
+              Namespace:       helper_attributes
+          - Kind:            S_UNAMESPACE
+            UsingNamespaceSym: 
+              Namespace:       atl
+          - Kind:            S_UNAMESPACE
+            UsingNamespaceSym: 
+              Namespace:       std
+      - !StringTable
+        Strings:
+          - 'SimpleFunction.c'
+symbols:         
+...
diff --git a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
index b454ab3..f4e38a3 100644
--- a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
@@ -760,3 +760,9 @@
   P.formatLine("original type = {0}", UDT.Type);
   return Error::success();
 }
+
+Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
+                                            UsingNamespaceSym &UN) {
+  P.format(" `{0}`", UN.Name);
+  return Error::success();
+}
diff --git a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
index 60ca56b..7ee5604 100644
--- a/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
+++ b/llvm/unittests/DebugInfo/CodeView/TypeIndexDiscoveryTest.cpp
@@ -600,4 +600,11 @@
   BaseClassRecord BaseClass2(MemberAccess::Public, TypeIndex(48), 1);
   writeFieldList(BaseClass1, BaseClass2);
   checkTypeReferences(0, TypeIndex(47), TypeIndex(48));
-}
\ No newline at end of file
+}
+
+TEST_F(TypeIndexIteratorTest, UsingNamespace) {
+  UsingNamespaceSym UN(SymbolRecordKind::UsingNamespaceSym);
+  UN.Name = "std";
+  writeSymbolRecords(UN);
+  checkTypeReferences(0);
+}