diff options
| author | Ronan <ro.cailleau@gmail.com> | 2025-04-25 00:48:37 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-24 15:48:37 -0700 |
| commit | 5f632cd204b7a85f3a97b6c316c5a34f9fc8193e (patch) | |
| tree | 7dc74fbe8c80870a4c485bbaa5765ff379914779 /source/compiler-core | |
| parent | c7ecf3039d2cc8680f1ea5f4bee2d13521ae34f7 (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.cpp | 14 | ||||
| -rw-r--r-- | source/compiler-core/slang-diagnostic-sink.h | 18 | ||||
| -rw-r--r-- | source/compiler-core/slang-lexer.cpp | 37 | ||||
| -rw-r--r-- | source/compiler-core/slang-lexer.h | 2 | ||||
| -rw-r--r-- | source/compiler-core/slang-source-loc.cpp | 40 | ||||
| -rw-r--r-- | source/compiler-core/slang-source-loc.h | 55 |
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; } |
