aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex/PPExpressions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Lex/PPExpressions.cpp')
-rw-r--r--clang/lib/Lex/PPExpressions.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index cf7e32b..118d4ae 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -979,3 +979,49 @@ 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 || Macro->getNumTokens() != 1 || !Macro->isObjectLike())
+ 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) {
+ unsigned Value;
+ // We don't use NumericParser to avoid diagnostics
+ if (!RevisionDate.consumeInteger(10, Value))
+ 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;
+}