summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/core/slang-string.cpp166
-rw-r--r--source/core/slang-string.h972
-rw-r--r--source/core/slang-token-reader.h4
-rw-r--r--source/slang/slang-ast-base.h9
-rw-r--r--source/slang/slang-ast-builder.cpp2
-rw-r--r--source/slang/slang-ast-modifier.h7
-rw-r--r--source/slang/slang-ast-support-types.h6
-rw-r--r--source/slang/slang-check-decl.cpp5
-rw-r--r--source/slang/slang-check-modifier.cpp10
-rw-r--r--source/slang/slang-check.h2
-rwxr-xr-xsource/slang/slang-compiler.cpp4
-rwxr-xr-xsource/slang/slang-compiler.h8
-rw-r--r--source/slang/slang-parser.cpp10
-rw-r--r--source/slang/slang-reflection.cpp4
-rw-r--r--source/slang/slang-serialize-ast-type-info.h8
-rw-r--r--source/slang/slang-serialize-container.cpp150
-rw-r--r--source/slang/slang-serialize-container.h14
-rw-r--r--source/slang/slang-serialize-factory.cpp3
-rw-r--r--source/slang/slang-serialize-ir.cpp2
-rw-r--r--source/slang/slang-serialize-type-info.h96
-rw-r--r--source/slang/slang-serialize-types.h2
-rw-r--r--source/slang/slang-serialize.cpp69
-rw-r--r--source/slang/slang-serialize.h26
-rw-r--r--source/slang/slang-syntax.cpp22
-rw-r--r--source/slang/slang.cpp140
25 files changed, 1060 insertions, 681 deletions
diff --git a/source/core/slang-string.cpp b/source/core/slang-string.cpp
index 3ce4c7ec9..975c83315 100644
--- a/source/core/slang-string.cpp
+++ b/source/core/slang-string.cpp
@@ -147,112 +147,112 @@ namespace Slang
//
- _EndLine EndLine;
+ _EndLine EndLine;
String operator+(const char * op1, const String & op2)
- {
+ {
String result(op1);
result.append(op2);
return result;
- }
+ }
- String operator+(const String & op1, const char * op2)
- {
+ String operator+(const String & op1, const char * op2)
+ {
String result(op1);
result.append(op2);
return result;
- }
+ }
- String operator+(const String & op1, const String & op2)
- {
+ String operator+(const String & op1, const String & op2)
+ {
String result(op1);
result.append(op2);
return result;
- }
-
- int StringToInt(const String & str, int radix)
- {
- if (str.startsWith("0x"))
- return (int)strtoll(str.getBuffer(), NULL, 16);
- else
- return (int)strtoll(str.getBuffer(), NULL, radix);
- }
- unsigned int StringToUInt(const String & str, int radix)
- {
- if (str.startsWith("0x"))
- return (unsigned int)strtoull(str.getBuffer(), NULL, 16);
- else
- return (unsigned int)strtoull(str.getBuffer(), NULL, radix);
- }
- double StringToDouble(const String & str)
- {
- return (double)strtod(str.getBuffer(), NULL);
- }
- float StringToFloat(const String & str)
- {
- return strtof(str.getBuffer(), NULL);
- }
+ }
+
+ int StringToInt(const String & str, int radix)
+ {
+ if (str.startsWith("0x"))
+ return (int)strtoll(str.getBuffer(), NULL, 16);
+ else
+ return (int)strtoll(str.getBuffer(), NULL, radix);
+ }
+ unsigned int StringToUInt(const String & str, int radix)
+ {
+ if (str.startsWith("0x"))
+ return (unsigned int)strtoull(str.getBuffer(), NULL, 16);
+ else
+ return (unsigned int)strtoull(str.getBuffer(), NULL, radix);
+ }
+ double StringToDouble(const String & str)
+ {
+ return (double)strtod(str.getBuffer(), NULL);
+ }
+ float StringToFloat(const String & str)
+ {
+ return strtof(str.getBuffer(), NULL);
+ }
#if 0
- String String::ReplaceAll(String src, String dst) const
- {
- String rs = *this;
- int index = 0;
- int srcLen = src.length;
- int len = rs.length;
- while ((index = rs.IndexOf(src, index)) != -1)
- {
- rs = rs.SubString(0, index) + dst + rs.SubString(index + srcLen, len - index - srcLen);
- len = rs.length;
- }
- return rs;
- }
+ String String::ReplaceAll(String src, String dst) const
+ {
+ String rs = *this;
+ int index = 0;
+ int srcLen = src.length;
+ int len = rs.length;
+ while ((index = rs.IndexOf(src, index)) != -1)
+ {
+ rs = rs.SubString(0, index) + dst + rs.SubString(index + srcLen, len - index - srcLen);
+ len = rs.length;
+ }
+ return rs;
+ }
#endif
- String String::fromWString(const wchar_t * wstr)
- {
+ String String::fromWString(const wchar_t * wstr)
+ {
#ifdef _WIN32
- return Slang::Encoding::UTF16->ToString((const char*)wstr, (int)(wcslen(wstr) * sizeof(wchar_t)));
+ return Slang::Encoding::UTF16->ToString((const char*)wstr, (int)(wcslen(wstr) * sizeof(wchar_t)));
#else
- return Slang::Encoding::UTF32->ToString((const char*)wstr, (int)(wcslen(wstr) * sizeof(wchar_t)));
+ return Slang::Encoding::UTF32->ToString((const char*)wstr, (int)(wcslen(wstr) * sizeof(wchar_t)));
#endif
- }
+ }
- String String::fromWString(const wchar_t * wstr, const wchar_t * wend)
- {
+ String String::fromWString(const wchar_t * wstr, const wchar_t * wend)
+ {
#ifdef _WIN32
- return Slang::Encoding::UTF16->ToString((const char*)wstr, (int)((wend - wstr) * sizeof(wchar_t)));
+ return Slang::Encoding::UTF16->ToString((const char*)wstr, (int)((wend - wstr) * sizeof(wchar_t)));
#else
- return Slang::Encoding::UTF32->ToString((const char*)wstr, (int)((wend - wstr) * sizeof(wchar_t)));
+ return Slang::Encoding::UTF32->ToString((const char*)wstr, (int)((wend - wstr) * sizeof(wchar_t)));
#endif
- }
+ }
- String String::fromWChar(const wchar_t ch)
- {
+ String String::fromWChar(const wchar_t ch)
+ {
#ifdef _WIN32
- return Slang::Encoding::UTF16->ToString((const char*)&ch, (int)(sizeof(wchar_t)));
+ return Slang::Encoding::UTF16->ToString((const char*)&ch, (int)(sizeof(wchar_t)));
#else
- return Slang::Encoding::UTF32->ToString((const char*)&ch, (int)(sizeof(wchar_t)));
+ return Slang::Encoding::UTF32->ToString((const char*)&ch, (int)(sizeof(wchar_t)));
#endif
- }
-
- String String::fromUnicodePoint(unsigned int codePoint)
- {
- char buf[6];
- int len = Slang::EncodeUnicodePointToUTF8(buf, (int)codePoint);
- buf[len] = 0;
- return String(buf);
- }
-
- OSString String::toWString(Index* outLength) const
- {
- if (!m_buffer)
- {
+ }
+
+ String String::fromUnicodePoint(unsigned int codePoint)
+ {
+ char buf[6];
+ int len = Slang::EncodeUnicodePointToUTF8(buf, (int)codePoint);
+ buf[len] = 0;
+ return String(buf);
+ }
+
+ OSString String::toWString(Index* outLength) const
+ {
+ if (!m_buffer)
+ {
return OSString();
- }
- else
- {
- List<char> buf;
+ }
+ else
+ {
+ List<char> buf;
switch(sizeof(wchar_t))
{
case 2:
@@ -268,20 +268,20 @@ namespace Slang
}
auto length = Index(buf.getCount() / sizeof(wchar_t));
- if (outLength)
- *outLength = length;
+ if (outLength)
+ *outLength = length;
for(int ii = 0; ii < sizeof(wchar_t); ++ii)
- buf.add(0);
+ buf.add(0);
wchar_t* beginData = (wchar_t*)buf.getBuffer();
wchar_t* endData = beginData + length;
- buf.detachBuffer();
+ buf.detachBuffer();
return OSString(beginData, endData);
- }
- }
+ }
+ }
//
diff --git a/source/core/slang-string.h b/source/core/slang-string.h
index 75c282a58..9f6eaafa7 100644
--- a/source/core/slang-string.h
+++ b/source/core/slang-string.h
@@ -14,53 +14,53 @@
namespace Slang
{
- class _EndLine
- {};
- extern _EndLine EndLine;
-
- // in-place reversion, works only for ascii string
- inline void ReverseInternalAscii(char * buffer, int length)
- {
- int i, j;
- char c;
- for (i = 0, j = length - 1; i<j; i++, j--)
- {
- c = buffer[i];
- buffer[i] = buffer[j];
- buffer[j] = c;
- }
- }
- template<typename IntType>
- inline int IntToAscii(char * buffer, IntType val, int radix)
- {
- int i = 0;
- IntType sign;
- sign = val;
- if (sign < 0)
- val = (IntType)(0 - val);
- do
- {
- int digit = (val % radix);
- if (digit <= 9)
- buffer[i++] = (char)(digit + '0');
- else
- buffer[i++] = (char)(digit - 10 + 'A');
- } while ((val /= radix) > 0);
- if (sign < 0)
- buffer[i++] = '-';
- buffer[i] = '\0';
- return i;
- }
-
- inline bool IsUtf8LeadingByte(char ch)
- {
- return (((unsigned char)ch) & 0xC0) == 0xC0;
- }
-
- inline bool IsUtf8ContinuationByte(char ch)
- {
- return (((unsigned char)ch) & 0xC0) == 0x80;
- }
+ class _EndLine
+ {};
+ extern _EndLine EndLine;
+
+ // in-place reversion, works only for ascii string
+ inline void ReverseInternalAscii(char * buffer, int length)
+ {
+ int i, j;
+ char c;
+ for (i = 0, j = length - 1; i<j; i++, j--)
+ {
+ c = buffer[i];
+ buffer[i] = buffer[j];
+ buffer[j] = c;
+ }
+ }
+ template<typename IntType>
+ inline int IntToAscii(char * buffer, IntType val, int radix)
+ {
+ int i = 0;
+ IntType sign;
+ sign = val;
+ if (sign < 0)
+ val = (IntType)(0 - val);
+ do
+ {
+ int digit = (val % radix);
+ if (digit <= 9)
+ buffer[i++] = (char)(digit + '0');
+ else
+ buffer[i++] = (char)(digit - 10 + 'A');
+ } while ((val /= radix) > 0);
+ if (sign < 0)
+ buffer[i++] = '-';
+ buffer[i] = '\0';
+ return i;
+ }
+
+ inline bool IsUtf8LeadingByte(char ch)
+ {
+ return (((unsigned char)ch) & 0xC0) == 0xC0;
+ }
+
+ inline bool IsUtf8ContinuationByte(char ch)
+ {
+ return (((unsigned char)ch) & 0xC0) == 0x80;
+ }
struct UnownedStringSlice
{
@@ -166,14 +166,18 @@ namespace Slang
return (*this) != UnownedStringSlice(str, str + ::strlen(str));
}
+ /// True if contents is a single char of c
+ SLANG_FORCE_INLINE bool isChar(char c) const { return getLength() == 1 && m_begin[0] == c; }
+
bool startsWith(UnownedStringSlice const& other) const;
bool startsWith(char const* str) const;
bool endsWith(UnownedStringSlice const& other) const;
bool endsWith(char const* str) const;
-
+ /// Trims any horizontal whitespace from the start and end and returns as a substring
UnownedStringSlice trim() const;
+ /// Trims any 'c' from the start or the end, and returns as a substring
UnownedStringSlice trim(char c) const;
HashCode getHashCode() const
@@ -383,15 +387,15 @@ namespace Slang
wchar_t* m_end; ///< Points to terminating 0
};
- /*!
- @brief Represents a UTF-8 encoded string.
- */
+ /*!
+ @brief Represents a UTF-8 encoded string.
+ */
- class String
- {
+ class String
+ {
friend struct StringSlice;
- friend class StringBuilder;
- private:
+ friend class StringBuilder;
+ private:
char* getData() const
@@ -410,13 +414,13 @@ namespace Slang
: m_buffer(buffer)
{}
- static String fromWString(const wchar_t * wstr);
- static String fromWString(const wchar_t * wstr, const wchar_t * wend);
- static String fromWChar(const wchar_t ch);
- static String fromUnicodePoint(unsigned int codePoint);
- String()
- {
- }
+ static String fromWString(const wchar_t * wstr);
+ static String fromWString(const wchar_t * wstr, const wchar_t * wend);
+ static String fromWChar(const wchar_t ch);
+ static String fromUnicodePoint(unsigned int codePoint);
+ String()
+ {
+ }
/// Returns a buffer which can hold at least count chars
char* prepareForAppend(Index count);
@@ -425,14 +429,14 @@ namespace Slang
SLANG_FORCE_INLINE StringRepresentation* getStringRepresentation() const { return m_buffer; }
- const char * begin() const
- {
- return getData();
- }
- const char * end() const
- {
- return getData() + getLength();
- }
+ const char * begin() const
+ {
+ return getData();
+ }
+ const char * end() const
+ {
+ return getData() + getLength();
+ }
void append(int32_t value, int radix = 10);
void append(uint32_t value, int radix = 10);
@@ -451,76 +455,79 @@ namespace Slang
/// Append a character (to remove ambiguity with other integral types)
void appendChar(char chr);
- String(int32_t val, int radix = 10)
- {
- append(val, radix);
- }
- String(uint32_t val, int radix = 10)
- {
- append(val, radix);
- }
- String(int64_t val, int radix = 10)
- {
- append(val, radix);
- }
- String(uint64_t val, int radix = 10)
- {
- append(val, radix);
- }
- String(float val, const char * format = "%g")
- {
- append(val, format);
- }
- String(double val, const char * format = "%g")
- {
- append(val, format);
- }
- String(const char * str)
- {
+ String(const char* str)
+ {
append(str);
#if 0
- if (str)
- {
+ if (str)
+ {
buffer = StringRepresentation::createWithLength(strlen(str));
- memcpy(buffer.Ptr(), str, getLength() + 1);
- }
+ memcpy(buffer.Ptr(), str, getLength() + 1);
+ }
#endif
- }
+ }
String(const char* textBegin, char const* textEnd)
- {
+ {
append(textBegin, textEnd);
#if 0
- if (textBegin != textEnd)
- {
+ if (textBegin != textEnd)
+ {
buffer = StringRepresentation::createWithLength(textEnd - textBegin);
- memcpy(buffer.Ptr(), textBegin, getLength());
+ memcpy(buffer.Ptr(), textBegin, getLength());
buffer->getData()[getLength()] = 0;
- }
+ }
#endif
- }
- String(char chr)
- {
+ }
+
+ // Make all String ctors from a numeric explicit, to avoid unexpected/unnecessary conversions
+ explicit String(int32_t val, int radix = 10)
+ {
+ append(val, radix);
+ }
+ explicit String(uint32_t val, int radix = 10)
+ {
+ append(val, radix);
+ }
+ explicit String(int64_t val, int radix = 10)
+ {
+ append(val, radix);
+ }
+ explicit String(uint64_t val, int radix = 10)
+ {
+ append(val, radix);
+ }
+ explicit String(float val, const char * format = "%g")
+ {
+ append(val, format);
+ }
+ explicit String(double val, const char * format = "%g")
+ {
+ append(val, format);
+ }
+
+ explicit String(char chr)
+ {
append(chr);
#if 0
- if (chr)
- {
+ if (chr)
+ {
buffer = StringRepresentation::createWithLength(1);
buffer->getData()[0] = chr;
buffer->getData()[1] = 0;
- }
+ }
#endif
- }
- String(String const& str)
- {
+ }
+ String(String const& str)
+ {
m_buffer = str.m_buffer;
#if 0
- this->operator=(str);
+ this->operator=(str);
#endif
- }
- String(String&& other)
- {
+ }
+ String(String&& other)
+ {
m_buffer = _Move(other.m_buffer);
- }
+ }
String(StringSlice const& slice)
{
@@ -532,152 +539,155 @@ namespace Slang
append(slice);
}
- ~String()
- {
+ ~String()
+ {
m_buffer.setNull();
- }
+ }
- String & operator=(const String & str)
- {
+ String & operator=(const String & str)
+ {
m_buffer = str.m_buffer;
- return *this;
- }
- String & operator=(String&& other)
- {
+ return *this;
+ }
+ String & operator=(String&& other)
+ {
m_buffer = _Move(other.m_buffer);
return *this;
- }
- char operator[](Index id) const
- {
+ }
+ char operator[](Index id) const
+ {
SLANG_ASSERT(id >= 0 && id < getLength());
- return begin()[id];
- }
+ return begin()[id];
+ }
Index getLength() const
{
return m_buffer ? m_buffer->getLength() : 0;
}
- friend String operator+(const char*op1, const String & op2);
- friend String operator+(const String & op1, const char * op2);
- friend String operator+(const String & op1, const String & op2);
+ friend String operator+(const char*op1, const String & op2);
+ friend String operator+(const String & op1, const char * op2);
+ friend String operator+(const String & op1, const String & op2);
- StringSlice trimStart() const
- {
- if (!m_buffer)
- return StringSlice();
- Index startIndex = 0;
+ StringSlice trimStart() const
+ {
+ if (!m_buffer)
+ return StringSlice();
+ Index startIndex = 0;
const char*const data = getData();
- while (startIndex < getLength() &&
- (data[startIndex] == ' ' || data[startIndex] == '\t' || data[startIndex] == '\r' || data[startIndex] == '\n'))
- startIndex++;
+ while (startIndex < getLength() &&
+ (data[startIndex] == ' ' || data[startIndex] == '\t' || data[startIndex] == '\r' || data[startIndex] == '\n'))
+ startIndex++;
return StringSlice(m_buffer, startIndex, getLength());
- }
+ }
- StringSlice trimEnd() const
- {
- if (!m_buffer)
- return StringSlice();
+ StringSlice trimEnd() const
+ {
+ if (!m_buffer)
+ return StringSlice();
- Index endIndex = getLength();
+ Index endIndex = getLength();
const char*const data = getData();
- while (endIndex > 0 &&
- (data[endIndex-1] == ' ' || data[endIndex-1] == '\t' || data[endIndex-1] == '\r' || data[endIndex-1] == '\n'))
- endIndex--;
+ while (endIndex > 0 &&
+ (data[endIndex-1] == ' ' || data[endIndex-1] == '\t' || data[endIndex-1] == '\r' || data[endIndex-1] == '\n'))
+ endIndex--;
return StringSlice(m_buffer, 0, endIndex);
- }
+ }
- StringSlice trim() const
- {
- if (!m_buffer)
- return StringSlice();
+ StringSlice trim() const
+ {
+ if (!m_buffer)
+ return StringSlice();
- Index startIndex = 0;
+ Index startIndex = 0;
const char*const data = getData();
- while (startIndex < getLength() &&
- (data[startIndex] == ' ' || data[startIndex] == '\t'))
- startIndex++;
+ while (startIndex < getLength() &&
+ (data[startIndex] == ' ' || data[startIndex] == '\t'))
+ startIndex++;
Index endIndex = getLength();
- while (endIndex > startIndex &&
- (data[endIndex-1] == ' ' || data[endIndex-1] == '\t'))
- endIndex--;
+ while (endIndex > startIndex &&
+ (data[endIndex-1] == ' ' || data[endIndex-1] == '\t'))
+ endIndex--;
return StringSlice(m_buffer, startIndex, endIndex);
- }
+ }
- StringSlice subString(Index id, Index len) const
- {
- if (len == 0)
- return StringSlice();
+ StringSlice subString(Index id, Index len) const
+ {
+ if (len == 0)
+ return StringSlice();
if (id + len > getLength())
- len = getLength() - id;
+ len = getLength() - id;
#if _DEBUG
- if (id < 0 || id >= getLength() || (id + len) > getLength())
- throw "SubString: index out of range.";
- if (len < 0)
- throw "SubString: length less than zero.";
+ if (id < 0 || id >= getLength() || (id + len) > getLength())
+ throw "SubString: index out of range.";
+ if (len < 0)
+ throw "SubString: length less than zero.";
#endif
return StringSlice(m_buffer, id, id + len);
- }
+ }
- char const* getBuffer() const
- {
+ char const* getBuffer() const
+ {
return getData();
- }
+ }
OSString toWString(Index* len = 0) const;
- bool equals(const String & str, bool caseSensitive = true)
- {
- if (caseSensitive)
- return (strcmp(begin(), str.begin()) == 0);
- else
- {
+ bool equals(const String & str, bool caseSensitive = true)
+ {
+ if (caseSensitive)
+ return (strcmp(begin(), str.begin()) == 0);
+ else
+ {
#ifdef _MSC_VER
- return (_stricmp(begin(), str.begin()) == 0);
+ return (_stricmp(begin(), str.begin()) == 0);
#else
- return (strcasecmp(begin(), str.begin()) == 0);
+ return (strcasecmp(begin(), str.begin()) == 0);
#endif
- }
- }
- bool operator==(const char * strbuffer) const
- {
- return (strcmp(begin(), strbuffer) == 0);
- }
-
- bool operator==(const String & str) const
- {
- return (strcmp(begin(), str.begin()) == 0);
- }
- bool operator!=(const char * strbuffer) const
- {
- return (strcmp(begin(), strbuffer) != 0);
- }
- bool operator!=(const String & str) const
- {
- return (strcmp(begin(), str.begin()) != 0);
- }
- bool operator>(const String & str) const
- {
- return (strcmp(begin(), str.begin()) > 0);
- }
- bool operator<(const String & str) const
- {
- return (strcmp(begin(), str.begin()) < 0);
- }
- bool operator>=(const String & str) const
- {
- return (strcmp(begin(), str.begin()) >= 0);
- }
- bool operator<=(const String & str) const
- {
- return (strcmp(begin(), str.begin()) <= 0);
- }
-
- String toUpper() const
- {
+ }
+ }
+ bool operator==(const char * strbuffer) const
+ {
+ return (strcmp(begin(), strbuffer) == 0);
+ }
+
+ bool operator==(const String & str) const
+ {
+ return (strcmp(begin(), str.begin()) == 0);
+ }
+ bool operator!=(const char * strbuffer) const
+ {
+ return (strcmp(begin(), strbuffer) != 0);
+ }
+ bool operator!=(const String & str) const
+ {
+ return (strcmp(begin(), str.begin()) != 0);
+ }
+ bool operator>(const String & str) const
+ {
+ return (strcmp(begin(), str.begin()) > 0);
+ }
+ bool operator<(const String & str) const
+ {
+ return (strcmp(begin(), str.begin()) < 0);
+ }
+ bool operator>=(const String & str) const
+ {
+ return (strcmp(begin(), str.begin()) >= 0);
+ }
+ bool operator<=(const String & str) const
+ {
+ return (strcmp(begin(), str.begin()) <= 0);
+ }
+
+ SLANG_FORCE_INLINE bool operator==(const UnownedStringSlice& slice) const { return getUnownedSlice() == slice; }
+ SLANG_FORCE_INLINE bool operator!=(const UnownedStringSlice& slice) const { return getUnownedSlice() != slice; }
+
+ String toUpper() const
+ {
String result;
for (auto c : *this)
{
@@ -685,10 +695,10 @@ namespace Slang
result.append(d);
}
return result;
- }
+ }
- String toLower() const
- {
+ String toLower() const
+ {
String result;
for (auto c : *this)
{
@@ -696,321 +706,321 @@ namespace Slang
result.append(d);
}
return result;
- }
+ }
Index indexOf(const char * str, Index id) const // String str
- {
- if (id >= getLength())
- return Index(-1);
- auto findRs = strstr(begin() + id, str);
- Index res = findRs ? findRs - begin() : Index(-1);
- return res;
- }
+ {
+ if (id >= getLength())
+ return Index(-1);
+ auto findRs = strstr(begin() + id, str);
+ Index res = findRs ? findRs - begin() : Index(-1);
+ return res;
+ }
Index indexOf(const String & str, Index id) const
- {
- return indexOf(str.begin(), id);
- }
+ {
+ return indexOf(str.begin(), id);
+ }
Index indexOf(const char * str) const
- {
- return indexOf(str, 0);
- }
+ {
+ return indexOf(str, 0);
+ }
Index indexOf(const String & str) const
- {
- return indexOf(str.begin(), 0);
- }
+ {
+ return indexOf(str.begin(), 0);
+ }
Index indexOf(char ch, Index id) const
- {
+ {
const Index length = getLength();
SLANG_ASSERT(id >= 0 && id <= length);
- if (!m_buffer)
- return Index(-1);
+ if (!m_buffer)
+ return Index(-1);
const char* data = getData();
- for (Index i = id; i < length; i++)
- if (data[i] == ch)
- return i;
- return Index(-1);
- }
+ for (Index i = id; i < length; i++)
+ if (data[i] == ch)
+ return i;
+ return Index(-1);
+ }
Index indexOf(char ch) const
- {
- return indexOf(ch, 0);
- }
+ {
+ return indexOf(ch, 0);
+ }
Index lastIndexOf(char ch) const
- {
+ {
const Index length = getLength();
const char* data = getData();
// TODO(JS): If we know Index is signed we can do this a bit more simply
for (Index i = length; i > 0; i--)
- if (data[i - 1] == ch)
- return i - 1;
- return Index(-1);
- }
-
- bool startsWith(const char * str) const // String str
- {
- if (!m_buffer)
- return false;
+ if (data[i - 1] == ch)
+ return i - 1;
+ return Index(-1);
+ }
+
+ bool startsWith(const char * str) const // String str
+ {
+ if (!m_buffer)
+ return false;
Index strLen = Index(::strlen(str));
- if (strLen > getLength())
- return false;
+ if (strLen > getLength())
+ return false;
const char*const data = getData();
- for (Index i = 0; i < strLen; i++)
- if (str[i] != data[i])
- return false;
- return true;
- }
+ for (Index i = 0; i < strLen; i++)
+ if (str[i] != data[i])
+ return false;
+ return true;
+ }
- bool startsWith(const String& str) const
- {
- return startsWith(str.begin());
- }
+ bool startsWith(const String& str) const
+ {
+ return startsWith(str.begin());
+ }
- bool endsWith(char const * str) const // String str
- {
- if (!m_buffer)
- return false;
+ bool endsWith(char const * str) const // String str
+ {
+ if (!m_buffer)
+ return false;
- const Index strLen = Index(::strlen(str));
+ const Index strLen = Index(::strlen(str));
const Index len = getLength();
- if (strLen > len)
- return false;
+ if (strLen > len)
+ return false;
const char* data = getData();
- for (Index i = strLen; i > 0; i--)
- if (str[i-1] != data[len - strLen + i-1])
- return false;
- return true;
- }
-
- bool endsWith(const String & str) const
- {
- return endsWith(str.begin());
- }
-
- bool contains(const char * str) const // String str
- {
- return m_buffer && indexOf(str) != Index(-1);
- }
-
- bool contains(const String & str) const
- {
- return contains(str.begin());
- }
-
- HashCode getHashCode() const
- {
- return Slang::getHashCode(StringRepresentation::asSlice(m_buffer));
- }
+ for (Index i = strLen; i > 0; i--)
+ if (str[i-1] != data[len - strLen + i-1])
+ return false;
+ return true;
+ }
+
+ bool endsWith(const String & str) const
+ {
+ return endsWith(str.begin());
+ }
+
+ bool contains(const char * str) const // String str
+ {
+ return m_buffer && indexOf(str) != Index(-1);
+ }
+
+ bool contains(const String & str) const
+ {
+ return contains(str.begin());
+ }
+
+ HashCode getHashCode() const
+ {
+ return Slang::getHashCode(StringRepresentation::asSlice(m_buffer));
+ }
UnownedStringSlice getUnownedSlice() const
{
return StringRepresentation::asSlice(m_buffer);
}
- };
+ };
- class StringBuilder : public String
- {
- private:
+ class StringBuilder : public String
+ {
+ private:
enum { InitialSize = 1024 };
- public:
- explicit StringBuilder(UInt bufferSize = InitialSize)
- {
+ public:
+ explicit StringBuilder(UInt bufferSize = InitialSize)
+ {
ensureUniqueStorageWithCapacity(bufferSize);
- }
- void EnsureCapacity(UInt size)
- {
+ }
+ void EnsureCapacity(UInt size)
+ {
ensureUniqueStorageWithCapacity(size);
- }
- StringBuilder & operator << (char ch)
- {
- Append(&ch, 1);
- return *this;
- }
- StringBuilder & operator << (Int32 val)
- {
- Append(val);
- return *this;
- }
- StringBuilder & operator << (UInt32 val)
- {
- Append(val);
- return *this;
- }
- StringBuilder & operator << (Int64 val)
- {
- Append(val);
- return *this;
- }
- StringBuilder & operator << (UInt64 val)
- {
- Append(val);
- return *this;
- }
- StringBuilder & operator << (float val)
- {
- Append(val);
- return *this;
- }
- StringBuilder & operator << (double val)
- {
- Append(val);
- return *this;
- }
- StringBuilder & operator << (const char * str)
- {
- Append(str, strlen(str));
- return *this;
- }
- StringBuilder & operator << (const String & str)
- {
- Append(str);
- return *this;
- }
- StringBuilder & operator << (UnownedStringSlice const& str)
- {
- append(str);
- return *this;
- }
- StringBuilder & operator << (const _EndLine)
- {
- Append('\n');
- return *this;
- }
- void Append(char ch)
- {
- Append(&ch, 1);
- }
- void Append(float val)
- {
- char buf[128];
- sprintf_s(buf, 128, "%g", val);
- int len = (int)strnlen_s(buf, 128);
- Append(buf, len);
- }
- void Append(double val)
- {
- char buf[128];
- sprintf_s(buf, 128, "%g", val);
- int len = (int)strnlen_s(buf, 128);
- Append(buf, len);
- }
- void Append(Int32 value, int radix = 10)
- {
- char vBuffer[33];
- int len = IntToAscii(vBuffer, value, radix);
- ReverseInternalAscii(vBuffer, len);
- Append(vBuffer);
- }
- void Append(UInt32 value, int radix = 10)
- {
- char vBuffer[33];
- int len = IntToAscii(vBuffer, value, radix);
- ReverseInternalAscii(vBuffer, len);
- Append(vBuffer);
- }
- void Append(Int64 value, int radix = 10)
- {
- char vBuffer[65];
- int len = IntToAscii(vBuffer, value, radix);
- ReverseInternalAscii(vBuffer, len);
- Append(vBuffer);
- }
- void Append(UInt64 value, int radix = 10)
- {
- char vBuffer[65];
- int len = IntToAscii(vBuffer, value, radix);
- ReverseInternalAscii(vBuffer, len);
- Append(vBuffer);
- }
- void Append(const String & str)
- {
- Append(str.getBuffer(), str.getLength());
- }
- void Append(const char * str)
- {
- Append(str, strlen(str));
- }
- void Append(const char * str, UInt strLen)
- {
+ }
+ StringBuilder & operator << (char ch)
+ {
+ Append(&ch, 1);
+ return *this;
+ }
+ StringBuilder & operator << (Int32 val)
+ {
+ Append(val);
+ return *this;
+ }
+ StringBuilder & operator << (UInt32 val)
+ {
+ Append(val);
+ return *this;
+ }
+ StringBuilder & operator << (Int64 val)
+ {
+ Append(val);
+ return *this;
+ }
+ StringBuilder & operator << (UInt64 val)
+ {
+ Append(val);
+ return *this;
+ }
+ StringBuilder & operator << (float val)
+ {
+ Append(val);
+ return *this;
+ }
+ StringBuilder & operator << (double val)
+ {
+ Append(val);
+ return *this;
+ }
+ StringBuilder & operator << (const char * str)
+ {
+ Append(str, strlen(str));
+ return *this;
+ }
+ StringBuilder & operator << (const String & str)
+ {
+ Append(str);
+ return *this;
+ }
+ StringBuilder & operator << (UnownedStringSlice const& str)
+ {
+ append(str);
+ return *this;
+ }
+ StringBuilder & operator << (const _EndLine)
+ {
+ Append('\n');
+ return *this;
+ }
+ void Append(char ch)
+ {
+ Append(&ch, 1);
+ }
+ void Append(float val)
+ {
+ char buf[128];
+ sprintf_s(buf, 128, "%g", val);
+ int len = (int)strnlen_s(buf, 128);
+ Append(buf, len);
+ }
+ void Append(double val)
+ {
+ char buf[128];
+ sprintf_s(buf, 128, "%g", val);
+ int len = (int)strnlen_s(buf, 128);
+ Append(buf, len);
+ }
+ void Append(Int32 value, int radix = 10)
+ {
+ char vBuffer[33];
+ int len = IntToAscii(vBuffer, value, radix);
+ ReverseInternalAscii(vBuffer, len);
+ Append(vBuffer);
+ }
+ void Append(UInt32 value, int radix = 10)
+ {
+ char vBuffer[33];
+ int len = IntToAscii(vBuffer, value, radix);
+ ReverseInternalAscii(vBuffer, len);
+ Append(vBuffer);
+ }
+ void Append(Int64 value, int radix = 10)
+ {
+ char vBuffer[65];
+ int len = IntToAscii(vBuffer, value, radix);
+ ReverseInternalAscii(vBuffer, len);
+ Append(vBuffer);
+ }
+ void Append(UInt64 value, int radix = 10)
+ {
+ char vBuffer[65];
+ int len = IntToAscii(vBuffer, value, radix);
+ ReverseInternalAscii(vBuffer, len);
+ Append(vBuffer);
+ }
+ void Append(const String & str)
+ {
+ Append(str.getBuffer(), str.getLength());
+ }
+ void Append(const char * str)
+ {
+ Append(str, strlen(str));
+ }
+ void Append(const char * str, UInt strLen)
+ {
append(str, str + strLen);
- }
+ }
#if 0
- int Capacity()
- {
- return bufferSize;
- }
-
- char * Buffer()
- {
- return buffer;
- }
-
- int Length()
- {
- return length;
- }
+ int Capacity()
+ {
+ return bufferSize;
+ }
+
+ char * Buffer()
+ {
+ return buffer;
+ }
+
+ int Length()
+ {
+ return length;
+ }
#endif
- String ToString()
- {
+ String ToString()
+ {
return *this;
- }
+ }
- String ProduceString()
- {
+ String ProduceString()
+ {
return *this;
- }
+ }
#if 0
- String GetSubString(int start, int count)
- {
- String rs;
- rs.buffer = new char[count + 1];
- rs.length = count;
- strncpy_s(rs.buffer.Ptr(), count + 1, buffer + start, count);
- rs.buffer[count] = 0;
- return rs;
- }
+ String GetSubString(int start, int count)
+ {
+ String rs;
+ rs.buffer = new char[count + 1];
+ rs.length = count;
+ strncpy_s(rs.buffer.Ptr(), count + 1, buffer + start, count);
+ rs.buffer[count] = 0;
+ return rs;
+ }
#endif
#if 0
- void Remove(int id, int len)
- {
+ void Remove(int id, int len)
+ {
#if _DEBUG
- if (id >= length || id < 0)
- throw "Remove: Index out of range.";
- if (len < 0)
- throw "Remove: remove length smaller than zero.";
+ if (id >= length || id < 0)
+ throw "Remove: Index out of range.";
+ if (len < 0)
+ throw "Remove: remove length smaller than zero.";
#endif
- int actualDelLength = ((id + len) >= length) ? (length - id) : len;
- for (int i = id + actualDelLength; i <= length; i++)
- buffer[i - actualDelLength] = buffer[i];
- length -= actualDelLength;
- }
+ int actualDelLength = ((id + len) >= length) ? (length - id) : len;
+ for (int i = id + actualDelLength; i <= length; i++)
+ buffer[i - actualDelLength] = buffer[i];
+ length -= actualDelLength;
+ }
#endif
- void Clear()
- {
+ void Clear()
+ {
m_buffer.setNull();
- }
- };
+ }
+ };
- int StringToInt(const String & str, int radix = 10);
- unsigned int StringToUInt(const String & str, int radix = 10);
- double StringToDouble(const String & str);
- float StringToFloat(const String & str);
+ int StringToInt(const String & str, int radix = 10);
+ unsigned int StringToUInt(const String & str, int radix = 10);
+ double StringToDouble(const String & str);
+ float StringToFloat(const String & str);
}
#endif
diff --git a/source/core/slang-token-reader.h b/source/core/slang-token-reader.h
index 474db5c4a..0c2d390d2 100644
--- a/source/core/slang-token-reader.h
+++ b/source/core/slang-token-reader.h
@@ -103,7 +103,7 @@ namespace Slang
{
auto token = ReadToken();
bool neg = false;
- if (token.Content == '-')
+ if (token.Content.getUnownedSlice().isChar('-'))
{
neg = true;
token = ReadToken();
@@ -130,7 +130,7 @@ namespace Slang
{
auto token = ReadToken();
bool neg = false;
- if (token.Content == '-')
+ if (token.Content.getUnownedSlice().isChar('-'))
{
neg = true;
token = ReadToken();
diff --git a/source/slang/slang-ast-base.h b/source/slang/slang-ast-base.h
index e9005212c..2bfa7940b 100644
--- a/source/slang/slang-ast-base.h
+++ b/source/slang/slang-ast-base.h
@@ -155,6 +155,8 @@ class Type: public Val
bool _equalsImplOverride(Type* type);
Type* _createCanonicalTypeOverride();
+ void _setASTBuilder(ASTBuilder* astBuilder) { m_astBuilder = astBuilder; }
+
protected:
bool equalsImpl(Type* type);
Type* createCanonicalType();
@@ -276,10 +278,10 @@ class Modifier : public SyntaxNode
Modifier* next = nullptr;
// The keyword that was used to introduce t that was used to name this modifier.
- Name* name = nullptr;
+ Name* keywordName = nullptr;
- Name* getName() { return name; }
- NameLoc getNameAndLoc() { return NameLoc(name, loc); }
+ Name* getKeywordName() { return keywordName; }
+ NameLoc getKeywordNameAndLoc() { return NameLoc(keywordName, loc); }
};
// A syntax node which can have modifiers applied
@@ -327,7 +329,6 @@ public:
SourceLoc getNameLoc() { return nameAndLoc.loc ; }
NameLoc getNameAndLoc() { return nameAndLoc ; }
-
DeclCheckStateExt checkState = DeclCheckState::Unchecked;
// The next declaration defined in the same container with the same name
diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp
index 54fe55478..3b97bfbb7 100644
--- a/source/slang/slang-ast-builder.cpp
+++ b/source/slang/slang-ast-builder.cpp
@@ -140,7 +140,7 @@ void SharedASTBuilder::registerMagicDecl(Decl* decl, MagicTypeModifier* modifier
if (auto genericDecl = as<GenericDecl>(decl->parentDecl))
declToRegister = genericDecl;
- m_magicDecls[modifier->name] = declToRegister;
+ m_magicDecls[modifier->magicName] = declToRegister;
}
Decl* SharedASTBuilder::findMagicDecl(const String& name)
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index d707e9771..55b62483b 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -350,9 +350,10 @@ class BuiltinTypeModifier : public Modifier
class MagicTypeModifier : public Modifier
{
SLANG_AST_CLASS(MagicTypeModifier)
-
- String name;
- uint32_t tag;
+
+ /// Modifier has a name so call this magicModifier to disambiguate
+ String magicName;
+ uint32_t tag = uint32_t(0);
};
// A modifier applied to declarations of builtin types to indicate how they
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index 10bf46b63..8338f0b21 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -1255,6 +1255,8 @@ namespace Slang
// requirement by a particular declaration or value.
struct RequirementWitness
{
+ SLANG_VALUE_CLASS(RequirementWitness)
+
RequirementWitness()
: m_flavor(Flavor::none)
{}
@@ -1305,8 +1307,10 @@ namespace Slang
typedef Dictionary<Decl*, RequirementWitness> RequirementDictionary;
- struct WitnessTable : RefObject
+ struct WitnessTable : SerialRefObject
{
+ SLANG_OBJ_CLASS(WitnessTable)
+
List<KeyValuePair<Decl*, RequirementWitness>> requirementList;
RequirementDictionary requirementDictionary;
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index d771e689c..e7c2a5853 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -1231,6 +1231,11 @@ namespace Slang
}
}
+ void registerBuiltinDecls(Session* session, Decl* decl)
+ {
+ _registerBuiltinDeclsRec(session, decl);
+ }
+
void SemanticsDeclVisitorBase::checkModule(ModuleDecl* moduleDecl)
{
// When we are dealing with code from the standard library,
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index b38018354..4594af28d 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -395,7 +395,7 @@ namespace Slang
// Let it go thru iff single string attribute
if (!hasStringArgs(attr, 1))
{
- getSink()->diagnose(attr, Diagnostics::expectedSingleStringArg, attr->name);
+ getSink()->diagnose(attr, Diagnostics::expectedSingleStringArg, attr->keywordName);
}
}
else if (as<OutputControlPointsAttribute>(attr))
@@ -403,7 +403,7 @@ namespace Slang
// Let it go thru iff single integral attribute
if (!hasIntArgs(attr, 1))
{
- getSink()->diagnose(attr, Diagnostics::expectedSingleIntArg, attr->name);
+ getSink()->diagnose(attr, Diagnostics::expectedSingleIntArg, attr->keywordName);
}
}
else if (as<PushConstantAttribute>(attr))
@@ -433,7 +433,7 @@ namespace Slang
}
else
{
- getSink()->diagnose(attr, Diagnostics::expectedSingleIntArg, attr->name);
+ getSink()->diagnose(attr, Diagnostics::expectedSingleIntArg, attr->keywordName);
return false;
}
}
@@ -551,7 +551,7 @@ namespace Slang
UncheckedAttribute* uncheckedAttr,
ModifiableSyntaxNode* attrTarget)
{
- auto attrName = uncheckedAttr->getName();
+ auto attrName = uncheckedAttr->getKeywordName();
auto attrDecl = lookUpAttributeDecl(
attrName,
uncheckedAttr->scope);
@@ -580,7 +580,7 @@ namespace Slang
// We are going to replace the unchecked attribute with the checked one.
// First copy all of the state over from the original attribute.
- attr->name = uncheckedAttr->name;
+ attr->keywordName = uncheckedAttr->keywordName;
attr->args = uncheckedAttr->args;
attr->loc = uncheckedAttr->loc;
diff --git a/source/slang/slang-check.h b/source/slang/slang-check.h
index 94deba1aa..0309e5393 100644
--- a/source/slang/slang-check.h
+++ b/source/slang/slang-check.h
@@ -36,4 +36,6 @@ namespace Slang
bool isGlobalShaderParameter(VarDeclBase* decl);
bool isFromStdLib(Decl* decl);
+
+ void registerBuiltinDecls(Session* session, Decl* decl);
}
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index ea8540800..306119b5f 100755
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -2346,7 +2346,7 @@ SlangResult dissassembleDXILUsingDXC(
options.compressionType = linkage->serialCompressionType;
if (linkage->debugInfoLevel != DebugInfoLevel::None)
{
- options.optionFlags |= SerialOptionFlag::DebugInfo;
+ options.optionFlags |= SerialOptionFlag::SourceLocation;
}
if (linkage->m_obfuscateCode)
{
@@ -2360,7 +2360,7 @@ SlangResult dissassembleDXILUsingDXC(
RiffContainer container;
{
SerialContainerData data;
- SLANG_RETURN_ON_FAIL(SerialContainerUtil::requestToData(this, options, data));
+ SLANG_RETURN_ON_FAIL(SerialContainerUtil::addEndToEndRequestToData(this, options, data));
SLANG_RETURN_ON_FAIL(SerialContainerUtil::write(data, options, &container));
}
// We now write the RiffContainer to the stream
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 56885ab46..1710baa6e 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -925,7 +925,7 @@ namespace Slang
//
/// Create a module (initially empty).
- Module(Linkage* linkage);
+ Module(Linkage* linkage, ASTBuilder* astBuilder = nullptr);
/// Get the AST for the module (if it has been parsed)
ModuleDecl* getModuleDecl() { return m_moduleDecl; }
@@ -978,7 +978,7 @@ namespace Slang
NodeBase* findExportFromMangledName(const UnownedStringSlice& slice);
/// Get the ASTBuilder
- ASTBuilder* getASTBuilder() { return &m_astBuilder; }
+ ASTBuilder* getASTBuilder() { return m_astBuilder; }
/// Collect information on the shader parameters of the module.
///
@@ -1058,7 +1058,7 @@ namespace Slang
// The builder that owns all of the AST nodes from parsing the source of
// this module.
- ASTBuilder m_astBuilder;
+ RefPtr<ASTBuilder> m_astBuilder;
// Holds map of exported mangled names to symbols. m_mangledExportPool maps names to indices,
// and m_mangledExportSymbols holds the NodeBase* values for each index.
@@ -2170,6 +2170,8 @@ namespace Slang
private:
+ SlangResult _readBuiltinModule(Scope* scope, String moduleName);
+
SlangResult _loadRequest(EndToEndCompileRequest* request, const void* data, size_t size);
/// Linkage used for all built-in (stdlib) code.
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index e02ccf245..4d93c35a8 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -730,7 +730,7 @@ namespace Slang
Token nameToken = parseAttributeName(parser);
UncheckedAttribute* modifier = parser->astBuilder->create<UncheckedAttribute>();
- modifier->name = nameToken.getName();
+ modifier->keywordName = nameToken.getName();
modifier->loc = nameToken.getLoc();
modifier->scope = parser->currentScope;
@@ -903,7 +903,7 @@ namespace Slang
Modifier* parsedModifier = nullptr;
if (tryParseUsingSyntaxDecl<Modifier>(parser, &parsedModifier))
{
- parsedModifier->name = nameToken.getName();
+ parsedModifier->keywordName = nameToken.getName();
if (!parsedModifier->loc.isValid())
{
parsedModifier->loc = nameToken.loc;
@@ -5504,7 +5504,7 @@ namespace Slang
numThreadsAttrib->args.setCount(3);
// Just mark the loc and name from the first in the list
- numThreadsAttrib->name = getName(parser, "numthreads");
+ numThreadsAttrib->keywordName = getName(parser, "numthreads");
numThreadsAttrib->loc = nameAndLoc.loc;
numThreadsAttrib->scope = parser->currentScope;
}
@@ -5566,7 +5566,7 @@ namespace Slang
SLANG_ASSERT(modifier);
#undef CASE
- modifier->name = nameAndLoc.name;
+ modifier->keywordName = nameAndLoc.name;
modifier->loc = nameAndLoc.loc;
// Special handling for GLSLLayoutModifier
@@ -5610,7 +5610,7 @@ namespace Slang
{
MagicTypeModifier* modifier = parser->astBuilder->create<MagicTypeModifier>();
parser->ReadToken(TokenType::LParent);
- modifier->name = parser->ReadToken(TokenType::Identifier).getContent();
+ modifier->magicName = parser->ReadToken(TokenType::Identifier).getContent();
if (AdvanceIf(parser, TokenType::Comma))
{
modifier->tag = uint32_t(StringToInt(parser->ReadToken(TokenType::IntegerLiteral).getContent()));
diff --git a/source/slang/slang-reflection.cpp b/source/slang/slang-reflection.cpp
index 1b0a590cc..fd76c5e0b 100644
--- a/source/slang/slang-reflection.cpp
+++ b/source/slang/slang-reflection.cpp
@@ -114,7 +114,7 @@ SlangReflectionUserAttribute* findUserAttributeByName(Session* session, Decl* de
auto nameObj = session->tryGetNameObj(name);
for (auto x : decl->getModifiersOfType<UserDefinedAttribute>())
{
- if (x->name == nameObj)
+ if (x->keywordName == nameObj)
return (SlangReflectionUserAttribute*)(x);
}
return nullptr;
@@ -136,7 +136,7 @@ SLANG_API char const* spReflectionUserAttribute_GetName(SlangReflectionUserAttri
{
auto userAttr = convert(attrib);
if (!userAttr) return nullptr;
- return userAttr->getName()->text.getBuffer();
+ return userAttr->getKeywordName()->text.getBuffer();
}
SLANG_API unsigned int spReflectionUserAttribute_GetArgumentCount(SlangReflectionUserAttribute* attrib)
{
diff --git a/source/slang/slang-serialize-ast-type-info.h b/source/slang/slang-serialize-ast-type-info.h
index 733694e8a..400474046 100644
--- a/source/slang/slang-serialize-ast-type-info.h
+++ b/source/slang/slang-serialize-ast-type-info.h
@@ -92,6 +92,7 @@ SLANG_VALUE_TYPE_INFO(LookupResultItem)
// QualType
SLANG_VALUE_TYPE_INFO(QualType)
+
// LookupResult
template <>
struct SerialTypeInfo<LookupResult>
@@ -205,6 +206,13 @@ struct SerialTypeInfo<LookupResultItem_Breadcrumb::ThisParameterMode> : public S
template <>
struct SerialTypeInfo<LookupResultItem_Breadcrumb::Kind> : public SerialConvertTypeInfo<LookupResultItem_Breadcrumb::Kind, uint8_t> {};
+// RequirementWitness::Flavor
+template <>
+struct SerialTypeInfo<RequirementWitness::Flavor> : public SerialConvertTypeInfo<RequirementWitness::Flavor, uint8_t> {};
+
+// RequirementWitness
+SLANG_VALUE_TYPE_INFO(RequirementWitness)
+
} // namespace Slang
#endif
diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp
index 8c4edb9a0..067e6637a 100644
--- a/source/slang/slang-serialize-container.cpp
+++ b/source/slang/slang-serialize-container.cpp
@@ -16,42 +16,100 @@
namespace Slang {
-/* static */SlangResult SerialContainerUtil::requestToData(EndToEndCompileRequest* request, const WriteOptions& options, SerialContainerData& out)
+/* static */SlangResult SerialContainerUtil::write(Module* module, const WriteOptions& options, Stream* stream)
{
- SLANG_UNUSED(options);
-
- out.clear();
-
- auto linkage = request->getLinkage();
- auto sink = request->getSink();
- auto frontEndReq = request->getFrontEndReq();
-
- for (TranslationUnitRequest* translationUnit : frontEndReq->translationUnits)
+ RiffContainer container;
{
- auto module = translationUnit->module;
- auto irModule = module->getIRModule();
+ SerialContainerData data;
+ SLANG_RETURN_ON_FAIL(SerialContainerUtil::addModuleToData(module, options, data));
+ SLANG_RETURN_ON_FAIL(SerialContainerUtil::write(data, options, &container));
+ }
+ // We now write the RiffContainer to the stream
+ SLANG_RETURN_ON_FAIL(RiffUtil::write(container.getRoot(), true, stream));
+ return SLANG_OK;
+}
- // Root AST node
- auto moduleDecl = translationUnit->getModuleDecl();
+/* static */SlangResult SerialContainerUtil::write(FrontEndCompileRequest* frontEndReq, const WriteOptions& options, Stream* stream)
+{
+ RiffContainer container;
+ {
+ SerialContainerData data;
+ SLANG_RETURN_ON_FAIL(SerialContainerUtil::addFrontEndRequestToData(frontEndReq, options, data));
+ SLANG_RETURN_ON_FAIL(SerialContainerUtil::write(data, options, &container));
+ }
+ // We now write the RiffContainer to the stream
+ SLANG_RETURN_ON_FAIL(RiffUtil::write(container.getRoot(), true, stream));
+ return SLANG_OK;
+}
- SLANG_ASSERT(irModule || moduleDecl);
+/* static */SlangResult SerialContainerUtil::write(EndToEndCompileRequest* request, const WriteOptions& options, Stream* stream)
+{
+ RiffContainer container;
+ {
+ SerialContainerData data;
+ SLANG_RETURN_ON_FAIL(SerialContainerUtil::addEndToEndRequestToData(request, options, data));
+ SLANG_RETURN_ON_FAIL(SerialContainerUtil::write(data, options, &container));
+ }
+ // We now write the RiffContainer to the stream
+ SLANG_RETURN_ON_FAIL(RiffUtil::write(container.getRoot(), true, stream));
+ return SLANG_OK;
+}
+/* static */SlangResult SerialContainerUtil::addModuleToData(Module* module, const WriteOptions& options, SerialContainerData& outData)
+{
+ if (options.optionFlags & (SerialOptionFlag::ASTModule | SerialOptionFlag::IRModule))
+ {
SerialContainerData::Module dstModule;
// NOTE: The astBuilder is not set here, as not needed to be scoped for serialization (it is assumed the
// TranslationUnitRequest stays in scope)
- dstModule.astRootNode = moduleDecl;
- dstModule.irModule = irModule;
+ if (options.optionFlags & SerialOptionFlag::ASTModule)
+ {
+ // Root AST node
+ auto moduleDecl = module->getModuleDecl();
+ SLANG_ASSERT(moduleDecl);
- out.modules.add(dstModule);
+ dstModule.astRootNode = moduleDecl;
+ }
+ if (options.optionFlags & SerialOptionFlag::IRModule)
+ {
+ // IR module
+ dstModule.irModule = module->getIRModule();
+ SLANG_ASSERT(dstModule.irModule);
+ }
+
+ outData.modules.add(dstModule);
+ }
+
+ return SLANG_OK;
+}
+
+
+/* static */SlangResult SerialContainerUtil::addFrontEndRequestToData(FrontEndCompileRequest* frontEndReq, const WriteOptions& options, SerialContainerData& outData)
+{
+ // Go through translation units, adding modules
+ for (TranslationUnitRequest* translationUnit : frontEndReq->translationUnits)
+ {
+ SLANG_RETURN_ON_FAIL(addModuleToData(translationUnit->module, options, outData));
}
+ return SLANG_OK;
+}
+
+/* static */SlangResult SerialContainerUtil::addEndToEndRequestToData(EndToEndCompileRequest* request, const WriteOptions& options, SerialContainerData& out)
+{
+ auto linkage = request->getLinkage();
+ auto sink = request->getSink();
+
+ // Output the front end request data
+ SLANG_RETURN_ON_FAIL(addFrontEndRequestToData(request->getFrontEndReq(), options, out));
+
+ //
auto program = request->getSpecializedGlobalAndEntryPointsComponentType();
// Add all the target modules
{
-
for (auto target : linkage->targets)
{
auto targetProgram = program->getTargetProgram(target);
@@ -117,7 +175,7 @@ namespace Slang {
// Module list
RiffContainer::ScopeChunk moduleListScope(container, RiffContainer::Chunk::Kind::List, SerialBinary::kModuleListFourCc);
- if (options.optionFlags & SerialOptionFlag::DebugInfo)
+ if (options.optionFlags & SerialOptionFlag::SourceLocation)
{
sourceLocWriter = new SerialSourceLocWriter(options.sourceManager);
}
@@ -226,6 +284,20 @@ namespace Slang {
return SLANG_OK;
}
+
+static List<ExtensionDecl*>& _getCandidateExtensionList(
+ AggTypeDecl* typeDecl,
+ Dictionary<AggTypeDecl*, RefPtr<CandidateExtensionList>>& mapTypeToCandidateExtensions)
+{
+ RefPtr<CandidateExtensionList> entry;
+ if (!mapTypeToCandidateExtensions.TryGetValue(typeDecl, entry))
+ {
+ entry = new CandidateExtensionList();
+ mapTypeToCandidateExtensions.Add(typeDecl, entry);
+ }
+ return entry->candidateExtensions;
+}
+
/* static */Result SerialContainerUtil::read(RiffContainer* container, const ReadOptions& options, SerialContainerData& out)
{
out.clear();
@@ -396,6 +468,10 @@ namespace Slang {
// Set the sourceLocReader before doing de-serialize, such can lookup the remapped sourceLocs
reader.getExtraObjects().set(sourceLocReader);
+ // Go through all of the AST nodes
+ // 1) Set the ASTBuilder on Type nodes
+
+
// TODO(JS):
// If modules can have more complicated relationships (like a two modules can refer to symbols
// from each other), then we can make this work by
@@ -412,6 +488,34 @@ namespace Slang {
// Get the root node. It's at index 1 (0 is the null value).
astRootNode = reader.getPointer(SerialIndex(1)).dynamicCast<NodeBase>();
+
+ // 2) Add the extensions to the module mapTypeToCandidateExtensions cache
+
+ {
+ ModuleDecl* moduleDecl = as<ModuleDecl>(astRootNode);
+
+ for (auto& obj : reader.getObjects())
+ {
+ if (Type* type = obj.dynamicCast<Type>())
+ {
+ type->_setASTBuilder(astBuilder);
+ }
+
+ if (ExtensionDecl* extensionDecl = obj.dynamicCast<ExtensionDecl>())
+ {
+ if (auto targetDeclRefType = as<DeclRefType>(extensionDecl->targetType))
+ {
+ // Attach our extension to that type as a candidate...
+ if (auto aggTypeDeclRef = targetDeclRefType->declRef.as<AggTypeDecl>())
+ {
+ auto aggTypeDecl = aggTypeDeclRef.getDecl();
+
+ _getCandidateExtensionList(aggTypeDecl, moduleDecl->mapTypeToCandidateExtensions).add(extensionDecl);
+ }
+ }
+ }
+ }
+ }
}
// Onto next chunk
@@ -489,7 +593,7 @@ namespace Slang {
RefPtr<SerialSourceLocWriter> sourceLocWriter;
- if (options.optionFlags & SerialOptionFlag::DebugInfo)
+ if (options.optionFlags & SerialOptionFlag::SourceLocation)
{
sourceLocWriter = new SerialSourceLocWriter(options.sourceManager);
}
@@ -530,7 +634,7 @@ namespace Slang {
RefPtr<SerialSourceLocReader> sourceLocReader;
// If we have debug info then find and read it
- if (options.optionFlags & SerialOptionFlag::DebugInfo)
+ if (options.optionFlags & SerialOptionFlag::SourceLocation)
{
RiffContainer::ListChunk* debugList = rootList->findContainedList(SerialSourceLocData::kDebugFourCc);
if (!debugList)
@@ -593,7 +697,7 @@ namespace Slang {
}
}
}
- else if (options.optionFlags & SerialOptionFlag::DebugInfo)
+ else if (options.optionFlags & SerialOptionFlag::SourceLocation)
{
// They should be on the same line nos
for (Index i = 1; i < readInsts.getCount(); ++i)
diff --git a/source/slang/slang-serialize-container.h b/source/slang/slang-serialize-container.h
index bc34982e7..5368f62e6 100644
--- a/source/slang/slang-serialize-container.h
+++ b/source/slang/slang-serialize-container.h
@@ -93,8 +93,14 @@ struct SerialContainerUtil
DiagnosticSink* sink = nullptr;
};
+ /// Add module to outData
+ static SlangResult addModuleToData(Module* module, const WriteOptions& options, SerialContainerData& outData);
+
/// Get the serializable contents of the request as data
- static SlangResult requestToData(EndToEndCompileRequest* request, const WriteOptions& options, SerialContainerData& outData);
+ static SlangResult addEndToEndRequestToData(EndToEndCompileRequest* request, const WriteOptions& options, SerialContainerData& outData);
+
+ /// Convert front end request into something serializable
+ static SlangResult addFrontEndRequestToData(FrontEndCompileRequest* request, const WriteOptions& options, SerialContainerData& outData);
/// Write the data into the container
static SlangResult write(const SerialContainerData& data, const WriteOptions& options, RiffContainer* container);
@@ -104,6 +110,12 @@ struct SerialContainerUtil
/// Verify IR serialization
static SlangResult verifyIRSerialize(IRModule* module, Session* session, const WriteOptions& options);
+
+ /// Write the request to the stream
+ static SlangResult write(FrontEndCompileRequest* frontEndReq, const WriteOptions& options, Stream* stream);
+ static SlangResult write(EndToEndCompileRequest* request, const WriteOptions& options, Stream* stream);
+ static SlangResult write(Module* module, const WriteOptions& options, Stream* stream);
+
};
} // namespace Slang
diff --git a/source/slang/slang-serialize-factory.cpp b/source/slang/slang-serialize-factory.cpp
index f93fbba69..3ff536137 100644
--- a/source/slang/slang-serialize-factory.cpp
+++ b/source/slang/slang-serialize-factory.cpp
@@ -111,6 +111,9 @@ SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const NodeBas
ASTSerialUtil::addSerialClasses(serialClasses);
SerialRefObjects::addSerialClasses(serialClasses);
+ // Check if it seems ok
+ SLANG_ASSERT(serialClasses->isOk());
+
return SLANG_OK;
}
diff --git a/source/slang/slang-serialize-ir.cpp b/source/slang/slang-serialize-ir.cpp
index d923577f4..50e4467e3 100644
--- a/source/slang/slang-serialize-ir.cpp
+++ b/source/slang/slang-serialize-ir.cpp
@@ -307,7 +307,7 @@ Result IRSerialWriter::write(IRModule* module, SerialSourceLocWriter* sourceLocW
}
}
- if ((options & SerialOptionFlag::DebugInfo) && sourceLocWriter)
+ if ((options & SerialOptionFlag::SourceLocation) && sourceLocWriter)
{
_calcDebugInfo(sourceLocWriter);
}
diff --git a/source/slang/slang-serialize-type-info.h b/source/slang/slang-serialize-type-info.h
index 89097fc32..7ed45bb0b 100644
--- a/source/slang/slang-serialize-type-info.h
+++ b/source/slang/slang-serialize-type-info.h
@@ -150,11 +150,7 @@ struct SerialTypeInfo<T*>
{
typedef T* NativeType;
typedef SerialIndex SerialType;
-
- enum
- {
- SerialAlignment = SLANG_ALIGN_OF(SerialType)
- };
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
static void toSerial(SerialWriter* writer, const void* inNative, void* outSerial)
{
@@ -166,6 +162,25 @@ struct SerialTypeInfo<T*>
}
};
+// RefPtr (pretty much the same as T* - except for native rep)
+template <typename T>
+struct SerialTypeInfo<RefPtr<T>>
+{
+ typedef RefPtr<T> NativeType;
+ typedef SerialIndex SerialType;
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto& src = *(const NativeType*)native;
+ *(SerialType*)serial = writer->addPointer(src);
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ *(NativeType*)native = reader->getPointer(*(const SerialType*)serial).dynamicCast<T>();
+ }
+};
+
// Special case Name
template <>
struct SerialTypeInfo<Name*> : public SerialTypeInfo<RefObject*>
@@ -208,6 +223,27 @@ struct SerialTypeInfo<List<T, ALLOCATOR>>
}
};
+// String
+template <>
+struct SerialTypeInfo<String>
+{
+ typedef String NativeType;
+ typedef SerialIndex SerialType;
+ enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+
+ static void toSerial(SerialWriter* writer, const void* native, void* serial)
+ {
+ auto& src = *(const NativeType*)native;
+ *(SerialType*)serial = writer->addString(src);
+ }
+ static void toNative(SerialReader* reader, const void* serial, void* native)
+ {
+ auto& src = *(const SerialType*)serial;
+ auto& dst = *(NativeType*)native;
+ dst = reader->getString(src);
+ }
+};
+
// Dictionary
template <typename KEY, typename VALUE>
struct SerialTypeInfo<Dictionary<KEY, VALUE>>
@@ -244,8 +280,9 @@ struct SerialTypeInfo<Dictionary<KEY, VALUE>>
i++;
}
- dst.keys = writer->addArray(keys.getBuffer(), count);
- dst.values = writer->addArray(values.getBuffer(), count);
+ // When we add the array it is already converted to a serializable type, so add as SerialArray
+ dst.keys = writer->addSerialArray<KEY>(keys.getBuffer(), count);
+ dst.values = writer->addSerialArray<VALUE>(values.getBuffer(), count);
}
static void toNative(SerialReader* reader, const void* serial, void* native)
{
@@ -271,49 +308,42 @@ struct SerialTypeInfo<Dictionary<KEY, VALUE>>
}
};
-// Handle RefPtr - just convert into * to do the conversion
-template <typename T>
-struct SerialTypeInfo<RefPtr<T>>
+// KeyValuePair
+template<typename KEY, typename VALUE>
+struct SerialTypeInfo<KeyValuePair<KEY, VALUE>>
{
- typedef RefPtr<T> NativeType;
- typedef typename SerialTypeInfo<T*>::SerialType SerialType;
- enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
+ typedef KeyValuePair<KEY, VALUE> NativeType;
- static void toSerial(SerialWriter* writer, const void* native, void* serial)
- {
- auto& src = *(const NativeType*)native;
- T* obj = src;
- SerialTypeInfo<T*>::toSerial(writer, &obj, serial);
- }
- static void toNative(SerialReader* reader, const void* serial, void* native)
+ typedef typename SerialTypeInfo<KEY>::SerialType KeySerialType;
+ typedef typename SerialTypeInfo<VALUE>::SerialType ValueSerialType;
+
+ struct SerialType
{
- T* obj = nullptr;
- SerialTypeInfo<T*>::toNative(reader, serial, &obj);
- *(NativeType*)native = obj;
- }
-};
+ KeySerialType key;
+ ValueSerialType value;
+ };
-// String
-template <>
-struct SerialTypeInfo<String>
-{
- typedef String NativeType;
- typedef SerialIndex SerialType;
enum { SerialAlignment = SLANG_ALIGN_OF(SerialType) };
static void toSerial(SerialWriter* writer, const void* native, void* serial)
{
auto& src = *(const NativeType*)native;
- *(SerialType*)serial = writer->addString(src);
+ auto& dst = *(SerialType*)serial;
+
+ SerialTypeInfo<KEY>::toSerial(writer, &src.Key, &dst.key);
+ SerialTypeInfo<VALUE>::toSerial(writer, &src.Value, &dst.value);
}
static void toNative(SerialReader* reader, const void* serial, void* native)
{
auto& src = *(const SerialType*)serial;
auto& dst = *(NativeType*)native;
- dst = reader->getString(src);
+
+ SerialTypeInfo<KEY>::toNative(reader, &src.key, &dst.Key);
+ SerialTypeInfo<VALUE>::toNative(reader, &src.value, &dst.Value);
}
};
+
} // namespace Slang
#endif
diff --git a/source/slang/slang-serialize-types.h b/source/slang/slang-serialize-types.h
index 9bb84e290..fb0dd2f9d 100644
--- a/source/slang/slang-serialize-types.h
+++ b/source/slang/slang-serialize-types.h
@@ -27,7 +27,7 @@ struct SerialOptionFlag
enum Enum : Type
{
RawSourceLocation = 0x01, ///< If set will store directly SourceLoc - only useful if current source locs will be identical when read in (typically this is *NOT* the case)
- DebugInfo = 0x02, ///< If set will output debug information, that can be reconstructed when read after being stored.
+ SourceLocation = 0x02, ///< If set will output SourceLoc information, that can be reconstructed when read after being stored.
ASTModule = 0x04, ///< If set will output AST modules - typically required, but potentially not desired (for example with obsfucation)
IRModule = 0x08, ///< If set will output IR modules - typically required
};
diff --git a/source/slang/slang-serialize.cpp b/source/slang/slang-serialize.cpp
index 34680d860..4f8fdc546 100644
--- a/source/slang/slang-serialize.cpp
+++ b/source/slang/slang-serialize.cpp
@@ -151,6 +151,58 @@ SerialClass* SerialClasses::_createSerialClass(const SerialClass* cls)
return dst;
}
+bool SerialClasses::isOk() const
+{
+ StringSlicePool pool(StringSlicePool::Style::Default);
+
+ for (const auto& classes : m_classesByTypeKind)
+ {
+ for (const SerialClass* cls : classes)
+ {
+ // It is possible potentially to have gaps
+ if (cls == nullptr)
+ {
+ continue;
+ }
+
+ if (cls->super && cls->super->typeKind != cls->typeKind)
+ {
+ // If has a super type, must be the same typeKind
+ return false;
+ }
+
+ // Make sure the fields are uniquely named
+
+ pool.clear();
+
+ {
+ const SerialClass* curCls = cls;
+
+ do
+ {
+ for (Index i = 0; i < curCls->fieldsCount; ++i)
+ {
+ const SerialField& field = curCls->fields[i];
+
+ StringSlicePool::Handle handle;
+ if (pool.findOrAdd(UnownedStringSlice(field.name), handle))
+ {
+ return false;
+ }
+ }
+
+ // Add the fields of the parent
+ curCls = curCls->super;
+ }
+ while (curCls);
+ }
+ }
+ }
+
+ return true;
+}
+
+
SerialClasses::SerialClasses():
m_arena(2048)
{
@@ -375,7 +427,7 @@ SerialIndex SerialWriter::addName(const Name* name)
return index;
}
-SerialIndex SerialWriter::_addArray(size_t elementSize, size_t alignment, const void* elements, Index elementCount)
+SerialIndex SerialWriter::addSerialArray(size_t elementSize, size_t alignment, const void* elements, Index elementCount)
{
typedef SerialInfo::ArrayEntry Entry;
@@ -699,12 +751,19 @@ String SerialReader::getString(SerialIndex index)
// Okay we need to construct as a string
UnownedStringSlice slice = getStringSlice(index);
- String string(slice);
- StringRepresentation* stringRep = string.getStringRepresentation();
- m_scope.add(stringRep);
+ StringRepresentation* stringRep = nullptr;
+
+ const Index length = slice.getLength();
+ if (length)
+ {
+ stringRep = StringRepresentation::createWithCapacityAndLength(length, length);
+ memcpy(stringRep->getData(), slice.begin(), length * sizeof(char));
+ addScope(stringRep);
+ }
+
m_objects[Index(index)] = stringRep;
- return string;
+ return String(stringRep);
}
Name* SerialReader::getName(SerialIndex index)
diff --git a/source/slang/slang-serialize.h b/source/slang/slang-serialize.h
index a48a7e216..ff402b35c 100644
--- a/source/slang/slang-serialize.h
+++ b/source/slang/slang-serialize.h
@@ -246,7 +246,9 @@ public:
const List<SerialPointer>& getObjects() const { return m_objects; }
/// Add an object to be kept in scope
- void addScope(const RefObject* obj) { m_scope.add(obj); }
+ void addScopeWithoutAddRef(const RefObject* obj) { m_scope.add(obj); }
+ /// Add obj with a reference
+ void addScope(const RefObject* obj) { const_cast<RefObject*>(obj)->addReference(); m_scope.add(obj); }
/// Used for attaching extra objects necessary for serializing
SerialExtraObjects& getExtraObjects() { return m_extraObjects; }
@@ -324,9 +326,21 @@ public:
SerialIndex writeObject(const NodeBase* ptr);
SerialIndex writeObject(const RefObject* ptr);
+ /// Add an array - may need to convert to serialized format
template <typename T>
SerialIndex addArray(const T* in, Index count);
+ template <typename NATIVE_TYPE>
+ /// Add an array where all the elements are already in serialized format (ie there is no need to do a conversion)
+ SerialIndex addSerialArray(const void* elements, Index elementCount)
+ {
+ typedef SerialTypeInfo<NATIVE_TYPE> TypeInfo;
+ return addSerialArray(sizeof(typename TypeInfo::SerialType), SerialTypeInfo<NATIVE_TYPE>::SerialAlignment, elements, elementCount);
+ }
+
+ /// Add an array where all the elements are already in serialized format (ie there is no need to do a conversion)
+ SerialIndex addSerialArray(size_t elementSize, size_t alignment, const void* elements, Index elementCount);
+
/// Add the string
SerialIndex addString(const UnownedStringSlice& slice) { return _addStringSlice(SerialTypeKind::String, m_sliceMap, slice); }
SerialIndex addString(const String& in);
@@ -362,8 +376,6 @@ protected:
SerialIndex _addStringSlice(SerialTypeKind typeKind, SliceMap& sliceMap, const UnownedStringSlice& slice);
- SerialIndex _addArray(size_t elementSize, size_t alignment, const void* elements, Index elementCount);
-
SerialIndex _add(const void* nativePtr, SerialInfo::Entry* entry)
{
m_entries.add(entry);
@@ -399,7 +411,7 @@ SerialIndex SerialWriter::addArray(const T* in, Index count)
if (std::is_same<T, ElementSerialType>::value)
{
// If they are the same we can just write out
- return _addArray(sizeof(T), SLANG_ALIGN_OF(ElementSerialType), in, count);
+ return addSerialArray(sizeof(T), SLANG_ALIGN_OF(ElementSerialType), in, count);
}
else
{
@@ -411,7 +423,7 @@ SerialIndex SerialWriter::addArray(const T* in, Index count)
{
ElementTypeInfo::toSerial(this, &in[i], &work[i]);
}
- return _addArray(sizeof(ElementSerialType), SLANG_ALIGN_OF(ElementSerialType), work.getBuffer(), count);
+ return addSerialArray(sizeof(ElementSerialType), SLANG_ALIGN_OF(ElementSerialType), work.getBuffer(), count);
}
}
@@ -478,7 +490,6 @@ struct SerialClass
class SerialClasses : public RefObject
{
public:
-
/// Will add it's own copy into m_classesByType
/// In process will calculate alignment, offset etc for fields
/// NOTE! the super set, *must* be an already added to this SerialClasses
@@ -492,6 +503,9 @@ public:
/// Returns true if this cls is *owned* by this SerialClasses
bool isOwned(const SerialClass* cls) const;
+ /// Returns true if the SerialClasses structure appears ok
+ bool isOk() const;
+
/// Get a serial class based on its type/subType
const SerialClass* getSerialClass(SerialTypeKind typeKind, SerialSubType subType) const
{
diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp
index ea17ad1d1..82e94fb6a 100644
--- a/source/slang/slang-syntax.cpp
+++ b/source/slang/slang-syntax.cpp
@@ -453,14 +453,14 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
}
}
- if (magicMod->name == "SamplerState")
+ if (magicMod->magicName == "SamplerState")
{
auto type = astBuilder->create<SamplerStateType>();
type->declRef = declRef;
type->flavor = SamplerStateFlavor(magicMod->tag);
return type;
}
- else if (magicMod->name == "Vector")
+ else if (magicMod->magicName == "Vector")
{
SLANG_ASSERT(subst && subst->args.getCount() == 2);
auto vecType = astBuilder->create<VectorExpressionType>();
@@ -469,14 +469,14 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
vecType->elementCount = ExtractGenericArgInteger(subst->args[1]);
return vecType;
}
- else if (magicMod->name == "Matrix")
+ else if (magicMod->magicName == "Matrix")
{
SLANG_ASSERT(subst && subst->args.getCount() == 3);
auto matType = astBuilder->create<MatrixExpressionType>();
matType->declRef = declRef;
return matType;
}
- else if (magicMod->name == "Texture")
+ else if (magicMod->magicName == "Texture")
{
SLANG_ASSERT(subst && subst->args.getCount() >= 1);
auto textureType = astBuilder->create<TextureType>(
@@ -485,7 +485,7 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
textureType->declRef = declRef;
return textureType;
}
- else if (magicMod->name == "TextureSampler")
+ else if (magicMod->magicName == "TextureSampler")
{
SLANG_ASSERT(subst && subst->args.getCount() >= 1);
auto textureType = astBuilder->create<TextureSamplerType>(
@@ -494,7 +494,7 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
textureType->declRef = declRef;
return textureType;
}
- else if (magicMod->name == "GLSLImageType")
+ else if (magicMod->magicName == "GLSLImageType")
{
SLANG_ASSERT(subst && subst->args.getCount() >= 1);
auto textureType = astBuilder->create<GLSLImageType>(
@@ -503,7 +503,7 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
textureType->declRef = declRef;
return textureType;
}
- else if (magicMod->name == "FeedbackType")
+ else if (magicMod->magicName == "FeedbackType")
{
SLANG_ASSERT(subst == nullptr);
auto type = astBuilder->create<FeedbackType>();
@@ -517,7 +517,7 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
// of this ridiculously slow `if` cascade.
#define CASE(n,T) \
- else if(magicMod->name == #n) { \
+ else if(magicMod->magicName == #n) { \
auto type = astBuilder->create<T>(); \
type->declRef = declRef; \
return type; \
@@ -529,7 +529,7 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
#undef CASE
#define CASE(n,T) \
- else if(magicMod->name == #n) { \
+ else if(magicMod->magicName == #n) { \
SLANG_ASSERT(subst && subst->args.getCount() == 1); \
auto type = astBuilder->create<T>(); \
type->elementType = ExtractGenericArgType(subst->args[0]); \
@@ -558,7 +558,7 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
// "magic" builtin types which have no generic parameters
#define CASE(n,T) \
- else if(magicMod->name == #n) { \
+ else if(magicMod->magicName == #n) { \
auto type = astBuilder->create<T>(); \
type->declRef = declRef; \
return type; \
@@ -575,7 +575,7 @@ Index getFilterCountImpl(const ReflectClassInfo& clsInfo, MemberFilterStyle filt
else
{
- auto classInfo = astBuilder->findSyntaxClass(magicMod->name.getUnownedSlice());
+ auto classInfo = astBuilder->findSyntaxClass(magicMod->magicName.getUnownedSlice());
if (!classInfo.classInfo)
{
SLANG_UNEXPECTED("unhandled type");
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 90ddf030c..a66441948 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -136,7 +136,6 @@ void Session::init()
// And the global ASTBuilder
globalAstBuilder = new ASTBuilder(m_sharedASTBuilder, "globalAstBuilder");
-
// Make sure our source manager is initialized
builtinSourceManager.initialize(nullptr, nullptr);
@@ -175,8 +174,41 @@ void Session::init()
slangLanguageScope = new Scope();
slangLanguageScope->nextSibling = hlslLanguageScope;
- addBuiltinSource(coreLanguageScope, "core", getCoreLibraryCode());
- addBuiltinSource(hlslLanguageScope, "hlsl", getHLSLLibraryCode());
+ if (false)
+ {
+ // Let's try loading serialized modules and adding them
+ _readBuiltinModule(coreLanguageScope, "core");
+ _readBuiltinModule(hlslLanguageScope, "hlsl");
+ }
+ else
+ {
+ addBuiltinSource(coreLanguageScope, "core", getCoreLibraryCode());
+ addBuiltinSource(hlslLanguageScope, "hlsl", getHLSLLibraryCode());
+
+ // Write out
+ if (false)
+ {
+ for (auto& pair : m_builtinLinkage->mapNameToLoadedModules)
+ {
+ const Name* moduleName = pair.Key;
+ Module* module = pair.Value;
+
+ // Set up options
+ SerialContainerUtil::WriteOptions options;
+ //options.optionFlags |= SerialOptionFlag::SourceLocation;
+ options.sourceManager = m_builtinLinkage->getSourceManager();
+
+ StringBuilder builder;
+ builder << moduleName->text << ".slang-module";
+
+ FileStream stream(builder.ProduceString(), FileMode::Create, FileAccess::Write, FileShare::ReadWrite);
+ if (SLANG_FAILED(SerialContainerUtil::write(module, options, &stream)))
+ {
+ SLANG_UNEXPECTED("Unable to load stdlib");
+ }
+ }
+ }
+ }
{
for (Index i = 0; i < Index(SourceLanguage::CountOf); ++i)
@@ -194,6 +226,88 @@ void Session::init()
m_languagePreludes[Index(SourceLanguage::HLSL)] = get_slang_hlsl_prelude();
}
+SlangResult Session::_readBuiltinModule(Scope* scope, String moduleName)
+{
+ StringBuilder moduleFilename;
+ moduleFilename << moduleName << ".slang-module";
+
+ RiffContainer riffContainer;
+ try
+ {
+ FileStream stream(moduleFilename.ProduceString(), FileMode::Open, FileAccess::Read, FileShare::ReadOnly);
+ // Load the riff container
+ SLANG_RETURN_ON_FAIL(RiffUtil::read(&stream, riffContainer));
+ }
+ catch (const IOException&)
+ {
+ return SLANG_FAIL;
+ }
+
+ // Load up the module
+
+ SerialContainerData containerData;
+
+ Linkage* linkage = getBuiltinLinkage();
+
+ NamePool* sessionNamePool = &namePool;
+ NamePool* linkageNamePool = linkage->getNamePool();
+
+ SerialContainerUtil::ReadOptions options;
+ options.namePool = linkageNamePool;
+ options.session = this;
+ options.sharedASTBuilder = linkage->getASTBuilder()->getSharedASTBuilder();
+ options.sourceManager = linkage->getSourceManager();
+ options.linkage = linkage;
+
+ // Hmm - don't have a suitable sink yet, so attempt to just not have one
+ options.sink = nullptr;
+
+ SLANG_RETURN_ON_FAIL(SerialContainerUtil::read(&riffContainer, options, containerData));
+
+ for (auto& srcModule : containerData.modules)
+ {
+ RefPtr<Module> module(new Module(linkage, srcModule.astBuilder));
+
+ ModuleDecl* moduleDecl = as<ModuleDecl>(srcModule.astRootNode);
+
+ if (moduleDecl)
+ {
+ if (isFromStdLib(moduleDecl))
+ {
+ registerBuiltinDecls(this, moduleDecl);
+ }
+
+ module->setModuleDecl(moduleDecl);
+ }
+
+ module->setIRModule(srcModule.irModule);
+
+ // Put in the loaded module map
+ linkage->mapNameToLoadedModules.Add(sessionNamePool->getName(moduleName), module);
+
+ // Add the resulting code to the appropriate scope
+ if (!scope->containerDecl)
+ {
+ // We are the first chunk of code to be loaded for this scope
+ scope->containerDecl = moduleDecl;
+ }
+ else
+ {
+ // We need to create a new scope to link into the whole thing
+ auto subScope = new Scope();
+ subScope->containerDecl = moduleDecl;
+ subScope->nextSibling = scope->nextSibling;
+ scope->nextSibling = subScope;
+ }
+
+ // We need to retain this AST so that we can use it in other code
+ // (Note that the `Scope` type does not retain the AST it points to)
+ stdlibModules.add(module);
+ }
+
+ return SLANG_OK;
+}
+
ISlangUnknown* Session::getInterface(const Guid& guid)
{
if(guid == IID_ISlangUnknown || guid == IID_IGlobalSession)
@@ -1240,7 +1354,7 @@ void FrontEndCompileRequest::generateIR()
options.compressionType = SerialCompressionType::None;
options.sourceManager = getSourceManager();
- options.optionFlags |= SerialOptionFlag::DebugInfo;
+ options.optionFlags |= SerialOptionFlag::SourceLocation;
// Verify debug information
if (SLANG_FAILED(SerialContainerUtil::verifyIRSerialize(irModule, getSession(), options)))
@@ -1950,11 +2064,19 @@ void FilePathDependencyList::addDependency(Module* module)
// Module
//
-Module::Module(Linkage* linkage)
+Module::Module(Linkage* linkage, ASTBuilder* astBuilder)
: ComponentType(linkage)
- , m_astBuilder(linkage->getASTBuilder()->getSharedASTBuilder(), "Module")
, m_mangledExportPool(StringSlicePool::Style::Empty)
{
+ if (astBuilder)
+ {
+ m_astBuilder = astBuilder;
+ }
+ else
+ {
+ m_astBuilder = new ASTBuilder(linkage->getASTBuilder()->getSharedASTBuilder(), "Module");
+ }
+
addModuleDependency(this);
}
@@ -2053,7 +2175,7 @@ void Module::_processFindDeclsExportSymbolsRec(Decl* decl)
return;
}
- // process `decl` itself
+ // If it's a container process it's children
if(auto containerDecl = as<ContainerDecl>(decl))
{
for (auto child : containerDecl->members)
@@ -2061,7 +2183,9 @@ void Module::_processFindDeclsExportSymbolsRec(Decl* decl)
_processFindDeclsExportSymbolsRec(child);
}
}
- else if (auto genericDecl = as<GenericDecl>(decl))
+
+ // GenericDecl is also a container, so do subsequent test
+ if (auto genericDecl = as<GenericDecl>(decl))
{
_processFindDeclsExportSymbolsRec(genericDecl->inner);
}