diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
57 files changed, 2219 insertions, 1037 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp index ed7f87c9b95c..a3210ba09068 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp @@ -107,6 +107,22 @@ void Builtin::Context::forgetBuiltin(unsigned ID, IdentifierTable &Table) { Table.get(getRecord(ID).Name).setBuiltinID(0); } +unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const { + const char *WidthPos = ::strchr(getRecord(ID).Attributes, 'V'); + if (!WidthPos) + return 0; + + ++WidthPos; + assert(*WidthPos == ':' && + "Vector width specifier must be followed by a ':'"); + ++WidthPos; + + char *EndPos; + unsigned Width = ::strtol(WidthPos, &EndPos, 10); + assert(*EndPos == ':' && "Vector width specific must end with a ':'"); + return Width; +} + bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg, const char *Fmt) const { assert(Fmt && "Not passed a format string"); @@ -139,3 +155,10 @@ bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg) { return isLike(ID, FormatIdx, HasVAListArg, "sS"); } + +bool Builtin::Context::canBeRedeclared(unsigned ID) const { + return ID == Builtin::NotBuiltin || + ID == Builtin::BI__va_start || + (!hasReferenceArgsOrResult(ID) && + !hasCustomTypechecking(ID)); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/Cuda.cpp b/contrib/llvm/tools/clang/lib/Basic/Cuda.cpp index 58b99a3b58cb..dc7e61c02b24 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Cuda.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Cuda.cpp @@ -18,12 +18,18 @@ const char *CudaVersionToString(CudaVersion V) { return "8.0"; case CudaVersion::CUDA_90: return "9.0"; + case CudaVersion::CUDA_91: + return "9.1"; + case CudaVersion::CUDA_92: + return "9.2"; } llvm_unreachable("invalid enum"); } const char *CudaArchToString(CudaArch A) { switch (A) { + case CudaArch::LAST: + break; case CudaArch::UNKNOWN: return "unknown"; case CudaArch::SM_20: @@ -52,6 +58,34 @@ const char *CudaArchToString(CudaArch A) { return "sm_62"; case CudaArch::SM_70: return "sm_70"; + case CudaArch::SM_72: + return "sm_72"; + case CudaArch::GFX600: // tahiti + return "gfx600"; + case CudaArch::GFX601: // pitcairn, verde, oland,hainan + return "gfx601"; + case CudaArch::GFX700: // kaveri + return "gfx700"; + case CudaArch::GFX701: // hawaii + return "gfx701"; + case CudaArch::GFX702: // 290,290x,R390,R390x + return "gfx702"; + case CudaArch::GFX703: // kabini mullins + return "gfx703"; + case CudaArch::GFX704: // bonaire + return "gfx704"; + case CudaArch::GFX801: // carrizo + return "gfx801"; + case CudaArch::GFX802: // tonga,iceland + return "gfx802"; + case CudaArch::GFX803: // fiji,polaris10 + return "gfx803"; + case CudaArch::GFX810: // stoney + return "gfx810"; + case CudaArch::GFX900: // vega, instinct + return "gfx900"; + case CudaArch::GFX902: // TBA + return "gfx902"; } llvm_unreachable("invalid enum"); } @@ -71,6 +105,20 @@ CudaArch StringToCudaArch(llvm::StringRef S) { .Case("sm_61", CudaArch::SM_61) .Case("sm_62", CudaArch::SM_62) .Case("sm_70", CudaArch::SM_70) + .Case("sm_72", CudaArch::SM_72) + .Case("gfx600", CudaArch::GFX600) + .Case("gfx601", CudaArch::GFX601) + .Case("gfx700", CudaArch::GFX700) + .Case("gfx701", CudaArch::GFX701) + .Case("gfx702", CudaArch::GFX702) + .Case("gfx703", CudaArch::GFX703) + .Case("gfx704", CudaArch::GFX704) + .Case("gfx801", CudaArch::GFX801) + .Case("gfx802", CudaArch::GFX802) + .Case("gfx803", CudaArch::GFX803) + .Case("gfx810", CudaArch::GFX810) + .Case("gfx900", CudaArch::GFX900) + .Case("gfx902", CudaArch::GFX902) .Default(CudaArch::UNKNOWN); } @@ -102,6 +150,10 @@ const char *CudaVirtualArchToString(CudaVirtualArch A) { return "compute_62"; case CudaVirtualArch::COMPUTE_70: return "compute_70"; + case CudaVirtualArch::COMPUTE_72: + return "compute_72"; + case CudaVirtualArch::COMPUTE_AMDGCN: + return "compute_amdgcn"; } llvm_unreachable("invalid enum"); } @@ -120,11 +172,15 @@ CudaVirtualArch StringToCudaVirtualArch(llvm::StringRef S) { .Case("compute_61", CudaVirtualArch::COMPUTE_61) .Case("compute_62", CudaVirtualArch::COMPUTE_62) .Case("compute_70", CudaVirtualArch::COMPUTE_70) + .Case("compute_72", CudaVirtualArch::COMPUTE_72) + .Case("compute_amdgcn", CudaVirtualArch::COMPUTE_AMDGCN) .Default(CudaVirtualArch::UNKNOWN); } CudaVirtualArch VirtualArchForCudaArch(CudaArch A) { switch (A) { + case CudaArch::LAST: + break; case CudaArch::UNKNOWN: return CudaVirtualArch::UNKNOWN; case CudaArch::SM_20: @@ -152,12 +208,30 @@ CudaVirtualArch VirtualArchForCudaArch(CudaArch A) { return CudaVirtualArch::COMPUTE_62; case CudaArch::SM_70: return CudaVirtualArch::COMPUTE_70; + case CudaArch::SM_72: + return CudaVirtualArch::COMPUTE_72; + case CudaArch::GFX600: + case CudaArch::GFX601: + case CudaArch::GFX700: + case CudaArch::GFX701: + case CudaArch::GFX702: + case CudaArch::GFX703: + case CudaArch::GFX704: + case CudaArch::GFX801: + case CudaArch::GFX802: + case CudaArch::GFX803: + case CudaArch::GFX810: + case CudaArch::GFX900: + case CudaArch::GFX902: + return CudaVirtualArch::COMPUTE_AMDGCN; } llvm_unreachable("invalid enum"); } CudaVersion MinVersionForCudaArch(CudaArch A) { switch (A) { + case CudaArch::LAST: + break; case CudaArch::UNKNOWN: return CudaVersion::UNKNOWN; case CudaArch::SM_20: @@ -176,6 +250,22 @@ CudaVersion MinVersionForCudaArch(CudaArch A) { return CudaVersion::CUDA_80; case CudaArch::SM_70: return CudaVersion::CUDA_90; + case CudaArch::SM_72: + return CudaVersion::CUDA_91; + case CudaArch::GFX600: + case CudaArch::GFX601: + case CudaArch::GFX700: + case CudaArch::GFX701: + case CudaArch::GFX702: + case CudaArch::GFX703: + case CudaArch::GFX704: + case CudaArch::GFX801: + case CudaArch::GFX802: + case CudaArch::GFX803: + case CudaArch::GFX810: + case CudaArch::GFX900: + case CudaArch::GFX902: + return CudaVersion::CUDA_70; } llvm_unreachable("invalid enum"); } @@ -186,6 +276,19 @@ CudaVersion MaxVersionForCudaArch(CudaArch A) { return CudaVersion::UNKNOWN; case CudaArch::SM_20: case CudaArch::SM_21: + case CudaArch::GFX600: + case CudaArch::GFX601: + case CudaArch::GFX700: + case CudaArch::GFX701: + case CudaArch::GFX702: + case CudaArch::GFX703: + case CudaArch::GFX704: + case CudaArch::GFX801: + case CudaArch::GFX802: + case CudaArch::GFX803: + case CudaArch::GFX810: + case CudaArch::GFX900: + case CudaArch::GFX902: return CudaVersion::CUDA_80; default: return CudaVersion::LATEST; diff --git a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp index 26baa838f8c6..519e835e32a2 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp @@ -1,4 +1,4 @@ -//===--- Diagnostic.cpp - C Language Family Diagnostic Handling -----------===// +//===- Diagnostic.cpp - C Language Family Diagnostic Handling -------------===// // // The LLVM Compiler Infrastructure // @@ -14,15 +14,30 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/DiagnosticError.h" +#include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Specifiers.h" +#include "clang/Basic/TokenKinds.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Locale.h" #include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <cstring> +#include <limits> +#include <string> +#include <utility> +#include <vector> using namespace clang; @@ -57,27 +72,13 @@ static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, Output.append(Str.begin(), Str.end()); } -DiagnosticsEngine::DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> diags, - DiagnosticOptions *DiagOpts, - DiagnosticConsumer *client, - bool ShouldOwnClient) - : Diags(std::move(diags)), DiagOpts(DiagOpts), Client(nullptr), - SourceMgr(nullptr) { +DiagnosticsEngine::DiagnosticsEngine( + IntrusiveRefCntPtr<DiagnosticIDs> diags, + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, DiagnosticConsumer *client, + bool ShouldOwnClient) + : Diags(std::move(diags)), DiagOpts(std::move(DiagOpts)) { setClient(client, ShouldOwnClient); ArgToStringFn = DummyArgToStringFn; - ArgToStringCookie = nullptr; - - AllExtensionsSilenced = 0; - SuppressAfterFatalError = true; - SuppressAllDiagnostics = false; - ElideType = true; - PrintTemplateTree = false; - ShowColors = false; - ShowOverloads = Ovl_All; - - ErrorLimit = 0; - TemplateBacktraceLimit = 0; - ConstexprBacktraceLimit = 0; Reset(); } @@ -121,7 +122,7 @@ void DiagnosticsEngine::Reset() { TrapNumErrorsOccurred = 0; TrapNumUnrecoverableErrorsOccurred = 0; - CurDiagID = ~0U; + CurDiagID = std::numeric_limits<unsigned>::max(); LastDiagLevel = DiagnosticIDs::Ignored; DelayedDiagID = 0; @@ -152,8 +153,7 @@ void DiagnosticsEngine::ReportDelayed() { Report(ID) << DelayedDiagArg1 << DelayedDiagArg2; } -void DiagnosticsEngine::DiagStateMap::appendFirst( - DiagState *State) { +void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) { assert(Files.empty() && "not first"); FirstDiagState = CurDiagState = State; CurDiagStateLoc = SourceLocation(); @@ -236,6 +236,96 @@ DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr, return &F; } +void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr, + StringRef DiagName) const { + llvm::errs() << "diagnostic state at "; + CurDiagStateLoc.dump(SrcMgr); + llvm::errs() << ": " << CurDiagState << "\n"; + + for (auto &F : Files) { + FileID ID = F.first; + File &File = F.second; + + bool PrintedOuterHeading = false; + auto PrintOuterHeading = [&] { + if (PrintedOuterHeading) return; + PrintedOuterHeading = true; + + llvm::errs() << "File " << &File << " <FileID " << ID.getHashValue() + << ">: " << SrcMgr.getBuffer(ID)->getBufferIdentifier(); + if (F.second.Parent) { + std::pair<FileID, unsigned> Decomp = + SrcMgr.getDecomposedIncludedLoc(ID); + assert(File.ParentOffset == Decomp.second); + llvm::errs() << " parent " << File.Parent << " <FileID " + << Decomp.first.getHashValue() << "> "; + SrcMgr.getLocForStartOfFile(Decomp.first) + .getLocWithOffset(Decomp.second) + .dump(SrcMgr); + } + if (File.HasLocalTransitions) + llvm::errs() << " has_local_transitions"; + llvm::errs() << "\n"; + }; + + if (DiagName.empty()) + PrintOuterHeading(); + + for (DiagStatePoint &Transition : File.StateTransitions) { + bool PrintedInnerHeading = false; + auto PrintInnerHeading = [&] { + if (PrintedInnerHeading) return; + PrintedInnerHeading = true; + + PrintOuterHeading(); + llvm::errs() << " "; + SrcMgr.getLocForStartOfFile(ID) + .getLocWithOffset(Transition.Offset) + .dump(SrcMgr); + llvm::errs() << ": state " << Transition.State << ":\n"; + }; + + if (DiagName.empty()) + PrintInnerHeading(); + + for (auto &Mapping : *Transition.State) { + StringRef Option = + DiagnosticIDs::getWarningOptionForDiag(Mapping.first); + if (!DiagName.empty() && DiagName != Option) + continue; + + PrintInnerHeading(); + llvm::errs() << " "; + if (Option.empty()) + llvm::errs() << "<unknown " << Mapping.first << ">"; + else + llvm::errs() << Option; + llvm::errs() << ": "; + + switch (Mapping.second.getSeverity()) { + case diag::Severity::Ignored: llvm::errs() << "ignored"; break; + case diag::Severity::Remark: llvm::errs() << "remark"; break; + case diag::Severity::Warning: llvm::errs() << "warning"; break; + case diag::Severity::Error: llvm::errs() << "error"; break; + case diag::Severity::Fatal: llvm::errs() << "fatal"; break; + } + + if (!Mapping.second.isUser()) + llvm::errs() << " default"; + if (Mapping.second.isPragma()) + llvm::errs() << " pragma"; + if (Mapping.second.hasNoWarningAsError()) + llvm::errs() << " no-error"; + if (Mapping.second.hasNoErrorAsFatal()) + llvm::errs() << " no-fatal"; + if (Mapping.second.wasUpgradedFromWarning()) + llvm::errs() << " overruled"; + llvm::errs() << "\n"; + } + } + } +} + void DiagnosticsEngine::PushDiagStatePoint(DiagState *State, SourceLocation Loc) { assert(Loc.isValid() && "Adding invalid loc point"); @@ -373,7 +463,8 @@ void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor, } void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { - assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!"); + assert(CurDiagID == std::numeric_limits<unsigned>::max() && + "Multiple diagnostics in flight at once!"); CurDiagLoc = storedDiag.getLocation(); CurDiagID = storedDiag.getID(); @@ -394,7 +485,7 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { ++NumWarnings; } - CurDiagID = ~0U; + CurDiagID = std::numeric_limits<unsigned>::max(); } bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) { @@ -429,8 +520,7 @@ bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) { return Emitted; } - -DiagnosticConsumer::~DiagnosticConsumer() {} +DiagnosticConsumer::~DiagnosticConsumer() = default; void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) { @@ -447,7 +537,7 @@ void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, template <std::size_t StrLen> static bool ModifierIs(const char *Modifier, unsigned ModifierLen, const char (&Str)[StrLen]) { - return StrLen-1 == ModifierLen && !memcmp(Modifier, Str, StrLen-1); + return StrLen-1 == ModifierLen && memcmp(Modifier, Str, StrLen-1) == 0; } /// ScanForward - Scans forward, looking for the given character, skipping @@ -527,7 +617,6 @@ static void HandleOrdinalModifier(unsigned ValNo, Out << ValNo << llvm::getOrdinalSuffix(ValNo); } - /// PluralNumber - Parse an unsigned integer and advance Start. static unsigned PluralNumber(const char *&Start, const char *End) { // Programming 101: Parse a decimal number :-) @@ -563,7 +652,7 @@ static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) { if (*Start == ':') return true; - while (1) { + while (true) { char C = *Start; if (C == '%') { // Modulo expression @@ -628,7 +717,7 @@ static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo, const char *Argument, unsigned ArgumentLen, SmallVectorImpl<char> &OutStr) { const char *ArgumentEnd = Argument + ArgumentLen; - while (1) { + while (true) { assert(Argument < ArgumentEnd && "Plural expression didn't match."); const char *ExprEnd = Argument; while (*ExprEnd != ':') { @@ -648,7 +737,7 @@ static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo, } } -/// \brief Returns the friendly description for a token kind that will appear +/// Returns the friendly description for a token kind that will appear /// without quotes in diagnostic messages. These strings may be translatable in /// future. static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) { @@ -679,7 +768,6 @@ FormatDiagnostic(SmallVectorImpl<char> &OutStr) const { void Diagnostic:: FormatDiagnostic(const char *DiagStr, const char *DiagEnd, SmallVectorImpl<char> &OutStr) const { - // When the diagnostic string is only "%0", the entire string is being given // by an outside source. Remove unprintable characters from this string // and skip all the other string processing. @@ -899,7 +987,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, FormattedArgs, OutStr, QualTypeVals); break; - case DiagnosticsEngine::ak_qualtype_pair: + case DiagnosticsEngine::ak_qualtype_pair: { // Create a struct with all the info needed for printing. TemplateDiffTypes TDT; TDT.FromType = getRawArg(ArgNo); @@ -967,6 +1055,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); break; } + } // Remember this argument info for subsequent formatting operations. Turn // std::strings into a null terminated string to make it be the same case as @@ -978,7 +1067,6 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, else FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string, (intptr_t)getArgStdStr(ArgNo).c_str())); - } // Append the type tree to the end of the diagnostics. @@ -987,12 +1075,11 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, StringRef Message) - : ID(ID), Level(Level), Loc(), Message(Message) { } + : ID(ID), Level(Level), Message(Message) {} StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info) - : ID(Info.getID()), Level(Level) -{ + : ID(Info.getID()), Level(Level) { assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) && "Valid source location without setting a source manager for diagnostic"); if (Info.getLocation().isValid()) @@ -1008,8 +1095,8 @@ StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, StringRef Message, FullSourceLoc Loc, ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> FixIts) - : ID(ID), Level(Level), Loc(Loc), Message(Message), - Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end()) + : ID(ID), Level(Level), Loc(Loc), Message(Message), + Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end()) { } @@ -1019,9 +1106,9 @@ StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, /// reported by DiagnosticsEngine. bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; } -void IgnoringDiagConsumer::anchor() { } +void IgnoringDiagConsumer::anchor() {} -ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() {} +ForwardingDiagnosticConsumer::~ForwardingDiagnosticConsumer() = default; void ForwardingDiagnosticConsumer::HandleDiagnostic( DiagnosticsEngine::Level DiagLevel, diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp index c4c425d9eb1d..697de68a5afb 100644 --- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp @@ -340,7 +340,7 @@ bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) { getBuiltinDiagClass(DiagID) != CLASS_ERROR; } -/// \brief Determine whether the given built-in diagnostic ID is a +/// Determine whether the given built-in diagnostic ID is a /// Note. bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) { return DiagID < diag::DIAG_UPPER_LIMIT && @@ -412,7 +412,7 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag)); } -/// \brief Based on the way the client configured the Diagnostic +/// Based on the way the client configured the Diagnostic /// object, classify the specified diagnostic ID into a Level, consumable by /// the DiagnosticClient. /// @@ -470,7 +470,7 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, Result = diag::Severity::Error; } - // If -Wfatal-errors is enabled, map errors to fatal unless explicity + // If -Wfatal-errors is enabled, map errors to fatal unless explicitly // disabled. if (Result == diag::Severity::Error) { if (State->ErrorsAsFatal && !Mapping.hasNoErrorAsFatal()) diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp index 93c2196ca979..ebd9bb45f380 100644 --- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp @@ -1,4 +1,4 @@ -//===--- DiagnosticOptions.cpp - C Language Family Diagnostic Handling ----===// +//===- DiagnosticOptions.cpp - C Language Family Diagnostic Handling ------===// // // The LLVM Compiler Infrastructure // @@ -13,6 +13,7 @@ #include "clang/Basic/DiagnosticOptions.h" #include "llvm/Support/raw_ostream.h" +#include <type_traits> namespace clang { @@ -21,4 +22,4 @@ raw_ostream &operator<<(raw_ostream &Out, DiagnosticLevelMask M) { return Out << static_cast<UT>(M); } -} // end namespace clang +} // namespace clang diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp index a3e226d6cc96..7e2d01c4981d 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp @@ -102,7 +102,7 @@ void FileManager::clearStatCaches() { StatCache.reset(); } -/// \brief Retrieve the directory that the given file name resides in. +/// Retrieve the directory that the given file name resides in. /// Filename can point to either a real file or a virtual file. static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr, StringRef Filename, @@ -157,7 +157,7 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName, DirName != llvm::sys::path::root_path(DirName) && llvm::sys::path::is_separator(DirName.back())) DirName = DirName.substr(0, DirName.size()-1); -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 // Fixing a problem with "clang C:test.c" on Windows. // Stat("C:") does not recognize "C:" as a valid directory std::string DirNameStr; @@ -450,13 +450,13 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, } llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> -FileManager::getBufferForFile(StringRef Filename) { +FileManager::getBufferForFile(StringRef Filename, bool isVolatile) { if (FileSystemOpts.WorkingDir.empty()) - return FS->getBufferForFile(Filename); + return FS->getBufferForFile(Filename, -1, true, isVolatile); SmallString<128> FilePath(Filename); FixupRelativePath(FilePath); - return FS->getBufferForFile(FilePath.c_str()); + return FS->getBufferForFile(FilePath.c_str(), -1, true, isVolatile); } /// getStatValue - Get the 'stat' information for the specified path, @@ -534,23 +534,9 @@ StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { StringRef CanonicalName(Dir->getName()); -#ifdef LLVM_ON_UNIX - char CanonicalNameBuf[PATH_MAX]; - if (realpath(Dir->getName().str().c_str(), CanonicalNameBuf)) + SmallString<4096> CanonicalNameBuf; + if (!FS->getRealPath(Dir->getName(), CanonicalNameBuf)) CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage); -#else - SmallString<256> CanonicalNameBuf(CanonicalName); - llvm::sys::fs::make_absolute(CanonicalNameBuf); - llvm::sys::path::native(CanonicalNameBuf); - // We've run into needing to remove '..' here in the wild though, so - // remove it. - // On Windows, symlinks are significantly less prevalent, so removing - // '..' is pretty safe. - // Ideally we'd have an equivalent of `realpath` and could implement - // sys::fs::canonical across all the platforms. - llvm::sys::path::remove_dots(CanonicalNameBuf, /* remove_dot_dot */ true); - CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage); -#endif CanonicalDirNames.insert(std::make_pair(Dir, CanonicalName)); return CanonicalName; diff --git a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp index 799df1d3c3a6..ebee32670e0a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp @@ -1,4 +1,4 @@ -//===--- FileSystemStatCache.cpp - Caching for 'stat' calls ---------------===// +//===- FileSystemStatCache.cpp - Caching for 'stat' calls -----------------===// // // The LLVM Compiler Infrastructure // @@ -13,11 +13,14 @@ #include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/VirtualFileSystem.h" +#include "llvm/Support/Chrono.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/Path.h" +#include <utility> using namespace clang; -void FileSystemStatCache::anchor() { } +void FileSystemStatCache::anchor() {} static void copyStatusToFileData(const vfs::Status &Status, FileData &Data) { diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp index 2bed531ae3d7..2fef481ae2c5 100644 --- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp @@ -65,7 +65,7 @@ IdentifierInfoLookup::~IdentifierInfoLookup() = default; namespace { -/// \brief A simple identifier lookup iterator that represents an +/// A simple identifier lookup iterator that represents an /// empty sequence of identifiers. class EmptyLookupIterator : public IdentifierIterator { @@ -79,16 +79,16 @@ IdentifierIterator *IdentifierInfoLookup::getIdentifiers() { return new EmptyLookupIterator(); } +IdentifierTable::IdentifierTable(IdentifierInfoLookup *ExternalLookup) + : HashTable(8192), // Start with space for 8K identifiers. + ExternalLookup(ExternalLookup) {} + IdentifierTable::IdentifierTable(const LangOptions &LangOpts, - IdentifierInfoLookup* externalLookup) - : HashTable(8192), // Start with space for 8K identifiers. - ExternalLookup(externalLookup) { + IdentifierInfoLookup *ExternalLookup) + : IdentifierTable(ExternalLookup) { // Populate the identifier table with info about keywords for the current // language. AddKeywords(LangOpts); - - // Add the '_experimental_modules_import' contextual keyword. - get("import").setModulesImport(true); } //===----------------------------------------------------------------------===// @@ -108,25 +108,27 @@ namespace { KEYALTIVEC = 0x40, KEYNOCXX = 0x80, KEYBORLAND = 0x100, - KEYOPENCL = 0x200, + KEYOPENCLC = 0x200, KEYC11 = 0x400, KEYARC = 0x800, KEYNOMS18 = 0x01000, KEYNOOPENCL = 0x02000, WCHARSUPPORT = 0x04000, HALFSUPPORT = 0x08000, - KEYCONCEPTS = 0x10000, - KEYOBJC2 = 0x20000, - KEYZVECTOR = 0x40000, - KEYCOROUTINES = 0x80000, - KEYMODULES = 0x100000, - KEYCXX2A = 0x200000, + CHAR8SUPPORT = 0x10000, + KEYCONCEPTS = 0x20000, + KEYOBJC2 = 0x40000, + KEYZVECTOR = 0x80000, + KEYCOROUTINES = 0x100000, + KEYMODULES = 0x200000, + KEYCXX2A = 0x400000, + KEYOPENCLCXX = 0x800000, KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A, - KEYALL = (0x3fffff & ~KEYNOMS18 & + KEYALL = (0xffffff & ~KEYNOMS18 & ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude. }; - /// \brief How a keyword is treated in the selected standard. + /// How a keyword is treated in the selected standard. enum KeywordStatus { KS_Disabled, // Disabled KS_Extension, // Is an extension @@ -136,7 +138,7 @@ namespace { } // namespace -/// \brief Translates flags as specified in TokenKinds.def into keyword status +/// Translates flags as specified in TokenKinds.def into keyword status /// in the given language standard. static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, unsigned Flags) { @@ -151,8 +153,11 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, if (LangOpts.Bool && (Flags & BOOLSUPPORT)) return KS_Enabled; if (LangOpts.Half && (Flags & HALFSUPPORT)) return KS_Enabled; if (LangOpts.WChar && (Flags & WCHARSUPPORT)) return KS_Enabled; + if (LangOpts.Char8 && (Flags & CHAR8SUPPORT)) return KS_Enabled; if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) return KS_Enabled; - if (LangOpts.OpenCL && (Flags & KEYOPENCL)) return KS_Enabled; + if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLC)) + return KS_Enabled; + if (LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLCXX)) return KS_Enabled; if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) return KS_Enabled; if (LangOpts.C11 && (Flags & KEYC11)) return KS_Enabled; // We treat bridge casts as objective-C keywords so we can warn on them @@ -237,9 +242,12 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { if (LangOpts.DeclSpecKeyword) AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this); + + // Add the '_experimental_modules_import' contextual keyword. + get("import").setModulesImport(true); } -/// \brief Checks if the specified token kind represents a keyword in the +/// Checks if the specified token kind represents a keyword in the /// specified language. /// \returns Status of the keyword in the language. static KeywordStatus getTokenKwStatus(const LangOptions &LangOpts, @@ -252,7 +260,7 @@ static KeywordStatus getTokenKwStatus(const LangOptions &LangOpts, } } -/// \brief Returns true if the identifier represents a keyword in the +/// Returns true if the identifier represents a keyword in the /// specified language. bool IdentifierInfo::isKeyword(const LangOptions &LangOpts) const { switch (getTokenKwStatus(LangOpts, getTokenID())) { @@ -264,7 +272,7 @@ bool IdentifierInfo::isKeyword(const LangOptions &LangOpts) const { } } -/// \brief Returns true if the identifier represents a C++ keyword in the +/// Returns true if the identifier represents a C++ keyword in the /// specified language. bool IdentifierInfo::isCPlusPlusKeyword(const LangOptions &LangOpts) const { if (!LangOpts.CPlusPlus || !isKeyword(LangOpts)) @@ -496,6 +504,8 @@ void Selector::print(llvm::raw_ostream &OS) const { OS << getAsString(); } +LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); } + /// Interpreting the given string using the normal CamelCase /// conventions, determine whether the given string starts with the /// given "word", which is assumed to end in a lowercase letter. @@ -637,6 +647,12 @@ SelectorTable::constructSetterSelector(IdentifierTable &Idents, return SelTable.getUnarySelector(SetterName); } +std::string SelectorTable::getPropertyNameFromSetterSelector(Selector Sel) { + StringRef Name = Sel.getNameForSlot(0); + assert(Name.startswith("set") && "invalid setter name"); + return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str(); +} + size_t SelectorTable::getTotalMemory() const { SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl); return SelTabImpl.Allocator.getTotalMemory(); diff --git a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp index db81507aa209..763ba33683bc 100644 --- a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp @@ -1,4 +1,4 @@ -//===--- LangOptions.cpp - C Language Family Language Options ---*- C++ -*-===// +//===- LangOptions.cpp - C Language Family Language Options ---------------===// // // The LLVM Compiler Infrastructure // @@ -10,13 +10,12 @@ // This file defines the LangOptions class. // //===----------------------------------------------------------------------===// + #include "clang/Basic/LangOptions.h" -#include "llvm/ADT/StringRef.h" using namespace clang; -LangOptions::LangOptions() - : IsHeaderFile(false) { +LangOptions::LangOptions() { #define LANGOPT(Name, Bits, Default, Description) Name = Default; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default); #include "clang/Basic/LangOptions.def" @@ -44,3 +43,8 @@ bool LangOptions::isNoBuiltinFunc(StringRef FuncName) const { return true; return false; } + +VersionTuple LangOptions::getOpenCLVersionTuple() const { + const int Ver = OpenCLCPlusPlus ? OpenCLCPlusPlusVersion : OpenCLVersion; + return VersionTuple(Ver / 100, (Ver % 100) / 10); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp index 7124184865c6..2714b98120c0 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Module.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp @@ -44,7 +44,8 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, IsSystem(false), IsExternC(false), IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), InferExportWildcard(false), ConfigMacrosExhaustive(false), - NoUndeclaredIncludes(false), NameVisibility(Hidden) { + NoUndeclaredIncludes(false), ModuleMapIsPrivate(false), + NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) IsAvailable = false; @@ -54,6 +55,8 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, IsExternC = true; if (Parent->NoUndeclaredIncludes) NoUndeclaredIncludes = true; + if (Parent->ModuleMapIsPrivate) + ModuleMapIsPrivate = true; IsMissingRequirement = Parent->IsMissingRequirement; Parent->SubModuleIndex[Name] = Parent->SubModules.size(); @@ -68,7 +71,7 @@ Module::~Module() { } } -/// \brief Determine whether a translation unit built using the current +/// Determine whether a translation unit built using the current /// language options has the given feature. static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target) { @@ -78,6 +81,11 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, .Case("coroutines", LangOpts.CoroutinesTS) .Case("cplusplus", LangOpts.CPlusPlus) .Case("cplusplus11", LangOpts.CPlusPlus11) + .Case("cplusplus14", LangOpts.CPlusPlus14) + .Case("cplusplus17", LangOpts.CPlusPlus17) + .Case("c99", LangOpts.C99) + .Case("c11", LangOpts.C11) + .Case("c17", LangOpts.C17) .Case("freestanding", LangOpts.Freestanding) .Case("gnuinlineasm", LangOpts.GNUAsm) .Case("objc", LangOpts.ObjC1) @@ -95,11 +103,16 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, Requirement &Req, - UnresolvedHeaderDirective &MissingHeader) const { + UnresolvedHeaderDirective &MissingHeader, + Module *&ShadowingModule) const { if (IsAvailable) return true; for (const Module *Current = this; Current; Current = Current->Parent) { + if (Current->ShadowingModule) { + ShadowingModule = Current->ShadowingModule; + return false; + } for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != Current->Requirements[I].second) { diff --git a/contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp b/contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp index 133c66945dde..8fa0afbe03f2 100644 --- a/contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp @@ -1,4 +1,4 @@ -//===- ObjCRuntime.cpp - Objective-C Runtime Handling -----------*- C++ -*-===// +//===- ObjCRuntime.cpp - Objective-C Runtime Handling ---------------------===// // // The LLVM Compiler Infrastructure // @@ -11,8 +11,13 @@ // target Objective-C runtime. // //===----------------------------------------------------------------------===// + #include "clang/Basic/ObjCRuntime.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/VersionTuple.h" #include "llvm/Support/raw_ostream.h" +#include <cstddef> +#include <string> using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp index 09c919e2b072..67b7d91e6292 100644 --- a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// /// \file -/// \brief This file implements the OpenMP enum and support functions. +/// This file implements the OpenMP enum and support functions. /// //===----------------------------------------------------------------------===// @@ -891,6 +891,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_target_teams: case OMPD_target_teams_distribute: case OMPD_target_teams_distribute_simd: + CaptureRegions.push_back(OMPD_task); CaptureRegions.push_back(OMPD_target); CaptureRegions.push_back(OMPD_teams); break; @@ -901,6 +902,7 @@ void clang::getOpenMPCaptureRegions( break; case OMPD_target: case OMPD_target_simd: + CaptureRegions.push_back(OMPD_task); CaptureRegions.push_back(OMPD_target); break; case OMPD_teams_distribute_parallel_for: @@ -911,6 +913,7 @@ void clang::getOpenMPCaptureRegions( case OMPD_target_parallel: case OMPD_target_parallel_for: case OMPD_target_parallel_for_simd: + CaptureRegions.push_back(OMPD_task); CaptureRegions.push_back(OMPD_target); CaptureRegions.push_back(OMPD_parallel); break; @@ -924,6 +927,13 @@ void clang::getOpenMPCaptureRegions( case OMPD_taskloop_simd: CaptureRegions.push_back(OMPD_taskloop); break; + case OMPD_target_teams_distribute_parallel_for: + case OMPD_target_teams_distribute_parallel_for_simd: + CaptureRegions.push_back(OMPD_task); + CaptureRegions.push_back(OMPD_target); + CaptureRegions.push_back(OMPD_teams); + CaptureRegions.push_back(OMPD_parallel); + break; case OMPD_simd: case OMPD_for: case OMPD_for_simd: @@ -938,8 +948,6 @@ void clang::getOpenMPCaptureRegions( case OMPD_atomic: case OMPD_target_data: case OMPD_distribute_simd: - case OMPD_target_teams_distribute_parallel_for: - case OMPD_target_teams_distribute_parallel_for_simd: CaptureRegions.push_back(OMPD_unknown); break; case OMPD_threadprivate: diff --git a/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp b/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp index 3743b6ad5fef..bf805fc7deb1 100644 --- a/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// /// /// \file -/// \brief Defines and computes precedence levels for binary/ternary operators. +/// Defines and computes precedence levels for binary/ternary operators. /// //===----------------------------------------------------------------------===// #include "clang/Basic/OperatorPrecedence.h" diff --git a/contrib/llvm/tools/clang/lib/Basic/Sanitizers.cpp b/contrib/llvm/tools/clang/lib/Basic/Sanitizers.cpp index 91b6b2dc74eb..8faf17b8f22e 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Sanitizers.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Sanitizers.cpp @@ -1,4 +1,4 @@ -//===--- Sanitizers.cpp - C Language Family Language Options ----*- C++ -*-===// +//===- Sanitizers.cpp - C Language Family Language Options ----------------===// // // The LLVM Compiler Infrastructure // @@ -10,9 +10,8 @@ // This file defines the classes from Sanitizers.h // //===----------------------------------------------------------------------===// + #include "clang/Basic/Sanitizers.h" -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp index 89ddbc946a49..fef1f44fc8a5 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp @@ -1,4 +1,4 @@ -//==--- SourceLocation.cpp - Compact identifier for Source Files -*- C++ -*-==// +//===- SourceLocation.cpp - Compact identifier for Source Files -----------===// // // The LLVM Compiler Infrastructure // @@ -12,10 +12,17 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" -#include <cstdio> +#include <cassert> +#include <string> +#include <utility> + using namespace clang; //===----------------------------------------------------------------------===// @@ -81,7 +88,6 @@ FileID FullSourceLoc::getFileID() const { return SrcMgr->getFileID(*this); } - FullSourceLoc FullSourceLoc::getExpansionLoc() const { assert(isValid()); return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr); @@ -97,15 +103,6 @@ FullSourceLoc FullSourceLoc::getFileLoc() const { return FullSourceLoc(SrcMgr->getFileLoc(*this), *SrcMgr); } -std::pair<FullSourceLoc, FullSourceLoc> -FullSourceLoc::getImmediateExpansionRange() const { - assert(isValid()); - std::pair<SourceLocation, SourceLocation> Range = - SrcMgr->getImmediateExpansionRange(*this); - return std::make_pair(FullSourceLoc(Range.first, *SrcMgr), - FullSourceLoc(Range.second, *SrcMgr)); -} - PresumedLoc FullSourceLoc::getPresumedLoc(bool UseLineDirectives) const { if (!isValid()) return PresumedLoc(); @@ -148,15 +145,6 @@ unsigned FullSourceLoc::getColumnNumber(bool *Invalid) const { return SrcMgr->getColumnNumber(getFileID(), getFileOffset(), Invalid); } -std::pair<FullSourceLoc, FullSourceLoc> -FullSourceLoc::getExpansionRange() const { - assert(isValid()); - std::pair<SourceLocation, SourceLocation> Range = - SrcMgr->getExpansionRange(*this); - return std::make_pair(FullSourceLoc(Range.first, *SrcMgr), - FullSourceLoc(Range.second, *SrcMgr)); -} - const FileEntry *FullSourceLoc::getFileEntry() const { assert(isValid()); return SrcMgr->getFileEntryForID(getFileID()); diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp index 0a51985614c8..ae76817826e1 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -170,8 +170,10 @@ llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr) .StartsWith("\xFE\xFF", "UTF-16 (BE)") .StartsWith("\xFF\xFE", "UTF-16 (LE)") - .StartsWith("\x00\x00\xFE\xFF", "UTF-32 (BE)") - .StartsWith("\xFF\xFE\x00\x00", "UTF-32 (LE)") + .StartsWith(llvm::StringLiteral::withInnerNUL("\x00\x00\xFE\xFF"), + "UTF-32 (BE)") + .StartsWith(llvm::StringLiteral::withInnerNUL("\xFF\xFE\x00\x00"), + "UTF-32 (LE)") .StartsWith("\x2B\x2F\x76", "UTF-7") .StartsWith("\xF7\x64\x4C", "UTF-1") .StartsWith("\xDD\x73\x66\x73", "UTF-EBCDIC") @@ -258,7 +260,7 @@ const LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID, return &*--I; } -/// \brief Add a new line entry that has already been encoded into +/// Add a new line entry that has already been encoded into /// the internal representation of the line table. void LineTableInfo::AddEntry(FileID FID, const std::vector<LineEntry> &Entries) { @@ -466,7 +468,7 @@ SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries, return std::make_pair(-ID - 1, CurrentLoadedOffset); } -/// \brief As part of recovering from missing or changed content, produce a +/// As part of recovering from missing or changed content, produce a /// fake, non-empty buffer. llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const { if (!FakeBufferForRecovery) @@ -476,7 +478,7 @@ llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const { return FakeBufferForRecovery.get(); } -/// \brief As part of recovering from missing or changed content, produce a +/// As part of recovering from missing or changed content, produce a /// fake content cache. const SrcMgr::ContentCache * SourceManager::getFakeContentCacheForRecovery() const { @@ -488,7 +490,7 @@ SourceManager::getFakeContentCacheForRecovery() const { return FakeContentCacheForRecovery.get(); } -/// \brief Returns the previous in-order FileID or an invalid FileID if there +/// Returns the previous in-order FileID or an invalid FileID if there /// is no previous one. FileID SourceManager::getPreviousFileID(FileID FID) const { if (FID.isInvalid()) @@ -508,7 +510,7 @@ FileID SourceManager::getPreviousFileID(FileID FID) const { return FileID::get(ID-1); } -/// \brief Returns the next in-order FileID or an invalid FileID if there is +/// Returns the next in-order FileID or an invalid FileID if there is /// no next one. FileID SourceManager::getNextFileID(FileID FID) const { if (FID.isInvalid()) @@ -577,13 +579,24 @@ SourceManager::createExpansionLoc(SourceLocation SpellingLoc, SourceLocation ExpansionLocStart, SourceLocation ExpansionLocEnd, unsigned TokLength, + bool ExpansionIsTokenRange, int LoadedID, unsigned LoadedOffset) { - ExpansionInfo Info = ExpansionInfo::create(SpellingLoc, ExpansionLocStart, - ExpansionLocEnd); + ExpansionInfo Info = ExpansionInfo::create( + SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange); return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset); } +SourceLocation SourceManager::createTokenSplitLoc(SourceLocation Spelling, + SourceLocation TokenStart, + SourceLocation TokenEnd) { + assert(getFileID(TokenStart) == getFileID(TokenEnd) && + "token spans multiple files"); + return createExpansionLocImpl( + ExpansionInfo::createForTokenSplit(Spelling, TokenStart, TokenEnd), + TokenEnd.getOffset() - TokenStart.getOffset()); +} + SourceLocation SourceManager::createExpansionLocImpl(const ExpansionInfo &Info, unsigned TokLength, @@ -679,7 +692,7 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const { // SourceLocation manipulation methods. //===----------------------------------------------------------------------===// -/// \brief Return the FileID for a SourceLocation. +/// Return the FileID for a SourceLocation. /// /// This is the cache-miss path of getFileID. Not as hot as that function, but /// still very important. It is responsible for finding the entry in the @@ -695,7 +708,7 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const { return getFileIDLoaded(SLocOffset); } -/// \brief Return the FileID for a SourceLocation with a low offset. +/// Return the FileID for a SourceLocation with a low offset. /// /// This function knows that the SourceLocation is in a local buffer, not a /// loaded one. @@ -786,7 +799,7 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { } } -/// \brief Return the FileID for a SourceLocation with a high offset. +/// Return the FileID for a SourceLocation with a high offset. /// /// This function knows that the SourceLocation is in a loaded buffer, not a /// local one. @@ -893,7 +906,7 @@ SourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const { if (isMacroArgExpansion(Loc)) Loc = getImmediateSpellingLoc(Loc); else - Loc = getImmediateExpansionRange(Loc).first; + Loc = getImmediateExpansionRange(Loc).getBegin(); } while (!Loc.isFileID()); return Loc; } @@ -948,28 +961,36 @@ SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{ /// getImmediateExpansionRange - Loc is required to be an expansion location. /// Return the start/end of the expansion information. -std::pair<SourceLocation,SourceLocation> +CharSourceRange SourceManager::getImmediateExpansionRange(SourceLocation Loc) const { assert(Loc.isMacroID() && "Not a macro expansion loc!"); const ExpansionInfo &Expansion = getSLocEntry(getFileID(Loc)).getExpansion(); return Expansion.getExpansionLocRange(); } +SourceLocation SourceManager::getTopMacroCallerLoc(SourceLocation Loc) const { + while (isMacroArgExpansion(Loc)) + Loc = getImmediateSpellingLoc(Loc); + return Loc; +} + /// getExpansionRange - Given a SourceLocation object, return the range of /// tokens covered by the expansion in the ultimate file. -std::pair<SourceLocation,SourceLocation> -SourceManager::getExpansionRange(SourceLocation Loc) const { - if (Loc.isFileID()) return std::make_pair(Loc, Loc); +CharSourceRange SourceManager::getExpansionRange(SourceLocation Loc) const { + if (Loc.isFileID()) + return CharSourceRange(SourceRange(Loc, Loc), true); - std::pair<SourceLocation,SourceLocation> Res = - getImmediateExpansionRange(Loc); + CharSourceRange Res = getImmediateExpansionRange(Loc); // Fully resolve the start and end locations to their ultimate expansion // points. - while (!Res.first.isFileID()) - Res.first = getImmediateExpansionRange(Res.first).first; - while (!Res.second.isFileID()) - Res.second = getImmediateExpansionRange(Res.second).second; + while (!Res.getBegin().isFileID()) + Res.setBegin(getImmediateExpansionRange(Res.getBegin()).getBegin()); + while (!Res.getEnd().isFileID()) { + CharSourceRange EndRange = getImmediateExpansionRange(Res.getEnd()); + Res.setEnd(EndRange.getEnd()); + Res.setTokenRange(EndRange.isTokenRange()); + } return Res; } @@ -1498,7 +1519,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc); } -/// \brief Returns whether the PresumedLoc for a given SourceLocation is +/// Returns whether the PresumedLoc for a given SourceLocation is /// in the main file. /// /// This computes the "presumed" location for a SourceLocation, then checks @@ -1528,7 +1549,7 @@ bool SourceManager::isInMainFile(SourceLocation Loc) const { return FI.getIncludeLoc().isInvalid(); } -/// \brief The size of the SLocEntry that \p FID represents. +/// The size of the SLocEntry that \p FID represents. unsigned SourceManager::getFileIDSize(FileID FID) const { bool Invalid = false; const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); @@ -1551,7 +1572,7 @@ unsigned SourceManager::getFileIDSize(FileID FID) const { // Other miscellaneous methods. //===----------------------------------------------------------------------===// -/// \brief Retrieve the inode for the given file entry, if possible. +/// Retrieve the inode for the given file entry, if possible. /// /// This routine involves a system call, and therefore should only be used /// in non-performance-critical code. @@ -1567,7 +1588,7 @@ getActualFileUID(const FileEntry *File) { return ID; } -/// \brief Get the source location for the given file:line:col triplet. +/// Get the source location for the given file:line:col triplet. /// /// If the source file is included multiple times, the source location will /// be based upon an arbitrary inclusion. @@ -1581,7 +1602,7 @@ SourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile, return translateLineCol(FirstFID, Line, Col); } -/// \brief Get the FileID for the given file. +/// Get the FileID for the given file. /// /// If the source file is included multiple times, the FileID will be the /// first inclusion. @@ -1698,7 +1719,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { return FirstFID; } -/// \brief Get the source location in \arg FID for the given line:col. +/// Get the source location in \arg FID for the given line:col. /// Returns null location if \arg FID is not a file SLocEntry. SourceLocation SourceManager::translateLineCol(FileID FID, unsigned Line, @@ -1759,7 +1780,7 @@ SourceLocation SourceManager::translateLineCol(FileID FID, return FileLoc.getLocWithOffset(FilePos + i); } -/// \brief Compute a map of macro argument chunks to their expanded source +/// Compute a map of macro argument chunks to their expanded source /// location. Chunks that are not part of a macro argument will map to an /// invalid source location. e.g. if a file contains one macro argument at /// offset 100 with length 10, this is how the map will be formed: @@ -1879,7 +1900,7 @@ void SourceManager::associateFileChunkWithMacroArgExp( // 0 -> SourceLocation() // 100 -> Expanded loc #1 // 110 -> SourceLocation() - // and we found a new macro FileID that lexed from offet 105 with length 3, + // and we found a new macro FileID that lexed from offset 105 with length 3, // the new map will be: // 0 -> SourceLocation() // 100 -> Expanded loc #1 @@ -1898,7 +1919,7 @@ void SourceManager::associateFileChunkWithMacroArgExp( MacroArgsCache[EndOffs] = EndOffsMappedLoc; } -/// \brief If \arg Loc points inside a function macro argument, the returned +/// If \arg Loc points inside a function macro argument, the returned /// location will be the macro location in which the argument was expanded. /// If a macro argument is used multiple times, the expanded location will /// be at the first expansion of the argument. @@ -2007,7 +2028,7 @@ InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID, return IBTUCacheOverflow; } -/// \brief Determines the order of 2 source locations in the translation unit. +/// Determines the order of 2 source locations in the translation unit. /// /// \returns true if LHS source location comes before RHS, false otherwise. bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, @@ -2237,3 +2258,29 @@ size_t SourceManager::getDataStructureSizes() const { return size; } + +SourceManagerForFile::SourceManagerForFile(StringRef FileName, + StringRef Content) { + // This is referenced by `FileMgr` and will be released by `FileMgr` when it + // is deleted. + IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem( + new vfs::InMemoryFileSystem); + InMemoryFileSystem->addFile( + FileName, 0, + llvm::MemoryBuffer::getMemBuffer(Content, FileName, + /*RequiresNullTerminator=*/false)); + // This is passed to `SM` as reference, so the pointer has to be referenced + // in `Environment` so that `FileMgr` can out-live this function scope. + FileMgr = + llvm::make_unique<FileManager>(FileSystemOptions(), InMemoryFileSystem); + // This is passed to `SM` as reference, so the pointer has to be referenced + // by `Environment` due to the same reason above. + Diagnostics = llvm::make_unique<DiagnosticsEngine>( + IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), + new DiagnosticOptions); + SourceMgr = llvm::make_unique<SourceManager>(*Diagnostics, *FileMgr); + FileID ID = SourceMgr->createFileID(FileMgr->getFile(FileName), + SourceLocation(), clang::SrcMgr::C_User); + assert(ID.isValid()); + SourceMgr->setMainFileID(ID); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp index ddd292c1b743..3400c8721f7a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp @@ -14,6 +14,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" @@ -32,12 +33,31 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { TLSSupported = true; VLASupported = true; NoAsmVariants = false; + HasLegalHalfType = false; HasFloat128 = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; LongWidth = LongAlign = 32; LongLongWidth = LongLongAlign = 64; + + // Fixed point default bit widths + ShortAccumWidth = ShortAccumAlign = 16; + AccumWidth = AccumAlign = 32; + LongAccumWidth = LongAccumAlign = 64; + ShortFractWidth = ShortFractAlign = 8; + FractWidth = FractAlign = 16; + LongFractWidth = LongFractAlign = 32; + + // Fixed point default integral and fractional bit sizes + // We give the _Accum 1 fewer fractional bits than their corresponding _Fract + // types by default to have the same number of fractional bits between _Accum + // and _Fract types. + PaddingOnUnsignedFixedPoint = false; + ShortAccumScale = 7; + AccumScale = 15; + LongAccumScale = 31; + SuitableAlign = 64; DefaultAlignForAttributeAligned = 128; MinGlobalAlign = 0; @@ -114,6 +134,18 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { // Out of line virtual dtor for TargetInfo. TargetInfo::~TargetInfo() {} +bool +TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const { + Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch"; + return false; +} + +bool +TargetInfo::checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const { + Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return"; + return false; +} + /// getTypeName - Return the user string for the specified integer type enum. /// For example, SignedShort -> "short". const char *TargetInfo::getTypeName(IntType T) { @@ -342,6 +374,11 @@ void TargetInfo::adjust(LangOptions &Opts) { if (Opts.NewAlignOverride) NewAlign = Opts.NewAlignOverride * getCharWidth(); + + // Each unsigned fixed point type has the same number of fractional bits as + // its corresponding signed type. + PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint; + CheckFixedPointBits(); } bool TargetInfo::initFeatureMap( @@ -356,6 +393,14 @@ bool TargetInfo::initFeatureMap( return true; } +TargetInfo::CallingConvKind +TargetInfo::getCallingConvKind(bool ClangABICompat4) const { + if (getCXXABI() != TargetCXXABI::Microsoft && + (ClangABICompat4 || getTriple().getOS() == llvm::Triple::PS4)) + return CCK_ClangABI4OrPS4; + return CCK_Default; +} + LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const { switch (TK) { case OCLTK_Image: @@ -688,3 +733,63 @@ bool TargetInfo::validateInputConstraint( return true; } + +void TargetInfo::CheckFixedPointBits() const { + // Check that the number of fractional and integral bits (and maybe sign) can + // fit into the bits given for a fixed point type. + assert(ShortAccumScale + getShortAccumIBits() + 1 <= ShortAccumWidth); + assert(AccumScale + getAccumIBits() + 1 <= AccumWidth); + assert(LongAccumScale + getLongAccumIBits() + 1 <= LongAccumWidth); + assert(getUnsignedShortAccumScale() + getUnsignedShortAccumIBits() <= + ShortAccumWidth); + assert(getUnsignedAccumScale() + getUnsignedAccumIBits() <= AccumWidth); + assert(getUnsignedLongAccumScale() + getUnsignedLongAccumIBits() <= + LongAccumWidth); + + assert(getShortFractScale() + 1 <= ShortFractWidth); + assert(getFractScale() + 1 <= FractWidth); + assert(getLongFractScale() + 1 <= LongFractWidth); + assert(getUnsignedShortFractScale() <= ShortFractWidth); + assert(getUnsignedFractScale() <= FractWidth); + assert(getUnsignedLongFractScale() <= LongFractWidth); + + // Each unsigned fract type has either the same number of fractional bits + // as, or one more fractional bit than, its corresponding signed fract type. + assert(getShortFractScale() == getUnsignedShortFractScale() || + getShortFractScale() == getUnsignedShortFractScale() - 1); + assert(getFractScale() == getUnsignedFractScale() || + getFractScale() == getUnsignedFractScale() - 1); + assert(getLongFractScale() == getUnsignedLongFractScale() || + getLongFractScale() == getUnsignedLongFractScale() - 1); + + // When arranged in order of increasing rank (see 6.3.1.3a), the number of + // fractional bits is nondecreasing for each of the following sets of + // fixed-point types: + // - signed fract types + // - unsigned fract types + // - signed accum types + // - unsigned accum types. + assert(getLongFractScale() >= getFractScale() && + getFractScale() >= getShortFractScale()); + assert(getUnsignedLongFractScale() >= getUnsignedFractScale() && + getUnsignedFractScale() >= getUnsignedShortFractScale()); + assert(LongAccumScale >= AccumScale && AccumScale >= ShortAccumScale); + assert(getUnsignedLongAccumScale() >= getUnsignedAccumScale() && + getUnsignedAccumScale() >= getUnsignedShortAccumScale()); + + // When arranged in order of increasing rank (see 6.3.1.3a), the number of + // integral bits is nondecreasing for each of the following sets of + // fixed-point types: + // - signed accum types + // - unsigned accum types + assert(getLongAccumIBits() >= getAccumIBits() && + getAccumIBits() >= getShortAccumIBits()); + assert(getUnsignedLongAccumIBits() >= getUnsignedAccumIBits() && + getUnsignedAccumIBits() >= getUnsignedShortAccumIBits()); + + // Each signed accum type has at least as many integral bits as its + // corresponding unsigned accum type. + assert(getShortAccumIBits() >= getUnsignedShortAccumIBits()); + assert(getAccumIBits() >= getUnsignedAccumIBits()); + assert(getLongAccumIBits() >= getUnsignedLongAccumIBits()); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index 7deebc06c3ef..1ef2fe3b8141 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -29,6 +29,7 @@ #include "Targets/OSTargets.h" #include "Targets/PNaCl.h" #include "Targets/PPC.h" +#include "Targets/RISCV.h" #include "Targets/SPIR.h" #include "Targets/Sparc.h" #include "Targets/SystemZ.h" @@ -37,6 +38,7 @@ #include "Targets/X86.h" #include "Targets/XCore.h" #include "clang/Basic/Diagnostic.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" using namespace clang; @@ -370,6 +372,17 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::r600: return new AMDGPUTargetInfo(Triple, Opts); + case llvm::Triple::riscv32: + // TODO: add cases for FreeBSD, NetBSD, RTEMS once tested. + if (os == llvm::Triple::Linux) + return new LinuxTargetInfo<RISCV32TargetInfo>(Triple, Opts); + return new RISCV32TargetInfo(Triple, Opts); + case llvm::Triple::riscv64: + // TODO: add cases for FreeBSD, NetBSD, RTEMS once tested. + if (os == llvm::Triple::Linux) + return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts); + return new RISCV64TargetInfo(Triple, Opts); + case llvm::Triple::sparc: switch (os) { case llvm::Triple::Linux: @@ -595,6 +608,10 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, // Set the target CPU if specified. if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) { Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU; + SmallVector<StringRef, 32> ValidList; + Target->fillValidCPUList(ValidList); + if (!ValidList.empty()) + Diags.Report(diag::note_valid_options) << llvm::join(ValidList, ", "); return nullptr; } @@ -621,6 +638,9 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, Opts->Features.clear(); for (const auto &F : Features) Opts->Features.push_back((F.getValue() ? "+" : "-") + F.getKey().str()); + // Sort here, so we handle the features in a predictable order. (This matters + // when we're dealing with features that overlap.) + llvm::sort(Opts->Features.begin(), Opts->Features.end()); if (!Target->handleTargetFeatures(Opts->Features, Diags)) return nullptr; @@ -632,5 +652,7 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, if (!Target->validateTarget(Diags)) return nullptr; + Target->CheckFixedPointBits(); + return Target.release(); } diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.h b/contrib/llvm/tools/clang/lib/Basic/Targets.h index 6fc967ddabee..d450aa3f37ed 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.h @@ -1,4 +1,4 @@ -//===------- Targets.h - Declare target feature support -------------------===// +//===------- Targets.h - Declare target feature support ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.cpp index 8762ef691700..3444591ac593 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.cpp @@ -29,26 +29,27 @@ const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, #include "clang/Basic/BuiltinsAArch64.def" }; AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), ABI("aapcs") { - if (getTriple().getOS() == llvm::Triple::NetBSD || - getTriple().getOS() == llvm::Triple::OpenBSD) { - // NetBSD apparently prefers consistency across ARM targets to - // consistency across 64-bit targets. + if (getTriple().getOS() == llvm::Triple::OpenBSD) { Int64Type = SignedLongLong; IntMaxType = SignedLongLong; } else { - if (!getTriple().isOSDarwin()) + if (!getTriple().isOSDarwin() && getTriple().getOS() != llvm::Triple::NetBSD) WCharType = UnsignedInt; Int64Type = SignedLong; IntMaxType = SignedLong; } + // All AArch64 implementations support ARMv8 FP, which makes half a legal type. + HasLegalHalfType = true; LongWidth = LongAlign = PointerWidth = PointerAlign = 64; MaxVectorAlign = 128; @@ -101,6 +102,11 @@ bool AArch64TargetInfo::setCPU(const std::string &Name) { return isValidCPUName(Name); } +void AArch64TargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + llvm::AArch64::fillValidCPUArchList(Values); +} + void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); @@ -183,6 +189,11 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if ((FPU & NeonMode) && HasFullFP16) Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); + if (HasFullFP16) + Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); + + if (HasDotProd) + Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); switch (ArchKind) { default: @@ -220,6 +231,7 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, Crypto = 0; Unaligned = 1; HasFullFP16 = 0; + HasDotProd = 0; ArchKind = llvm::AArch64::ArchKind::ARMV8A; for (const auto &Feature : Features) { @@ -239,6 +251,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, ArchKind = llvm::AArch64::ArchKind::ARMV8_2A; if (Feature == "+fullfp16") HasFullFP16 = 1; + if (Feature == "+dotprod") + HasDotProd = 1; } setDataLayout(); @@ -519,6 +533,11 @@ void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts, getVisualStudioDefines(Opts, Builder); } +TargetInfo::CallingConvKind +MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const { + return CCK_MicrosoftWin64; +} + MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : WindowsARM64TargetInfo(Triple, Opts) { diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.h b/contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.h index 33268f0f8d99..a9df895e4dad 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/AArch64.h @@ -33,6 +33,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { unsigned Crypto; unsigned Unaligned; unsigned HasFullFP16; + unsigned HasDotProd; llvm::AArch64::ArchKind ArchKind; static const Builtin::Info BuiltinInfo[]; @@ -46,6 +47,7 @@ public: bool setABI(const std::string &Name) override; bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; bool setCPU(const std::string &Name) override; bool useFP16ConversionIntrinsics() const override { @@ -80,6 +82,11 @@ public: std::string &SuggestedModifier) const override; const char *getClobbers() const override; + StringRef getConstraintRegister(StringRef Constraint, + StringRef Expression) const override { + return Expression; + } + int getEHDataRegisterNumber(unsigned RegNo) const override; }; @@ -119,6 +126,8 @@ public: MacroBuilder &Builder) const; void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; + TargetInfo::CallingConvKind + getCallingConvKind(bool ClangABICompat4) const override; }; // ARM64 MinGW target diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.cpp index 4c510e47379f..b6b9aa2f1244 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.cpp @@ -30,64 +30,35 @@ namespace targets { static const char *const DataLayoutStringR600 = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" - "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; + "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"; -static const char *const DataLayoutStringSIPrivateIsZero = - "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32" +static const char *const DataLayoutStringAMDGCN = + "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32" "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" - "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; - -static const char *const DataLayoutStringSIGenericIsZero = - "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:32:32-p5:32:32" - "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" - "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-A5"; - -static const LangASMap AMDGPUPrivIsZeroDefIsGenMap = { - 4, // Default - 1, // opencl_global - 3, // opencl_local - 2, // opencl_constant - 0, // opencl_private - 4, // opencl_generic - 1, // cuda_device - 2, // cuda_constant - 3 // cuda_shared + "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"; + +const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = { + Generic, // Default + Global, // opencl_global + Local, // opencl_local + Constant, // opencl_constant + Private, // opencl_private + Generic, // opencl_generic + Global, // cuda_device + Constant, // cuda_constant + Local // cuda_shared }; -static const LangASMap AMDGPUGenIsZeroDefIsGenMap = { - 0, // Default - 1, // opencl_global - 3, // opencl_local - 2, // opencl_constant - 5, // opencl_private - 0, // opencl_generic - 1, // cuda_device - 2, // cuda_constant - 3 // cuda_shared -}; - -static const LangASMap AMDGPUPrivIsZeroDefIsPrivMap = { - 0, // Default - 1, // opencl_global - 3, // opencl_local - 2, // opencl_constant - 0, // opencl_private - 4, // opencl_generic - 1, // cuda_device - 2, // cuda_constant - 3 // cuda_shared -}; - -static const LangASMap AMDGPUGenIsZeroDefIsPrivMap = { - 5, // Default - 1, // opencl_global - 3, // opencl_local - 2, // opencl_constant - 5, // opencl_private - 0, // opencl_generic - 1, // cuda_device - 2, // cuda_constant - 3 // cuda_shared +const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { + Private, // Default + Global, // opencl_global + Local, // opencl_local + Constant, // opencl_constant + Private, // opencl_private + Generic, // opencl_generic + Global, // cuda_device + Constant, // cuda_constant + Local // cuda_shared }; } // namespace targets } // namespace clang @@ -144,7 +115,7 @@ const char *const AMDGPUTargetInfo::GCCRegNames[] = { "s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112", "s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121", "s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc", - "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi", + "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi", "flat_scratch_lo", "flat_scratch_hi" }; @@ -157,49 +128,66 @@ bool AMDGPUTargetInfo::initFeatureMap( const std::vector<std::string> &FeatureVec) const { // XXX - What does the member GPU mean if device name string passed here? - if (getTriple().getArch() == llvm::Triple::amdgcn) { + if (isAMDGCN(getTriple())) { if (CPU.empty()) - CPU = "tahiti"; - - switch (parseAMDGCNName(CPU)) { - case GK_GFX6: - case GK_GFX7: - break; + CPU = "gfx600"; - case GK_GFX9: + switch (parseAMDGCNName(CPU).Kind) { + case GK_GFX906: + Features["dl-insts"] = true; + LLVM_FALLTHROUGH; + case GK_GFX904: + case GK_GFX902: + case GK_GFX900: Features["gfx9-insts"] = true; LLVM_FALLTHROUGH; - case GK_GFX8: - Features["s-memrealtime"] = true; + case GK_GFX810: + case GK_GFX803: + case GK_GFX802: + case GK_GFX801: Features["16-bit-insts"] = true; Features["dpp"] = true; + Features["s-memrealtime"] = true; + break; + case GK_GFX704: + case GK_GFX703: + case GK_GFX702: + case GK_GFX701: + case GK_GFX700: + case GK_GFX601: + case GK_GFX600: break; - case GK_NONE: return false; default: - llvm_unreachable("unhandled subtarget"); + llvm_unreachable("Unhandled GPU!"); } } else { if (CPU.empty()) CPU = "r600"; - switch (parseR600Name(CPU)) { - case GK_R600: - case GK_R700: - case GK_EVERGREEN: - case GK_NORTHERN_ISLANDS: - break; - case GK_R600_DOUBLE_OPS: - case GK_R700_DOUBLE_OPS: - case GK_EVERGREEN_DOUBLE_OPS: + switch (parseR600Name(CPU).Kind) { case GK_CAYMAN: + case GK_CYPRESS: + case GK_RV770: + case GK_RV670: // TODO: Add fp64 when implemented. break; - case GK_NONE: - return false; + case GK_TURKS: + case GK_CAICOS: + case GK_BARTS: + case GK_SUMO: + case GK_REDWOOD: + case GK_JUNIPER: + case GK_CEDAR: + case GK_RV730: + case GK_RV710: + case GK_RS880: + case GK_R630: + case GK_R600: + break; default: - llvm_unreachable("unhandled subtarget"); + llvm_unreachable("Unhandled GPU!"); } } @@ -210,6 +198,7 @@ void AMDGPUTargetInfo::adjustTargetOptions(const CodeGenOptions &CGOpts, TargetOptions &TargetOpts) const { bool hasFP32Denormals = false; bool hasFP64Denormals = false; + GPUInfo CGOptsGPU = parseGPUName(TargetOpts.CPU); for (auto &I : TargetOpts.FeaturesAsWritten) { if (I == "+fp32-denormals" || I == "-fp32-denormals") hasFP32Denormals = true; @@ -218,120 +207,68 @@ void AMDGPUTargetInfo::adjustTargetOptions(const CodeGenOptions &CGOpts, } if (!hasFP32Denormals) TargetOpts.Features.push_back( - (Twine(hasFullSpeedFMAF32(TargetOpts.CPU) && !CGOpts.FlushDenorm + (Twine(CGOptsGPU.HasFastFMAF && !CGOpts.FlushDenorm ? '+' : '-') + Twine("fp32-denormals")) .str()); // Always do not flush fp64 or fp16 denorms. - if (!hasFP64Denormals && hasFP64) + if (!hasFP64Denormals && CGOptsGPU.HasFP64) TargetOpts.Features.push_back("+fp64-fp16-denormals"); } -AMDGPUTargetInfo::GPUKind AMDGPUTargetInfo::parseR600Name(StringRef Name) { - return llvm::StringSwitch<GPUKind>(Name) - .Case("r600", GK_R600) - .Case("rv610", GK_R600) - .Case("rv620", GK_R600) - .Case("rv630", GK_R600) - .Case("rv635", GK_R600) - .Case("rs780", GK_R600) - .Case("rs880", GK_R600) - .Case("rv670", GK_R600_DOUBLE_OPS) - .Case("rv710", GK_R700) - .Case("rv730", GK_R700) - .Case("rv740", GK_R700_DOUBLE_OPS) - .Case("rv770", GK_R700_DOUBLE_OPS) - .Case("palm", GK_EVERGREEN) - .Case("cedar", GK_EVERGREEN) - .Case("sumo", GK_EVERGREEN) - .Case("sumo2", GK_EVERGREEN) - .Case("redwood", GK_EVERGREEN) - .Case("juniper", GK_EVERGREEN) - .Case("hemlock", GK_EVERGREEN_DOUBLE_OPS) - .Case("cypress", GK_EVERGREEN_DOUBLE_OPS) - .Case("barts", GK_NORTHERN_ISLANDS) - .Case("turks", GK_NORTHERN_ISLANDS) - .Case("caicos", GK_NORTHERN_ISLANDS) - .Case("cayman", GK_CAYMAN) - .Case("aruba", GK_CAYMAN) - .Default(GK_NONE); +constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::InvalidGPU; +constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::R600GPUs[]; +constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::AMDGCNGPUs[]; + +AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseR600Name(StringRef Name) { + const auto *Result = llvm::find_if( + R600GPUs, [Name](const GPUInfo &GPU) { return GPU.Name == Name; }); + + if (Result == std::end(R600GPUs)) + return InvalidGPU; + return *Result; } -AMDGPUTargetInfo::GPUKind AMDGPUTargetInfo::parseAMDGCNName(StringRef Name) { - return llvm::StringSwitch<GPUKind>(Name) - .Case("gfx600", GK_GFX6) - .Case("tahiti", GK_GFX6) - .Case("gfx601", GK_GFX6) - .Case("pitcairn", GK_GFX6) - .Case("verde", GK_GFX6) - .Case("oland", GK_GFX6) - .Case("hainan", GK_GFX6) - .Case("gfx700", GK_GFX7) - .Case("bonaire", GK_GFX7) - .Case("kaveri", GK_GFX7) - .Case("gfx701", GK_GFX7) - .Case("hawaii", GK_GFX7) - .Case("gfx702", GK_GFX7) - .Case("gfx703", GK_GFX7) - .Case("kabini", GK_GFX7) - .Case("mullins", GK_GFX7) - .Case("gfx800", GK_GFX8) - .Case("iceland", GK_GFX8) - .Case("gfx801", GK_GFX8) - .Case("carrizo", GK_GFX8) - .Case("gfx802", GK_GFX8) - .Case("tonga", GK_GFX8) - .Case("gfx803", GK_GFX8) - .Case("fiji", GK_GFX8) - .Case("polaris10", GK_GFX8) - .Case("polaris11", GK_GFX8) - .Case("gfx804", GK_GFX8) - .Case("gfx810", GK_GFX8) - .Case("stoney", GK_GFX8) - .Case("gfx900", GK_GFX9) - .Case("gfx901", GK_GFX9) - .Case("gfx902", GK_GFX9) - .Case("gfx903", GK_GFX9) - .Default(GK_NONE); +AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseAMDGCNName(StringRef Name) { + const auto *Result = llvm::find_if( + AMDGCNGPUs, [Name](const GPUInfo &GPU) { return GPU.Name == Name; }); + + if (Result == std::end(AMDGCNGPUs)) + return InvalidGPU; + return *Result; +} + +AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseGPUName(StringRef Name) const { + if (isAMDGCN(getTriple())) + return parseAMDGCNName(Name); + else + return parseR600Name(Name); +} + +void AMDGPUTargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + if (isAMDGCN(getTriple())) + llvm::for_each(AMDGCNGPUs, [&Values](const GPUInfo &GPU) { + Values.emplace_back(GPU.Name);}); + else + llvm::for_each(R600GPUs, [&Values](const GPUInfo &GPU) { + Values.emplace_back(GPU.Name);}); } void AMDGPUTargetInfo::setAddressSpaceMap(bool DefaultIsPrivate) { - if (isGenericZero(getTriple())) { - AddrSpaceMap = DefaultIsPrivate ? &AMDGPUGenIsZeroDefIsPrivMap - : &AMDGPUGenIsZeroDefIsGenMap; - } else { - AddrSpaceMap = DefaultIsPrivate ? &AMDGPUPrivIsZeroDefIsPrivMap - : &AMDGPUPrivIsZeroDefIsGenMap; - } + AddrSpaceMap = DefaultIsPrivate ? &AMDGPUDefIsPrivMap : &AMDGPUDefIsGenMap; } AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), - GPU(isAMDGCN(Triple) ? GK_GFX6 : parseR600Name(Opts.CPU)), - hasFP64(false), hasFMAF(false), hasLDEXPF(false), - AS(isGenericZero(Triple)) { - if (getTriple().getArch() == llvm::Triple::amdgcn) { - hasFP64 = true; - hasFMAF = true; - hasLDEXPF = true; - } - if (getTriple().getArch() == llvm::Triple::r600) { - if (GPU == GK_EVERGREEN_DOUBLE_OPS || GPU == GK_CAYMAN) { - hasFMAF = true; - } - } - auto IsGenericZero = isGenericZero(Triple); - resetDataLayout(getTriple().getArch() == llvm::Triple::amdgcn - ? (IsGenericZero ? DataLayoutStringSIGenericIsZero - : DataLayoutStringSIPrivateIsZero) - : DataLayoutStringR600); - assert(DataLayout->getAllocaAddrSpace() == AS.Private); + GPU(isAMDGCN(Triple) ? AMDGCNGPUs[0] : parseR600Name(Opts.CPU)) { + resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN + : DataLayoutStringR600); + assert(DataLayout->getAllocaAddrSpace() == Private); setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D || - Triple.getEnvironment() == llvm::Triple::OpenCL || - Triple.getEnvironmentName() == "amdgizcl" || !isAMDGCN(Triple)); UseAddrSpaceMapMangling = true; @@ -349,7 +286,11 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple, void AMDGPUTargetInfo::adjust(LangOptions &Opts) { TargetInfo::adjust(Opts); - setAddressSpaceMap(Opts.OpenCL || !isAMDGCN(getTriple())); + // ToDo: There are still a few places using default address space as private + // address space in OpenCL, which needs to be cleaned up, then Opts.OpenCL + // can be removed from the following line. + setAddressSpaceMap(/*DefaultIsPrivate=*/Opts.OpenCL || + !isAMDGCN(getTriple())); } ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const { @@ -359,15 +300,27 @@ ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const { void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { - if (getTriple().getArch() == llvm::Triple::amdgcn) + Builder.defineMacro("__AMD__"); + Builder.defineMacro("__AMDGPU__"); + + if (isAMDGCN(getTriple())) Builder.defineMacro("__AMDGCN__"); else Builder.defineMacro("__R600__"); - if (hasFMAF) + if (GPU.Kind != GK_NONE) + Builder.defineMacro(Twine("__") + Twine(GPU.CanonicalName) + Twine("__")); + + // TODO: __HAS_FMAF__, __HAS_LDEXPF__, __HAS_FP64__ are deprecated and will be + // removed in the near future. + if (GPU.HasFMAF) Builder.defineMacro("__HAS_FMAF__"); - if (hasLDEXPF) + if (GPU.HasFastFMAF) + Builder.defineMacro("FP_FAST_FMAF"); + if (GPU.HasLDEXPF) Builder.defineMacro("__HAS_LDEXPF__"); - if (hasFP64) + if (GPU.HasFP64) Builder.defineMacro("__HAS_FP64__"); + if (GPU.HasFastFMA) + Builder.defineMacro("FP_FAST_FMA"); } diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.h b/contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.h index a4e070f1cb12..b0221031addf 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.h @@ -28,60 +28,157 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; - struct LLVM_LIBRARY_VISIBILITY AddrSpace { - unsigned Generic, Global, Local, Constant, Private; - AddrSpace(bool IsGenericZero_ = false) { - if (IsGenericZero_) { - Generic = 0; - Global = 1; - Local = 3; - Constant = 2; - Private = 5; - } else { - Generic = 4; - Global = 1; - Local = 3; - Constant = 2; - Private = 0; - } - } + enum AddrSpace { + Generic = 0, + Global = 1, + Local = 3, + Constant = 4, + Private = 5 }; + static const LangASMap AMDGPUDefIsGenMap; + static const LangASMap AMDGPUDefIsPrivMap; + + /// GPU kinds supported by the AMDGPU target. + enum GPUKind : uint32_t { + // Not specified processor. + GK_NONE = 0, - /// \brief The GPU profiles supported by the AMDGPU target. - enum GPUKind { - GK_NONE, + // R600-based processors. GK_R600, - GK_R600_DOUBLE_OPS, - GK_R700, - GK_R700_DOUBLE_OPS, - GK_EVERGREEN, - GK_EVERGREEN_DOUBLE_OPS, - GK_NORTHERN_ISLANDS, + GK_R630, + GK_RS880, + GK_RV670, + GK_RV710, + GK_RV730, + GK_RV770, + GK_CEDAR, + GK_CYPRESS, + GK_JUNIPER, + GK_REDWOOD, + GK_SUMO, + GK_BARTS, + GK_CAICOS, GK_CAYMAN, - GK_GFX6, - GK_GFX7, - GK_GFX8, - GK_GFX9 - } GPU; - - bool hasFP64 : 1; - bool hasFMAF : 1; - bool hasLDEXPF : 1; - const AddrSpace AS; - - static bool hasFullSpeedFMAF32(StringRef GPUName) { - return parseAMDGCNName(GPUName) >= GK_GFX9; - } + GK_TURKS, + + GK_R600_FIRST = GK_R600, + GK_R600_LAST = GK_TURKS, + + // AMDGCN-based processors. + GK_GFX600, + GK_GFX601, + GK_GFX700, + GK_GFX701, + GK_GFX702, + GK_GFX703, + GK_GFX704, + GK_GFX801, + GK_GFX802, + GK_GFX803, + GK_GFX810, + GK_GFX900, + GK_GFX902, + GK_GFX904, + GK_GFX906, + + GK_AMDGCN_FIRST = GK_GFX600, + GK_AMDGCN_LAST = GK_GFX906, + }; + + struct GPUInfo { + llvm::StringLiteral Name; + llvm::StringLiteral CanonicalName; + AMDGPUTargetInfo::GPUKind Kind; + bool HasFMAF; + bool HasFastFMAF; + bool HasLDEXPF; + bool HasFP64; + bool HasFastFMA; + }; + + static constexpr GPUInfo InvalidGPU = + {{""}, {""}, GK_NONE, false, false, false, false, false}; + static constexpr GPUInfo R600GPUs[26] = { + // Name Canonical Kind Has Has Has Has Has + // Name FMAF Fast LDEXPF FP64 Fast + // FMAF FMA + {{"r600"}, {"r600"}, GK_R600, false, false, false, false, false}, + {{"rv630"}, {"r600"}, GK_R600, false, false, false, false, false}, + {{"rv635"}, {"r600"}, GK_R600, false, false, false, false, false}, + {{"r630"}, {"r630"}, GK_R630, false, false, false, false, false}, + {{"rs780"}, {"rs880"}, GK_RS880, false, false, false, false, false}, + {{"rs880"}, {"rs880"}, GK_RS880, false, false, false, false, false}, + {{"rv610"}, {"rs880"}, GK_RS880, false, false, false, false, false}, + {{"rv620"}, {"rs880"}, GK_RS880, false, false, false, false, false}, + {{"rv670"}, {"rv670"}, GK_RV670, false, false, false, false, false}, + {{"rv710"}, {"rv710"}, GK_RV710, false, false, false, false, false}, + {{"rv730"}, {"rv730"}, GK_RV730, false, false, false, false, false}, + {{"rv740"}, {"rv770"}, GK_RV770, false, false, false, false, false}, + {{"rv770"}, {"rv770"}, GK_RV770, false, false, false, false, false}, + {{"cedar"}, {"cedar"}, GK_CEDAR, false, false, false, false, false}, + {{"palm"}, {"cedar"}, GK_CEDAR, false, false, false, false, false}, + {{"cypress"}, {"cypress"}, GK_CYPRESS, true, false, false, false, false}, + {{"hemlock"}, {"cypress"}, GK_CYPRESS, true, false, false, false, false}, + {{"juniper"}, {"juniper"}, GK_JUNIPER, false, false, false, false, false}, + {{"redwood"}, {"redwood"}, GK_REDWOOD, false, false, false, false, false}, + {{"sumo"}, {"sumo"}, GK_SUMO, false, false, false, false, false}, + {{"sumo2"}, {"sumo"}, GK_SUMO, false, false, false, false, false}, + {{"barts"}, {"barts"}, GK_BARTS, false, false, false, false, false}, + {{"caicos"}, {"caicos"}, GK_BARTS, false, false, false, false, false}, + {{"aruba"}, {"cayman"}, GK_CAYMAN, true, false, false, false, false}, + {{"cayman"}, {"cayman"}, GK_CAYMAN, true, false, false, false, false}, + {{"turks"}, {"turks"}, GK_TURKS, false, false, false, false, false}, + }; + static constexpr GPUInfo AMDGCNGPUs[32] = { + // Name Canonical Kind Has Has Has Has Has + // Name FMAF Fast LDEXPF FP64 Fast + // FMAF FMA + {{"gfx600"}, {"gfx600"}, GK_GFX600, true, true, true, true, true}, + {{"tahiti"}, {"gfx600"}, GK_GFX600, true, true, true, true, true}, + {{"gfx601"}, {"gfx601"}, GK_GFX601, true, false, true, true, true}, + {{"hainan"}, {"gfx601"}, GK_GFX601, true, false, true, true, true}, + {{"oland"}, {"gfx601"}, GK_GFX601, true, false, true, true, true}, + {{"pitcairn"}, {"gfx601"}, GK_GFX601, true, false, true, true, true}, + {{"verde"}, {"gfx601"}, GK_GFX601, true, false, true, true, true}, + {{"gfx700"}, {"gfx700"}, GK_GFX700, true, false, true, true, true}, + {{"kaveri"}, {"gfx700"}, GK_GFX700, true, false, true, true, true}, + {{"gfx701"}, {"gfx701"}, GK_GFX701, true, true, true, true, true}, + {{"hawaii"}, {"gfx701"}, GK_GFX701, true, true, true, true, true}, + {{"gfx702"}, {"gfx702"}, GK_GFX702, true, true, true, true, true}, + {{"gfx703"}, {"gfx703"}, GK_GFX703, true, false, true, true, true}, + {{"kabini"}, {"gfx703"}, GK_GFX703, true, false, true, true, true}, + {{"mullins"}, {"gfx703"}, GK_GFX703, true, false, true, true, true}, + {{"gfx704"}, {"gfx704"}, GK_GFX704, true, false, true, true, true}, + {{"bonaire"}, {"gfx704"}, GK_GFX704, true, false, true, true, true}, + {{"gfx801"}, {"gfx801"}, GK_GFX801, true, true, true, true, true}, + {{"carrizo"}, {"gfx801"}, GK_GFX801, true, true, true, true, true}, + {{"gfx802"}, {"gfx802"}, GK_GFX802, true, false, true, true, true}, + {{"iceland"}, {"gfx802"}, GK_GFX802, true, false, true, true, true}, + {{"tonga"}, {"gfx802"}, GK_GFX802, true, false, true, true, true}, + {{"gfx803"}, {"gfx803"}, GK_GFX803, true, false, true, true, true}, + {{"fiji"}, {"gfx803"}, GK_GFX803, true, false, true, true, true}, + {{"polaris10"}, {"gfx803"}, GK_GFX803, true, false, true, true, true}, + {{"polaris11"}, {"gfx803"}, GK_GFX803, true, false, true, true, true}, + {{"gfx810"}, {"gfx810"}, GK_GFX810, true, false, true, true, true}, + {{"stoney"}, {"gfx810"}, GK_GFX810, true, false, true, true, true}, + {{"gfx900"}, {"gfx900"}, GK_GFX900, true, true, true, true, true}, + {{"gfx902"}, {"gfx902"}, GK_GFX900, true, true, true, true, true}, + {{"gfx904"}, {"gfx904"}, GK_GFX904, true, true, true, true, true}, + {{"gfx906"}, {"gfx906"}, GK_GFX906, true, true, true, true, true}, + }; + + static GPUInfo parseR600Name(StringRef Name); + + static GPUInfo parseAMDGCNName(StringRef Name); + + GPUInfo parseGPUName(StringRef Name) const; + + GPUInfo GPU; static bool isAMDGCN(const llvm::Triple &TT) { return TT.getArch() == llvm::Triple::amdgcn; } - static bool isGenericZero(const llvm::Triple &TT) { - return TT.getEnvironmentName() == "amdgiz" || - TT.getEnvironmentName() == "amdgizcl"; - } - public: AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts); @@ -90,12 +187,10 @@ public: void adjust(LangOptions &Opts) override; uint64_t getPointerWidthV(unsigned AddrSpace) const override { - if (GPU <= GK_CAYMAN) + if (GPU.Kind <= GK_R600_LAST) return 32; - - if (AddrSpace == AS.Private || AddrSpace == AS.Local) { + if (AddrSpace == Private || AddrSpace == Local) return 32; - } return 64; } @@ -194,6 +289,19 @@ public: return true; } + // \p Constraint will be left pointing at the last character of + // the constraint. In practice, it won't be changed unless the + // constraint is longer than one character. + std::string convertConstraint(const char *&Constraint) const override { + const char *Begin = Constraint; + TargetInfo::ConstraintInfo Info("", ""); + if (validateAsmConstraint(Constraint, Info)) + return std::string(Begin).substr(0, Constraint - Begin + 1); + + Constraint = Begin; + return std::string(1, *Constraint); + } + bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -211,24 +319,22 @@ public: return TargetInfo::CharPtrBuiltinVaList; } - static GPUKind parseR600Name(StringRef Name); - - static GPUKind parseAMDGCNName(StringRef Name); - bool isValidCPUName(StringRef Name) const override { if (getTriple().getArch() == llvm::Triple::amdgcn) - return GK_NONE != parseAMDGCNName(Name); + return GK_NONE != parseAMDGCNName(Name).Kind; else - return GK_NONE != parseR600Name(Name); + return GK_NONE != parseR600Name(Name).Kind; } + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool setCPU(const std::string &Name) override { if (getTriple().getArch() == llvm::Triple::amdgcn) GPU = parseAMDGCNName(Name); else GPU = parseR600Name(Name); - return GPU != GK_NONE; + return GK_NONE != GPU.Kind; } void setSupportedOpenCLOpts() override { @@ -236,16 +342,16 @@ public: Opts.support("cl_clang_storage_class_specifiers"); Opts.support("cl_khr_icd"); - if (hasFP64) + if (GPU.HasFP64) Opts.support("cl_khr_fp64"); - if (GPU >= GK_EVERGREEN) { + if (GPU.Kind >= GK_CEDAR) { Opts.support("cl_khr_byte_addressable_store"); Opts.support("cl_khr_global_int32_base_atomics"); Opts.support("cl_khr_global_int32_extended_atomics"); Opts.support("cl_khr_local_int32_base_atomics"); Opts.support("cl_khr_local_int32_extended_atomics"); } - if (GPU >= GK_GFX6) { + if (GPU.Kind >= GK_AMDGCN_FIRST) { Opts.support("cl_khr_fp16"); Opts.support("cl_khr_int64_base_atomics"); Opts.support("cl_khr_int64_extended_atomics"); @@ -273,11 +379,13 @@ public: } llvm::Optional<LangAS> getConstantAddressSpace() const override { - return getLangASFromTargetAS(AS.Constant); + return getLangASFromTargetAS(Constant); } /// \returns Target specific vtbl ptr address space. - unsigned getVtblPtrAddressSpace() const override { return AS.Constant; } + unsigned getVtblPtrAddressSpace() const override { + return static_cast<unsigned>(Constant); + } /// \returns If a target requires an address within a target specific address /// space \p AddressSpace to be converted in order to be used, then return the @@ -289,9 +397,9 @@ public: getDWARFAddressSpace(unsigned AddressSpace) const override { const unsigned DWARF_Private = 1; const unsigned DWARF_Local = 2; - if (AddressSpace == AS.Private) { + if (AddressSpace == Private) { return DWARF_Private; - } else if (AddressSpace == AS.Local) { + } else if (AddressSpace == Local) { return DWARF_Local; } else { return None; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp index 6fb0ab41ff5b..efed9b096d56 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.cpp @@ -334,9 +334,20 @@ bool ARMTargetInfo::initFeatureMap( llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const { + std::string ArchFeature; std::vector<StringRef> TargetFeatures; llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName()); + // Map the base architecture to an appropriate target feature, so we don't + // rely on the target triple. + llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU); + if (CPUArch == llvm::ARM::ArchKind::INVALID) + CPUArch = Arch; + if (CPUArch != llvm::ARM::ArchKind::INVALID) { + ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str(); + TargetFeatures.push_back(ArchFeature); + } + // get default FPU features unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch); llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures); @@ -379,6 +390,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, Unaligned = 1; SoftFloat = SoftFloatABI = false; HWDiv = 0; + DotProd = 0; // This does not diagnose illegal cases like having both // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp". @@ -419,6 +431,10 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, Unaligned = 0; } else if (Feature == "+fp16") { HW_FP |= HW_FP_HP; + } else if (Feature == "+fullfp16") { + HasLegalHalfType = true; + } else if (Feature == "+dotprod") { + DotProd = true; } } HW_FP &= ~HW_FP_remove; @@ -478,6 +494,10 @@ bool ARMTargetInfo::isValidCPUName(StringRef Name) const { llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID; } +void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { + llvm::ARM::fillValidCPUArchList(Values); +} + bool ARMTargetInfo::setCPU(const std::string &Name) { if (Name != "generic") setArchInfo(llvm::ARM::parseCPUArch(Name)); @@ -706,6 +726,18 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, if (Opts.UnsafeFPMath) Builder.defineMacro("__ARM_FP_FAST", "1"); + // Armv8.2-A FP16 vector intrinsic + if ((FPU & NeonFPU) && HasLegalHalfType) + Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); + + // Armv8.2-A FP16 scalar intrinsics + if (HasLegalHalfType) + Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); + + // Armv8.2-A dot product intrinsics + if (DotProd) + Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); + switch (ArchKind) { default: break; @@ -956,6 +988,8 @@ WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const { return CCCR_Ignore; case CC_C: case CC_OpenCLKernel: + case CC_PreserveMost: + case CC_PreserveAll: return CCCR_OK; default: return CCCR_Warning; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.h b/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.h index fb0e7e66bea3..9c72c3387f7a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/ARM.h @@ -69,6 +69,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { unsigned Crypto : 1; unsigned DSP : 1; unsigned Unaligned : 1; + unsigned DotProd : 1; enum { LDREX_B = (1 << 0), /// byte (8-bit) @@ -122,6 +123,8 @@ public: bool hasFeature(StringRef Feature) const override; bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool setCPU(const std::string &Name) override; bool setFPMath(StringRef Name) override; @@ -153,6 +156,11 @@ public: std::string &SuggestedModifier) const override; const char *getClobbers() const override; + StringRef getConstraintRegister(StringRef Constraint, + StringRef Expression) const override { + return Expression; + } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; int getEHDataRegisterNumber(unsigned RegNo) const override; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/AVR.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/AVR.cpp index 3022fe33d76c..9b66449cbca6 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/AVR.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/AVR.cpp @@ -28,7 +28,7 @@ struct LLVM_LIBRARY_VISIBILITY MCUInfo { }; // This list should be kept up-to-date with AVRDevices.td in LLVM. -static ArrayRef<MCUInfo> AVRMcus = { +static MCUInfo AVRMcus[] = { {"at90s1200", "__AVR_AT90S1200__"}, {"attiny11", "__AVR_ATtiny11__"}, {"attiny12", "__AVR_ATtiny12__"}, @@ -273,35 +273,29 @@ static ArrayRef<MCUInfo> AVRMcus = { } // namespace targets } // namespace clang +static constexpr llvm::StringLiteral ValidFamilyNames[] = { + "avr1", "avr2", "avr25", "avr3", "avr31", + "avr35", "avr4", "avr5", "avr51", "avr6", + "avrxmega1", "avrxmega2", "avrxmega3", "avrxmega4", "avrxmega5", + "avrxmega6", "avrxmega7", "avrtiny"}; + bool AVRTargetInfo::isValidCPUName(StringRef Name) const { - bool IsFamily = llvm::StringSwitch<bool>(Name) - .Case("avr1", true) - .Case("avr2", true) - .Case("avr25", true) - .Case("avr3", true) - .Case("avr31", true) - .Case("avr35", true) - .Case("avr4", true) - .Case("avr5", true) - .Case("avr51", true) - .Case("avr6", true) - .Case("avrxmega1", true) - .Case("avrxmega2", true) - .Case("avrxmega3", true) - .Case("avrxmega4", true) - .Case("avrxmega5", true) - .Case("avrxmega6", true) - .Case("avrxmega7", true) - .Case("avrtiny", true) - .Default(false); + bool IsFamily = + llvm::find(ValidFamilyNames, Name) != std::end(ValidFamilyNames); bool IsMCU = - std::find_if(AVRMcus.begin(), AVRMcus.end(), [&](const MCUInfo &Info) { + llvm::find_if(AVRMcus, [&](const MCUInfo &Info) { return Info.Name == Name; - }) != AVRMcus.end(); + }) != std::end(AVRMcus); return IsFamily || IsMCU; } +void AVRTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { + Values.append(std::begin(ValidFamilyNames), std::end(ValidFamilyNames)); + for (const MCUInfo &Info : AVRMcus) + Values.push_back(Info.Name); +} + void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("AVR"); @@ -309,12 +303,10 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVR__"); if (!this->CPU.empty()) { - auto It = - std::find_if(AVRMcus.begin(), AVRMcus.end(), [&](const MCUInfo &Info) { - return Info.Name == this->CPU; - }); + auto It = llvm::find_if( + AVRMcus, [&](const MCUInfo &Info) { return Info.Name == this->CPU; }); - if (It != AVRMcus.end()) + if (It != std::end(AVRMcus)) Builder.defineMacro(It->DefineName); } } diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/AVR.h b/contrib/llvm/tools/clang/lib/Basic/Targets/AVR.h index 3dfb84f75668..d595f48e8ef7 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/AVR.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/AVR.h @@ -55,7 +55,7 @@ public: WIntType = SignedInt; Char32Type = UnsignedLong; SigAtomicType = SignedChar; - resetDataLayout("e-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"); + resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"); } void getTargetDefines(const LangOptions &Opts, @@ -167,6 +167,7 @@ public: } bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; bool setCPU(const std::string &Name) override { bool isValid = isValidCPUName(Name); if (isValid) diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/BPF.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/BPF.cpp index 54e34f15532d..cf41a09d76f5 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/BPF.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/BPF.cpp @@ -14,6 +14,7 @@ #include "BPF.h" #include "Targets.h" #include "clang/Basic/MacroBuilder.h" +#include "llvm/ADT/StringRef.h" using namespace clang; using namespace clang::targets; @@ -23,3 +24,14 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts, DefineStd(Builder, "bpf", Opts); Builder.defineMacro("__BPF__"); } + +static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2", + "probe"}; + +bool BPFTargetInfo::isValidCPUName(StringRef Name) const { + return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); +} + +void BPFTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/BPF.h b/contrib/llvm/tools/clang/lib/Basic/Targets/BPF.h index 4dd9cbd9d221..7f97f8189145 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/BPF.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/BPF.h @@ -46,7 +46,14 @@ public: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - bool hasFeature(StringRef Feature) const override { return Feature == "bpf"; } + bool hasFeature(StringRef Feature) const override { + return Feature == "bpf" || Feature == "alu32" || Feature == "dwarfris"; + } + + void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, + bool Enabled) const override { + Features[Name] = Enabled; + } ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } @@ -56,6 +63,7 @@ public: return TargetInfo::VoidPtrBuiltinVaList; } + bool isValidGCCRegisterName(StringRef Name) const override { return true; } ArrayRef<const char *> getGCCRegNames() const override { return None; } bool validateAsmConstraint(const char *&Name, @@ -77,12 +85,9 @@ public: } } - bool isValidCPUName(StringRef Name) const override { - if (Name == "generic" || Name == "v1" || - Name == "v2" || Name == "probe") - return true; - return false; - } + bool isValidCPUName(StringRef Name) const override; + + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; bool setCPU(const std::string &Name) override { StringRef CPUName(Name); diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.cpp index 71d4c1e0f161..0ef1f6db281e 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.cpp @@ -75,7 +75,6 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, bool HexagonTargetInfo::initFeatureMap( llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const { - Features["hvx-double"] = false; Features["long-calls"] = false; return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); @@ -132,6 +131,10 @@ const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { }; bool HexagonTargetInfo::hasFeature(StringRef Feature) const { + std::string VS = "hvxv" + HVXVersion; + if (Feature == VS) + return true; + return llvm::StringSwitch<bool>(Feature) .Case("hexagon", true) .Case("hvx", HasHVX) @@ -141,15 +144,29 @@ bool HexagonTargetInfo::hasFeature(StringRef Feature) const { .Default(false); } +struct CPUSuffix { + llvm::StringLiteral Name; + llvm::StringLiteral Suffix; +}; + +static constexpr CPUSuffix Suffixes[] = { + {{"hexagonv4"}, {"4"}}, {{"hexagonv5"}, {"5"}}, + {{"hexagonv55"}, {"55"}}, {{"hexagonv60"}, {"60"}}, + {{"hexagonv62"}, {"62"}}, {{"hexagonv65"}, {"65"}}, +}; + const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) { - return llvm::StringSwitch<const char *>(Name) - .Case("hexagonv4", "4") - .Case("hexagonv5", "5") - .Case("hexagonv55", "55") - .Case("hexagonv60", "60") - .Case("hexagonv62", "62") - .Case("hexagonv65", "65") - .Default(nullptr); + const CPUSuffix *Item = llvm::find_if( + Suffixes, [Name](const CPUSuffix &S) { return S.Name == Name; }); + if (Item == std::end(Suffixes)) + return nullptr; + return Item->Suffix.data(); +} + +void HexagonTargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + for (const CPUSuffix &Suffix : Suffixes) + Values.push_back(Suffix.Name); } ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const { diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.h b/contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.h index 7b0966457c4b..fb4956a9e53d 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Hexagon.h @@ -112,6 +112,8 @@ public: return getHexagonCPUSuffix(Name); } + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool setCPU(const std::string &Name) override { if (!isValidCPUName(Name)) return false; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Lanai.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/Lanai.cpp index 1d8314af99fb..0e8030c04e5c 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Lanai.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Lanai.cpp @@ -40,6 +40,10 @@ ArrayRef<TargetInfo::GCCRegAlias> LanaiTargetInfo::getGCCRegAliases() const { bool LanaiTargetInfo::isValidCPUName(StringRef Name) const { return llvm::StringSwitch<bool>(Name).Case("v11", true).Default(false); } +void LanaiTargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + Values.emplace_back("v11"); +} bool LanaiTargetInfo::setCPU(const std::string &Name) { CPU = llvm::StringSwitch<CPUKind>(Name).Case("v11", CK_V11).Default(CK_NONE); diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Lanai.h b/contrib/llvm/tools/clang/lib/Basic/Targets/Lanai.h index 5f99c17a5344..b9e6dbe04433 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Lanai.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Lanai.h @@ -65,6 +65,8 @@ public: bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool setCPU(const std::string &Name) override; bool hasFeature(StringRef Feature) const override; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Mips.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/Mips.cpp index a8a1bcc36361..cbd5a01c3da8 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Mips.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Mips.cpp @@ -44,26 +44,19 @@ bool MipsTargetInfo::processorSupportsGPR64() const { return false; } +static constexpr llvm::StringLiteral ValidCPUNames[] = { + {"mips1"}, {"mips2"}, {"mips3"}, {"mips4"}, {"mips5"}, + {"mips32"}, {"mips32r2"}, {"mips32r3"}, {"mips32r5"}, {"mips32r6"}, + {"mips64"}, {"mips64r2"}, {"mips64r3"}, {"mips64r5"}, {"mips64r6"}, + {"octeon"}, {"p5600"}}; + bool MipsTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::StringSwitch<bool>(Name) - .Case("mips1", true) - .Case("mips2", true) - .Case("mips3", true) - .Case("mips4", true) - .Case("mips5", true) - .Case("mips32", true) - .Case("mips32r2", true) - .Case("mips32r3", true) - .Case("mips32r5", true) - .Case("mips32r6", true) - .Case("mips64", true) - .Case("mips64r2", true) - .Case("mips64r3", true) - .Case("mips64r5", true) - .Case("mips64r6", true) - .Case("octeon", true) - .Case("p5600", true) - .Default(false); + return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); +} + +void MipsTargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } void MipsTargetInfo::getTargetDefines(const LangOptions &Opts, @@ -207,9 +200,7 @@ ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const { bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { // microMIPS64R6 backend was removed. - if ((getTriple().getArch() == llvm::Triple::mips64 || - getTriple().getArch() == llvm::Triple::mips64el) && - IsMicromips && (ABI == "n32" || ABI == "n64")) { + if (getTriple().isMIPS64() && IsMicromips && (ABI == "n32" || ABI == "n64")) { Diags.Report(diag::err_target_unsupported_cpu_for_micromips) << CPU; return false; } @@ -229,9 +220,7 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { // FIXME: It's valid to use O32 on a mips64/mips64el triple but the backend // can't handle this yet. It's better to fail here than on the // backend assertion. - if ((getTriple().getArch() == llvm::Triple::mips64 || - getTriple().getArch() == llvm::Triple::mips64el) && - ABI == "o32") { + if (getTriple().isMIPS64() && ABI == "o32") { Diags.Report(diag::err_target_unsupported_abi_for_triple) << ABI << getTriple().str(); return false; @@ -240,9 +229,7 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const { // FIXME: It's valid to use N32/N64 on a mips/mipsel triple but the backend // can't handle this yet. It's better to fail here than on the // backend assertion. - if ((getTriple().getArch() == llvm::Triple::mips || - getTriple().getArch() == llvm::Triple::mipsel) && - (ABI == "n32" || ABI == "n64")) { + if (getTriple().isMIPS32() && (ABI == "n32" || ABI == "n64")) { Diags.Report(diag::err_target_unsupported_abi_for_triple) << ABI << getTriple().str(); return false; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Mips.h b/contrib/llvm/tools/clang/lib/Basic/Targets/Mips.h index 4b61116a3256..11e9ac914430 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Mips.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Mips.h @@ -69,10 +69,7 @@ public: UseIndirectJumpHazard(false), HasFP64(false) { TheCXXABI.set(TargetCXXABI::GenericMIPS); - setABI((getTriple().getArch() == llvm::Triple::mips || - getTriple().getArch() == llvm::Triple::mipsel) - ? "o32" - : "n64"); + setABI(getTriple().isMIPS32() ? "o32" : "n64"); CPU = ABI == "o32" ? "mips32r2" : "mips64r2"; @@ -163,6 +160,7 @@ public: } bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; bool setCPU(const std::string &Name) override { CPU = Name; @@ -391,7 +389,9 @@ public: return llvm::makeArrayRef(NewABIRegAliases); } - bool hasInt128Type() const override { return ABI == "n32" || ABI == "n64"; } + bool hasInt128Type() const override { + return (ABI == "n32" || ABI == "n64") || getTargetOpts().ForceEnableInt128; + } bool validateTarget(DiagnosticsEngine &Diags) const override; }; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/NVPTX.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/NVPTX.cpp index add3b318aeb6..fd4ee1606061 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/NVPTX.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/NVPTX.cpp @@ -40,6 +40,22 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) && "NVPTX only supports 32- and 64-bit modes."); + PTXVersion = 32; + for (const StringRef Feature : Opts.FeaturesAsWritten) { + if (!Feature.startswith("+ptx")) + continue; + PTXVersion = llvm::StringSwitch<unsigned>(Feature) + .Case("+ptx61", 61) + .Case("+ptx60", 60) + .Case("+ptx50", 50) + .Case("+ptx43", 43) + .Case("+ptx42", 42) + .Case("+ptx41", 41) + .Case("+ptx40", 40) + .Case("+ptx32", 32) + .Default(32); + } + TLSSupported = false; VLASupported = false; AddrSpaceMap = &NVPTXAddrSpaceMap; @@ -52,6 +68,9 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, if (TargetPointerWidth == 32) resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"); + else if (Opts.NVPTXUseShortPointers) + resetDataLayout( + "e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"); else resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64"); @@ -145,7 +164,6 @@ ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const { bool NVPTXTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch<bool>(Feature) .Cases("ptx", "nvptx", true) - .Case("satom", GPU >= CudaArch::SM_60) // Atomics w/ scope. .Default(false); } @@ -157,6 +175,21 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, // Set __CUDA_ARCH__ for the GPU specified. std::string CUDAArchCode = [this] { switch (GPU) { + case CudaArch::GFX600: + case CudaArch::GFX601: + case CudaArch::GFX700: + case CudaArch::GFX701: + case CudaArch::GFX702: + case CudaArch::GFX703: + case CudaArch::GFX704: + case CudaArch::GFX801: + case CudaArch::GFX802: + case CudaArch::GFX803: + case CudaArch::GFX810: + case CudaArch::GFX900: + case CudaArch::GFX902: + case CudaArch::LAST: + break; case CudaArch::UNKNOWN: assert(false && "No GPU arch when compiling CUDA device code."); return ""; @@ -186,6 +219,8 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, return "620"; case CudaArch::SM_70: return "700"; + case CudaArch::SM_72: + return "720"; } llvm_unreachable("unhandled CudaArch"); }(); diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/NVPTX.h b/contrib/llvm/tools/clang/lib/Basic/Targets/NVPTX.h index a84870763f54..84d466d2f49f 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/NVPTX.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/NVPTX.h @@ -40,6 +40,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { static const char *const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; CudaArch GPU; + uint32_t PTXVersion; std::unique_ptr<TargetInfo> HostTarget; public: @@ -55,7 +56,8 @@ public: initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const override { - Features["satom"] = GPU >= CudaArch::SM_60; + Features[CudaArchToString(GPU)] = true; + Features["ptx" + std::to_string(PTXVersion)] = true; return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -98,6 +100,12 @@ public: return StringToCudaArch(Name) != CudaArch::UNKNOWN; } + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override { + for (int i = static_cast<int>(CudaArch::SM_20); + i < static_cast<int>(CudaArch::LAST); ++i) + Values.emplace_back(CudaArchToString(static_cast<CudaArch>(i))); + } + bool setCPU(const std::string &Name) override { GPU = StringToCudaArch(Name); return GPU != CudaArch::UNKNOWN; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Nios2.h b/contrib/llvm/tools/clang/lib/Basic/Targets/Nios2.h index aa02f8f6262f..ffeb414d4778 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Nios2.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Nios2.h @@ -56,6 +56,10 @@ public: return Name == "nios2r1" || Name == "nios2r2"; } + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override { + Values.append({"nios2r1", "nios2r2"}); + } + bool setCPU(const std::string &Name) override { if (isValidCPUName(Name)) { CPU = Name; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/OSTargets.h b/contrib/llvm/tools/clang/lib/Basic/Targets/OSTargets.h index 5af63615dc5e..d0354784acf9 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/OSTargets.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/OSTargets.h @@ -95,16 +95,22 @@ public: if (Triple.isMacOSX()) this->TLSSupported = !Triple.isMacOSXVersionLT(10, 7); else if (Triple.isiOS()) { - // 64-bit iOS supported it from 8 onwards, 32-bit from 9 onwards. - if (Triple.getArch() == llvm::Triple::x86_64 || - Triple.getArch() == llvm::Triple::aarch64) + // 64-bit iOS supported it from 8 onwards, 32-bit device from 9 onwards, + // 32-bit simulator from 10 onwards. + if (Triple.isArch64Bit()) this->TLSSupported = !Triple.isOSVersionLT(8); - else if (Triple.getArch() == llvm::Triple::x86 || - Triple.getArch() == llvm::Triple::arm || - Triple.getArch() == llvm::Triple::thumb) - this->TLSSupported = !Triple.isOSVersionLT(9); - } else if (Triple.isWatchOS()) - this->TLSSupported = !Triple.isOSVersionLT(2); + else if (Triple.isArch32Bit()) { + if (!Triple.isSimulatorEnvironment()) + this->TLSSupported = !Triple.isOSVersionLT(9); + else + this->TLSSupported = !Triple.isOSVersionLT(10); + } + } else if (Triple.isWatchOS()) { + if (!Triple.isSimulatorEnvironment()) + this->TLSSupported = !Triple.isOSVersionLT(2); + else + this->TLSSupported = !Triple.isOSVersionLT(3); + } this->MCountName = "\01mcount"; } @@ -363,7 +369,7 @@ protected: public: NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo<Target>(Triple, Opts) { - this->MCountName = "_mcount"; + this->MCountName = "__mcount"; } }; @@ -479,6 +485,7 @@ public: default: case llvm::Triple::x86_64: this->MCountName = ".mcount"; + this->NewAlign = 256; break; } } @@ -544,13 +551,24 @@ protected: Builder.defineMacro("_LARGEFILE_SOURCE"); Builder.defineMacro("_LARGEFILE64_SOURCE"); Builder.defineMacro("__EXTENSIONS__"); - Builder.defineMacro("_REENTRANT"); + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); } public: SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo<Target>(Triple, Opts) { // FIXME: WIntType should be SignedLong + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->HasFloat128 = true; + break; + } } }; @@ -599,8 +617,10 @@ protected: Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1)); if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) { - if (Opts.CPlusPlus17) - Builder.defineMacro("_MSVC_LANG", "201403L"); + if (Opts.CPlusPlus2a) + Builder.defineMacro("_MSVC_LANG", "201704L"); + else if (Opts.CPlusPlus17) + Builder.defineMacro("_MSVC_LANG", "201703L"); else if (Opts.CPlusPlus14) Builder.defineMacro("_MSVC_LANG", "201402L"); } diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/PPC.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/PPC.cpp index a44aa0cd96f0..b4eb3b1b97b7 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/PPC.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/PPC.cpp @@ -15,7 +15,6 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" -#include "llvm/ADT/StringSwitch.h" using namespace clang; using namespace clang::targets; @@ -96,7 +95,7 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("_CALL_ELF", "2"); // This typically is only for a new enough linker (bfd >= 2.16.2 or gold), but - // our suppport post-dates this and it should work on all 64-bit ppc linux + // our support post-dates this and it should work on all 64-bit ppc linux // platforms. It is guaranteed to work on all elfv2 platforms. if (getTriple().getOS() == llvm::Triple::Linux && PointerWidth == 64) Builder.defineMacro("_CALL_LINUX", "1"); @@ -116,111 +115,37 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64)) Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16"); - // CPU identification. - ArchDefineTypes defs = - (ArchDefineTypes)llvm::StringSwitch<int>(CPU) - .Case("440", ArchDefineName) - .Case("450", ArchDefineName | ArchDefine440) - .Case("601", ArchDefineName) - .Case("602", ArchDefineName | ArchDefinePpcgr) - .Case("603", ArchDefineName | ArchDefinePpcgr) - .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) - .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) - .Case("604", ArchDefineName | ArchDefinePpcgr) - .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr) - .Case("620", ArchDefineName | ArchDefinePpcgr) - .Case("630", ArchDefineName | ArchDefinePpcgr) - .Case("7400", ArchDefineName | ArchDefinePpcgr) - .Case("7450", ArchDefineName | ArchDefinePpcgr) - .Case("750", ArchDefineName | ArchDefinePpcgr) - .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) - .Case("a2", ArchDefineA2) - .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q) - .Case("pwr3", ArchDefinePpcgr) - .Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq) - .Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) - .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4 | - ArchDefinePpcgr | ArchDefinePpcsq) - .Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5 | - ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) - .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x | - ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) - .Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6 | - ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | - ArchDefinePpcgr | ArchDefinePpcsq) - .Case("pwr8", ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x | - ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | - ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) - .Case("pwr9", ArchDefineName | ArchDefinePwr8 | ArchDefinePwr7 | - ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | - ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) - .Case("power3", ArchDefinePpcgr) - .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) - .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) - .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | - ArchDefinePpcgr | ArchDefinePpcsq) - .Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | - ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) - .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | - ArchDefinePwr5 | ArchDefinePwr4 | - ArchDefinePpcgr | ArchDefinePpcsq) - .Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 | - ArchDefinePwr5x | ArchDefinePwr5 | - ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) - .Case("power8", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x | - ArchDefinePwr6 | ArchDefinePwr5x | - ArchDefinePwr5 | ArchDefinePwr4 | - ArchDefinePpcgr | ArchDefinePpcsq) - .Case("power9", ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 | - ArchDefinePwr6x | ArchDefinePwr6 | - ArchDefinePwr5x | ArchDefinePwr5 | - ArchDefinePwr4 | ArchDefinePpcgr | - ArchDefinePpcsq) - // powerpc64le automatically defaults to at least power8. - .Case("ppc64le", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x | - ArchDefinePwr6 | ArchDefinePwr5x | - ArchDefinePwr5 | ArchDefinePwr4 | - ArchDefinePpcgr | ArchDefinePpcsq) - .Default(ArchDefineNone); - - if (defs & ArchDefineName) + if (ArchDefs & ArchDefineName) Builder.defineMacro(Twine("_ARCH_", StringRef(CPU).upper())); - if (defs & ArchDefinePpcgr) + if (ArchDefs & ArchDefinePpcgr) Builder.defineMacro("_ARCH_PPCGR"); - if (defs & ArchDefinePpcsq) + if (ArchDefs & ArchDefinePpcsq) Builder.defineMacro("_ARCH_PPCSQ"); - if (defs & ArchDefine440) + if (ArchDefs & ArchDefine440) Builder.defineMacro("_ARCH_440"); - if (defs & ArchDefine603) + if (ArchDefs & ArchDefine603) Builder.defineMacro("_ARCH_603"); - if (defs & ArchDefine604) + if (ArchDefs & ArchDefine604) Builder.defineMacro("_ARCH_604"); - if (defs & ArchDefinePwr4) + if (ArchDefs & ArchDefinePwr4) Builder.defineMacro("_ARCH_PWR4"); - if (defs & ArchDefinePwr5) + if (ArchDefs & ArchDefinePwr5) Builder.defineMacro("_ARCH_PWR5"); - if (defs & ArchDefinePwr5x) + if (ArchDefs & ArchDefinePwr5x) Builder.defineMacro("_ARCH_PWR5X"); - if (defs & ArchDefinePwr6) + if (ArchDefs & ArchDefinePwr6) Builder.defineMacro("_ARCH_PWR6"); - if (defs & ArchDefinePwr6x) + if (ArchDefs & ArchDefinePwr6x) Builder.defineMacro("_ARCH_PWR6X"); - if (defs & ArchDefinePwr7) + if (ArchDefs & ArchDefinePwr7) Builder.defineMacro("_ARCH_PWR7"); - if (defs & ArchDefinePwr8) + if (ArchDefs & ArchDefinePwr8) Builder.defineMacro("_ARCH_PWR8"); - if (defs & ArchDefinePwr9) + if (ArchDefs & ArchDefinePwr9) Builder.defineMacro("_ARCH_PWR9"); - if (defs & ArchDefineA2) + if (ArchDefs & ArchDefineA2) Builder.defineMacro("_ARCH_A2"); - if (defs & ArchDefineA2q) { + if (ArchDefs & ArchDefineA2q) { Builder.defineMacro("_ARCH_A2Q"); Builder.defineMacro("_ARCH_QP"); } @@ -384,6 +309,14 @@ bool PPCTargetInfo::initFeatureMap( if (!ppcUserFeaturesCheck(Diags, FeaturesVec)) return false; + if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) && + std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") != + FeaturesVec.end()) { + // We have __float128 on PPC but not power 9 and above. + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU; + return false; + } + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -479,57 +412,25 @@ ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { return llvm::makeArrayRef(GCCRegAliases); } +static constexpr llvm::StringLiteral ValidCPUNames[] = { + {"generic"}, {"440"}, {"450"}, {"601"}, {"602"}, + {"603"}, {"603e"}, {"603ev"}, {"604"}, {"604e"}, + {"620"}, {"630"}, {"g3"}, {"7400"}, {"g4"}, + {"7450"}, {"g4+"}, {"750"}, {"970"}, {"g5"}, + {"a2"}, {"a2q"}, {"e500mc"}, {"e5500"}, {"power3"}, + {"pwr3"}, {"power4"}, {"pwr4"}, {"power5"}, {"pwr5"}, + {"power5x"}, {"pwr5x"}, {"power6"}, {"pwr6"}, {"power6x"}, + {"pwr6x"}, {"power7"}, {"pwr7"}, {"power8"}, {"pwr8"}, + {"power9"}, {"pwr9"}, {"powerpc"}, {"ppc"}, {"powerpc64"}, + {"ppc64"}, {"powerpc64le"}, {"ppc64le"}, +}; + bool PPCTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::StringSwitch<bool>(Name) - .Case("generic", true) - .Case("440", true) - .Case("450", true) - .Case("601", true) - .Case("602", true) - .Case("603", true) - .Case("603e", true) - .Case("603ev", true) - .Case("604", true) - .Case("604e", true) - .Case("620", true) - .Case("630", true) - .Case("g3", true) - .Case("7400", true) - .Case("g4", true) - .Case("7450", true) - .Case("g4+", true) - .Case("750", true) - .Case("970", true) - .Case("g5", true) - .Case("a2", true) - .Case("a2q", true) - .Case("e500mc", true) - .Case("e5500", true) - .Case("power3", true) - .Case("pwr3", true) - .Case("power4", true) - .Case("pwr4", true) - .Case("power5", true) - .Case("pwr5", true) - .Case("power5x", true) - .Case("pwr5x", true) - .Case("power6", true) - .Case("pwr6", true) - .Case("power6x", true) - .Case("pwr6x", true) - .Case("power7", true) - .Case("pwr7", true) - .Case("power8", true) - .Case("pwr8", true) - .Case("power9", true) - .Case("pwr9", true) - .Case("powerpc", true) - .Case("ppc", true) - .Case("powerpc64", true) - .Case("ppc64", true) - .Case("powerpc64le", true) - .Case("ppc64le", true) - .Default(false); + return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); +} + +void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } void PPCTargetInfo::adjust(LangOptions &Opts) { diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/PPC.h b/contrib/llvm/tools/clang/lib/Basic/Targets/PPC.h index 04bef258e386..439c73a0e326 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/PPC.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/PPC.h @@ -18,6 +18,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Compiler.h" namespace clang { @@ -25,39 +26,8 @@ namespace targets { // PPC abstract base class class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { - static const Builtin::Info BuiltinInfo[]; - static const char *const GCCRegNames[]; - static const TargetInfo::GCCRegAlias GCCRegAliases[]; - std::string CPU; - - // Target cpu features. - bool HasAltivec; - bool HasVSX; - bool HasP8Vector; - bool HasP8Crypto; - bool HasDirectMove; - bool HasQPX; - bool HasHTM; - bool HasBPERMD; - bool HasExtDiv; - bool HasP9Vector; - -protected: - std::string ABI; - -public: - PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) - : TargetInfo(Triple), HasAltivec(false), HasVSX(false), - HasP8Vector(false), HasP8Crypto(false), HasDirectMove(false), - HasQPX(false), HasHTM(false), HasBPERMD(false), HasExtDiv(false), - HasP9Vector(false) { - SuitableAlign = 128; - SimdDefaultAlign = 128; - LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); - } - /// \brief Flags for architecture specific defines. + /// Flags for architecture specific defines. typedef enum { ArchDefineNone = 0, ArchDefineName = 1 << 0, // <name> is substituted for arch name. @@ -78,6 +48,37 @@ public: ArchDefineA2q = 1 << 15 } ArchDefineTypes; + + ArchDefineTypes ArchDefs = ArchDefineNone; + static const Builtin::Info BuiltinInfo[]; + static const char *const GCCRegNames[]; + static const TargetInfo::GCCRegAlias GCCRegAliases[]; + std::string CPU; + + // Target cpu features. + bool HasAltivec = false; + bool HasVSX = false; + bool HasP8Vector = false; + bool HasP8Crypto = false; + bool HasDirectMove = false; + bool HasQPX = false; + bool HasHTM = false; + bool HasBPERMD = false; + bool HasExtDiv = false; + bool HasP9Vector = false; + +protected: + std::string ABI; + +public: + PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + SuitableAlign = 128; + SimdDefaultAlign = 128; + LongDoubleWidth = LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); + } + // Set the language option for altivec based on our value. void adjust(LangOptions &Opts) override; @@ -86,11 +87,66 @@ public: // 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell, // titan, rs64. bool isValidCPUName(StringRef Name) const override; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; bool setCPU(const std::string &Name) override { bool CPUKnown = isValidCPUName(Name); - if (CPUKnown) + if (CPUKnown) { CPU = Name; + + // CPU identification. + ArchDefs = + (ArchDefineTypes)llvm::StringSwitch<int>(CPU) + .Case("440", ArchDefineName) + .Case("450", ArchDefineName | ArchDefine440) + .Case("601", ArchDefineName) + .Case("602", ArchDefineName | ArchDefinePpcgr) + .Case("603", ArchDefineName | ArchDefinePpcgr) + .Case("603e", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) + .Case("603ev", ArchDefineName | ArchDefine603 | ArchDefinePpcgr) + .Case("604", ArchDefineName | ArchDefinePpcgr) + .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr) + .Case("620", ArchDefineName | ArchDefinePpcgr) + .Case("630", ArchDefineName | ArchDefinePpcgr) + .Case("7400", ArchDefineName | ArchDefinePpcgr) + .Case("7450", ArchDefineName | ArchDefinePpcgr) + .Case("750", ArchDefineName | ArchDefinePpcgr) + .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr | + ArchDefinePpcsq) + .Case("a2", ArchDefineA2) + .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q) + .Cases("power3", "pwr3", ArchDefinePpcgr) + .Cases("power4", "pwr4", + ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Cases("power5", "pwr5", + ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | + ArchDefinePpcsq) + .Cases("power5x", "pwr5x", + ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | + ArchDefinePpcgr | ArchDefinePpcsq) + .Cases("power6", "pwr6", + ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | + ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Cases("power6x", "pwr6x", + ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | + ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | + ArchDefinePpcsq) + .Cases("power7", "pwr7", + ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 | + ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | + ArchDefinePpcgr | ArchDefinePpcsq) + // powerpc64le automatically defaults to at least power8. + .Cases("power8", "pwr8", "ppc64le", + ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x | + ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | + ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Cases("power9", "pwr9", + ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 | + ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | + ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | + ArchDefinePpcsq) + .Default(ArchDefineNone); + } return CPUKnown; } @@ -310,10 +366,6 @@ public: LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); break; - case llvm::Triple::NetBSD: - IntMaxType = SignedLongLong; - Int64Type = SignedLongLong; - break; default: break; } @@ -334,6 +386,15 @@ public: } return false; } + + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + case CC_Swift: + return CCCR_OK; + default: + return CCCR_Warning; + } + } }; class LLVM_LIBRARY_VISIBILITY DarwinPPC32TargetInfo diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/RISCV.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/RISCV.cpp new file mode 100644 index 000000000000..7eb5e6a686a9 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/RISCV.cpp @@ -0,0 +1,104 @@ +//===--- RISCV.cpp - Implement RISCV target feature support ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements RISCV TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#include "RISCV.h" +#include "clang/Basic/MacroBuilder.h" +#include "llvm/ADT/StringSwitch.h" + +using namespace clang; +using namespace clang::targets; + +ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const { + static const char *const GCCRegNames[] = { + "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", + "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", + "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", + "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31"}; + return llvm::makeArrayRef(GCCRegNames); +} + +ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const { + static const TargetInfo::GCCRegAlias GCCRegAliases[] = { + {{"zero"}, "x0"}, {{"ra"}, "x1"}, {{"sp"}, "x2"}, {{"gp"}, "x3"}, + {{"tp"}, "x4"}, {{"t0"}, "x5"}, {{"t1"}, "x6"}, {{"t2"}, "x7"}, + {{"s0"}, "x8"}, {{"s1"}, "x9"}, {{"a0"}, "x10"}, {{"a1"}, "x11"}, + {{"a2"}, "x12"}, {{"a3"}, "x13"}, {{"a4"}, "x15"}, {{"a5"}, "x15"}, + {{"a6"}, "x16"}, {{"a7"}, "x17"}, {{"s2"}, "x18"}, {{"s3"}, "x19"}, + {{"s4"}, "x20"}, {{"s5"}, "x21"}, {{"s6"}, "x22"}, {{"s7"}, "x23"}, + {{"s8"}, "x24"}, {{"s9"}, "x25"}, {{"s10"}, "x26"}, {{"s11"}, "x27"}, + {{"t3"}, "x28"}, {{"t4"}, "x29"}, {{"t5"}, "x30"}, {{"t6"}, "x31"}}; + return llvm::makeArrayRef(GCCRegAliases); +} + +void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + Builder.defineMacro("__ELF__"); + Builder.defineMacro("__riscv"); + bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; + Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32"); + // TODO: modify when more code models and ABIs are supported. + Builder.defineMacro("__riscv_cmodel_medlow"); + Builder.defineMacro("__riscv_float_abi_soft"); + + if (HasM) { + Builder.defineMacro("__riscv_mul"); + Builder.defineMacro("__riscv_div"); + Builder.defineMacro("__riscv_muldiv"); + } + + if (HasA) + Builder.defineMacro("__riscv_atomic"); + + if (HasF || HasD) { + Builder.defineMacro("__riscv_flen", HasD ? "64" : "32"); + Builder.defineMacro("__riscv_fdiv"); + Builder.defineMacro("__riscv_fsqrt"); + } + + if (HasC) + Builder.defineMacro("__riscv_compressed"); +} + +/// Return true if has this feature, need to sync with handleTargetFeatures. +bool RISCVTargetInfo::hasFeature(StringRef Feature) const { + bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64; + return llvm::StringSwitch<bool>(Feature) + .Case("riscv", true) + .Case("riscv32", !Is64Bit) + .Case("riscv64", Is64Bit) + .Case("m", HasM) + .Case("a", HasA) + .Case("f", HasF) + .Case("d", HasD) + .Case("c", HasC) + .Default(false); +} + +/// Perform initialization based on the user configured set of features. +bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { + for (const auto &Feature : Features) { + if (Feature == "+m") + HasM = true; + else if (Feature == "+a") + HasA = true; + else if (Feature == "+f") + HasF = true; + else if (Feature == "+d") + HasD = true; + else if (Feature == "+c") + HasC = true; + } + + return true; +} diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/RISCV.h b/contrib/llvm/tools/clang/lib/Basic/Targets/RISCV.h new file mode 100644 index 000000000000..f83aae539391 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/RISCV.h @@ -0,0 +1,114 @@ +//===--- RISCV.h - Declare RISCV target feature support ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares RISCV TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H +#define LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H + +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Compiler.h" + +namespace clang { +namespace targets { + +// RISC-V Target +class RISCVTargetInfo : public TargetInfo { +protected: + std::string ABI; + bool HasM; + bool HasA; + bool HasF; + bool HasD; + bool HasC; + +public: + RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple), HasM(false), HasA(false), HasF(false), + HasD(false), HasC(false) { + TLSSupported = false; + LongDoubleWidth = 128; + LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + SuitableAlign = 128; + WCharType = SignedInt; + WIntType = UnsignedInt; + } + + StringRef getABI() const override { return ABI; } + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override; + + ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + + const char *getClobbers() const override { return ""; } + + ArrayRef<const char *> getGCCRegNames() const override; + + ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override { + return false; + } + + bool hasFeature(StringRef Feature) const override; + + bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) override; +}; +class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { +public: + RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : RISCVTargetInfo(Triple, Opts) { + IntPtrType = SignedInt; + PtrDiffType = SignedInt; + SizeType = UnsignedInt; + resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128"); + } + + bool setABI(const std::string &Name) override { + // TODO: support ilp32f and ilp32d ABIs. + if (Name == "ilp32") { + ABI = Name; + return true; + } + return false; + } +}; +class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo { +public: + RISCV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : RISCVTargetInfo(Triple, Opts) { + LongWidth = LongAlign = PointerWidth = PointerAlign = 64; + IntMaxType = Int64Type = SignedLong; + resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128"); + } + + bool setABI(const std::string &Name) override { + // TODO: support lp64f and lp64d ABIs. + if (Name == "lp64") { + ABI = Name; + return true; + } + return false; + } +}; +} // namespace targets +} // namespace clang + +#endif // LLVM_CLANG_LIB_BASIC_TARGETS_RISCV_H diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/SPIR.h b/contrib/llvm/tools/clang/lib/Basic/Targets/SPIR.h index c384d4260ca9..9815292fc276 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/SPIR.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/SPIR.h @@ -47,6 +47,7 @@ public: LongWidth = LongAlign = 64; AddrSpaceMap = &SPIRAddrSpaceMap; UseAddrSpaceMapMangling = true; + HasLegalHalfType = true; // Define available target features // These must be defined in sorted order! NoAsmVariants = true; @@ -59,6 +60,10 @@ public: return Feature == "spir"; } + // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is + // memcpy as per section 3 of the SPIR spec. + bool useFP16ConversionIntrinsics() const override { return false; } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } const char *getClobbers() const override { return ""; } diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.cpp index 429c1ee3a23c..ee4f309363af 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.cpp @@ -20,9 +20,17 @@ using namespace clang; using namespace clang::targets; const char *const SparcTargetInfo::GCCRegNames[] = { + // Integer registers "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", - "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" + "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + + // Floating-point registers + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", + "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", + "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32", + "f34", "f36", "f38", "f40", "f42", "f44", "f46", "f48", "f50", "f52", "f54", + "f56", "f58", "f60", "f62", }; ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const { @@ -51,49 +59,81 @@ bool SparcTargetInfo::hasFeature(StringRef Feature) const { .Default(false); } +struct SparcCPUInfo { + llvm::StringLiteral Name; + SparcTargetInfo::CPUKind Kind; + SparcTargetInfo::CPUGeneration Generation; +}; + +static constexpr SparcCPUInfo CPUInfo[] = { + {{"v8"}, SparcTargetInfo::CK_V8, SparcTargetInfo::CG_V8}, + {{"supersparc"}, SparcTargetInfo::CK_SUPERSPARC, SparcTargetInfo::CG_V8}, + {{"sparclite"}, SparcTargetInfo::CK_SPARCLITE, SparcTargetInfo::CG_V8}, + {{"f934"}, SparcTargetInfo::CK_F934, SparcTargetInfo::CG_V8}, + {{"hypersparc"}, SparcTargetInfo::CK_HYPERSPARC, SparcTargetInfo::CG_V8}, + {{"sparclite86x"}, + SparcTargetInfo::CK_SPARCLITE86X, + SparcTargetInfo::CG_V8}, + {{"sparclet"}, SparcTargetInfo::CK_SPARCLET, SparcTargetInfo::CG_V8}, + {{"tsc701"}, SparcTargetInfo::CK_TSC701, SparcTargetInfo::CG_V8}, + {{"v9"}, SparcTargetInfo::CK_V9, SparcTargetInfo::CG_V9}, + {{"ultrasparc"}, SparcTargetInfo::CK_ULTRASPARC, SparcTargetInfo::CG_V9}, + {{"ultrasparc3"}, SparcTargetInfo::CK_ULTRASPARC3, SparcTargetInfo::CG_V9}, + {{"niagara"}, SparcTargetInfo::CK_NIAGARA, SparcTargetInfo::CG_V9}, + {{"niagara2"}, SparcTargetInfo::CK_NIAGARA2, SparcTargetInfo::CG_V9}, + {{"niagara3"}, SparcTargetInfo::CK_NIAGARA3, SparcTargetInfo::CG_V9}, + {{"niagara4"}, SparcTargetInfo::CK_NIAGARA4, SparcTargetInfo::CG_V9}, + {{"ma2100"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, + {{"ma2150"}, SparcTargetInfo::CK_MYRIAD2150, SparcTargetInfo::CG_V8}, + {{"ma2155"}, SparcTargetInfo::CK_MYRIAD2155, SparcTargetInfo::CG_V8}, + {{"ma2450"}, SparcTargetInfo::CK_MYRIAD2450, SparcTargetInfo::CG_V8}, + {{"ma2455"}, SparcTargetInfo::CK_MYRIAD2455, SparcTargetInfo::CG_V8}, + {{"ma2x5x"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, + {{"ma2080"}, SparcTargetInfo::CK_MYRIAD2080, SparcTargetInfo::CG_V8}, + {{"ma2085"}, SparcTargetInfo::CK_MYRIAD2085, SparcTargetInfo::CG_V8}, + {{"ma2480"}, SparcTargetInfo::CK_MYRIAD2480, SparcTargetInfo::CG_V8}, + {{"ma2485"}, SparcTargetInfo::CK_MYRIAD2485, SparcTargetInfo::CG_V8}, + {{"ma2x8x"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, + // FIXME: the myriad2[.n] spellings are obsolete, + // but a grace period is needed to allow updating dependent builds. + {{"myriad2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, + {{"myriad2.1"}, SparcTargetInfo::CK_MYRIAD2100, SparcTargetInfo::CG_V8}, + {{"myriad2.2"}, SparcTargetInfo::CK_MYRIAD2x5x, SparcTargetInfo::CG_V8}, + {{"myriad2.3"}, SparcTargetInfo::CK_MYRIAD2x8x, SparcTargetInfo::CG_V8}, + {{"leon2"}, SparcTargetInfo::CK_LEON2, SparcTargetInfo::CG_V8}, + {{"at697e"}, SparcTargetInfo::CK_LEON2_AT697E, SparcTargetInfo::CG_V8}, + {{"at697f"}, SparcTargetInfo::CK_LEON2_AT697F, SparcTargetInfo::CG_V8}, + {{"leon3"}, SparcTargetInfo::CK_LEON3, SparcTargetInfo::CG_V8}, + {{"ut699"}, SparcTargetInfo::CK_LEON3_UT699, SparcTargetInfo::CG_V8}, + {{"gr712rc"}, SparcTargetInfo::CK_LEON3_GR712RC, SparcTargetInfo::CG_V8}, + {{"leon4"}, SparcTargetInfo::CK_LEON4, SparcTargetInfo::CG_V8}, + {{"gr740"}, SparcTargetInfo::CK_LEON4_GR740, SparcTargetInfo::CG_V8}, +}; + +SparcTargetInfo::CPUGeneration +SparcTargetInfo::getCPUGeneration(CPUKind Kind) const { + if (Kind == CK_GENERIC) + return CG_V8; + const SparcCPUInfo *Item = llvm::find_if( + CPUInfo, [Kind](const SparcCPUInfo &Info) { return Info.Kind == Kind; }); + if (Item == std::end(CPUInfo)) + llvm_unreachable("Unexpected CPU kind"); + return Item->Generation; +} + SparcTargetInfo::CPUKind SparcTargetInfo::getCPUKind(StringRef Name) const { - return llvm::StringSwitch<CPUKind>(Name) - .Case("v8", CK_V8) - .Case("supersparc", CK_SUPERSPARC) - .Case("sparclite", CK_SPARCLITE) - .Case("f934", CK_F934) - .Case("hypersparc", CK_HYPERSPARC) - .Case("sparclite86x", CK_SPARCLITE86X) - .Case("sparclet", CK_SPARCLET) - .Case("tsc701", CK_TSC701) - .Case("v9", CK_V9) - .Case("ultrasparc", CK_ULTRASPARC) - .Case("ultrasparc3", CK_ULTRASPARC3) - .Case("niagara", CK_NIAGARA) - .Case("niagara2", CK_NIAGARA2) - .Case("niagara3", CK_NIAGARA3) - .Case("niagara4", CK_NIAGARA4) - .Case("ma2100", CK_MYRIAD2100) - .Case("ma2150", CK_MYRIAD2150) - .Case("ma2155", CK_MYRIAD2155) - .Case("ma2450", CK_MYRIAD2450) - .Case("ma2455", CK_MYRIAD2455) - .Case("ma2x5x", CK_MYRIAD2x5x) - .Case("ma2080", CK_MYRIAD2080) - .Case("ma2085", CK_MYRIAD2085) - .Case("ma2480", CK_MYRIAD2480) - .Case("ma2485", CK_MYRIAD2485) - .Case("ma2x8x", CK_MYRIAD2x8x) - // FIXME: the myriad2[.n] spellings are obsolete, - // but a grace period is needed to allow updating dependent builds. - .Case("myriad2", CK_MYRIAD2x5x) - .Case("myriad2.1", CK_MYRIAD2100) - .Case("myriad2.2", CK_MYRIAD2x5x) - .Case("myriad2.3", CK_MYRIAD2x8x) - .Case("leon2", CK_LEON2) - .Case("at697e", CK_LEON2_AT697E) - .Case("at697f", CK_LEON2_AT697F) - .Case("leon3", CK_LEON3) - .Case("ut699", CK_LEON3_UT699) - .Case("gr712rc", CK_LEON3_GR712RC) - .Case("leon4", CK_LEON4) - .Case("gr740", CK_LEON4_GR740) - .Default(CK_GENERIC); + const SparcCPUInfo *Item = llvm::find_if( + CPUInfo, [Name](const SparcCPUInfo &Info) { return Info.Name == Name; }); + + if (Item == std::end(CPUInfo)) + return CK_GENERIC; + return Item->Kind; +} + +void SparcTargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + for (const SparcCPUInfo &Info : CPUInfo) + Values.push_back(Info.Name); } void SparcTargetInfo::getTargetDefines(const LangOptions &Opts, @@ -178,6 +218,13 @@ void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro(MyriadArchValue, "1"); Builder.defineMacro(MyriadArchValue + "__", "1"); } + if (Myriad2Value == "2") { + Builder.defineMacro("__ma2x5x", "1"); + Builder.defineMacro("__ma2x5x__", "1"); + } else if (Myriad2Value == "3") { + Builder.defineMacro("__ma2x8x", "1"); + Builder.defineMacro("__ma2x8x__", "1"); + } Builder.defineMacro("__myriad2__", Myriad2Value); Builder.defineMacro("__myriad2", Myriad2Value); } @@ -195,3 +242,10 @@ void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__sparcv9__"); } } + +void SparcV9TargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + for (const SparcCPUInfo &Info : CPUInfo) + if (Info.Generation == CG_V9) + Values.push_back(Info.Name); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.h b/contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.h index aacc26119dfb..af2189f21468 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/Sparc.h @@ -1,4 +1,4 @@ -//===--- Sparc.h - Declare Sparc target feature support -------------------===// +//===--- Sparc.h - declare sparc target feature support ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -131,48 +131,7 @@ public: CG_V9, }; - CPUGeneration getCPUGeneration(CPUKind Kind) const { - switch (Kind) { - case CK_GENERIC: - case CK_V8: - case CK_SUPERSPARC: - case CK_SPARCLITE: - case CK_F934: - case CK_HYPERSPARC: - case CK_SPARCLITE86X: - case CK_SPARCLET: - case CK_TSC701: - case CK_MYRIAD2100: - case CK_MYRIAD2150: - case CK_MYRIAD2155: - case CK_MYRIAD2450: - case CK_MYRIAD2455: - case CK_MYRIAD2x5x: - case CK_MYRIAD2080: - case CK_MYRIAD2085: - case CK_MYRIAD2480: - case CK_MYRIAD2485: - case CK_MYRIAD2x8x: - case CK_LEON2: - case CK_LEON2_AT697E: - case CK_LEON2_AT697F: - case CK_LEON3: - case CK_LEON3_UT699: - case CK_LEON3_GR712RC: - case CK_LEON4: - case CK_LEON4_GR740: - return CG_V8; - case CK_V9: - case CK_ULTRASPARC: - case CK_ULTRASPARC3: - case CK_NIAGARA: - case CK_NIAGARA2: - case CK_NIAGARA3: - case CK_NIAGARA4: - return CG_V9; - } - llvm_unreachable("Unexpected CPU kind"); - } + CPUGeneration getCPUGeneration(CPUKind Kind) const; CPUKind getCPUKind(StringRef Name) const; @@ -180,6 +139,8 @@ public: return getCPUKind(Name) != CK_GENERIC; } + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool setCPU(const std::string &Name) override { CPU = getCPUKind(Name); return CPU != CK_GENERIC; @@ -259,6 +220,8 @@ public: return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9; } + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool setCPU(const std::string &Name) override { if (!SparcTargetInfo::setCPU(Name)) return false; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/SystemZ.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/SystemZ.cpp index 98f3ae2f72b4..6f06f1fc760c 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/SystemZ.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/SystemZ.cpp @@ -30,15 +30,30 @@ const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = { }; const char *const SystemZTargetInfo::GCCRegNames[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", - "r11", "r12", "r13", "r14", "r15", "f0", "f2", "f4", "f6", "f1", "f3", - "f5", "f7", "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15" + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "f0", "f2", "f4", "f6", "f1", "f3", "f5", "f7", + "f8", "f10", "f12", "f14", "f9", "f11", "f13", "f15", + /*ap*/"", "cc", /*fp*/"", /*rp*/"", "a0", "a1", + "v16", "v18", "v20", "v22", "v17", "v19", "v21", "v23", + "v24", "v26", "v28", "v30", "v25", "v27", "v29", "v31" +}; + +const TargetInfo::AddlRegName GCCAddlRegNames[] = { + {{"v0"}, 16}, {{"v2"}, 17}, {{"v4"}, 18}, {{"v6"}, 19}, + {{"v1"}, 20}, {{"v3"}, 21}, {{"v5"}, 22}, {{"v7"}, 23}, + {{"v8"}, 24}, {{"v10"}, 25}, {{"v12"}, 26}, {{"v14"}, 27}, + {{"v9"}, 28}, {{"v11"}, 29}, {{"v13"}, 30}, {{"v15"}, 31} }; ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const { return llvm::makeArrayRef(GCCRegNames); } +ArrayRef<TargetInfo::AddlRegName> SystemZTargetInfo::getGCCAddlRegNames() const { + return llvm::makeArrayRef(GCCAddlRegNames); +} + bool SystemZTargetInfo::validateAsmConstraint( const char *&Name, TargetInfo::ConstraintInfo &Info) const { switch (*Name) { @@ -48,6 +63,7 @@ bool SystemZTargetInfo::validateAsmConstraint( case 'a': // Address register case 'd': // Data register (equivalent to 'r') case 'f': // Floating-point register + case 'v': // Vector register Info.setAllowsRegister(); return true; @@ -67,14 +83,32 @@ bool SystemZTargetInfo::validateAsmConstraint( } } -int SystemZTargetInfo::getISARevision(const StringRef &Name) const { - return llvm::StringSwitch<int>(Name) - .Cases("arch8", "z10", 8) - .Cases("arch9", "z196", 9) - .Cases("arch10", "zEC12", 10) - .Cases("arch11", "z13", 11) - .Cases("arch12", "z14", 12) - .Default(-1); +struct ISANameRevision { + llvm::StringLiteral Name; + int ISARevisionID; +}; +static constexpr ISANameRevision ISARevisions[] = { + {{"arch8"}, 8}, {{"z10"}, 8}, + {{"arch9"}, 9}, {{"z196"}, 9}, + {{"arch10"}, 10}, {{"zEC12"}, 10}, + {{"arch11"}, 11}, {{"z13"}, 11}, + {{"arch12"}, 12}, {{"z14"}, 12} +}; + +int SystemZTargetInfo::getISARevision(StringRef Name) const { + const auto Rev = + llvm::find_if(ISARevisions, [Name](const ISANameRevision &CR) { + return CR.Name == Name; + }); + if (Rev == std::end(ISARevisions)) + return -1; + return Rev->ISARevisionID; +} + +void SystemZTargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + for (const ISANameRevision &Rev : ISARevisions) + Values.push_back(Rev.Name); } bool SystemZTargetInfo::hasFeature(StringRef Feature) const { diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/SystemZ.h b/contrib/llvm/tools/clang/lib/Basic/Targets/SystemZ.h index 3023c1d2ea26..842316005ed9 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/SystemZ.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/SystemZ.h @@ -62,6 +62,8 @@ public: return None; } + ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; + bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; @@ -74,12 +76,14 @@ public: return TargetInfo::SystemZBuiltinVaList; } - int getISARevision(const StringRef &Name) const; + int getISARevision(StringRef Name) const; bool isValidCPUName(StringRef Name) const override { return getISARevision(Name) != -1; } + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool setCPU(const std::string &Name) override { CPU = Name; ISARevision = getISARevision(CPU); diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/WebAssembly.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/WebAssembly.cpp index 915aad4b563b..b8a2a092aff4 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/WebAssembly.cpp @@ -29,19 +29,25 @@ const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = { #include "clang/Basic/BuiltinsWebAssembly.def" }; +static constexpr llvm::StringLiteral ValidCPUNames[] = { + {"mvp"}, {"bleeding-edge"}, {"generic"}}; + bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch<bool>(Feature) .Case("simd128", SIMDLevel >= SIMD128) .Case("nontrapping-fptoint", HasNontrappingFPToInt) + .Case("sign-ext", HasSignExt) + .Case("exception-handling", HasExceptionHandling) .Default(false); } bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const { - return llvm::StringSwitch<bool>(Name) - .Case("mvp", true) - .Case("bleeding-edge", true) - .Case("generic", true) - .Default(false); + return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); +} + +void WebAssemblyTargetInfo::fillValidCPUList( + SmallVectorImpl<StringRef> &Values) const { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts, @@ -70,6 +76,22 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( HasNontrappingFPToInt = false; continue; } + if (Feature == "+sign-ext") { + HasSignExt = true; + continue; + } + if (Feature == "-sign-ext") { + HasSignExt = false; + continue; + } + if (Feature == "+exception-handling") { + HasExceptionHandling = true; + continue; + } + if (Feature == "-exception-handling") { + HasExceptionHandling = false; + continue; + } Diags.Report(diag::err_opt_not_valid_with_opt) << Feature << "-target-feature"; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/WebAssembly.h b/contrib/llvm/tools/clang/lib/Basic/Targets/WebAssembly.h index ee0073d081e0..c04c5cb6fb3a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/WebAssembly.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/WebAssembly.h @@ -31,10 +31,13 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { } SIMDLevel; bool HasNontrappingFPToInt; + bool HasSignExt; + bool HasExceptionHandling; public: explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &) - : TargetInfo(T), SIMDLevel(NoSIMD), HasNontrappingFPToInt(false) { + : TargetInfo(T), SIMDLevel(NoSIMD), HasNontrappingFPToInt(false), + HasSignExt(false), HasExceptionHandling(false) { NoAsmVariants = true; SuitableAlign = 128; LargeArrayMinWidth = 128; @@ -43,9 +46,12 @@ public: SigAtomicType = SignedLong; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); - SizeType = UnsignedInt; - PtrDiffType = SignedInt; - IntPtrType = SignedInt; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + // size_t being unsigned long for both wasm32 and wasm64 makes mangled names + // more consistent between the two. + SizeType = UnsignedLong; + PtrDiffType = SignedLong; + IntPtrType = SignedLong; } protected: @@ -60,6 +66,7 @@ private: if (CPU == "bleeding-edge") { Features["simd128"] = true; Features["nontrapping-fptoint"] = true; + Features["sign-ext"] = true; } return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -70,6 +77,7 @@ private: DiagnosticsEngine &Diags) final; bool isValidCPUName(StringRef Name) const final; + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const final; bool setCPU(const std::string &Name) final { return isValidCPUName(Name); } @@ -115,7 +123,6 @@ public: explicit WebAssembly32TargetInfo(const llvm::Triple &T, const TargetOptions &Opts) : WebAssemblyTargetInfo(T, Opts) { - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128"); } @@ -132,7 +139,6 @@ public: : WebAssemblyTargetInfo(T, Opts) { LongAlign = LongWidth = 64; PointerAlign = PointerWidth = 64; - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; SizeType = UnsignedLong; PtrDiffType = SignedLong; IntPtrType = SignedLong; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp index 8251e6abd649..7ae0696ce7e7 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/X86.cpp @@ -15,8 +15,10 @@ #include "clang/Basic/Builtins.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetBuiltins.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/TargetParser.h" namespace clang { namespace targets { @@ -131,7 +133,11 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "mmx", true); break; - case CK_Icelake: + case CK_IcelakeServer: + setFeatureEnabledImpl(Features, "pconfig", true); + setFeatureEnabledImpl(Features, "wbnoinvd", true); + LLVM_FALLTHROUGH; + case CK_IcelakeClient: setFeatureEnabledImpl(Features, "vaes", true); setFeatureEnabledImpl(Features, "gfni", true); setFeatureEnabledImpl(Features, "vpclmulqdq", true); @@ -139,6 +145,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "avx512vnni", true); setFeatureEnabledImpl(Features, "avx512vbmi2", true); setFeatureEnabledImpl(Features, "avx512vpopcntdq", true); + setFeatureEnabledImpl(Features, "rdpid", true); LLVM_FALLTHROUGH; case CK_Cannonlake: setFeatureEnabledImpl(Features, "avx512ifma", true); @@ -159,7 +166,8 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "xsavec", true); setFeatureEnabledImpl(Features, "xsaves", true); setFeatureEnabledImpl(Features, "mpx", true); - setFeatureEnabledImpl(Features, "sgx", true); + if (Kind != CK_SkylakeServer) // SKX inherits all SKL features, except SGX + setFeatureEnabledImpl(Features, "sgx", true); setFeatureEnabledImpl(Features, "clflushopt", true); setFeatureEnabledImpl(Features, "rtm", true); LLVM_FALLTHROUGH; @@ -174,6 +182,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "bmi", true); setFeatureEnabledImpl(Features, "bmi2", true); setFeatureEnabledImpl(Features, "fma", true); + setFeatureEnabledImpl(Features, "invpcid", true); setFeatureEnabledImpl(Features, "movbe", true); LLVM_FALLTHROUGH; case CK_IvyBridge: @@ -217,9 +226,20 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "fxsr", true); break; + case CK_Tremont: + setFeatureEnabledImpl(Features, "cldemote", true); + setFeatureEnabledImpl(Features, "movdiri", true); + setFeatureEnabledImpl(Features, "movdir64b", true); + setFeatureEnabledImpl(Features, "gfni", true); + setFeatureEnabledImpl(Features, "waitpkg", true); + LLVM_FALLTHROUGH; + case CK_GoldmontPlus: + setFeatureEnabledImpl(Features, "ptwrite", true); + setFeatureEnabledImpl(Features, "rdpid", true); + setFeatureEnabledImpl(Features, "sgx", true); + LLVM_FALLTHROUGH; case CK_Goldmont: setFeatureEnabledImpl(Features, "sha", true); - setFeatureEnabledImpl(Features, "rdrnd", true); setFeatureEnabledImpl(Features, "rdseed", true); setFeatureEnabledImpl(Features, "xsave", true); setFeatureEnabledImpl(Features, "xsaveopt", true); @@ -230,6 +250,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "fsgsbase", true); LLVM_FALLTHROUGH; case CK_Silvermont: + setFeatureEnabledImpl(Features, "rdrnd", true); setFeatureEnabledImpl(Features, "aes", true); setFeatureEnabledImpl(Features, "pclmul", true); setFeatureEnabledImpl(Features, "sse4.2", true); @@ -741,8 +762,6 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasMPX = true; } else if (Feature == "+shstk") { HasSHSTK = true; - } else if (Feature == "+ibt") { - HasIBT = true; } else if (Feature == "+movbe") { HasMOVBE = true; } else if (Feature == "+sgx") { @@ -767,16 +786,34 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasCLFLUSHOPT = true; } else if (Feature == "+clwb") { HasCLWB = true; + } else if (Feature == "+wbnoinvd") { + HasWBNOINVD = true; } else if (Feature == "+prefetchwt1") { HasPREFETCHWT1 = true; } else if (Feature == "+clzero") { HasCLZERO = true; + } else if (Feature == "+cldemote") { + HasCLDEMOTE = true; + } else if (Feature == "+rdpid") { + HasRDPID = true; } else if (Feature == "+retpoline") { HasRetpoline = true; } else if (Feature == "+retpoline-external-thunk") { HasRetpolineExternalThunk = true; } else if (Feature == "+sahf") { HasLAHFSAHF = true; + } else if (Feature == "+waitpkg") { + HasWAITPKG = true; + } else if (Feature == "+movdiri") { + HasMOVDIRI = true; + } else if (Feature == "+movdir64b") { + HasMOVDIR64B = true; + } else if (Feature == "+pconfig") { + HasPCONFIG = true; + } else if (Feature == "+ptwrite") { + HasPTWRITE = true; + } else if (Feature == "+invpcid") { + HasINVPCID = true; } X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) @@ -897,6 +934,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_Goldmont: defineCPUMacros(Builder, "goldmont"); break; + case CK_GoldmontPlus: + defineCPUMacros(Builder, "goldmont_plus"); + break; + case CK_Tremont: + defineCPUMacros(Builder, "tremont"); + break; case CK_Nehalem: case CK_Westmere: case CK_SandyBridge: @@ -906,7 +949,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_SkylakeClient: case CK_SkylakeServer: case CK_Cannonlake: - case CK_Icelake: + case CK_IcelakeClient: + case CK_IcelakeServer: // FIXME: Historically, we defined this legacy name, it would be nice to // remove it at some point. We've never exposed fine-grained names for // recent primary x86 CPUs, and we should keep it that way. @@ -1102,12 +1146,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__XSAVES__"); if (HasPKU) Builder.defineMacro("__PKU__"); - if (HasCX16) - Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16"); if (HasCLFLUSHOPT) Builder.defineMacro("__CLFLUSHOPT__"); if (HasCLWB) Builder.defineMacro("__CLWB__"); + if (HasWBNOINVD) + Builder.defineMacro("__WBNOINVD__"); if (HasMPX) Builder.defineMacro("__MPX__"); if (HasSHSTK) @@ -1118,6 +1162,22 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__PREFETCHWT1__"); if (HasCLZERO) Builder.defineMacro("__CLZERO__"); + if (HasRDPID) + Builder.defineMacro("__RDPID__"); + if (HasCLDEMOTE) + Builder.defineMacro("__CLDEMOTE__"); + if (HasWAITPKG) + Builder.defineMacro("__WAITPKG__"); + if (HasMOVDIRI) + Builder.defineMacro("__MOVDIRI__"); + if (HasMOVDIR64B) + Builder.defineMacro("__MOVDIR64B__"); + if (HasPCONFIG) + Builder.defineMacro("__PCONFIG__"); + if (HasPTWRITE) + Builder.defineMacro("__PTWRITE__"); + if (HasINVPCID) + Builder.defineMacro("__INVPCID__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1197,6 +1257,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, } if (CPU >= CK_i586) Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); + if (HasCX16) + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16"); if (HasFloat128) Builder.defineMacro("__SIZEOF_FLOAT128__", "16"); @@ -1225,6 +1287,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("avx512ifma", true) .Case("bmi", true) .Case("bmi2", true) + .Case("cldemote", true) .Case("clflushopt", true) .Case("clwb", true) .Case("clzero", true) @@ -1235,17 +1298,23 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("fsgsbase", true) .Case("fxsr", true) .Case("gfni", true) + .Case("invpcid", true) .Case("lwp", true) .Case("lzcnt", true) .Case("mmx", true) .Case("movbe", true) + .Case("movdiri", true) + .Case("movdir64b", true) .Case("mpx", true) .Case("mwaitx", true) .Case("pclmul", true) + .Case("pconfig", true) .Case("pku", true) .Case("popcnt", true) .Case("prefetchwt1", true) .Case("prfchw", true) + .Case("ptwrite", true) + .Case("rdpid", true) .Case("rdrnd", true) .Case("rdseed", true) .Case("rtm", true) @@ -1264,6 +1333,8 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("tbm", true) .Case("vaes", true) .Case("vpclmulqdq", true) + .Case("wbnoinvd", true) + .Case("waitpkg", true) .Case("x87", true) .Case("xop", true) .Case("xsave", true) @@ -1294,6 +1365,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("avx512ifma", HasAVX512IFMA) .Case("bmi", HasBMI) .Case("bmi2", HasBMI2) + .Case("cldemote", HasCLDEMOTE) .Case("clflushopt", HasCLFLUSHOPT) .Case("clwb", HasCLWB) .Case("clzero", HasCLZERO) @@ -1304,20 +1376,25 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("fsgsbase", HasFSGSBASE) .Case("fxsr", HasFXSR) .Case("gfni", HasGFNI) - .Case("ibt", HasIBT) + .Case("invpcid", HasINVPCID) .Case("lwp", HasLWP) .Case("lzcnt", HasLZCNT) .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon) .Case("mmx", MMX3DNowLevel >= MMX) .Case("movbe", HasMOVBE) + .Case("movdiri", HasMOVDIRI) + .Case("movdir64b", HasMOVDIR64B) .Case("mpx", HasMPX) .Case("mwaitx", HasMWAITX) .Case("pclmul", HasPCLMUL) + .Case("pconfig", HasPCONFIG) .Case("pku", HasPKU) .Case("popcnt", HasPOPCNT) .Case("prefetchwt1", HasPREFETCHWT1) .Case("prfchw", HasPRFCHW) + .Case("ptwrite", HasPTWRITE) + .Case("rdpid", HasRDPID) .Case("rdrnd", HasRDRND) .Case("rdseed", HasRDSEED) .Case("retpoline", HasRetpoline) @@ -1337,6 +1414,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("tbm", HasTBM) .Case("vaes", HasVAES) .Case("vpclmulqdq", HasVPCLMULQDQ) + .Case("wbnoinvd", HasWBNOINVD) + .Case("waitpkg", HasWAITPKG) .Case("x86", true) .Case("x86_32", getTriple().getArch() == llvm::Triple::x86) .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) @@ -1360,6 +1439,95 @@ bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { .Default(false); } +static llvm::X86::ProcessorFeatures getFeature(StringRef Name) { + return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name) +#define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, llvm::X86::ENUM) +#include "llvm/Support/X86TargetParser.def" + ; + // Note, this function should only be used after ensuring the value is + // correct, so it asserts if the value is out of range. +} + +static unsigned getFeaturePriority(llvm::X86::ProcessorFeatures Feat) { + enum class FeatPriority { +#define FEATURE(FEAT) FEAT, +#include "clang/Basic/X86Target.def" + }; + switch (Feat) { +#define FEATURE(FEAT) \ + case llvm::X86::FEAT: \ + return static_cast<unsigned>(FeatPriority::FEAT); +#include "clang/Basic/X86Target.def" + default: + llvm_unreachable("No Feature Priority for non-CPUSupports Features"); + } +} + +unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const { + // Valid CPUs have a 'key feature' that compares just better than its key + // feature. + CPUKind Kind = getCPUKind(Name); + if (Kind != CK_Generic) { + switch (Kind) { + default: + llvm_unreachable( + "CPU Type without a key feature used in 'target' attribute"); +#define PROC_WITH_FEAT(ENUM, STR, IS64, KEY_FEAT) \ + case CK_##ENUM: \ + return (getFeaturePriority(llvm::X86::KEY_FEAT) << 1) + 1; +#include "clang/Basic/X86Target.def" + } + } + + // Now we know we have a feature, so get its priority and shift it a few so + // that we have sufficient room for the CPUs (above). + return getFeaturePriority(getFeature(Name)) << 1; +} + +bool X86TargetInfo::validateCPUSpecificCPUDispatch(StringRef Name) const { + return llvm::StringSwitch<bool>(Name) +#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, true) +#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, true) +#include "clang/Basic/X86Target.def" + .Default(false); +} + +static StringRef CPUSpecificCPUDispatchNameDealias(StringRef Name) { + return llvm::StringSwitch<StringRef>(Name) +#define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) .Case(NEW_NAME, NAME) +#include "clang/Basic/X86Target.def" + .Default(Name); +} + +char X86TargetInfo::CPUSpecificManglingCharacter(StringRef Name) const { + return llvm::StringSwitch<char>(CPUSpecificCPUDispatchNameDealias(Name)) +#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, MANGLING) +#include "clang/Basic/X86Target.def" + .Default(0); +} + +void X86TargetInfo::getCPUSpecificCPUDispatchFeatures( + StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const { + StringRef WholeList = + llvm::StringSwitch<StringRef>(CPUSpecificCPUDispatchNameDealias(Name)) +#define CPU_SPECIFIC(NAME, MANGLING, FEATURES) .Case(NAME, FEATURES) +#include "clang/Basic/X86Target.def" + .Default(""); + WholeList.split(Features, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false); +} + +std::string X86TargetInfo::getCPUKindCanonicalName(CPUKind Kind) const { + switch (Kind) { + case CK_Generic: + return ""; +#define PROC(ENUM, STRING, IS64BIT) \ + case CK_##ENUM: \ + return STRING; +#include "clang/Basic/X86Target.def" + } + llvm_unreachable("Invalid CPUKind"); +} + // We can't use a generic validation scheme for the cpus accepted here // versus subtarget cpus accepted in the target attribute because the // variables intitialized by the runtime only support the below currently @@ -1445,7 +1613,7 @@ bool X86TargetInfo::validateAsmConstraint( case 'y': // Any MMX register. case 'v': // Any {X,Y,Z}MM register (Arch & context dependent) case 'x': // Any SSE register. - case 'k': // Any AVX512 mask register (same as Yk, additionaly allows k0 + case 'k': // Any AVX512 mask register (same as Yk, additionally allows k0 // for intermideate k reg operations). case 'Q': // Any register accessible as [r]h: a, b, c, and d. case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp. @@ -1573,8 +1741,6 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const { bool X86TargetInfo::checkCPUKind(CPUKind Kind) const { // Perform any per-CPU checks necessary to determine if this CPU is // acceptable. - // FIXME: This results in terrible diagnostics. Clang just says the CPU is - // invalid without explaining *why*. switch (Kind) { case CK_Generic: // No processor selected! @@ -1587,6 +1753,18 @@ bool X86TargetInfo::checkCPUKind(CPUKind Kind) const { llvm_unreachable("Unhandled CPU kind"); } +void X86TargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { +#define PROC(ENUM, STRING, IS64BIT) \ + if (IS64BIT || getTriple().getArch() == llvm::Triple::x86) \ + Values.emplace_back(STRING); + // Go through CPUKind checking to ensure that the alias is de-aliased and + // 64 bit-ness is checked. +#define PROC_ALIAS(ENUM, ALIAS) \ + if (checkCPUKind(getCPUKind(ALIAS))) \ + Values.emplace_back(ALIAS); +#include "clang/Basic/X86Target.def" +} + X86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const { return llvm::StringSwitch<CPUKind>(CPU) #define PROC(ENUM, STRING, IS64BIT) .Case(STRING, CK_##ENUM) diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets/X86.h b/contrib/llvm/tools/clang/lib/Basic/Targets/X86.h index fa2fbee387b6..b6cb27977b69 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets/X86.h +++ b/contrib/llvm/tools/clang/lib/Basic/Targets/X86.h @@ -81,7 +81,6 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasSHA = false; bool HasMPX = false; bool HasSHSTK = false; - bool HasIBT = false; bool HasSGX = false; bool HasCX16 = false; bool HasFXSR = false; @@ -91,16 +90,26 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasXSAVES = false; bool HasMWAITX = false; bool HasCLZERO = false; + bool HasCLDEMOTE = false; + bool HasPCONFIG = false; bool HasPKU = false; bool HasCLFLUSHOPT = false; bool HasCLWB = false; bool HasMOVBE = false; bool HasPREFETCHWT1 = false; + bool HasRDPID = false; bool HasRetpoline = false; bool HasRetpolineExternalThunk = false; bool HasLAHFSAHF = false; - - /// \brief Enumeration of all of the X86 CPUs supported by Clang. + bool HasWBNOINVD = false; + bool HasWAITPKG = false; + bool HasMOVDIRI = false; + bool HasMOVDIR64B = false; + bool HasPTWRITE = false; + bool HasINVPCID = false; + +protected: + /// Enumeration of all of the X86 CPUs supported by Clang. /// /// Each enumeration represents a particular CPU supported by Clang. These /// loosely correspond to the options passed to '-march' or '-mtune' flags. @@ -114,6 +123,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { CPUKind getCPUKind(StringRef CPU) const; + std::string getCPUKindCanonicalName(CPUKind Kind) const; + enum FPMathKind { FP_Default, FP_SSE, FP_387 } FPMath = FP_Default; public: @@ -139,6 +150,14 @@ public: bool validateCpuIs(StringRef Name) const override; + bool validateCPUSpecificCPUDispatch(StringRef Name) const override; + + char CPUSpecificManglingCharacter(StringRef Name) const override; + + void getCPUSpecificCPUDispatchFeatures( + StringRef Name, + llvm::SmallVectorImpl<StringRef> &Features) const override; + bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; @@ -159,6 +178,17 @@ public: bool validateInputSize(StringRef Constraint, unsigned Size) const override; + virtual bool + checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override { + return true; + }; + + virtual bool + checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override { + return true; + }; + + virtual bool validateOperandSize(StringRef Constraint, unsigned Size) const; std::string convertConstraint(const char *&Constraint) const override; @@ -166,8 +196,8 @@ public: return "~{dirflag},~{fpsr},~{flags}"; } - StringRef getConstraintRegister(const StringRef &Constraint, - const StringRef &Expression) const override { + StringRef getConstraintRegister(StringRef Constraint, + StringRef Expression) const override { StringRef::iterator I, E; for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) { if (isalpha(*I)) @@ -255,10 +285,17 @@ public: return checkCPUKind(getCPUKind(Name)); } + void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; + bool setCPU(const std::string &Name) override { return checkCPUKind(CPU = getCPUKind(Name)); } + bool supportsMultiVersioning() const override { + return getTriple().isOSBinFormatELF(); + } + unsigned multiVersionSortPriority(StringRef Name) const override; + bool setFPMath(StringRef Name) override; CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { @@ -270,6 +307,7 @@ public: case CC_X86VectorCall: case CC_X86RegCall: case CC_C: + case CC_PreserveMost: case CC_Swift: case CC_X86Pascal: case CC_IntelOclBicc: @@ -312,9 +350,11 @@ public: (1 << TargetInfo::LongDouble)); // x86-32 has atomics up to 8 bytes - // FIXME: Check that we actually have cmpxchg8b before setting - // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.) - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + CPUKind Kind = getCPUKind(Opts.CPU); + if (Kind >= CK_i586 || Kind == CK_Generic) + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + else if (Kind >= CK_i486) + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; } BuiltinVaListKind getBuiltinVaListKind() const override { @@ -709,6 +749,11 @@ public: Builder.defineMacro("_M_X64", "100"); Builder.defineMacro("_M_AMD64", "100"); } + + TargetInfo::CallingConvKind + getCallingConvKind(bool ClangABICompat4) const override { + return CCK_MicrosoftWin64; + } }; // x86-64 MinGW target diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp index ea3754e02af5..a1a67c2bc144 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Version.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Version.cpp @@ -36,7 +36,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_601/final/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); diff --git a/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp b/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp deleted file mode 100644 index 9c73fd98a174..000000000000 --- a/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp +++ /dev/null @@ -1,100 +0,0 @@ -//===- VersionTuple.cpp - Version Number Handling ---------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the VersionTuple class, which represents a version in -// the form major[.minor[.subminor]]. -// -//===----------------------------------------------------------------------===// -#include "clang/Basic/VersionTuple.h" -#include "llvm/Support/raw_ostream.h" - -using namespace clang; - -std::string VersionTuple::getAsString() const { - std::string Result; - { - llvm::raw_string_ostream Out(Result); - Out << *this; - } - return Result; -} - -raw_ostream& clang::operator<<(raw_ostream &Out, - const VersionTuple &V) { - Out << V.getMajor(); - if (Optional<unsigned> Minor = V.getMinor()) - Out << (V.usesUnderscores() ? '_' : '.') << *Minor; - if (Optional<unsigned> Subminor = V.getSubminor()) - Out << (V.usesUnderscores() ? '_' : '.') << *Subminor; - if (Optional<unsigned> Build = V.getBuild()) - Out << (V.usesUnderscores() ? '_' : '.') << *Build; - return Out; -} - -static bool parseInt(StringRef &input, unsigned &value) { - assert(value == 0); - if (input.empty()) return true; - - char next = input[0]; - input = input.substr(1); - if (next < '0' || next > '9') return true; - value = (unsigned) (next - '0'); - - while (!input.empty()) { - next = input[0]; - if (next < '0' || next > '9') return false; - input = input.substr(1); - value = value * 10 + (unsigned) (next - '0'); - } - - return false; -} - -bool VersionTuple::tryParse(StringRef input) { - unsigned major = 0, minor = 0, micro = 0, build = 0; - - // Parse the major version, [0-9]+ - if (parseInt(input, major)) return true; - - if (input.empty()) { - *this = VersionTuple(major); - return false; - } - - // If we're not done, parse the minor version, \.[0-9]+ - if (input[0] != '.') return true; - input = input.substr(1); - if (parseInt(input, minor)) return true; - - if (input.empty()) { - *this = VersionTuple(major, minor); - return false; - } - - // If we're not done, parse the micro version, \.[0-9]+ - if (input[0] != '.') return true; - input = input.substr(1); - if (parseInt(input, micro)) return true; - - if (input.empty()) { - *this = VersionTuple(major, minor, micro); - return false; - } - - // If we're not done, parse the micro version, \.[0-9]+ - if (input[0] != '.') return true; - input = input.substr(1); - if (parseInt(input, build)) return true; - - // If we have characters left over, it's an error. - if (!input.empty()) return true; - - *this = VersionTuple(major, minor, micro, build); - return false; -} diff --git a/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp b/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp index 9d44597dc3fb..bcfcbdbb9014 100644 --- a/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp @@ -1,4 +1,4 @@ -//===- VirtualFileSystem.cpp - Virtual File System Layer --------*- C++ -*-===// +//===- VirtualFileSystem.cpp - Virtual File System Layer ------------------===// // // The LLVM Compiler Infrastructure // @@ -6,30 +6,57 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// // This file implements the VirtualFileSystem interface. +// //===----------------------------------------------------------------------===// #include "clang/Basic/VirtualFileSystem.h" -#include "clang/Basic/FileManager.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Chrono.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" +#include "llvm/Support/SMLoc.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/YAMLParser.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> #include <atomic> +#include <cassert> +#include <cstdint> +#include <iterator> +#include <limits> +#include <map> #include <memory> +#include <string> +#include <system_error> #include <utility> +#include <vector> using namespace clang; -using namespace clang::vfs; +using namespace vfs; using namespace llvm; + using llvm::sys::fs::file_status; using llvm::sys::fs::file_type; using llvm::sys::fs::perms; @@ -38,13 +65,13 @@ using llvm::sys::fs::UniqueID; Status::Status(const file_status &Status) : UID(Status.getUniqueID()), MTime(Status.getLastModificationTime()), User(Status.getUser()), Group(Status.getGroup()), Size(Status.getSize()), - Type(Status.type()), Perms(Status.permissions()), IsVFSMapped(false) {} + Type(Status.type()), Perms(Status.permissions()) {} Status::Status(StringRef Name, UniqueID UID, sys::TimePoint<> MTime, uint32_t User, uint32_t Group, uint64_t Size, file_type Type, perms Perms) : Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size), - Type(Type), Perms(Perms), IsVFSMapped(false) {} + Type(Type), Perms(Perms) {} Status Status::copyWithNewName(const Status &In, StringRef NewName) { return Status(NewName, In.getUniqueID(), In.getLastModificationTime(), @@ -62,28 +89,34 @@ bool Status::equivalent(const Status &Other) const { assert(isStatusKnown() && Other.isStatusKnown()); return getUniqueID() == Other.getUniqueID(); } + bool Status::isDirectory() const { return Type == file_type::directory_file; } + bool Status::isRegularFile() const { return Type == file_type::regular_file; } + bool Status::isOther() const { return exists() && !isRegularFile() && !isDirectory() && !isSymlink(); } + bool Status::isSymlink() const { return Type == file_type::symlink_file; } + bool Status::isStatusKnown() const { return Type != file_type::status_error; } + bool Status::exists() const { return isStatusKnown() && Type != file_type::file_not_found; } -File::~File() {} +File::~File() = default; -FileSystem::~FileSystem() {} +FileSystem::~FileSystem() = default; ErrorOr<std::unique_ptr<MemoryBuffer>> FileSystem::getBufferForFile(const llvm::Twine &Name, int64_t FileSize, @@ -97,7 +130,7 @@ FileSystem::getBufferForFile(const llvm::Twine &Name, int64_t FileSize, std::error_code FileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { if (llvm::sys::path::is_absolute(Path)) - return std::error_code(); + return {}; auto WorkingDir = getCurrentWorkingDirectory(); if (!WorkingDir) @@ -106,6 +139,11 @@ std::error_code FileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { return llvm::sys::fs::make_absolute(WorkingDir.get(), Path); } +std::error_code FileSystem::getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const { + return errc::operation_not_permitted; +} + bool FileSystem::exists(const Twine &Path) { auto Status = status(Path); return Status && Status->exists(); @@ -118,6 +156,7 @@ static bool isTraversalComponent(StringRef Component) { static bool pathHasTraversal(StringRef Path) { using namespace llvm::sys; + for (StringRef Comp : llvm::make_range(path::begin(Path), path::end(Path))) if (isTraversalComponent(Comp)) return true; @@ -130,12 +169,15 @@ static bool pathHasTraversal(StringRef Path) { //===-----------------------------------------------------------------------===/ namespace { -/// \brief Wrapper around a raw file descriptor. + +/// Wrapper around a raw file descriptor. class RealFile : public File { + friend class RealFileSystem; + int FD; Status S; std::string RealName; - friend class RealFileSystem; + RealFile(int FD, StringRef NewName, StringRef NewRealPathName) : FD(FD), S(NewName, {}, {}, {}, {}, {}, llvm::sys::fs::file_type::status_error, {}), @@ -145,6 +187,7 @@ class RealFile : public File { public: ~RealFile() override; + ErrorOr<Status> status() override; ErrorOr<std::string> getName() override; ErrorOr<std::unique_ptr<MemoryBuffer>> getBuffer(const Twine &Name, @@ -153,7 +196,9 @@ public: bool IsVolatile) override; std::error_code close() override; }; -} // end anonymous namespace + +} // namespace + RealFile::~RealFile() { close(); } ErrorOr<Status> RealFile::status() { @@ -186,7 +231,8 @@ std::error_code RealFile::close() { } namespace { -/// \brief The file system according to your operating system. + +/// The file system according to your operating system. class RealFileSystem : public FileSystem { public: ErrorOr<Status> status(const Twine &Path) override; @@ -195,8 +241,11 @@ public: llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const override; }; -} // end anonymous namespace + +} // namespace ErrorOr<Status> RealFileSystem::status(const Twine &Path) { sys::fs::file_status RealStatus; @@ -209,7 +258,8 @@ ErrorOr<std::unique_ptr<File>> RealFileSystem::openFileForRead(const Twine &Name) { int FD; SmallString<256> RealName; - if (std::error_code EC = sys::fs::openFileForRead(Name, FD, &RealName)) + if (std::error_code EC = + sys::fs::openFileForRead(Name, FD, sys::fs::OF_None, &RealName)) return EC; return std::unique_ptr<File>(new RealFile(FD, Name.str(), RealName.str())); } @@ -232,39 +282,50 @@ std::error_code RealFileSystem::setCurrentWorkingDirectory(const Twine &Path) { return llvm::sys::fs::set_current_path(Path); } +std::error_code +RealFileSystem::getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const { + return llvm::sys::fs::real_path(Path, Output); +} + IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() { static IntrusiveRefCntPtr<FileSystem> FS = new RealFileSystem(); return FS; } namespace { + class RealFSDirIter : public clang::vfs::detail::DirIterImpl { llvm::sys::fs::directory_iterator Iter; + public: RealFSDirIter(const Twine &Path, std::error_code &EC) : Iter(Path, EC) { - if (!EC && Iter != llvm::sys::fs::directory_iterator()) { + if (Iter != llvm::sys::fs::directory_iterator()) { llvm::sys::fs::file_status S; - EC = llvm::sys::fs::status(Iter->path(), S, true); + std::error_code ErrorCode = llvm::sys::fs::status(Iter->path(), S, true); CurrentEntry = Status::copyWithNewName(S, Iter->path()); + if (!EC) + EC = ErrorCode; } } std::error_code increment() override { std::error_code EC; Iter.increment(EC); - if (EC) { - return EC; - } else if (Iter == llvm::sys::fs::directory_iterator()) { + if (Iter == llvm::sys::fs::directory_iterator()) { CurrentEntry = Status(); } else { llvm::sys::fs::file_status S; - EC = llvm::sys::fs::status(Iter->path(), S, true); + std::error_code ErrorCode = llvm::sys::fs::status(Iter->path(), S, true); CurrentEntry = Status::copyWithNewName(S, Iter->path()); + if (!EC) + EC = ErrorCode; } return EC; } }; -} + +} // namespace directory_iterator RealFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -274,6 +335,7 @@ directory_iterator RealFileSystem::dir_begin(const Twine &Dir, //===-----------------------------------------------------------------------===/ // OverlayFileSystem implementation //===-----------------------------------------------------------------------===/ + OverlayFileSystem::OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> BaseFS) { FSList.push_back(std::move(BaseFS)); } @@ -311,17 +373,28 @@ OverlayFileSystem::getCurrentWorkingDirectory() const { // All file systems are synchronized, just take the first working directory. return FSList.front()->getCurrentWorkingDirectory(); } + std::error_code OverlayFileSystem::setCurrentWorkingDirectory(const Twine &Path) { for (auto &FS : FSList) if (std::error_code EC = FS->setCurrentWorkingDirectory(Path)) return EC; - return std::error_code(); + return {}; +} + +std::error_code +OverlayFileSystem::getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const { + for (auto &FS : FSList) + if (FS->exists(Path)) + return FS->getRealPath(Path, Output); + return errc::no_such_file_or_directory; } -clang::vfs::detail::DirIterImpl::~DirIterImpl() { } +clang::vfs::detail::DirIterImpl::~DirIterImpl() = default; namespace { + class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl { OverlayFileSystem &Overlays; std::string Path; @@ -340,7 +413,7 @@ class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl { if (CurrentDirIter != directory_iterator()) break; // found } - return std::error_code(); + return {}; } std::error_code incrementDirIter(bool IsFirstTime) { @@ -379,7 +452,8 @@ public: std::error_code increment() override { return incrementImpl(false); } }; -} // end anonymous namespace + +} // namespace directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -389,6 +463,7 @@ directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir, namespace clang { namespace vfs { + namespace detail { enum InMemoryNodeKind { IME_File, IME_Directory }; @@ -402,13 +477,15 @@ class InMemoryNode { public: InMemoryNode(Status Stat, InMemoryNodeKind Kind) : Stat(std::move(Stat)), Kind(Kind) {} - virtual ~InMemoryNode() {} + virtual ~InMemoryNode() = default; + const Status &getStatus() const { return Stat; } InMemoryNodeKind getKind() const { return Kind; } virtual std::string toString(unsigned Indent) const = 0; }; namespace { + class InMemoryFile : public InMemoryNode { std::unique_ptr<llvm::MemoryBuffer> Buffer; @@ -417,9 +494,11 @@ public: : InMemoryNode(std::move(Stat), IME_File), Buffer(std::move(Buffer)) {} llvm::MemoryBuffer *getBuffer() { return Buffer.get(); } + std::string toString(unsigned Indent) const override { return (std::string(Indent, ' ') + getStatus().getName() + "\n").str(); } + static bool classof(const InMemoryNode *N) { return N->getKind() == IME_File; } @@ -433,6 +512,7 @@ public: explicit InMemoryFileAdaptor(InMemoryFile &Node) : Node(Node) {} llvm::ErrorOr<Status> status() override { return Node.getStatus(); } + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) override { @@ -440,9 +520,11 @@ public: return llvm::MemoryBuffer::getMemBuffer( Buf->getBuffer(), Buf->getBufferIdentifier(), RequiresNullTerminator); } - std::error_code close() override { return std::error_code(); } + + std::error_code close() override { return {}; } }; -} // end anonymous namespace + +} // namespace class InMemoryDirectory : public InMemoryNode { std::map<std::string, std::unique_ptr<InMemoryNode>> Entries; @@ -450,34 +532,38 @@ class InMemoryDirectory : public InMemoryNode { public: InMemoryDirectory(Status Stat) : InMemoryNode(std::move(Stat), IME_Directory) {} + InMemoryNode *getChild(StringRef Name) { auto I = Entries.find(Name); if (I != Entries.end()) return I->second.get(); return nullptr; } + InMemoryNode *addChild(StringRef Name, std::unique_ptr<InMemoryNode> Child) { return Entries.insert(make_pair(Name, std::move(Child))) .first->second.get(); } - typedef decltype(Entries)::const_iterator const_iterator; + using const_iterator = decltype(Entries)::const_iterator; + const_iterator begin() const { return Entries.begin(); } const_iterator end() const { return Entries.end(); } std::string toString(unsigned Indent) const override { std::string Result = (std::string(Indent, ' ') + getStatus().getName() + "\n").str(); - for (const auto &Entry : Entries) { + for (const auto &Entry : Entries) Result += Entry.second->toString(Indent + 2); - } return Result; } + static bool classof(const InMemoryNode *N) { return N->getKind() == IME_Directory; } }; -} + +} // namespace detail InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths) : Root(new detail::InMemoryDirectory( @@ -486,7 +572,7 @@ InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths) llvm::sys::fs::perms::all_all))), UseNormalizedPaths(UseNormalizedPaths) {} -InMemoryFileSystem::~InMemoryFileSystem() {} +InMemoryFileSystem::~InMemoryFileSystem() = default; std::string InMemoryFileSystem::toString() const { return Root->toString(/*Indent=*/0); @@ -645,13 +731,15 @@ InMemoryFileSystem::openFileForRead(const Twine &Path) { } namespace { + /// Adaptor from InMemoryDir::iterator to directory_iterator. class InMemoryDirIterator : public clang::vfs::detail::DirIterImpl { detail::InMemoryDirectory::const_iterator I; detail::InMemoryDirectory::const_iterator E; public: - InMemoryDirIterator() {} + InMemoryDirIterator() = default; + explicit InMemoryDirIterator(detail::InMemoryDirectory &Dir) : I(Dir.begin()), E(Dir.end()) { if (I != E) @@ -663,10 +751,11 @@ public: // When we're at the end, make CurrentEntry invalid and DirIterImpl will do // the rest. CurrentEntry = I != E ? I->second->getStatus() : Status(); - return std::error_code(); + return {}; } }; -} // end anonymous namespace + +} // namespace directory_iterator InMemoryFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { @@ -697,11 +786,25 @@ std::error_code InMemoryFileSystem::setCurrentWorkingDirectory(const Twine &P) { if (!Path.empty()) WorkingDirectory = Path.str(); - return std::error_code(); -} + return {}; } + +std::error_code +InMemoryFileSystem::getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const { + auto CWD = getCurrentWorkingDirectory(); + if (!CWD || CWD->empty()) + return errc::operation_not_permitted; + Path.toVector(Output); + if (auto EC = makeAbsolute(Output)) + return EC; + llvm::sys::path::remove_dots(Output, /*remove_dot_dot=*/true); + return {}; } +} // namespace vfs +} // namespace clang + //===-----------------------------------------------------------------------===/ // RedirectingFileSystem implementation //===-----------------------------------------------------------------------===/ @@ -713,14 +816,15 @@ enum EntryKind { EK_File }; -/// \brief A single file or directory in the VFS. +/// A single file or directory in the VFS. class Entry { EntryKind Kind; std::string Name; public: - virtual ~Entry(); Entry(EntryKind K, StringRef Name) : Kind(K), Name(Name) {} + virtual ~Entry() = default; + StringRef getName() const { return Name; } EntryKind getKind() const { return Kind; } }; @@ -737,14 +841,20 @@ public: S(std::move(S)) {} RedirectingDirectoryEntry(StringRef Name, Status S) : Entry(EK_Directory, Name), S(std::move(S)) {} + Status getStatus() { return S; } + void addContent(std::unique_ptr<Entry> Content) { Contents.push_back(std::move(Content)); } + Entry *getLastContent() const { return Contents.back().get(); } - typedef decltype(Contents)::iterator iterator; + + using iterator = decltype(Contents)::iterator; + iterator contents_begin() { return Contents.begin(); } iterator contents_end() { return Contents.end(); } + static bool classof(const Entry *E) { return E->getKind() == EK_Directory; } }; @@ -755,21 +865,27 @@ public: NK_External, NK_Virtual }; + private: std::string ExternalContentsPath; NameKind UseName; + public: RedirectingFileEntry(StringRef Name, StringRef ExternalContentsPath, NameKind UseName) : Entry(EK_File, Name), ExternalContentsPath(ExternalContentsPath), UseName(UseName) {} + StringRef getExternalContentsPath() const { return ExternalContentsPath; } - /// \brief whether to use the external path as the name for this file. + + /// whether to use the external path as the name for this file. bool useExternalName(bool GlobalUseExternalName) const { return UseName == NK_NotSet ? GlobalUseExternalName : (UseName == NK_External); } + NameKind getUseName() const { return UseName; } + static bool classof(const Entry *E) { return E->getKind() == EK_File; } }; @@ -785,10 +901,11 @@ public: RedirectingDirectoryEntry::iterator Begin, RedirectingDirectoryEntry::iterator End, std::error_code &EC); + std::error_code increment() override; }; -/// \brief A virtual file system parsed from a YAML file. +/// A virtual file system parsed from a YAML file. /// /// Currently, this class allows creating virtual directories and mapping /// virtual file paths to existing external files, available in \c ExternalFS. @@ -844,10 +961,14 @@ public: /// /path/to/file). However, any directory that contains more than one child /// must be uniquely represented by a directory entry. class RedirectingFileSystem : public vfs::FileSystem { + friend class RedirectingFileSystemParser; + /// The root(s) of the virtual file system. std::vector<std::unique_ptr<Entry>> Roots; - /// \brief The file system to use for external references. + + /// The file system to use for external references. IntrusiveRefCntPtr<FileSystem> ExternalFS; + /// If IsRelativeOverlay is set, this represents the directory /// path that should be prefixed to each 'external-contents' entry /// when reading from YAML files. @@ -856,7 +977,7 @@ class RedirectingFileSystem : public vfs::FileSystem { /// @name Configuration /// @{ - /// \brief Whether to perform case-sensitive comparisons. + /// Whether to perform case-sensitive comparisons. /// /// Currently, case-insensitive matching only works correctly with ASCII. bool CaseSensitive = true; @@ -865,11 +986,11 @@ class RedirectingFileSystem : public vfs::FileSystem { /// be prefixed in every 'external-contents' when reading from YAML files. bool IsRelativeOverlay = false; - /// \brief Whether to use to use the value of 'external-contents' for the + /// Whether to use to use the value of 'external-contents' for the /// names of files. This global value is overridable on a per-file basis. bool UseExternalNames = true; - /// \brief Whether an invalid path obtained via 'external-contents' should + /// Whether an invalid path obtained via 'external-contents' should /// cause iteration on the VFS to stop. If 'true', the VFS should ignore /// the entry and continue with the next. Allows YAML files to be shared /// across multiple compiler invocations regardless of prior existent @@ -882,31 +1003,29 @@ class RedirectingFileSystem : public vfs::FileSystem { /// "." and "./" in their paths. FIXME: some unittests currently fail on /// win32 when using remove_dots and remove_leading_dotslash on paths. bool UseCanonicalizedPaths = -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 false; #else true; #endif - friend class RedirectingFileSystemParser; - private: RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS) : ExternalFS(std::move(ExternalFS)) {} - /// \brief Looks up the path <tt>[Start, End)</tt> in \p From, possibly + /// Looks up the path <tt>[Start, End)</tt> in \p From, possibly /// recursing into the contents of \p From if it is a directory. ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start, sys::path::const_iterator End, Entry *From); - /// \brief Get the status of a given an \c Entry. + /// Get the status of a given an \c Entry. ErrorOr<Status> status(const Twine &Path, Entry *E); public: - /// \brief Looks up \p Path in \c Roots. + /// Looks up \p Path in \c Roots. ErrorOr<Entry *> lookupPath(const Twine &Path); - /// \brief Parses \p Buffer, which is expected to be in YAML format and + /// Parses \p Buffer, which is expected to be in YAML format and /// returns a virtual file system representing its contents. static RedirectingFileSystem * create(std::unique_ptr<MemoryBuffer> Buffer, @@ -919,6 +1038,7 @@ public: llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override { return ExternalFS->getCurrentWorkingDirectory(); } + std::error_code setCurrentWorkingDirectory(const Twine &Path) override { return ExternalFS->setCurrentWorkingDirectory(Path); } @@ -927,17 +1047,17 @@ public: ErrorOr<Entry *> E = lookupPath(Dir); if (!E) { EC = E.getError(); - return directory_iterator(); + return {}; } ErrorOr<Status> S = status(Dir, *E); if (!S) { EC = S.getError(); - return directory_iterator(); + return {}; } if (!S->isDirectory()) { EC = std::error_code(static_cast<int>(errc::not_a_directory), std::system_category()); - return directory_iterator(); + return {}; } auto *D = cast<RedirectingDirectoryEntry>(*E); @@ -959,7 +1079,7 @@ public: #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void dump() const { - for (const std::unique_ptr<Entry> &Root : Roots) + for (const auto &Root : Roots) dumpEntry(Root.get()); } @@ -979,10 +1099,9 @@ LLVM_DUMP_METHOD void dumpEntry(Entry *E, int NumSpaces = 0) const { } } #endif - }; -/// \brief A helper class to hold the common YAML parsing state. +/// A helper class to hold the common YAML parsing state. class RedirectingFileSystemParser { yaml::Stream &Stream; @@ -993,7 +1112,8 @@ class RedirectingFileSystemParser { // false on error bool parseScalarString(yaml::Node *N, StringRef &Result, SmallVectorImpl<char> &Storage) { - yaml::ScalarNode *S = dyn_cast<yaml::ScalarNode>(N); + const auto *S = dyn_cast<yaml::ScalarNode>(N); + if (!S) { error(N, "expected string"); return false; @@ -1024,11 +1144,13 @@ class RedirectingFileSystemParser { } struct KeyStatus { - KeyStatus(bool Required=false) : Required(Required), Seen(false) {} bool Required; - bool Seen; + bool Seen = false; + + KeyStatus(bool Required = false) : Required(Required) {} }; - typedef std::pair<StringRef, KeyStatus> KeyStatusPair; + + using KeyStatusPair = std::pair<StringRef, KeyStatus>; // false on error bool checkDuplicateOrUnknownKey(yaml::Node *KeyNode, StringRef Key, @@ -1048,11 +1170,9 @@ class RedirectingFileSystemParser { // false on error bool checkMissingKeys(yaml::Node *Obj, DenseMap<StringRef, KeyStatus> &Keys) { - for (DenseMap<StringRef, KeyStatus>::iterator I = Keys.begin(), - E = Keys.end(); - I != E; ++I) { - if (I->second.Required && !I->second.Seen) { - error(Obj, Twine("missing key '") + I->first + "'"); + for (const auto &I : Keys) { + if (I.second.Required && !I.second.Seen) { + error(Obj, Twine("missing key '") + I.first + "'"); return false; } } @@ -1062,7 +1182,7 @@ class RedirectingFileSystemParser { Entry *lookupOrCreateEntry(RedirectingFileSystem *FS, StringRef Name, Entry *ParentEntry = nullptr) { if (!ParentEntry) { // Look for a existent root - for (const std::unique_ptr<Entry> &Root : FS->Roots) { + for (const auto &Root : FS->Roots) { if (Name.equals(Root->getName())) { ParentEntry = Root.get(); return ParentEntry; @@ -1125,7 +1245,7 @@ class RedirectingFileSystemParser { } std::unique_ptr<Entry> parseEntry(yaml::Node *N, RedirectingFileSystem *FS) { - yaml::MappingNode *M = dyn_cast<yaml::MappingNode>(N); + auto *M = dyn_cast<yaml::MappingNode>(N); if (!M) { error(N, "expected mapping node for file or directory entry"); return nullptr; @@ -1148,21 +1268,20 @@ class RedirectingFileSystemParser { auto UseExternalName = RedirectingFileEntry::NK_NotSet; EntryKind Kind; - for (yaml::MappingNode::iterator I = M->begin(), E = M->end(); I != E; - ++I) { + for (auto &I : *M) { StringRef Key; // Reuse the buffer for key and value, since we don't look at key after // parsing value. SmallString<256> Buffer; - if (!parseScalarString(I->getKey(), Key, Buffer)) + if (!parseScalarString(I.getKey(), Key, Buffer)) return nullptr; - if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys)) + if (!checkDuplicateOrUnknownKey(I.getKey(), Key, Keys)) return nullptr; StringRef Value; if (Key == "name") { - if (!parseScalarString(I->getValue(), Value, Buffer)) + if (!parseScalarString(I.getValue(), Value, Buffer)) return nullptr; if (FS->UseCanonicalizedPaths) { @@ -1176,47 +1295,44 @@ class RedirectingFileSystemParser { Name = Value; } } else if (Key == "type") { - if (!parseScalarString(I->getValue(), Value, Buffer)) + if (!parseScalarString(I.getValue(), Value, Buffer)) return nullptr; if (Value == "file") Kind = EK_File; else if (Value == "directory") Kind = EK_Directory; else { - error(I->getValue(), "unknown value for 'type'"); + error(I.getValue(), "unknown value for 'type'"); return nullptr; } } else if (Key == "contents") { if (HasContents) { - error(I->getKey(), + error(I.getKey(), "entry already has 'contents' or 'external-contents'"); return nullptr; } HasContents = true; - yaml::SequenceNode *Contents = - dyn_cast<yaml::SequenceNode>(I->getValue()); + auto *Contents = dyn_cast<yaml::SequenceNode>(I.getValue()); if (!Contents) { // FIXME: this is only for directories, what about files? - error(I->getValue(), "expected array"); + error(I.getValue(), "expected array"); return nullptr; } - for (yaml::SequenceNode::iterator I = Contents->begin(), - E = Contents->end(); - I != E; ++I) { - if (std::unique_ptr<Entry> E = parseEntry(&*I, FS)) + for (auto &I : *Contents) { + if (std::unique_ptr<Entry> E = parseEntry(&I, FS)) EntryArrayContents.push_back(std::move(E)); else return nullptr; } } else if (Key == "external-contents") { if (HasContents) { - error(I->getKey(), + error(I.getKey(), "entry already has 'contents' or 'external-contents'"); return nullptr; } HasContents = true; - if (!parseScalarString(I->getValue(), Value, Buffer)) + if (!parseScalarString(I.getValue(), Value, Buffer)) return nullptr; SmallString<256> FullPath; @@ -1238,7 +1354,7 @@ class RedirectingFileSystemParser { ExternalContentsPath = FullPath.str(); } else if (Key == "use-external-name") { bool Val; - if (!parseScalarBool(I->getValue(), Val)) + if (!parseScalarBool(I.getValue(), Val)) return nullptr; UseExternalName = Val ? RedirectingFileEntry::NK_External : RedirectingFileEntry::NK_Virtual; @@ -1311,7 +1427,7 @@ public: // false on error bool parse(yaml::Node *Root, RedirectingFileSystem *FS) { - yaml::MappingNode *Top = dyn_cast<yaml::MappingNode>(Root); + auto *Top = dyn_cast<yaml::MappingNode>(Root); if (!Top) { error(Root, "expected mapping node"); return false; @@ -1330,26 +1446,24 @@ public: std::vector<std::unique_ptr<Entry>> RootEntries; // Parse configuration and 'roots' - for (yaml::MappingNode::iterator I = Top->begin(), E = Top->end(); I != E; - ++I) { + for (auto &I : *Top) { SmallString<10> KeyBuffer; StringRef Key; - if (!parseScalarString(I->getKey(), Key, KeyBuffer)) + if (!parseScalarString(I.getKey(), Key, KeyBuffer)) return false; - if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys)) + if (!checkDuplicateOrUnknownKey(I.getKey(), Key, Keys)) return false; if (Key == "roots") { - yaml::SequenceNode *Roots = dyn_cast<yaml::SequenceNode>(I->getValue()); + auto *Roots = dyn_cast<yaml::SequenceNode>(I.getValue()); if (!Roots) { - error(I->getValue(), "expected array"); + error(I.getValue(), "expected array"); return false; } - for (yaml::SequenceNode::iterator I = Roots->begin(), E = Roots->end(); - I != E; ++I) { - if (std::unique_ptr<Entry> E = parseEntry(&*I, FS)) + for (auto &I : *Roots) { + if (std::unique_ptr<Entry> E = parseEntry(&I, FS)) RootEntries.push_back(std::move(E)); else return false; @@ -1357,32 +1471,32 @@ public: } else if (Key == "version") { StringRef VersionString; SmallString<4> Storage; - if (!parseScalarString(I->getValue(), VersionString, Storage)) + if (!parseScalarString(I.getValue(), VersionString, Storage)) return false; int Version; if (VersionString.getAsInteger<int>(10, Version)) { - error(I->getValue(), "expected integer"); + error(I.getValue(), "expected integer"); return false; } if (Version < 0) { - error(I->getValue(), "invalid version number"); + error(I.getValue(), "invalid version number"); return false; } if (Version != 0) { - error(I->getValue(), "version mismatch, expected 0"); + error(I.getValue(), "version mismatch, expected 0"); return false; } } else if (Key == "case-sensitive") { - if (!parseScalarBool(I->getValue(), FS->CaseSensitive)) + if (!parseScalarBool(I.getValue(), FS->CaseSensitive)) return false; } else if (Key == "overlay-relative") { - if (!parseScalarBool(I->getValue(), FS->IsRelativeOverlay)) + if (!parseScalarBool(I.getValue(), FS->IsRelativeOverlay)) return false; } else if (Key == "use-external-names") { - if (!parseScalarBool(I->getValue(), FS->UseExternalNames)) + if (!parseScalarBool(I.getValue(), FS->UseExternalNames)) return false; } else if (Key == "ignore-non-existent-contents") { - if (!parseScalarBool(I->getValue(), FS->IgnoreNonExistentContents)) + if (!parseScalarBool(I.getValue(), FS->IgnoreNonExistentContents)) return false; } else { llvm_unreachable("key missing from Keys"); @@ -1398,22 +1512,20 @@ public: // Now that we sucessefully parsed the YAML file, canonicalize the internal // representation to a proper directory tree so that we can search faster // inside the VFS. - for (std::unique_ptr<Entry> &E : RootEntries) + for (auto &E : RootEntries) uniqueOverlayTree(FS, E.get()); return true; } }; -} // end of anonymous namespace -Entry::~Entry() = default; +} // namespace RedirectingFileSystem * RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS) { - SourceMgr SM; yaml::Stream Stream(Buffer->getMemBufferRef(), SM); @@ -1473,7 +1585,7 @@ ErrorOr<Entry *> RedirectingFileSystem::lookupPath(const Twine &Path_) { sys::path::const_iterator Start = sys::path::begin(Path); sys::path::const_iterator End = sys::path::end(Path); - for (const std::unique_ptr<Entry> &Root : Roots) { + for (const auto &Root : Roots) { ErrorOr<Entry *> Result = lookupPath(Start, End, Root.get()); if (Result || Result.getError() != llvm::errc::no_such_file_or_directory) return Result; @@ -1484,7 +1596,7 @@ ErrorOr<Entry *> RedirectingFileSystem::lookupPath(const Twine &Path_) { ErrorOr<Entry *> RedirectingFileSystem::lookupPath(sys::path::const_iterator Start, sys::path::const_iterator End, Entry *From) { -#ifndef LLVM_ON_WIN32 +#ifndef _WIN32 assert(!isTraversalComponent(*Start) && !isTraversalComponent(From->getName()) && "Paths should not contain traversal components"); @@ -1557,6 +1669,7 @@ ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path) { } namespace { + /// Provide a file wrapper with an overriden status. class FileWithFixedStatus : public File { std::unique_ptr<File> InnerFile; @@ -1568,14 +1681,17 @@ public: ErrorOr<Status> status() override { return S; } ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> + getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) override { return InnerFile->getBuffer(Name, FileSize, RequiresNullTerminator, IsVolatile); } + std::error_code close() override { return InnerFile->close(); } }; -} // end anonymous namespace + +} // namespace ErrorOr<std::unique_ptr<File>> RedirectingFileSystem::openFileForRead(const Twine &Path) { @@ -1670,11 +1786,13 @@ void YAMLVFSWriter::addFileMapping(StringRef VirtualPath, StringRef RealPath) { } namespace { + class JSONWriter { llvm::raw_ostream &OS; SmallVector<StringRef, 16> DirStack; - inline unsigned getDirIndent() { return 4 * DirStack.size(); } - inline unsigned getFileIndent() { return 4 * (DirStack.size() + 1); } + + unsigned getDirIndent() { return 4 * DirStack.size(); } + unsigned getFileIndent() { return 4 * (DirStack.size() + 1); } bool containedIn(StringRef Parent, StringRef Path); StringRef containedPart(StringRef Parent, StringRef Path); void startDirectory(StringRef Path); @@ -1683,14 +1801,17 @@ class JSONWriter { public: JSONWriter(llvm::raw_ostream &OS) : OS(OS) {} + void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> UseExternalNames, Optional<bool> IsCaseSensitive, Optional<bool> IsOverlayRelative, Optional<bool> IgnoreNonExistentContents, StringRef OverlayDir); }; -} + +} // namespace bool JSONWriter::containedIn(StringRef Parent, StringRef Path) { using namespace llvm::sys; + // Compare each path component. auto IParent = path::begin(Parent), EParent = path::end(Parent); for (auto IChild = path::begin(Path), EChild = path::end(Path); @@ -1812,8 +1933,8 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, } void YAMLVFSWriter::write(llvm::raw_ostream &OS) { - std::sort(Mappings.begin(), Mappings.end(), - [](const YAMLVFSEntry &LHS, const YAMLVFSEntry &RHS) { + llvm::sort(Mappings.begin(), Mappings.end(), + [](const YAMLVFSEntry &LHS, const YAMLVFSEntry &RHS) { return LHS.VPath < RHS.VPath; }); @@ -1868,7 +1989,7 @@ std::error_code VFSFromYamlDirIterImpl::increment() { if (Current == End) CurrentEntry = Status(); - return std::error_code(); + return {}; } vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_, diff --git a/contrib/llvm/tools/clang/lib/Basic/XRayInstr.cpp b/contrib/llvm/tools/clang/lib/Basic/XRayInstr.cpp new file mode 100644 index 000000000000..8cc36df79468 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/XRayInstr.cpp @@ -0,0 +1,30 @@ +//===--- XRayInstr.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is part of XRay, a function call instrumentation system. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/XRayInstr.h" +#include "llvm/ADT/StringSwitch.h" + +namespace clang { + +XRayInstrMask parseXRayInstrValue(StringRef Value) { + XRayInstrMask ParsedKind = llvm::StringSwitch<XRayInstrMask>(Value) + .Case("all", XRayInstrKind::All) + .Case("custom", XRayInstrKind::Custom) + .Case("function", XRayInstrKind::Function) + .Case("typed", XRayInstrKind::Typed) + .Case("none", XRayInstrKind::None) + .Default(XRayInstrKind::None); + return ParsedKind; +} + +} // namespace clang diff --git a/contrib/llvm/tools/clang/lib/Basic/XRayLists.cpp b/contrib/llvm/tools/clang/lib/Basic/XRayLists.cpp index 462777d53400..ad331899d2e2 100644 --- a/contrib/llvm/tools/clang/lib/Basic/XRayLists.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/XRayLists.cpp @@ -16,24 +16,32 @@ using namespace clang; XRayFunctionFilter::XRayFunctionFilter( ArrayRef<std::string> AlwaysInstrumentPaths, - ArrayRef<std::string> NeverInstrumentPaths, SourceManager &SM) + ArrayRef<std::string> NeverInstrumentPaths, + ArrayRef<std::string> AttrListPaths, SourceManager &SM) : AlwaysInstrument( llvm::SpecialCaseList::createOrDie(AlwaysInstrumentPaths)), NeverInstrument(llvm::SpecialCaseList::createOrDie(NeverInstrumentPaths)), - SM(SM) {} + AttrList(llvm::SpecialCaseList::createOrDie(AttrListPaths)), SM(SM) {} XRayFunctionFilter::ImbueAttribute XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const { // First apply the always instrument list, than if it isn't an "always" see // whether it's treated as a "never" instrument function. + // TODO: Remove these as they're deprecated; use the AttrList exclusively. if (AlwaysInstrument->inSection("xray_always_instrument", "fun", FunctionName, - "arg1")) + "arg1") || + AttrList->inSection("always", "fun", FunctionName, "arg1")) return ImbueAttribute::ALWAYS_ARG1; if (AlwaysInstrument->inSection("xray_always_instrument", "fun", - FunctionName)) + FunctionName) || + AttrList->inSection("always", "fun", FunctionName)) return ImbueAttribute::ALWAYS; - if (NeverInstrument->inSection("xray_never_instrument", "fun", FunctionName)) + + if (NeverInstrument->inSection("xray_never_instrument", "fun", + FunctionName) || + AttrList->inSection("never", "fun", FunctionName)) return ImbueAttribute::NEVER; + return ImbueAttribute::NONE; } @@ -41,10 +49,12 @@ XRayFunctionFilter::ImbueAttribute XRayFunctionFilter::shouldImbueFunctionsInFile(StringRef Filename, StringRef Category) const { if (AlwaysInstrument->inSection("xray_always_instrument", "src", Filename, - Category)) + Category) || + AttrList->inSection("always", "src", Filename, Category)) return ImbueAttribute::ALWAYS; if (NeverInstrument->inSection("xray_never_instrument", "src", Filename, - Category)) + Category) || + AttrList->inSection("never", "src", Filename, Category)) return ImbueAttribute::NEVER; return ImbueAttribute::NONE; } |