1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
// parse-diagnostic-util.h
#ifndef PARSE_DIAGNOSTIC_UTIL_H
#define PARSE_DIAGNOSTIC_UTIL_H
#include "../../source/core/slang-string-util.h"
#include "../../source/core/slang-string.h"
#include "../../source/compiler-core/slang-downstream-compiler.h"
#include "../../slang-com-ptr.h"
struct ParseDiagnosticUtil
{
struct OutputInfo
{
int resultCode;
Slang::String stdError;
Slang::String stdOut;
};
/// We need a way to identify downstream compilers and others - specifically here Slang.
/// Ideally we'd have an enum that included Slang.
/// Just adding to SlangPassThrough doesn't seem right. If we had an enumeration with a
/// more appropriate name, then including downstream and slang compilers wouldn't be a problem.
/// So for now this is punted, and this type is used to represent possible compiler identities.
struct CompilerIdentity
{
typedef CompilerIdentity ThisType;
enum Type
{
Unknown,
Slang,
DownstreamCompiler,
};
static CompilerIdentity make(Type type, SlangPassThrough downstreamCompiler) { CompilerIdentity ident; ident.m_type = type; ident.m_downstreamCompiler = downstreamCompiler; return ident; }
static CompilerIdentity make(SlangPassThrough downstreamCompiler) { return make(Type::DownstreamCompiler, downstreamCompiler); }
static CompilerIdentity makeSlang() { return make(Type::Slang, SLANG_PASS_THROUGH_NONE); }
bool operator==(const ThisType& rhs) const { return m_type == rhs.m_type && m_downstreamCompiler == rhs.m_downstreamCompiler; }
bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
Type m_type = Type::Unknown;
SlangPassThrough m_downstreamCompiler = SLANG_PASS_THROUGH_NONE;
};
typedef uint32_t EqualityFlags;
struct EqualityFlag
{
enum Enum : EqualityFlags
{
IgnoreLineNos = 0x1,
};
};
typedef SlangResult (*LineParser)(const Slang::UnownedStringSlice& line, Slang::List<Slang::UnownedStringSlice>& lineSlices, Slang::DownstreamDiagnostic& outDiagnostic);
/// Given a compiler identity returns a line parsing function.
static LineParser getLineParser(const CompilerIdentity& compilerIdentity);
/// For a 'generic' (as in uses DownstreamCompiler mechanism) line parsing
static SlangResult parseGenericLine(const Slang::UnownedStringSlice& line, Slang::List<Slang::UnownedStringSlice>& lineSlices, Slang::DownstreamDiagnostic& outDiagnostic);
/// For parsing diagnostics from Slang
static SlangResult parseSlangLine(const Slang::UnownedStringSlice& line, Slang::List<Slang::UnownedStringSlice>& lineSlices, Slang::DownstreamDiagnostic& outDiagnostic);
/// Parse diagnostics into output text
static SlangResult parseDiagnostics(const Slang::UnownedStringSlice& inText, Slang::List<Slang::DownstreamDiagnostic>& outDiagnostics);
/// Parse diagnostics with known compiler identity.
/// If the prefix is empty, it is assumed there is no prefix and it won't be checked.
static SlangResult parseDiagnostics(const Slang::UnownedStringSlice& inText, const CompilerIdentity& identity, const Slang::UnownedStringSlice& prefix, Slang::List<Slang::DownstreamDiagnostic>& outDiagnostics);
/// Given the file output style used by tests, get components of the output into Diagnostic
static SlangResult parseOutputInfo(const Slang::UnownedStringSlice& in, OutputInfo& out);
/// Given a line split it into slices - taking into account compiler output, path considerations, and potentially line prefixing
static SlangResult splitDiagnosticLine(const CompilerIdentity& compilerIdentity, const Slang::UnownedStringSlice& line, const Slang::UnownedStringSlice& linePrefix, Slang::List<Slang::UnownedStringSlice>& outSlices);
/// Give text of diagnostic determine which compiler the output is from
static SlangResult identifyCompiler(const Slang::UnownedStringSlice& in, CompilerIdentity& outIdentity);
/// Determines if the diagnostics in a and b (they are parsed via parseDiagnostics) are equal, taking into account flags
/// Note! If the parse of either a or b fails, then equality is returns as false.
static bool areEqual(const Slang::UnownedStringSlice& a, const Slang::UnownedStringSlice& b, EqualityFlags flags);
};
#endif // PARSE_DIAGNOSTIC_UTIL_H
|