diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp | 21 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/FileManager.cpp | 24 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp | 6 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp | 18 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp | 7 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Module.cpp | 11 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp | 174 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp | 40 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp | 48 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets.cpp | 811 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Version.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp | 134 |
14 files changed, 993 insertions, 306 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp index f10d156..7529c47 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp @@ -55,10 +55,12 @@ static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, Output.append(Str.begin(), Str.end()); } -DiagnosticsEngine::DiagnosticsEngine( - const IntrusiveRefCntPtr<DiagnosticIDs> &diags, DiagnosticOptions *DiagOpts, - DiagnosticConsumer *client, bool ShouldOwnClient) - : Diags(diags), DiagOpts(DiagOpts), Client(nullptr), SourceMgr(nullptr) { +DiagnosticsEngine::DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> diags, + DiagnosticOptions *DiagOpts, + DiagnosticConsumer *client, + bool ShouldOwnClient) + : Diags(std::move(diags)), DiagOpts(DiagOpts), Client(nullptr), + SourceMgr(nullptr) { setClient(client, ShouldOwnClient); ArgToStringFn = DummyArgToStringFn; ArgToStringCookie = nullptr; @@ -740,7 +742,10 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, // "%diff{compare $ to $|other text}1,2" // treat it as: // "compare %1 to %2" - const char *Pipe = ScanFormat(Argument, Argument + ArgumentLen, '|'); + const char *ArgumentEnd = Argument + ArgumentLen; + const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|'); + assert(ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd && + "Found too many '|'s in a %diff modifier!"); const char *FirstDollar = ScanFormat(Argument, Pipe, '$'); const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$'); const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) }; @@ -1008,7 +1013,7 @@ PartialDiagnostic::StorageAllocator::StorageAllocator() { PartialDiagnostic::StorageAllocator::~StorageAllocator() { // Don't assert if we are in a CrashRecovery context, as this invariant may // be invalidated during a crash. - assert((NumFreeListEntries == NumCached || - llvm::CrashRecoveryContext::isRecoveringFromCrash()) && - "A partial is on the lamb"); + assert((NumFreeListEntries == NumCached || + llvm::CrashRecoveryContext::isRecoveringFromCrash()) && + "A partial is on the lam"); } diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp index f54a0ef..93c2196 100644 --- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp @@ -16,7 +16,7 @@ namespace clang { -raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M) { +raw_ostream &operator<<(raw_ostream &Out, DiagnosticLevelMask M) { using UT = std::underlying_type<DiagnosticLevelMask>::type; return Out << static_cast<UT>(M); } diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp index ce9b7e1..50050d0 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp @@ -26,10 +26,13 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" -#include <map> -#include <set> +#include <algorithm> +#include <cassert> +#include <climits> +#include <cstdint> +#include <cstdlib> #include <string> -#include <system_error> +#include <utility> using namespace clang; @@ -137,7 +140,7 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { // Add the virtual directory to the cache. auto UDE = llvm::make_unique<DirectoryEntry>(); - UDE->Name = NamedDirEnt.first().data(); + UDE->Name = NamedDirEnt.first(); NamedDirEnt.second = UDE.get(); VirtualDirectoryEntries.push_back(std::move(UDE)); @@ -182,7 +185,7 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName, // Get the null-terminated directory name as stored as the key of the // SeenDirEntries map. - const char *InterndDirName = NamedDirEnt.first().data(); + StringRef InterndDirName = NamedDirEnt.first(); // Check to see if the directory exists. FileData Data; @@ -200,7 +203,7 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName, DirectoryEntry &UDE = UniqueRealDirs[Data.UniqueID]; NamedDirEnt.second = &UDE; - if (!UDE.getName()) { + if (UDE.getName().empty()) { // We don't have this directory yet, add it. We use the string // key from the SeenDirEntries map as the string. UDE.Name = InterndDirName; @@ -229,7 +232,7 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, // Get the null-terminated file name as stored as the key of the // SeenFileEntries map. - const char *InterndFileName = NamedFileEnt.first().data(); + StringRef InterndFileName = NamedFileEnt.first(); // Look up the directory for the file. When looking up something like // sys/foo.h we'll discover all of the search directories that have a 'sys' @@ -420,7 +423,7 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, if (isVolatile) FileSize = -1; - const char *Filename = Entry->getName(); + StringRef Filename = Entry->getName(); // If the file is already open, use the open file descriptor. if (Entry->File) { auto Result = @@ -460,7 +463,7 @@ FileManager::getBufferForFile(StringRef Filename) { /// if the path points to a virtual file or does not exist, or returns /// false if it's an existent real file. If FileDescriptor is NULL, /// do directory look-up instead of file look-up. -bool FileManager::getStatValue(const char *Path, FileData &Data, bool isFile, +bool FileManager::getStatValue(StringRef Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F) { // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be // absolute! @@ -497,7 +500,6 @@ void FileManager::invalidateCache(const FileEntry *Entry) { UniqueRealFiles.erase(Entry->getUniqueID()); } - void FileManager::GetUniqueIDMapping( SmallVectorImpl<const FileEntry *> &UIDToFiles) const { UIDToFiles.clear(); @@ -533,7 +535,7 @@ StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { #ifdef LLVM_ON_UNIX char CanonicalNameBuf[PATH_MAX]; - if (realpath(Dir->getName(), CanonicalNameBuf)) + if (realpath(Dir->getName().str().c_str(), CanonicalNameBuf)) CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage); #else SmallString<256> CanonicalNameBuf(CanonicalName); diff --git a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp index 187ea37..799df1d 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp @@ -23,7 +23,7 @@ static void copyStatusToFileData(const vfs::Status &Status, FileData &Data) { Data.Name = Status.getName(); Data.Size = Status.getSize(); - Data.ModTime = Status.getLastModificationTime().toEpochTime(); + Data.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); Data.UniqueID = Status.getUniqueID(); Data.IsDirectory = Status.isDirectory(); Data.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; @@ -40,7 +40,7 @@ static void copyStatusToFileData(const vfs::Status &Status, /// success for directories (not files). On a successful file lookup, the /// implementation can optionally fill in FileDescriptor with a valid /// descriptor and the client guarantees that it will close it. -bool FileSystemStatCache::get(const char *Path, FileData &Data, bool isFile, +bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache, vfs::FileSystem &FS) { LookupResult R; @@ -107,7 +107,7 @@ bool FileSystemStatCache::get(const char *Path, FileData &Data, bool isFile, } MemorizeStatCalls::LookupResult -MemorizeStatCalls::getStat(const char *Path, FileData &Data, bool isFile, +MemorizeStatCalls::getStat(StringRef Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) { LookupResult Result = statChained(Path, Data, isFile, F, FS); diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp index d6ad0f5..af424cd 100644 --- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp @@ -113,7 +113,8 @@ namespace { KEYOBJC2 = 0x20000, KEYZVECTOR = 0x40000, KEYCOROUTINES = 0x80000, - KEYALL = (0xfffff & ~KEYNOMS18 & + KEYMODULES = 0x100000, + KEYALL = (0x1fffff & ~KEYNOMS18 & ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude. }; @@ -147,9 +148,10 @@ 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.Coroutines && (Flags & KEYCOROUTINES)) return KS_Enabled; + if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled; + if (LangOpts.CoroutinesTS && (Flags & KEYCOROUTINES)) return KS_Enabled; + if (LangOpts.ModulesTS && (Flags & KEYMODULES)) return KS_Enabled; if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) return KS_Future; return KS_Disabled; } @@ -441,9 +443,11 @@ std::string Selector::getAsString() const { if (getIdentifierInfoFlag() < MultiArg) { IdentifierInfo *II = getAsIdentifierInfo(); - // If the number of arguments is 0 then II is guaranteed to not be null. - if (getNumArgs() == 0) + if (getNumArgs() == 0) { + assert(II && "If the number of arguments is 0 then II is guaranteed to " + "not be null."); return II->getName(); + } if (!II) return ":"; @@ -619,8 +623,8 @@ Selector SelectorTable::getSelector(unsigned nKeys, IdentifierInfo **IIV) { // variable size array (for parameter types) at the end of them. unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *); MultiKeywordSelector *SI = - (MultiKeywordSelector*)SelTabImpl.Allocator.Allocate(Size, - llvm::alignOf<MultiKeywordSelector>()); + (MultiKeywordSelector *)SelTabImpl.Allocator.Allocate( + Size, alignof(MultiKeywordSelector)); new (SI) MultiKeywordSelector(nKeys, IIV); SelTabImpl.Table.InsertNode(SI, InsertPos); return Selector(SI); diff --git a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp index 8c0ecd4..ff10a77 100644 --- a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp @@ -15,7 +15,8 @@ using namespace clang; -LangOptions::LangOptions() { +LangOptions::LangOptions() + : IsHeaderFile(false) { #define LANGOPT(Name, Bits, Default, Description) Name = Default; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default); #include "clang/Basic/LangOptions.def" @@ -34,10 +35,10 @@ void LangOptions::resetNonModularOptions() { SanitizerBlacklistFiles.clear(); CurrentModule.clear(); + IsHeaderFile = false; } -bool LangOptions::isNoBuiltinFunc(const char *Name) const { - StringRef FuncName(Name); +bool LangOptions::isNoBuiltinFunc(StringRef FuncName) const { for (unsigned i = 0, e = NoBuiltinFuncs.size(); i != e; ++i) if (FuncName.equals(NoBuiltinFuncs[i])) return true; diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp index 3d1a40d..80bbc24 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Module.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp @@ -33,7 +33,7 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), InferExportWildcard(false), ConfigMacrosExhaustive(false), - NameVisibility(Hidden) { + NoUndeclaredIncludes(false), NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) IsAvailable = false; @@ -41,6 +41,8 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, IsSystem = true; if (Parent->IsExternC) IsExternC = true; + if (Parent->NoUndeclaredIncludes) + NoUndeclaredIncludes = true; IsMissingRequirement = Parent->IsMissingRequirement; Parent->SubModuleIndex[Name] = Parent->SubModules.size(); @@ -64,6 +66,8 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, .Case("blocks", LangOpts.Blocks) .Case("cplusplus", LangOpts.CPlusPlus) .Case("cplusplus11", LangOpts.CPlusPlus11) + .Case("freestanding", LangOpts.Freestanding) + .Case("gnuinlineasm", LangOpts.GNUAsm) .Case("objc", LangOpts.ObjC1) .Case("objc_arc", LangOpts.ObjCAutoRefCount) .Case("opencl", LangOpts.OpenCL) @@ -179,6 +183,11 @@ bool Module::directlyUses(const Module *Requested) const { for (auto *Use : Top->DirectUses) if (Requested->isSubModuleOf(Use)) return true; + + // Anyone is allowed to use our builtin stddef.h and its accompanying module. + if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") + return true; + return false; } diff --git a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp index d1e4779..905c369 100644 --- a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp @@ -610,6 +610,106 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_target_simd: + switch (CKind) { +#define OPENMP_TARGET_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_teams_distribute: + switch (CKind) { +#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_teams_distribute_simd: + switch (CKind) { +#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_teams_distribute_parallel_for_simd: + switch (CKind) { +#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_teams_distribute_parallel_for: + switch (CKind) { +#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams_distribute: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams_distribute_parallel_for: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams_distribute_parallel_for_simd: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams_distribute_simd: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_declare_target: case OMPD_end_declare_target: case OMPD_unknown: @@ -635,8 +735,15 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_distribute_parallel_for || DKind == OMPD_distribute_parallel_for_simd || DKind == OMPD_distribute_simd || - DKind == OMPD_target_parallel_for_simd; - // TODO add next directives. + DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd || + DKind == OMPD_teams_distribute || + DKind == OMPD_teams_distribute_simd || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd; } bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { @@ -647,8 +754,11 @@ bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_target_parallel_for || DKind == OMPD_distribute_parallel_for || DKind == OMPD_distribute_parallel_for_simd || - DKind == OMPD_target_parallel_for_simd; - // TODO add next directives. + DKind == OMPD_target_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd; } bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) { @@ -661,15 +771,21 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_target_parallel || DKind == OMPD_target_parallel_for || DKind == OMPD_distribute_parallel_for || DKind == OMPD_distribute_parallel_for_simd || - DKind == OMPD_target_parallel_for_simd; - // TODO add next directives. + DKind == OMPD_target_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd; } bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) { - // TODO add next directives. return DKind == OMPD_target || DKind == OMPD_target_parallel || DKind == OMPD_target_parallel_for || - DKind == OMPD_target_parallel_for_simd; + DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd || + DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd; } bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) { @@ -677,25 +793,50 @@ bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_target_exit_data || DKind == OMPD_target_update; } +bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) { + return DKind == OMPD_teams || DKind == OMPD_teams_distribute || + DKind == OMPD_teams_distribute_simd || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for; +} + bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { - return DKind == OMPD_teams; // TODO add next directives. + return isOpenMPNestingTeamsDirective(DKind) || + DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd; } bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_simd || DKind == OMPD_for_simd || DKind == OMPD_parallel_for_simd || DKind == OMPD_taskloop_simd || DKind == OMPD_distribute_parallel_for_simd || - DKind == OMPD_distribute_simd; - // TODO add next directives. + DKind == OMPD_distribute_simd || DKind == OMPD_target_simd || + DKind == OMPD_teams_distribute_simd || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd; } -bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) { +bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) { return Kind == OMPD_distribute || Kind == OMPD_distribute_parallel_for || Kind == OMPD_distribute_parallel_for_simd || Kind == OMPD_distribute_simd; // TODO add next directives. } +bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) { + return isOpenMPNestingDistributeDirective(Kind) || + Kind == OMPD_teams_distribute || Kind == OMPD_teams_distribute_simd || + Kind == OMPD_teams_distribute_parallel_for_simd || + Kind == OMPD_teams_distribute_parallel_for || + Kind == OMPD_target_teams_distribute || + Kind == OMPD_target_teams_distribute_parallel_for || + Kind == OMPD_target_teams_distribute_parallel_for_simd || + Kind == OMPD_target_teams_distribute_simd; +} + bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) { return Kind == OMPC_private || Kind == OMPC_firstprivate || Kind == OMPC_lastprivate || Kind == OMPC_linear || @@ -713,5 +854,12 @@ bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) { bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) { return Kind == OMPD_distribute_parallel_for || Kind == OMPD_distribute_parallel_for_simd || - Kind == OMPD_distribute_simd; + Kind == OMPD_distribute_simd || Kind == OMPD_teams_distribute || + Kind == OMPD_teams_distribute_simd || + Kind == OMPD_teams_distribute_parallel_for_simd || + Kind == OMPD_teams_distribute_parallel_for || + Kind == OMPD_target_teams_distribute || + Kind == OMPD_target_teams_distribute_parallel_for || + Kind == OMPD_target_teams_distribute_parallel_for_simd || + Kind == OMPD_target_teams_distribute_simd; } diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp index d254e86..a58d046 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp @@ -14,7 +14,6 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include <cstdio> using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp index 1e83b63..380ca37 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -25,7 +25,6 @@ #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cstring> -#include <string> using namespace clang; using namespace SrcMgr; @@ -387,8 +386,6 @@ SourceManager::~SourceManager() { ContentCacheAlloc.Deallocate(I->second); } } - - llvm::DeleteContainerSeconds(MacroArgsCacheMap); } void SourceManager::clearIDTables() { @@ -1438,8 +1435,8 @@ SourceManager::getFileCharacteristic(SourceLocation Loc) const { /// Return the filename or buffer identifier of the buffer the location is in. /// Note that this name does not respect \#line directives. Use getPresumedLoc /// for normal clients. -const char *SourceManager::getBufferName(SourceLocation Loc, - bool *Invalid) const { +StringRef SourceManager::getBufferName(SourceLocation Loc, + bool *Invalid) const { if (isInvalid(Loc, Invalid)) return "<invalid loc>"; return getBuffer(getFileID(Loc), Invalid)->getBufferIdentifier(); @@ -1471,7 +1468,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, // To get the source name, first consult the FileEntry (if one exists) // before the MemBuffer as this will avoid unnecessarily paging in the // MemBuffer. - const char *Filename; + StringRef Filename; if (C->OrigEntry) Filename = C->OrigEntry->getName(); else @@ -1514,7 +1511,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, } } - return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc); + return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc); } /// \brief Returns whether the PresumedLoc for a given SourceLocation is @@ -1785,13 +1782,10 @@ SourceLocation SourceManager::translateLineCol(FileID FID, /// 0 -> SourceLocation() /// 100 -> Expanded macro arg location /// 110 -> SourceLocation() -void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr, +void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache, FileID FID) const { assert(FID.isValid()); - assert(!CachePtr); - CachePtr = new MacroArgsMap(); - MacroArgsMap &MacroArgsCache = *CachePtr; // Initially no macro argument chunk is present. MacroArgsCache.insert(std::make_pair(0, SourceLocation())); @@ -1941,9 +1935,11 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { if (FID.isInvalid()) return Loc; - MacroArgsMap *&MacroArgsCache = MacroArgsCacheMap[FID]; - if (!MacroArgsCache) - computeMacroArgsCache(MacroArgsCache, FID); + std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID]; + if (!MacroArgsCache) { + MacroArgsCache = llvm::make_unique<MacroArgsMap>(); + computeMacroArgsCache(*MacroArgsCache, FID); + } assert(!MacroArgsCache->empty()); MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset); @@ -2096,10 +2092,10 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // Clear the lookup cache, it depends on a common location. IsBeforeInTUCache.clear(); - const char *LB = getBuffer(LOffs.first)->getBufferIdentifier(); - const char *RB = getBuffer(ROffs.first)->getBufferIdentifier(); - bool LIsBuiltins = strcmp("<built-in>", LB) == 0; - bool RIsBuiltins = strcmp("<built-in>", RB) == 0; + StringRef LB = getBuffer(LOffs.first)->getBufferIdentifier(); + StringRef RB = getBuffer(ROffs.first)->getBufferIdentifier(); + bool LIsBuiltins = LB == "<built-in>"; + bool RIsBuiltins = RB == "<built-in>"; // Sort built-in before non-built-in. if (LIsBuiltins || RIsBuiltins) { if (LIsBuiltins != RIsBuiltins) @@ -2108,8 +2104,8 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // lower IDs come first. return LOffs.first < ROffs.first; } - bool LIsAsm = strcmp("<inline asm>", LB) == 0; - bool RIsAsm = strcmp("<inline asm>", RB) == 0; + bool LIsAsm = LB == "<inline asm>"; + bool RIsAsm = RB == "<inline asm>"; // Sort assembler after built-ins, but before the rest. if (LIsAsm || RIsAsm) { if (LIsAsm != RIsAsm) @@ -2117,8 +2113,8 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, assert(LOffs.first == ROffs.first); return false; } - bool LIsScratch = strcmp("<scratch space>", LB) == 0; - bool RIsScratch = strcmp("<scratch space>", RB) == 0; + bool LIsScratch = LB == "<scratch space>"; + bool RIsScratch = RB == "<scratch space>"; // Sort scratch after inline asm, but before the rest. if (LIsScratch || RIsScratch) { if (LIsScratch != RIsScratch) diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp index 92f658a..b1b01e5 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp @@ -27,7 +27,7 @@ static const LangAS::Map DefaultAddrSpaceMap = { 0 }; TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or // SPARC. These should be overridden by concrete targets as needed. - BigEndian = true; + BigEndian = !T.isLittleEndian(); TLSSupported = true; NoAsmVariants = false; HasFloat128 = false; @@ -39,6 +39,13 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { SuitableAlign = 64; DefaultAlignForAttributeAligned = 128; MinGlobalAlign = 0; + // From the glibc documentation, on GNU systems, malloc guarantees 16-byte + // alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See + // https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html + if (T.isGNUEnvironment()) + NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; + else + NewAlign = 0; // Infer from basic type alignment. HalfWidth = 16; HalfAlign = 16; FloatWidth = 32; @@ -70,16 +77,17 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { UseZeroLengthBitfieldAlignment = false; UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; - HalfFormat = &llvm::APFloat::IEEEhalf; - FloatFormat = &llvm::APFloat::IEEEsingle; - DoubleFormat = &llvm::APFloat::IEEEdouble; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; - Float128Format = &llvm::APFloat::IEEEquad; + HalfFormat = &llvm::APFloat::IEEEhalf(); + FloatFormat = &llvm::APFloat::IEEEsingle(); + DoubleFormat = &llvm::APFloat::IEEEdouble(); + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + Float128Format = &llvm::APFloat::IEEEquad(); MCountName = "mcount"; RegParmMax = 0; SSERegParmMax = 0; HasAlignMac68kSupport = false; HasBuiltinMSVaList = false; + IsRenderScriptTarget = false; // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; @@ -219,12 +227,12 @@ TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const { switch (BitWidth) { case 96: - if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended) + if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended()) return LongDouble; break; case 128: - if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble || - &getLongDoubleFormat() == &llvm::APFloat::IEEEquad) + if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() || + &getLongDoubleFormat() == &llvm::APFloat::IEEEquad()) return LongDouble; if (hasFloat128Type()) return Float128; @@ -301,12 +309,13 @@ void TargetInfo::adjust(const LangOptions &Opts) { // to generating illegal code that uses 64bit doubles. if (DoubleWidth != FloatWidth) { DoubleWidth = DoubleAlign = 64; - DoubleFormat = &llvm::APFloat::IEEEdouble; + DoubleFormat = &llvm::APFloat::IEEEdouble(); } LongDoubleWidth = LongDoubleAlign = 128; - assert(PointerWidth == 32 || PointerWidth == 64); - bool Is32BitArch = PointerWidth == 32; + unsigned MaxPointerWidth = getMaxPointerWidth(); + assert(MaxPointerWidth == 32 || MaxPointerWidth == 64); + bool Is32BitArch = MaxPointerWidth == 32; SizeType = Is32BitArch ? UnsignedInt : UnsignedLong; PtrDiffType = Is32BitArch ? SignedInt : SignedLong; IntPtrType = Is32BitArch ? SignedInt : SignedLong; @@ -314,10 +323,13 @@ void TargetInfo::adjust(const LangOptions &Opts) { IntMaxType = SignedLongLong; Int64Type = SignedLong; - HalfFormat = &llvm::APFloat::IEEEhalf; - FloatFormat = &llvm::APFloat::IEEEsingle; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + HalfFormat = &llvm::APFloat::IEEEhalf(); + FloatFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleFormat = &llvm::APFloat::IEEEquad(); } + + if (Opts.NewAlignOverride) + NewAlign = Opts.NewAlignOverride * getCharWidth(); } bool TargetInfo::initFeatureMap( @@ -398,8 +410,8 @@ bool TargetInfo::isValidGCCRegisterName(StringRef Name) const { return false; } -StringRef -TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const { +StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name, + bool ReturnCanonical) const { assert(isValidGCCRegisterName(Name) && "Invalid register passed in"); // Get rid of any register prefix. @@ -424,7 +436,7 @@ TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const { // Make sure the register that the additional name is for is within // the bounds of the register names from above. if (AN == Name && ARN.RegNum < Names.size()) - return Name; + return ReturnCanonical ? Names[ARN.RegNum] : Name; } // Now check aliases. diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index be5d4ad..1a95ff2 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -21,6 +21,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/Version.h" +#include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -464,6 +465,8 @@ protected: Triple.getEnvironmentVersion(Maj, Min, Rev); this->PlatformName = "android"; this->PlatformMinVersion = VersionTuple(Maj, Min, Rev); + if (Maj) + Builder.defineMacro("__ANDROID_API__", Twine(Maj)); } if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); @@ -509,7 +512,7 @@ protected: Builder.defineMacro("__unix__"); Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) - Builder.defineMacro("_POSIX_THREADS"); + Builder.defineMacro("_REENTRANT"); switch (Triple.getArch()) { default: @@ -805,8 +808,8 @@ public: this->SizeType = TargetInfo::UnsignedInt; this->PtrDiffType = TargetInfo::SignedInt; this->IntPtrType = TargetInfo::SignedInt; - // RegParmMax is inherited from the underlying architecture - this->LongDoubleFormat = &llvm::APFloat::IEEEdouble; + // RegParmMax is inherited from the underlying architecture. + this->LongDoubleFormat = &llvm::APFloat::IEEEdouble(); if (Triple.getArch() == llvm::Triple::arm) { // Handled in ARM's setABI(). } else if (Triple.getArch() == llvm::Triple::x86) { @@ -822,6 +825,28 @@ public: } }; +// Fuchsia Target +template<typename Target> +class FuchsiaTargetInfo : public OSTargetInfo<Target> { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + Builder.defineMacro("__Fuchsia__"); + Builder.defineMacro("__ELF__"); + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + // Required by the libc++ locale support. + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + } +public: + FuchsiaTargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { + this->MCountName = "__mcount"; + } +}; + // WebAssembly target template <typename Target> class WebAssemblyOSTargetInfo : public OSTargetInfo<Target> { @@ -869,6 +894,7 @@ class PPCTargetInfo : public TargetInfo { bool HasHTM; bool HasBPERMD; bool HasExtDiv; + bool HasP9Vector; protected: std::string ABI; @@ -877,11 +903,10 @@ public: PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), HasVSX(false), HasP8Vector(false), HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false), - HasBPERMD(false), HasExtDiv(false) { - BigEndian = (Triple.getArch() != llvm::Triple::ppc64le); + HasBPERMD(false), HasExtDiv(false), HasP9Vector(false) { SimdDefaultAlign = 128; LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; + LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); } /// \brief Flags for architecture specific defines. @@ -1121,7 +1146,7 @@ public: bool useFloat128ManglingForLongDouble() const override { return LongDoubleWidth == 128 && - LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble && + LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble() && getTriple().isOSBinFormatELF(); } }; @@ -1157,6 +1182,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasHTM = true; } else if (Feature == "+float128") { HasFloat128 = true; + } else if (Feature == "+power9-vector") { + HasP9Vector = true; } // TODO: Finish this list and add an assert that we've handled them // all. @@ -1326,6 +1353,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__HTM__"); if (HasFloat128) Builder.defineMacro("__FLOAT128__"); + if (HasP9Vector) + Builder.defineMacro("__POWER9_VECTOR__"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -1355,8 +1384,12 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, } // Handle explicit options being passed to the compiler here: if we've -// explicitly turned off vsx and turned on power8-vector or direct-move then -// go ahead and error since the customer has expressed a somewhat incompatible +// explicitly turned off vsx and turned on any of: +// - power8-vector +// - direct-move +// - float128 +// - power9-vector +// then go ahead and error since the customer has expressed an incompatible // set of options. static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, const std::vector<std::string> &FeaturesVec) { @@ -1383,6 +1416,13 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, << "-mno-vsx"; return false; } + + if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power9-vector") != + FeaturesVec.end()) { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector" + << "-mno-vsx"; + return false; + } } return true; @@ -1407,6 +1447,7 @@ bool PPCTargetInfo::initFeatureMap( .Default(false); Features["qpx"] = (CPU == "a2q"); + Features["power9-vector"] = (CPU == "pwr9"); Features["crypto"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) .Case("pwr9", true) @@ -1459,6 +1500,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const { .Case("bpermd", HasBPERMD) .Case("extdiv", HasExtDiv) .Case("float128", HasFloat128) + .Case("power9-vector", HasP9Vector) .Default(false); } @@ -1468,19 +1510,21 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, // as well. Do the inverse if we're disabling vsx. We'll diagnose any user // incompatible options. if (Enabled) { - if (Name == "direct-move") { - Features[Name] = Features["vsx"] = true; - } else if (Name == "power8-vector") { - Features[Name] = Features["vsx"] = true; - } else if (Name == "float128") { + if (Name == "direct-move" || + Name == "power8-vector" || + Name == "float128" || + Name == "power9-vector") { + // power9-vector is really a superset of power8-vector so encode that. Features[Name] = Features["vsx"] = true; + if (Name == "power9-vector") + Features["power8-vector"] = true; } else { Features[Name] = true; } } else { if (Name == "vsx") { Features[Name] = Features["direct-move"] = Features["power8-vector"] = - Features["float128"] = false; + Features["float128"] = Features["power9-vector"] = false; } else { Features[Name] = false; } @@ -1606,7 +1650,7 @@ public: if (getTriple().getOS() == llvm::Triple::FreeBSD) { LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } // PPC32 supports atomics up to 4 bytes. @@ -1640,7 +1684,7 @@ public: switch (getTriple().getOS()) { case llvm::Triple::FreeBSD: LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); break; case llvm::Triple::NetBSD: IntMaxType = SignedLongLong; @@ -1707,31 +1751,57 @@ class NVPTXTargetInfo : public TargetInfo { static const char *const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; CudaArch GPU; + std::unique_ptr<TargetInfo> HostTarget; public: - NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, + unsigned TargetPointerWidth) : TargetInfo(Triple) { - BigEndian = false; + assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) && + "NVPTX only supports 32- and 64-bit modes."); + TLSSupported = false; - LongWidth = LongAlign = 64; AddrSpaceMap = &NVPTXAddrSpaceMap; UseAddrSpaceMapMangling = true; + // Define available target features // These must be defined in sorted order! NoAsmVariants = true; GPU = CudaArch::SM_20; + if (TargetPointerWidth == 32) + resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"); + else + resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64"); + // If possible, get a TargetInfo for our host triple, so we can match its // types. llvm::Triple HostTriple(Opts.HostTriple); - if (HostTriple.isNVPTX()) - return; - std::unique_ptr<TargetInfo> HostTarget( - AllocateTarget(llvm::Triple(Opts.HostTriple), Opts)); + if (!HostTriple.isNVPTX()) + HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts)); + + // If no host target, make some guesses about the data layout and return. if (!HostTarget) { + LongWidth = LongAlign = TargetPointerWidth; + PointerWidth = PointerAlign = TargetPointerWidth; + switch (TargetPointerWidth) { + case 32: + SizeType = TargetInfo::UnsignedInt; + PtrDiffType = TargetInfo::SignedInt; + IntPtrType = TargetInfo::SignedInt; + break; + case 64: + SizeType = TargetInfo::UnsignedLong; + PtrDiffType = TargetInfo::SignedLong; + IntPtrType = TargetInfo::SignedLong; + break; + default: + llvm_unreachable("TargetPointerWidth must be 32 or 64"); + } return; } + // Copy properties from host target. PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0); PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0); BoolWidth = HostTarget->getBoolWidth(); @@ -1749,6 +1819,7 @@ public: LongLongWidth = HostTarget->getLongLongWidth(); LongLongAlign = HostTarget->getLongLongAlign(); MinGlobalAlign = HostTarget->getMinGlobalAlign(); + NewAlign = HostTarget->getNewAlign(); DefaultAlignForAttributeAligned = HostTarget->getDefaultAlignForAttributeAligned(); SizeType = HostTarget->getSizeType(); @@ -1769,6 +1840,12 @@ public: UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment(); ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary(); + // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and + // we need those macros to be identical on host and device, because (among + // other things) they affect which standard library classes are defined, and + // we need all classes to be defined on both the host and device. + MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth(); + // Properties intentionally not copied from host: // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the // host/device boundary. @@ -1825,8 +1902,19 @@ public: return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin); } + bool + initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, + StringRef CPU, + const std::vector<std::string> &FeaturesVec) const override { + Features["satom"] = GPU >= CudaArch::SM_60; + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); + } + bool hasFeature(StringRef Feature) const override { - return Feature == "ptx" || Feature == "nvptx"; + return llvm::StringSwitch<bool>(Feature) + .Cases("ptx", "nvptx", true) + .Case("satom", GPU >= CudaArch::SM_60) // Atomics w/ scope. + .Default(false); } ArrayRef<const char *> getGCCRegNames() const override; @@ -1863,16 +1951,26 @@ public: } void setSupportedOpenCLOpts() override { auto &Opts = getSupportedOpenCLOpts(); - Opts.cl_clang_storage_class_specifiers = 1; - Opts.cl_khr_gl_sharing = 1; - Opts.cl_khr_icd = 1; + Opts.support("cl_clang_storage_class_specifiers"); + Opts.support("cl_khr_gl_sharing"); + Opts.support("cl_khr_icd"); + + Opts.support("cl_khr_fp64"); + Opts.support("cl_khr_byte_addressable_store"); + Opts.support("cl_khr_global_int32_base_atomics"); + Opts.support("cl_khr_global_int32_extended_atomics"); + Opts.support("cl_khr_local_int32_base_atomics"); + Opts.support("cl_khr_local_int32_extended_atomics"); + } - Opts.cl_khr_fp64 = 1; - Opts.cl_khr_byte_addressable_store = 1; - Opts.cl_khr_global_int32_base_atomics = 1; - Opts.cl_khr_global_int32_extended_atomics = 1; - Opts.cl_khr_local_int32_base_atomics = 1; - Opts.cl_khr_local_int32_extended_atomics = 1; + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + // CUDA compilations support all of the host's calling conventions. + // + // TODO: We should warn if you apply a non-default CC to anything other than + // a host function. + if (HostTarget) + return HostTarget->checkCallingConvention(CC); + return CCCR_Warning; } }; @@ -1881,6 +1979,8 @@ const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = { { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, #include "clang/Basic/BuiltinsNVPTX.def" }; @@ -1890,31 +1990,6 @@ ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const { return llvm::makeArrayRef(GCCRegNames); } -class NVPTX32TargetInfo : public NVPTXTargetInfo { -public: - NVPTX32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : NVPTXTargetInfo(Triple, Opts) { - LongWidth = LongAlign = 32; - PointerWidth = PointerAlign = 32; - SizeType = TargetInfo::UnsignedInt; - PtrDiffType = TargetInfo::SignedInt; - IntPtrType = TargetInfo::SignedInt; - resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"); - } -}; - -class NVPTX64TargetInfo : public NVPTXTargetInfo { -public: - NVPTX64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : NVPTXTargetInfo(Triple, Opts) { - PointerWidth = PointerAlign = 64; - SizeType = TargetInfo::UnsignedLong; - PtrDiffType = TargetInfo::SignedLong; - IntPtrType = TargetInfo::SignedLong; - resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64"); - } -}; - static const unsigned AMDGPUAddrSpaceMap[] = { 1, // opencl_global 3, // opencl_local @@ -1952,26 +2027,28 @@ class AMDGPUTargetInfo final : public TargetInfo { GK_EVERGREEN_DOUBLE_OPS, GK_NORTHERN_ISLANDS, GK_CAYMAN, - GK_SOUTHERN_ISLANDS, - GK_SEA_ISLANDS, - GK_VOLCANIC_ISLANDS + GK_GFX6, + GK_GFX7, + GK_GFX8 } GPU; bool hasFP64:1; bool hasFMAF:1; bool hasLDEXPF:1; + bool hasFullSpeedFP32Denorms:1; static bool isAMDGCN(const llvm::Triple &TT) { return TT.getArch() == llvm::Triple::amdgcn; } public: - AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple) , - GPU(isAMDGCN(Triple) ? GK_SOUTHERN_ISLANDS : GK_R600), + GPU(isAMDGCN(Triple) ? GK_GFX6 : GK_R600), hasFP64(false), hasFMAF(false), - hasLDEXPF(false) { + hasLDEXPF(false), + hasFullSpeedFP32Denorms(false){ if (getTriple().getArch() == llvm::Triple::amdgcn) { hasFP64 = true; hasFMAF = true; @@ -1999,6 +2076,10 @@ public: } } + uint64_t getMaxPointerWidth() const override { + return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32; + } + const char * getClobbers() const override { return ""; } @@ -2025,6 +2106,24 @@ public: DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeatureVec) const override; + void adjustTargetOptions(const CodeGenOptions &CGOpts, + TargetOptions &TargetOpts) const override { + bool hasFP32Denormals = false; + bool hasFP64Denormals = false; + for (auto &I : TargetOpts.FeaturesAsWritten) { + if (I == "+fp32-denormals" || I == "-fp32-denormals") + hasFP32Denormals = true; + if (I == "+fp64-denormals" || I == "-fp64-denormals") + hasFP64Denormals = true; + } + if (!hasFP32Denormals) + TargetOpts.Features.push_back((Twine(hasFullSpeedFP32Denorms && + !CGOpts.FlushDenorm ? '+' : '-') + Twine("fp32-denormals")).str()); + // Always do not flush fp64 denorms. + if (!hasFP64Denormals && hasFP64) + TargetOpts.Features.push_back("+fp64-denormals"); + } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin); @@ -2081,23 +2180,32 @@ public: static GPUKind parseAMDGCNName(StringRef Name) { return llvm::StringSwitch<GPUKind>(Name) - .Case("tahiti", GK_SOUTHERN_ISLANDS) - .Case("pitcairn", GK_SOUTHERN_ISLANDS) - .Case("verde", GK_SOUTHERN_ISLANDS) - .Case("oland", GK_SOUTHERN_ISLANDS) - .Case("hainan", GK_SOUTHERN_ISLANDS) - .Case("bonaire", GK_SEA_ISLANDS) - .Case("kabini", GK_SEA_ISLANDS) - .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) - .Case("fiji", GK_VOLCANIC_ISLANDS) - .Case("stoney", GK_VOLCANIC_ISLANDS) - .Case("polaris10", GK_VOLCANIC_ISLANDS) - .Case("polaris11", GK_VOLCANIC_ISLANDS) + .Case("tahiti", GK_GFX6) + .Case("pitcairn", GK_GFX6) + .Case("verde", GK_GFX6) + .Case("oland", GK_GFX6) + .Case("hainan", GK_GFX6) + .Case("bonaire", GK_GFX7) + .Case("kabini", GK_GFX7) + .Case("kaveri", GK_GFX7) + .Case("hawaii", GK_GFX7) + .Case("mullins", GK_GFX7) + .Case("gfx700", GK_GFX7) + .Case("gfx701", GK_GFX7) + .Case("gfx702", GK_GFX7) + .Case("tonga", GK_GFX8) + .Case("iceland", GK_GFX8) + .Case("carrizo", GK_GFX8) + .Case("fiji", GK_GFX8) + .Case("stoney", GK_GFX8) + .Case("polaris10", GK_GFX8) + .Case("polaris11", GK_GFX8) + .Case("gfx800", GK_GFX8) + .Case("gfx801", GK_GFX8) + .Case("gfx802", GK_GFX8) + .Case("gfx803", GK_GFX8) + .Case("gfx804", GK_GFX8) + .Case("gfx810", GK_GFX8) .Default(GK_NONE); } @@ -2112,26 +2220,34 @@ public: void setSupportedOpenCLOpts() override { auto &Opts = getSupportedOpenCLOpts(); - Opts.cl_clang_storage_class_specifiers = 1; - Opts.cl_khr_icd = 1; + Opts.support("cl_clang_storage_class_specifiers"); + Opts.support("cl_khr_icd"); if (hasFP64) - Opts.cl_khr_fp64 = 1; + Opts.support("cl_khr_fp64"); if (GPU >= GK_EVERGREEN) { - Opts.cl_khr_byte_addressable_store = 1; - Opts.cl_khr_global_int32_base_atomics = 1; - Opts.cl_khr_global_int32_extended_atomics = 1; - Opts.cl_khr_local_int32_base_atomics = 1; - Opts.cl_khr_local_int32_extended_atomics = 1; + Opts.support("cl_khr_byte_addressable_store"); + Opts.support("cl_khr_global_int32_base_atomics"); + Opts.support("cl_khr_global_int32_extended_atomics"); + Opts.support("cl_khr_local_int32_base_atomics"); + Opts.support("cl_khr_local_int32_extended_atomics"); } - if (GPU >= GK_SOUTHERN_ISLANDS) { - Opts.cl_khr_fp16 = 1; - Opts.cl_khr_int64_base_atomics = 1; - Opts.cl_khr_int64_extended_atomics = 1; - Opts.cl_khr_3d_image_writes = 1; + if (GPU >= GK_GFX6) { + Opts.support("cl_khr_fp16"); + Opts.support("cl_khr_int64_base_atomics"); + Opts.support("cl_khr_int64_extended_atomics"); + Opts.support("cl_khr_mipmap_image"); + Opts.support("cl_khr_subgroups"); + Opts.support("cl_khr_3d_image_writes"); + Opts.support("cl_amd_media_ops"); + Opts.support("cl_amd_media_ops2"); } } + LangAS::ID getOpenCLImageAddrSpace() const override { + return LangAS::opencl_constant; + } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { switch (CC) { default: @@ -2141,6 +2257,13 @@ public: return CCCR_OK; } } + + // In amdgcn target the null pointer in global, constant, and generic + // address space has value 0 but in private and local address space has + // value ~0. + uint64_t getNullPointerValue(unsigned AS) const override { + return AS != LangAS::opencl_local && AS != 0 ? 0 : ~0; + } }; const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = { @@ -2218,11 +2341,11 @@ bool AMDGPUTargetInfo::initFeatureMap( CPU = "tahiti"; switch (parseAMDGCNName(CPU)) { - case GK_SOUTHERN_ISLANDS: - case GK_SEA_ISLANDS: + case GK_GFX6: + case GK_GFX7: break; - case GK_VOLCANIC_ISLANDS: + case GK_GFX8: Features["s-memrealtime"] = true; Features["16-bit-insts"] = true; break; @@ -2258,17 +2381,25 @@ bool AMDGPUTargetInfo::initFeatureMap( return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); } -// Namespace for x86 abstract base class -const Builtin::Info BuiltinInfo[] = { +const Builtin::Info BuiltinInfoX86[] = { #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsX86.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, +#include "clang/Basic/BuiltinsX86_64.def" }; + static const char* const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", @@ -2287,6 +2418,7 @@ static const char* const GCCRegNames[] = { "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", + "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7", }; const TargetInfo::AddlRegName AddlRegNames[] = { @@ -2531,6 +2663,12 @@ class X86TargetInfo : public TargetInfo { CK_BDVER4, //@} + /// \name zen + /// Zen architecture processors. + //@{ + CK_ZNVER1, + //@} + /// This specification is deprecated and will be removed in the future. /// Users should prefer \see CK_K8. // FIXME: Warn on this when the CPU is set to it. @@ -2612,6 +2750,7 @@ class X86TargetInfo : public TargetInfo { .Case("bdver2", CK_BDVER2) .Case("bdver3", CK_BDVER3) .Case("bdver4", CK_BDVER4) + .Case("znver1", CK_ZNVER1) .Case("x86-64", CK_x86_64) .Case("geode", CK_Geode) .Default(CK_Generic); @@ -2626,17 +2765,12 @@ class X86TargetInfo : public TargetInfo { public: X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; - LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; + LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); } unsigned getFloatEvalMethod() const override { // X87 evaluates with 80 bits "long double" precision. return SSELevel == NoSSE ? 2 : 0; } - ArrayRef<Builtin::Info> getTargetBuiltins() const override { - return llvm::makeArrayRef(BuiltinInfo, - clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin); - } ArrayRef<const char *> getGCCRegNames() const override { return llvm::makeArrayRef(GCCRegNames); } @@ -2674,6 +2808,40 @@ public: const char *getClobbers() const override { return "~{dirflag},~{fpsr},~{flags}"; } + + StringRef getConstraintRegister(const StringRef &Constraint, + const StringRef &Expression) const override { + StringRef::iterator I, E; + for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) { + if (isalpha(*I)) + break; + } + if (I == E) + return ""; + switch (*I) { + // For the register constraints, return the matching register name + case 'a': + return "ax"; + case 'b': + return "bx"; + case 'c': + return "cx"; + case 'd': + return "dx"; + case 'S': + return "si"; + case 'D': + return "di"; + // In case the constraint is 'r' we need to return Expression + case 'r': + return Expression; + default: + // Default value if there is no constraint for the register + return ""; + } + return ""; + } + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level, @@ -2782,6 +2950,7 @@ public: case CK_BDVER2: case CK_BDVER3: case CK_BDVER4: + case CK_ZNVER1: case CK_x86_64: return true; } @@ -2797,6 +2966,7 @@ public: case CC_X86FastCall: case CC_X86StdCall: case CC_X86VectorCall: + case CC_X86RegCall: case CC_C: case CC_Swift: case CC_X86Pascal: @@ -2816,7 +2986,7 @@ public: } void setSupportedOpenCLOpts() override { - getSupportedOpenCLOpts().setAll(); + getSupportedOpenCLOpts().supportAll(); } }; @@ -3028,6 +3198,33 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "cx16", true); setFeatureEnabledImpl(Features, "fxsr", true); break; + case CK_ZNVER1: + setFeatureEnabledImpl(Features, "adx", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "avx2", true); + setFeatureEnabledImpl(Features, "bmi", true); + setFeatureEnabledImpl(Features, "bmi2", true); + setFeatureEnabledImpl(Features, "clflushopt", true); + setFeatureEnabledImpl(Features, "cx16", true); + setFeatureEnabledImpl(Features, "f16c", true); + setFeatureEnabledImpl(Features, "fma", true); + setFeatureEnabledImpl(Features, "fsgsbase", true); + setFeatureEnabledImpl(Features, "fxsr", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "mwaitx", true); + setFeatureEnabledImpl(Features, "movbe", true); + setFeatureEnabledImpl(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "popcnt", true); + setFeatureEnabledImpl(Features, "prfchw", true); + setFeatureEnabledImpl(Features, "rdrnd", true); + setFeatureEnabledImpl(Features, "rdseed", true); + setFeatureEnabledImpl(Features, "sha", true); + setFeatureEnabledImpl(Features, "sse4a", true); + setFeatureEnabledImpl(Features, "xsave", true); + setFeatureEnabledImpl(Features, "xsavec", true); + setFeatureEnabledImpl(Features, "xsaveopt", true); + setFeatureEnabledImpl(Features, "xsaves", true); + break; case CK_BDVER4: setFeatureEnabledImpl(Features, "avx2", true); setFeatureEnabledImpl(Features, "bmi2", true); @@ -3244,6 +3441,12 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, Name == "avx512vbmi" || Name == "avx512ifma") { if (Enabled) setSSELevel(Features, AVX512F, Enabled); + // Enable BWI instruction if VBMI is being enabled. + if (Name == "avx512vbmi" && Enabled) + Features["avx512bw"] = true; + // Also disable VBMI if BWI is being disabled. + if (Name == "avx512bw" && !Enabled) + Features["avx512vbmi"] = false; } else if (Name == "fma") { if (Enabled) setSSELevel(Features, AVX, Enabled); @@ -3573,6 +3776,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_BDVER4: defineCPUMacros(Builder, "bdver4"); break; + case CK_ZNVER1: + defineCPUMacros(Builder, "znver1"); + break; case CK_Geode: defineCPUMacros(Builder, "geode"); break; @@ -3891,6 +4097,7 @@ X86TargetInfo::validateAsmConstraint(const char *&Name, case 't': // Any SSE register, when SSE2 is enabled. case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled. case 'm': // Any MMX register, when inter-unit moves enabled. + case 'k': // AVX512 arch mask registers: k1-k7. Info.setAllowsRegister(); return true; } @@ -3911,7 +4118,10 @@ X86TargetInfo::validateAsmConstraint(const char *&Name, case 'u': // Second from top of floating point stack. case 'q': // Any register accessible as [r]l: a, b, c, and d. case 'y': // Any MMX register. + case 'v': // Any {X,Y,Z}MM register (Arch & context dependent) case 'x': // Any SSE register. + case 'k': // Any AVX512 mask register (same as Yk, additionaly allows k0 + // for intermideate k reg operations). case 'Q': // Any register accessible as [r]h: a, b, c, and d. case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp. case 'l': // "Index" registers: any general register that can be used as an @@ -3945,12 +4155,15 @@ bool X86TargetInfo::validateOperandSize(StringRef Constraint, unsigned Size) const { switch (Constraint[0]) { default: break; + case 'k': + // Registers k0-k7 (AVX512) size limit is 64 bit. case 'y': return Size <= 64; case 'f': case 't': case 'u': return Size <= 128; + case 'v': case 'x': if (SSELevel >= AVX512F) // 512-bit zmm registers can be used if target supports AVX512F. @@ -3965,6 +4178,7 @@ bool X86TargetInfo::validateOperandSize(StringRef Constraint, default: break; case 'm': // 'Ym' is synonymous with 'y'. + case 'k': return Size <= 64; case 'i': case 't': @@ -3996,6 +4210,20 @@ X86TargetInfo::convertConstraint(const char *&Constraint) const { return std::string("{st}"); case 'u': // second from top of floating point stack. return std::string("{st(1)}"); // second from top of floating point stack. + case 'Y': + switch (Constraint[1]) { + default: + // Break from inner switch and fall through (copy single char), + // continue parsing after copying the current constraint into + // the return string. + break; + case 'k': + // "^" hints llvm that this is a 2 letter constraint. + // "Constraint++" is used to promote the string iterator + // to the next constraint. + return std::string("^") + std::string(Constraint++, 2); + } + LLVM_FALLTHROUGH; default: return std::string(1, *Constraint); } @@ -4055,6 +4283,10 @@ public: return X86TargetInfo::validateOperandSize(Constraint, Size); } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - + Builtin::FirstTSBuiltin + 1); + } }; class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> { @@ -4149,7 +4381,7 @@ public: const TargetOptions &Opts) : WindowsX86_32TargetInfo(Triple, Opts) { LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -4248,7 +4480,7 @@ public: MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : X86_32TargetInfo(Triple, Opts) { LongDoubleWidth = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); resetDataLayout("e-m:e-p:32:32-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32"); WIntType = UnsignedInt; } @@ -4380,6 +4612,7 @@ public: case CC_X86_64Win64: case CC_PreserveMost: case CC_PreserveAll: + case CC_X86RegCall: return CCCR_OK; default: return CCCR_Warning; @@ -4410,6 +4643,10 @@ public: return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize, HasSizeMismatch); } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return llvm::makeArrayRef(BuiltinInfoX86, + X86::LastTSBuiltin - Builtin::FirstTSBuiltin); + } }; // x86-64 Windows target @@ -4447,6 +4684,8 @@ public: case CC_X86VectorCall: case CC_IntelOclBicc: case CC_X86_64SysV: + case CC_Swift: + case CC_X86RegCall: return CCCR_OK; default: return CCCR_Warning; @@ -4461,7 +4700,7 @@ public: const TargetOptions &Opts) : WindowsX86_64TargetInfo(Triple, Opts) { LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -4480,7 +4719,7 @@ public: // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks // with x86 FP ops. Weird. LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; + LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); } void getTargetDefines(const LangOptions &Opts, @@ -4641,8 +4880,10 @@ class ARMTargetInfo : public TargetInfo { DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; const llvm::Triple &T = getTriple(); - // size_t is unsigned long on MachO-derived environments, NetBSD and Bitrig. + // size_t is unsigned long on MachO-derived environments, NetBSD, + // OpenBSD and Bitrig. if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD || + T.getOS() == llvm::Triple::OpenBSD || T.getOS() == llvm::Triple::Bitrig) SizeType = UnsignedLong; else @@ -4650,6 +4891,7 @@ class ARMTargetInfo : public TargetInfo { switch (T.getOS()) { case llvm::Triple::NetBSD: + case llvm::Triple::OpenBSD: WCharType = SignedInt; break; case llvm::Triple::Win32: @@ -4824,6 +5066,8 @@ class ARMTargetInfo : public TargetInfo { return "8M_BASE"; case llvm::ARM::AK_ARMV8MMainline: return "8M_MAIN"; + case llvm::ARM::AK_ARMV8R: + return "8R"; } } @@ -4841,14 +5085,13 @@ class ARMTargetInfo : public TargetInfo { } public: - ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, - bool IsBigEndian) + ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), HW_FP(0) { - BigEndian = IsBigEndian; switch (getTriple().getOS()) { case llvm::Triple::NetBSD: + case llvm::Triple::OpenBSD: PtrDiffType = SignedLong; break; default: @@ -4871,7 +5114,7 @@ public: // the frontend matches that. if (Triple.getEnvironment() == llvm::Triple::EABI || Triple.getOS() == llvm::Triple::UnknownOS || - StringRef(CPU).startswith("cortex-m")) { + ArchProfile == llvm::ARM::PK_M) { setABI("aapcs"); } else if (Triple.isWatchABI()) { setABI("aapcs16"); @@ -4951,7 +5194,7 @@ public: StringRef CPU, const std::vector<std::string> &FeaturesVec) const override { - std::vector<const char*> TargetFeatures; + std::vector<StringRef> TargetFeatures; unsigned Arch = llvm::ARM::parseArch(getTriple().getArchName()); // get default FPU features @@ -4962,9 +5205,9 @@ public: unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch); llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures); - for (const char *Feature : TargetFeatures) + for (auto Feature : TargetFeatures) if (Feature[0] == '+') - Features[Feature+1] = true; + Features[Feature.drop_front(1)] = true; return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -5200,7 +5443,7 @@ public: if (SoftFloat) Builder.defineMacro("__SOFTFP__"); - if (CPU == "xscale") + if (ArchKind == llvm::ARM::AK_XSCALE) Builder.defineMacro("__XSCALE__"); if (isThumb()) { @@ -5232,6 +5475,8 @@ public: Builder.defineMacro("__ARM_VFPV3__"); if (FPU & VFP4FPU) Builder.defineMacro("__ARM_VFPV4__"); + if (FPU & FPARMV8) + Builder.defineMacro("__ARM_FPV5__"); } // This only gets set when Neon instructions are actually available, unlike @@ -5479,13 +5724,15 @@ const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { { #ID, TYPE, ATTRS, nullptr, LANG, nullptr }, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsARM.def" }; class ARMleTargetInfo : public ARMTargetInfo { public: ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : ARMTargetInfo(Triple, Opts, /*BigEndian=*/false) {} + : ARMTargetInfo(Triple, Opts) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__ARMEL__"); @@ -5496,7 +5743,7 @@ public: class ARMbeTargetInfo : public ARMTargetInfo { public: ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : ARMTargetInfo(Triple, Opts, /*BigEndian=*/true) {} + : ARMTargetInfo(Triple, Opts) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__ARMEB__"); @@ -5697,7 +5944,7 @@ public: MaxAtomicPromoteWidth = 128; LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); // {} in inline assembly are neon specifiers, not assembly variant // specifiers. @@ -5728,16 +5975,9 @@ public: } bool setCPU(const std::string &Name) override { - bool CPUKnown = llvm::StringSwitch<bool>(Name) - .Case("generic", true) - .Cases("cortex-a53", "cortex-a57", "cortex-a72", - "cortex-a35", "exynos-m1", true) - .Case("cortex-a73", true) - .Case("cyclone", true) - .Case("kryo", true) - .Case("vulcan", true) - .Default(false); - return CPUKnown; + return Name == "generic" || + llvm::AArch64::parseCPUArch(Name) != + static_cast<unsigned>(llvm::AArch64::ArchKind::AK_INVALID); } void getTargetDefines(const LangOptions &Opts, @@ -6014,7 +6254,6 @@ class AArch64leTargetInfo : public AArch64TargetInfo { public: AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : AArch64TargetInfo(Triple, Opts) { - BigEndian = false; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -6064,7 +6303,7 @@ public: UseSignedCharForObjCBool = false; LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); TheCXXABI.set(TargetCXXABI::iOS64); } @@ -6081,11 +6320,11 @@ class HexagonTargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; bool HasHVX, HasHVXDouble; + bool UseLongCalls; public: HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; // Specify the vector alignment explicitly. For v512x1, the calculated // alignment would be 512*alignment(i1), which is 512 bytes, instead of // the required minimum of 64 bytes. @@ -6105,6 +6344,7 @@ public: UseBitFieldTypeAlignment = true; ZeroLengthBitfieldBoundary = 32; HasHVX = HasHVXDouble = false; + UseLongCalls = false; } ArrayRef<Builtin::Info> getTargetBuiltins() const override { @@ -6139,6 +6379,7 @@ public: .Case("hexagon", true) .Case("hvx", HasHVX) .Case("hvx-double", HasHVXDouble) + .Case("long-calls", UseLongCalls) .Default(false); } @@ -6149,6 +6390,9 @@ public: bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; + void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, + bool Enabled) const override; + BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } @@ -6217,6 +6461,17 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, } } +bool HexagonTargetInfo::initFeatureMap(llvm::StringMap<bool> &Features, + DiagnosticsEngine &Diags, StringRef CPU, + const std::vector<std::string> &FeaturesVec) const { + // Default for v60: -hvx, -hvx-double. + Features["hvx"] = false; + Features["hvx-double"] = false; + Features["long-calls"] = false; + + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); +} + bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) { for (auto &F : Features) { @@ -6228,21 +6483,27 @@ bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasHVX = HasHVXDouble = true; else if (F == "-hvx-double") HasHVXDouble = false; + + if (F == "+long-calls") + UseLongCalls = true; + else if (F == "-long-calls") + UseLongCalls = false; } return true; } -bool HexagonTargetInfo::initFeatureMap(llvm::StringMap<bool> &Features, - DiagnosticsEngine &Diags, StringRef CPU, - const std::vector<std::string> &FeaturesVec) const { - // Default for v60: -hvx, -hvx-double. - Features["hvx"] = false; - Features["hvx-double"] = false; - - return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); +void HexagonTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, bool Enabled) const { + if (Enabled) { + if (Name == "hvx-double") + Features["hvx"] = true; + } else { + if (Name == "hvx") + Features["hvx-double"] = false; + } + Features[Name] = Enabled; } - const char *const HexagonTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -6472,8 +6733,9 @@ public: CK_NIAGARA2, CK_NIAGARA3, CK_NIAGARA4, - CK_MYRIAD2_1, - CK_MYRIAD2_2, + CK_MYRIAD2100, + CK_MYRIAD2150, + CK_MYRIAD2450, CK_LEON2, CK_LEON2_AT697E, CK_LEON2_AT697F, @@ -6500,8 +6762,9 @@ public: case CK_SPARCLITE86X: case CK_SPARCLET: case CK_TSC701: - case CK_MYRIAD2_1: - case CK_MYRIAD2_2: + case CK_MYRIAD2100: + case CK_MYRIAD2150: + case CK_MYRIAD2450: case CK_LEON2: case CK_LEON2_AT697E: case CK_LEON2_AT697F: @@ -6540,9 +6803,14 @@ public: .Case("niagara2", CK_NIAGARA2) .Case("niagara3", CK_NIAGARA3) .Case("niagara4", CK_NIAGARA4) - .Case("myriad2", CK_MYRIAD2_1) - .Case("myriad2.1", CK_MYRIAD2_1) - .Case("myriad2.2", CK_MYRIAD2_2) + .Case("ma2100", CK_MYRIAD2100) + .Case("ma2150", CK_MYRIAD2150) + .Case("ma2450", CK_MYRIAD2450) + // FIXME: the myriad2[.n] spellings are obsolete, + // but a grace period is needed to allow updating dependent builds. + .Case("myriad2", CK_MYRIAD2100) + .Case("myriad2.1", CK_MYRIAD2100) + .Case("myriad2.2", CK_MYRIAD2150) .Case("leon2", CK_LEON2) .Case("at697e", CK_LEON2_AT697E) .Case("at697f", CK_LEON2_AT697F) @@ -6630,7 +6898,10 @@ public: PtrDiffType = SignedLong; break; } - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + // Up to 32 bits are lock-free atomic, but we're willing to do atomic ops + // on up to 64 bits. + MaxAtomicPromoteWidth = 64; + MaxAtomicInlineWidth = 32; } void getTargetDefines(const LangOptions &Opts, @@ -6651,18 +6922,27 @@ public: break; } if (getTriple().getVendor() == llvm::Triple::Myriad) { + std::string MyriadArchValue, Myriad2Value; + Builder.defineMacro("__sparc_v8__"); + Builder.defineMacro("__leon__"); switch (CPU) { - case CK_MYRIAD2_1: - Builder.defineMacro("__myriad2", "1"); - Builder.defineMacro("__myriad2__", "1"); + case CK_MYRIAD2150: + MyriadArchValue = "__ma2150"; + Myriad2Value = "2"; break; - case CK_MYRIAD2_2: - Builder.defineMacro("__myriad2", "2"); - Builder.defineMacro("__myriad2__", "2"); + case CK_MYRIAD2450: + MyriadArchValue = "__ma2450"; + Myriad2Value = "2"; break; default: + MyriadArchValue = "__ma2100"; + Myriad2Value = "1"; break; } + Builder.defineMacro(MyriadArchValue, "1"); + Builder.defineMacro(MyriadArchValue+"__", "1"); + Builder.defineMacro("__myriad2__", Myriad2Value); + Builder.defineMacro("__myriad2", Myriad2Value); } } @@ -6677,7 +6957,6 @@ class SparcV8elTargetInfo : public SparcV8TargetInfo { SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : SparcV8TargetInfo(Triple, Opts) { resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64"); - BigEndian = false; } }; @@ -6702,7 +6981,7 @@ public: // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned. LongDoubleWidth = 128; LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } @@ -6745,7 +7024,7 @@ public: PointerWidth = PointerAlign = 64; LongDoubleWidth = 128; LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); DefaultAlignForAttributeAligned = 64; MinGlobalAlign = 16; resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); @@ -6791,9 +7070,13 @@ public: CPU = Name; bool CPUKnown = llvm::StringSwitch<bool>(Name) .Case("z10", true) + .Case("arch8", true) .Case("z196", true) + .Case("arch9", true) .Case("zEC12", true) + .Case("arch10", true) .Case("z13", true) + .Case("arch11", true) .Default(false); return CPUKnown; @@ -6802,9 +7085,9 @@ public: initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const override { - if (CPU == "zEC12") + if (CPU == "zEC12" || CPU == "arch10") Features["transactional-execution"] = true; - if (CPU == "z13") { + if (CPU == "z13" || CPU == "arch11") { Features["transactional-execution"] = true; Features["vector"] = true; } @@ -6912,7 +7195,6 @@ class MSP430TargetInfo : public TargetInfo { public: MSP430TargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; TLSSupported = false; IntWidth = 16; IntAlign = 16; @@ -7018,11 +7300,14 @@ public: DoubleAlign = 32; LongDoubleWidth = 32; LongDoubleAlign = 32; - FloatFormat = &llvm::APFloat::IEEEsingle; - DoubleFormat = &llvm::APFloat::IEEEsingle; - LongDoubleFormat = &llvm::APFloat::IEEEsingle; - resetDataLayout("E-p:32:32-i8:8:32-i16:16:32-i64:32" - "-f64:32-v64:32-v128:32-a:0:32-n32"); + FloatFormat = &llvm::APFloat::IEEEsingle(); + DoubleFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleFormat = &llvm::APFloat::IEEEsingle(); + resetDataLayout("E-p:32:32:32-i1:8:8-i8:8:32-" + "i16:16:32-i32:32:32-i64:32:32-" + "f32:32:32-f64:32:32-v64:32:32-" + "v128:32:32-v256:32:32-v512:32:32-" + "v1024:32:32-a0:0:32-n32"); AddrSpaceMap = &TCEOpenCLAddrSpaceMap; UseAddrSpaceMapMangling = true; } @@ -7050,6 +7335,31 @@ public: } }; +class TCELETargetInfo : public TCETargetInfo { +public: + TCELETargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : TCETargetInfo(Triple, Opts) { + BigEndian = false; + + resetDataLayout("e-p:32:32:32-i1:8:8-i8:8:32-" + "i16:16:32-i32:32:32-i64:32:32-" + "f32:32:32-f64:32:32-v64:32:32-" + "v128:32:32-v256:32:32-v512:32:32-" + "v1024:32:32-a0:0:32-n32"); + + } + + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "tcele", Opts); + Builder.defineMacro("__TCE__"); + Builder.defineMacro("__TCE_V1__"); + Builder.defineMacro("__TCELE__"); + Builder.defineMacro("__TCELE_V1__"); + } + +}; + class BPFTargetInfo : public TargetInfo { public: BPFTargetInfo(const llvm::Triple &Triple, const TargetOptions &) @@ -7062,10 +7372,8 @@ public: Int64Type = SignedLong; RegParmMax = 5; if (Triple.getArch() == llvm::Triple::bpfeb) { - BigEndian = true; resetDataLayout("E-m:e-p:64:64-i64:64-n32:64-S128"); } else { - BigEndian = false; resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); } MaxAtomicPromoteWidth = 64; @@ -7144,8 +7452,6 @@ public: IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat), DspRev(NoDSP), HasMSA(false), HasFP64(false) { TheCXXABI.set(TargetCXXABI::GenericMIPS); - BigEndian = getTriple().getArch() == llvm::Triple::mips || - getTriple().getArch() == llvm::Triple::mips64; setABI((getTriple().getArch() == llvm::Triple::mips || getTriple().getArch() == llvm::Triple::mipsel) @@ -7206,7 +7512,7 @@ public: void setO32ABITypes() { Int64Type = SignedLongLong; IntMaxType = Int64Type; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); LongDoubleWidth = LongDoubleAlign = 64; LongWidth = LongAlign = 32; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; @@ -7218,10 +7524,10 @@ public: void setN32N64ABITypes() { LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); if (getTriple().getOS() == llvm::Triple::FreeBSD) { LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; SuitableAlign = 128; @@ -7648,7 +7954,6 @@ class PNaClTargetInfo : public TargetInfo { public: PNaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple) { - BigEndian = false; this->LongAlign = 32; this->LongWidth = 32; this->PointerAlign = 32; @@ -7716,7 +8021,6 @@ class Le64TargetInfo : public TargetInfo { public: Le64TargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; NoAsmVariants = true; LongWidth = LongAlign = PointerWidth = PointerAlign = 64; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; @@ -7762,7 +8066,6 @@ class WebAssemblyTargetInfo : public TargetInfo { public: explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &) : TargetInfo(T), SIMDLevel(NoSIMD) { - BigEndian = false; NoAsmVariants = true; SuitableAlign = 128; LargeArrayMinWidth = 128; @@ -7770,7 +8073,10 @@ public: SimdDefaultAlign = 128; SigAtomicType = SignedLong; LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; } protected: @@ -7889,6 +8195,9 @@ public: LongAlign = LongWidth = 64; PointerAlign = PointerWidth = 64; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + SizeType = UnsignedLong; + PtrDiffType = SignedLong; + IntPtrType = SignedLong; resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); } @@ -7923,7 +8232,6 @@ public: "SPIR target must use unknown OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && "SPIR target must use unknown environment type"); - BigEndian = false; TLSSupported = false; LongWidth = LongAlign = 64; AddrSpaceMap = &SPIRAddrSpaceMap; @@ -7966,7 +8274,7 @@ public: void setSupportedOpenCLOpts() override { // Assume all OpenCL extensions and optional core features are supported // for SPIR since it is a generic target. - getSupportedOpenCLOpts().setAll(); + getSupportedOpenCLOpts().supportAll(); } }; @@ -8007,7 +8315,6 @@ class XCoreTargetInfo : public TargetInfo { public: XCoreTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; NoAsmVariants = true; LongLongAlign = 32; SuitableAlign = 32; @@ -8073,7 +8380,7 @@ public: : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) { SuitableAlign = 32; LongDoubleWidth = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } }; @@ -8082,7 +8389,7 @@ class AndroidX86_64TargetInfo : public LinuxTargetInfo<X86_64TargetInfo> { public: AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) { - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); } bool useFloat128ManglingForLongDouble() const override { @@ -8099,6 +8406,7 @@ public: Triple.getOSName(), Triple.getEnvironmentName()), Opts) { + IsRenderScriptTarget = true; LongWidth = LongAlign = 64; } void getTargetDefines(const LangOptions &Opts, @@ -8116,7 +8424,9 @@ public: : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), Triple.getOSName(), Triple.getEnvironmentName()), - Opts) {} + Opts) { + IsRenderScriptTarget = true; + } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -8125,6 +8435,107 @@ public: } }; + +// AVR Target +class AVRTargetInfo : public TargetInfo { +public: + AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + TLSSupported = false; + PointerWidth = 16; + PointerAlign = 8; + IntWidth = 16; + IntAlign = 8; + LongWidth = 32; + LongAlign = 8; + LongLongWidth = 64; + LongLongAlign = 8; + SuitableAlign = 8; + DefaultAlignForAttributeAligned = 8; + HalfWidth = 16; + HalfAlign = 8; + FloatWidth = 32; + FloatAlign = 8; + DoubleWidth = 32; + DoubleAlign = 8; + DoubleFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleWidth = 32; + LongDoubleAlign = 8; + LongDoubleFormat = &llvm::APFloat::IEEEsingle(); + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; + Char16Type = UnsignedInt; + WCharType = SignedInt; + WIntType = SignedInt; + Char32Type = UnsignedLong; + SigAtomicType = SignedChar; + resetDataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + "-f32:32:32-f64:64:64-n8"); + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { + Builder.defineMacro("__AVR__"); + } + + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return None; + } + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + + const char *getClobbers() const override { + return ""; + } + + ArrayRef<const char *> getGCCRegNames() const override { + static const char * const GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "X", "Y", "Z", "SP" + }; + return llvm::makeArrayRef(GCCRegNames); + } + + ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { + return None; + } + + ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override { + static const TargetInfo::AddlRegName AddlRegNames[] = { + { { "r26", "r27"}, 26 }, + { { "r28", "r29"}, 27 }, + { { "r30", "r31"}, 28 }, + { { "SPL", "SPH"}, 29 }, + }; + return llvm::makeArrayRef(AddlRegNames); + } + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override { + return false; + } + + IntType getIntTypeByWidth(unsigned BitWidth, + bool IsSigned) const final { + // AVR prefers int for 16-bit integers. + return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt) + : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned); + } + + IntType getLeastIntTypeByWidth(unsigned BitWidth, + bool IsSigned) const final { + // AVR uses int for int_least16_t and int_fast16_t. + return BitWidth == 16 + ? (IsSigned ? SignedInt : UnsignedInt) + : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); + } +}; + } // end anonymous namespace //===----------------------------------------------------------------------===// @@ -8157,6 +8568,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::Linux: return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: @@ -8169,6 +8582,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, switch (os) { case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<AArch64beTargetInfo>(Triple, Opts); case llvm::Triple::Linux: return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: @@ -8189,6 +8604,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: @@ -8225,6 +8642,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: @@ -8239,6 +8658,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new ARMbeTargetInfo(Triple, Opts); } + case llvm::Triple::avr: + return new AVRTargetInfo(Triple, Opts); case llvm::Triple::bpfeb: case llvm::Triple::bpfel: return new BPFTargetInfo(Triple, Opts); @@ -8364,9 +8785,9 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, } case llvm::Triple::nvptx: - return new NVPTX32TargetInfo(Triple, Opts); + return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32); case llvm::Triple::nvptx64: - return new NVPTX64TargetInfo(Triple, Opts); + return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64); case llvm::Triple::amdgcn: case llvm::Triple::r600: @@ -8430,6 +8851,9 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::tce: return new TCETargetInfo(Triple, Opts); + case llvm::Triple::tcele: + return new TCELETargetInfo(Triple, Opts); + case llvm::Triple::x86: if (Triple.isOSDarwin()) return new DarwinI386TargetInfo(Triple, Opts); @@ -8455,6 +8879,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new BitrigI386TargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::KFreeBSD: return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Minix: @@ -8510,6 +8936,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new BitrigX86_64TargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::KFreeBSD: return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::Solaris: @@ -8612,6 +9040,7 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, return nullptr; Target->setSupportedOpenCLOpts(); + Target->setOpenCLExtensionOpts(); if (!Target->validateTarget(Diags)) return nullptr; diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp index 4fa52b4..97e75a9 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_391/final/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_400/final/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/VirtualFileSystem.cpp b/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp index 8ace2b3..50fcb22 100644 --- a/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp @@ -47,7 +47,7 @@ Status::Status(const file_status &Status) User(Status.getUser()), Group(Status.getGroup()), Size(Status.getSize()), Type(Status.type()), Perms(Status.permissions()), IsVFSMapped(false) {} -Status::Status(StringRef Name, UniqueID UID, sys::TimeValue MTime, +Status::Status(StringRef Name, UniqueID UID, sys::TimePoint<> MTime, uint32_t User, uint32_t Group, uint64_t Size, file_type Type, perms Perms) : Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size), @@ -494,8 +494,8 @@ public: InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths) : Root(new detail::InMemoryDirectory( - Status("", getNextVirtualUniqueID(), llvm::sys::TimeValue::MinTime(), - 0, 0, 0, llvm::sys::fs::file_type::directory_file, + Status("", getNextVirtualUniqueID(), llvm::sys::TimePoint<>(), 0, 0, + 0, llvm::sys::fs::file_type::directory_file, llvm::sys::fs::perms::all_all))), UseNormalizedPaths(UseNormalizedPaths) {} @@ -532,7 +532,7 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, // End of the path, create a new file. // FIXME: expose the status details in the interface. Status Stat(P.str(), getNextVirtualUniqueID(), - llvm::sys::TimeValue(ModificationTime, 0), 0, 0, + llvm::sys::toTimePoint(ModificationTime), 0, 0, Buffer->getBufferSize(), llvm::sys::fs::file_type::regular_file, llvm::sys::fs::all_all); @@ -545,9 +545,9 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, // FIXME: expose the status details in the interface. Status Stat( StringRef(Path.str().begin(), Name.end() - Path.str().begin()), - getNextVirtualUniqueID(), llvm::sys::TimeValue(ModificationTime, 0), - 0, 0, Buffer->getBufferSize(), - llvm::sys::fs::file_type::directory_file, llvm::sys::fs::all_all); + getNextVirtualUniqueID(), llvm::sys::toTimePoint(ModificationTime), 0, + 0, Buffer->getBufferSize(), llvm::sys::fs::file_type::directory_file, + llvm::sys::fs::all_all); Dir = cast<detail::InMemoryDirectory>(Dir->addChild( Name, llvm::make_unique<detail::InMemoryDirectory>(std::move(Stat)))); continue; @@ -801,6 +801,7 @@ public: /// 'case-sensitive': <boolean, default=true> /// 'use-external-names': <boolean, default=true> /// 'overlay-relative': <boolean, default=false> +/// 'ignore-non-existent-contents': <boolean, default=true> /// /// Virtual directories are represented as /// \verbatim @@ -860,6 +861,14 @@ class RedirectingFileSystem : public vfs::FileSystem { /// \brief Whether to use to use the value of 'external-contents' for the /// names of files. This global value is overridable on a per-file basis. bool UseExternalNames = true; + + /// \brief Whether an invalid path obtained via 'external-contents' should + /// cause iteration on the VFS to stop. If 'true', the VFS should ignore + /// the entry and continue with the next. Allows YAML files to be shared + /// across multiple compiler invocations regardless of prior existent + /// paths in 'external-contents'. This global value is overridable on a + /// per-file basis. + bool IgnoreNonExistentContents = true; /// @} /// Virtual file paths and external files could be canonicalized without "..", @@ -878,9 +887,6 @@ private: RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS) : ExternalFS(std::move(ExternalFS)) {} - /// \brief Looks up \p Path in \c Roots. - ErrorOr<Entry *> lookupPath(const Twine &Path); - /// \brief Looks up the path <tt>[Start, End)</tt> in \p From, possibly /// recursing into the contents of \p From if it is a directory. ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start, @@ -890,6 +896,9 @@ private: ErrorOr<Status> status(const Twine &Path, Entry *E); public: + /// \brief Looks up \p Path in \c Roots. + ErrorOr<Entry *> lookupPath(const Twine &Path); + /// \brief Parses \p Buffer, which is expected to be in YAML format and /// returns a virtual file system representing its contents. static RedirectingFileSystem * @@ -937,6 +946,10 @@ public: return ExternalContentsPrefixDir; } + bool ignoreNonExistentContents() const { + return IgnoreNonExistentContents; + } + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void dump() const { for (const std::unique_ptr<Entry> &Root : Roots) @@ -1060,8 +1073,9 @@ class RedirectingFileSystemParser { // ... or create a new one std::unique_ptr<Entry> E = llvm::make_unique<RedirectingDirectoryEntry>( - Name, Status("", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0, - 0, file_type::directory_file, sys::fs::all_all)); + Name, + Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), + 0, 0, 0, file_type::directory_file, sys::fs::all_all)); if (!ParentEntry) { // Add a new root to the overlay FS->Roots.push_back(std::move(E)); @@ -1262,8 +1276,8 @@ class RedirectingFileSystemParser { case EK_Directory: Result = llvm::make_unique<RedirectingDirectoryEntry>( LastComponent, std::move(EntryArrayContents), - Status("", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0, 0, - file_type::directory_file, sys::fs::all_all)); + Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), + 0, 0, 0, file_type::directory_file, sys::fs::all_all)); break; } @@ -1279,8 +1293,8 @@ class RedirectingFileSystemParser { Entries.push_back(std::move(Result)); Result = llvm::make_unique<RedirectingDirectoryEntry>( *I, std::move(Entries), - Status("", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0, 0, - file_type::directory_file, sys::fs::all_all)); + Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), + 0, 0, 0, file_type::directory_file, sys::fs::all_all)); } return Result; } @@ -1301,6 +1315,7 @@ public: KeyStatusPair("case-sensitive", false), KeyStatusPair("use-external-names", false), KeyStatusPair("overlay-relative", false), + KeyStatusPair("ignore-non-existent-contents", false), KeyStatusPair("roots", true), }; @@ -1359,6 +1374,9 @@ public: } else if (Key == "use-external-names") { if (!parseScalarBool(I->getValue(), FS->UseExternalNames)) return false; + } else if (Key == "ignore-non-existent-contents") { + if (!parseScalarBool(I->getValue(), FS->IgnoreNonExistentContents)) + return false; } else { llvm_unreachable("key missing from Keys"); } @@ -1588,6 +1606,47 @@ vfs::getVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer, std::move(ExternalFS)); } +static void getVFSEntries(Entry *SrcE, SmallVectorImpl<StringRef> &Path, + SmallVectorImpl<YAMLVFSEntry> &Entries) { + auto Kind = SrcE->getKind(); + if (Kind == EK_Directory) { + auto *DE = dyn_cast<RedirectingDirectoryEntry>(SrcE); + assert(DE && "Must be a directory"); + for (std::unique_ptr<Entry> &SubEntry : + llvm::make_range(DE->contents_begin(), DE->contents_end())) { + Path.push_back(SubEntry->getName()); + getVFSEntries(SubEntry.get(), Path, Entries); + Path.pop_back(); + } + return; + } + + assert(Kind == EK_File && "Must be a EK_File"); + auto *FE = dyn_cast<RedirectingFileEntry>(SrcE); + assert(FE && "Must be a file"); + SmallString<128> VPath; + for (auto &Comp : Path) + llvm::sys::path::append(VPath, Comp); + Entries.push_back(YAMLVFSEntry(VPath.c_str(), FE->getExternalContentsPath())); +} + +void vfs::collectVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer, + SourceMgr::DiagHandlerTy DiagHandler, + StringRef YAMLFilePath, + SmallVectorImpl<YAMLVFSEntry> &CollectedEntries, + void *DiagContext, + IntrusiveRefCntPtr<FileSystem> ExternalFS) { + RedirectingFileSystem *VFS = RedirectingFileSystem::create( + std::move(Buffer), DiagHandler, YAMLFilePath, DiagContext, + std::move(ExternalFS)); + ErrorOr<Entry *> RootE = VFS->lookupPath("/"); + if (!RootE) + return; + SmallVector<StringRef, 8> Components; + Components.push_back("/"); + getVFSEntries(*RootE, Components, CollectedEntries); +} + UniqueID vfs::getNextVirtualUniqueID() { static std::atomic<unsigned> UID; unsigned ID = ++UID; @@ -1619,7 +1678,7 @@ public: JSONWriter(llvm::raw_ostream &OS) : OS(OS) {} void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> UseExternalNames, Optional<bool> IsCaseSensitive, Optional<bool> IsOverlayRelative, - StringRef OverlayDir); + Optional<bool> IgnoreNonExistentContents, StringRef OverlayDir); }; } @@ -1675,6 +1734,7 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> UseExternalNames, Optional<bool> IsCaseSensitive, Optional<bool> IsOverlayRelative, + Optional<bool> IgnoreNonExistentContents, StringRef OverlayDir) { using namespace llvm::sys; @@ -1692,6 +1752,9 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, OS << " 'overlay-relative': '" << (UseOverlayRelative ? "true" : "false") << "',\n"; } + if (IgnoreNonExistentContents.hasValue()) + OS << " 'ignore-non-existent-contents': '" + << (IgnoreNonExistentContents.getValue() ? "true" : "false") << "',\n"; OS << " 'roots': [\n"; if (!Entries.empty()) { @@ -1748,7 +1811,8 @@ void YAMLVFSWriter::write(llvm::raw_ostream &OS) { }); JSONWriter(OS).write(Mappings, UseExternalNames, IsCaseSensitive, - IsOverlayRelative, OverlayDir); + IsOverlayRelative, IgnoreNonExistentContents, + OverlayDir); } VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl( @@ -1756,29 +1820,47 @@ VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl( RedirectingDirectoryEntry::iterator Begin, RedirectingDirectoryEntry::iterator End, std::error_code &EC) : Dir(_Path.str()), FS(FS), Current(Begin), End(End) { - if (Current != End) { + while (Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); llvm::ErrorOr<vfs::Status> S = FS.status(PathStr); - if (S) + if (S) { CurrentEntry = *S; - else + return; + } + // Skip entries which do not map to a reliable external content. + if (FS.ignoreNonExistentContents() && + S.getError() == llvm::errc::no_such_file_or_directory) { + ++Current; + continue; + } else { EC = S.getError(); + break; + } } } std::error_code VFSFromYamlDirIterImpl::increment() { assert(Current != End && "cannot iterate past end"); - if (++Current != End) { + while (++Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); llvm::ErrorOr<vfs::Status> S = FS.status(PathStr); - if (!S) - return S.getError(); + if (!S) { + // Skip entries which do not map to a reliable external content. + if (FS.ignoreNonExistentContents() && + S.getError() == llvm::errc::no_such_file_or_directory) { + continue; + } else { + return S.getError(); + } + } CurrentEntry = *S; - } else { - CurrentEntry = Status(); + break; } + + if (Current == End) + CurrentEntry = Status(); return std::error_code(); } |