aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Basic
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Basic')
-rw-r--r--lib/Basic/Attributes.cpp75
-rw-r--r--lib/Basic/FileManager.cpp257
-rw-r--r--lib/Basic/IdentifierTable.cpp15
-rw-r--r--lib/Basic/LangStandards.cpp45
-rw-r--r--lib/Basic/Module.cpp4
-rw-r--r--lib/Basic/OpenMPKinds.cpp85
-rw-r--r--lib/Basic/SourceManager.cpp203
-rw-r--r--lib/Basic/Stack.cpp75
-rw-r--r--lib/Basic/TargetInfo.cpp6
-rw-r--r--lib/Basic/Targets.cpp23
-rw-r--r--lib/Basic/Targets/AArch64.cpp32
-rw-r--r--lib/Basic/Targets/AArch64.h1
-rw-r--r--lib/Basic/Targets/AMDGPU.cpp8
-rw-r--r--lib/Basic/Targets/ARM.cpp103
-rw-r--r--lib/Basic/Targets/BPF.cpp12
-rw-r--r--lib/Basic/Targets/BPF.h4
-rw-r--r--lib/Basic/Targets/OSTargets.h15
-rw-r--r--lib/Basic/Targets/PPC.cpp10
-rw-r--r--lib/Basic/Targets/PPC.h1
-rw-r--r--lib/Basic/Targets/RISCV.cpp63
-rw-r--r--lib/Basic/Targets/RISCV.h20
-rw-r--r--lib/Basic/Targets/SPIR.h2
-rw-r--r--lib/Basic/Targets/Sparc.h1
-rw-r--r--lib/Basic/Targets/SystemZ.cpp2
-rw-r--r--lib/Basic/Targets/X86.cpp20
-rw-r--r--lib/Basic/Targets/X86.h39
-rw-r--r--lib/Basic/TokenKinds.cpp20
27 files changed, 814 insertions, 327 deletions
diff --git a/lib/Basic/Attributes.cpp b/lib/Basic/Attributes.cpp
index 9a8eb3d932cc..74cc3d1d03da 100644
--- a/lib/Basic/Attributes.cpp
+++ b/lib/Basic/Attributes.cpp
@@ -1,5 +1,6 @@
#include "clang/Basic/Attributes.h"
#include "clang/Basic/AttrSubjectMatchRules.h"
+#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/StringSwitch.h"
using namespace clang;
@@ -21,7 +22,7 @@ int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
#include "clang/Basic/AttrHasAttributeImpl.inc"
- return 0;
+ return 0;
}
const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
@@ -33,3 +34,75 @@ const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
}
llvm_unreachable("Invalid subject match rule");
}
+
+static StringRef
+normalizeAttrScopeName(StringRef ScopeName,
+ AttributeCommonInfo::Syntax SyntaxUsed) {
+ // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
+ // to be "clang".
+ if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
+ SyntaxUsed == AttributeCommonInfo::AS_C2x) {
+ if (ScopeName == "__gnu__")
+ ScopeName = "gnu";
+ else if (ScopeName == "_Clang")
+ ScopeName = "clang";
+ }
+ return ScopeName;
+}
+
+static StringRef normalizeAttrName(StringRef AttrName,
+ StringRef NormalizedScopeName,
+ AttributeCommonInfo::Syntax SyntaxUsed) {
+ // Normalize the attribute name, __foo__ becomes foo. This is only allowable
+ // for GNU attributes, and attributes using the double square bracket syntax.
+ bool ShouldNormalize =
+ SyntaxUsed == AttributeCommonInfo::AS_GNU ||
+ ((SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
+ SyntaxUsed == AttributeCommonInfo::AS_C2x) &&
+ (NormalizedScopeName.empty() || NormalizedScopeName == "gnu" ||
+ NormalizedScopeName == "clang"));
+ if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") &&
+ AttrName.endswith("__"))
+ AttrName = AttrName.slice(2, AttrName.size() - 2);
+
+ return AttrName;
+}
+
+bool AttributeCommonInfo::isGNUScope() const {
+ return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"));
+}
+
+#include "clang/Sema/AttrParsedAttrKinds.inc"
+
+AttributeCommonInfo::Kind
+AttributeCommonInfo::getParsedKind(const IdentifierInfo *Name,
+ const IdentifierInfo *ScopeName,
+ Syntax SyntaxUsed) {
+ StringRef AttrName = Name->getName();
+
+ SmallString<64> FullName;
+ if (ScopeName)
+ FullName += normalizeAttrScopeName(ScopeName->getName(), SyntaxUsed);
+
+ AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
+
+ // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
+ // unscoped.
+ if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
+ FullName += "::";
+ FullName += AttrName;
+
+ return ::getAttrKind(FullName, SyntaxUsed);
+}
+
+unsigned AttributeCommonInfo::calculateAttributeSpellingListIndex() const {
+ // Both variables will be used in tablegen generated
+ // attribute spell list index matching code.
+ auto Syntax = static_cast<AttributeCommonInfo::Syntax>(getSyntax());
+ StringRef Scope =
+ getScopeName() ? normalizeAttrScopeName(getScopeName()->getName(), Syntax)
+ : "";
+ StringRef Name = normalizeAttrName(getAttrName()->getName(), Scope, Syntax);
+
+#include "clang/Sema/AttrSpellingListIndex.inc"
+}
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index b6a7fde09f35..88a7a1250837 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -18,9 +18,10 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemStatCache.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Config/llvm-config.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
@@ -35,6 +36,14 @@
using namespace clang;
+#define DEBUG_TYPE "file-search"
+
+ALWAYS_ENABLED_STATISTIC(NumDirLookups, "Number of directory lookups.");
+ALWAYS_ENABLED_STATISTIC(NumFileLookups, "Number of file lookups.");
+ALWAYS_ENABLED_STATISTIC(NumDirCacheMisses,
+ "Number of directory cache misses.");
+ALWAYS_ENABLED_STATISTIC(NumFileCacheMisses, "Number of file cache misses.");
+
//===----------------------------------------------------------------------===//
// Common logic.
//===----------------------------------------------------------------------===//
@@ -43,9 +52,6 @@ FileManager::FileManager(const FileSystemOptions &FSO,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
: FS(std::move(FS)), FileSystemOpts(FSO), SeenDirEntries(64),
SeenFileEntries(64), NextFileUID(0) {
- NumDirLookups = NumFileLookups = 0;
- NumDirCacheMisses = NumFileCacheMisses = 0;
-
// If the caller doesn't provide a virtual file system, just grab the real
// file system.
if (!this->FS)
@@ -63,14 +69,14 @@ void FileManager::clearStatCache() { StatCache.reset(); }
/// Retrieve the directory that the given file name resides in.
/// Filename can point to either a real file or a virtual file.
-static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
- StringRef Filename,
- bool CacheFailure) {
+static llvm::ErrorOr<const DirectoryEntry *>
+getDirectoryFromFile(FileManager &FileMgr, StringRef Filename,
+ bool CacheFailure) {
if (Filename.empty())
- return nullptr;
+ return std::errc::no_such_file_or_directory;
if (llvm::sys::path::is_separator(Filename[Filename.size() - 1]))
- return nullptr; // If Filename is a directory.
+ return std::errc::is_a_directory;
StringRef DirName = llvm::sys::path::parent_path(Filename);
// Use the current directory if file has no path component.
@@ -87,7 +93,8 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) {
if (DirName.empty())
DirName = ".";
- auto &NamedDirEnt = *SeenDirEntries.insert({DirName, nullptr}).first;
+ auto &NamedDirEnt = *SeenDirEntries.insert(
+ {DirName, std::errc::no_such_file_or_directory}).first;
// When caching a virtual directory, we always cache its ancestors
// at the same time. Therefore, if DirName is already in the cache,
@@ -97,17 +104,17 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) {
return;
// Add the virtual directory to the cache.
- auto UDE = llvm::make_unique<DirectoryEntry>();
+ auto UDE = std::make_unique<DirectoryEntry>();
UDE->Name = NamedDirEnt.first();
- NamedDirEnt.second = UDE.get();
+ NamedDirEnt.second = *UDE.get();
VirtualDirectoryEntries.push_back(std::move(UDE));
// Recursively add the other ancestors.
addAncestorsAsVirtualDirs(DirName);
}
-const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
- bool CacheFailure) {
+llvm::Expected<DirectoryEntryRef>
+FileManager::getDirectoryRef(StringRef DirName, bool CacheFailure) {
// stat doesn't like trailing separators except for root directory.
// At least, on Win32 MSVCRT, stat() cannot strip trailing '/'.
// (though it can strip '\\')
@@ -130,9 +137,13 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
// See if there was already an entry in the map. Note that the map
// contains both virtual and real directories.
- auto SeenDirInsertResult = SeenDirEntries.insert({DirName, nullptr});
- if (!SeenDirInsertResult.second)
- return SeenDirInsertResult.first->second;
+ auto SeenDirInsertResult =
+ SeenDirEntries.insert({DirName, std::errc::no_such_file_or_directory});
+ if (!SeenDirInsertResult.second) {
+ if (SeenDirInsertResult.first->second)
+ return DirectoryEntryRef(&*SeenDirInsertResult.first);
+ return llvm::errorCodeToError(SeenDirInsertResult.first->second.getError());
+ }
// We've not seen this before. Fill it in.
++NumDirCacheMisses;
@@ -145,11 +156,15 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
// Check to see if the directory exists.
llvm::vfs::Status Status;
- if (getStatValue(InterndDirName, Status, false, nullptr /*directory lookup*/)) {
+ auto statError = getStatValue(InterndDirName, Status, false,
+ nullptr /*directory lookup*/);
+ if (statError) {
// There's no real directory at the given path.
- if (!CacheFailure)
+ if (CacheFailure)
+ NamedDirEnt.second = statError;
+ else
SeenDirEntries.erase(DirName);
- return nullptr;
+ return llvm::errorCodeToError(statError);
}
// It exists. See if we have already opened a directory with the
@@ -158,24 +173,51 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
// Windows).
DirectoryEntry &UDE = UniqueRealDirs[Status.getUniqueID()];
- NamedDirEnt.second = &UDE;
+ NamedDirEnt.second = UDE;
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;
}
- return &UDE;
+ return DirectoryEntryRef(&NamedDirEnt);
+}
+
+llvm::ErrorOr<const DirectoryEntry *>
+FileManager::getDirectory(StringRef DirName, bool CacheFailure) {
+ auto Result = getDirectoryRef(DirName, CacheFailure);
+ if (Result)
+ return &Result->getDirEntry();
+ return llvm::errorToErrorCode(Result.takeError());
}
-const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
- bool CacheFailure) {
+llvm::ErrorOr<const FileEntry *>
+FileManager::getFile(StringRef Filename, bool openFile, bool CacheFailure) {
+ auto Result = getFileRef(Filename, openFile, CacheFailure);
+ if (Result)
+ return &Result->getFileEntry();
+ return llvm::errorToErrorCode(Result.takeError());
+}
+
+llvm::Expected<FileEntryRef>
+FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
++NumFileLookups;
// See if there is already an entry in the map.
- auto SeenFileInsertResult = SeenFileEntries.insert({Filename, nullptr});
- if (!SeenFileInsertResult.second)
- return SeenFileInsertResult.first->second;
+ auto SeenFileInsertResult =
+ SeenFileEntries.insert({Filename, std::errc::no_such_file_or_directory});
+ if (!SeenFileInsertResult.second) {
+ if (!SeenFileInsertResult.first->second)
+ return llvm::errorCodeToError(
+ SeenFileInsertResult.first->second.getError());
+ // Construct and return and FileEntryRef, unless it's a redirect to another
+ // filename.
+ SeenFileEntryOrRedirect Value = *SeenFileInsertResult.first->second;
+ FileEntry *FE;
+ if (LLVM_LIKELY(FE = Value.dyn_cast<FileEntry *>()))
+ return FileEntryRef(SeenFileInsertResult.first->first(), *FE);
+ return getFileRef(*Value.get<const StringRef *>(), openFile, CacheFailure);
+ }
// We've not seen this before. Fill it in.
++NumFileCacheMisses;
@@ -191,14 +233,16 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// subdirectory. This will let us avoid having to waste time on known-to-fail
// searches when we go to find sys/bar.h, because all the search directories
// without a 'sys' subdir will get a cached failure result.
- const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
- CacheFailure);
- if (DirInfo == nullptr) { // Directory doesn't exist, file can't exist.
- if (!CacheFailure)
+ auto DirInfoOrErr = getDirectoryFromFile(*this, Filename, CacheFailure);
+ if (!DirInfoOrErr) { // Directory doesn't exist, file can't exist.
+ if (CacheFailure)
+ NamedFileEnt.second = DirInfoOrErr.getError();
+ else
SeenFileEntries.erase(Filename);
- return nullptr;
+ return llvm::errorCodeToError(DirInfoOrErr.getError());
}
+ const DirectoryEntry *DirInfo = *DirInfoOrErr;
// FIXME: Use the directory info to prune this, before doing the stat syscall.
// FIXME: This will reduce the # syscalls.
@@ -206,12 +250,16 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// Check to see if the file exists.
std::unique_ptr<llvm::vfs::File> F;
llvm::vfs::Status Status;
- if (getStatValue(InterndFileName, Status, true, openFile ? &F : nullptr)) {
+ auto statError = getStatValue(InterndFileName, Status, true,
+ openFile ? &F : nullptr);
+ if (statError) {
// There's no real file at the given path.
- if (!CacheFailure)
+ if (CacheFailure)
+ NamedFileEnt.second = statError;
+ else
SeenFileEntries.erase(Filename);
- return nullptr;
+ return llvm::errorCodeToError(statError);
}
assert((openFile || !F) && "undesired open file");
@@ -225,11 +273,15 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// If the name returned by getStatValue is different than Filename, re-intern
// the name.
if (Status.getName() != Filename) {
- auto &NamedFileEnt =
- *SeenFileEntries.insert({Status.getName(), &UFE}).first;
- assert(NamedFileEnt.second == &UFE &&
+ auto &NewNamedFileEnt =
+ *SeenFileEntries.insert({Status.getName(), &UFE}).first;
+ assert((*NewNamedFileEnt.second).get<FileEntry *>() == &UFE &&
"filename from getStatValue() refers to wrong file");
- InterndFileName = NamedFileEnt.first().data();
+ InterndFileName = NewNamedFileEnt.first().data();
+ // In addition to re-interning the name, construct a redirecting seen file
+ // entry, that will point to the name the filesystem actually wants to use.
+ StringRef *Redirect = new (CanonicalNameStorage) StringRef(InterndFileName);
+ NamedFileEnt.second = Redirect;
}
if (UFE.isValid()) { // Already have an entry with this inode, return it.
@@ -248,9 +300,11 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// to switch towards a design where we return a FileName object that
// encapsulates both the name by which the file was accessed and the
// corresponding FileEntry.
+ // FIXME: The Name should be removed from FileEntry once all clients
+ // adopt FileEntryRef.
UFE.Name = InterndFileName;
- return &UFE;
+ return FileEntryRef(InterndFileName, UFE);
}
// Otherwise, we don't have this file yet, add it.
@@ -271,7 +325,7 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// We should still fill the path even if we aren't opening the file.
fillRealPathName(&UFE, InterndFileName);
}
- return &UFE;
+ return FileEntryRef(InterndFileName, UFE);
}
const FileEntry *
@@ -280,9 +334,16 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
++NumFileLookups;
// See if there is already an entry in the map for an existing file.
- auto &NamedFileEnt = *SeenFileEntries.insert({Filename, nullptr}).first;
- if (NamedFileEnt.second)
- return NamedFileEnt.second;
+ auto &NamedFileEnt = *SeenFileEntries.insert(
+ {Filename, std::errc::no_such_file_or_directory}).first;
+ if (NamedFileEnt.second) {
+ SeenFileEntryOrRedirect Value = *NamedFileEnt.second;
+ FileEntry *FE;
+ if (LLVM_LIKELY(FE = Value.dyn_cast<FileEntry *>()))
+ return FE;
+ return getVirtualFile(*Value.get<const StringRef *>(), Size,
+ ModificationTime);
+ }
// We've not seen this before, or the file is cached as non-existent.
++NumFileCacheMisses;
@@ -292,15 +353,14 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
// Now that all ancestors of Filename are in the cache, the
// following call is guaranteed to find the DirectoryEntry from the
// cache.
- const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
- /*CacheFailure=*/true);
+ auto DirInfo = getDirectoryFromFile(*this, Filename, /*CacheFailure=*/true);
assert(DirInfo &&
"The directory of a virtual file should already be in the cache.");
// Check to see if the file exists. If so, drop the virtual file
llvm::vfs::Status Status;
const char *InterndFileName = NamedFileEnt.first().data();
- if (getStatValue(InterndFileName, Status, true, nullptr) == 0) {
+ if (!getStatValue(InterndFileName, Status, true, nullptr)) {
UFE = &UniqueRealFiles[Status.getUniqueID()];
Status = llvm::vfs::Status(
Status.getName(), Status.getUniqueID(),
@@ -324,7 +384,7 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
fillRealPathName(UFE, Status.getName());
} else {
- VirtualFileEntries.push_back(llvm::make_unique<FileEntry>());
+ VirtualFileEntries.push_back(std::make_unique<FileEntry>());
UFE = VirtualFileEntries.back().get();
NamedFileEnt.second = UFE;
}
@@ -332,13 +392,32 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
UFE->Name = InterndFileName;
UFE->Size = Size;
UFE->ModTime = ModificationTime;
- UFE->Dir = DirInfo;
+ UFE->Dir = *DirInfo;
UFE->UID = NextFileUID++;
UFE->IsValid = true;
UFE->File.reset();
return UFE;
}
+llvm::Optional<FileEntryRef> FileManager::getBypassFile(FileEntryRef VF) {
+ // Stat of the file and return nullptr if it doesn't exist.
+ llvm::vfs::Status Status;
+ if (getStatValue(VF.getName(), Status, /*isFile=*/true, /*F=*/nullptr))
+ return None;
+
+ // Fill it in from the stat.
+ BypassFileEntries.push_back(std::make_unique<FileEntry>());
+ const FileEntry &VFE = VF.getFileEntry();
+ FileEntry &BFE = *BypassFileEntries.back();
+ BFE.Name = VFE.getName();
+ BFE.Size = Status.getSize();
+ BFE.Dir = VFE.Dir;
+ BFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
+ BFE.UID = NextFileUID++;
+ BFE.IsValid = true;
+ return FileEntryRef(VF.getName(), BFE);
+}
+
bool FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const {
StringRef pathRef(path.data(), path.size());
@@ -375,8 +454,7 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
}
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
- bool ShouldCloseOpenFile) {
+FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile) {
uint64_t FileSize = Entry->getSize();
// If there's a high enough chance that the file have changed since we
// got its size, force a stat before opening it.
@@ -389,80 +467,59 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
auto Result =
Entry->File->getBuffer(Filename, FileSize,
/*RequiresNullTerminator=*/true, isVolatile);
- // FIXME: we need a set of APIs that can make guarantees about whether a
- // FileEntry is open or not.
- if (ShouldCloseOpenFile)
- Entry->closeFile();
+ Entry->closeFile();
return Result;
}
// Otherwise, open the file.
+ return getBufferForFileImpl(Filename, FileSize, isVolatile);
+}
+llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+FileManager::getBufferForFileImpl(StringRef Filename, int64_t FileSize,
+ bool isVolatile) {
if (FileSystemOpts.WorkingDir.empty())
return FS->getBufferForFile(Filename, FileSize,
/*RequiresNullTerminator=*/true, isVolatile);
- SmallString<128> FilePath(Entry->getName());
+ SmallString<128> FilePath(Filename);
FixupRelativePath(FilePath);
return FS->getBufferForFile(FilePath, FileSize,
/*RequiresNullTerminator=*/true, isVolatile);
}
-llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-FileManager::getBufferForFile(StringRef Filename, bool isVolatile) {
- if (FileSystemOpts.WorkingDir.empty())
- return FS->getBufferForFile(Filename, -1, true, isVolatile);
-
- SmallString<128> FilePath(Filename);
- FixupRelativePath(FilePath);
- return FS->getBufferForFile(FilePath.c_str(), -1, true, isVolatile);
-}
-
/// getStatValue - Get the 'stat' information for the specified path,
/// using the cache to accelerate it if possible. This returns true
/// 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(StringRef Path, llvm::vfs::Status &Status,
- bool isFile,
- std::unique_ptr<llvm::vfs::File> *F) {
+std::error_code
+FileManager::getStatValue(StringRef Path, llvm::vfs::Status &Status,
+ bool isFile, std::unique_ptr<llvm::vfs::File> *F) {
// FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
// absolute!
if (FileSystemOpts.WorkingDir.empty())
- return bool(FileSystemStatCache::get(Path, Status, isFile, F,
- StatCache.get(), *FS));
+ return FileSystemStatCache::get(Path, Status, isFile, F,
+ StatCache.get(), *FS);
SmallString<128> FilePath(Path);
FixupRelativePath(FilePath);
- return bool(FileSystemStatCache::get(FilePath.c_str(), Status, isFile, F,
- StatCache.get(), *FS));
+ return FileSystemStatCache::get(FilePath.c_str(), Status, isFile, F,
+ StatCache.get(), *FS);
}
-bool FileManager::getNoncachedStatValue(StringRef Path,
- llvm::vfs::Status &Result) {
+std::error_code
+FileManager::getNoncachedStatValue(StringRef Path,
+ llvm::vfs::Status &Result) {
SmallString<128> FilePath(Path);
FixupRelativePath(FilePath);
llvm::ErrorOr<llvm::vfs::Status> S = FS->status(FilePath.c_str());
if (!S)
- return true;
+ return S.getError();
Result = *S;
- return false;
-}
-
-void FileManager::invalidateCache(const FileEntry *Entry) {
- assert(Entry && "Cannot invalidate a NULL FileEntry");
-
- SeenFileEntries.erase(Entry->getName());
-
- // FileEntry invalidation should not block future optimizations in the file
- // caches. Possible alternatives are cache truncation (invalidate last N) or
- // invalidation of the whole cache.
- //
- // FIXME: This is broken. We sometimes have the same FileEntry* shared
- // betweeen multiple SeenFileEntries, so this can leave dangling pointers.
- UniqueRealFiles.erase(Entry->getUniqueID());
+ return std::error_code();
}
void FileManager::GetUniqueIDMapping(
@@ -471,23 +528,21 @@ void FileManager::GetUniqueIDMapping(
UIDToFiles.resize(NextFileUID);
// Map file entries
- for (llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator>::const_iterator
- FE = SeenFileEntries.begin(), FEEnd = SeenFileEntries.end();
+ for (llvm::StringMap<llvm::ErrorOr<SeenFileEntryOrRedirect>,
+ llvm::BumpPtrAllocator>::const_iterator
+ FE = SeenFileEntries.begin(),
+ FEEnd = SeenFileEntries.end();
FE != FEEnd; ++FE)
- if (FE->getValue())
- UIDToFiles[FE->getValue()->getUID()] = FE->getValue();
+ if (llvm::ErrorOr<SeenFileEntryOrRedirect> Entry = FE->getValue()) {
+ if (const auto *FE = (*Entry).dyn_cast<FileEntry *>())
+ UIDToFiles[FE->getUID()] = FE;
+ }
// Map virtual file entries
for (const auto &VFE : VirtualFileEntries)
UIDToFiles[VFE->getUID()] = VFE.get();
}
-void FileManager::modifyFileEntry(FileEntry *File,
- off_t Size, time_t ModificationTime) {
- File->Size = Size;
- File->ModTime = ModificationTime;
-}
-
StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) {
// FIXME: use llvm::sys::fs::canonical() when it gets implemented
llvm::DenseMap<const DirectoryEntry *, llvm::StringRef>::iterator Known
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index ca9c71287ab7..4aebea19924f 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -412,6 +412,21 @@ public:
} // namespace clang.
+bool Selector::isKeywordSelector(ArrayRef<StringRef> Names) const {
+ assert(!Names.empty() && "must have >= 1 selector slots");
+ if (getNumArgs() != Names.size())
+ return false;
+ for (unsigned I = 0, E = Names.size(); I != E; ++I) {
+ if (getNameForSlot(I) != Names[I])
+ return false;
+ }
+ return true;
+}
+
+bool Selector::isUnarySelector(StringRef Name) const {
+ return isUnarySelector() && getNameForSlot(0) == Name;
+}
+
unsigned Selector::getNumArgs() const {
unsigned IIF = getIdentifierInfoFlag();
if (IIF <= ZeroArg)
diff --git a/lib/Basic/LangStandards.cpp b/lib/Basic/LangStandards.cpp
new file mode 100644
index 000000000000..ee27bfd12113
--- /dev/null
+++ b/lib/Basic/LangStandards.cpp
@@ -0,0 +1,45 @@
+//===--- LangStandards.cpp - Language Standard Definitions ----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/LangStandard.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+using namespace clang;
+
+#define LANGSTANDARD(id, name, lang, desc, features) \
+ static const LangStandard Lang_##id = {name, desc, features, Language::lang};
+#include "clang/Basic/LangStandards.def"
+
+const LangStandard &LangStandard::getLangStandardForKind(Kind K) {
+ switch (K) {
+ case lang_unspecified:
+ llvm::report_fatal_error("getLangStandardForKind() on unspecified kind");
+#define LANGSTANDARD(id, name, lang, desc, features) \
+ case lang_##id: return Lang_##id;
+#include "clang/Basic/LangStandards.def"
+ }
+ llvm_unreachable("Invalid language kind!");
+}
+
+LangStandard::Kind LangStandard::getLangKind(StringRef Name) {
+ return llvm::StringSwitch<Kind>(Name)
+#define LANGSTANDARD(id, name, lang, desc, features) .Case(name, lang_##id)
+#define LANGSTANDARD_ALIAS(id, alias) .Case(alias, lang_##id)
+#include "clang/Basic/LangStandards.def"
+ .Default(lang_unspecified);
+}
+
+const LangStandard *LangStandard::getLangStandardForName(StringRef Name) {
+ Kind K = getLangKind(Name);
+ if (K == lang_unspecified)
+ return nullptr;
+
+ return &getLangStandardForKind(K);
+}
+
+
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index f394f26e550c..541431dbbe7d 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -246,8 +246,8 @@ ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
if (!TopHeaderNames.empty()) {
for (std::vector<std::string>::iterator
I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
- if (const FileEntry *FE = FileMgr.getFile(*I))
- TopHeaders.insert(FE);
+ if (auto FE = FileMgr.getFile(*I))
+ TopHeaders.insert(*FE);
}
TopHeaderNames.clear();
}
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index 82e193efef32..a52ed8caa121 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -55,6 +55,8 @@ OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Case("uniform", OMPC_uniform)
+ .Case("device_type", OMPC_device_type)
+ .Case("match", OMPC_match)
.Default(OMPC_unknown);
}
@@ -71,6 +73,10 @@ const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) {
return "uniform";
case OMPC_threadprivate:
return "threadprivate or thread local";
+ case OMPC_device_type:
+ return "device_type";
+ case OMPC_match:
+ return "match";
}
llvm_unreachable("Invalid OpenMP clause kind");
}
@@ -145,6 +151,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
.Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown);
+ case OMPC_device_type:
+ return llvm::StringSwitch<OpenMPDeviceType>(Str)
+#define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_DEVICE_TYPE_unknown);
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -192,6 +203,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_unified_shared_memory:
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
+ case OMPC_match:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -328,6 +340,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type");
+ case OMPC_device_type:
+ switch (Type) {
+ case OMPC_DEVICE_TYPE_unknown:
+ return "unknown";
+#define OPENMP_DEVICE_TYPE_KIND(Name) \
+ case OMPC_DEVICE_TYPE_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'device_type' clause type");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -375,6 +397,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_unified_shared_memory:
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
+ case OMPC_match:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -588,8 +611,6 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
- case OMPD_declare_simd:
- break;
case OMPD_cancel:
switch (CKind) {
#define OPENMP_CANCEL_CLAUSE(Name) \
@@ -630,6 +651,36 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_master_taskloop:
+ switch (CKind) {
+#define OPENMP_MASTER_TASKLOOP_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_master_taskloop_simd:
+ switch (CKind) {
+#define OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_parallel_master_taskloop:
+ switch (CKind) {
+#define OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_critical:
switch (CKind) {
#define OPENMP_CRITICAL_CLAUSE(Name) \
@@ -820,6 +871,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_declare_variant:
+ switch (CKind) {
+#define OPENMP_DECLARE_VARIANT_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:
@@ -831,6 +892,7 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_declare_reduction:
+ case OMPD_declare_simd:
break;
}
return false;
@@ -840,7 +902,9 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd ||
DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||
DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd ||
- DKind == OMPD_distribute || DKind == OMPD_target_parallel_for ||
+ DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd ||
+ DKind == OMPD_parallel_master_taskloop || DKind == OMPD_distribute ||
+ DKind == OMPD_target_parallel_for ||
DKind == OMPD_distribute_parallel_for ||
DKind == OMPD_distribute_parallel_for_simd ||
DKind == OMPD_distribute_simd ||
@@ -871,7 +935,9 @@ bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
}
bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
- return DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd;
+ return DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd ||
+ DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd ||
+ DKind == OMPD_parallel_master_taskloop;
}
bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
@@ -884,7 +950,8 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
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;
+ DKind == OMPD_target_teams_distribute_parallel_for_simd ||
+ DKind == OMPD_parallel_master_taskloop;
}
bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
@@ -920,6 +987,7 @@ bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_simd || DKind == OMPD_for_simd ||
DKind == OMPD_parallel_for_simd || DKind == OMPD_taskloop_simd ||
+ DKind == OMPD_master_taskloop_simd ||
DKind == OMPD_distribute_parallel_for_simd ||
DKind == OMPD_distribute_simd || DKind == OMPD_target_simd ||
DKind == OMPD_teams_distribute_simd ||
@@ -1021,6 +1089,12 @@ void clang::getOpenMPCaptureRegions(
break;
case OMPD_taskloop:
case OMPD_taskloop_simd:
+ case OMPD_master_taskloop:
+ case OMPD_master_taskloop_simd:
+ CaptureRegions.push_back(OMPD_taskloop);
+ break;
+ case OMPD_parallel_master_taskloop:
+ CaptureRegions.push_back(OMPD_parallel);
CaptureRegions.push_back(OMPD_taskloop);
break;
case OMPD_target_teams_distribute_parallel_for:
@@ -1060,6 +1134,7 @@ void clang::getOpenMPCaptureRegions(
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_requires:
+ case OMPD_declare_variant:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index 12b0305e707c..58b95289eaf2 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -96,7 +96,7 @@ void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree) {
}
const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
- const SourceManager &SM,
+ FileManager &FM,
SourceLocation Loc,
bool *Invalid) const {
// Lazily create the Buffer for ContentCaches that wrap files. If we already
@@ -134,9 +134,7 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
return Buffer.getPointer();
}
- bool isVolatile = SM.userFilesAreVolatile() && !IsSystemFile;
- auto BufferOrError =
- SM.getFileManager().getBufferForFile(ContentsEntry, isVolatile);
+ auto BufferOrError = FM.getBufferForFile(ContentsEntry, IsFileVolatile);
// If we were unable to open the file, then we are in an inconsistent
// situation where the content cache referenced a file which no longer
@@ -389,7 +387,7 @@ void SourceManager::initializeForReplay(const SourceManager &Old) {
Clone->OrigEntry = Cache->OrigEntry;
Clone->ContentsEntry = Cache->ContentsEntry;
Clone->BufferOverridden = Cache->BufferOverridden;
- Clone->IsSystemFile = Cache->IsSystemFile;
+ Clone->IsFileVolatile = Cache->IsFileVolatile;
Clone->IsTransient = Cache->IsTransient;
Clone->replaceBuffer(Cache->getRawBuffer(), /*DoNotFree*/true);
return Clone;
@@ -438,7 +436,7 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt,
new (Entry) ContentCache(FileEnt);
}
- Entry->IsSystemFile = isSystemFile;
+ Entry->IsFileVolatile = UserFilesAreVolatile && !isSystemFile;
Entry->IsTransient = FilesAreTransient;
return Entry;
@@ -466,10 +464,9 @@ const SrcMgr::SLocEntry &SourceManager::loadSLocEntry(unsigned Index,
// If the file of the SLocEntry changed we could still have loaded it.
if (!SLocEntryLoaded[Index]) {
// Try to recover; create a SLocEntry so the rest of clang can handle it.
- LoadedSLocEntryTable[Index] = SLocEntry::get(0,
- FileInfo::get(SourceLocation(),
- getFakeContentCacheForRecovery(),
- SrcMgr::C_User));
+ LoadedSLocEntryTable[Index] = SLocEntry::get(
+ 0, FileInfo::get(SourceLocation(), getFakeContentCacheForRecovery(),
+ SrcMgr::C_User, ""));
}
}
@@ -505,7 +502,7 @@ llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
const SrcMgr::ContentCache *
SourceManager::getFakeContentCacheForRecovery() const {
if (!FakeContentCacheForRecovery) {
- FakeContentCacheForRecovery = llvm::make_unique<SrcMgr::ContentCache>();
+ FakeContentCacheForRecovery = std::make_unique<SrcMgr::ContentCache>();
FakeContentCacheForRecovery->replaceBuffer(getFakeBufferForRecovery(),
/*DoNotFree=*/true);
}
@@ -556,7 +553,7 @@ FileID SourceManager::getNextFileID(FileID FID) const {
/// createFileID - Create a new FileID for the specified ContentCache and
/// include position. This works regardless of whether the ContentCache
/// corresponds to a file or some other input source.
-FileID SourceManager::createFileID(const ContentCache *File,
+FileID SourceManager::createFileID(const ContentCache *File, StringRef Filename,
SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter,
int LoadedID, unsigned LoadedOffset) {
@@ -565,14 +562,14 @@ FileID SourceManager::createFileID(const ContentCache *File,
unsigned Index = unsigned(-LoadedID) - 2;
assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
assert(!SLocEntryLoaded[Index] && "FileID already loaded");
- LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
- FileInfo::get(IncludePos, File, FileCharacter));
+ LoadedSLocEntryTable[Index] = SLocEntry::get(
+ LoadedOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename));
SLocEntryLoaded[Index] = true;
return FileID::get(LoadedID);
}
- LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
- FileInfo::get(IncludePos, File,
- FileCharacter)));
+ LocalSLocEntryTable.push_back(
+ SLocEntry::get(NextLocalOffset,
+ FileInfo::get(IncludePos, File, FileCharacter, Filename)));
unsigned FileSize = File->getSize();
assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
@@ -646,7 +643,7 @@ const llvm::MemoryBuffer *
SourceManager::getMemoryBufferForFile(const FileEntry *File, bool *Invalid) {
const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
assert(IR && "getOrCreateContentCache() cannot return NULL");
- return IR->getBuffer(Diag, *this, SourceLocation(), Invalid);
+ return IR->getBuffer(Diag, getFileManager(), SourceLocation(), Invalid);
}
void SourceManager::overrideFileContents(const FileEntry *SourceFile,
@@ -672,17 +669,19 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile,
getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
}
-void SourceManager::disableFileContentsOverride(const FileEntry *File) {
- if (!isFileOverridden(File))
- return;
+const FileEntry *
+SourceManager::bypassFileContentsOverride(const FileEntry &File) {
+ assert(isFileOverridden(&File));
+ llvm::Optional<FileEntryRef> BypassFile =
+ FileMgr.getBypassFile(FileEntryRef(File.getName(), File));
- const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
- const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(nullptr);
- const_cast<SrcMgr::ContentCache *>(IR)->ContentsEntry = IR->OrigEntry;
+ // If the file can't be found in the FS, give up.
+ if (!BypassFile)
+ return nullptr;
- assert(OverriddenFilesInfo);
- OverriddenFilesInfo->OverriddenFiles.erase(File);
- OverriddenFilesInfo->OverriddenFilesWithBuffer.erase(File);
+ const FileEntry *FE = &BypassFile->getFileEntry();
+ (void)getOrCreateContentCache(FE);
+ return FE;
}
void SourceManager::setFileIsTransient(const FileEntry *File) {
@@ -700,7 +699,7 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
}
const llvm::MemoryBuffer *Buf = SLoc.getFile().getContentCache()->getBuffer(
- Diag, *this, SourceLocation(), &MyInvalid);
+ Diag, getFileManager(), SourceLocation(), &MyInvalid);
if (Invalid)
*Invalid = MyInvalid;
@@ -1131,7 +1130,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL,
}
const llvm::MemoryBuffer *Buffer =
Entry.getFile().getContentCache()->getBuffer(
- Diag, *this, SourceLocation(), &CharDataInvalid);
+ Diag, getFileManager(), SourceLocation(), &CharDataInvalid);
if (Invalid)
*Invalid = CharDataInvalid;
return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
@@ -1228,7 +1227,7 @@ static void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI,
const SourceManager &SM, bool &Invalid) {
// Note that calling 'getBuffer()' may lazily page in the file.
const MemoryBuffer *Buffer =
- FI->getBuffer(Diag, SM, SourceLocation(), &Invalid);
+ FI->getBuffer(Diag, SM.getFileManager(), SourceLocation(), &Invalid);
if (Invalid)
return;
@@ -1459,7 +1458,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc,
if (C->OrigEntry)
Filename = C->OrigEntry->getName();
else
- Filename = C->getBuffer(Diag, *this)->getBufferIdentifier();
+ Filename = C->getBuffer(Diag, getFileManager())->getBufferIdentifier();
unsigned LineNo = getLineNumber(LocInfo.first, LocInfo.second, &Invalid);
if (Invalid)
@@ -1558,22 +1557,6 @@ unsigned SourceManager::getFileIDSize(FileID FID) const {
// Other miscellaneous methods.
//===----------------------------------------------------------------------===//
-/// Retrieve the inode for the given file entry, if possible.
-///
-/// This routine involves a system call, and therefore should only be used
-/// in non-performance-critical code.
-static Optional<llvm::sys::fs::UniqueID>
-getActualFileUID(const FileEntry *File) {
- if (!File)
- return None;
-
- llvm::sys::fs::UniqueID ID;
- if (llvm::sys::fs::getUniqueID(File->getName(), ID))
- return None;
-
- return ID;
-}
-
/// Get the source location for the given file:line:col triplet.
///
/// If the source file is included multiple times, the source location will
@@ -1595,13 +1578,8 @@ SourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile,
FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
assert(SourceFile && "Null source file!");
- // Find the first file ID that corresponds to the given file.
- FileID FirstFID;
-
// First, check the main file ID, since it is common to look for a
// location in the main file.
- Optional<llvm::sys::fs::UniqueID> SourceFileUID;
- Optional<StringRef> SourceFileName;
if (MainFileID.isValid()) {
bool Invalid = false;
const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid);
@@ -1609,100 +1587,35 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
return FileID();
if (MainSLoc.isFile()) {
- const ContentCache *MainContentCache
- = MainSLoc.getFile().getContentCache();
- if (!MainContentCache || !MainContentCache->OrigEntry) {
- // Can't do anything
- } else if (MainContentCache->OrigEntry == SourceFile) {
- FirstFID = MainFileID;
- } else {
- // Fall back: check whether we have the same base name and inode
- // as the main file.
- const FileEntry *MainFile = MainContentCache->OrigEntry;
- SourceFileName = llvm::sys::path::filename(SourceFile->getName());
- if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) {
- SourceFileUID = getActualFileUID(SourceFile);
- if (SourceFileUID) {
- if (Optional<llvm::sys::fs::UniqueID> MainFileUID =
- getActualFileUID(MainFile)) {
- if (*SourceFileUID == *MainFileUID) {
- FirstFID = MainFileID;
- SourceFile = MainFile;
- }
- }
- }
- }
- }
+ const ContentCache *MainContentCache =
+ MainSLoc.getFile().getContentCache();
+ if (MainContentCache && MainContentCache->OrigEntry == SourceFile)
+ return MainFileID;
}
}
- if (FirstFID.isInvalid()) {
- // The location we're looking for isn't in the main file; look
- // through all of the local source locations.
- for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
- bool Invalid = false;
- const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid);
- if (Invalid)
- return FileID();
+ // The location we're looking for isn't in the main file; look
+ // through all of the local source locations.
+ for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
+ bool Invalid = false;
+ const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid);
+ if (Invalid)
+ return FileID();
- if (SLoc.isFile() &&
- SLoc.getFile().getContentCache() &&
- SLoc.getFile().getContentCache()->OrigEntry == SourceFile) {
- FirstFID = FileID::get(I);
- break;
- }
- }
- // If that still didn't help, try the modules.
- if (FirstFID.isInvalid()) {
- for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) {
- const SLocEntry &SLoc = getLoadedSLocEntry(I);
- if (SLoc.isFile() &&
- SLoc.getFile().getContentCache() &&
- SLoc.getFile().getContentCache()->OrigEntry == SourceFile) {
- FirstFID = FileID::get(-int(I) - 2);
- break;
- }
- }
- }
+ if (SLoc.isFile() && SLoc.getFile().getContentCache() &&
+ SLoc.getFile().getContentCache()->OrigEntry == SourceFile)
+ return FileID::get(I);
}
- // If we haven't found what we want yet, try again, but this time stat()
- // each of the files in case the files have changed since we originally
- // parsed the file.
- if (FirstFID.isInvalid() &&
- (SourceFileName ||
- (SourceFileName = llvm::sys::path::filename(SourceFile->getName()))) &&
- (SourceFileUID || (SourceFileUID = getActualFileUID(SourceFile)))) {
- bool Invalid = false;
- for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
- FileID IFileID;
- IFileID.ID = I;
- const SLocEntry &SLoc = getSLocEntry(IFileID, &Invalid);
- if (Invalid)
- return FileID();
-
- if (SLoc.isFile()) {
- const ContentCache *FileContentCache
- = SLoc.getFile().getContentCache();
- const FileEntry *Entry = FileContentCache ? FileContentCache->OrigEntry
- : nullptr;
- if (Entry &&
- *SourceFileName == llvm::sys::path::filename(Entry->getName())) {
- if (Optional<llvm::sys::fs::UniqueID> EntryUID =
- getActualFileUID(Entry)) {
- if (*SourceFileUID == *EntryUID) {
- FirstFID = FileID::get(I);
- SourceFile = Entry;
- break;
- }
- }
- }
- }
- }
+ // If that still didn't help, try the modules.
+ for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) {
+ const SLocEntry &SLoc = getLoadedSLocEntry(I);
+ if (SLoc.isFile() && SLoc.getFile().getContentCache() &&
+ SLoc.getFile().getContentCache()->OrigEntry == SourceFile)
+ return FileID::get(-int(I) - 2);
}
- (void) SourceFile;
- return FirstFID;
+ return FileID();
}
/// Get the source location in \arg FID for the given line:col.
@@ -1745,13 +1658,13 @@ SourceLocation SourceManager::translateLineCol(FileID FID,
}
if (Line > Content->NumLines) {
- unsigned Size = Content->getBuffer(Diag, *this)->getBufferSize();
+ unsigned Size = Content->getBuffer(Diag, getFileManager())->getBufferSize();
if (Size > 0)
--Size;
return FileLoc.getLocWithOffset(Size);
}
- const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
+ const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, getFileManager());
unsigned FilePos = Content->SourceLineCache[Line - 1];
const char *Buf = Buffer->getBufferStart() + FilePos;
unsigned BufLength = Buffer->getBufferSize() - FilePos;
@@ -1927,7 +1840,7 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const {
std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID];
if (!MacroArgsCache) {
- MacroArgsCache = llvm::make_unique<MacroArgsMap>();
+ MacroArgsCache = std::make_unique<MacroArgsMap>();
computeMacroArgsCache(*MacroArgsCache, FID);
}
@@ -2256,14 +2169,14 @@ SourceManagerForFile::SourceManagerForFile(StringRef FileName,
// This is passed to `SM` as reference, so the pointer has to be referenced
// in `Environment` so that `FileMgr` can out-live this function scope.
FileMgr =
- llvm::make_unique<FileManager>(FileSystemOptions(), InMemoryFileSystem);
+ std::make_unique<FileManager>(FileSystemOptions(), InMemoryFileSystem);
// This is passed to `SM` as reference, so the pointer has to be referenced
// by `Environment` due to the same reason above.
- Diagnostics = llvm::make_unique<DiagnosticsEngine>(
+ Diagnostics = std::make_unique<DiagnosticsEngine>(
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
new DiagnosticOptions);
- SourceMgr = llvm::make_unique<SourceManager>(*Diagnostics, *FileMgr);
- FileID ID = SourceMgr->createFileID(FileMgr->getFile(FileName),
+ SourceMgr = std::make_unique<SourceManager>(*Diagnostics, *FileMgr);
+ FileID ID = SourceMgr->createFileID(*FileMgr->getFile(FileName),
SourceLocation(), clang::SrcMgr::C_User);
assert(ID.isValid());
SourceMgr->setMainFileID(ID);
diff --git a/lib/Basic/Stack.cpp b/lib/Basic/Stack.cpp
new file mode 100644
index 000000000000..5e4750931500
--- /dev/null
+++ b/lib/Basic/Stack.cpp
@@ -0,0 +1,75 @@
+//===--- Stack.cpp - Utilities for dealing with stack space ---------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Defines utilities for dealing with stack allocation and stack space.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Stack.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/CrashRecoveryContext.h"
+
+#ifdef _MSC_VER
+#include <intrin.h> // for _AddressOfReturnAddress
+#endif
+
+static LLVM_THREAD_LOCAL void *BottomOfStack = nullptr;
+
+static void *getStackPointer() {
+#if __GNUC__ || __has_builtin(__builtin_frame_address)
+ return __builtin_frame_address(0);
+#elif defined(_MSC_VER)
+ return _AddressOfReturnAddress();
+#else
+ char CharOnStack = 0;
+ // The volatile store here is intended to escape the local variable, to
+ // prevent the compiler from optimizing CharOnStack into anything other
+ // than a char on the stack.
+ //
+ // Tested on: MSVC 2015 - 2019, GCC 4.9 - 9, Clang 3.2 - 9, ICC 13 - 19.
+ char *volatile Ptr = &CharOnStack;
+ return Ptr;
+#endif
+}
+
+void clang::noteBottomOfStack() {
+ if (!BottomOfStack)
+ BottomOfStack = getStackPointer();
+}
+
+bool clang::isStackNearlyExhausted() {
+ // We consider 256 KiB to be sufficient for any code that runs between checks
+ // for stack size.
+ constexpr size_t SufficientStack = 256 << 10;
+
+ // If we don't know where the bottom of the stack is, hope for the best.
+ if (!BottomOfStack)
+ return false;
+
+ intptr_t StackDiff = (intptr_t)getStackPointer() - (intptr_t)BottomOfStack;
+ size_t StackUsage = (size_t)std::abs(StackDiff);
+
+ // If the stack pointer has a surprising value, we do not understand this
+ // stack usage scheme. (Perhaps the target allocates new stack regions on
+ // demand for us.) Don't try to guess what's going on.
+ if (StackUsage > DesiredStackSize)
+ return false;
+
+ return StackUsage >= DesiredStackSize - SufficientStack;
+}
+
+void clang::runWithSufficientStackSpaceSlow(llvm::function_ref<void()> Diag,
+ llvm::function_ref<void()> Fn) {
+ llvm::CrashRecoveryContext CRC;
+ CRC.RunSafelyOnThread([&] {
+ noteBottomOfStack();
+ Diag();
+ Fn();
+ }, DesiredStackSize);
+}
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index a9dfe69b90c5..3a21a19e1f19 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -17,6 +17,7 @@
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetParser.h"
#include <cstdlib>
@@ -111,6 +112,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
HasAlignMac68kSupport = false;
HasBuiltinMSVaList = false;
IsRenderScriptTarget = false;
+ HasAArch64SVETypes = false;
// Default to no types using fpret.
RealTypeUsesObjCFPRet = 0;
@@ -135,6 +137,10 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
// Out of line virtual dtor for TargetInfo.
TargetInfo::~TargetInfo() {}
+void TargetInfo::resetDataLayout(StringRef DL) {
+ DataLayout.reset(new llvm::DataLayout(DL));
+}
+
bool
TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {
Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index a08e399e7270..63a64ed2931a 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -363,15 +363,26 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new AMDGPUTargetInfo(Triple, Opts);
case llvm::Triple::riscv32:
- // TODO: add cases for FreeBSD, NetBSD, RTEMS once tested.
- if (os == llvm::Triple::Linux)
+ // TODO: add cases for NetBSD, RTEMS once tested.
+ switch (os) {
+ case llvm::Triple::FreeBSD:
+ return new FreeBSDTargetInfo<RISCV32TargetInfo>(Triple, Opts);
+ case llvm::Triple::Linux:
return new LinuxTargetInfo<RISCV32TargetInfo>(Triple, Opts);
- return new RISCV32TargetInfo(Triple, Opts);
+ default:
+ return new RISCV32TargetInfo(Triple, Opts);
+ }
+
case llvm::Triple::riscv64:
- // TODO: add cases for FreeBSD, NetBSD, RTEMS once tested.
- if (os == llvm::Triple::Linux)
+ // TODO: add cases for NetBSD, RTEMS once tested.
+ switch (os) {
+ case llvm::Triple::FreeBSD:
+ return new FreeBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts);
+ case llvm::Triple::Linux:
return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts);
- return new RISCV64TargetInfo(Triple, Opts);
+ default:
+ return new RISCV64TargetInfo(Triple, Opts);
+ }
case llvm::Triple::sparc:
switch (os) {
diff --git a/lib/Basic/Targets/AArch64.cpp b/lib/Basic/Targets/AArch64.cpp
index 74ac69ab8946..c86cc63e3d84 100644
--- a/lib/Basic/Targets/AArch64.cpp
+++ b/lib/Basic/Targets/AArch64.cpp
@@ -62,6 +62,16 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
// Make __builtin_ms_va_list available.
HasBuiltinMSVaList = true;
+ // Make the SVE types available. Note that this deliberately doesn't
+ // depend on SveMode, since in principle it should be possible to turn
+ // SVE on and off within a translation unit. It should also be possible
+ // to compile the global declaration:
+ //
+ // __SVInt8_t *ptr;
+ //
+ // even without SVE.
+ HasAArch64SVETypes = true;
+
// {} in inline assembly are neon specifiers, not assembly variant
// specifiers.
NoAsmVariants = true;
@@ -196,9 +206,6 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__ARM_NEON_FP", "0xE");
}
- if (FPU & SveMode)
- Builder.defineMacro("__ARM_FEATURE_SVE", "1");
-
if (HasCRC)
Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
@@ -219,6 +226,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasMTE)
Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1");
+ if (HasTME)
+ Builder.defineMacro("__ARM_FEATURE_TME", "1");
+
if ((FPU & NeonMode) && HasFP16FML)
Builder.defineMacro("__ARM_FEATURE_FP16FML", "1");
@@ -270,6 +280,7 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasDotProd = false;
HasFP16FML = false;
HasMTE = false;
+ HasTME = false;
ArchKind = llvm::AArch64::ArchKind::ARMV8A;
for (const auto &Feature : Features) {
@@ -301,6 +312,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasFP16FML = true;
if (Feature == "+mte")
HasMTE = true;
+ if (Feature == "+tme")
+ HasTME = true;
}
setDataLayout();
@@ -351,10 +364,19 @@ const char *const AArch64TargetInfo::GCCRegNames[] = {
"d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
"d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
- // Vector registers
+ // Neon vector registers
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
"v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22",
- "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
+ "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
+
+ // SVE vector registers
+ "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10",
+ "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21",
+ "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31",
+
+ // SVE predicate registers
+ "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
+ "p11", "p12", "p13", "p14", "p15"
};
ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
diff --git a/lib/Basic/Targets/AArch64.h b/lib/Basic/Targets/AArch64.h
index 5833c146003b..b6aa07780edd 100644
--- a/lib/Basic/Targets/AArch64.h
+++ b/lib/Basic/Targets/AArch64.h
@@ -35,6 +35,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
bool HasDotProd;
bool HasFP16FML;
bool HasMTE;
+ bool HasTME;
llvm::AArch64::ArchKind ArchKind;
diff --git a/lib/Basic/Targets/AMDGPU.cpp b/lib/Basic/Targets/AMDGPU.cpp
index b5c82e288570..481630c0fa45 100644
--- a/lib/Basic/Targets/AMDGPU.cpp
+++ b/lib/Basic/Targets/AMDGPU.cpp
@@ -17,6 +17,7 @@
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetBuiltins.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/IR/DataLayout.h"
using namespace clang;
using namespace clang::targets;
@@ -131,9 +132,6 @@ bool AMDGPUTargetInfo::initFeatureMap(
// XXX - What does the member GPU mean if device name string passed here?
if (isAMDGCN(getTriple())) {
- if (CPU.empty())
- CPU = "gfx600";
-
switch (llvm::AMDGPU::parseArchAMDGCN(CPU)) {
case GK_GFX1012:
case GK_GFX1011:
@@ -145,6 +143,7 @@ bool AMDGPUTargetInfo::initFeatureMap(
case GK_GFX1010:
Features["dl-insts"] = true;
Features["ci-insts"] = true;
+ Features["flat-address-space"] = true;
Features["16-bit-insts"] = true;
Features["dpp"] = true;
Features["gfx8-insts"] = true;
@@ -184,12 +183,13 @@ bool AMDGPUTargetInfo::initFeatureMap(
case GK_GFX701:
case GK_GFX700:
Features["ci-insts"] = true;
+ Features["flat-address-space"] = true;
LLVM_FALLTHROUGH;
case GK_GFX601:
case GK_GFX600:
break;
case GK_NONE:
- return false;
+ break;
default:
llvm_unreachable("Unhandled GPU!");
}
diff --git a/lib/Basic/Targets/ARM.cpp b/lib/Basic/Targets/ARM.cpp
index c6834b9fac15..437a77afdc99 100644
--- a/lib/Basic/Targets/ARM.cpp
+++ b/lib/Basic/Targets/ARM.cpp
@@ -309,8 +309,9 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
setAtomic();
// Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
+ // as well the default alignment
if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
- MaxVectorAlign = 64;
+ DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
// Do force alignment of members that follow zero length bitfields. If
// the alignment of the zero-length bitfield is greater than the member
@@ -321,7 +322,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
if (Triple.getOS() == llvm::Triple::Linux ||
Triple.getOS() == llvm::Triple::UnknownOS)
this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
- ? "\01__gnu_mcount_nc"
+ ? "llvm.arm.gnu.eabi.mcount"
: "\01mcount";
SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
@@ -427,11 +428,10 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
for (const auto &Feature : Features) {
if (Feature == "+soft-float") {
SoftFloat = true;
- } else if (Feature == "+vfp2sp" || Feature == "+vfp2d16sp" ||
- Feature == "+vfp2" || Feature == "+vfp2d16") {
+ } else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
FPU |= VFP2FPU;
HW_FP |= HW_FP_SP;
- if (Feature == "+vfp2" || Feature == "+vfp2d16")
+ if (Feature == "+vfp2")
HW_FP |= HW_FP_DP;
} else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
Feature == "+vfp3" || Feature == "+vfp3d16") {
@@ -884,19 +884,102 @@ bool ARMTargetInfo::validateAsmConstraint(
switch (*Name) {
default:
break;
- case 'l': // r0-r7
- case 'h': // r8-r15
- case 't': // VFP Floating point register single precision
- case 'w': // VFP Floating point register double precision
+ case 'l': // r0-r7 if thumb, r0-r15 if ARM
Info.setAllowsRegister();
return true;
+ case 'h': // r8-r15, thumb only
+ if (isThumb()) {
+ Info.setAllowsRegister();
+ return true;
+ }
+ break;
+ case 's': // An integer constant, but allowing only relocatable values.
+ return true;
+ case 't': // s0-s31, d0-d31, or q0-q15
+ case 'w': // s0-s15, d0-d7, or q0-q3
+ case 'x': // s0-s31, d0-d15, or q0-q7
+ Info.setAllowsRegister();
+ return true;
+ case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
+ // only available in ARMv6T2 and above
+ if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
+ Info.setRequiresImmediate(0, 65535);
+ return true;
+ }
+ break;
case 'I':
+ if (isThumb()) {
+ if (!supportsThumb2())
+ Info.setRequiresImmediate(0, 255);
+ else
+ // FIXME: should check if immediate value would be valid for a Thumb2
+ // data-processing instruction
+ Info.setRequiresImmediate();
+ } else
+ // FIXME: should check if immediate value would be valid for an ARM
+ // data-processing instruction
+ Info.setRequiresImmediate();
+ return true;
case 'J':
+ if (isThumb() && !supportsThumb2())
+ Info.setRequiresImmediate(-255, -1);
+ else
+ Info.setRequiresImmediate(-4095, 4095);
+ return true;
case 'K':
+ if (isThumb()) {
+ if (!supportsThumb2())
+ // FIXME: should check if immediate value can be obtained from shifting
+ // a value between 0 and 255 left by any amount
+ Info.setRequiresImmediate();
+ else
+ // FIXME: should check if immediate value would be valid for a Thumb2
+ // data-processing instruction when inverted
+ Info.setRequiresImmediate();
+ } else
+ // FIXME: should check if immediate value would be valid for an ARM
+ // data-processing instruction when inverted
+ Info.setRequiresImmediate();
+ return true;
case 'L':
+ if (isThumb()) {
+ if (!supportsThumb2())
+ Info.setRequiresImmediate(-7, 7);
+ else
+ // FIXME: should check if immediate value would be valid for a Thumb2
+ // data-processing instruction when negated
+ Info.setRequiresImmediate();
+ } else
+ // FIXME: should check if immediate value would be valid for an ARM
+ // data-processing instruction when negated
+ Info.setRequiresImmediate();
+ return true;
case 'M':
- // FIXME
+ if (isThumb() && !supportsThumb2())
+ // FIXME: should check if immediate value is a multiple of 4 between 0 and
+ // 1020
+ Info.setRequiresImmediate();
+ else
+ // FIXME: should check if immediate value is a power of two or a integer
+ // between 0 and 32
+ Info.setRequiresImmediate();
return true;
+ case 'N':
+ // Thumb1 only
+ if (isThumb() && !supportsThumb2()) {
+ Info.setRequiresImmediate(0, 31);
+ return true;
+ }
+ break;
+ case 'O':
+ // Thumb1 only
+ if (isThumb() && !supportsThumb2()) {
+ // FIXME: should check if immediate value is a multiple of 4 between -508
+ // and 508
+ Info.setRequiresImmediate();
+ return true;
+ }
+ break;
case 'Q': // A memory address that is a single base register.
Info.setAllowsMemory();
return true;
diff --git a/lib/Basic/Targets/BPF.cpp b/lib/Basic/Targets/BPF.cpp
index 0cf55a58a951..2fe2450b9a65 100644
--- a/lib/Basic/Targets/BPF.cpp
+++ b/lib/Basic/Targets/BPF.cpp
@@ -13,11 +13,18 @@
#include "BPF.h"
#include "Targets.h"
#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
#include "llvm/ADT/StringRef.h"
using namespace clang;
using namespace clang::targets;
+const Builtin::Info BPFTargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+#include "clang/Basic/BuiltinsBPF.def"
+};
+
void BPFTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__bpf__");
@@ -34,3 +41,8 @@ bool BPFTargetInfo::isValidCPUName(StringRef Name) const {
void BPFTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames));
}
+
+ArrayRef<Builtin::Info> BPFTargetInfo::getTargetBuiltins() const {
+ return llvm::makeArrayRef(BuiltinInfo, clang::BPF::LastTSBuiltin -
+ Builtin::FirstTSBuiltin);
+}
diff --git a/lib/Basic/Targets/BPF.h b/lib/Basic/Targets/BPF.h
index 79abd8828a2c..117f81430bf4 100644
--- a/lib/Basic/Targets/BPF.h
+++ b/lib/Basic/Targets/BPF.h
@@ -22,6 +22,8 @@ namespace clang {
namespace targets {
class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
+ static const Builtin::Info BuiltinInfo[];
+
public:
BPFTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
@@ -54,7 +56,7 @@ public:
Features[Name] = Enabled;
}
- ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override;
const char *getClobbers() const override { return ""; }
diff --git a/lib/Basic/Targets/OSTargets.h b/lib/Basic/Targets/OSTargets.h
index 8542311ffa41..cc72a0a39f30 100644
--- a/lib/Basic/Targets/OSTargets.h
+++ b/lib/Basic/Targets/OSTargets.h
@@ -561,6 +561,10 @@ public:
break;
}
}
+ TargetInfo::CallingConvCheckResult
+ checkCallingConvention(CallingConv CC) const override {
+ return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
+ }
};
// RTEMS Target
@@ -618,8 +622,11 @@ protected:
Builder.defineMacro("_XOPEN_SOURCE", "600");
else
Builder.defineMacro("_XOPEN_SOURCE", "500");
- if (Opts.CPlusPlus)
+ if (Opts.CPlusPlus) {
Builder.defineMacro("__C99FEATURES__");
+ Builder.defineMacro("_FILE_OFFSET_BITS", "64");
+ }
+ // GCC restricts the next two to C++.
Builder.defineMacro("_LARGEFILE_SOURCE");
Builder.defineMacro("_LARGEFILE64_SOURCE");
Builder.defineMacro("__EXTENSIONS__");
@@ -768,9 +775,11 @@ public:
if (Triple.getArch() == llvm::Triple::arm) {
// Handled in ARM's setABI().
} else if (Triple.getArch() == llvm::Triple::x86) {
- this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32-S128");
+ this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
+ "i64:64-n8:16:32-S128");
} else if (Triple.getArch() == llvm::Triple::x86_64) {
- this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32:64-S128");
+ this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
+ "i64:64-n8:16:32:64-S128");
} else if (Triple.getArch() == llvm::Triple::mipsel) {
// Handled on mips' setDataLayout.
} else {
diff --git a/lib/Basic/Targets/PPC.cpp b/lib/Basic/Targets/PPC.cpp
index 2a773d999286..a40991048873 100644
--- a/lib/Basic/Targets/PPC.cpp
+++ b/lib/Basic/Targets/PPC.cpp
@@ -54,6 +54,10 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasFloat128 = true;
} else if (Feature == "+power9-vector") {
HasP9Vector = true;
+ } else if (Feature == "+spe") {
+ HasSPE = true;
+ LongDoubleWidth = LongDoubleAlign = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble();
} else if (Feature == "-hard-float") {
FloatABI = SoftFloat;
}
@@ -165,6 +169,10 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__VEC__", "10206");
Builder.defineMacro("__ALTIVEC__");
}
+ if (HasSPE) {
+ Builder.defineMacro("__SPE__");
+ Builder.defineMacro("__NO_FPRS__");
+ }
if (HasVSX)
Builder.defineMacro("__VSX__");
if (HasP8Vector)
@@ -203,7 +211,6 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
// __CMODEL_LARGE__
// _CALL_SYSV
// _CALL_DARWIN
- // __NO_FPRS__
}
// Handle explicit options being passed to the compiler here: if we've
@@ -332,6 +339,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
.Case("extdiv", HasExtDiv)
.Case("float128", HasFloat128)
.Case("power9-vector", HasP9Vector)
+ .Case("spe", HasSPE)
.Default(false);
}
diff --git a/lib/Basic/Targets/PPC.h b/lib/Basic/Targets/PPC.h
index 6e5df097921b..6c6421c28e23 100644
--- a/lib/Basic/Targets/PPC.h
+++ b/lib/Basic/Targets/PPC.h
@@ -66,6 +66,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
bool HasBPERMD = false;
bool HasExtDiv = false;
bool HasP9Vector = false;
+ bool HasSPE = false;
protected:
std::string ABI;
diff --git a/lib/Basic/Targets/RISCV.cpp b/lib/Basic/Targets/RISCV.cpp
index f800bb0b25da..ab8272c034fd 100644
--- a/lib/Basic/Targets/RISCV.cpp
+++ b/lib/Basic/Targets/RISCV.cpp
@@ -19,23 +19,38 @@ using namespace clang::targets;
ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
static const char *const GCCRegNames[] = {
+ // Integer registers
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
"x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
- "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31"};
+ "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31",
+
+ // Floating point registers
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
return llvm::makeArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
- {{"zero"}, "x0"}, {{"ra"}, "x1"}, {{"sp"}, "x2"}, {{"gp"}, "x3"},
- {{"tp"}, "x4"}, {{"t0"}, "x5"}, {{"t1"}, "x6"}, {{"t2"}, "x7"},
- {{"s0"}, "x8"}, {{"s1"}, "x9"}, {{"a0"}, "x10"}, {{"a1"}, "x11"},
- {{"a2"}, "x12"}, {{"a3"}, "x13"}, {{"a4"}, "x14"}, {{"a5"}, "x15"},
- {{"a6"}, "x16"}, {{"a7"}, "x17"}, {{"s2"}, "x18"}, {{"s3"}, "x19"},
- {{"s4"}, "x20"}, {{"s5"}, "x21"}, {{"s6"}, "x22"}, {{"s7"}, "x23"},
- {{"s8"}, "x24"}, {{"s9"}, "x25"}, {{"s10"}, "x26"}, {{"s11"}, "x27"},
- {{"t3"}, "x28"}, {{"t4"}, "x29"}, {{"t5"}, "x30"}, {{"t6"}, "x31"}};
+ {{"zero"}, "x0"}, {{"ra"}, "x1"}, {{"sp"}, "x2"}, {{"gp"}, "x3"},
+ {{"tp"}, "x4"}, {{"t0"}, "x5"}, {{"t1"}, "x6"}, {{"t2"}, "x7"},
+ {{"s0"}, "x8"}, {{"s1"}, "x9"}, {{"a0"}, "x10"}, {{"a1"}, "x11"},
+ {{"a2"}, "x12"}, {{"a3"}, "x13"}, {{"a4"}, "x14"}, {{"a5"}, "x15"},
+ {{"a6"}, "x16"}, {{"a7"}, "x17"}, {{"s2"}, "x18"}, {{"s3"}, "x19"},
+ {{"s4"}, "x20"}, {{"s5"}, "x21"}, {{"s6"}, "x22"}, {{"s7"}, "x23"},
+ {{"s8"}, "x24"}, {{"s9"}, "x25"}, {{"s10"}, "x26"}, {{"s11"}, "x27"},
+ {{"t3"}, "x28"}, {{"t4"}, "x29"}, {{"t5"}, "x30"}, {{"t6"}, "x31"},
+ {{"ft0"}, "f0"}, {{"ft1"}, "f1"}, {{"ft2"}, "f2"}, {{"ft3"}, "f3"},
+ {{"ft4"}, "f4"}, {{"ft5"}, "f5"}, {{"ft6"}, "f6"}, {{"ft7"}, "f7"},
+ {{"fs0"}, "f8"}, {{"fs1"}, "f9"}, {{"fa0"}, "f10"}, {{"fa1"}, "f11"},
+ {{"fa2"}, "f12"}, {{"fa3"}, "f13"}, {{"fa4"}, "f14"}, {{"fa5"}, "f15"},
+ {{"fa6"}, "f16"}, {{"fa7"}, "f17"}, {{"fs2"}, "f18"}, {{"fs3"}, "f19"},
+ {{"fs4"}, "f20"}, {{"fs5"}, "f21"}, {{"fs6"}, "f22"}, {{"fs7"}, "f23"},
+ {{"fs8"}, "f24"}, {{"fs9"}, "f25"}, {{"fs10"}, "f26"}, {{"fs11"}, "f27"},
+ {{"ft8"}, "f28"}, {{"ft9"}, "f29"}, {{"ft10"}, "f30"}, {{"ft11"}, "f31"}};
return llvm::makeArrayRef(GCCRegAliases);
}
@@ -56,6 +71,14 @@ bool RISCVTargetInfo::validateAsmConstraint(
// A 5-bit unsigned immediate for CSR access instructions.
Info.setRequiresImmediate(0, 31);
return true;
+ case 'f':
+ // A floating-point register.
+ Info.setAllowsRegister();
+ return true;
+ case 'A':
+ // An address that is held in a general-purpose register.
+ Info.setAllowsMemory();
+ return true;
}
}
@@ -65,9 +88,25 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__riscv");
bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
- // TODO: modify when more code models and ABIs are supported.
- Builder.defineMacro("__riscv_cmodel_medlow");
- Builder.defineMacro("__riscv_float_abi_soft");
+ StringRef CodeModel = getTargetOpts().CodeModel;
+ if (CodeModel == "default")
+ CodeModel = "small";
+
+ if (CodeModel == "small")
+ Builder.defineMacro("__riscv_cmodel_medlow");
+ else if (CodeModel == "medium")
+ Builder.defineMacro("__riscv_cmodel_medany");
+
+ StringRef ABIName = getABI();
+ if (ABIName == "ilp32f" || ABIName == "lp64f")
+ Builder.defineMacro("__riscv_float_abi_single");
+ else if (ABIName == "ilp32d" || ABIName == "lp64d")
+ Builder.defineMacro("__riscv_float_abi_double");
+ else
+ Builder.defineMacro("__riscv_float_abi_soft");
+
+ if (ABIName == "ilp32e")
+ Builder.defineMacro("__riscv_abi_rve");
if (HasM) {
Builder.defineMacro("__riscv_mul");
diff --git a/lib/Basic/Targets/RISCV.h b/lib/Basic/Targets/RISCV.h
index bc814b79ce51..9118494a87ab 100644
--- a/lib/Basic/Targets/RISCV.h
+++ b/lib/Basic/Targets/RISCV.h
@@ -87,13 +87,19 @@ public:
}
bool setABI(const std::string &Name) override {
- // TODO: support ilp32f and ilp32d ABIs.
- if (Name == "ilp32") {
+ if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
ABI = Name;
return true;
}
return false;
}
+
+ void setMaxAtomicWidth() override {
+ MaxAtomicPromoteWidth = 128;
+
+ if (HasA)
+ MaxAtomicInlineWidth = 32;
+ }
};
class LLVM_LIBRARY_VISIBILITY RISCV64TargetInfo : public RISCVTargetInfo {
public:
@@ -105,13 +111,19 @@ public:
}
bool setABI(const std::string &Name) override {
- // TODO: support lp64f and lp64d ABIs.
- if (Name == "lp64") {
+ if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
ABI = Name;
return true;
}
return false;
}
+
+ void setMaxAtomicWidth() override {
+ MaxAtomicPromoteWidth = 128;
+
+ if (HasA)
+ MaxAtomicInlineWidth = 64;
+ }
};
} // namespace targets
} // namespace clang
diff --git a/lib/Basic/Targets/SPIR.h b/lib/Basic/Targets/SPIR.h
index 6023c868dbdc..802ccf8b671e 100644
--- a/lib/Basic/Targets/SPIR.h
+++ b/lib/Basic/Targets/SPIR.h
@@ -88,7 +88,7 @@ public:
: CCCR_Warning;
}
- CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
+ CallingConv getDefaultCallingConv() const override {
return CC_SpirFunction;
}
diff --git a/lib/Basic/Targets/Sparc.h b/lib/Basic/Targets/Sparc.h
index 963192a4634f..1f799565e99b 100644
--- a/lib/Basic/Targets/Sparc.h
+++ b/lib/Basic/Targets/Sparc.h
@@ -208,6 +208,7 @@ public:
// aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
LongDoubleWidth = 128;
LongDoubleAlign = 128;
+ SuitableAlign = 128;
LongDoubleFormat = &llvm::APFloat::IEEEquad();
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
}
diff --git a/lib/Basic/Targets/SystemZ.cpp b/lib/Basic/Targets/SystemZ.cpp
index d86928a6333b..ad3915e4d5dd 100644
--- a/lib/Basic/Targets/SystemZ.cpp
+++ b/lib/Basic/Targets/SystemZ.cpp
@@ -92,7 +92,7 @@ static constexpr ISANameRevision ISARevisions[] = {
{{"arch10"}, 10}, {{"zEC12"}, 10},
{{"arch11"}, 11}, {{"z13"}, 11},
{{"arch12"}, 12}, {{"z14"}, 12},
- {{"arch13"}, 13},
+ {{"arch13"}, 13}, {{"z15"}, 13}
};
int SystemZTargetInfo::getISARevision(StringRef Name) const {
diff --git a/lib/Basic/Targets/X86.cpp b/lib/Basic/Targets/X86.cpp
index d618c90b05c0..311ae6e17028 100644
--- a/lib/Basic/Targets/X86.cpp
+++ b/lib/Basic/Targets/X86.cpp
@@ -157,11 +157,20 @@ bool X86TargetInfo::initFeatureMap(
// SkylakeServer cores inherits all SKL features, except SGX
goto SkylakeCommon;
+ case CK_Tigerlake:
+ setFeatureEnabledImpl(Features, "avx512vp2intersect", true);
+ setFeatureEnabledImpl(Features, "movdiri", true);
+ setFeatureEnabledImpl(Features, "movdir64b", true);
+ setFeatureEnabledImpl(Features, "shstk", true);
+ // Tigerlake cores inherits IcelakeClient, except pconfig and wbnoinvd
+ goto IcelakeCommon;
+
case CK_IcelakeServer:
setFeatureEnabledImpl(Features, "pconfig", true);
setFeatureEnabledImpl(Features, "wbnoinvd", true);
LLVM_FALLTHROUGH;
case CK_IcelakeClient:
+IcelakeCommon:
setFeatureEnabledImpl(Features, "vaes", true);
setFeatureEnabledImpl(Features, "gfni", true);
setFeatureEnabledImpl(Features, "vpclmulqdq", true);
@@ -189,7 +198,6 @@ bool X86TargetInfo::initFeatureMap(
SkylakeCommon:
setFeatureEnabledImpl(Features, "xsavec", true);
setFeatureEnabledImpl(Features, "xsaves", true);
- setFeatureEnabledImpl(Features, "mpx", true);
setFeatureEnabledImpl(Features, "clflushopt", true);
setFeatureEnabledImpl(Features, "aes", true);
LLVM_FALLTHROUGH;
@@ -268,7 +276,6 @@ SkylakeCommon:
setFeatureEnabledImpl(Features, "xsavec", true);
setFeatureEnabledImpl(Features, "xsaves", true);
setFeatureEnabledImpl(Features, "clflushopt", true);
- setFeatureEnabledImpl(Features, "mpx", true);
setFeatureEnabledImpl(Features, "fsgsbase", true);
setFeatureEnabledImpl(Features, "aes", true);
LLVM_FALLTHROUGH;
@@ -789,8 +796,6 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasAVX512VP2INTERSECT = true;
} else if (Feature == "+sha") {
HasSHA = true;
- } else if (Feature == "+mpx") {
- HasMPX = true;
} else if (Feature == "+shstk") {
HasSHSTK = true;
} else if (Feature == "+movbe") {
@@ -895,7 +900,7 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
/// definitions for this particular subtarget.
void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
- // Inline assembly supports X86 flag outputs.
+ // Inline assembly supports X86 flag outputs.
Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
std::string CodeModel = getTargetOpts().CodeModel;
@@ -1000,6 +1005,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Cannonlake:
case CK_IcelakeClient:
case CK_IcelakeServer:
+ case CK_Tigerlake:
// FIXME: Historically, we defined this legacy name, it would be nice to
// remove it at some point. We've never exposed fine-grained names for
// recent primary x86 CPUs, and we should keep it that way.
@@ -1210,8 +1216,6 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__CLWB__");
if (HasWBNOINVD)
Builder.defineMacro("__WBNOINVD__");
- if (HasMPX)
- Builder.defineMacro("__MPX__");
if (HasSHSTK)
Builder.defineMacro("__SHSTK__");
if (HasSGX)
@@ -1368,7 +1372,6 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("movbe", true)
.Case("movdiri", true)
.Case("movdir64b", true)
- .Case("mpx", true)
.Case("mwaitx", true)
.Case("pclmul", true)
.Case("pconfig", true)
@@ -1452,7 +1455,6 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("movbe", HasMOVBE)
.Case("movdiri", HasMOVDIRI)
.Case("movdir64b", HasMOVDIR64B)
- .Case("mpx", HasMPX)
.Case("mwaitx", HasMWAITX)
.Case("pclmul", HasPCLMUL)
.Case("pconfig", HasPCONFIG)
diff --git a/lib/Basic/Targets/X86.h b/lib/Basic/Targets/X86.h
index 588b6d3da1d6..cad869f71230 100644
--- a/lib/Basic/Targets/X86.h
+++ b/lib/Basic/Targets/X86.h
@@ -80,7 +80,6 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasAVX512IFMA = false;
bool HasAVX512VP2INTERSECT = false;
bool HasSHA = false;
- bool HasMPX = false;
bool HasSHSTK = false;
bool HasSGX = false;
bool HasCX8 = false;
@@ -320,8 +319,8 @@ public:
}
}
- CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
- return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
+ CallingConv getDefaultCallingConv() const override {
+ return CC_C;
}
bool hasSjLjLowering() const override { return true; }
@@ -340,7 +339,8 @@ public:
LongDoubleWidth = 96;
LongDoubleAlign = 32;
SuitableAlign = 128;
- resetDataLayout("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128");
+ resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
+ "f80:32-n8:16:32-S128");
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
IntPtrType = SignedInt;
@@ -440,7 +440,8 @@ public:
UseSignedCharForObjCBool = false;
SizeType = UnsignedLong;
IntPtrType = SignedLong;
- resetDataLayout("e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128");
+ resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
+ "f80:128-n8:16:32-S128");
HasAlignMac68kSupport = true;
}
@@ -465,9 +466,10 @@ public:
DoubleAlign = LongLongAlign = 64;
bool IsWinCOFF =
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
- resetDataLayout(IsWinCOFF
- ? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
- : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32");
+ resetDataLayout(IsWinCOFF ? "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:"
+ "64-i64:64-f80:32-n8:16:32-a:0:32-S32"
+ : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:"
+ "64-i64:64-f80:32-n8:16:32-a:0:32-S32");
}
};
@@ -515,7 +517,8 @@ public:
: X86_32TargetInfo(Triple, Opts) {
this->WCharType = TargetInfo::UnsignedShort;
DoubleAlign = LongLongAlign = 64;
- resetDataLayout("e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32");
+ resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:"
+ "32-n8:16:32-a:0:32-S32");
}
void getTargetDefines(const LangOptions &Opts,
@@ -552,7 +555,8 @@ public:
: X86_32TargetInfo(Triple, Opts) {
LongDoubleWidth = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
- resetDataLayout("e-m:e-p:32:32-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32");
+ resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:"
+ "32-f128:32-n8:16:32-a:0:32-S32");
WIntType = UnsignedInt;
}
@@ -611,10 +615,12 @@ public:
RegParmMax = 6;
// Pointers are 32-bit in x32.
- resetDataLayout(IsX32
- ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128"
- : IsWinCOFF ? "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
- : "e-m:e-i64:64-f80:128-n8:16:32:64-S128");
+ resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
+ "i64:64-f80:128-n8:16:32:64-S128"
+ : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:"
+ "64-i64:64-f80:128-n8:16:32:64-S128"
+ : "e-m:e-p270:32:32-p271:32:32-p272:64:"
+ "64-i64:64-f80:128-n8:16:32:64-S128");
// Use fpret only for long double.
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
@@ -659,7 +665,7 @@ public:
}
}
- CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
+ CallingConv getDefaultCallingConv() const override {
return CC_C;
}
@@ -804,7 +810,8 @@ public:
llvm::Triple T = llvm::Triple(Triple);
if (T.isiOS())
UseSignedCharForObjCBool = false;
- resetDataLayout("e-m:o-i64:64-f80:128-n8:16:32:64-S128");
+ resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:"
+ "16:32:64-S128");
}
bool handleTargetFeatures(std::vector<std::string> &Features,
diff --git a/lib/Basic/TokenKinds.cpp b/lib/Basic/TokenKinds.cpp
index a71cd72517de..d55e176c72c4 100644
--- a/lib/Basic/TokenKinds.cpp
+++ b/lib/Basic/TokenKinds.cpp
@@ -45,3 +45,23 @@ const char *tok::getKeywordSpelling(TokenKind Kind) {
}
return nullptr;
}
+
+bool tok::isAnnotation(TokenKind Kind) {
+ switch (Kind) {
+#define ANNOTATION(X) case annot_ ## X: return true;
+#include "clang/Basic/TokenKinds.def"
+ default:
+ break;
+ }
+ return false;
+}
+
+bool tok::isPragmaAnnotation(TokenKind Kind) {
+ switch (Kind) {
+#define PRAGMA_ANNOTATION(X) case annot_ ## X: return true;
+#include "clang/Basic/TokenKinds.def"
+ default:
+ break;
+ }
+ return false;
+}