diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
18 files changed, 1096 insertions, 409 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp index 83228ad..f89caf7 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp @@ -24,6 +24,27 @@ using namespace clang; +const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, + DiagNullabilityKind nullability) { + StringRef string; + switch (nullability.first) { + case NullabilityKind::NonNull: + string = nullability.second ? "'nonnull'" : "'_Nonnull'"; + break; + + case NullabilityKind::Nullable: + string = nullability.second ? "'nullable'" : "'_Nullable'"; + break; + + case NullabilityKind::Unspecified: + string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'"; + break; + } + + DB.AddString(string); + return DB; +} + static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, StringRef Modifier, StringRef Argument, ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs, @@ -112,7 +133,7 @@ void DiagnosticsEngine::Reset() { // Create a DiagState and DiagStatePoint representing diagnostic changes // through command-line. - DiagStates.push_back(DiagState()); + DiagStates.emplace_back(); DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc())); } @@ -321,18 +342,10 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { NumDiagArgs = 0; DiagRanges.clear(); - DiagRanges.reserve(storedDiag.range_size()); - for (StoredDiagnostic::range_iterator - RI = storedDiag.range_begin(), - RE = storedDiag.range_end(); RI != RE; ++RI) - DiagRanges.push_back(*RI); + DiagRanges.append(storedDiag.range_begin(), storedDiag.range_end()); DiagFixItHints.clear(); - DiagFixItHints.reserve(storedDiag.fixit_size()); - for (StoredDiagnostic::fixit_iterator - FI = storedDiag.fixit_begin(), - FE = storedDiag.fixit_end(); FI != FE; ++FI) - DiagFixItHints.push_back(*FI); + DiagFixItHints.append(storedDiag.fixit_begin(), storedDiag.fixit_end()); assert(Client && "DiagnosticConsumer not set!"); Level DiagLevel = storedDiag.getLevel(); @@ -633,7 +646,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, // 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. - if (DiagEnd - DiagStr == 2 && DiagStr[0] == '%' && DiagStr[1] == '0' && + if (DiagEnd - DiagStr == 2 && + StringRef(DiagStr, DiagEnd - DiagStr).equals("%0") && getArgKind(0) == DiagnosticsEngine::ak_std_string) { const std::string &S = getArgStdStr(0); for (char c : S) { @@ -948,14 +962,8 @@ StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, SmallString<64> Message; Info.FormatDiagnostic(Message); this->Message.assign(Message.begin(), Message.end()); - - Ranges.reserve(Info.getNumRanges()); - for (unsigned I = 0, N = Info.getNumRanges(); I != N; ++I) - Ranges.push_back(Info.getRange(I)); - - FixIts.reserve(Info.getNumFixItHints()); - for (unsigned I = 0, N = Info.getNumFixItHints(); I != N; ++I) - FixIts.push_back(Info.getFixItHint(I)); + this->Ranges.assign(Info.getRanges().begin(), Info.getRanges().end()); + this->FixIts.assign(Info.getFixItHints().begin(), Info.getFixItHints().end()); } StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp index 1c68375..643503b 100644 --- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp @@ -528,7 +528,7 @@ static bool getDiagnosticsInGroup(diag::Flavor Flavor, // An empty group is considered to be a warning group: we have empty groups // for GCC compatibility, and GCC does not have remarks. if (!Group->Members && !Group->SubGroups) - return Flavor == diag::Flavor::Remark ? true : false; + return Flavor == diag::Flavor::Remark; bool NotFound = true; diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp new file mode 100644 index 0000000..f54a0ef --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp @@ -0,0 +1,24 @@ +//===--- DiagnosticOptions.cpp - C Language Family Diagnostic Handling ----===// +// +// 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 DiagnosticOptions related interfaces. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/DiagnosticOptions.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { + +raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M) { + using UT = std::underlying_type<DiagnosticLevelMask>::type; + return Out << static_cast<UT>(M); +} + +} // end namespace clang diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp index 214e0f3..1a636ae 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp @@ -19,6 +19,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemStatCache.h" +#include "clang/Frontend/PCHContainerOperations.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/FileSystem.h" @@ -430,7 +431,7 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, SmallString<128> FilePath(Entry->getName()); FixupRelativePath(FilePath); - return FS->getBufferForFile(FilePath.str(), FileSize, + return FS->getBufferForFile(FilePath, FileSize, /*RequiresNullTerminator=*/true, isVolatile); } @@ -585,3 +586,5 @@ void FileManager::PrintStats() const { //llvm::errs() << PagesMapped << BytesOfPagesMapped << FSLookups; } + +PCHContainerOperations::~PCHContainerOperations() {} diff --git a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp index 83e42bd..187ea37 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp @@ -15,19 +15,8 @@ #include "clang/Basic/VirtualFileSystem.h" #include "llvm/Support/Path.h" -// FIXME: This is terrible, we need this for ::close. -#if !defined(_MSC_VER) && !defined(__MINGW32__) -#include <unistd.h> -#include <sys/uio.h> -#else -#include <io.h> -#endif using namespace clang; -#if defined(_MSC_VER) -#define S_ISDIR(s) ((_S_IFDIR & s) !=0) -#endif - void FileSystemStatCache::anchor() { } static void copyStatusToFileData(const vfs::Status &Status, diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp index 613b43f..dcb7603 100644 --- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp @@ -16,6 +16,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/Specifiers.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallString.h" @@ -35,7 +36,7 @@ IdentifierInfo::IdentifierInfo() { HasMacro = false; HadMacro = false; IsExtension = false; - IsCXX11CompatKeyword = false; + IsFutureCompatKeyword = false; IsPoisoned = false; IsCPPOperatorKeyword = false; NeedsHandleIdentifier = false; @@ -70,8 +71,6 @@ IdentifierIterator *IdentifierInfoLookup::getIdentifiers() { return new EmptyLookupIterator(); } -ExternalIdentifierLookup::~ExternalIdentifierLookup() {} - IdentifierTable::IdentifierTable(const LangOptions &LangOpts, IdentifierInfoLookup* externalLookup) : HashTable(8192), // Start with space for 8K identifiers. @@ -105,10 +104,14 @@ namespace { KEYOPENCL = 0x200, KEYC11 = 0x400, KEYARC = 0x800, - KEYNOMS = 0x01000, - WCHARSUPPORT = 0x02000, - HALFSUPPORT = 0x04000, - KEYALL = (0xffff & ~KEYNOMS) // Because KEYNOMS is used to exclude. + KEYNOMS18 = 0x01000, + KEYNOOPENCL = 0x02000, + WCHARSUPPORT = 0x04000, + HALFSUPPORT = 0x08000, + KEYCONCEPTS = 0x10000, + KEYOBJC2 = 0x20000, + KEYALL = (0x3ffff & ~KEYNOMS18 & + ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude. }; /// \brief How a keyword is treated in the selected standard. @@ -141,6 +144,8 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, // We treat bridge casts as objective-C keywords so we can warn on them // in non-arc mode. if (LangOpts.ObjC2 && (Flags & KEYARC)) return KS_Enabled; + if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled; + if (LangOpts.ObjC2 && (Flags & KEYOBJC2)) return KS_Enabled; if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) return KS_Future; return KS_Disabled; } @@ -154,15 +159,21 @@ static void AddKeyword(StringRef Keyword, KeywordStatus AddResult = getKeywordStatus(LangOpts, Flags); // Don't add this keyword under MSVCCompat. - if (LangOpts.MSVCCompat && (Flags & KEYNOMS)) - return; + if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) && + !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015)) + return; + + // Don't add this keyword under OpenCL. + if (LangOpts.OpenCL && (Flags & KEYNOOPENCL)) + return; + // Don't add this keyword if disabled in this language. if (AddResult == KS_Disabled) return; IdentifierInfo &Info = Table.get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode); Info.setIsExtensionToken(AddResult == KS_Extension); - Info.setIsCXX11CompatKeyword(AddResult == KS_Future); + Info.setIsFutureCompatKeyword(AddResult == KS_Future); } /// AddCXXOperatorKeyword - Register a C++ operator keyword alternative @@ -207,6 +218,12 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { if (LangOpts.ParseUnknownAnytype) AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL, LangOpts, *this); + + // FIXME: __declspec isn't really a CUDA extension, however it is required for + // supporting cuda_builtin_vars.h, which uses __declspec(property). Once that + // has been rewritten in terms of something more generic, remove this code. + if (LangOpts.CUDA) + AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this); } /// \brief Checks if the specified token kind represents a keyword in the @@ -629,3 +646,18 @@ const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) { llvm_unreachable("Invalid OverloadedOperatorKind!"); } + +StringRef clang::getNullabilitySpelling(NullabilityKind kind, + bool isContextSensitive) { + switch (kind) { + case NullabilityKind::NonNull: + return isContextSensitive ? "nonnull" : "_Nonnull"; + + case NullabilityKind::Nullable: + return isContextSensitive ? "nullable" : "_Nullable"; + + case NullabilityKind::Unspecified: + return isContextSensitive ? "null_unspecified" : "_Null_unspecified"; + } + llvm_unreachable("Unknown nullability kind."); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp index dcbd228..2c87845 100644 --- a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp @@ -30,7 +30,7 @@ void LangOptions::resetNonModularOptions() { // FIXME: This should not be reset; modules can be different with different // sanitizer options (this affects __has_feature(address_sanitizer) etc). Sanitize.clear(); - SanitizerBlacklistFile.clear(); + SanitizerBlacklistFiles.clear(); CurrentModule.clear(); ImplementationOfModule.clear(); diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp index 03f9bd3..3846fec 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Module.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp @@ -25,14 +25,14 @@ using namespace clang; Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, - bool IsFramework, bool IsExplicit) + bool IsFramework, bool IsExplicit, unsigned VisibilityID) : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(), - Umbrella(), ASTFile(nullptr), IsMissingRequirement(false), - IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), - IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), - IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), - InferExportWildcard(false), ConfigMacrosExhaustive(false), - NameVisibility(Hidden) { + Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID), + IsMissingRequirement(false), IsAvailable(true), IsFromModuleFile(false), + IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), + IsExternC(false), IsInferred(false), InferSubmodules(false), + InferExplicitSubmodules(false), InferExportWildcard(false), + ConfigMacrosExhaustive(false), NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) IsAvailable = false; @@ -58,16 +58,21 @@ Module::~Module() { /// language options has the given feature. static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target) { - return llvm::StringSwitch<bool>(Feature) - .Case("altivec", LangOpts.AltiVec) - .Case("blocks", LangOpts.Blocks) - .Case("cplusplus", LangOpts.CPlusPlus) - .Case("cplusplus11", LangOpts.CPlusPlus11) - .Case("objc", LangOpts.ObjC1) - .Case("objc_arc", LangOpts.ObjCAutoRefCount) - .Case("opencl", LangOpts.OpenCL) - .Case("tls", Target.isTLSSupported()) - .Default(Target.hasFeature(Feature)); + bool HasFeature = llvm::StringSwitch<bool>(Feature) + .Case("altivec", LangOpts.AltiVec) + .Case("blocks", LangOpts.Blocks) + .Case("cplusplus", LangOpts.CPlusPlus) + .Case("cplusplus11", LangOpts.CPlusPlus11) + .Case("objc", LangOpts.ObjC1) + .Case("objc_arc", LangOpts.ObjCAutoRefCount) + .Case("opencl", LangOpts.OpenCL) + .Case("tls", Target.isTLSSupported()) + .Default(Target.hasFeature(Feature)); + if (!HasFeature) + HasFeature = std::find(LangOpts.ModuleFeatures.begin(), + LangOpts.ModuleFeatures.end(), + Feature) != LangOpts.ModuleFeatures.end(); + return HasFeature; } bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, @@ -77,10 +82,6 @@ bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, return true; for (const Module *Current = this; Current; Current = Current->Parent) { - if (!Current->MissingHeaders.empty()) { - MissingHeader = Current->MissingHeaders.front(); - 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) { @@ -88,6 +89,10 @@ bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, return false; } } + if (!Current->MissingHeaders.empty()) { + MissingHeader = Current->MissingHeaders.front(); + return false; + } } llvm_unreachable("could not find a reason why module is unavailable"); @@ -133,11 +138,11 @@ std::string Module::getFullModuleName() const { return Result; } -const DirectoryEntry *Module::getUmbrellaDir() const { - if (const FileEntry *Header = getUmbrellaHeader()) - return Header->getDir(); +Module::DirectoryName Module::getUmbrellaDir() const { + if (Header U = getUmbrellaHeader()) + return {"", U.Entry->getDir()}; - return Umbrella.dyn_cast<const DirectoryEntry *>(); + return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()}; } ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { @@ -153,6 +158,19 @@ ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); } +bool Module::directlyUses(const Module *Requested) const { + auto *Top = getTopLevelModule(); + + // A top-level module implicitly uses itself. + if (Requested->isSubModuleOf(Top)) + return true; + + for (auto *Use : Top->DirectUses) + if (Requested->isSubModuleOf(Use)) + return true; + return false; +} + void Module::addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target) { @@ -166,7 +184,11 @@ void Module::addRequirement(StringRef Feature, bool RequiredState, } void Module::markUnavailable(bool MissingRequirement) { - if (!IsAvailable) + auto needUpdate = [MissingRequirement](Module *M) { + return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement); + }; + + if (!needUpdate(this)) return; SmallVector<Module *, 2> Stack; @@ -175,7 +197,7 @@ void Module::markUnavailable(bool MissingRequirement) { Module *Current = Stack.back(); Stack.pop_back(); - if (!Current->IsAvailable) + if (!needUpdate(Current)) continue; Current->IsAvailable = false; @@ -183,7 +205,7 @@ void Module::markUnavailable(bool MissingRequirement) { for (submodule_iterator Sub = Current->submodule_begin(), SubEnd = Current->submodule_end(); Sub != SubEnd; ++Sub) { - if ((*Sub)->IsAvailable) + if (needUpdate(*Sub)) Stack.push_back(*Sub); } } @@ -316,15 +338,15 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS << "\n"; } - if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) { + if (Header H = getUmbrellaHeader()) { OS.indent(Indent + 2); OS << "umbrella header \""; - OS.write_escaped(UmbrellaHeader->getName()); + OS.write_escaped(H.NameAsWritten); OS << "\"\n"; - } else if (const DirectoryEntry *UmbrellaDir = getUmbrellaDir()) { + } else if (DirectoryName D = getUmbrellaDir()) { OS.indent(Indent + 2); OS << "umbrella \""; - OS.write_escaped(UmbrellaDir->getName()); + OS.write_escaped(D.NameAsWritten); OS << "\"\n"; } @@ -457,4 +479,47 @@ void Module::dump() const { print(llvm::errs()); } +void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, + VisibleCallback Vis, ConflictCallback Cb) { + if (isVisible(M)) + return; + ++Generation; + + struct Visiting { + Module *M; + Visiting *ExportedBy; + }; + + std::function<void(Visiting)> VisitModule = [&](Visiting V) { + // Modules that aren't available cannot be made visible. + if (!V.M->isAvailable()) + return; + + // Nothing to do for a module that's already visible. + unsigned ID = V.M->getVisibilityID(); + if (ImportLocs.size() <= ID) + ImportLocs.resize(ID + 1); + else if (ImportLocs[ID].isValid()) + return; + + ImportLocs[ID] = Loc; + Vis(M); + + // Make any exported modules visible. + SmallVector<Module *, 16> Exports; + V.M->getExportedModules(Exports); + for (Module *E : Exports) + VisitModule({E, &V}); + + for (auto &C : V.M->Conflicts) { + if (isVisible(C.Other)) { + llvm::SmallVector<Module*, 8> Path; + for (Visiting *I = &V; I; I = I->ExportedBy) + Path.push_back(I->M); + Cb(Path, C.Other, C.Message); + } + } + }; + VisitModule({M, nullptr}); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp index 6e98d48..b7407f6 100644 --- a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp @@ -91,6 +91,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, #define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_SCHEDULE_unknown); + case OMPC_depend: + return llvm::StringSwitch<OpenMPDependClauseKind>(Str) +#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_DEPEND_unknown); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -154,6 +159,15 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, return #Name; #include "clang/Basic/OpenMPKinds.def" } + case OMPC_depend: + switch (Type) { + case OMPC_DEPEND_unknown: + return "unknown"; +#define OPENMP_DEPEND_KIND(Name) \ + case OMPC_DEPEND_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } llvm_unreachable("Invalid OpenMP 'schedule' clause type"); case OMPC_unknown: case OMPC_threadprivate: @@ -332,6 +346,9 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: + case OMPD_taskgroup: + case OMPD_cancellation_point: + case OMPD_cancel: case OMPD_ordered: break; } @@ -374,7 +391,6 @@ bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) { } bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) { - return Kind == OMPC_threadprivate || - Kind == OMPC_copyin; // TODO add next clauses like 'copyprivate'. + return Kind == OMPC_threadprivate || Kind == OMPC_copyin; } diff --git a/contrib/llvm/tools/clang/lib/Basic/SanitizerBlacklist.cpp b/contrib/llvm/tools/clang/lib/Basic/SanitizerBlacklist.cpp index ea5b8d0..095fcd6 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SanitizerBlacklist.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SanitizerBlacklist.cpp @@ -15,9 +15,9 @@ using namespace clang; -SanitizerBlacklist::SanitizerBlacklist(StringRef BlacklistPath, - SourceManager &SM) - : SCL(llvm::SpecialCaseList::createOrDie(BlacklistPath)), SM(SM) {} +SanitizerBlacklist::SanitizerBlacklist( + const std::vector<std::string> &BlacklistPaths, SourceManager &SM) + : SCL(llvm::SpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {} bool SanitizerBlacklist::isBlacklistedGlobal(StringRef GlobalName, StringRef Category) const { diff --git a/contrib/llvm/tools/clang/lib/Basic/Sanitizers.cpp b/contrib/llvm/tools/clang/lib/Basic/Sanitizers.cpp index e9aaa36..91b6b2d 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Sanitizers.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Sanitizers.cpp @@ -11,25 +11,27 @@ // //===----------------------------------------------------------------------===// #include "clang/Basic/Sanitizers.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" using namespace clang; -SanitizerSet::SanitizerSet() : Kinds(0) {} - -bool SanitizerSet::has(SanitizerKind K) const { - unsigned Bit = static_cast<unsigned>(K); - return Kinds & (1 << Bit); -} - -void SanitizerSet::set(SanitizerKind K, bool Value) { - unsigned Bit = static_cast<unsigned>(K); - Kinds = Value ? (Kinds | (1 << Bit)) : (Kinds & ~(1 << Bit)); -} - -void SanitizerSet::clear() { - Kinds = 0; +SanitizerMask clang::parseSanitizerValue(StringRef Value, bool AllowGroups) { + SanitizerMask ParsedKind = llvm::StringSwitch<SanitizerMask>(Value) +#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID) +#define SANITIZER_GROUP(NAME, ID, ALIAS) \ + .Case(NAME, AllowGroups ? SanitizerKind::ID##Group : 0) +#include "clang/Basic/Sanitizers.def" + .Default(0); + return ParsedKind; } -bool SanitizerSet::empty() const { - return Kinds == 0; +SanitizerMask clang::expandSanitizerGroups(SanitizerMask Kinds) { +#define SANITIZER(NAME, ID) +#define SANITIZER_GROUP(NAME, ID, ALIAS) \ + if (Kinds & SanitizerKind::ID##Group) \ + Kinds |= SanitizerKind::ID; +#include "clang/Basic/Sanitizers.def" + return Kinds; } diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp index 6b885a7..d254e86 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp @@ -134,7 +134,7 @@ const char *FullSourceLoc::getCharacterData(bool *Invalid) const { StringRef FullSourceLoc::getBufferData(bool *Invalid) const { assert(isValid()); - return SrcMgr->getBuffer(SrcMgr->getFileID(*this), Invalid)->getBuffer();; + return SrcMgr->getBuffer(SrcMgr->getFileID(*this), Invalid)->getBuffer(); } std::pair<FileID, unsigned> FullSourceLoc::getDecomposedLoc() const { diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp index 118e3f3..c0b0453 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -110,8 +110,8 @@ llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag, // possible. if (!BufferOrError) { StringRef FillStr("<<<MISSING SOURCE FILE>>>\n"); - Buffer.setPointer(MemoryBuffer::getNewMemBuffer(ContentsEntry->getSize(), - "<invalid>").release()); + Buffer.setPointer(MemoryBuffer::getNewUninitMemBuffer( + ContentsEntry->getSize(), "<invalid>").release()); char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart()); for (unsigned i = 0, e = ContentsEntry->getSize(); i != e; ++i) Ptr[i] = FillStr[i % FillStr.size()]; diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp index 871bbd5..dbd2f9a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp @@ -36,6 +36,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { LongWidth = LongAlign = 32; LongLongWidth = LongLongAlign = 64; SuitableAlign = 64; + DefaultAlignForAttributeAligned = 128; MinGlobalAlign = 0; HalfWidth = 16; HalfAlign = 16; @@ -49,6 +50,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; MaxVectorAlign = 0; + MaxTLSAlign = 0; + SimdDefaultAlign = 0; SizeType = UnsignedLong; PtrDiffType = SignedLong; IntMaxType = SignedLongLong; diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index a7a0057..3cf74bc 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -25,9 +25,9 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" -#include "llvm/IR/Type.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetParser.h" #include <algorithm> #include <memory> using namespace clang; @@ -185,6 +185,28 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, } namespace { +// CloudABI Target +template <typename Target> +class CloudABITargetInfo : public OSTargetInfo<Target> { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + Builder.defineMacro("__CloudABI__"); + Builder.defineMacro("__ELF__"); + + // CloudABI uses ISO/IEC 10646:2012 for wchar_t, char16_t and char32_t. + Builder.defineMacro("__STDC_ISO_10646__", "201206L"); + Builder.defineMacro("__STDC_UTF_16__"); + Builder.defineMacro("__STDC_UTF_32__"); + } + +public: + CloudABITargetInfo(const llvm::Triple &Triple) + : OSTargetInfo<Target>(Triple) { + this->UserLabelPrefix = ""; + } +}; + template<typename Target> class DarwinTargetInfo : public OSTargetInfo<Target> { protected: @@ -364,8 +386,13 @@ protected: DefineStd(Builder, "linux", Opts); Builder.defineMacro("__gnu_linux__"); Builder.defineMacro("__ELF__"); - if (Triple.getEnvironment() == llvm::Triple::Android) + if (Triple.getEnvironment() == llvm::Triple::Android) { Builder.defineMacro("__ANDROID__", "1"); + unsigned Maj, Min, Rev; + Triple.getEnvironmentVersion(Maj, Min, Rev); + this->PlatformName = "android"; + this->PlatformMinVersion = VersionTuple(Maj, Min, Rev); + } if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); if (Opts.CPlusPlus) @@ -473,6 +500,17 @@ protected: Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); + + switch (Triple.getArch()) { + default: + break; + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: + Builder.defineMacro("__ARM_DWARF_EH__"); + break; + } } public: BitrigTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { @@ -526,6 +564,35 @@ public: } }; +template <typename Target> +class PS4OSTargetInfo : public OSTargetInfo<Target> { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + Builder.defineMacro("__FreeBSD__", "9"); + Builder.defineMacro("__FreeBSD_cc_version", "900001"); + Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); + DefineStd(Builder, "unix", Opts); + Builder.defineMacro("__ELF__"); + Builder.defineMacro("__PS4__"); + } +public: + PS4OSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + this->WCharType = this->UnsignedShort; + + // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits). + this->MaxTLSAlign = 256; + this->UserLabelPrefix = ""; + + switch (Triple.getArch()) { + default: + case llvm::Triple::x86_64: + this->MCountName = ".mcount"; + break; + } + } +}; + // Solaris target template<typename Target> class SolarisTargetInfo : public OSTargetInfo<Target> { @@ -574,7 +641,7 @@ protected: if (Opts.RTTIData) Builder.defineMacro("_CPPRTTI"); - if (Opts.Exceptions) + if (Opts.CXXExceptions) Builder.defineMacro("_CPPUNWIND"); } @@ -592,6 +659,9 @@ protected: Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion)); // FIXME We cannot encode the revision information into 32-bits Builder.defineMacro("_MSC_BUILD", Twine(1)); + + if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) + Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1)); } if (Opts.MicrosoftExt) { @@ -647,8 +717,7 @@ public: // RegParmMax is inherited from the underlying architecture this->LongDoubleFormat = &llvm::APFloat::IEEEdouble; if (Triple.getArch() == llvm::Triple::arm) { - this->DescriptionString = - "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128"; + // Handled in ARM's setABI(). } else if (Triple.getArch() == llvm::Triple::x86) { this->DescriptionString = "e-m:e-p:32:32-i64:64-n8:16:32-S128"; } else if (Triple.getArch() == llvm::Triple::x86_64) { @@ -660,19 +729,12 @@ public: this->DescriptionString = "e-p:32:32-i64:64"; } } - typename Target::CallingConvCheckResult checkCallingConvention( - CallingConv CC) const override { - return CC == CC_PnaclCall ? Target::CCCR_OK : - Target::checkCallingConvention(CC); - } }; -} // end anonymous namespace. //===----------------------------------------------------------------------===// // Specific target implementations. //===----------------------------------------------------------------------===// -namespace { // PPC abstract base class class PPCTargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; @@ -683,14 +745,23 @@ class PPCTargetInfo : public TargetInfo { // Target cpu features. bool HasVSX; bool HasP8Vector; + bool HasP8Crypto; + bool HasDirectMove; + bool HasQPX; + bool HasHTM; + bool HasBPERMD; + bool HasExtDiv; protected: std::string ABI; public: PPCTargetInfo(const llvm::Triple &Triple) - : TargetInfo(Triple), HasVSX(false), HasP8Vector(false) { + : TargetInfo(Triple), HasVSX(false), HasP8Vector(false), + HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false), + HasBPERMD(false), HasExtDiv(false) { BigEndian = (Triple.getArch() != llvm::Triple::ppc64le); + SimdDefaultAlign = 128; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; } @@ -794,6 +865,8 @@ public: bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; bool hasFeature(StringRef Feature) const override; + void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, + bool Enabled) const override; void getGCCRegNames(const char * const *&Names, unsigned &NumNames) const override; @@ -924,6 +997,12 @@ public: bool hasSjLjLowering() const override { return true; } + + bool useFloat128ManglingForLongDouble() const override { + return LongDoubleWidth == 128 && + LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble && + getTriple().isOSBinFormatELF(); + } }; const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { @@ -949,14 +1028,53 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, continue; } + if (Feature == "bpermd") { + HasBPERMD = true; + continue; + } + + if (Feature == "extdiv") { + HasExtDiv = true; + continue; + } + if (Feature == "power8-vector") { HasP8Vector = true; continue; } + if (Feature == "crypto") { + HasP8Crypto = true; + continue; + } + + if (Feature == "direct-move") { + HasDirectMove = true; + continue; + } + + if (Feature == "qpx") { + HasQPX = true; + continue; + } + + if (Feature == "htm") { + HasHTM = true; + continue; + } + // TODO: Finish this list and add an assert that we've handled them // all. } + if (!HasVSX && (HasP8Vector || HasDirectMove)) { + if (HasP8Vector) + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower8-vector" << + "-mno-vsx"; + else if (HasDirectMove) + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mdirect-move" << + "-mno-vsx"; + return false; + } return true; } @@ -988,7 +1106,7 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, } // ABI options. - if (ABI == "elfv1") + if (ABI == "elfv1" || ABI == "elfv1-qpx") Builder.defineMacro("_CALL_ELF", "1"); if (ABI == "elfv2") Builder.defineMacro("_CALL_ELF", "2"); @@ -1106,6 +1224,18 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__VSX__"); if (HasP8Vector) Builder.defineMacro("__POWER8_VECTOR__"); + if (HasP8Crypto) + Builder.defineMacro("__CRYPTO__"); + if (HasHTM) + Builder.defineMacro("__HTM__"); + if (getTriple().getArch() == llvm::Triple::ppc64le || + (defs & ArchDefinePwr8) || (CPU == "pwr8")) { + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); + if (PointerWidth == 64) + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); + } // FIXME: The following are not yet generated here by Clang, but are // generated by GCC: @@ -1144,9 +1274,33 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { .Default(false); Features["qpx"] = (CPU == "a2q"); - - if (!ABI.empty()) - Features[ABI] = true; + Features["crypto"] = llvm::StringSwitch<bool>(CPU) + .Case("ppc64le", true) + .Case("pwr8", true) + .Default(false); + Features["power8-vector"] = llvm::StringSwitch<bool>(CPU) + .Case("ppc64le", true) + .Case("pwr8", true) + .Default(false); + Features["bpermd"] = llvm::StringSwitch<bool>(CPU) + .Case("ppc64le", true) + .Case("pwr8", true) + .Case("pwr7", true) + .Default(false); + Features["extdiv"] = llvm::StringSwitch<bool>(CPU) + .Case("ppc64le", true) + .Case("pwr8", true) + .Case("pwr7", true) + .Default(false); + Features["direct-move"] = llvm::StringSwitch<bool>(CPU) + .Case("ppc64le", true) + .Case("pwr8", true) + .Default(false); + Features["vsx"] = llvm::StringSwitch<bool>(CPU) + .Case("ppc64le", true) + .Case("pwr8", true) + .Case("pwr7", true) + .Default(false); } bool PPCTargetInfo::hasFeature(StringRef Feature) const { @@ -1154,9 +1308,48 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const { .Case("powerpc", true) .Case("vsx", HasVSX) .Case("power8-vector", HasP8Vector) + .Case("crypto", HasP8Crypto) + .Case("direct-move", HasDirectMove) + .Case("qpx", HasQPX) + .Case("htm", HasHTM) + .Case("bpermd", HasBPERMD) + .Case("extdiv", HasExtDiv) .Default(false); } +/* There is no clear way for the target to know which of the features in the + final feature vector came from defaults and which are actually specified by + the user. To that end, we use the fact that this function is not called on + default features - only user specified ones. By the first time this + function is called, the default features are populated. + We then keep track of the features that the user specified so that we + can ensure we do not override a user's request (only defaults). + For example: + -mcpu=pwr8 -mno-vsx (should disable vsx and everything that depends on it) + -mcpu=pwr8 -mdirect-move -mno-vsx (should actually be diagnosed) + +NOTE: Do not call this from PPCTargetInfo::getDefaultFeatures +*/ +void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, bool Enabled) const { + static llvm::StringMap<bool> ExplicitFeatures; + ExplicitFeatures[Name] = Enabled; + + // At this point, -mno-vsx turns off the dependent features but we respect + // the user's requests. + if (!Enabled && Name == "vsx") { + Features["direct-move"] = ExplicitFeatures["direct-move"]; + Features["power8-vector"] = ExplicitFeatures["power8-vector"]; + } + if ((Enabled && Name == "power8-vector") || + (Enabled && Name == "direct-move")) { + if (ExplicitFeatures.find("vsx") == ExplicitFeatures.end()) { + Features["vsx"] = true; + } + } + Features[Name] = Enabled; +} + const char * const PPCTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -1259,9 +1452,7 @@ void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, Aliases = GCCRegAliases; NumAliases = llvm::array_lengthof(GCCRegAliases); } -} // end anonymous namespace. -namespace { class PPC32TargetInfo : public PPCTargetInfo { public: PPC32TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) { @@ -1293,11 +1484,9 @@ public: return TargetInfo::PowerABIBuiltinVaList; } }; -} // end anonymous namespace. // Note: ABI differences may eventually require us to have a separate // TargetInfo for little endian. -namespace { class PPC64TargetInfo : public PPCTargetInfo { public: PPC64TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) { @@ -1332,19 +1521,16 @@ public: BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } - // PPC64 Linux-specifc ABI options. + // PPC64 Linux-specific ABI options. bool setABI(const std::string &Name) override { - if (Name == "elfv1" || Name == "elfv2") { + if (Name == "elfv1" || Name == "elfv1-qpx" || Name == "elfv2") { ABI = Name; return true; } return false; } }; -} // end anonymous namespace. - -namespace { class DarwinPPC32TargetInfo : public DarwinTargetInfo<PPC32TargetInfo> { public: @@ -1372,9 +1558,7 @@ public: DescriptionString = "E-m:o-i64:64-n32:64"; } }; -} // end anonymous namespace. -namespace { static const unsigned NVPTXAddrSpaceMap[] = { 1, // opencl_global 3, // opencl_local @@ -1396,6 +1580,7 @@ namespace { GK_SM21, GK_SM30, GK_SM35, + GK_SM37, } GPU; public: @@ -1431,6 +1616,9 @@ namespace { case GK_SM35: CUDAArchCode = "350"; break; + case GK_SM37: + CUDAArchCode = "370"; + break; default: llvm_unreachable("Unhandled target CPU"); } @@ -1483,6 +1671,7 @@ namespace { .Case("sm_21", GK_SM21) .Case("sm_30", GK_SM30) .Case("sm_35", GK_SM35) + .Case("sm_37", GK_SM37) .Default(GK_NONE); return GPU != GK_NONE; @@ -1510,26 +1699,25 @@ namespace { public: NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) { PointerWidth = PointerAlign = 32; - SizeType = PtrDiffType = TargetInfo::UnsignedInt; + SizeType = TargetInfo::UnsignedInt; + PtrDiffType = TargetInfo::SignedInt; IntPtrType = TargetInfo::SignedInt; DescriptionString = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"; - } + } }; class NVPTX64TargetInfo : public NVPTXTargetInfo { public: NVPTX64TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) { PointerWidth = PointerAlign = 64; - SizeType = PtrDiffType = TargetInfo::UnsignedLongLong; - IntPtrType = TargetInfo::SignedLongLong; + SizeType = TargetInfo::UnsignedLong; + PtrDiffType = TargetInfo::SignedLong; + IntPtrType = TargetInfo::SignedLong; DescriptionString = "e-i64:64-v16:16-v32:32-n16:32:64"; - } + } }; -} - -namespace { -static const unsigned R600AddrSpaceMap[] = { +static const unsigned AMDGPUAddrSpaceMap[] = { 1, // opencl_global 3, // opencl_local 2, // opencl_constant @@ -1555,10 +1743,11 @@ static const char *DescriptionStringSI = "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; -class R600TargetInfo : public TargetInfo { +class AMDGPUTargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; + static const char * const GCCRegNames[]; - /// \brief The GPU profiles supported by the R600 target. + /// \brief The GPU profiles supported by the AMDGPU target. enum GPUKind { GK_NONE, GK_R600, @@ -1570,14 +1759,32 @@ class R600TargetInfo : public TargetInfo { GK_NORTHERN_ISLANDS, GK_CAYMAN, GK_SOUTHERN_ISLANDS, - GK_SEA_ISLANDS + GK_SEA_ISLANDS, + GK_VOLCANIC_ISLANDS } GPU; + bool hasFP64:1; + bool hasFMAF:1; + bool hasLDEXPF:1; + public: - R600TargetInfo(const llvm::Triple &Triple) - : TargetInfo(Triple), GPU(GK_R600) { - DescriptionString = DescriptionStringR600; - AddrSpaceMap = &R600AddrSpaceMap; + AMDGPUTargetInfo(const llvm::Triple &Triple) + : TargetInfo(Triple) { + + if (Triple.getArch() == llvm::Triple::amdgcn) { + DescriptionString = DescriptionStringSI; + GPU = GK_SOUTHERN_ISLANDS; + hasFP64 = true; + hasFMAF = true; + hasLDEXPF = true; + } else { + DescriptionString = DescriptionStringR600; + GPU = GK_R600; + hasFP64 = false; + hasFMAF = false; + hasLDEXPF = false; + } + AddrSpaceMap = &AMDGPUAddrSpaceMap; UseAddrSpaceMapMangling = true; } @@ -1600,10 +1807,7 @@ public: } void getGCCRegNames(const char * const *&Names, - unsigned &numNames) const override { - Names = nullptr; - numNames = 0; - } + unsigned &NumNames) const override; void getGCCRegAliases(const GCCRegAlias *&Aliases, unsigned &NumAliases) const override { @@ -1619,12 +1823,19 @@ public: void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const override { Records = BuiltinInfo; - NumRecords = clang::R600::LastTSBuiltin - Builtin::FirstTSBuiltin; + NumRecords = clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__R600__"); + if (hasFMAF) + Builder.defineMacro("__HAS_FMAF__"); + if (hasLDEXPF) + Builder.defineMacro("__HAS_LDEXPF__"); + if (hasFP64 && Opts.OpenCL) { + Builder.defineMacro("cl_khr_fp64"); + } } BuiltinVaListKind getBuiltinVaListKind() const override { @@ -1668,6 +1879,9 @@ public: .Case("kaveri", GK_SEA_ISLANDS) .Case("hawaii", GK_SEA_ISLANDS) .Case("mullins", GK_SEA_ISLANDS) + .Case("tonga", GK_VOLCANIC_ISLANDS) + .Case("iceland", GK_VOLCANIC_ISLANDS) + .Case("carrizo", GK_VOLCANIC_ISLANDS) .Default(GK_NONE); if (GPU == GK_NONE) { @@ -1682,16 +1896,26 @@ public: case GK_EVERGREEN: case GK_NORTHERN_ISLANDS: DescriptionString = DescriptionStringR600; + hasFP64 = false; + hasFMAF = false; + hasLDEXPF = false; break; case GK_R600_DOUBLE_OPS: case GK_R700_DOUBLE_OPS: case GK_EVERGREEN_DOUBLE_OPS: case GK_CAYMAN: DescriptionString = DescriptionStringR600DoubleOps; + hasFP64 = true; + hasFMAF = true; + hasLDEXPF = false; break; case GK_SOUTHERN_ISLANDS: case GK_SEA_ISLANDS: + case GK_VOLCANIC_ISLANDS: DescriptionString = DescriptionStringSI; + hasFP64 = true; + hasFMAF = true; + hasLDEXPF = true; break; } @@ -1699,15 +1923,70 @@ public: } }; -const Builtin::Info R600TargetInfo::BuiltinInfo[] = { +const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, -#include "clang/Basic/BuiltinsR600.def" +#include "clang/Basic/BuiltinsAMDGPU.def" +}; +const char * const AMDGPUTargetInfo::GCCRegNames[] = { + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", + "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", + "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", + "v32", "v33", "v34", "v35", "v36", "v37", "v38", "v39", + "v40", "v41", "v42", "v43", "v44", "v45", "v46", "v47", + "v48", "v49", "v50", "v51", "v52", "v53", "v54", "v55", + "v56", "v57", "v58", "v59", "v60", "v61", "v62", "v63", + "v64", "v65", "v66", "v67", "v68", "v69", "v70", "v71", + "v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79", + "v80", "v81", "v82", "v83", "v84", "v85", "v86", "v87", + "v88", "v89", "v90", "v91", "v92", "v93", "v94", "v95", + "v96", "v97", "v98", "v99", "v100", "v101", "v102", "v103", + "v104", "v105", "v106", "v107", "v108", "v109", "v110", "v111", + "v112", "v113", "v114", "v115", "v116", "v117", "v118", "v119", + "v120", "v121", "v122", "v123", "v124", "v125", "v126", "v127", + "v128", "v129", "v130", "v131", "v132", "v133", "v134", "v135", + "v136", "v137", "v138", "v139", "v140", "v141", "v142", "v143", + "v144", "v145", "v146", "v147", "v148", "v149", "v150", "v151", + "v152", "v153", "v154", "v155", "v156", "v157", "v158", "v159", + "v160", "v161", "v162", "v163", "v164", "v165", "v166", "v167", + "v168", "v169", "v170", "v171", "v172", "v173", "v174", "v175", + "v176", "v177", "v178", "v179", "v180", "v181", "v182", "v183", + "v184", "v185", "v186", "v187", "v188", "v189", "v190", "v191", + "v192", "v193", "v194", "v195", "v196", "v197", "v198", "v199", + "v200", "v201", "v202", "v203", "v204", "v205", "v206", "v207", + "v208", "v209", "v210", "v211", "v212", "v213", "v214", "v215", + "v216", "v217", "v218", "v219", "v220", "v221", "v222", "v223", + "v224", "v225", "v226", "v227", "v228", "v229", "v230", "v231", + "v232", "v233", "v234", "v235", "v236", "v237", "v238", "v239", + "v240", "v241", "v242", "v243", "v244", "v245", "v246", "v247", + "v248", "v249", "v250", "v251", "v252", "v253", "v254", "v255", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", + "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", + "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", + "s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39", + "s40", "s41", "s42", "s43", "s44", "s45", "s46", "s47", + "s48", "s49", "s50", "s51", "s52", "s53", "s54", "s55", + "s56", "s57", "s58", "s59", "s60", "s61", "s62", "s63", + "s64", "s65", "s66", "s67", "s68", "s69", "s70", "s71", + "s72", "s73", "s74", "s75", "s76", "s77", "s78", "s79", + "s80", "s81", "s82", "s83", "s84", "s85", "s86", "s87", + "s88", "s89", "s90", "s91", "s92", "s93", "s94", "s95", + "s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103", + "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_scr", "exec_lo", "exec_hi", + "vcc_lo", "vcc_hi", "flat_scr_lo", "flat_scr_hi" }; -} // end anonymous namespace +void AMDGPUTargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); +} -namespace { // Namespace for x86 abstract base class const Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, @@ -1986,6 +2265,7 @@ public: Names = AddlRegNames; NumNames = llvm::array_lengthof(AddlRegNames); } + bool validateCpuSupports(StringRef Name) const override; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override; @@ -2020,7 +2300,9 @@ public: bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; StringRef getABI() const override { - if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX) + if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX512F) + return "avx512"; + else if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX) return "avx"; else if (getTriple().getArch() == llvm::Triple::x86 && MMX3DNowLevel == NoMMX3DNow) @@ -2496,12 +2778,11 @@ void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level, void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, StringRef Name, bool Enabled) { - // FIXME: This *really* should not be here. We need some way of translating - // options into llvm subtarget features. - if (Name == "sse4") - Name = "sse4.2"; - - Features[Name] = Enabled; + // This is a bit of a hack to deal with the sse4 target feature when used + // as part of the target attribute. We handle sse4 correctly everywhere + // else. See below for more information on how we handle the sse4 options. + if (Name != "sse4") + Features[Name] = Enabled; if (Name == "mmx") { setMMXLevel(Features, MMX, Enabled); @@ -2552,6 +2833,15 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, } else if (Name == "sha") { if (Enabled) setSSELevel(Features, SSE2, Enabled); + } else if (Name == "sse4") { + // We can get here via the __target__ attribute since that's not controlled + // via the -msse4/-mno-sse4 command line alias. Handle this the same way + // here - turn on the sse4.2 if enabled, turn off the sse4.1 level if + // disabled. + if (Enabled) + setSSELevel(Features, SSE42, Enabled); + else + setSSELevel(Features, SSE41, Enabled); } } @@ -2748,6 +3038,9 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, Features.erase(it); else if (SSELevel > NoSSE) MMX3DNowLevel = std::max(MMX3DNowLevel, MMX); + + SimdDefaultAlign = + (getABI() == "avx512") ? 512 : (getABI() == "avx") ? 256 : 128; return true; } @@ -3112,6 +3405,33 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Default(false); } +// We can't use a generic validation scheme for the features accepted here +// versus subtarget features accepted in the target attribute because the +// bitfield structure that's initialized in the runtime only supports the +// below currently rather than the full range of subtarget features. (See +// X86TargetInfo::hasFeature for a somewhat comprehensive list). +bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { + return llvm::StringSwitch<bool>(FeatureStr) + .Case("cmov", true) + .Case("mmx", true) + .Case("popcnt", true) + .Case("sse", true) + .Case("sse2", true) + .Case("sse3", true) + .Case("sse4.1", true) + .Case("sse4.2", true) + .Case("avx", true) + .Case("avx2", true) + .Case("sse4a", true) + .Case("fma4", true) + .Case("xop", true) + .Case("fma", true) + .Case("avx512f", true) + .Case("bmi", true) + .Case("bmi2", true) + .Default(false); +} + bool X86TargetInfo::validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const { @@ -3236,9 +3556,7 @@ X86TargetInfo::convertConstraint(const char *&Constraint) const { return std::string(1, *Constraint); } } -} // end anonymous namespace -namespace { // X86-32 generic target class X86_32TargetInfo : public X86TargetInfo { public: @@ -3293,9 +3611,7 @@ public: return X86TargetInfo::validateOperandSize(Constraint, Size); } }; -} // end anonymous namespace -namespace { class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> { public: NetBSDI386TargetInfo(const llvm::Triple &Triple) @@ -3311,9 +3627,7 @@ public: return 1; } }; -} // end anonymous namespace -namespace { class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { public: OpenBSDI386TargetInfo(const llvm::Triple &Triple) @@ -3323,9 +3637,7 @@ public: PtrDiffType = SignedLong; } }; -} // end anonymous namespace -namespace { class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> { public: BitrigI386TargetInfo(const llvm::Triple &Triple) @@ -3335,9 +3647,7 @@ public: PtrDiffType = SignedLong; } }; -} // end anonymous namespace -namespace { class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { public: DarwinI386TargetInfo(const llvm::Triple &Triple) @@ -3353,9 +3663,7 @@ public: } }; -} // end anonymous namespace -namespace { // x86-32 Windows target class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> { public: @@ -3365,8 +3673,9 @@ public: DoubleAlign = LongLongAlign = 64; bool IsWinCOFF = getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); - DescriptionString = IsWinCOFF ? "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32" - : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-S32"; + DescriptionString = IsWinCOFF + ? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" + : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -3394,11 +3703,8 @@ public: }; } // end anonymous namespace -static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) { - Builder.defineMacro("__MSVCRT__"); - Builder.defineMacro("__MINGW32__"); - - // Mingw defines __declspec(a) to __attribute__((a)). Clang supports +static void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) { + // Mingw and cygwin define __declspec(a) to __attribute__((a)). Clang supports // __declspec natively under -fms-extensions, but we define a no-op __declspec // macro anyway for pre-processor compatibility. if (Opts.MicrosoftExt) @@ -3421,6 +3727,12 @@ static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) { } } +static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) { + Builder.defineMacro("__MSVCRT__"); + Builder.defineMacro("__MINGW32__"); + addCygMingDefines(Opts, Builder); +} + namespace { // x86-32 MinGW target class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo { @@ -3436,9 +3748,7 @@ public: addMinGWDefines(Opts, Builder); } }; -} // end anonymous namespace -namespace { // x86-32 Cygwin target class CygwinX86_32TargetInfo : public X86_32TargetInfo { public: @@ -3447,7 +3757,7 @@ public: TLSSupported = false; WCharType = UnsignedShort; DoubleAlign = LongLongAlign = 64; - DescriptionString = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"; + DescriptionString = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -3455,14 +3765,13 @@ public: Builder.defineMacro("_X86_"); Builder.defineMacro("__CYGWIN__"); Builder.defineMacro("__CYGWIN32__"); + addCygMingDefines(Opts, Builder); DefineStd(Builder, "unix", Opts); if (Opts.CPlusPlus) Builder.defineMacro("_GNU_SOURCE"); } }; -} // end anonymous namespace -namespace { // x86-32 Haiku target class HaikuX86_32TargetInfo : public X86_32TargetInfo { public: @@ -3481,7 +3790,6 @@ public: Builder.defineMacro("__HAIKU__"); } }; -} // end anonymous namespace // RTEMS Target template<typename Target> @@ -3518,7 +3826,6 @@ public: } }; -namespace { // x86-32 RTEMS target class RTEMSX86_32TargetInfo : public X86_32TargetInfo { public: @@ -3535,14 +3842,14 @@ public: Builder.defineMacro("__rtems__"); } }; -} // end anonymous namespace -namespace { // x86-64 generic target class X86_64TargetInfo : public X86TargetInfo { public: X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) { const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32; + bool IsWinCOFF = + getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64; LongDoubleWidth = 128; LongDoubleAlign = 128; @@ -3557,9 +3864,10 @@ public: RegParmMax = 6; // Pointers are 32-bit in x32. - DescriptionString = (IsX32) - ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128" - : "e-m:e-i64:64-f80:128-n8:16:32:64-S128"; + DescriptionString = IsX32 ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128" + : IsWinCOFF + ? "e-m:w-i64:64-f80:128-n8:16:32:64-S128" + : "e-m:e-i64:64-f80:128-n8:16:32:64-S128"; // Use fpret only for long double. RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); @@ -3595,9 +3903,7 @@ public: // for x32 we need it here explicitly bool hasInt128Type() const override { return true; } }; -} // end anonymous namespace -namespace { // x86-64 Windows target class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> { public: @@ -3613,24 +3919,34 @@ public: IntPtrType = SignedLongLong; this->UserLabelPrefix = ""; } + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder); Builder.defineMacro("_WIN64"); } + BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { - return (CC == CC_C || - CC == CC_X86VectorCall || - CC == CC_IntelOclBicc || - CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning; + switch (CC) { + case CC_X86StdCall: + case CC_X86ThisCall: + case CC_X86FastCall: + return CCCR_Ignore; + case CC_C: + case CC_X86VectorCall: + case CC_IntelOclBicc: + case CC_X86_64SysV: + return CCCR_OK; + default: + return CCCR_Warning; + } } }; -} // end anonymous namespace -namespace { // x86-64 Windows Visual Studio target class MicrosoftX86_64TargetInfo : public WindowsX86_64TargetInfo { public: @@ -3647,9 +3963,7 @@ public: Builder.defineMacro("_M_AMD64"); } }; -} // end anonymous namespace -namespace { // x86-64 MinGW target class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo { public: @@ -3667,9 +3981,7 @@ public: Builder.defineMacro("__SEH__"); } }; -} // end anonymous namespace -namespace { class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { public: DarwinX86_64TargetInfo(const llvm::Triple &Triple) @@ -3683,9 +3995,7 @@ public: DescriptionString = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"; } }; -} // end anonymous namespace -namespace { class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> { public: OpenBSDX86_64TargetInfo(const llvm::Triple &Triple) @@ -3694,9 +4004,7 @@ public: Int64Type = SignedLongLong; } }; -} // end anonymous namespace -namespace { class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> { public: BitrigX86_64TargetInfo(const llvm::Triple &Triple) @@ -3705,10 +4013,7 @@ public: Int64Type = SignedLongLong; } }; -} - -namespace { class ARMTargetInfo : public TargetInfo { // Possible FPU choices. enum FPUMode { @@ -3800,8 +4105,9 @@ class ARMTargetInfo : public TargetInfo { DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; const llvm::Triple &T = getTriple(); - // size_t is unsigned long on MachO-derived environments and NetBSD. - if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD) + // size_t is unsigned long on MachO-derived environments, NetBSD and Bitrig. + if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD || + T.getOS() == llvm::Triple::Bitrig) SizeType = UnsignedLong; else SizeType = UnsignedInt; @@ -3831,16 +4137,18 @@ class ARMTargetInfo : public TargetInfo { BigEndian ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"; } else if (T.isOSWindows()) { - // FIXME: this is invalid for WindowsCE assert(!BigEndian && "Windows on ARM does not support big endian"); DescriptionString = "e" - "-m:e" + "-m:w" "-p:32:32" "-i64:64" "-v128:64:128" "-a:0:32" "-n32" "-S64"; + } else if (T.isOSNaCl()) { + assert(!BigEndian && "NaCl on ARM does not support big endian"); + DescriptionString = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128"; } else { DescriptionString = BigEndian ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" @@ -3965,7 +4273,9 @@ public: // zero length bitfield. UseZeroLengthBitfieldAlignment = true; } + StringRef getABI() const override { return ABI; } + bool setABI(const std::string &Name) override { ABI = Name; @@ -3984,8 +4294,13 @@ public: return false; } + // FIXME: This should be based on Arch attributes, not CPU names. void getDefaultFeatures(llvm::StringMap<bool> &Features) const override { StringRef ArchName = getTriple().getArchName(); + unsigned ArchKind = llvm::ARMTargetParser::parseArch(ArchName); + bool IsV8 = (ArchKind == llvm::ARM::AK_ARMV8A || + ArchKind == llvm::ARM::AK_ARMV8_1A); + if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore") Features["vfp2"] = true; else if (CPU == "cortex-a8" || CPU == "cortex-a9") { @@ -4002,28 +4317,19 @@ public: Features["neon"] = true; Features["hwdiv"] = true; Features["hwdiv-arm"] = true; - } else if (CPU == "cyclone") { - Features["v8fp"] = true; - Features["neon"] = true; - Features["hwdiv"] = true; - Features["hwdiv-arm"] = true; - } else if (CPU == "cortex-a53" || CPU == "cortex-a57") { + } else if (CPU == "cyclone" || CPU == "cortex-a53" || CPU == "cortex-a57" || + CPU == "cortex-a72") { Features["fp-armv8"] = true; Features["neon"] = true; Features["hwdiv"] = true; Features["hwdiv-arm"] = true; Features["crc"] = true; Features["crypto"] = true; - } else if (CPU == "cortex-r5" || - // Enable the hwdiv extension for all v8a AArch32 cores by - // default. - ArchName == "armv8a" || ArchName == "armv8" || - ArchName == "armebv8a" || ArchName == "armebv8" || - ArchName == "thumbv8a" || ArchName == "thumbv8" || - ArchName == "thumbebv8a" || ArchName == "thumbebv8") { + } else if (CPU == "cortex-r5" || CPU == "cortex-r7" || IsV8) { Features["hwdiv"] = true; Features["hwdiv-arm"] = true; - } else if (CPU == "cortex-m3" || CPU == "cortex-m4" || CPU == "cortex-m7") { + } else if (CPU == "cortex-m3" || CPU == "cortex-m4" || CPU == "cortex-m7" || + CPU == "sc300" || CPU == "cortex-r4" || CPU == "cortex-r4f") { Features["hwdiv"] = true; } } @@ -4036,6 +4342,9 @@ public: SoftFloat = SoftFloatABI = false; HWDiv = 0; + // This does not diagnose illegal cases like having both + // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp". + uint32_t HW_FP_remove = 0; for (const auto &Feature : Features) { if (Feature == "+soft-float") { SoftFloat = true; @@ -4043,19 +4352,19 @@ public: SoftFloatABI = true; } else if (Feature == "+vfp2") { FPU |= VFP2FPU; - HW_FP = HW_FP_SP | HW_FP_DP; + HW_FP |= HW_FP_SP | HW_FP_DP; } else if (Feature == "+vfp3") { FPU |= VFP3FPU; - HW_FP = HW_FP_SP | HW_FP_DP; + HW_FP |= HW_FP_SP | HW_FP_DP; } else if (Feature == "+vfp4") { FPU |= VFP4FPU; - HW_FP = HW_FP_SP | HW_FP_DP | HW_FP_HP; + HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP; } else if (Feature == "+fp-armv8") { FPU |= FPARMV8; - HW_FP = HW_FP_SP | HW_FP_DP | HW_FP_HP; + HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP; } else if (Feature == "+neon") { FPU |= NeonFPU; - HW_FP = HW_FP_SP | HW_FP_DP; + HW_FP |= HW_FP_SP | HW_FP_DP; } else if (Feature == "+hwdiv") { HWDiv |= HWDivThumb; } else if (Feature == "+hwdiv-arm") { @@ -4065,9 +4374,10 @@ public: } else if (Feature == "+crypto") { Crypto = 1; } else if (Feature == "+fp-only-sp") { - HW_FP &= ~HW_FP_DP; + HW_FP_remove |= HW_FP_DP | HW_FP_HP; } } + HW_FP &= ~HW_FP_remove; if (!(FPU & NeonFPU) && FPMath == FP_Neon) { Diags.Report(diag::err_target_unsupported_fpmath) << "neon"; @@ -4080,12 +4390,10 @@ public: Features.push_back("-neonfp"); // Remove front-end specific options which the backend handles differently. - const StringRef FrontEndFeatures[] = { "+soft-float", "+soft-float-abi" }; - for (const auto &FEFeature : FrontEndFeatures) { - auto Feature = std::find(Features.begin(), Features.end(), FEFeature); - if (Feature != Features.end()) - Features.erase(Feature); - } + auto Feature = + std::find(Features.begin(), Features.end(), "+soft-float-abi"); + if (Feature != Features.end()) + Features.erase(Feature); return true; } @@ -4100,45 +4408,71 @@ public: .Case("hwdiv-arm", HWDiv & HWDivARM) .Default(false); } - // FIXME: Should we actually have some table instead of these switches? - static const char *getCPUDefineSuffix(StringRef Name) { - return llvm::StringSwitch<const char *>(Name) - .Cases("arm8", "arm810", "4") - .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", - "4") - .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "arm720t", "arm9", "4T") - .Cases("arm9tdmi", "arm920", "arm920t", "arm922t", "arm940t", "4T") - .Case("ep9312", "4T") - .Cases("arm10tdmi", "arm1020t", "5T") - .Cases("arm9e", "arm946e-s", "arm966e-s", "arm968e-s", "5TE") - .Case("arm926ej-s", "5TEJ") - .Cases("arm10e", "arm1020e", "arm1022e", "5TE") - .Cases("xscale", "iwmmxt", "5TE") - .Case("arm1136j-s", "6J") - .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK") - .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K") - .Cases("arm1156t2-s", "arm1156t2f-s", "6T2") - .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A") - .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait", - "7A") - .Cases("cortex-r4", "cortex-r5", "7R") - .Case("swift", "7S") - .Case("cyclone", "8A") - .Case("cortex-m3", "7M") - .Cases("cortex-m4", "cortex-m7", "7EM") - .Case("cortex-m0", "6M") - .Cases("cortex-a53", "cortex-a57", "8A") - .Default(nullptr); - } - static const char *getCPUProfile(StringRef Name) { - return llvm::StringSwitch<const char *>(Name) - .Cases("cortex-a5", "cortex-a7", "cortex-a8", "A") - .Cases("cortex-a9", "cortex-a12", "cortex-a15", "cortex-a17", "krait", - "A") - .Cases("cortex-a53", "cortex-a57", "A") - .Cases("cortex-m3", "cortex-m4", "cortex-m0", "cortex-m7", "M") - .Cases("cortex-r4", "cortex-r5", "R") - .Default(""); + const char *getCPUDefineSuffix(StringRef Name) const { + if(Name == "generic") { + auto subarch = getTriple().getSubArch(); + switch (subarch) { + case llvm::Triple::SubArchType::ARMSubArch_v8_1a: + return "8_1A"; + default: + break; + } + } + + unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(Name); + if (ArchKind == llvm::ARM::AK_INVALID) + return ""; + + // For most sub-arches, the build attribute CPU name is enough. + // For Cortex variants, it's slightly different. + switch(ArchKind) { + default: + return llvm::ARMTargetParser::getCPUAttr(ArchKind); + case llvm::ARM::AK_ARMV6M: + case llvm::ARM::AK_ARMV6SM: + return "6M"; + case llvm::ARM::AK_ARMV7: + case llvm::ARM::AK_ARMV7A: + case llvm::ARM::AK_ARMV7S: + return "7A"; + case llvm::ARM::AK_ARMV7R: + return "7R"; + case llvm::ARM::AK_ARMV7M: + return "7M"; + case llvm::ARM::AK_ARMV7EM: + return "7EM"; + case llvm::ARM::AK_ARMV8A: + return "8A"; + case llvm::ARM::AK_ARMV8_1A: + return "8_1A"; + } + } + const char *getCPUProfile(StringRef Name) const { + if(Name == "generic") { + auto subarch = getTriple().getSubArch(); + switch (subarch) { + case llvm::Triple::SubArchType::ARMSubArch_v8_1a: + return "A"; + default: + break; + } + } + + unsigned CPUArch = llvm::ARMTargetParser::parseCPUArch(Name); + if (CPUArch == llvm::ARM::AK_INVALID) + return ""; + + StringRef ArchName = llvm::ARMTargetParser::getArchName(CPUArch); + switch(llvm::ARMTargetParser::parseArchProfile(ArchName)) { + case llvm::ARM::PK_A: + return "A"; + case llvm::ARM::PK_R: + return "R"; + case llvm::ARM::PK_M: + return "M"; + default: + return ""; + } } bool setCPU(const std::string &Name) override { if (!getCPUDefineSuffix(Name)) @@ -4165,6 +4499,7 @@ public: // We check both CPUArchVer and ArchName because when only triple is // specified, the default CPU is arm1136j-s. return ArchName.endswith("v6t2") || ArchName.endswith("v7") || + ArchName.endswith("v8.1a") || ArchName.endswith("v8") || CPUArch == "6T2" || CPUArchVer >= 7; } void getTargetDefines(const LangOptions &Opts, @@ -4499,8 +4834,8 @@ class ARMleTargetInfo : public ARMTargetInfo { public: ARMleTargetInfo(const llvm::Triple &Triple) : ARMTargetInfo(Triple, false) { } - virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { Builder.defineMacro("__ARMEL__"); ARMTargetInfo::getTargetDefines(Opts, Builder); } @@ -4510,16 +4845,14 @@ class ARMbeTargetInfo : public ARMTargetInfo { public: ARMbeTargetInfo(const llvm::Triple &Triple) : ARMTargetInfo(Triple, true) { } - virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const { + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { Builder.defineMacro("__ARMEB__"); Builder.defineMacro("__ARM_BIG_ENDIAN"); ARMTargetInfo::getTargetDefines(Opts, Builder); } }; -} // end anonymous namespace. -namespace { class WindowsARMTargetInfo : public WindowsTargetInfo<ARMleTargetInfo> { const llvm::Triple Triple; public: @@ -4585,10 +4918,7 @@ public: WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); } }; -} - -namespace { class DarwinARMTargetInfo : public DarwinTargetInfo<ARMleTargetInfo> { protected: @@ -4610,10 +4940,7 @@ public: TheCXXABI.set(TargetCXXABI::iOS); } }; -} // end anonymous namespace. - -namespace { class AArch64TargetInfo : public TargetInfo { virtual void setDescriptionString() = 0; static const TargetInfo::GCCRegAlias GCCRegAliases[]; @@ -4655,13 +4982,20 @@ public: MaxAtomicInlineWidth = 128; MaxAtomicPromoteWidth = 128; - LongDoubleWidth = LongDoubleAlign = 128; + LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad; // {} in inline assembly are neon specifiers, not assembly variant // specifiers. NoAsmVariants = true; + // AAPCS gives rules for bitfields. 7.1.7 says: "The container type + // contributes to the alignment of the containing aggregate in the same way + // a plain (non bit-field) member of that type would, without exception for + // zero-sized or anonymous bit-fields." + UseBitFieldTypeAlignment = true; + UseZeroLengthBitfieldAlignment = true; + // AArch64 targets default to using the ARM C++ ABI. TheCXXABI.set(TargetCXXABI::GenericAArch64); } @@ -4678,14 +5012,14 @@ public: bool setCPU(const std::string &Name) override { bool CPUKnown = llvm::StringSwitch<bool>(Name) .Case("generic", true) - .Cases("cortex-a53", "cortex-a57", true) + .Cases("cortex-a53", "cortex-a57", "cortex-a72", true) .Case("cyclone", true) .Default(false); return CPUKnown; } - virtual void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const override { + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { // Target identification. Builder.defineMacro("__aarch64__"); @@ -4742,10 +5076,16 @@ public: if (Crypto) Builder.defineMacro("__ARM_FEATURE_CRYPTO"); + + // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } - virtual void getTargetBuiltins(const Builtin::Info *&Records, - unsigned &NumRecords) const override { + void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const override { Records = BuiltinInfo; NumRecords = clang::AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin; } @@ -4781,14 +5121,13 @@ public: return TargetInfo::AArch64ABIBuiltinVaList; } - virtual void getGCCRegNames(const char *const *&Names, - unsigned &NumNames) const override; - virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, - unsigned &NumAliases) const override; + void getGCCRegNames(const char *const *&Names, + unsigned &NumNames) const override; + void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const override; - virtual bool - validateAsmConstraint(const char *&Name, - TargetInfo::ConstraintInfo &Info) const override { + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override { switch (*Name) { default: return false; @@ -4963,9 +5302,7 @@ public: AArch64TargetInfo::getTargetDefines(Opts, Builder); } }; -} // end anonymous namespace. -namespace { class DarwinAArch64TargetInfo : public DarwinTargetInfo<AArch64leTargetInfo> { protected: void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, @@ -4988,7 +5325,7 @@ public: WCharType = SignedInt; UseSignedCharForObjCBool = false; - LongDoubleWidth = LongDoubleAlign = 64; + LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble; TheCXXABI.set(TargetCXXABI::iOS64); @@ -4998,9 +5335,7 @@ public: return TargetInfo::CharPtrBuiltinVaList; } }; -} // end anonymous namespace -namespace { // Hexagon abstract base class class HexagonTargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; @@ -5149,24 +5484,25 @@ const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { ALL_LANGUAGES }, #include "clang/Basic/BuiltinsHexagon.def" }; -} - -namespace { // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit). class SparcTargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; static const char * const GCCRegNames[]; bool SoftFloat; public: - SparcTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {} + SparcTargetInfo(const llvm::Triple &Triple) + : TargetInfo(Triple), SoftFloat(false) {} bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override { - SoftFloat = false; - for (unsigned i = 0, e = Features.size(); i != e; ++i) - if (Features[i] == "+soft-float") - SoftFloat = true; + // The backend doesn't actually handle soft float yet, but in case someone + // is using the support for the front end continue to support it. + auto Feature = std::find(Features.begin(), Features.end(), "+soft-float"); + if (Feature != Features.end()) { + SoftFloat = true; + Features.erase(Feature); + } return true; } void getTargetDefines(const LangOptions &Opts, @@ -5276,6 +5612,16 @@ class SparcV8TargetInfo : public SparcTargetInfo { public: SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) { DescriptionString = "E-m:e-p:32:32-i64:64-f128:64-n32-S64"; + // NetBSD uses long (same as llvm default); everyone else uses int. + if (getTriple().getOS() == llvm::Triple::NetBSD) { + SizeType = UnsignedLong; + IntPtrType = SignedLong; + PtrDiffType = SignedLong; + } else { + SizeType = UnsignedInt; + IntPtrType = SignedInt; + PtrDiffType = SignedInt; + } } void getTargetDefines(const LangOptions &Opts, @@ -5285,6 +5631,15 @@ public: } }; +// SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel. +class SparcV8elTargetInfo : public SparcV8TargetInfo { + public: + SparcV8elTargetInfo(const llvm::Triple &Triple) : SparcV8TargetInfo(Triple) { + DescriptionString = "e-m:e-p:32:32-i64:64-f128:64-n32-S64"; + BigEndian = false; + } +}; + // SPARC v9 is the 64-bit mode selected by Triple::sparcv9. class SparcV9TargetInfo : public SparcTargetInfo { public: @@ -5339,25 +5694,18 @@ public: } }; -} // end anonymous namespace. - -namespace { -class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> { -public: - SolarisSparcV8TargetInfo(const llvm::Triple &Triple) - : SolarisTargetInfo<SparcV8TargetInfo>(Triple) { - SizeType = UnsignedInt; - PtrDiffType = SignedInt; - } -}; -} // end anonymous namespace. - -namespace { class SystemZTargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; + std::string CPU; + bool HasTransactionalExecution; + bool HasVector; public: - SystemZTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + SystemZTargetInfo(const llvm::Triple &Triple) + : TargetInfo(Triple), CPU("z10"), HasTransactionalExecution(false), HasVector(false) { + IntMaxType = SignedLong; + Int64Type = SignedLong; TLSSupported = true; IntWidth = IntAlign = 32; LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; @@ -5365,6 +5713,7 @@ public: LongDoubleWidth = 128; LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEquad; + DefaultAlignForAttributeAligned = 64; MinGlobalAlign = 16; DescriptionString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; @@ -5375,12 +5724,13 @@ public: Builder.defineMacro("__s390x__"); Builder.defineMacro("__zarch__"); Builder.defineMacro("__LONG_DOUBLE_128__"); + if (HasTransactionalExecution) + Builder.defineMacro("__HTM__"); } void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const override { - // FIXME: Implement. - Records = nullptr; - NumRecords = 0; + Records = BuiltinInfo; + NumRecords = clang::SystemZ::LastTSBuiltin-Builtin::FirstTSBuiltin; } void getGCCRegNames(const char *const *&Names, @@ -5401,16 +5751,66 @@ public: return TargetInfo::SystemZBuiltinVaList; } bool setCPU(const std::string &Name) override { + CPU = Name; bool CPUKnown = llvm::StringSwitch<bool>(Name) .Case("z10", true) .Case("z196", true) .Case("zEC12", true) + .Case("z13", true) .Default(false); - // No need to store the CPU yet. There aren't any CPU-specific - // macros to define. return CPUKnown; } + void getDefaultFeatures(llvm::StringMap<bool> &Features) const override { + if (CPU == "zEC12") + Features["transactional-execution"] = true; + if (CPU == "z13") { + Features["transactional-execution"] = true; + Features["vector"] = true; + } + } + + bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) override { + HasTransactionalExecution = false; + for (unsigned i = 0, e = Features.size(); i != e; ++i) { + if (Features[i] == "+transactional-execution") + HasTransactionalExecution = true; + if (Features[i] == "+vector") + HasVector = true; + } + // If we use the vector ABI, vector types are 64-bit aligned. + if (HasVector) { + MaxVectorAlign = 64; + DescriptionString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" + "-v128:64-a:8:16-n32:64"; + } + return true; + } + + bool hasFeature(StringRef Feature) const override { + return llvm::StringSwitch<bool>(Feature) + .Case("systemz", true) + .Case("htm", HasTransactionalExecution) + .Case("vx", HasVector) + .Default(false); + } + + StringRef getABI() const override { + if (HasVector) + return "vector"; + return ""; + } + + bool useFloat128ManglingForLongDouble() const override { + return true; + } +}; + +const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, +#include "clang/Basic/BuiltinsSystemZ.def" }; const char *const SystemZTargetInfo::GCCRegNames[] = { @@ -5454,9 +5854,7 @@ validateAsmConstraint(const char *&Name, return true; } } -} -namespace { class MSP430TargetInfo : public TargetInfo { static const char * const GCCRegNames[]; public: @@ -5531,9 +5929,6 @@ namespace { Names = GCCRegNames; NumNames = llvm::array_lengthof(GCCRegNames); } -} - -namespace { // LLVM and Clang cannot be used directly to output native binaries for // target, but is used to compile C code to llvm bitcode with correct @@ -5611,9 +6006,61 @@ namespace { void getGCCRegAliases(const GCCRegAlias *&Aliases, unsigned &NumAliases) const override {} }; -} -namespace { +class BPFTargetInfo : public TargetInfo { +public: + BPFTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + LongWidth = LongAlign = PointerWidth = PointerAlign = 64; + SizeType = UnsignedLong; + PtrDiffType = SignedLong; + IntPtrType = SignedLong; + IntMaxType = SignedLong; + Int64Type = SignedLong; + RegParmMax = 5; + if (Triple.getArch() == llvm::Triple::bpfeb) { + BigEndian = true; + DescriptionString = "E-m:e-p:64:64-i64:64-n32:64-S128"; + } else { + BigEndian = false; + DescriptionString = "e-m:e-p:64:64-i64:64-n32:64-S128"; + } + MaxAtomicPromoteWidth = 64; + MaxAtomicInlineWidth = 64; + TLSSupported = false; + } + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { + DefineStd(Builder, "bpf", Opts); + Builder.defineMacro("__BPF__"); + } + bool hasFeature(StringRef Feature) const override { + return Feature == "bpf"; + } + + void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const override {} + const char *getClobbers() const override { + return ""; + } + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const override { + Names = nullptr; + NumNames = 0; + } + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const override { + return true; + } + void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const override { + Aliases = nullptr; + NumAliases = 0; + } +}; + class MipsTargetInfoBase : public TargetInfo { virtual void setDescriptionString() = 0; @@ -5652,6 +6099,10 @@ public: return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64"; } + bool isNan2008() const override { + return IsNan2008; + } + StringRef getABI() const override { return ABI; } bool setCPU(const std::string &Name) override { bool IsMips32 = getTriple().getArch() == llvm::Triple::mips || @@ -5665,23 +6116,19 @@ public: .Case("mips5", true) .Case("mips32", IsMips32) .Case("mips32r2", IsMips32) + .Case("mips32r3", IsMips32) + .Case("mips32r5", IsMips32) .Case("mips32r6", IsMips32) .Case("mips64", true) .Case("mips64r2", true) + .Case("mips64r3", true) + .Case("mips64r5", true) .Case("mips64r6", true) .Case("octeon", true) .Default(false); } const std::string& getCPU() const { return CPU; } void getDefaultFeatures(llvm::StringMap<bool> &Features) const override { - // The backend enables certain ABI's by default according to the - // architecture. - // Disable both possible defaults so that we don't end up with multiple - // ABI's selected and trigger an assertion. - Features["o32"] = false; - Features["n64"] = false; - - Features[ABI] = true; if (CPU == "octeon") Features["mips64r2"] = Features["cnmips"] = true; else @@ -5818,7 +6265,28 @@ public: case 'R': // An address that can be used in a non-macro load or store Info.setAllowsMemory(); return true; + case 'Z': + if (Name[1] == 'C') { // An address usable by ll, and sc. + Info.setAllowsMemory(); + Name++; // Skip over 'Z'. + return true; + } + return false; + } + } + + std::string convertConstraint(const char *&Constraint) const override { + std::string R; + switch (*Constraint) { + case 'Z': // Two-character constraint; add "^" hint for later parsing. + if (Constraint[1] == 'C') { + R = std::string("^") + std::string(Constraint, 2); + Constraint++; + return R; + } + break; } + return TargetInfo::convertConstraint(Constraint); } const char *getClobbers() const override { @@ -5882,12 +6350,6 @@ public: IsNan2008 = false; } - // Remove front-end specific options. - std::vector<std::string>::iterator it = - std::find(Features.begin(), Features.end(), "+soft-float"); - if (it != Features.end()) - Features.erase(it); - setDescriptionString(); return true; @@ -5938,6 +6400,10 @@ public: Builder.defineMacro("__mips_isa_rev", "1"); else if (CPUStr == "mips32r2") Builder.defineMacro("__mips_isa_rev", "2"); + else if (CPUStr == "mips32r3") + Builder.defineMacro("__mips_isa_rev", "3"); + else if (CPUStr == "mips32r5") + Builder.defineMacro("__mips_isa_rev", "5"); else if (CPUStr == "mips32r6") Builder.defineMacro("__mips_isa_rev", "6"); @@ -6087,6 +6553,10 @@ public: Builder.defineMacro("__mips_isa_rev", "1"); else if (CPUStr == "mips64r2") Builder.defineMacro("__mips_isa_rev", "2"); + else if (CPUStr == "mips64r3") + Builder.defineMacro("__mips_isa_rev", "3"); + else if (CPUStr == "mips64r5") + Builder.defineMacro("__mips_isa_rev", "5"); else if (CPUStr == "mips64r6") Builder.defineMacro("__mips_isa_rev", "6"); @@ -6185,9 +6655,7 @@ public: Mips64TargetInfoBase::getTargetDefines(Opts, Builder); } }; -} // end anonymous namespace. -namespace { class PNaClTargetInfo : public TargetInfo { public: PNaClTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { @@ -6252,9 +6720,20 @@ void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, Aliases = nullptr; NumAliases = 0; } -} // end anonymous namespace. -namespace { +// We attempt to use PNaCl (le32) frontend and Mips32EL backend. +class NaClMips32ELTargetInfo : public Mips32ELTargetInfo { +public: + NaClMips32ELTargetInfo(const llvm::Triple &Triple) : + Mips32ELTargetInfo(Triple) { + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; + } + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::PNaClABIBuiltinVaList; + } +}; + class Le64TargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; @@ -6359,6 +6838,15 @@ namespace { BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; } + + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + return (CC == CC_SpirFunction || + CC == CC_SpirKernel) ? CCCR_OK : CCCR_Warning; + } + + CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { + return CC_SpirFunction; + } }; @@ -6392,9 +6880,7 @@ namespace { DefineStd(Builder, "SPIR64", Opts); } }; -} -namespace { class XCoreTargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; public: @@ -6460,6 +6946,30 @@ const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = { }; } // end anonymous namespace. +namespace { +// x86_32 Android target +class AndroidX86_32TargetInfo : public LinuxTargetInfo<X86_32TargetInfo> { +public: + AndroidX86_32TargetInfo(const llvm::Triple &Triple) + : LinuxTargetInfo<X86_32TargetInfo>(Triple) { + SuitableAlign = 32; + LongDoubleWidth = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble; + } +}; +} // end anonymous namespace + +namespace { +// x86_64 Android target +class AndroidX86_64TargetInfo : public LinuxTargetInfo<X86_64TargetInfo> { +public: + AndroidX86_64TargetInfo(const llvm::Triple &Triple) + : LinuxTargetInfo<X86_64TargetInfo>(Triple) { + LongDoubleFormat = &llvm::APFloat::IEEEquad; + } +}; +} // end anonymous namespace + //===----------------------------------------------------------------------===// // Driver code @@ -6562,6 +7072,10 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { return new ARMbeTargetInfo(Triple); } + case llvm::Triple::bpfeb: + case llvm::Triple::bpfel: + return new BPFTargetInfo(Triple); + case llvm::Triple::msp430: return new MSP430TargetInfo(Triple); @@ -6590,7 +7104,7 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { case llvm::Triple::NetBSD: return new NetBSDTargetInfo<Mips32ELTargetInfo>(Triple); case llvm::Triple::NaCl: - return new NaClTargetInfo<Mips32ELTargetInfo>(Triple); + return new NaClTargetInfo<NaClMips32ELTargetInfo>(Triple); default: return new Mips32ELTargetInfo(Triple); } @@ -6629,10 +7143,10 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { case llvm::Triple::le32: switch (os) { - case llvm::Triple::NaCl: - return new NaClTargetInfo<PNaClTargetInfo>(Triple); - default: - return nullptr; + case llvm::Triple::NaCl: + return new NaClTargetInfo<PNaClTargetInfo>(Triple); + default: + return nullptr; } case llvm::Triple::le64: @@ -6689,14 +7203,14 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { case llvm::Triple::amdgcn: case llvm::Triple::r600: - return new R600TargetInfo(Triple); + return new AMDGPUTargetInfo(Triple); case llvm::Triple::sparc: switch (os) { case llvm::Triple::Linux: return new LinuxTargetInfo<SparcV8TargetInfo>(Triple); case llvm::Triple::Solaris: - return new SolarisSparcV8TargetInfo(Triple); + return new SolarisTargetInfo<SparcV8TargetInfo>(Triple); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple); case llvm::Triple::OpenBSD: @@ -6707,6 +7221,21 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { return new SparcV8TargetInfo(Triple); } + // The 'sparcel' architecture copies all the above cases except for Solaris. + case llvm::Triple::sparcel: + switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple); + case llvm::Triple::NetBSD: + return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple); + case llvm::Triple::OpenBSD: + return new OpenBSDTargetInfo<SparcV8elTargetInfo>(Triple); + case llvm::Triple::RTEMS: + return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple); + default: + return new SparcV8elTargetInfo(Triple); + } + case llvm::Triple::sparcv9: switch (os) { case llvm::Triple::Linux: @@ -6739,8 +7268,16 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { return new DarwinI386TargetInfo(Triple); switch (os) { - case llvm::Triple::Linux: - return new LinuxTargetInfo<X86_32TargetInfo>(Triple); + case llvm::Triple::CloudABI: + return new CloudABITargetInfo<X86_32TargetInfo>(Triple); + case llvm::Triple::Linux: { + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo<X86_32TargetInfo>(Triple); + case llvm::Triple::Android: + return new AndroidX86_32TargetInfo(Triple); + } + } case llvm::Triple::DragonFly: return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple); case llvm::Triple::NetBSD: @@ -6785,8 +7322,16 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { return new DarwinX86_64TargetInfo(Triple); switch (os) { - case llvm::Triple::Linux: - return new LinuxTargetInfo<X86_64TargetInfo>(Triple); + case llvm::Triple::CloudABI: + return new CloudABITargetInfo<X86_64TargetInfo>(Triple); + case llvm::Triple::Linux: { + switch (Triple.getEnvironment()) { + default: + return new LinuxTargetInfo<X86_64TargetInfo>(Triple); + case llvm::Triple::Android: + return new AndroidX86_64TargetInfo(Triple); + } + } case llvm::Triple::DragonFly: return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple); case llvm::Triple::NetBSD: @@ -6813,22 +7358,24 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { } case llvm::Triple::NaCl: return new NaClTargetInfo<X86_64TargetInfo>(Triple); + case llvm::Triple::PS4: + return new PS4OSTargetInfo<X86_64TargetInfo>(Triple); default: return new X86_64TargetInfo(Triple); } - case llvm::Triple::spir: { - if (Triple.getOS() != llvm::Triple::UnknownOS || - Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) - return nullptr; - return new SPIR32TargetInfo(Triple); - } - case llvm::Triple::spir64: { - if (Triple.getOS() != llvm::Triple::UnknownOS || - Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) - return nullptr; - return new SPIR64TargetInfo(Triple); - } + case llvm::Triple::spir: { + if (Triple.getOS() != llvm::Triple::UnknownOS || + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + return nullptr; + return new SPIR32TargetInfo(Triple); + } + case llvm::Triple::spir64: { + if (Triple.getOS() != llvm::Triple::UnknownOS || + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + return nullptr; + return new SPIR64TargetInfo(Triple); + } } } diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp index ae9eb1a..6accb04 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_361/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 index aa43ae2..9c73fd9 100644 --- a/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp @@ -32,6 +32,8 @@ raw_ostream& clang::operator<<(raw_ostream &Out, 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; } @@ -55,7 +57,7 @@ static bool parseInt(StringRef &input, unsigned &value) { } bool VersionTuple::tryParse(StringRef input) { - unsigned major = 0, minor = 0, micro = 0; + unsigned major = 0, minor = 0, micro = 0, build = 0; // Parse the major version, [0-9]+ if (parseInt(input, major)) return true; @@ -80,9 +82,19 @@ bool VersionTuple::tryParse(StringRef input) { 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); + *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 c89195e..a36102c 100644 --- a/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp @@ -92,7 +92,7 @@ class RealFile : public File { } public: - ~RealFile(); + ~RealFile() override; ErrorOr<Status> status() override; ErrorOr<std::unique_ptr<MemoryBuffer>> getBuffer(const Twine &Name, int64_t FileSize = -1, @@ -324,20 +324,6 @@ directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir, // VFSFromYAML implementation //===-----------------------------------------------------------------------===/ -// Allow DenseMap<StringRef, ...>. This is useful below because we know all the -// strings are literals and will outlive the map, and there is no reason to -// store them. -namespace llvm { - template<> - struct DenseMapInfo<StringRef> { - // This assumes that "" will never be a valid key. - static inline StringRef getEmptyKey() { return StringRef(""); } - static inline StringRef getTombstoneKey() { return StringRef(); } - static unsigned getHashValue(StringRef Val) { return HashString(Val); } - static bool isEqual(StringRef LHS, StringRef RHS) { return LHS == RHS; } - }; -} - namespace { enum EntryKind { @@ -362,7 +348,7 @@ class DirectoryEntry : public Entry { Status S; public: - virtual ~DirectoryEntry(); + ~DirectoryEntry() override; DirectoryEntry(StringRef Name, std::vector<Entry *> Contents, Status S) : Entry(EK_Directory, Name), Contents(std::move(Contents)), S(std::move(S)) {} @@ -498,7 +484,7 @@ private: ErrorOr<Status> status(const Twine &Path, Entry *E); public: - ~VFSFromYAML(); + ~VFSFromYAML() override; /// \brief Parses \p Buffer, which is expected to be in YAML format and /// returns a virtual file system representing its contents. @@ -1134,7 +1120,7 @@ VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl(const Twine &_Path, if (Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); - llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str()); + llvm::ErrorOr<vfs::Status> S = FS.status(PathStr); if (S) CurrentEntry = *S; else @@ -1147,7 +1133,7 @@ std::error_code VFSFromYamlDirIterImpl::increment() { if (++Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); - llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str()); + llvm::ErrorOr<vfs::Status> S = FS.status(PathStr); if (!S) return S.getError(); CurrentEntry = *S; |