diff options
Diffstat (limited to 'clang/lib/Lex/PPMacroExpansion.cpp')
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 144 |
1 files changed, 117 insertions, 27 deletions
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index f3be2107f985..bbc271e5611e 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -37,8 +37,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -54,6 +52,7 @@ #include <cstddef> #include <cstring> #include <ctime> +#include <optional> #include <string> #include <tuple> #include <utility> @@ -285,7 +284,8 @@ void Preprocessor::dumpMacroInfo(const IdentifierInfo *II) { // Dump module macros. llvm::DenseSet<ModuleMacro*> Active; - for (auto *MM : State ? State->getActiveModuleMacros(*this, II) : None) + for (auto *MM : + State ? State->getActiveModuleMacros(*this, II) : std::nullopt) Active.insert(MM); llvm::DenseSet<ModuleMacro*> Visited; llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf.begin(), Leaf.end()); @@ -371,6 +371,8 @@ void Preprocessor::RegisterBuiltinMacros() { Ident__has_feature = RegisterBuiltinMacro(*this, "__has_feature"); Ident__has_extension = RegisterBuiltinMacro(*this, "__has_extension"); Ident__has_builtin = RegisterBuiltinMacro(*this, "__has_builtin"); + Ident__has_constexpr_builtin = + RegisterBuiltinMacro(*this, "__has_constexpr_builtin"); Ident__has_attribute = RegisterBuiltinMacro(*this, "__has_attribute"); if (!getLangOpts().CPlusPlus) Ident__has_c_attribute = RegisterBuiltinMacro(*this, "__has_c_attribute"); @@ -387,6 +389,10 @@ void Preprocessor::RegisterBuiltinMacros() { Ident__is_target_os = RegisterBuiltinMacro(*this, "__is_target_os"); Ident__is_target_environment = RegisterBuiltinMacro(*this, "__is_target_environment"); + Ident__is_target_variant_os = + RegisterBuiltinMacro(*this, "__is_target_variant_os"); + Ident__is_target_variant_environment = + RegisterBuiltinMacro(*this, "__is_target_variant_environment"); // Modules. Ident__building_module = RegisterBuiltinMacro(*this, "__building_module"); @@ -1081,8 +1087,15 @@ void Preprocessor::removeCachedMacroExpandedTokensOfLastLexer() { /// the identifier tokens inserted. static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, Preprocessor &PP) { - time_t TT = time(nullptr); - struct tm *TM = localtime(&TT); + time_t TT; + std::tm *TM; + if (PP.getPreprocessorOpts().SourceDateEpoch) { + TT = *PP.getPreprocessorOpts().SourceDateEpoch; + TM = std::gmtime(&TT); + } else { + TT = std::time(nullptr); + TM = std::localtime(&TT); + } static const char * const Months[] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" @@ -1091,8 +1104,11 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, { SmallString<32> TmpBuffer; llvm::raw_svector_ostream TmpStream(TmpBuffer); - TmpStream << llvm::format("\"%s %2d %4d\"", Months[TM->tm_mon], - TM->tm_mday, TM->tm_year + 1900); + if (TM) + TmpStream << llvm::format("\"%s %2d %4d\"", Months[TM->tm_mon], + TM->tm_mday, TM->tm_year + 1900); + else + TmpStream << "??? ?? ????"; Token TmpTok; TmpTok.startToken(); PP.CreateString(TmpStream.str(), TmpTok); @@ -1102,8 +1118,11 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, { SmallString<32> TmpBuffer; llvm::raw_svector_ostream TmpStream(TmpBuffer); - TmpStream << llvm::format("\"%02d:%02d:%02d\"", - TM->tm_hour, TM->tm_min, TM->tm_sec); + if (TM) + TmpStream << llvm::format("\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, + TM->tm_sec); + else + TmpStream << "??:??:??"; Token TmpTok; TmpTok.startToken(); PP.CreateString(TmpStream.str(), TmpTok); @@ -1230,7 +1249,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, return false; // Search include directories. - Optional<FileEntryRef> File = + OptionalFileEntryRef File = PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); @@ -1282,7 +1301,7 @@ static void EvaluateFeatureLikeBuiltinMacro(llvm::raw_svector_ostream& OS, unsigned ParenDepth = 1; SourceLocation LParenLoc = Tok.getLocation(); - llvm::Optional<int> Result; + std::optional<int> Result; Token ResultTok; bool SuppressDiagnostic = false; @@ -1326,10 +1345,10 @@ already_lexed: // The last ')' has been reached; return the value if one found or // a diagnostic and a dummy value. if (Result) { - OS << Result.value(); + OS << *Result; // For strict conformance to __has_cpp_attribute rules, use 'L' // suffix for dated literals. - if (Result.value() > 1) + if (*Result > 1) OS << 'L'; } else { OS << 0; @@ -1428,9 +1447,47 @@ static bool isTargetEnvironment(const TargetInfo &TI, const IdentifierInfo *II) { std::string EnvName = (llvm::Twine("---") + II->getName().lower()).str(); llvm::Triple Env(EnvName); + // The unknown environment is matched only if + // '__is_target_environment(unknown)' is used. + if (Env.getEnvironment() == llvm::Triple::UnknownEnvironment && + EnvName != "---unknown") + return false; return TI.getTriple().getEnvironment() == Env.getEnvironment(); } +/// Implements the __is_target_variant_os builtin macro. +static bool isTargetVariantOS(const TargetInfo &TI, const IdentifierInfo *II) { + if (TI.getTriple().isOSDarwin()) { + const llvm::Triple *VariantTriple = TI.getDarwinTargetVariantTriple(); + if (!VariantTriple) + return false; + + std::string OSName = + (llvm::Twine("unknown-unknown-") + II->getName().lower()).str(); + llvm::Triple OS(OSName); + if (OS.getOS() == llvm::Triple::Darwin) { + // Darwin matches macos, ios, etc. + return VariantTriple->isOSDarwin(); + } + return VariantTriple->getOS() == OS.getOS(); + } + return false; +} + +/// Implements the __is_target_variant_environment builtin macro. +static bool isTargetVariantEnvironment(const TargetInfo &TI, + const IdentifierInfo *II) { + if (TI.getTriple().isOSDarwin()) { + const llvm::Triple *VariantTriple = TI.getDarwinTargetVariantTriple(); + if (!VariantTriple) + return false; + std::string EnvName = (llvm::Twine("---") + II->getName().lower()).str(); + llvm::Triple Env(EnvName); + return VariantTriple->getEnvironment() == Env.getEnvironment(); + } + return false; +} + /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded /// as a builtin macro, handle it and return the next token as 'Tok'. void Preprocessor::ExpandBuiltinMacro(Token &Tok) { @@ -1556,22 +1613,24 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { Diag(Tok.getLocation(), diag::warn_pp_date_time); // MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime. - - // Get the file that we are lexing out of. If we're currently lexing from - // a macro, dig into the include stack. - const FileEntry *CurFile = nullptr; - PreprocessorLexer *TheLexer = getCurrentFileLexer(); - - if (TheLexer) - CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID()); - const char *Result; - if (CurFile) { - time_t TT = CurFile->getModificationTime(); - struct tm *TM = localtime(&TT); + if (getPreprocessorOpts().SourceDateEpoch) { + time_t TT = *getPreprocessorOpts().SourceDateEpoch; + std::tm *TM = std::gmtime(&TT); Result = asctime(TM); } else { - Result = "??? ??? ?? ??:??:?? ????\n"; + // Get the file that we are lexing out of. If we're currently lexing from + // a macro, dig into the include stack. + const FileEntry *CurFile = nullptr; + if (PreprocessorLexer *TheLexer = getCurrentFileLexer()) + CurFile = SourceMgr.getFileEntryForID(TheLexer->getFileID()); + if (CurFile) { + time_t TT = CurFile->getModificationTime(); + struct tm *TM = localtime(&TT); + Result = asctime(TM); + } else { + Result = "??? ??? ?? ??:??:?? ????\n"; + } } // Surround the string with " and strip the trailing newline. OS << '"' << StringRef(Result).drop_back() << '"'; @@ -1663,7 +1722,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { .Case("__array_rank", true) .Case("__array_extent", true) .Case("__reference_binds_to_temporary", true) - .Case("__underlying_type", true) +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) .Case("__" #Trait, true) +#include "clang/Basic/TransformTypeTraits.def" .Default(false); } else { return llvm::StringSwitch<bool>(II->getName()) @@ -1677,9 +1737,23 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { .Case("__is_target_vendor", true) .Case("__is_target_os", true) .Case("__is_target_environment", true) + .Case("__is_target_variant_os", true) + .Case("__is_target_variant_environment", true) .Default(false); } }); + } else if (II == Ident__has_constexpr_builtin) { + EvaluateFeatureLikeBuiltinMacro( + OS, Tok, II, *this, false, + [this](Token &Tok, bool &HasLexedNextToken) -> int { + IdentifierInfo *II = ExpectFeatureIdentifierInfo( + Tok, *this, diag::err_feature_check_malformed); + if (!II) + return false; + unsigned BuiltinOp = II->getBuiltinID(); + return BuiltinOp != 0 && + this->getBuiltinInfo().isConstantEvaluated(BuiltinOp); + }); } else if (II == Ident__is_identifier) { EvaluateFeatureLikeBuiltinMacro(OS, Tok, II, *this, false, [](Token &Tok, bool &HasLexedNextToken) -> int { @@ -1877,6 +1951,22 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { Tok, *this, diag::err_feature_check_malformed); return II && isTargetEnvironment(getTargetInfo(), II); }); + } else if (II == Ident__is_target_variant_os) { + EvaluateFeatureLikeBuiltinMacro( + OS, Tok, II, *this, false, + [this](Token &Tok, bool &HasLexedNextToken) -> int { + IdentifierInfo *II = ExpectFeatureIdentifierInfo( + Tok, *this, diag::err_feature_check_malformed); + return II && isTargetVariantOS(getTargetInfo(), II); + }); + } else if (II == Ident__is_target_variant_environment) { + EvaluateFeatureLikeBuiltinMacro( + OS, Tok, II, *this, false, + [this](Token &Tok, bool &HasLexedNextToken) -> int { + IdentifierInfo *II = ExpectFeatureIdentifierInfo( + Tok, *this, diag::err_feature_check_malformed); + return II && isTargetVariantEnvironment(getTargetInfo(), II); + }); } else { llvm_unreachable("Unknown identifier!"); } |