diff options
author | cor3ntin <corentinjabot@gmail.com> | 2025-06-03 14:22:54 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-03 14:22:54 +0200 |
commit | c9968f4a04e055353f0667a16bcf34f1b3d855a5 (patch) | |
tree | ba967ced23066d241a59260ad270c3f2f416ec18 /clang/lib/Lex/PPExpressions.cpp | |
parent | ec96c0c072ef3f78813c378949c00e1c07aa44e5 (diff) | |
download | llvm-c9968f4a04e055353f0667a16bcf34f1b3d855a5.zip llvm-c9968f4a04e055353f0667a16bcf34f1b3d855a5.tar.gz llvm-c9968f4a04e055353f0667a16bcf34f1b3d855a5.tar.bz2 |
[Clang] Improve infrastructure for libstdc++ workarounds (Reland) (#142592)
Reland with debug traces to try to understand a bug that only happens on
one CI configuration
===
This introduces a way detect the libstdc++ version,
use that to enable workarounds.
The version is cached.
This should make it easier in the future to find and remove
these hacks.
I did not find the need for enabling a hack between or after
specific versions, so it's left as a future exercise.
We can extend this fature to other libraries as the need arise.
===
Diffstat (limited to 'clang/lib/Lex/PPExpressions.cpp')
-rw-r--r-- | clang/lib/Lex/PPExpressions.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index cf7e32b..7b1dbb2 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -979,3 +979,56 @@ Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro, return EvaluateDirectiveExpression(IfNDefMacro, Tok, EvaluatedDefined, CheckForEoD); } + +static std::optional<CXXStandardLibraryVersionInfo> +getCXXStandardLibraryVersion(Preprocessor &PP, StringRef MacroName, + CXXStandardLibraryVersionInfo::Library Lib) { + MacroInfo *Macro = PP.getMacroInfo(PP.getIdentifierInfo(MacroName)); + if (!Macro) + return std::nullopt; + + if (Macro->getNumTokens() != 1 || !Macro->isObjectLike()) { + Macro->dump(); + return std::nullopt; + } + + const Token &RevisionDateTok = Macro->getReplacementToken(0); + + bool Invalid = false; + llvm::SmallVector<char, 10> Buffer; + llvm::StringRef RevisionDate = + PP.getSpelling(RevisionDateTok, Buffer, &Invalid); + if (!Invalid) { + llvm::errs() << RevisionDate << "\n"; + unsigned Value; + // We don't use NumericParser to avoid diagnostics + if (!RevisionDate.consumeInteger(10, Value)) { + llvm::errs() << "Value:" << Value << "\n"; + return CXXStandardLibraryVersionInfo{Lib, Value}; + } + } + return CXXStandardLibraryVersionInfo{CXXStandardLibraryVersionInfo::Unknown, + 0}; +} + +std::optional<unsigned> Preprocessor::getStdLibCxxVersion() { + if (!CXXStandardLibraryVersion) + CXXStandardLibraryVersion = getCXXStandardLibraryVersion( + *this, "__GLIBCXX__", CXXStandardLibraryVersionInfo::LibStdCXX); + if (!CXXStandardLibraryVersion) + return std::nullopt; + + if (CXXStandardLibraryVersion->Lib == + CXXStandardLibraryVersionInfo::LibStdCXX) + return CXXStandardLibraryVersion->Version; + return std::nullopt; +} + +bool Preprocessor::NeedsStdLibCxxWorkaroundBefore(unsigned FixedVersion) { + assert(FixedVersion >= 2000'00'00 && FixedVersion <= 2100'00'00 && + "invalid value for __GLIBCXX__"); + std::optional<unsigned> Ver = getStdLibCxxVersion(); + if (!Ver) + return false; + return *Ver < FixedVersion; +} |