1 //===- DebugSubsectionVisitor.cpp ---------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
11 
12 #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
13 #include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
14 #include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
15 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
16 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
17 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
18 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
19 #include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
20 #include "llvm/Support/BinaryStreamReader.h"
21 #include "llvm/Support/BinaryStreamRef.h"
22 
23 using namespace llvm;
24 using namespace llvm::codeview;
25 
26 DebugSubsectionState::DebugSubsectionState() {}
27 
28 DebugSubsectionState::DebugSubsectionState(
29     const DebugStringTableSubsectionRef &Strings)
30     : Strings(&Strings) {}
31 
32 DebugSubsectionState::DebugSubsectionState(
33     const DebugStringTableSubsectionRef &Strings,
34     const DebugChecksumsSubsectionRef &Checksums)
35     : Strings(&Strings), Checksums(&Checksums) {}
36 
37 void DebugSubsectionState::initializeStrings(const DebugSubsectionRecord &SR) {
38   assert(SR.kind() == DebugSubsectionKind::StringTable);
39   assert(!Strings && "Found a string table even though we already have one!");
40 
41   OwnedStrings = llvm::make_unique<DebugStringTableSubsectionRef>();
42   consumeError(OwnedStrings->initialize(SR.getRecordData()));
43   Strings = OwnedStrings.get();
44 }
45 
46 void DebugSubsectionState::initializeChecksums(
47     const DebugSubsectionRecord &FCR) {
48   assert(FCR.kind() == DebugSubsectionKind::FileChecksums);
49   if (Checksums)
50     return;
51 
52   OwnedChecksums = llvm::make_unique<DebugChecksumsSubsectionRef>();
53   consumeError(OwnedChecksums->initialize(FCR.getRecordData()));
54   Checksums = OwnedChecksums.get();
55 }
56 
57 Error llvm::codeview::visitDebugSubsection(const DebugSubsectionRecord &R,
58                                            DebugSubsectionVisitor &V,
59                                            const DebugSubsectionState &State) {
60   BinaryStreamReader Reader(R.getRecordData());
61   switch (R.kind()) {
62   case DebugSubsectionKind::Lines: {
63     DebugLinesSubsectionRef Fragment;
64     if (auto EC = Fragment.initialize(Reader))
65       return EC;
66 
67     return V.visitLines(Fragment, State);
68   }
69   case DebugSubsectionKind::FileChecksums: {
70     DebugChecksumsSubsectionRef Fragment;
71     if (auto EC = Fragment.initialize(Reader))
72       return EC;
73 
74     return V.visitFileChecksums(Fragment, State);
75   }
76   case DebugSubsectionKind::InlineeLines: {
77     DebugInlineeLinesSubsectionRef Fragment;
78     if (auto EC = Fragment.initialize(Reader))
79       return EC;
80     return V.visitInlineeLines(Fragment, State);
81   }
82   case DebugSubsectionKind::CrossScopeExports: {
83     DebugCrossModuleExportsSubsectionRef Section;
84     if (auto EC = Section.initialize(Reader))
85       return EC;
86     return V.visitCrossModuleExports(Section, State);
87   }
88   case DebugSubsectionKind::CrossScopeImports: {
89     DebugCrossModuleImportsSubsectionRef Section;
90     if (auto EC = Section.initialize(Reader))
91       return EC;
92     return V.visitCrossModuleImports(Section, State);
93   }
94   default: {
95     DebugUnknownSubsectionRef Fragment(R.kind(), R.getRecordData());
96     return V.visitUnknown(Fragment);
97   }
98   }
99 }
100