aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex/PPExpressions.cpp
diff options
context:
space:
mode:
authorcor3ntin <corentinjabot@gmail.com>2025-06-03 14:22:54 +0200
committerGitHub <noreply@github.com>2025-06-03 14:22:54 +0200
commitc9968f4a04e055353f0667a16bcf34f1b3d855a5 (patch)
treeba967ced23066d241a59260ad270c3f2f416ec18 /clang/lib/Lex/PPExpressions.cpp
parentec96c0c072ef3f78813c378949c00e1c07aa44e5 (diff)
downloadllvm-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.cpp53
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;
+}