summaryrefslogtreecommitdiffstats
path: root/source/compiler-core
diff options
context:
space:
mode:
authorRonan <ro.cailleau@gmail.com>2025-04-25 00:48:37 +0200
committerGitHub <noreply@github.com>2025-04-24 15:48:37 -0700
commit5f632cd204b7a85f3a97b6c316c5a34f9fc8193e (patch)
tree7dc74fbe8c80870a4c485bbaa5765ff379914779 /source/compiler-core
parentc7ecf3039d2cc8680f1ea5f4bee2d13521ae34f7 (diff)
Implemented #pragma warning (#6748)
* Implemented #pragma warning Based on https://learn.microsoft.com/en-us/cpp/preprocessor/warning?view=msvc-170 * Make #pragma warning work with #includes. - SourceLoc are not sorted by inclusion order. - Construct a mapping from SourceLoc to "absolute locations" that are sorted by inclusion order (roughly represents a location in a raw file with all #include resolved). - The absolute location can be used in the pragma warning timeline * Added preprocessor #pragma warning tests. - Fixed #pragma warning (push / pop) SourceLoc - Fixed unused directiveLoc in #pragma warning parsing * #pragma warning: Added some comments and fixed some typos * Cleaned #pragma warning preprocessor implementation. --------- Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'source/compiler-core')
-rw-r--r--source/compiler-core/slang-diagnostic-sink.cpp14
-rw-r--r--source/compiler-core/slang-diagnostic-sink.h18
-rw-r--r--source/compiler-core/slang-lexer.cpp37
-rw-r--r--source/compiler-core/slang-lexer.h2
-rw-r--r--source/compiler-core/slang-source-loc.cpp40
-rw-r--r--source/compiler-core/slang-source-loc.h55
6 files changed, 159 insertions, 7 deletions
diff --git a/source/compiler-core/slang-diagnostic-sink.cpp b/source/compiler-core/slang-diagnostic-sink.cpp
index f9a7d9c88..28a98266a 100644
--- a/source/compiler-core/slang-diagnostic-sink.cpp
+++ b/source/compiler-core/slang-diagnostic-sink.cpp
@@ -612,10 +612,20 @@ bool DiagnosticSink::diagnoseImpl(
return true;
}
-Severity DiagnosticSink::getEffectiveMessageSeverity(DiagnosticInfo const& info)
+Severity DiagnosticSink::getEffectiveMessageSeverity(
+ DiagnosticInfo const& info,
+ SourceLoc const& location)
{
Severity effectiveSeverity = info.severity;
+ if (effectiveSeverity <= Severity::Warning && m_sourceWarningStateTracker)
+ {
+ effectiveSeverity = m_sourceWarningStateTracker->consumeWarningSeverity(
+ location,
+ info.id,
+ effectiveSeverity);
+ }
+
Severity* pSeverityOverride = m_severityOverrides.tryGetValue(info.id);
// See if there is an override
@@ -639,7 +649,7 @@ bool DiagnosticSink::diagnoseImpl(
DiagnosticArg const* args)
{
// Override the severity in the 'info' structure to pass it further into formatDiagnostics
- info.severity = getEffectiveMessageSeverity(info);
+ info.severity = getEffectiveMessageSeverity(info, pos);
if (info.severity == Severity::Disable)
return false;
diff --git a/source/compiler-core/slang-diagnostic-sink.h b/source/compiler-core/slang-diagnostic-sink.h
index 90f1bfccf..2d60747d9 100644
--- a/source/compiler-core/slang-diagnostic-sink.h
+++ b/source/compiler-core/slang-diagnostic-sink.h
@@ -81,6 +81,11 @@ public:
}
};
+struct SourceWarningStateTrackerBase : public RefObject
+{
+ virtual Severity consumeWarningSeverity(SourceLoc loc, int id, Severity severity) = 0;
+};
+
class Name;
void printDiagnosticArg(StringBuilder& sb, char const* str);
@@ -249,6 +254,15 @@ public:
void setParentSink(DiagnosticSink* parentSink) { m_parentSink = parentSink; }
DiagnosticSink* getParentSink() const { return m_parentSink; }
+ void setSourceWarningStateTracker(SourceWarningStateTrackerBase* ptr)
+ {
+ m_sourceWarningStateTracker = ptr;
+ }
+ RefPtr<SourceWarningStateTrackerBase> getSourceWarningStateTracker() const
+ {
+ return m_sourceWarningStateTracker;
+ }
+
/// Reset state.
/// Resets error counts. Resets the output buffer.
void reset();
@@ -283,7 +297,7 @@ protected:
DiagnosticArg const* args);
bool diagnoseImpl(DiagnosticInfo const& info, const UnownedStringSlice& formattedMessage);
- Severity getEffectiveMessageSeverity(DiagnosticInfo const& info);
+ Severity getEffectiveMessageSeverity(DiagnosticInfo const& info, SourceLoc const& location);
/// If set all diagnostics (as formatted by *this* sink, will be routed to the parent).
DiagnosticSink* m_parentSink = nullptr;
@@ -304,6 +318,8 @@ protected:
// Configuration that allows the user to control the severity of certain diagnostic messages
Dictionary<int, Severity> m_severityOverrides;
+
+ RefPtr<SourceWarningStateTrackerBase> m_sourceWarningStateTracker = nullptr;
};
/// An `ISlangWriter` that writes directly to a diagnostic sink.
diff --git a/source/compiler-core/slang-lexer.cpp b/source/compiler-core/slang-lexer.cpp
index 048c266ca..c2ee5cd69 100644
--- a/source/compiler-core/slang-lexer.cpp
+++ b/source/compiler-core/slang-lexer.cpp
@@ -374,9 +374,14 @@ static void _lexIdentifier(Lexer* lexer)
}
}
-static SourceLoc _getSourceLoc(Lexer* lexer)
+static SourceLoc _getSourceLoc(const Lexer& lexer, const char* it)
{
- return lexer->m_startLoc + (lexer->m_cursor - lexer->m_begin);
+ return lexer.m_startLoc + (it - lexer.m_begin);
+}
+
+static SourceLoc _getSourceLoc(const Lexer* lexer)
+{
+ return _getSourceLoc(*lexer, lexer->m_cursor);
}
static void _lexDigits(Lexer* lexer, int base)
@@ -1857,4 +1862,32 @@ TokenList Lexer::lexAllTokens()
return UnownedStringSlice(in.begin() + offset, in.begin() + offset + tok.charsCount);
}
+SourceLoc Lexer::findNextLineEnd(SourceLoc from, UInt& lineCount) const
+{
+ const char* it = m_begin + (from.getRaw() - m_startLoc.getRaw());
+ if (it >= m_begin && it < m_end)
+ {
+ while (it != m_end)
+ {
+ const char c = *it;
+ if (c == '\n' || c == '\r')
+ {
+ const char next = ((it + 1) == m_end) ? char(kEOF) : *(it + 1);
+ if ((next ^ c) == ('\n' ^ '\r'))
+ {
+ ++it;
+ }
+ --lineCount;
+ if (lineCount == 0)
+ {
+ SourceLoc res = _getSourceLoc(*this, it);
+ return res;
+ }
+ }
+ ++it;
+ }
+ }
+ return {};
+}
+
} // namespace Slang
diff --git a/source/compiler-core/slang-lexer.h b/source/compiler-core/slang-lexer.h
index 0152ff6f5..c39d130b7 100644
--- a/source/compiler-core/slang-lexer.h
+++ b/source/compiler-core/slang-lexer.h
@@ -149,6 +149,8 @@ struct Lexer
return ((m_lexerFlags & kLexerFlag_SuppressDiagnostics) == 0) ? m_sink : nullptr;
}
+ SourceLoc findNextLineEnd(SourceLoc from, UInt& lineCount) const;
+
SourceView* m_sourceView;
DiagnosticSink* m_sink;
NamePool* m_namePool;
diff --git a/source/compiler-core/slang-source-loc.cpp b/source/compiler-core/slang-source-loc.cpp
index 5058a1522..cfde5f1da 100644
--- a/source/compiler-core/slang-source-loc.cpp
+++ b/source/compiler-core/slang-source-loc.cpp
@@ -1018,4 +1018,44 @@ PathInfo SourceManager::getPathInfo(SourceLoc loc, SourceLocType type)
}
}
+SourceLoc::RawValue SourceView::getAbsoluteLocation(SourceLoc location) const
+{
+ AbsoluteSegment segment;
+ if (m_absSegments.getCount())
+ {
+ if (m_absSegments.getFirst().begin > location)
+ {
+ segment.begin = m_range.begin;
+ segment.absoluteBegin = m_absoluteLocationBase;
+ }
+ else
+ {
+ auto it = std::upper_bound(
+ m_absSegments.begin(),
+ m_absSegments.end(),
+ location,
+ [](SourceLoc const& loc, AbsoluteSegment const& seg)
+ { return loc < seg.begin; }) -
+ 1;
+ segment = *it;
+ }
+ }
+ else
+ {
+ segment = getLastSegment();
+ }
+ auto offset = SourceRange(segment.begin, location).getSize();
+ return segment.absoluteBegin + offset;
+}
+
+SourceLoc::RawValue SourceManager::getAbsoluteLocation(SourceLoc location) const
+{
+ SourceLoc::RawValue res = 0;
+ if (const SourceView* view = findSourceView(location))
+ {
+ res = view->getAbsoluteLocation(location);
+ }
+ return res;
+}
+
} // namespace Slang
diff --git a/source/compiler-core/slang-source-loc.h b/source/compiler-core/slang-source-loc.h
index c46c9063a..674ed2076 100644
--- a/source/compiler-core/slang-source-loc.h
+++ b/source/compiler-core/slang-source-loc.h
@@ -147,6 +147,10 @@ public:
SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const { return raw == rhs.raw; }
SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(raw == rhs.raw); }
+ SLANG_FORCE_INLINE bool operator<(const ThisType& rhs) const { return raw < rhs.raw; }
+ SLANG_FORCE_INLINE bool operator>(const ThisType& rhs) const { return raw > rhs.raw; }
+ SLANG_FORCE_INLINE bool operator<=(const ThisType& rhs) const { return raw <= rhs.raw; }
+ SLANG_FORCE_INLINE bool operator>=(const ThisType& rhs) const { return raw >= rhs.raw; }
RawValue getRaw() const { return raw; }
void setRaw(RawValue value) { raw = value; }
@@ -177,7 +181,7 @@ struct SourceRange
return rawLoc >= begin.getRaw() && rawLoc <= end.getRaw();
}
/// Get the total size
- UInt getSize() const { return UInt(end.getRaw() - begin.getRaw()); }
+ SourceLoc::RawValue getSize() const { return end.getRaw() - begin.getRaw(); }
/// Get the offset of a loc in this range
int getOffset(SourceLoc loc) const
@@ -190,7 +194,7 @@ struct SourceRange
SourceLoc getSourceLocFromOffset(uint32_t offset) const
{
SLANG_ASSERT(offset <= getSize());
- return begin + Int(offset);
+ return begin + offset;
}
SourceRange() {}
@@ -406,6 +410,48 @@ public:
///< locations. Relative to the line number in the underlying file.
};
+ // Represents a segment of a source.
+ // All SourceLoc in segment are linearly mapped relative to absoluteBegin
+ struct AbsoluteSegment
+ {
+ // SourceLoc in the file range.
+ SourceLoc begin = {};
+ // Location in the absolute mapping of locations ordered by includes.
+ SourceLoc::RawValue absoluteBegin = {};
+ };
+
+ // Set the base of the absolute location mapping for this SourceView.
+ void setAbsoluteLocationBase(SourceLoc::RawValue absLoc) { m_absoluteLocationBase = absLoc; }
+
+ AbsoluteSegment getLastSegment() const
+ {
+ AbsoluteSegment res;
+ if (m_absSegments.getCount())
+ {
+ res = m_absSegments.getLast();
+ }
+ else
+ {
+ res.begin = m_range.begin;
+ res.absoluteBegin = m_absoluteLocationBase;
+ }
+ return res;
+ }
+
+ // Add a segment of absolute mapping after the previous ones.
+ void addAbsoluteSegment(SourceLoc begin, SourceLoc::RawValue absoluteBegin)
+ {
+ SLANG_ASSERT(m_range.contains(begin));
+ SLANG_ASSERT(getLastSegment().begin < begin);
+ AbsoluteSegment seg;
+ seg.begin = begin;
+ seg.absoluteBegin = absoluteBegin;
+ m_absSegments.add(seg);
+ }
+
+ // Maps a SourceLoc inside this SourceView to a unique absolute location ordered by includes.
+ SourceLoc::RawValue getAbsoluteLocation(SourceLoc loc) const;
+
/// Given a sourceLoc finds the entry associated with it. If returns -1 then no entry is
/// associated with this location, and therefore the location should be interpreted as an offset
/// into the underlying sourceFile.
@@ -495,6 +541,8 @@ protected:
SourceFile* m_sourceFile; ///< The source file. Can hold the line breaks
List<Entry> m_entries; ///< An array entries describing how we should interpret a range,
///< starting from the start location.
+ SourceLoc::RawValue m_absoluteLocationBase = 0; ///< Base of the absolute location mapping.
+ List<AbsoluteSegment> m_absSegments; ///< Segments of absolute location mapping.
};
struct SourceManager
@@ -564,6 +612,9 @@ struct SourceManager
void addSourceFile(const String& uniqueIdentity, SourceFile* sourceFile);
void addSourceFileIfNotExist(const String& uniqueIdentity, SourceFile* sourceFile);
+ // Maps a SourceLoc to an absolute location
+ SourceLoc::RawValue getAbsoluteLocation(SourceLoc location) const;
+
/// Get the slice pool
StringSlicePool& getStringSlicePool() { return m_slicePool; }