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.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;
+}