summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Basic
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
committerdim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
commit9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch)
treec978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/tools/clang/lib/Basic
parent03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff)
downloadFreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip
FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC 262121 (by emaste): Update lldb for clang/llvm 3.4 import This commit largely restores the lldb source to the upstream r196259 snapshot with the addition of threaded inferior support and a few bug fixes. Specific upstream lldb revisions restored include: SVN git 181387 779e6ac 181703 7bef4e2 182099 b31044e 182650 f2dcf35 182683 0d91b80 183862 15c1774 183929 99447a6 184177 0b2934b 184948 4dc3761 184954 007e7bc 186990 eebd175 Sponsored by: DARPA, AFRL MFC 262186 (by emaste): Fix mismerge in r262121 A break statement was lost in the merge. The error had no functional impact, but restore it to reduce the diff against upstream. MFC 262303: Pull in r197521 from upstream clang trunk (by rdivacky): Use the integrated assembler by default on FreeBSD/ppc and ppc64. Requested by: jhibbits MFC 262611: Pull in r196874 from upstream llvm trunk: Fix a crash that occurs when PWD is invalid. MCJIT needs to be able to run in hostile environments, even when PWD is invalid. There's no need to crash MCJIT in this case. The obvious fix is to simply leave MCContext's CompilationDir empty when PWD can't be determined. This way, MCJIT clients, and other clients that link with LLVM don't need a valid working directory. If we do want to guarantee valid CompilationDir, that should be done only for clients of getCompilationDir(). This is as simple as checking for an empty string. The only current use of getCompilationDir is EmitGenDwarfInfo, which won't conceivably run with an invalid working dir. However, in the purely hypothetically and untestable case that this happens, the AT_comp_dir will be omitted from the compilation_unit DIE. This should help fix assertions occurring with ports-mgmt/tinderbox, when it is using jails, and sometimes invalidates clang's current working directory. Reported by: decke MFC 262809: Pull in r203007 from upstream clang trunk: Don't produce an alias between destructors with different calling conventions. Fixes pr19007. (Please note that is an LLVM PR identifier, not a FreeBSD one.) This should fix Firefox and/or libxul crashes (due to problems with regparm/stdcall calling conventions) on i386. Reported by: multiple users on freebsd-current PR: bin/187103 MFC 263048: Repair recognition of "CC" as an alias for the C++ compiler, since it was silently broken by upstream for a Windows-specific use-case. Apparently some versions of CMake still rely on this archaic feature... Reported by: rakuco MFC 263049: Garbage collect the old way of adding the libstdc++ include directories in clang's InitHeaderSearch.cpp. This has been superseded by David Chisnall's commit in r255321. Moreover, if libc++ is used, the libstdc++ include directories should not be in the search path at all. These directories are now only used if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Builtins.cpp32
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp104
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/FileManager.cpp149
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp60
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp52
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Module.cpp84
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp94
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp216
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp79
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp2173
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Version.cpp2
13 files changed, 1855 insertions, 1200 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp
index 242c204..c84dd6d 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp
@@ -16,11 +16,13 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
using namespace clang;
static const Builtin::Info BuiltinInfo[] = {
{ "not a builtin function", 0, 0, 0, ALL_LANGUAGES },
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) { #ID, TYPE, ATTRS, 0, BUILTIN_LANG },
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, BUILTIN_LANG) { #ID, TYPE, ATTRS, HEADER,\
BUILTIN_LANG },
#include "clang/Basic/Builtins.def"
@@ -44,6 +46,23 @@ void Builtin::Context::InitializeTarget(const TargetInfo &Target) {
Target.getTargetBuiltins(TSRecords, NumTSRecords);
}
+bool Builtin::Context::BuiltinIsSupported(const Builtin::Info &BuiltinInfo,
+ const LangOptions &LangOpts) {
+ bool BuiltinsUnsupported = LangOpts.NoBuiltin &&
+ strchr(BuiltinInfo.Attributes, 'f');
+ bool MathBuiltinsUnsupported =
+ LangOpts.NoMathBuiltin && BuiltinInfo.HeaderName &&
+ llvm::StringRef(BuiltinInfo.HeaderName).equals("math.h");
+ bool GnuModeUnsupported = !LangOpts.GNUMode &&
+ (BuiltinInfo.builtin_lang & GNU_LANG);
+ bool MSModeUnsupported = !LangOpts.MicrosoftExt &&
+ (BuiltinInfo.builtin_lang & MS_LANG);
+ bool ObjCUnsupported = !LangOpts.ObjC1 &&
+ BuiltinInfo.builtin_lang == OBJC_LANG;
+ return !BuiltinsUnsupported && !MathBuiltinsUnsupported &&
+ !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported;
+}
+
/// InitializeBuiltins - Mark the identifiers for all the builtins with their
/// appropriate builtin ID # and mark any non-portable builtin identifiers as
/// such.
@@ -51,10 +70,8 @@ void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
const LangOptions& LangOpts) {
// Step #1: mark all target-independent builtins with their ID's.
for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
- if (!LangOpts.NoBuiltin || !strchr(BuiltinInfo[i].Attributes, 'f')) {
- if (LangOpts.ObjC1 ||
- BuiltinInfo[i].builtin_lang != clang::OBJC_LANG)
- Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
+ if (BuiltinIsSupported(BuiltinInfo[i], LangOpts)) {
+ Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
}
// Step #2: Register target-specific builtins.
@@ -64,16 +81,15 @@ void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
}
void
-Builtin::Context::GetBuiltinNames(SmallVectorImpl<const char *> &Names,
- bool NoBuiltins) {
+Builtin::Context::GetBuiltinNames(SmallVectorImpl<const char *> &Names) {
// Final all target-independent names
for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
- if (!NoBuiltins || !strchr(BuiltinInfo[i].Attributes, 'f'))
+ if (!strchr(BuiltinInfo[i].Attributes, 'f'))
Names.push_back(BuiltinInfo[i].Name);
// Find target-specific names.
for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
- if (!NoBuiltins || !strchr(TSRecords[i].Attributes, 'f'))
+ if (!strchr(TSRecords[i].Attributes, 'f'))
Names.push_back(TSRecords[i].Name);
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp
index 353af4b..9d99fbe 100644
--- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp
@@ -16,6 +16,7 @@
#include "clang/Basic/DiagnosticCategories.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include <map>
using namespace clang;
@@ -35,11 +36,10 @@ enum {
};
struct StaticDiagInfoRec {
- unsigned short DiagID;
+ uint16_t DiagID;
unsigned Mapping : 3;
unsigned Class : 3;
- unsigned SFINAE : 1;
- unsigned AccessControl : 1;
+ unsigned SFINAE : 2;
unsigned WarnNoWerror : 1;
unsigned WarnShowInSystemHeader : 1;
unsigned Category : 5;
@@ -66,9 +66,9 @@ struct StaticDiagInfoRec {
static const StaticDiagInfoRec StaticDiagInfo[] = {
#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \
- SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER, \
- CATEGORY) \
- { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS, \
+ SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) \
+ { diag::ENUM, DEFAULT_MAPPING, CLASS, \
+ DiagnosticIDs::SFINAE, \
NOWERROR, SHOWINSYSHEADER, CATEGORY, GROUP, \
STR_SIZE(DESC, uint16_t), DESC },
#include "clang/Basic/DiagnosticCommonKinds.inc"
@@ -82,18 +82,16 @@ static const StaticDiagInfoRec StaticDiagInfo[] = {
#include "clang/Basic/DiagnosticSemaKinds.inc"
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
#undef DIAG
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
-static const unsigned StaticDiagInfoSize =
- sizeof(StaticDiagInfo)/sizeof(StaticDiagInfo[0])-1;
+static const unsigned StaticDiagInfoSize = llvm::array_lengthof(StaticDiagInfo);
/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
/// or null if the ID is invalid.
static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
// If assertions are enabled, verify that the StaticDiagInfo array is sorted.
#ifndef NDEBUG
- static bool IsFirst = true;
+ static bool IsFirst = true; // So the check is only performed on first call.
if (IsFirst) {
for (unsigned i = 1; i != StaticDiagInfoSize; ++i) {
assert(StaticDiagInfo[i-1].DiagID != StaticDiagInfo[i].DiagID &&
@@ -109,7 +107,7 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
// Out of bounds diag. Can't be in the table.
using namespace diag;
- if (DiagID >= DIAG_UPPER_LIMIT)
+ if (DiagID >= DIAG_UPPER_LIMIT || DiagID <= DIAG_START_COMMON)
return 0;
// Compute the index of the requested diagnostic in the static table.
@@ -121,8 +119,7 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
// This is cheaper than a binary search on the table as it doesn't touch
// memory at all.
unsigned Offset = 0;
- unsigned ID = DiagID;
-#define DIAG_START_COMMON 0 // Sentinel value.
+ unsigned ID = DiagID - DIAG_START_COMMON - 1;
#define CATEGORY(NAME, PREV) \
if (DiagID > DIAG_START_##NAME) { \
Offset += NUM_BUILTIN_##PREV##_DIAGNOSTICS - DIAG_START_##PREV - 1; \
@@ -138,7 +135,6 @@ CATEGORY(COMMENT, AST)
CATEGORY(SEMA, COMMENT)
CATEGORY(ANALYSIS, SEMA)
#undef CATEGORY
-#undef DIAG_START_COMMON
// Avoid out of bounds reads.
if (ID + Offset >= StaticDiagInfoSize)
@@ -224,7 +220,7 @@ static const StaticDiagCategoryRec CategoryNameTable[] = {
/// getNumberOfCategories - Return the number of categories
unsigned DiagnosticIDs::getNumberOfCategories() {
- return sizeof(CategoryNameTable) / sizeof(CategoryNameTable[0])-1;
+ return llvm::array_lengthof(CategoryNameTable) - 1;
}
/// getCategoryNameFromID - Given a category ID, return the name of the
@@ -238,22 +234,10 @@ StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
-DiagnosticIDs::SFINAEResponse
+DiagnosticIDs::SFINAEResponse
DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
- if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
- if (Info->AccessControl)
- return SFINAE_AccessControl;
-
- if (!Info->SFINAE)
- return SFINAE_Report;
-
- if (Info->Class == CLASS_ERROR)
- return SFINAE_SubstitutionFailure;
-
- // Suppress notes, warnings, and extensions;
- return SFINAE_Suppress;
- }
-
+ if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+ return static_cast<DiagnosticIDs::SFINAEResponse>(Info->SFINAE);
return SFINAE_Report;
}
@@ -504,36 +488,34 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
return Result;
}
-struct clang::WarningOption {
- // Be safe with the size of 'NameLen' because we don't statically check if
- // the size will fit in the field; the struct size won't decrease with a
- // shorter type anyway.
- size_t NameLen;
- const char *NameStr;
- const short *Members;
- const short *SubGroups;
-
- StringRef getName() const {
- return StringRef(NameStr, NameLen);
- }
-};
-
#define GET_DIAG_ARRAYS
#include "clang/Basic/DiagnosticGroups.inc"
#undef GET_DIAG_ARRAYS
+namespace {
+ struct WarningOption {
+ uint16_t NameOffset;
+ uint16_t Members;
+ uint16_t SubGroups;
+
+ // String is stored with a pascal-style length byte.
+ StringRef getName() const {
+ return StringRef(DiagGroupNames + NameOffset + 1,
+ DiagGroupNames[NameOffset]);
+ }
+ };
+}
+
// Second the table of options, sorted by name for fast binary lookup.
static const WarningOption OptionTable[] = {
#define GET_DIAG_TABLE
#include "clang/Basic/DiagnosticGroups.inc"
#undef GET_DIAG_TABLE
};
-static const size_t OptionTableSize =
-sizeof(OptionTable) / sizeof(OptionTable[0]);
+static const size_t OptionTableSize = llvm::array_lengthof(OptionTable);
-static bool WarningOptionCompare(const WarningOption &LHS,
- const WarningOption &RHS) {
- return LHS.getName() < RHS.getName();
+static bool WarningOptionCompare(const WarningOption &LHS, StringRef RHS) {
+ return LHS.getName() < RHS;
}
/// getWarningOptionForDiag - Return the lowest-level warning option that
@@ -545,34 +527,30 @@ StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
return StringRef();
}
-void DiagnosticIDs::getDiagnosticsInGroup(
- const WarningOption *Group,
- SmallVectorImpl<diag::kind> &Diags) const {
+static void getDiagnosticsInGroup(const WarningOption *Group,
+ SmallVectorImpl<diag::kind> &Diags) {
// Add the members of the option diagnostic set.
- if (const short *Member = Group->Members) {
- for (; *Member != -1; ++Member)
- Diags.push_back(*Member);
- }
+ const int16_t *Member = DiagArrays + Group->Members;
+ for (; *Member != -1; ++Member)
+ Diags.push_back(*Member);
// Add the members of the subgroups.
- if (const short *SubGroups = Group->SubGroups) {
- for (; *SubGroups != (short)-1; ++SubGroups)
- getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
- }
+ const int16_t *SubGroups = DiagSubGroups + Group->SubGroups;
+ for (; *SubGroups != (int16_t)-1; ++SubGroups)
+ getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
}
bool DiagnosticIDs::getDiagnosticsInGroup(
StringRef Group,
SmallVectorImpl<diag::kind> &Diags) const {
- WarningOption Key = { Group.size(), Group.data(), 0, 0 };
const WarningOption *Found =
- std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
+ std::lower_bound(OptionTable, OptionTable + OptionTableSize, Group,
WarningOptionCompare);
if (Found == OptionTable + OptionTableSize ||
Found->getName() != Group)
return true; // Option not found.
- getDiagnosticsInGroup(Found, Diags);
+ ::getDiagnosticsInGroup(Found, Diags);
return false;
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp
index 9cc5902..af9b266 100644
--- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp
@@ -63,91 +63,16 @@ FileEntry::~FileEntry() {
if (FD != -1) ::close(FD);
}
-bool FileEntry::isNamedPipe() const {
- return S_ISFIFO(FileMode);
-}
-
-//===----------------------------------------------------------------------===//
-// Windows.
-//===----------------------------------------------------------------------===//
-
-#ifdef LLVM_ON_WIN32
-
-namespace {
- static std::string GetFullPath(const char *relPath) {
- char *absPathStrPtr = _fullpath(NULL, relPath, 0);
- assert(absPathStrPtr && "_fullpath() returned NULL!");
-
- std::string absPath(absPathStrPtr);
-
- free(absPathStrPtr);
- return absPath;
- }
-}
-
-class FileManager::UniqueDirContainer {
- /// UniqueDirs - Cache from full path to existing directories/files.
- ///
- llvm::StringMap<DirectoryEntry> UniqueDirs;
-
-public:
- /// getDirectory - Return an existing DirectoryEntry with the given
- /// name if there is already one; otherwise create and return a
- /// default-constructed DirectoryEntry.
- DirectoryEntry &getDirectory(const char *Name,
- const struct stat & /*StatBuf*/) {
- std::string FullPath(GetFullPath(Name));
- return UniqueDirs.GetOrCreateValue(FullPath).getValue();
- }
-
- size_t size() const { return UniqueDirs.size(); }
-};
-
-class FileManager::UniqueFileContainer {
- /// UniqueFiles - Cache from full path to existing directories/files.
- ///
- llvm::StringMap<FileEntry, llvm::BumpPtrAllocator> UniqueFiles;
-
-public:
- /// getFile - Return an existing FileEntry with the given name if
- /// there is already one; otherwise create and return a
- /// default-constructed FileEntry.
- FileEntry &getFile(const char *Name, const struct stat & /*StatBuf*/) {
- std::string FullPath(GetFullPath(Name));
-
- // Lowercase string because Windows filesystem is case insensitive.
- FullPath = StringRef(FullPath).lower();
- return UniqueFiles.GetOrCreateValue(FullPath).getValue();
- }
-
- size_t size() const { return UniqueFiles.size(); }
-
- void erase(const FileEntry *Entry) {
- std::string FullPath(GetFullPath(Entry->getName()));
-
- // Lowercase string because Windows filesystem is case insensitive.
- FullPath = StringRef(FullPath).lower();
- UniqueFiles.erase(FullPath);
- }
-};
-
-//===----------------------------------------------------------------------===//
-// Unix-like Systems.
-//===----------------------------------------------------------------------===//
-
-#else
-
class FileManager::UniqueDirContainer {
/// UniqueDirs - Cache from ID's to existing directories/files.
- std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;
+ std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueDirs;
public:
/// getDirectory - Return an existing DirectoryEntry with the given
/// ID's if there is already one; otherwise create and return a
/// default-constructed DirectoryEntry.
- DirectoryEntry &getDirectory(const char * /*Name*/,
- const struct stat &StatBuf) {
- return UniqueDirs[std::make_pair(StatBuf.st_dev, StatBuf.st_ino)];
+ DirectoryEntry &getDirectory(const llvm::sys::fs::UniqueID &UniqueID) {
+ return UniqueDirs[UniqueID];
}
size_t size() const { return UniqueDirs.size(); }
@@ -161,12 +86,10 @@ public:
/// getFile - Return an existing FileEntry with the given ID's if
/// there is already one; otherwise create and return a
/// default-constructed FileEntry.
- FileEntry &getFile(const char * /*Name*/, const struct stat &StatBuf) {
- return
- const_cast<FileEntry&>(
- *UniqueFiles.insert(FileEntry(StatBuf.st_dev,
- StatBuf.st_ino,
- StatBuf.st_mode)).first);
+ FileEntry &getFile(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe,
+ bool InPCH) {
+ return const_cast<FileEntry &>(
+ *UniqueFiles.insert(FileEntry(UniqueID, IsNamedPipe, InPCH)).first);
}
size_t size() const { return UniqueFiles.size(); }
@@ -174,8 +97,6 @@ public:
void erase(const FileEntry *Entry) { UniqueFiles.erase(*Entry); }
};
-#endif
-
//===----------------------------------------------------------------------===//
// Common logic.
//===----------------------------------------------------------------------===//
@@ -292,6 +213,16 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
DirName != llvm::sys::path::root_path(DirName) &&
llvm::sys::path::is_separator(DirName.back()))
DirName = DirName.substr(0, DirName.size()-1);
+#ifdef LLVM_ON_WIN32
+ // Fixing a problem with "clang C:test.c" on Windows.
+ // Stat("C:") does not recognize "C:" as a valid directory
+ std::string DirNameStr;
+ if (DirName.size() > 1 && DirName.back() == ':' &&
+ DirName.equals_lower(llvm::sys::path::root_name(DirName))) {
+ DirNameStr = DirName.str() + '.';
+ DirName = DirNameStr;
+ }
+#endif
++NumDirLookups;
llvm::StringMapEntry<DirectoryEntry *> &NamedDirEnt =
@@ -313,8 +244,8 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
const char *InterndDirName = NamedDirEnt.getKeyData();
// Check to see if the directory exists.
- struct stat StatBuf;
- if (getStatValue(InterndDirName, StatBuf, false, 0/*directory lookup*/)) {
+ FileData Data;
+ if (getStatValue(InterndDirName, Data, false, 0 /*directory lookup*/)) {
// There's no real directory at the given path.
if (!CacheFailure)
SeenDirEntries.erase(DirName);
@@ -325,7 +256,8 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
// same inode (this occurs on Unix-like systems when one dir is
// symlinked to another, for example) or the same path (on
// Windows).
- DirectoryEntry &UDE = UniqueRealDirs.getDirectory(InterndDirName, StatBuf);
+ DirectoryEntry &UDE =
+ UniqueRealDirs.getDirectory(Data.UniqueID);
NamedDirEnt.setValue(&UDE);
if (!UDE.getName()) {
@@ -378,8 +310,8 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// Nope, there isn't. Check to see if the file exists.
int FileDescriptor = -1;
- struct stat StatBuf;
- if (getStatValue(InterndFileName, StatBuf, true,
+ FileData Data;
+ if (getStatValue(InterndFileName, Data, true,
openFile ? &FileDescriptor : 0)) {
// There's no real file at the given path.
if (!CacheFailure)
@@ -395,7 +327,8 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// It exists. See if we have already opened a file with the same inode.
// This occurs when one dir is symlinked to another, for example.
- FileEntry &UFE = UniqueRealFiles.getFile(InterndFileName, StatBuf);
+ FileEntry &UFE =
+ UniqueRealFiles.getFile(Data.UniqueID, Data.IsNamedPipe, Data.InPCH);
NamedFileEnt.setValue(&UFE);
if (UFE.getName()) { // Already have an entry with this inode, return it.
@@ -410,8 +343,8 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
// FIXME: Change the name to be a char* that points back to the
// 'SeenFileEntries' key.
UFE.Name = InterndFileName;
- UFE.Size = StatBuf.st_size;
- UFE.ModTime = StatBuf.st_mtime;
+ UFE.Size = Data.Size;
+ UFE.ModTime = Data.ModTime;
UFE.Dir = DirInfo;
UFE.UID = NextFileUID++;
UFE.FD = FileDescriptor;
@@ -448,12 +381,12 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size,
"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
- struct stat StatBuf;
+ FileData Data;
const char *InterndFileName = NamedFileEnt.getKeyData();
- if (getStatValue(InterndFileName, StatBuf, true, 0) == 0) {
- StatBuf.st_size = Size;
- StatBuf.st_mtime = ModificationTime;
- UFE = &UniqueRealFiles.getFile(InterndFileName, StatBuf);
+ if (getStatValue(InterndFileName, Data, true, 0) == 0) {
+ Data.Size = Size;
+ Data.ModTime = ModificationTime;
+ UFE = &UniqueRealFiles.getFile(Data.UniqueID, Data.IsNamedPipe, Data.InPCH);
NamedFileEnt.setValue(UFE);
@@ -562,27 +495,27 @@ getBufferForFile(StringRef Filename, std::string *ErrorStr) {
/// 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, struct stat &StatBuf,
- bool isFile, int *FileDescriptor) {
+bool FileManager::getStatValue(const char *Path, FileData &Data, bool isFile,
+ int *FileDescriptor) {
// FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
// absolute!
if (FileSystemOpts.WorkingDir.empty())
- return FileSystemStatCache::get(Path, StatBuf, isFile, FileDescriptor,
+ return FileSystemStatCache::get(Path, Data, isFile, FileDescriptor,
StatCache.get());
SmallString<128> FilePath(Path);
FixupRelativePath(FilePath);
- return FileSystemStatCache::get(FilePath.c_str(), StatBuf,
- isFile, FileDescriptor, StatCache.get());
+ return FileSystemStatCache::get(FilePath.c_str(), Data, isFile,
+ FileDescriptor, StatCache.get());
}
-bool FileManager::getNoncachedStatValue(StringRef Path,
- struct stat &StatBuf) {
+bool FileManager::getNoncachedStatValue(StringRef Path,
+ llvm::sys::fs::file_status &Result) {
SmallString<128> FilePath(Path);
FixupRelativePath(FilePath);
- return ::stat(FilePath.c_str(), &StatBuf) != 0;
+ return llvm::sys::fs::status(FilePath.c_str(), Result);
}
void FileManager::invalidateCache(const FileEntry *Entry) {
@@ -610,7 +543,7 @@ void FileManager::GetUniqueIDMapping(
UIDToFiles[FE->getValue()->getUID()] = FE->getValue();
// Map virtual file entries
- for (SmallVector<FileEntry*, 4>::const_iterator
+ for (SmallVectorImpl<FileEntry *>::const_iterator
VFE = VirtualFileEntries.begin(), VFEEnd = VirtualFileEntries.end();
VFE != VFEEnd; ++VFE)
if (*VFE && *VFE != NON_EXISTENT_FILE)
diff --git a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp
index 38c4629..7a01bff 100644
--- a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/FileSystemStatCache.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-#include <fcntl.h>
// FIXME: This is terrible, we need this for ::close.
#if !defined(_MSC_VER) && !defined(__MINGW32__)
@@ -30,6 +30,16 @@ using namespace clang;
void FileSystemStatCache::anchor() { }
+static void copyStatusToFileData(const llvm::sys::fs::file_status &Status,
+ FileData &Data) {
+ Data.Size = Status.getSize();
+ Data.ModTime = Status.getLastModificationTime().toEpochTime();
+ Data.UniqueID = Status.getUniqueID();
+ Data.IsDirectory = is_directory(Status);
+ Data.IsNamedPipe = Status.type() == llvm::sys::fs::file_type::fifo_file;
+ Data.InPCH = false;
+}
+
/// FileSystemStatCache::get - Get the 'stat' information for the specified
/// path, using the cache to accelerate it if possible. This returns true if
/// the path does not exist or false if it exists.
@@ -39,19 +49,24 @@ void FileSystemStatCache::anchor() { }
/// 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, struct stat &StatBuf,
- bool isFile, int *FileDescriptor,
- FileSystemStatCache *Cache) {
+bool FileSystemStatCache::get(const char *Path, FileData &Data, bool isFile,
+ int *FileDescriptor, FileSystemStatCache *Cache) {
LookupResult R;
bool isForDir = !isFile;
// If we have a cache, use it to resolve the stat query.
if (Cache)
- R = Cache->getStat(Path, StatBuf, isFile, FileDescriptor);
+ R = Cache->getStat(Path, Data, isFile, FileDescriptor);
else if (isForDir || !FileDescriptor) {
// If this is a directory or a file descriptor is not needed and we have
// no cache, just go to the file system.
- R = ::stat(Path, &StatBuf) != 0 ? CacheMissing : CacheExists;
+ llvm::sys::fs::file_status Status;
+ if (llvm::sys::fs::status(Path, Status)) {
+ R = CacheMissing;
+ } else {
+ R = CacheExists;
+ copyStatusToFileData(Status, Data);
+ }
} else {
// Otherwise, we have to go to the filesystem. We can always just use
// 'stat' here, but (for files) the client is asking whether the file exists
@@ -60,22 +75,20 @@ bool FileSystemStatCache::get(const char *Path, struct stat &StatBuf,
//
// Because of this, check to see if the file exists with 'open'. If the
// open succeeds, use fstat to get the stat info.
- int OpenFlags = O_RDONLY;
-#ifdef O_BINARY
- OpenFlags |= O_BINARY; // Open input file in binary mode on win32.
-#endif
- *FileDescriptor = ::open(Path, OpenFlags);
-
- if (*FileDescriptor == -1) {
+ llvm::error_code EC = llvm::sys::fs::openFileForRead(Path, *FileDescriptor);
+
+ if (EC) {
// If the open fails, our "stat" fails.
R = CacheMissing;
} else {
// Otherwise, the open succeeded. Do an fstat to get the information
// about the file. We'll end up returning the open file descriptor to the
// client to do what they please with it.
- if (::fstat(*FileDescriptor, &StatBuf) == 0)
+ llvm::sys::fs::file_status Status;
+ if (!llvm::sys::fs::status(*FileDescriptor, Status)) {
R = CacheExists;
- else {
+ copyStatusToFileData(Status, Data);
+ } else {
// fstat rarely fails. If it does, claim the initial open didn't
// succeed.
R = CacheMissing;
@@ -90,7 +103,7 @@ bool FileSystemStatCache::get(const char *Path, struct stat &StatBuf,
// If the path exists, make sure that its "directoryness" matches the clients
// demands.
- if (S_ISDIR(StatBuf.st_mode) != isForDir) {
+ if (Data.IsDirectory != isForDir) {
// If not, close the file if opened.
if (FileDescriptor && *FileDescriptor != -1) {
::close(*FileDescriptor);
@@ -103,12 +116,11 @@ bool FileSystemStatCache::get(const char *Path, struct stat &StatBuf,
return false;
}
-
MemorizeStatCalls::LookupResult
-MemorizeStatCalls::getStat(const char *Path, struct stat &StatBuf,
- bool isFile, int *FileDescriptor) {
- LookupResult Result = statChained(Path, StatBuf, isFile, FileDescriptor);
-
+MemorizeStatCalls::getStat(const char *Path, FileData &Data, bool isFile,
+ int *FileDescriptor) {
+ LookupResult Result = statChained(Path, Data, isFile, FileDescriptor);
+
// Do not cache failed stats, it is easy to construct common inconsistent
// situations if we do, and they are not important for PCH performance (which
// currently only needs the stats to construct the initial FileManager
@@ -117,8 +129,8 @@ MemorizeStatCalls::getStat(const char *Path, struct stat &StatBuf,
return Result;
// Cache file 'stat' results and directories with absolutely paths.
- if (!S_ISDIR(StatBuf.st_mode) || llvm::sys::path::is_absolute(Path))
- StatCalls[Path] = StatBuf;
-
+ if (!Data.IsDirectory || llvm::sys::path::is_absolute(Path))
+ StatCalls[Path] = Data;
+
return Result;
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp
index 951c718..500e732 100644
--- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp
@@ -13,11 +13,10 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/CharInfo.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/CharInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
@@ -453,6 +452,32 @@ ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
return OMF_None;
}
+ObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) {
+ IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
+ if (!first) return OIT_None;
+
+ StringRef name = first->getName();
+
+ if (name.empty()) return OIT_None;
+ switch (name.front()) {
+ case 'a':
+ if (startsWithWord(name, "array")) return OIT_Array;
+ break;
+ case 'd':
+ if (startsWithWord(name, "default")) return OIT_ReturnsSelf;
+ if (startsWithWord(name, "dictionary")) return OIT_Dictionary;
+ break;
+ case 's':
+ if (startsWithWord(name, "shared")) return OIT_ReturnsSelf;
+ if (startsWithWord(name, "standard")) return OIT_Singleton;
+ case 'i':
+ if (startsWithWord(name, "init")) return OIT_Init;
+ default:
+ break;
+ }
+ return OIT_None;
+}
+
namespace {
struct SelectorTableImpl {
llvm::FoldingSet<MultiKeywordSelector> Table;
@@ -464,15 +489,20 @@ static SelectorTableImpl &getSelectorTableImpl(void *P) {
return *static_cast<SelectorTableImpl*>(P);
}
-/*static*/ Selector
-SelectorTable::constructSetterName(IdentifierTable &Idents,
- SelectorTable &SelTable,
- const IdentifierInfo *Name) {
- SmallString<100> SelectorName;
- SelectorName = "set";
- SelectorName += Name->getName();
- SelectorName[3] = toUppercase(SelectorName[3]);
- IdentifierInfo *SetterName = &Idents.get(SelectorName);
+SmallString<64>
+SelectorTable::constructSetterName(StringRef Name) {
+ SmallString<64> SetterName("set");
+ SetterName += Name;
+ SetterName[3] = toUppercase(SetterName[3]);
+ return SetterName;
+}
+
+Selector
+SelectorTable::constructSetterSelector(IdentifierTable &Idents,
+ SelectorTable &SelTable,
+ const IdentifierInfo *Name) {
+ IdentifierInfo *SetterName =
+ &Idents.get(constructSetterName(Name->getName()));
return SelTable.getUnarySelector(SetterName);
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp
index 13518cd..d08cef1 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Module.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp
@@ -11,6 +11,7 @@
// code.
//
//===----------------------------------------------------------------------===//
+
#include "clang/Basic/Module.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
@@ -20,6 +21,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace clang;
Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
@@ -65,16 +67,17 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
.Default(Target.hasFeature(Feature));
}
-bool
+bool
Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
- StringRef &Feature) const {
+ Requirement &Req) const {
if (IsAvailable)
return true;
for (const Module *Current = this; Current; Current = Current->Parent) {
- for (unsigned I = 0, N = Current->Requires.size(); I != N; ++I) {
- if (!hasFeature(Current->Requires[I], LangOpts, Target)) {
- Feature = Current->Requires[I];
+ for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
+ if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
+ Current->Requirements[I].second) {
+ Req = Current->Requirements[I];
return false;
}
}
@@ -111,8 +114,8 @@ std::string Module::getFullModuleName() const {
Names.push_back(M->Name);
std::string Result;
- for (SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(),
- IEnd = Names.rend();
+ for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
+ IEnd = Names.rend();
I != IEnd; ++I) {
if (!Result.empty())
Result += '.';
@@ -143,12 +146,13 @@ ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
}
-void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts,
+void Module::addRequirement(StringRef Feature, bool RequiredState,
+ const LangOptions &LangOpts,
const TargetInfo &Target) {
- Requires.push_back(Feature);
+ Requirements.push_back(Requirement(Feature, RequiredState));
// If this feature is currently available, we're done.
- if (hasFeature(Feature, LangOpts, Target))
+ if (hasFeature(Feature, LangOpts, Target) == RequiredState)
return;
if (!IsAvailable)
@@ -190,6 +194,16 @@ static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
}
void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
+ // All non-explicit submodules are exported.
+ for (std::vector<Module *>::const_iterator I = SubModules.begin(),
+ E = SubModules.end();
+ I != E; ++I) {
+ Module *Mod = *I;
+ if (!Mod->IsExplicit)
+ Exported.push_back(Mod);
+ }
+
+ // Find re-exported modules by filtering the list of imported modules.
bool AnyWildcard = false;
bool UnrestrictedWildcard = false;
SmallVector<Module *, 4> WildcardRestrictions;
@@ -242,6 +256,23 @@ void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
}
}
+void Module::buildVisibleModulesCache() const {
+ assert(VisibleModulesCache.empty() && "cache does not need building");
+
+ // This module is visible to itself.
+ VisibleModulesCache.insert(this);
+
+ // Every imported module is visible.
+ SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
+ while (!Stack.empty()) {
+ Module *CurrModule = Stack.pop_back_val();
+
+ // Every module transitively exported by an imported module is visible.
+ if (VisibleModulesCache.insert(CurrModule).second)
+ CurrModule->getExportedModules(Stack);
+ }
+}
+
void Module::print(raw_ostream &OS, unsigned Indent) const {
OS.indent(Indent);
if (IsFramework)
@@ -257,13 +288,15 @@ void Module::print(raw_ostream &OS, unsigned Indent) const {
OS << " {\n";
- if (!Requires.empty()) {
+ if (!Requirements.empty()) {
OS.indent(Indent + 2);
OS << "requires ";
- for (unsigned I = 0, N = Requires.size(); I != N; ++I) {
+ for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
if (I)
OS << ", ";
- OS << Requires[I];
+ if (!Requirements[I].second)
+ OS << "!";
+ OS << Requirements[I].first;
}
OS << "\n";
}
@@ -293,10 +326,10 @@ void Module::print(raw_ostream &OS, unsigned Indent) const {
OS << "\n";
}
- for (unsigned I = 0, N = Headers.size(); I != N; ++I) {
+ for (unsigned I = 0, N = NormalHeaders.size(); I != N; ++I) {
OS.indent(Indent + 2);
OS << "header \"";
- OS.write_escaped(Headers[I]->getName());
+ OS.write_escaped(NormalHeaders[I]->getName());
OS << "\"\n";
}
@@ -306,6 +339,13 @@ void Module::print(raw_ostream &OS, unsigned Indent) const {
OS.write_escaped(ExcludedHeaders[I]->getName());
OS << "\"\n";
}
+
+ for (unsigned I = 0, N = PrivateHeaders.size(); I != N; ++I) {
+ OS.indent(Indent + 2);
+ OS << "private header \"";
+ OS.write_escaped(PrivateHeaders[I]->getName());
+ OS << "\"\n";
+ }
for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
MI != MIEnd; ++MI)
@@ -337,6 +377,20 @@ void Module::print(raw_ostream &OS, unsigned Indent) const {
OS << "\n";
}
+ for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
+ OS.indent(Indent + 2);
+ OS << "use ";
+ OS << DirectUses[I]->getFullModuleName();
+ OS << "\n";
+ }
+
+ for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
+ OS.indent(Indent + 2);
+ OS << "use ";
+ printModuleId(OS, UnresolvedDirectUses[I]);
+ OS << "\n";
+ }
+
for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
OS.indent(Indent + 2);
OS << "link ";
diff --git a/contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp b/contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp
index 9bd433a..be50fc4 100644
--- a/contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/ObjCRuntime.cpp
@@ -71,16 +71,20 @@ bool ObjCRuntime::tryParse(StringRef input) {
kind = ObjCRuntime::GCC;
} else if (runtimeName == "objfw") {
kind = ObjCRuntime::ObjFW;
+ Version = VersionTuple(0, 8);
} else {
return true;
}
TheKind = kind;
-
+
if (dash != StringRef::npos) {
StringRef verString = input.substr(dash + 1);
- if (Version.tryParse(verString))
+ if (Version.tryParse(verString))
return true;
}
+ if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8))
+ Version = VersionTuple(0, 8);
+
return false;
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp
index 835908d..1350934 100644
--- a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp
@@ -32,12 +32,102 @@ const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) {
assert(Kind < NUM_OPENMP_DIRECTIVES);
switch (Kind) {
case OMPD_unknown:
- return ("unknown");
+ return "unknown";
#define OPENMP_DIRECTIVE(Name) \
case OMPD_##Name : return #Name;
#include "clang/Basic/OpenMPKinds.def"
- default:
+ case NUM_OPENMP_DIRECTIVES:
break;
}
llvm_unreachable("Invalid OpenMP directive kind");
}
+
+OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
+ return llvm::StringSwitch<OpenMPClauseKind>(Str)
+#define OPENMP_CLAUSE(Name, Class) \
+ .Case(#Name, OMPC_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_unknown);
+}
+
+const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) {
+ assert(Kind < NUM_OPENMP_CLAUSES);
+ switch (Kind) {
+ case OMPC_unknown:
+ return "unknown";
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name : return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ case OMPC_threadprivate:
+ return "threadprivate or thread local";
+ case NUM_OPENMP_CLAUSES:
+ break;
+ }
+ llvm_unreachable("Invalid OpenMP clause kind");
+}
+
+unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
+ StringRef Str) {
+ switch (Kind) {
+ case OMPC_default:
+ return llvm::StringSwitch<OpenMPDefaultClauseKind>(Str)
+#define OPENMP_DEFAULT_KIND(Name) \
+ .Case(#Name, OMPC_DEFAULT_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_DEFAULT_unknown);
+ case OMPC_unknown:
+ case OMPC_threadprivate:
+ case OMPC_private:
+ case OMPC_firstprivate:
+ case OMPC_shared:
+ case NUM_OPENMP_CLAUSES:
+ break;
+ }
+ llvm_unreachable("Invalid OpenMP simple clause kind");
+}
+
+const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
+ unsigned Type) {
+ switch (Kind) {
+ case OMPC_default:
+ switch (Type) {
+ case OMPC_DEFAULT_unknown:
+ return "unknown";
+#define OPENMP_DEFAULT_KIND(Name) \
+ case OMPC_DEFAULT_##Name : return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'default' clause type");
+ case OMPC_unknown:
+ case OMPC_threadprivate:
+ case OMPC_private:
+ case OMPC_firstprivate:
+ case OMPC_shared:
+ case NUM_OPENMP_CLAUSES:
+ break;
+ }
+ llvm_unreachable("Invalid OpenMP simple clause kind");
+}
+
+bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
+ OpenMPClauseKind CKind) {
+ assert(DKind < NUM_OPENMP_DIRECTIVES);
+ assert(CKind < NUM_OPENMP_CLAUSES);
+ switch (DKind) {
+ case OMPD_parallel:
+ switch (CKind) {
+#define OPENMP_PARALLEL_CLAUSE(Name) \
+ case OMPC_##Name: return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_unknown:
+ case OMPD_threadprivate:
+ case OMPD_task:
+ case NUM_OPENMP_DIRECTIVES:
+ break;
+ }
+ return false;
+}
diff --git a/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp b/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp
index f9de231..ade8d6d 100644
--- a/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp
@@ -28,7 +28,7 @@ prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator,
return prec::Unknown;
case tok::greatergreater:
- // C++0x [temp.names]p3:
+ // C++11 [temp.names]p3:
//
// [...] Similarly, the first non-nested >> is treated as two
// consecutive but distinct > tokens, the first of which is
diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp
index d6dc6d6..9d79551 100644
--- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp
@@ -536,6 +536,43 @@ SourceManager::getFakeContentCacheForRecovery() const {
return FakeContentCacheForRecovery;
}
+/// \brief Returns the previous in-order FileID or an invalid FileID if there
+/// is no previous one.
+FileID SourceManager::getPreviousFileID(FileID FID) const {
+ if (FID.isInvalid())
+ return FileID();
+
+ int ID = FID.ID;
+ if (ID == -1)
+ return FileID();
+
+ if (ID > 0) {
+ if (ID-1 == 0)
+ return FileID();
+ } else if (unsigned(-(ID-1) - 2) >= LoadedSLocEntryTable.size()) {
+ return FileID();
+ }
+
+ return FileID::get(ID-1);
+}
+
+/// \brief Returns the next in-order FileID or an invalid FileID if there is
+/// no next one.
+FileID SourceManager::getNextFileID(FileID FID) const {
+ if (FID.isInvalid())
+ return FileID();
+
+ int ID = FID.ID;
+ if (ID > 0) {
+ if (unsigned(ID+1) >= local_sloc_entry_size())
+ return FileID();
+ } else if (ID+1 >= -1) {
+ return FileID();
+ }
+
+ return FileID::get(ID+1);
+}
+
//===----------------------------------------------------------------------===//
// Methods to create new FileID's and macro expansions.
//===----------------------------------------------------------------------===//
@@ -998,6 +1035,77 @@ bool SourceManager::isMacroBodyExpansion(SourceLocation Loc) const {
return Expansion.isMacroBodyExpansion();
}
+bool SourceManager::isAtStartOfImmediateMacroExpansion(SourceLocation Loc,
+ SourceLocation *MacroBegin) const {
+ assert(Loc.isValid() && Loc.isMacroID() && "Expected a valid macro loc");
+
+ std::pair<FileID, unsigned> DecompLoc = getDecomposedLoc(Loc);
+ if (DecompLoc.second > 0)
+ return false; // Does not point at the start of expansion range.
+
+ bool Invalid = false;
+ const SrcMgr::ExpansionInfo &ExpInfo =
+ getSLocEntry(DecompLoc.first, &Invalid).getExpansion();
+ if (Invalid)
+ return false;
+ SourceLocation ExpLoc = ExpInfo.getExpansionLocStart();
+
+ if (ExpInfo.isMacroArgExpansion()) {
+ // For macro argument expansions, check if the previous FileID is part of
+ // the same argument expansion, in which case this Loc is not at the
+ // beginning of the expansion.
+ FileID PrevFID = getPreviousFileID(DecompLoc.first);
+ if (!PrevFID.isInvalid()) {
+ const SrcMgr::SLocEntry &PrevEntry = getSLocEntry(PrevFID, &Invalid);
+ if (Invalid)
+ return false;
+ if (PrevEntry.isExpansion() &&
+ PrevEntry.getExpansion().getExpansionLocStart() == ExpLoc)
+ return false;
+ }
+ }
+
+ if (MacroBegin)
+ *MacroBegin = ExpLoc;
+ return true;
+}
+
+bool SourceManager::isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
+ SourceLocation *MacroEnd) const {
+ assert(Loc.isValid() && Loc.isMacroID() && "Expected a valid macro loc");
+
+ FileID FID = getFileID(Loc);
+ SourceLocation NextLoc = Loc.getLocWithOffset(1);
+ if (isInFileID(NextLoc, FID))
+ return false; // Does not point at the end of expansion range.
+
+ bool Invalid = false;
+ const SrcMgr::ExpansionInfo &ExpInfo =
+ getSLocEntry(FID, &Invalid).getExpansion();
+ if (Invalid)
+ return false;
+
+ if (ExpInfo.isMacroArgExpansion()) {
+ // For macro argument expansions, check if the next FileID is part of the
+ // same argument expansion, in which case this Loc is not at the end of the
+ // expansion.
+ FileID NextFID = getNextFileID(FID);
+ if (!NextFID.isInvalid()) {
+ const SrcMgr::SLocEntry &NextEntry = getSLocEntry(NextFID, &Invalid);
+ if (Invalid)
+ return false;
+ if (NextEntry.isExpansion() &&
+ NextEntry.getExpansion().getExpansionLocStart() ==
+ ExpInfo.getExpansionLocStart())
+ return false;
+ }
+ }
+
+ if (MacroEnd)
+ *MacroEnd = ExpInfo.getExpansionLocEnd();
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// Queries about the code at a SourceLocation.
@@ -1150,7 +1258,7 @@ static void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI,
// If we found a newline, adjust the pointer and jump to the handling code.
if (Mask != 0) {
- NextBuf += llvm::CountTrailingZeros_32(Mask);
+ NextBuf += llvm::countTrailingZeros(Mask);
goto FoundSpecialChar;
}
NextBuf += 16;
@@ -1445,6 +1553,36 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc,
return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc);
}
+/// \brief Returns whether the PresumedLoc for a given SourceLocation is
+/// in the main file.
+///
+/// This computes the "presumed" location for a SourceLocation, then checks
+/// whether it came from a file other than the main file. This is different
+/// from isWrittenInMainFile() because it takes line marker directives into
+/// account.
+bool SourceManager::isInMainFile(SourceLocation Loc) const {
+ if (Loc.isInvalid()) return false;
+
+ // Presumed locations are always for expansion points.
+ std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
+
+ bool Invalid = false;
+ const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
+ if (Invalid || !Entry.isFile())
+ return false;
+
+ const SrcMgr::FileInfo &FI = Entry.getFile();
+
+ // Check if there is a line directive for this location.
+ if (FI.hasLineDirectives())
+ if (const LineEntry *Entry =
+ LineTable->FindNearestLineEntry(LocInfo.first, LocInfo.second))
+ if (Entry->IncludeOffset)
+ return false;
+
+ return FI.getIncludeLoc().isInvalid();
+}
+
/// \brief The size of the SLocEnty that \arg FID represents.
unsigned SourceManager::getFileIDSize(FileID FID) const {
bool Invalid = false;
@@ -1472,15 +1610,16 @@ unsigned SourceManager::getFileIDSize(FileID FID) const {
///
/// This routine involves a system call, and therefore should only be used
/// in non-performance-critical code.
-static Optional<ino_t> getActualFileInode(const FileEntry *File) {
+static Optional<llvm::sys::fs::UniqueID>
+getActualFileUID(const FileEntry *File) {
if (!File)
return None;
-
- struct stat StatBuf;
- if (::stat(File->getName(), &StatBuf))
+
+ llvm::sys::fs::UniqueID ID;
+ if (llvm::sys::fs::getUniqueID(File->getName(), ID))
return None;
-
- return StatBuf.st_ino;
+
+ return ID;
}
/// \brief Get the source location for the given file:line:col triplet.
@@ -1509,7 +1648,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
// First, check the main file ID, since it is common to look for a
// location in the main file.
- Optional<ino_t> SourceFileInode;
+ Optional<llvm::sys::fs::UniqueID> SourceFileUID;
Optional<StringRef> SourceFileName;
if (!MainFileID.isInvalid()) {
bool Invalid = false;
@@ -1530,10 +1669,11 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
const FileEntry *MainFile = MainContentCache->OrigEntry;
SourceFileName = llvm::sys::path::filename(SourceFile->getName());
if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) {
- SourceFileInode = getActualFileInode(SourceFile);
- if (SourceFileInode) {
- if (Optional<ino_t> MainFileInode = getActualFileInode(MainFile)) {
- if (*SourceFileInode == *MainFileInode) {
+ SourceFileUID = getActualFileUID(SourceFile);
+ if (SourceFileUID) {
+ if (Optional<llvm::sys::fs::UniqueID> MainFileUID =
+ getActualFileUID(MainFile)) {
+ if (*SourceFileUID == *MainFileUID) {
FirstFID = MainFileID;
SourceFile = MainFile;
}
@@ -1576,12 +1716,11 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
// 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.
+ // parsed the file.
if (FirstFID.isInvalid() &&
- (SourceFileName ||
+ (SourceFileName ||
(SourceFileName = llvm::sys::path::filename(SourceFile->getName()))) &&
- (SourceFileInode ||
- (SourceFileInode = getActualFileInode(SourceFile)))) {
+ (SourceFileUID || (SourceFileUID = getActualFileUID(SourceFile)))) {
bool Invalid = false;
for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
FileID IFileID;
@@ -1596,8 +1735,9 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
const FileEntry *Entry =FileContentCache? FileContentCache->OrigEntry : 0;
if (Entry &&
*SourceFileName == llvm::sys::path::filename(Entry->getName())) {
- if (Optional<ino_t> EntryInode = getActualFileInode(Entry)) {
- if (*SourceFileInode == *EntryInode) {
+ if (Optional<llvm::sys::fs::UniqueID> EntryUID =
+ getActualFileUID(Entry)) {
+ if (*SourceFileUID == *EntryUID) {
FirstFID = FileID::get(I);
SourceFile = Entry;
break;
@@ -1617,6 +1757,10 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
SourceLocation SourceManager::translateLineCol(FileID FID,
unsigned Line,
unsigned Col) const {
+ // Lines are used as a one-based index into a zero-based array. This assert
+ // checks for possible buffer underruns.
+ assert(Line != 0 && "Passed a zero-based line");
+
if (FID.isInvalid())
return SourceLocation();
@@ -1624,7 +1768,7 @@ SourceLocation SourceManager::translateLineCol(FileID FID,
const SLocEntry &Entry = getSLocEntry(FID, &Invalid);
if (Invalid)
return SourceLocation();
-
+
if (!Entry.isFile())
return SourceLocation();
@@ -1637,7 +1781,7 @@ SourceLocation SourceManager::translateLineCol(FileID FID,
= const_cast<ContentCache *>(Entry.getFile().getContentCache());
if (!Content)
return SourceLocation();
-
+
// If this is the first use of line information for this buffer, compute the
// SourceLineCache for it on demand.
if (Content->SourceLineCache == 0) {
@@ -1666,10 +1810,7 @@ SourceLocation SourceManager::translateLineCol(FileID FID,
// Check that the given column is valid.
while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
++i;
- if (i < Col-1)
- return FileLoc.getLocWithOffset(FilePos + i);
-
- return FileLoc.getLocWithOffset(FilePos + Col - 1);
+ return FileLoc.getLocWithOffset(FilePos + i);
}
/// \brief Compute a map of macro argument chunks to their expanded source
@@ -1700,7 +1841,10 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr,
return;
}
- const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID);
+ bool Invalid = false;
+ const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID, &Invalid);
+ if (Invalid)
+ return;
if (Entry.isFile()) {
SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc();
if (IncludeLoc.isInvalid())
@@ -1850,6 +1994,9 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const {
std::pair<FileID, unsigned>
SourceManager::getDecomposedIncludedLoc(FileID FID) const {
+ if (FID.isInvalid())
+ return std::make_pair(FileID(), 0);
+
// Uses IncludedLocMap to retrieve/cache the decomposed loc.
typedef std::pair<FileID, unsigned> DecompTy;
@@ -1861,11 +2008,14 @@ SourceManager::getDecomposedIncludedLoc(FileID FID) const {
return DecompLoc; // already in map.
SourceLocation UpperLoc;
- const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
- if (Entry.isExpansion())
- UpperLoc = Entry.getExpansion().getExpansionLocStart();
- else
- UpperLoc = Entry.getFile().getIncludeLoc();
+ bool Invalid = false;
+ const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+ if (!Invalid) {
+ if (Entry.isExpansion())
+ UpperLoc = Entry.getExpansion().getExpansionLocStart();
+ else
+ UpperLoc = Entry.getFile().getIncludeLoc();
+ }
if (UpperLoc.isValid())
DecompLoc = getDecomposedLoc(UpperLoc);
@@ -1925,6 +2075,12 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS);
+ // getDecomposedLoc may have failed to return a valid FileID because, e.g. it
+ // is a serialized one referring to a file that was removed after we loaded
+ // the PCH.
+ if (LOffs.first.isInvalid() || ROffs.first.isInvalid())
+ return LOffs.first.isInvalid() && !ROffs.first.isInvalid();
+
// If the source locations are in the same file, just compare offsets.
if (LOffs.first == ROffs.first)
return LOffs.second < ROffs.second;
diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp
index 0d44dc0..e993055 100644
--- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp
@@ -24,8 +24,7 @@ using namespace clang;
static const LangAS::Map DefaultAddrSpaceMap = { 0 };
// TargetInfo Constructor.
-TargetInfo::TargetInfo(const std::string &T) : TargetOpts(), Triple(T)
-{
+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;
@@ -89,6 +88,7 @@ TargetInfo::TargetInfo(const std::string &T) : TargetOpts(), Triple(T)
// Default to an empty address space map.
AddrSpaceMap = &DefaultAddrSpaceMap;
+ UseAddrSpaceMapMangling = false;
// Default to an unknown platform name.
PlatformName = "unknown";
@@ -103,6 +103,8 @@ TargetInfo::~TargetInfo() {}
const char *TargetInfo::getTypeName(IntType T) {
switch (T) {
default: llvm_unreachable("not an integer!");
+ case SignedChar: return "char";
+ case UnsignedChar: return "unsigned char";
case SignedShort: return "short";
case UnsignedShort: return "unsigned short";
case SignedInt: return "int";
@@ -119,10 +121,12 @@ const char *TargetInfo::getTypeName(IntType T) {
const char *TargetInfo::getTypeConstantSuffix(IntType T) {
switch (T) {
default: llvm_unreachable("not an integer!");
+ case SignedChar:
case SignedShort:
case SignedInt: return "";
case SignedLong: return "L";
case SignedLongLong: return "LL";
+ case UnsignedChar:
case UnsignedShort:
case UnsignedInt: return "U";
case UnsignedLong: return "UL";
@@ -135,6 +139,8 @@ const char *TargetInfo::getTypeConstantSuffix(IntType T) {
unsigned TargetInfo::getTypeWidth(IntType T) const {
switch (T) {
default: llvm_unreachable("not an integer!");
+ case SignedChar:
+ case UnsignedChar: return getCharWidth();
case SignedShort:
case UnsignedShort: return getShortWidth();
case SignedInt:
@@ -146,11 +152,49 @@ unsigned TargetInfo::getTypeWidth(IntType T) const {
};
}
+TargetInfo::IntType TargetInfo::getIntTypeByWidth(
+ unsigned BitWidth, bool IsSigned) const {
+ if (getCharWidth() == BitWidth)
+ return IsSigned ? SignedChar : UnsignedChar;
+ if (getShortWidth() == BitWidth)
+ return IsSigned ? SignedShort : UnsignedShort;
+ if (getIntWidth() == BitWidth)
+ return IsSigned ? SignedInt : UnsignedInt;
+ if (getLongWidth() == BitWidth)
+ return IsSigned ? SignedLong : UnsignedLong;
+ if (getLongLongWidth() == BitWidth)
+ return IsSigned ? SignedLongLong : UnsignedLongLong;
+ return NoInt;
+}
+
+TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const {
+ if (getFloatWidth() == BitWidth)
+ return Float;
+ if (getDoubleWidth() == BitWidth)
+ return Double;
+
+ switch (BitWidth) {
+ case 96:
+ if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended)
+ return LongDouble;
+ break;
+ case 128:
+ if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble ||
+ &getLongDoubleFormat() == &llvm::APFloat::IEEEquad)
+ return LongDouble;
+ break;
+ }
+
+ return NoFloat;
+}
+
/// getTypeAlign - Return the alignment (in bits) of the specified integer type
/// enum. For example, SignedInt -> getIntAlign().
unsigned TargetInfo::getTypeAlign(IntType T) const {
switch (T) {
default: llvm_unreachable("not an integer!");
+ case SignedChar:
+ case UnsignedChar: return getCharAlign();
case SignedShort:
case UnsignedShort: return getShortAlign();
case SignedInt:
@@ -167,11 +211,13 @@ unsigned TargetInfo::getTypeAlign(IntType T) const {
bool TargetInfo::isTypeSigned(IntType T) {
switch (T) {
default: llvm_unreachable("not an integer!");
+ case SignedChar:
case SignedShort:
case SignedInt:
case SignedLong:
case SignedLongLong:
return true;
+ case UnsignedChar:
case UnsignedShort:
case UnsignedInt:
case UnsignedLong:
@@ -188,6 +234,35 @@ void TargetInfo::setForcedLangOptions(LangOptions &Opts) {
UseBitFieldTypeAlignment = false;
if (Opts.ShortWChar)
WCharType = UnsignedShort;
+
+ if (Opts.OpenCL) {
+ // OpenCL C requires specific widths for types, irrespective of
+ // what these normally are for the target.
+ // We also define long long and long double here, although the
+ // OpenCL standard only mentions these as "reserved".
+ IntWidth = IntAlign = 32;
+ LongWidth = LongAlign = 64;
+ LongLongWidth = LongLongAlign = 128;
+ HalfWidth = HalfAlign = 16;
+ FloatWidth = FloatAlign = 32;
+ DoubleWidth = DoubleAlign = 64;
+ LongDoubleWidth = LongDoubleAlign = 128;
+
+ assert(PointerWidth == 32 || PointerWidth == 64);
+ bool Is32BitArch = PointerWidth == 32;
+ SizeType = Is32BitArch ? UnsignedInt : UnsignedLong;
+ PtrDiffType = Is32BitArch ? SignedInt : SignedLong;
+ IntPtrType = Is32BitArch ? SignedInt : SignedLong;
+
+ IntMaxType = SignedLongLong;
+ UIntMaxType = UnsignedLongLong;
+ Int64Type = SignedLong;
+
+ HalfFormat = &llvm::APFloat::IEEEhalf;
+ FloatFormat = &llvm::APFloat::IEEEsingle;
+ DoubleFormat = &llvm::APFloat::IEEEdouble;
+ LongDoubleFormat = &llvm::APFloat::IEEEquad;
+ }
}
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index f7c8c9c..bccd0d7 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -73,7 +73,7 @@ protected:
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
MacroBuilder &Builder) const=0;
public:
- OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
+ OSTargetInfo(const llvm::Triple &Triple) : TgtInfo(Triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
TgtInfo::getTargetDefines(Opts, Builder);
@@ -88,7 +88,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
const llvm::Triple &Triple,
StringRef &PlatformName,
VersionTuple &PlatformMinVersion) {
- Builder.defineMacro("__APPLE_CC__", "5621");
+ Builder.defineMacro("__APPLE_CC__", "6000");
Builder.defineMacro("__APPLE__");
Builder.defineMacro("__MACH__");
Builder.defineMacro("OBJC_NEW_PROPERTIES");
@@ -138,31 +138,37 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
return;
}
- // Set the appropriate OS version define.
- if (Triple.getOS() == llvm::Triple::IOS) {
- assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
- char Str[6];
- Str[0] = '0' + Maj;
- Str[1] = '0' + (Min / 10);
- Str[2] = '0' + (Min % 10);
- Str[3] = '0' + (Rev / 10);
- Str[4] = '0' + (Rev % 10);
- Str[5] = '\0';
- Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
- } else {
- // Note that the Driver allows versions which aren't representable in the
- // define (because we only get a single digit for the minor and micro
- // revision numbers). So, we limit them to the maximum representable
- // version.
- assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
- assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
- char Str[5];
- Str[0] = '0' + (Maj / 10);
- Str[1] = '0' + (Maj % 10);
- Str[2] = '0' + std::min(Min, 9U);
- Str[3] = '0' + std::min(Rev, 9U);
- Str[4] = '\0';
- Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
+ // If there's an environment specified in the triple, that means we're dealing
+ // with an embedded variant of some sort and don't want the platform
+ // version-min defines, so only add them if there's not one.
+ if (Triple.getEnvironmentName().empty()) {
+ // Set the appropriate OS version define.
+ if (Triple.isiOS()) {
+ assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
+ char Str[6];
+ Str[0] = '0' + Maj;
+ Str[1] = '0' + (Min / 10);
+ Str[2] = '0' + (Min % 10);
+ Str[3] = '0' + (Rev / 10);
+ Str[4] = '0' + (Rev % 10);
+ Str[5] = '\0';
+ Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
+ Str);
+ } else {
+ // Note that the Driver allows versions which aren't representable in the
+ // define (because we only get a single digit for the minor and micro
+ // revision numbers). So, we limit them to the maximum representable
+ // version.
+ assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
+ assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
+ char Str[5];
+ Str[0] = '0' + (Maj / 10);
+ Str[1] = '0' + (Maj % 10);
+ Str[2] = '0' + std::min(Min, 9U);
+ Str[3] = '0' + std::min(Rev, 9U);
+ Str[4] = '\0';
+ Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
+ }
}
PlatformMinVersion = VersionTuple(Maj, Min, Rev);
@@ -179,12 +185,10 @@ protected:
}
public:
- DarwinTargetInfo(const std::string& triple) :
- OSTargetInfo<Target>(triple) {
- llvm::Triple T = llvm::Triple(triple);
- this->TLSSupported = T.isMacOSX() && !T.isMacOSXVersionLT(10,7);
- this->MCountName = "\01mcount";
- }
+ DarwinTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ this->TLSSupported = Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 7);
+ this->MCountName = "\01mcount";
+ }
virtual std::string isValidSectionSpecifier(StringRef SR) const {
// Let MCSectionMachO validate this.
@@ -224,18 +228,17 @@ protected:
DefineStd(Builder, "unix", Opts);
}
public:
- DragonFlyBSDTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {
- this->UserLabelPrefix = "";
+ DragonFlyBSDTargetInfo(const llvm::Triple &Triple)
+ : OSTargetInfo<Target>(Triple) {
+ this->UserLabelPrefix = "";
- llvm::Triple Triple(triple);
- switch (Triple.getArch()) {
- default:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- this->MCountName = ".mcount";
- break;
- }
+ switch (Triple.getArch()) {
+ default:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ this->MCountName = ".mcount";
+ break;
+ }
}
};
@@ -256,31 +259,57 @@ protected:
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
DefineStd(Builder, "unix", Opts);
Builder.defineMacro("__ELF__");
+
+ // On FreeBSD, wchar_t contains the number of the code point as
+ // used by the character set of the locale. These character sets are
+ // not necessarily a superset of ASCII.
+ Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1");
}
public:
- FreeBSDTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {
- this->UserLabelPrefix = "";
-
- llvm::Triple Triple(triple);
- switch (Triple.getArch()) {
- default:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- this->MCountName = ".mcount";
- break;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- this->MCountName = "_mcount";
- break;
- case llvm::Triple::arm:
- this->MCountName = "__mcount";
- break;
- }
+ FreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ this->UserLabelPrefix = "";
+ switch (Triple.getArch()) {
+ default:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ this->MCountName = ".mcount";
+ break;
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ this->MCountName = "_mcount";
+ break;
+ case llvm::Triple::arm:
+ this->MCountName = "__mcount";
+ break;
}
+ }
+};
+
+// GNU/kFreeBSD Target
+template<typename Target>
+class KFreeBSDTargetInfo : public OSTargetInfo<Target> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const {
+ // GNU/kFreeBSD defines; list based off of gcc output
+
+ DefineStd(Builder, "unix", Opts);
+ Builder.defineMacro("__FreeBSD_kernel__");
+ Builder.defineMacro("__GLIBC__");
+ Builder.defineMacro("__ELF__");
+ if (Opts.POSIXThreads)
+ Builder.defineMacro("_REENTRANT");
+ if (Opts.CPlusPlus)
+ Builder.defineMacro("_GNU_SOURCE");
+ }
+public:
+ KFreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ this->UserLabelPrefix = "";
+ }
};
// Minix Target
@@ -302,10 +331,9 @@ protected:
DefineStd(Builder, "unix", Opts);
}
public:
- MinixTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {
- this->UserLabelPrefix = "";
- }
+ MinixTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ this->UserLabelPrefix = "";
+ }
};
// Linux target
@@ -327,8 +355,7 @@ protected:
Builder.defineMacro("_GNU_SOURCE");
}
public:
- LinuxTargetInfo(const std::string& triple)
- : OSTargetInfo<Target>(triple) {
+ LinuxTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
this->UserLabelPrefix = "";
this->WIntType = TargetInfo::UnsignedInt;
}
@@ -352,10 +379,9 @@ protected:
Builder.defineMacro("_POSIX_THREADS");
}
public:
- NetBSDTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {
- this->UserLabelPrefix = "";
- }
+ NetBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ this->UserLabelPrefix = "";
+ }
};
// OpenBSD Target
@@ -373,12 +399,10 @@ protected:
Builder.defineMacro("_REENTRANT");
}
public:
- OpenBSDTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {
- this->UserLabelPrefix = "";
- this->TLSSupported = false;
+ OpenBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ this->UserLabelPrefix = "";
+ this->TLSSupported = false;
- llvm::Triple Triple(triple);
switch (Triple.getArch()) {
default:
case llvm::Triple::x86:
@@ -412,11 +436,10 @@ protected:
Builder.defineMacro("_REENTRANT");
}
public:
- BitrigTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {
- this->UserLabelPrefix = "";
- this->TLSSupported = false;
- this->MCountName = "__mcount";
+ BitrigTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ this->UserLabelPrefix = "";
+ this->TLSSupported = false;
+ this->MCountName = "__mcount";
}
};
@@ -433,8 +456,7 @@ protected:
Builder.defineMacro("__ELF__");
}
public:
- PSPTargetInfo(const std::string& triple)
- : OSTargetInfo<Target>(triple) {
+ PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
this->UserLabelPrefix = "";
}
};
@@ -455,8 +477,7 @@ protected:
Builder.defineMacro("__powerpc64__");
}
public:
- PS3PPUTargetInfo(const std::string& triple)
- : OSTargetInfo<Target>(triple) {
+ PS3PPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
this->UserLabelPrefix = "";
this->LongWidth = this->LongAlign = 32;
this->PointerWidth = this->PointerAlign = 32;
@@ -481,8 +502,7 @@ protected:
Builder.defineMacro("__ELF__");
}
public:
- PS3SPUTargetInfo(const std::string& triple)
- : OSTargetInfo<Target>(triple) {
+ PS3SPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
this->UserLabelPrefix = "";
}
};
@@ -500,8 +520,8 @@ protected:
Builder.defineMacro("__SVR4");
}
public:
- AuroraUXTargetInfo(const std::string& triple)
- : OSTargetInfo<Target>(triple) {
+ AuroraUXTargetInfo(const llvm::Triple &Triple)
+ : OSTargetInfo<Target>(Triple) {
this->UserLabelPrefix = "";
this->WCharType = this->SignedLong;
// FIXME: WIntType should be SignedLong
@@ -535,8 +555,7 @@ protected:
Builder.defineMacro("_REENTRANT");
}
public:
- SolarisTargetInfo(const std::string& triple)
- : OSTargetInfo<Target>(triple) {
+ SolarisTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
this->UserLabelPrefix = "";
this->WCharType = this->SignedInt;
// FIXME: WIntType should be SignedLong
@@ -586,13 +605,13 @@ protected:
}
public:
- WindowsTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {}
+ WindowsTargetInfo(const llvm::Triple &Triple)
+ : OSTargetInfo<Target>(Triple) {}
};
template <typename Target>
class NaClTargetInfo : public OSTargetInfo<Target> {
- protected:
+protected:
virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
MacroBuilder &Builder) const {
if (Opts.POSIXThreads)
@@ -604,9 +623,9 @@ class NaClTargetInfo : public OSTargetInfo<Target> {
Builder.defineMacro("__ELF__");
Builder.defineMacro("__native_client__");
}
- public:
- NaClTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {
+
+public:
+ NaClTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
this->UserLabelPrefix = "";
this->LongAlign = 32;
this->LongWidth = 32;
@@ -645,8 +664,14 @@ class PPCTargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
static const TargetInfo::GCCRegAlias GCCRegAliases[];
std::string CPU;
+
+ // Target cpu features.
+ bool HasVSX;
+
public:
- PPCTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ PPCTargetInfo(const llvm::Triple &Triple)
+ : TargetInfo(Triple), HasVSX(false) {
+ BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
}
@@ -718,6 +743,8 @@ public:
.Case("ppc", true)
.Case("powerpc64", true)
.Case("ppc64", true)
+ .Case("powerpc64le", true)
+ .Case("ppc64le", true)
.Default(false);
if (CPUKnown)
@@ -739,10 +766,8 @@ public:
virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
- virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const;
-
+ virtual bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags);
virtual bool hasFeature(StringRef Feature) const;
virtual void getGCCRegNames(const char * const *&Names,
@@ -864,6 +889,29 @@ const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
#include "clang/Basic/BuiltinsPPC.def"
};
+ /// handleTargetFeatures - Perform initialization based on the user
+/// configured set of features.
+bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
+ // Remember the maximum enabled sselevel.
+ for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
+ // Ignore disabled features.
+ if (Features[i][0] == '-')
+ continue;
+
+ StringRef Feature = StringRef(Features[i]).substr(1);
+
+ if (Feature == "vsx") {
+ HasVSX = true;
+ continue;
+ }
+
+ // TODO: Finish this list and add an assert that we've handled them
+ // all.
+ }
+
+ return true;
+}
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
/// #defines that are not tied to a specific subtarget.
@@ -871,6 +919,7 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
// Target identification.
Builder.defineMacro("__ppc__");
+ Builder.defineMacro("__PPC__");
Builder.defineMacro("_ARCH_PPC");
Builder.defineMacro("__powerpc__");
Builder.defineMacro("__POWERPC__");
@@ -878,22 +927,27 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("_ARCH_PPC64");
Builder.defineMacro("__powerpc64__");
Builder.defineMacro("__ppc64__");
- } else {
- Builder.defineMacro("__ppc__");
+ Builder.defineMacro("__PPC64__");
}
// Target properties.
- if (getTriple().getOS() != llvm::Triple::NetBSD &&
- getTriple().getOS() != llvm::Triple::OpenBSD)
- Builder.defineMacro("_BIG_ENDIAN");
- Builder.defineMacro("__BIG_ENDIAN__");
+ if (getTriple().getArch() == llvm::Triple::ppc64le) {
+ Builder.defineMacro("_LITTLE_ENDIAN");
+ Builder.defineMacro("__LITTLE_ENDIAN__");
+ } else {
+ if (getTriple().getOS() != llvm::Triple::NetBSD &&
+ getTriple().getOS() != llvm::Triple::OpenBSD)
+ Builder.defineMacro("_BIG_ENDIAN");
+ Builder.defineMacro("__BIG_ENDIAN__");
+ }
// Subtarget options.
Builder.defineMacro("__NATURAL_ALIGNMENT__");
Builder.defineMacro("__REGISTER_PREFIX__", "");
// FIXME: Should be controlled by command line option.
- Builder.defineMacro("__LONG_DOUBLE_128__");
+ if (LongDoubleWidth == 128)
+ Builder.defineMacro("__LONG_DOUBLE_128__");
if (Opts.AltiVec) {
Builder.defineMacro("__VEC__", "10206");
@@ -988,13 +1042,15 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__TOS_BGQ__");
}
+ if (HasVSX)
+ Builder.defineMacro("__VSX__");
+
// FIXME: The following are not yet generated here by Clang, but are
// generated by GCC:
//
// _SOFT_FLOAT_
// __RECIP_PRECISION__
// __APPLE_ALTIVEC__
- // __VSX__
// __RECIP__
// __RECIPF__
// __RSQRTE__
@@ -1021,23 +1077,12 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
.Case("pwr6", true)
.Case("pwr7", true)
.Case("ppc64", true)
+ .Case("ppc64le", true)
.Default(false);
Features["qpx"] = (CPU == "a2q");
}
-bool PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const {
- if (Name == "altivec" || Name == "fprnd" || Name == "mfocrf" ||
- Name == "popcntd" || Name == "qpx") {
- Features[Name] = Enabled;
- return true;
- }
-
- return false;
-}
-
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
return Feature == "powerpc";
}
@@ -1150,7 +1195,7 @@ void PPCTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
namespace {
class PPC32TargetInfo : public PPCTargetInfo {
public:
- PPC32TargetInfo(const std::string &triple) : PPCTargetInfo(triple) {
+ PPC32TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
@@ -1182,10 +1227,12 @@ public:
};
} // end anonymous namespace.
+// Note: ABI differences may eventually require us to have a separate
+// TargetInfo for little endian.
namespace {
class PPC64TargetInfo : public PPCTargetInfo {
public:
- PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
+ PPC64TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
IntMaxType = SignedLong;
UIntMaxType = UnsignedLong;
@@ -1195,7 +1242,7 @@ public:
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-f128:64:64-"
+ "i64:64:64-f32:32:32-f64:64:64-"
"v128:128:128-n32:64";
} else
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
@@ -1216,10 +1263,11 @@ namespace {
class DarwinPPC32TargetInfo :
public DarwinTargetInfo<PPC32TargetInfo> {
public:
- DarwinPPC32TargetInfo(const std::string& triple)
- : DarwinTargetInfo<PPC32TargetInfo>(triple) {
+ DarwinPPC32TargetInfo(const llvm::Triple &Triple)
+ : DarwinTargetInfo<PPC32TargetInfo>(Triple) {
HasAlignMac68kSupport = true;
BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool?
+ PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726
LongLongAlign = 32;
SuitableAlign = 128;
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
@@ -1233,8 +1281,8 @@ public:
class DarwinPPC64TargetInfo :
public DarwinTargetInfo<PPC64TargetInfo> {
public:
- DarwinPPC64TargetInfo(const std::string& triple)
- : DarwinTargetInfo<PPC64TargetInfo>(triple) {
+ DarwinPPC64TargetInfo(const llvm::Triple &Triple)
+ : DarwinTargetInfo<PPC64TargetInfo>(Triple) {
HasAlignMac68kSupport = true;
SuitableAlign = 128;
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
@@ -1255,13 +1303,13 @@ namespace {
class NVPTXTargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
static const Builtin::Info BuiltinInfo[];
- std::vector<StringRef> AvailableFeatures;
public:
- NVPTXTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ NVPTXTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
BigEndian = false;
TLSSupported = false;
LongWidth = LongAlign = 64;
AddrSpaceMap = &NVPTXAddrSpaceMap;
+ UseAddrSpaceMapMangling = true;
// Define available target features
// These must be defined in sorted order!
NoAsmVariants = true;
@@ -1289,9 +1337,18 @@ namespace {
NumAliases = 0;
}
virtual bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const {
- // FIXME: implement
- return true;
+ TargetInfo::ConstraintInfo &Info) const {
+ switch (*Name) {
+ default: return false;
+ case 'c':
+ case 'h':
+ case 'r':
+ case 'l':
+ case 'f':
+ case 'd':
+ Info.setAllowsRegister();
+ return true;
+ }
}
virtual const char *getClobbers() const {
// FIXME: Is this really right?
@@ -1311,9 +1368,6 @@ namespace {
return Valid;
}
- virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const;
};
const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
@@ -1333,21 +1387,9 @@ namespace {
NumNames = llvm::array_lengthof(GCCRegNames);
}
- bool NVPTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const {
- if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(),
- Name)) {
- Features[Name] = Enabled;
- return true;
- } else {
- return false;
- }
- }
-
class NVPTX32TargetInfo : public NVPTXTargetInfo {
public:
- NVPTX32TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) {
+ NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
PointerWidth = PointerAlign = 32;
SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt;
DescriptionString
@@ -1359,7 +1401,7 @@ namespace {
class NVPTX64TargetInfo : public NVPTXTargetInfo {
public:
- NVPTX64TargetInfo(const std::string& triple) : NVPTXTargetInfo(triple) {
+ NVPTX64TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
PointerWidth = PointerAlign = 64;
SizeType = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong;
DescriptionString
@@ -1400,6 +1442,7 @@ static const char *DescriptionStringR600DoubleOps =
static const char *DescriptionStringSI =
"e"
"-p:64:64:64"
+ "-p3:32:32:32"
"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
"-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
"-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
@@ -1417,15 +1460,16 @@ class R600TargetInfo : public TargetInfo {
GK_EVERGREEN_DOUBLE_OPS,
GK_NORTHERN_ISLANDS,
GK_CAYMAN,
- GK_SOUTHERN_ISLANDS
+ GK_SOUTHERN_ISLANDS,
+ GK_SEA_ISLANDS
} GPU;
public:
- R600TargetInfo(const std::string& triple)
- : TargetInfo(triple),
- GPU(GK_R600) {
+ R600TargetInfo(const llvm::Triple &Triple)
+ : TargetInfo(Triple), GPU(GK_R600) {
DescriptionString = DescriptionStringR600;
AddrSpaceMap = &R600AddrSpaceMap;
+ UseAddrSpaceMapMangling = true;
}
virtual const char * getClobbers() const {
@@ -1496,6 +1540,10 @@ public:
.Case("pitcairn", GK_SOUTHERN_ISLANDS)
.Case("verde", GK_SOUTHERN_ISLANDS)
.Case("oland", GK_SOUTHERN_ISLANDS)
+ .Case("bonaire", GK_SEA_ISLANDS)
+ .Case("kabini", GK_SEA_ISLANDS)
+ .Case("kaveri", GK_SEA_ISLANDS)
+ .Case("hawaii", GK_SEA_ISLANDS)
.Default(GK_NONE);
if (GPU == GK_NONE) {
@@ -1518,6 +1566,7 @@ public:
DescriptionString = DescriptionStringR600DoubleOps;
break;
case GK_SOUTHERN_ISLANDS:
+ case GK_SEA_ISLANDS:
DescriptionString = DescriptionStringSI;
break;
}
@@ -1529,137 +1578,6 @@ public:
} // end anonymous namespace
namespace {
-// MBlaze abstract base class
-class MBlazeTargetInfo : public TargetInfo {
- static const char * const GCCRegNames[];
- static const TargetInfo::GCCRegAlias GCCRegAliases[];
-
-public:
- MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
- DescriptionString = "E-p:32:32:32-i8:8:8-i16:16:16";
- }
-
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords) const {
- // FIXME: Implement.
- Records = 0;
- NumRecords = 0;
- }
-
- virtual void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const;
-
- virtual bool hasFeature(StringRef Feature) const {
- return Feature == "mblaze";
- }
-
- virtual BuiltinVaListKind getBuiltinVaListKind() const {
- return TargetInfo::CharPtrBuiltinVaList;
- }
- virtual const char *getTargetPrefix() const {
- return "mblaze";
- }
- virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const;
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const;
- virtual bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const {
- switch (*Name) {
- default: return false;
- case 'O': // Zero
- return true;
- case 'b': // Base register
- case 'f': // Floating point register
- Info.setAllowsRegister();
- return true;
- }
- }
- virtual const char *getClobbers() const {
- return "";
- }
-};
-
-/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
-/// #defines that are not tied to a specific subtarget.
-void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
- // Target identification.
- Builder.defineMacro("__microblaze__");
- Builder.defineMacro("_ARCH_MICROBLAZE");
- Builder.defineMacro("__MICROBLAZE__");
-
- // Target properties.
- Builder.defineMacro("_BIG_ENDIAN");
- Builder.defineMacro("__BIG_ENDIAN__");
-
- // Subtarget options.
- Builder.defineMacro("__REGISTER_PREFIX__", "");
-}
-
-
-const char * const MBlazeTargetInfo::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", "r26", "r27", "r28", "r29", "r30", "r31",
- "$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",
- "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
- "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
-};
-
-void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- Names = GCCRegNames;
- NumNames = llvm::array_lengthof(GCCRegNames);
-}
-
-const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
- { {"f0"}, "r0" },
- { {"f1"}, "r1" },
- { {"f2"}, "r2" },
- { {"f3"}, "r3" },
- { {"f4"}, "r4" },
- { {"f5"}, "r5" },
- { {"f6"}, "r6" },
- { {"f7"}, "r7" },
- { {"f8"}, "r8" },
- { {"f9"}, "r9" },
- { {"f10"}, "r10" },
- { {"f11"}, "r11" },
- { {"f12"}, "r12" },
- { {"f13"}, "r13" },
- { {"f14"}, "r14" },
- { {"f15"}, "r15" },
- { {"f16"}, "r16" },
- { {"f17"}, "r17" },
- { {"f18"}, "r18" },
- { {"f19"}, "r19" },
- { {"f20"}, "r20" },
- { {"f21"}, "r21" },
- { {"f22"}, "r22" },
- { {"f23"}, "r23" },
- { {"f24"}, "r24" },
- { {"f25"}, "r25" },
- { {"f26"}, "r26" },
- { {"f27"}, "r27" },
- { {"f28"}, "r28" },
- { {"f29"}, "r29" },
- { {"f30"}, "r30" },
- { {"f31"}, "r31" },
-};
-
-void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- Aliases = GCCRegAliases;
- NumAliases = llvm::array_lengthof(GCCRegAliases);
-}
-} // end anonymous namespace.
-
-namespace {
// Namespace for x86 abstract base class
const Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
@@ -1695,11 +1613,17 @@ const TargetInfo::AddlRegName AddlRegNames[] = {
// most of the implementation can be shared.
class X86TargetInfo : public TargetInfo {
enum X86SSEEnum {
- NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2
+ NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42, AVX, AVX2, AVX512F
} SSELevel;
enum MMX3DNowEnum {
NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
} MMX3DNowLevel;
+ enum XOPEnum {
+ NoXOP,
+ SSE4A,
+ FMA4,
+ XOP
+ } XOPLevel;
bool HasAES;
bool HasPCLMUL;
@@ -1711,11 +1635,12 @@ class X86TargetInfo : public TargetInfo {
bool HasRTM;
bool HasPRFCHW;
bool HasRDSEED;
- bool HasSSE4a;
- bool HasFMA4;
+ bool HasTBM;
bool HasFMA;
- bool HasXOP;
bool HasF16C;
+ bool HasAVX512CD, HasAVX512ER, HasAVX512PF;
+ bool HasSHA;
+ bool HasCX16;
/// \brief Enumeration of all of the X86 CPUs supported by Clang.
///
@@ -1789,6 +1714,7 @@ class X86TargetInfo : public TargetInfo {
/// Atom processors
//@{
CK_Atom,
+ CK_Silvermont,
//@}
/// \name Nehalem
@@ -1800,6 +1726,10 @@ class X86TargetInfo : public TargetInfo {
CK_CoreAVX2,
//@}
+ /// \name Knights Landing
+ /// Knights Landing processor.
+ CK_KNL,
+
/// \name K6
/// K6 architecture processors.
//@{
@@ -1843,6 +1773,7 @@ class X86TargetInfo : public TargetInfo {
//@{
CK_BDVER1,
CK_BDVER2,
+ CK_BDVER3,
//@}
/// This specification is deprecated and will be removed in the future.
@@ -1858,13 +1789,21 @@ class X86TargetInfo : public TargetInfo {
//@}
} CPU;
+ enum FPMathKind {
+ FP_Default,
+ FP_SSE,
+ FP_387
+ } FPMath;
+
public:
- X86TargetInfo(const std::string& triple)
- : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
- HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false),
- HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasRTM(false),
- HasPRFCHW(false), HasRDSEED(false), HasSSE4a(false), HasFMA4(false),
- HasFMA(false), HasXOP(false), HasF16C(false), CPU(CK_Generic) {
+ X86TargetInfo(const llvm::Triple &Triple)
+ : TargetInfo(Triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
+ XOPLevel(NoXOP), HasAES(false), HasPCLMUL(false), HasLZCNT(false),
+ HasRDRND(false), HasBMI(false), HasBMI2(false), HasPOPCNT(false),
+ HasRTM(false), HasPRFCHW(false), HasRDSEED(false), HasTBM(false),
+ HasFMA(false), HasF16C(false), HasAVX512CD(false), HasAVX512ER(false),
+ HasAVX512PF(false), HasSHA(false), HasCX16(false), CPU(CK_Generic),
+ FPMath(FP_Default) {
BigEndian = false;
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
}
@@ -1900,12 +1839,24 @@ public:
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const;
- virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const;
+ static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level,
+ bool Enabled);
+ static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level,
+ bool Enabled);
+ static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
+ bool Enabled);
+ virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
+ StringRef Name, bool Enabled) const {
+ setFeatureEnabledImpl(Features, Name, Enabled);
+ }
+ // This exists purely to cut down on the number of virtual calls in
+ // getDefaultFeatures which calls this repeatedly.
+ static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
+ StringRef Name, bool Enabled);
virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
virtual bool hasFeature(StringRef Feature) const;
- virtual void HandleTargetFeatures(std::vector<std::string> &Features);
+ virtual bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags);
virtual const char* getABI() const {
if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
return "avx";
@@ -1939,10 +1890,12 @@ public:
.Case("core2", CK_Core2)
.Case("penryn", CK_Penryn)
.Case("atom", CK_Atom)
+ .Case("slm", CK_Silvermont)
.Case("corei7", CK_Corei7)
.Case("corei7-avx", CK_Corei7AVX)
.Case("core-avx-i", CK_CoreAVXi)
.Case("core-avx2", CK_CoreAVX2)
+ .Case("knl", CK_KNL)
.Case("k6", CK_K6)
.Case("k6-2", CK_K6_2)
.Case("k6-3", CK_K6_3)
@@ -1963,6 +1916,7 @@ public:
.Case("btver2", CK_BTVER2)
.Case("bdver1", CK_BDVER1)
.Case("bdver2", CK_BDVER2)
+ .Case("bdver3", CK_BDVER3)
.Case("x86-64", CK_x86_64)
.Case("geode", CK_Geode)
.Default(CK_Generic);
@@ -2013,10 +1967,12 @@ public:
case CK_Core2:
case CK_Penryn:
case CK_Atom:
+ case CK_Silvermont:
case CK_Corei7:
case CK_Corei7AVX:
case CK_CoreAVXi:
case CK_CoreAVX2:
+ case CK_KNL:
case CK_Athlon64:
case CK_Athlon64SSE3:
case CK_AthlonFX:
@@ -2029,12 +1985,15 @@ public:
case CK_BTVER2:
case CK_BDVER1:
case CK_BDVER2:
+ case CK_BDVER3:
case CK_x86_64:
return true;
}
llvm_unreachable("Unhandled CPU kind");
}
+ virtual bool setFPMath(StringRef Name);
+
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
// We accept all non-ARM calling conventions
return (CC == CC_X86ThisCall ||
@@ -2050,40 +2009,24 @@ public:
}
};
-void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
- // FIXME: This should not be here.
- Features["3dnow"] = false;
- Features["3dnowa"] = false;
- Features["mmx"] = false;
- Features["sse"] = false;
- Features["sse2"] = false;
- Features["sse3"] = false;
- Features["ssse3"] = false;
- Features["sse41"] = false;
- Features["sse42"] = false;
- Features["sse4a"] = false;
- Features["aes"] = false;
- Features["pclmul"] = false;
- Features["avx"] = false;
- Features["avx2"] = false;
- Features["lzcnt"] = false;
- Features["rdrand"] = false;
- Features["bmi"] = false;
- Features["bmi2"] = false;
- Features["popcnt"] = false;
- Features["rtm"] = false;
- Features["prfchw"] = false;
- Features["rdseed"] = false;
- Features["fma4"] = false;
- Features["fma"] = false;
- Features["xop"] = false;
- Features["f16c"] = false;
+bool X86TargetInfo::setFPMath(StringRef Name) {
+ if (Name == "387") {
+ FPMath = FP_387;
+ return true;
+ }
+ if (Name == "sse") {
+ FPMath = FP_SSE;
+ return true;
+ }
+ return false;
+}
+void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
// FIXME: This *really* should not be here.
// X86_64 always has SSE2.
if (getTriple().getArch() == llvm::Triple::x86_64)
- setFeatureEnabled(Features, "sse2", true);
+ setFeatureEnabledImpl(Features, "sse2", true);
switch (CPU) {
case CK_Generic:
@@ -2096,295 +2039,349 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
break;
case CK_PentiumMMX:
case CK_Pentium2:
- setFeatureEnabled(Features, "mmx", true);
+ setFeatureEnabledImpl(Features, "mmx", true);
break;
case CK_Pentium3:
case CK_Pentium3M:
- setFeatureEnabled(Features, "sse", true);
+ setFeatureEnabledImpl(Features, "sse", true);
break;
case CK_PentiumM:
case CK_Pentium4:
case CK_Pentium4M:
case CK_x86_64:
- setFeatureEnabled(Features, "sse2", true);
+ setFeatureEnabledImpl(Features, "sse2", true);
break;
case CK_Yonah:
case CK_Prescott:
case CK_Nocona:
- setFeatureEnabled(Features, "sse3", true);
+ setFeatureEnabledImpl(Features, "sse3", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_Core2:
- setFeatureEnabled(Features, "ssse3", true);
+ setFeatureEnabledImpl(Features, "ssse3", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_Penryn:
- setFeatureEnabled(Features, "sse4.1", true);
+ setFeatureEnabledImpl(Features, "sse4.1", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_Atom:
- setFeatureEnabled(Features, "ssse3", true);
+ setFeatureEnabledImpl(Features, "ssse3", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
+ break;
+ case CK_Silvermont:
+ setFeatureEnabledImpl(Features, "sse4.2", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
break;
case CK_Corei7:
- setFeatureEnabled(Features, "sse4", true);
+ setFeatureEnabledImpl(Features, "sse4.2", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_Corei7AVX:
- setFeatureEnabled(Features, "avx", true);
- setFeatureEnabled(Features, "aes", true);
- setFeatureEnabled(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "avx", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
break;
case CK_CoreAVXi:
- setFeatureEnabled(Features, "avx", true);
- setFeatureEnabled(Features, "aes", true);
- setFeatureEnabled(Features, "pclmul", true);
- setFeatureEnabled(Features, "rdrnd", true);
- setFeatureEnabled(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "avx", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "rdrnd", true);
+ setFeatureEnabledImpl(Features, "f16c", true);
break;
case CK_CoreAVX2:
- setFeatureEnabled(Features, "avx2", true);
- setFeatureEnabled(Features, "aes", true);
- setFeatureEnabled(Features, "pclmul", true);
- setFeatureEnabled(Features, "lzcnt", true);
- setFeatureEnabled(Features, "rdrnd", true);
- setFeatureEnabled(Features, "f16c", true);
- setFeatureEnabled(Features, "bmi", true);
- setFeatureEnabled(Features, "bmi2", true);
- setFeatureEnabled(Features, "rtm", true);
- setFeatureEnabled(Features, "fma", true);
+ setFeatureEnabledImpl(Features, "avx2", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "lzcnt", true);
+ setFeatureEnabledImpl(Features, "rdrnd", true);
+ setFeatureEnabledImpl(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "bmi", true);
+ setFeatureEnabledImpl(Features, "bmi2", true);
+ setFeatureEnabledImpl(Features, "rtm", true);
+ setFeatureEnabledImpl(Features, "fma", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
+ break;
+ case CK_KNL:
+ setFeatureEnabledImpl(Features, "avx512f", true);
+ setFeatureEnabledImpl(Features, "avx512cd", true);
+ setFeatureEnabledImpl(Features, "avx512er", true);
+ setFeatureEnabledImpl(Features, "avx512pf", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "lzcnt", true);
+ setFeatureEnabledImpl(Features, "rdrnd", true);
+ setFeatureEnabledImpl(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "bmi", true);
+ setFeatureEnabledImpl(Features, "bmi2", true);
+ setFeatureEnabledImpl(Features, "rtm", true);
+ setFeatureEnabledImpl(Features, "fma", true);
break;
case CK_K6:
case CK_WinChipC6:
- setFeatureEnabled(Features, "mmx", true);
+ setFeatureEnabledImpl(Features, "mmx", true);
break;
case CK_K6_2:
case CK_K6_3:
case CK_WinChip2:
case CK_C3:
- setFeatureEnabled(Features, "3dnow", true);
+ setFeatureEnabledImpl(Features, "3dnow", true);
break;
case CK_Athlon:
case CK_AthlonThunderbird:
case CK_Geode:
- setFeatureEnabled(Features, "3dnowa", true);
+ setFeatureEnabledImpl(Features, "3dnowa", true);
break;
case CK_Athlon4:
case CK_AthlonXP:
case CK_AthlonMP:
- setFeatureEnabled(Features, "sse", true);
- setFeatureEnabled(Features, "3dnowa", true);
+ setFeatureEnabledImpl(Features, "sse", true);
+ setFeatureEnabledImpl(Features, "3dnowa", true);
break;
case CK_K8:
case CK_Opteron:
case CK_Athlon64:
case CK_AthlonFX:
- setFeatureEnabled(Features, "sse2", true);
- setFeatureEnabled(Features, "3dnowa", true);
+ setFeatureEnabledImpl(Features, "sse2", true);
+ setFeatureEnabledImpl(Features, "3dnowa", true);
break;
case CK_K8SSE3:
case CK_OpteronSSE3:
case CK_Athlon64SSE3:
- setFeatureEnabled(Features, "sse3", true);
- setFeatureEnabled(Features, "3dnowa", true);
+ setFeatureEnabledImpl(Features, "sse3", true);
+ setFeatureEnabledImpl(Features, "3dnowa", true);
break;
case CK_AMDFAM10:
- setFeatureEnabled(Features, "sse3", true);
- setFeatureEnabled(Features, "sse4a", true);
- setFeatureEnabled(Features, "3dnowa", true);
- setFeatureEnabled(Features, "lzcnt", true);
- setFeatureEnabled(Features, "popcnt", true);
+ setFeatureEnabledImpl(Features, "sse3", true);
+ setFeatureEnabledImpl(Features, "sse4a", true);
+ setFeatureEnabledImpl(Features, "3dnowa", true);
+ setFeatureEnabledImpl(Features, "lzcnt", true);
+ setFeatureEnabledImpl(Features, "popcnt", true);
break;
case CK_BTVER1:
- setFeatureEnabled(Features, "ssse3", true);
- setFeatureEnabled(Features, "sse4a", true);
- setFeatureEnabled(Features, "lzcnt", true);
- setFeatureEnabled(Features, "popcnt", true);
+ setFeatureEnabledImpl(Features, "ssse3", true);
+ setFeatureEnabledImpl(Features, "sse4a", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
+ setFeatureEnabledImpl(Features, "lzcnt", true);
+ setFeatureEnabledImpl(Features, "popcnt", true);
+ setFeatureEnabledImpl(Features, "prfchw", true);
break;
case CK_BTVER2:
- setFeatureEnabled(Features, "avx", true);
- setFeatureEnabled(Features, "sse4a", true);
- setFeatureEnabled(Features, "lzcnt", true);
- setFeatureEnabled(Features, "aes", true);
- setFeatureEnabled(Features, "pclmul", true);
- setFeatureEnabled(Features, "bmi", true);
- setFeatureEnabled(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "avx", true);
+ setFeatureEnabledImpl(Features, "sse4a", true);
+ setFeatureEnabledImpl(Features, "lzcnt", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "prfchw", true);
+ setFeatureEnabledImpl(Features, "bmi", true);
+ setFeatureEnabledImpl(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_BDVER1:
- setFeatureEnabled(Features, "xop", true);
- setFeatureEnabled(Features, "lzcnt", true);
- setFeatureEnabled(Features, "aes", true);
- setFeatureEnabled(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "xop", true);
+ setFeatureEnabledImpl(Features, "lzcnt", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "prfchw", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_BDVER2:
- setFeatureEnabled(Features, "xop", true);
- setFeatureEnabled(Features, "lzcnt", true);
- setFeatureEnabled(Features, "aes", true);
- setFeatureEnabled(Features, "pclmul", true);
- setFeatureEnabled(Features, "bmi", true);
- setFeatureEnabled(Features, "fma", true);
- setFeatureEnabled(Features, "f16c", true);
+ case CK_BDVER3:
+ setFeatureEnabledImpl(Features, "xop", true);
+ setFeatureEnabledImpl(Features, "lzcnt", true);
+ setFeatureEnabledImpl(Features, "aes", true);
+ setFeatureEnabledImpl(Features, "pclmul", true);
+ setFeatureEnabledImpl(Features, "prfchw", true);
+ setFeatureEnabledImpl(Features, "bmi", true);
+ setFeatureEnabledImpl(Features, "fma", true);
+ setFeatureEnabledImpl(Features, "f16c", true);
+ setFeatureEnabledImpl(Features, "tbm", true);
+ setFeatureEnabledImpl(Features, "cx16", true);
break;
case CK_C3_2:
- setFeatureEnabled(Features, "sse", true);
+ setFeatureEnabledImpl(Features, "sse", true);
break;
}
}
-bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const {
- // FIXME: This *really* should not be here. We need some way of translating
- // options into llvm subtarget features.
- if (!Features.count(Name) &&
- (Name != "sse4" && Name != "sse4.2" && Name != "sse4.1" &&
- Name != "rdrnd"))
- return false;
+void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features,
+ X86SSEEnum Level, bool Enabled) {
+ if (Enabled) {
+ switch (Level) {
+ case AVX512F:
+ Features["avx512f"] = true;
+ case AVX2:
+ Features["avx2"] = true;
+ case AVX:
+ Features["avx"] = true;
+ case SSE42:
+ Features["sse4.2"] = true;
+ case SSE41:
+ Features["sse4.1"] = true;
+ case SSSE3:
+ Features["ssse3"] = true;
+ case SSE3:
+ Features["sse3"] = true;
+ case SSE2:
+ Features["sse2"] = true;
+ case SSE1:
+ Features["sse"] = true;
+ case NoSSE:
+ break;
+ }
+ return;
+ }
- // FIXME: this should probably use a switch with fall through.
+ switch (Level) {
+ case NoSSE:
+ case SSE1:
+ Features["sse"] = false;
+ case SSE2:
+ Features["sse2"] = Features["pclmul"] = Features["aes"] =
+ Features["sha"] = false;
+ case SSE3:
+ Features["sse3"] = false;
+ setXOPLevel(Features, NoXOP, false);
+ case SSSE3:
+ Features["ssse3"] = false;
+ case SSE41:
+ Features["sse4.1"] = false;
+ case SSE42:
+ Features["sse4.2"] = false;
+ case AVX:
+ Features["fma"] = Features["avx"] = Features["f16c"] = false;
+ setXOPLevel(Features, FMA4, false);
+ case AVX2:
+ Features["avx2"] = false;
+ case AVX512F:
+ Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] =
+ Features["avx512pf"] = false;
+ }
+}
+void X86TargetInfo::setMMXLevel(llvm::StringMap<bool> &Features,
+ MMX3DNowEnum Level, bool Enabled) {
if (Enabled) {
- if (Name == "mmx")
+ switch (Level) {
+ case AMD3DNowAthlon:
+ Features["3dnowa"] = true;
+ case AMD3DNow:
+ Features["3dnow"] = true;
+ case MMX:
Features["mmx"] = true;
- else if (Name == "sse")
- Features["mmx"] = Features["sse"] = true;
- else if (Name == "sse2")
- Features["mmx"] = Features["sse"] = Features["sse2"] = true;
- else if (Name == "sse3")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- true;
- else if (Name == "ssse3")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = true;
- else if (Name == "sse4" || Name == "sse4.2")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] =
- Features["popcnt"] = true;
- else if (Name == "sse4.1")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = true;
- else if (Name == "3dnow")
- Features["mmx"] = Features["3dnow"] = true;
- else if (Name == "3dnowa")
- Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = true;
- else if (Name == "aes")
- Features["sse"] = Features["sse2"] = Features["aes"] = true;
- else if (Name == "pclmul")
- Features["sse"] = Features["sse2"] = Features["pclmul"] = true;
- else if (Name == "avx")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] =
- Features["popcnt"] = Features["avx"] = true;
- else if (Name == "avx2")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] =
- Features["popcnt"] = Features["avx"] = Features["avx2"] = true;
- else if (Name == "fma")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] =
- Features["popcnt"] = Features["avx"] = Features["fma"] = true;
- else if (Name == "fma4")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] =
- Features["popcnt"] = Features["avx"] = Features["sse4a"] =
- Features["fma4"] = true;
- else if (Name == "xop")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] =
- Features["popcnt"] = Features["avx"] = Features["sse4a"] =
- Features["fma4"] = Features["xop"] = true;
- else if (Name == "sse4a")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["sse4a"] = true;
- else if (Name == "lzcnt")
- Features["lzcnt"] = true;
- else if (Name == "rdrnd")
- Features["rdrand"] = true;
- else if (Name == "bmi")
- Features["bmi"] = true;
- else if (Name == "bmi2")
- Features["bmi2"] = true;
- else if (Name == "popcnt")
- Features["popcnt"] = true;
- else if (Name == "f16c")
- Features["f16c"] = true;
- else if (Name == "rtm")
- Features["rtm"] = true;
- else if (Name == "prfchw")
- Features["prfchw"] = true;
- else if (Name == "rdseed")
- Features["rdseed"] = true;
- } else {
- if (Name == "mmx")
- Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false;
- else if (Name == "sse")
- Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] =
- Features["sse4a"] = Features["avx"] = Features["avx2"] =
- Features["fma"] = Features["fma4"] = Features["aes"] =
- Features["pclmul"] = Features["xop"] = false;
- else if (Name == "sse2")
- Features["sse2"] = Features["sse3"] = Features["ssse3"] =
- Features["sse41"] = Features["sse42"] = Features["sse4a"] =
- Features["avx"] = Features["avx2"] = Features["fma"] =
- Features["fma4"] = Features["aes"] = Features["pclmul"] =
- Features["xop"] = false;
- else if (Name == "sse3")
- Features["sse3"] = Features["ssse3"] = Features["sse41"] =
- Features["sse42"] = Features["sse4a"] = Features["avx"] =
- Features["avx2"] = Features["fma"] = Features["fma4"] =
- Features["xop"] = false;
- else if (Name == "ssse3")
- Features["ssse3"] = Features["sse41"] = Features["sse42"] =
- Features["avx"] = Features["avx2"] = Features["fma"] = false;
- else if (Name == "sse4" || Name == "sse4.1")
- Features["sse41"] = Features["sse42"] = Features["avx"] =
- Features["avx2"] = Features["fma"] = false;
- else if (Name == "sse4.2")
- Features["sse42"] = Features["avx"] = Features["avx2"] =
- Features["fma"] = false;
- else if (Name == "3dnow")
- Features["3dnow"] = Features["3dnowa"] = false;
- else if (Name == "3dnowa")
- Features["3dnowa"] = false;
- else if (Name == "aes")
- Features["aes"] = false;
- else if (Name == "pclmul")
- Features["pclmul"] = false;
- else if (Name == "avx")
- Features["avx"] = Features["avx2"] = Features["fma"] =
- Features["fma4"] = Features["xop"] = false;
- else if (Name == "avx2")
- Features["avx2"] = false;
- else if (Name == "fma")
- Features["fma"] = false;
- else if (Name == "sse4a")
- Features["sse4a"] = Features["fma4"] = Features["xop"] = false;
- else if (Name == "lzcnt")
- Features["lzcnt"] = false;
- else if (Name == "rdrnd")
- Features["rdrand"] = false;
- else if (Name == "bmi")
- Features["bmi"] = false;
- else if (Name == "bmi2")
- Features["bmi2"] = false;
- else if (Name == "popcnt")
- Features["popcnt"] = false;
- else if (Name == "fma4")
- Features["fma4"] = Features["xop"] = false;
- else if (Name == "xop")
- Features["xop"] = false;
- else if (Name == "f16c")
- Features["f16c"] = false;
- else if (Name == "rtm")
- Features["rtm"] = false;
- else if (Name == "prfchw")
- Features["prfchw"] = false;
- else if (Name == "rdseed")
- Features["rdseed"] = false;
+ case NoMMX3DNow:
+ break;
+ }
+ return;
}
- return true;
+ switch (Level) {
+ case NoMMX3DNow:
+ case MMX:
+ Features["mmx"] = false;
+ case AMD3DNow:
+ Features["3dnow"] = false;
+ case AMD3DNowAthlon:
+ Features["3dnowa"] = false;
+ }
+}
+
+void X86TargetInfo::setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
+ bool Enabled) {
+ if (Enabled) {
+ switch (Level) {
+ case XOP:
+ Features["xop"] = true;
+ case FMA4:
+ Features["fma4"] = true;
+ setSSELevel(Features, AVX, true);
+ case SSE4A:
+ Features["sse4a"] = true;
+ setSSELevel(Features, SSE3, true);
+ case NoXOP:
+ break;
+ }
+ return;
+ }
+
+ switch (Level) {
+ case NoXOP:
+ case SSE4A:
+ Features["sse4a"] = false;
+ case FMA4:
+ Features["fma4"] = false;
+ case XOP:
+ Features["xop"] = false;
+ }
}
-/// HandleTargetOptions - Perform initialization based on the user
+void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
+ StringRef Name, bool Enabled) {
+ // FIXME: This *really* should not be here. We need some way of translating
+ // options into llvm subtarget features.
+ if (Name == "sse4")
+ Name = "sse4.2";
+
+ Features[Name] = Enabled;
+
+ if (Name == "mmx") {
+ setMMXLevel(Features, MMX, Enabled);
+ } else if (Name == "sse") {
+ setSSELevel(Features, SSE1, Enabled);
+ } else if (Name == "sse2") {
+ setSSELevel(Features, SSE2, Enabled);
+ } else if (Name == "sse3") {
+ setSSELevel(Features, SSE3, Enabled);
+ } else if (Name == "ssse3") {
+ setSSELevel(Features, SSSE3, Enabled);
+ } else if (Name == "sse4.2") {
+ setSSELevel(Features, SSE42, Enabled);
+ } else if (Name == "sse4.1") {
+ setSSELevel(Features, SSE41, Enabled);
+ } else if (Name == "3dnow") {
+ setMMXLevel(Features, AMD3DNow, Enabled);
+ } else if (Name == "3dnowa") {
+ setMMXLevel(Features, AMD3DNowAthlon, Enabled);
+ } else if (Name == "aes") {
+ if (Enabled)
+ setSSELevel(Features, SSE2, Enabled);
+ } else if (Name == "pclmul") {
+ if (Enabled)
+ setSSELevel(Features, SSE2, Enabled);
+ } else if (Name == "avx") {
+ setSSELevel(Features, AVX, Enabled);
+ } else if (Name == "avx2") {
+ setSSELevel(Features, AVX2, Enabled);
+ } else if (Name == "avx512f") {
+ setSSELevel(Features, AVX512F, Enabled);
+ } else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf") {
+ if (Enabled)
+ setSSELevel(Features, AVX512F, Enabled);
+ } else if (Name == "fma") {
+ if (Enabled)
+ setSSELevel(Features, AVX, Enabled);
+ } else if (Name == "fma4") {
+ setXOPLevel(Features, FMA4, Enabled);
+ } else if (Name == "xop") {
+ setXOPLevel(Features, XOP, Enabled);
+ } else if (Name == "sse4a") {
+ setXOPLevel(Features, SSE4A, Enabled);
+ } else if (Name == "f16c") {
+ if (Enabled)
+ setSSELevel(Features, AVX, Enabled);
+ } else if (Name == "sha") {
+ if (Enabled)
+ setSSELevel(Features, SSE2, Enabled);
+ }
+}
+
+/// handleTargetFeatures - Perform initialization based on the user
/// configured set of features.
-void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
+bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
// Remember the maximum enabled sselevel.
for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
// Ignore disabled features.
@@ -2408,7 +2405,7 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
continue;
}
- if (Feature == "rdrand") {
+ if (Feature == "rdrnd") {
HasRDRND = true;
continue;
}
@@ -2443,37 +2440,53 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
continue;
}
- if (Feature == "sse4a") {
- HasSSE4a = true;
+ if (Feature == "tbm") {
+ HasTBM = true;
continue;
}
- if (Feature == "fma4") {
- HasFMA4 = true;
+ if (Feature == "fma") {
+ HasFMA = true;
continue;
}
- if (Feature == "fma") {
- HasFMA = true;
+ if (Feature == "f16c") {
+ HasF16C = true;
continue;
}
- if (Feature == "xop") {
- HasXOP = true;
+ if (Feature == "avx512cd") {
+ HasAVX512CD = true;
continue;
}
- if (Feature == "f16c") {
- HasF16C = true;
+ if (Feature == "avx512er") {
+ HasAVX512ER = true;
+ continue;
+ }
+
+ if (Feature == "avx512pf") {
+ HasAVX512PF = true;
+ continue;
+ }
+
+ if (Feature == "sha") {
+ HasSHA = true;
+ continue;
+ }
+
+ if (Feature == "cx16") {
+ HasCX16 = true;
continue;
}
assert(Features[i][0] == '+' && "Invalid target feature!");
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
+ .Case("avx512f", AVX512F)
.Case("avx2", AVX2)
.Case("avx", AVX)
- .Case("sse42", SSE42)
- .Case("sse41", SSE41)
+ .Case("sse4.2", SSE42)
+ .Case("sse4.1", SSE41)
.Case("ssse3", SSSE3)
.Case("sse3", SSE3)
.Case("sse2", SSE2)
@@ -2487,16 +2500,53 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
.Case("3dnow", AMD3DNow)
.Case("mmx", MMX)
.Default(NoMMX3DNow);
-
MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
+
+ XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
+ .Case("xop", XOP)
+ .Case("fma4", FMA4)
+ .Case("sse4a", SSE4A)
+ .Default(NoXOP);
+ XOPLevel = std::max(XOPLevel, XLevel);
+ }
+
+ // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
+ // Can't do this earlier because we need to be able to explicitly enable
+ // popcnt and still disable sse4.2.
+ if (!HasPOPCNT && SSELevel >= SSE42 &&
+ std::find(Features.begin(), Features.end(), "-popcnt") == Features.end()){
+ HasPOPCNT = true;
+ Features.push_back("+popcnt");
+ }
+
+ // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled.
+ if (!HasPRFCHW && MMX3DNowLevel >= AMD3DNow &&
+ std::find(Features.begin(), Features.end(), "-prfchw") == Features.end()){
+ HasPRFCHW = true;
+ Features.push_back("+prfchw");
+ }
+
+ // LLVM doesn't have a separate switch for fpmath, so only accept it if it
+ // matches the selected sse level.
+ if (FPMath == FP_SSE && SSELevel < SSE1) {
+ Diags.Report(diag::err_target_unsupported_fpmath) << "sse";
+ return false;
+ } else if (FPMath == FP_387 && SSELevel >= SSE1) {
+ Diags.Report(diag::err_target_unsupported_fpmath) << "387";
+ return false;
}
// Don't tell the backend if we're turning off mmx; it will end up disabling
// SSE, which we don't want.
+ // Additionally, if SSE is enabled and mmx is not explicitly disabled,
+ // then enable MMX.
std::vector<std::string>::iterator it;
it = std::find(Features.begin(), Features.end(), "-mmx");
if (it != Features.end())
Features.erase(it);
+ else if (SSELevel > NoSSE)
+ MMX3DNowLevel = std::max(MMX3DNowLevel, MMX);
+ return true;
}
/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
@@ -2574,12 +2624,18 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Atom:
defineCPUMacros(Builder, "atom");
break;
+ case CK_Silvermont:
+ defineCPUMacros(Builder, "slm");
+ break;
case CK_Corei7:
case CK_Corei7AVX:
case CK_CoreAVXi:
case CK_CoreAVX2:
defineCPUMacros(Builder, "corei7");
break;
+ case CK_KNL:
+ defineCPUMacros(Builder, "knl");
+ break;
case CK_K6_2:
Builder.defineMacro("__k6_2__");
Builder.defineMacro("__tune_k6_2__");
@@ -2632,6 +2688,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_BDVER2:
defineCPUMacros(Builder, "bdver2");
break;
+ case CK_BDVER3:
+ defineCPUMacros(Builder, "bdver3");
+ break;
case CK_Geode:
defineCPUMacros(Builder, "geode");
break;
@@ -2676,23 +2735,43 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasRDSEED)
Builder.defineMacro("__RDSEED__");
- if (HasSSE4a)
- Builder.defineMacro("__SSE4A__");
+ if (HasTBM)
+ Builder.defineMacro("__TBM__");
- if (HasFMA4)
+ switch (XOPLevel) {
+ case XOP:
+ Builder.defineMacro("__XOP__");
+ case FMA4:
Builder.defineMacro("__FMA4__");
+ case SSE4A:
+ Builder.defineMacro("__SSE4A__");
+ case NoXOP:
+ break;
+ }
if (HasFMA)
Builder.defineMacro("__FMA__");
- if (HasXOP)
- Builder.defineMacro("__XOP__");
-
if (HasF16C)
Builder.defineMacro("__F16C__");
+ if (HasAVX512CD)
+ Builder.defineMacro("__AVX512CD__");
+ if (HasAVX512ER)
+ Builder.defineMacro("__AVX512ER__");
+ if (HasAVX512PF)
+ Builder.defineMacro("__AVX512PF__");
+
+ if (HasSHA)
+ Builder.defineMacro("__SHA__");
+
+ if (HasCX16)
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
+
// Each case falls through to the previous one here.
switch (SSELevel) {
+ case AVX512F:
+ Builder.defineMacro("__AVX512F__");
case AVX2:
Builder.defineMacro("__AVX2__");
case AVX:
@@ -2717,6 +2796,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (Opts.MicrosoftExt && getTriple().getArch() == llvm::Triple::x86) {
switch (SSELevel) {
+ case AVX512F:
case AVX2:
case AVX:
case SSE42:
@@ -2760,10 +2840,17 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("aes", HasAES)
.Case("avx", SSELevel >= AVX)
.Case("avx2", SSELevel >= AVX2)
+ .Case("avx512f", SSELevel >= AVX512F)
+ .Case("avx512cd", HasAVX512CD)
+ .Case("avx512er", HasAVX512ER)
+ .Case("avx512pf", HasAVX512PF)
.Case("bmi", HasBMI)
.Case("bmi2", HasBMI2)
+ .Case("cx16", HasCX16)
+ .Case("f16c", HasF16C)
.Case("fma", HasFMA)
- .Case("fma4", HasFMA4)
+ .Case("fma4", XOPLevel >= FMA4)
+ .Case("tbm", HasTBM)
.Case("lzcnt", HasLZCNT)
.Case("rdrnd", HasRDRND)
.Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
@@ -2774,18 +2861,18 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("rtm", HasRTM)
.Case("prfchw", HasPRFCHW)
.Case("rdseed", HasRDSEED)
+ .Case("sha", HasSHA)
.Case("sse", SSELevel >= SSE1)
.Case("sse2", SSELevel >= SSE2)
.Case("sse3", SSELevel >= SSE3)
.Case("ssse3", SSELevel >= SSSE3)
- .Case("sse41", SSELevel >= SSE41)
- .Case("sse42", SSELevel >= SSE42)
- .Case("sse4a", HasSSE4a)
+ .Case("sse4.1", SSELevel >= SSE41)
+ .Case("sse4.2", SSELevel >= SSE42)
+ .Case("sse4a", XOPLevel >= SSE4A)
.Case("x86", true)
.Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
.Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
- .Case("xop", HasXOP)
- .Case("f16c", HasF16C)
+ .Case("xop", XOPLevel >= XOP)
.Default(false);
}
@@ -2858,7 +2945,7 @@ namespace {
// X86-32 generic target
class X86_32TargetInfo : public X86TargetInfo {
public:
- X86_32TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
+ X86_32TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
DoubleAlign = LongLongAlign = 32;
LongDoubleWidth = 96;
LongDoubleAlign = 32;
@@ -2909,12 +2996,16 @@ public:
namespace {
class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> {
public:
- NetBSDI386TargetInfo(const std::string &triple) :
- NetBSDTargetInfo<X86_32TargetInfo>(triple) {
- }
+ NetBSDI386TargetInfo(const llvm::Triple &Triple)
+ : NetBSDTargetInfo<X86_32TargetInfo>(Triple) {}
virtual unsigned getFloatEvalMethod() const {
- // NetBSD defaults to "double" rounding
+ unsigned Major, Minor, Micro;
+ getTriple().getOSVersion(Major, Minor, Micro);
+ // New NetBSD uses the default rounding mode.
+ if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0)
+ return X86_32TargetInfo::getFloatEvalMethod();
+ // NetBSD before 6.99.26 defaults to "double" rounding.
return 1;
}
};
@@ -2923,8 +3014,8 @@ public:
namespace {
class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> {
public:
- OpenBSDI386TargetInfo(const std::string& triple) :
- OpenBSDTargetInfo<X86_32TargetInfo>(triple) {
+ OpenBSDI386TargetInfo(const llvm::Triple &Triple)
+ : OpenBSDTargetInfo<X86_32TargetInfo>(Triple) {
SizeType = UnsignedLong;
IntPtrType = SignedLong;
PtrDiffType = SignedLong;
@@ -2935,8 +3026,8 @@ public:
namespace {
class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> {
public:
- BitrigI386TargetInfo(const std::string& triple) :
- BitrigTargetInfo<X86_32TargetInfo>(triple) {
+ BitrigI386TargetInfo(const llvm::Triple &Triple)
+ : BitrigTargetInfo<X86_32TargetInfo>(Triple) {
SizeType = UnsignedLong;
IntPtrType = SignedLong;
PtrDiffType = SignedLong;
@@ -2947,8 +3038,8 @@ public:
namespace {
class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
public:
- DarwinI386TargetInfo(const std::string& triple) :
- DarwinTargetInfo<X86_32TargetInfo>(triple) {
+ DarwinI386TargetInfo(const llvm::Triple &Triple)
+ : DarwinTargetInfo<X86_32TargetInfo>(Triple) {
LongDoubleWidth = 128;
LongDoubleAlign = 128;
SuitableAlign = 128;
@@ -2968,8 +3059,8 @@ namespace {
// x86-32 Windows target
class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> {
public:
- WindowsX86_32TargetInfo(const std::string& triple)
- : WindowsTargetInfo<X86_32TargetInfo>(triple) {
+ WindowsX86_32TargetInfo(const llvm::Triple &Triple)
+ : WindowsTargetInfo<X86_32TargetInfo>(Triple) {
TLSSupported = false;
WCharType = UnsignedShort;
DoubleAlign = LongLongAlign = 64;
@@ -2989,8 +3080,8 @@ namespace {
// x86-32 Windows Visual Studio target
class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
public:
- VisualStudioWindowsX86_32TargetInfo(const std::string& triple)
- : WindowsX86_32TargetInfo(triple) {
+ VisualStudioWindowsX86_32TargetInfo(const llvm::Triple &Triple)
+ : WindowsX86_32TargetInfo(Triple) {
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
}
@@ -3010,9 +3101,8 @@ namespace {
// x86-32 MinGW target
class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
public:
- MinGWX86_32TargetInfo(const std::string& triple)
- : WindowsX86_32TargetInfo(triple) {
- }
+ MinGWX86_32TargetInfo(const llvm::Triple &Triple)
+ : WindowsX86_32TargetInfo(Triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
@@ -3038,8 +3128,8 @@ namespace {
// x86-32 Cygwin target
class CygwinX86_32TargetInfo : public X86_32TargetInfo {
public:
- CygwinX86_32TargetInfo(const std::string& triple)
- : X86_32TargetInfo(triple) {
+ CygwinX86_32TargetInfo(const llvm::Triple &Triple)
+ : X86_32TargetInfo(Triple) {
TLSSupported = false;
WCharType = UnsignedShort;
DoubleAlign = LongLongAlign = 64;
@@ -3064,8 +3154,7 @@ namespace {
// x86-32 Haiku target
class HaikuX86_32TargetInfo : public X86_32TargetInfo {
public:
- HaikuX86_32TargetInfo(const std::string& triple)
- : X86_32TargetInfo(triple) {
+ HaikuX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
SizeType = UnsignedLong;
IntPtrType = SignedLong;
PtrDiffType = SignedLong;
@@ -3093,37 +3182,35 @@ protected:
Builder.defineMacro("__rtems__");
Builder.defineMacro("__ELF__");
}
-public:
- RTEMSTargetInfo(const std::string &triple)
- : OSTargetInfo<Target>(triple) {
- this->UserLabelPrefix = "";
- llvm::Triple Triple(triple);
- switch (Triple.getArch()) {
- default:
- case llvm::Triple::x86:
- // this->MCountName = ".mcount";
- break;
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- // this->MCountName = "_mcount";
- break;
- case llvm::Triple::arm:
- // this->MCountName = "__mcount";
- break;
- }
+public:
+ RTEMSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
+ this->UserLabelPrefix = "";
+ switch (Triple.getArch()) {
+ default:
+ case llvm::Triple::x86:
+ // this->MCountName = ".mcount";
+ break;
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ // this->MCountName = "_mcount";
+ break;
+ case llvm::Triple::arm:
+ // this->MCountName = "__mcount";
+ break;
}
+ }
};
namespace {
// x86-32 RTEMS target
class RTEMSX86_32TargetInfo : public X86_32TargetInfo {
public:
- RTEMSX86_32TargetInfo(const std::string& triple)
- : X86_32TargetInfo(triple) {
+ RTEMSX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) {
SizeType = UnsignedLong;
IntPtrType = SignedLong;
PtrDiffType = SignedLong;
@@ -3142,7 +3229,7 @@ namespace {
// x86-64 generic target
class X86_64TargetInfo : public X86TargetInfo {
public:
- X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
+ X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
LongDoubleWidth = 128;
LongDoubleAlign = 128;
@@ -3181,8 +3268,7 @@ public:
}
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
- return (CC == CC_Default ||
- CC == CC_C ||
+ return (CC == CC_C ||
CC == CC_IntelOclBicc ||
CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
}
@@ -3198,8 +3284,8 @@ namespace {
// x86-64 Windows target
class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> {
public:
- WindowsX86_64TargetInfo(const std::string& triple)
- : WindowsTargetInfo<X86_64TargetInfo>(triple) {
+ WindowsX86_64TargetInfo(const llvm::Triple &Triple)
+ : WindowsTargetInfo<X86_64TargetInfo>(Triple) {
TLSSupported = false;
WCharType = UnsignedShort;
LongWidth = LongAlign = 32;
@@ -3232,8 +3318,8 @@ namespace {
// x86-64 Windows Visual Studio target
class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
public:
- VisualStudioWindowsX86_64TargetInfo(const std::string& triple)
- : WindowsX86_64TargetInfo(triple) {
+ VisualStudioWindowsX86_64TargetInfo(const llvm::Triple &Triple)
+ : WindowsX86_64TargetInfo(Triple) {
LongDoubleWidth = LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
}
@@ -3251,9 +3337,8 @@ namespace {
// x86-64 MinGW target
class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo {
public:
- MinGWX86_64TargetInfo(const std::string& triple)
- : WindowsX86_64TargetInfo(triple) {
- }
+ MinGWX86_64TargetInfo(const llvm::Triple &Triple)
+ : WindowsX86_64TargetInfo(Triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
@@ -3277,8 +3362,8 @@ public:
namespace {
class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
public:
- DarwinX86_64TargetInfo(const std::string& triple)
- : DarwinTargetInfo<X86_64TargetInfo>(triple) {
+ DarwinX86_64TargetInfo(const llvm::Triple &Triple)
+ : DarwinTargetInfo<X86_64TargetInfo>(Triple) {
Int64Type = SignedLongLong;
MaxVectorAlign = 256;
}
@@ -3288,8 +3373,8 @@ public:
namespace {
class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> {
public:
- OpenBSDX86_64TargetInfo(const std::string& triple)
- : OpenBSDTargetInfo<X86_64TargetInfo>(triple) {
+ OpenBSDX86_64TargetInfo(const llvm::Triple &Triple)
+ : OpenBSDTargetInfo<X86_64TargetInfo>(Triple) {
IntMaxType = SignedLongLong;
UIntMaxType = UnsignedLongLong;
Int64Type = SignedLongLong;
@@ -3300,11 +3385,11 @@ public:
namespace {
class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> {
public:
- BitrigX86_64TargetInfo(const std::string& triple)
- : BitrigTargetInfo<X86_64TargetInfo>(triple) {
- IntMaxType = SignedLongLong;
- UIntMaxType = UnsignedLongLong;
- Int64Type = SignedLongLong;
+ BitrigX86_64TargetInfo(const llvm::Triple &Triple)
+ : BitrigTargetInfo<X86_64TargetInfo>(Triple) {
+ IntMaxType = SignedLongLong;
+ UIntMaxType = UnsignedLongLong;
+ Int64Type = SignedLongLong;
}
};
}
@@ -3314,9 +3399,17 @@ class AArch64TargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
static const TargetInfo::GCCRegAlias GCCRegAliases[];
+ enum FPUModeEnum {
+ FPUMode,
+ NeonMode
+ };
+
+ unsigned FPU;
+ unsigned Crypto;
static const Builtin::Info BuiltinInfo[];
+
public:
- AArch64TargetInfo(const std::string& triple) : TargetInfo(triple) {
+ AArch64TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
BigEndian = false;
LongWidth = LongAlign = 64;
LongDoubleWidth = LongDoubleAlign = 128;
@@ -3342,22 +3435,20 @@ public:
Builder.defineMacro("__AARCH64EL__");
// ACLE predefines. Many can only have one possible value on v8 AArch64.
-
- // FIXME: these were written based on an unreleased version of a 32-bit ACLE
- // which was intended to be compatible with a 64-bit implementation. They
- // will need updating when a real 64-bit ACLE exists. Particularly pressing
- // instances are: __ARM_ARCH_ISA_ARM, __ARM_ARCH_ISA_THUMB, __ARM_PCS.
- Builder.defineMacro("__ARM_ACLE", "101");
+ Builder.defineMacro("__ARM_ACLE", "200");
Builder.defineMacro("__ARM_ARCH", "8");
Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
+ Builder.defineMacro("__ARM_64BIT_STATE");
+ Builder.defineMacro("__ARM_PCS_AAPCS64");
+ Builder.defineMacro("__ARM_ARCH_ISA_A64");
+
Builder.defineMacro("__ARM_FEATURE_UNALIGNED");
Builder.defineMacro("__ARM_FEATURE_CLZ");
Builder.defineMacro("__ARM_FEATURE_FMA");
+ Builder.defineMacro("__ARM_FEATURE_DIV");
- // FIXME: ACLE 1.1 reserves bit 4. Will almost certainly come to mean
- // 128-bit LDXP present, at which point this becomes 0x1f.
- Builder.defineMacro("__ARM_FEATURE_LDREX", "0xf");
+ Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
// 0xe implies support for half, single and double precision operations.
Builder.defineMacro("__ARM_FP", "0xe");
@@ -3379,7 +3470,17 @@ public:
Opts.ShortEnums ? "1" : "4");
if (BigEndian)
- Builder.defineMacro("__ARM_BIG_ENDIAN");
+ Builder.defineMacro("__AARCH_BIG_ENDIAN");
+
+ if (FPU == NeonMode) {
+ Builder.defineMacro("__ARM_NEON");
+ // 64-bit NEON supports half, single and double precision operations.
+ Builder.defineMacro("__ARM_NEON_FP", "7");
+ }
+
+ if (Crypto) {
+ Builder.defineMacro("__ARM_FEATURE_CRYPTO");
+ }
}
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
@@ -3387,9 +3488,30 @@ public:
NumRecords = clang::AArch64::LastTSBuiltin-Builtin::FirstTSBuiltin;
}
virtual bool hasFeature(StringRef Feature) const {
- return Feature == "aarch64";
+ return Feature == "aarch64" || (Feature == "neon" && FPU == NeonMode);
}
- virtual void getGCCRegNames(const char * const *&Names,
+
+ virtual bool setCPU(const std::string &Name) {
+ return llvm::StringSwitch<bool>(Name)
+ .Case("generic", true)
+ .Cases("cortex-a53", "cortex-a57", true)
+ .Default(false);
+ }
+
+ virtual bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
+ FPU = FPUMode;
+ Crypto = 0;
+ for (unsigned i = 0, e = Features.size(); i != e; ++i) {
+ if (Features[i] == "+neon")
+ FPU = NeonMode;
+ if (Features[i] == "+crypto")
+ Crypto = 1;
+ }
+ return true;
+ }
+
+ virtual void getGCCRegNames(const char *const *&Names,
unsigned &NumNames) const;
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
unsigned &NumAliases) const;
@@ -3510,11 +3632,18 @@ class ARMTargetInfo : public TargetInfo {
VFP2FPU = (1 << 0),
VFP3FPU = (1 << 1),
VFP4FPU = (1 << 2),
- NeonFPU = (1 << 3)
+ NeonFPU = (1 << 3),
+ FPARMV8 = (1 << 4)
+ };
+
+ // Possible HWDiv features.
+ enum HWDivMode {
+ HWDivThumb = (1 << 0),
+ HWDivARM = (1 << 1)
};
static bool FPUModeIsVFP(FPUMode Mode) {
- return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU);
+ return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8);
}
static const TargetInfo::GCCRegAlias GCCRegAliases[];
@@ -3522,15 +3651,24 @@ class ARMTargetInfo : public TargetInfo {
std::string ABI, CPU;
- unsigned FPU : 4;
+ enum {
+ FP_Default,
+ FP_VFP,
+ FP_Neon
+ } FPMath;
+
+ unsigned FPU : 5;
unsigned IsAAPCS : 1;
unsigned IsThumb : 1;
+ unsigned HWDiv : 2;
// Initialized via features.
unsigned SoftFloat : 1;
unsigned SoftFloatABI : 1;
+ unsigned CRC : 1;
+
static const Builtin::Info BuiltinInfo[];
static bool shouldUseInlineAtomic(const llvm::Triple &T) {
@@ -3539,7 +3677,10 @@ class ARMTargetInfo : public TargetInfo {
// the kernel which on armv6 and newer uses ldrex and strex. The net result
// is that if we assume the kernel is at least as recent as the hardware,
// it is safe to use atomic instructions on armv6 and newer.
- if (T.getOS() != llvm::Triple::Linux && T.getOS() != llvm::Triple::FreeBSD)
+ if (!T.isOSLinux() &&
+ T.getOS() != llvm::Triple::FreeBSD &&
+ T.getOS() != llvm::Triple::NetBSD &&
+ T.getOS() != llvm::Triple::Bitrig)
return false;
StringRef ArchName = T.getArchName();
if (T.getArch() == llvm::Triple::arm) {
@@ -3562,14 +3703,23 @@ class ARMTargetInfo : public TargetInfo {
}
public:
- ARMTargetInfo(const std::string &TripleStr)
- : TargetInfo(TripleStr), ABI("aapcs-linux"), CPU("arm1136j-s"), IsAAPCS(true)
- {
+ ARMTargetInfo(const llvm::Triple &Triple)
+ : TargetInfo(Triple), ABI("aapcs-linux"), CPU("arm1136j-s"),
+ FPMath(FP_Default), IsAAPCS(true) {
BigEndian = false;
- SizeType = UnsignedInt;
- PtrDiffType = SignedInt;
- // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
- WCharType = UnsignedInt;
+ switch (getTriple().getOS()) {
+ case llvm::Triple::NetBSD:
+ SizeType = UnsignedLong;
+ PtrDiffType = SignedLong;
+ WCharType = SignedInt;
+ break;
+ default:
+ // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
+ WCharType = UnsignedInt;
+ SizeType = UnsignedInt;
+ PtrDiffType = SignedInt;
+ break;
+ }
// {} in inline assembly are neon specifiers, not assembly variant
// specifiers.
@@ -3645,6 +3795,9 @@ public:
// FIXME: Override "preferred align" for double and long long.
} else if (Name == "aapcs" || Name == "aapcs-vfp") {
+ // size_t is unsigned long on Darwin.
+ if (getTriple().isOSDarwin())
+ SizeType = UnsignedLong;
IsAAPCS = true;
// FIXME: Enumerated types are variable width in straight AAPCS.
} else if (Name == "aapcs-linux") {
@@ -3656,33 +3809,45 @@ public:
}
void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
+ StringRef ArchName = getTriple().getArchName();
if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
Features["vfp2"] = true;
- else if (CPU == "cortex-a8" || CPU == "cortex-a15" ||
- CPU == "cortex-a9" || CPU == "cortex-a9-mp")
+ else if (CPU == "cortex-a8" || CPU == "cortex-a9" ||
+ CPU == "cortex-a9-mp") {
+ Features["vfp3"] = true;
Features["neon"] = true;
- else if (CPU == "swift" || CPU == "cortex-a7") {
+ }
+ else if (CPU == "cortex-a5") {
+ Features["vfp4"] = true;
+ Features["neon"] = true;
+ } else if (CPU == "swift" || CPU == "cortex-a7" || CPU == "cortex-a15") {
Features["vfp4"] = true;
Features["neon"] = true;
+ Features["hwdiv"] = true;
+ Features["hwdiv-arm"] = true;
+ } else if (CPU == "cortex-a53" || CPU == "cortex-a57") {
+ Features["fp-armv8"] = true;
+ Features["neon"] = true;
+ Features["hwdiv"] = true;
+ Features["hwdiv-arm"] = true;
+ Features["crc"] = true;
+ } else if (CPU == "cortex-r5" || CPU == "cortex-m3" ||
+ CPU == "cortex-m4" ||
+ // Enable the hwdiv extension for all v8a AArch32 cores by
+ // default.
+ ArchName == "armv8a" || ArchName == "armv8" ||
+ ArchName == "thumbv8a" || ArchName == "thumbv8") {
+ Features["hwdiv"] = true;
+ Features["hwdiv-arm"] = true;
}
}
- virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const {
- if (Name == "soft-float" || Name == "soft-float-abi" ||
- Name == "vfp2" || Name == "vfp3" || Name == "vfp4" || Name == "neon" ||
- Name == "d16" || Name == "neonfp") {
- Features[Name] = Enabled;
- } else
- return false;
-
- return true;
- }
-
- virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+ virtual bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
FPU = 0;
+ CRC = 0;
SoftFloat = SoftFloatABI = false;
+ HWDiv = 0;
for (unsigned i = 0, e = Features.size(); i != e; ++i) {
if (Features[i] == "+soft-float")
SoftFloat = true;
@@ -3694,10 +3859,28 @@ public:
FPU |= VFP3FPU;
else if (Features[i] == "+vfp4")
FPU |= VFP4FPU;
+ else if (Features[i] == "+fp-armv8")
+ FPU |= FPARMV8;
else if (Features[i] == "+neon")
FPU |= NeonFPU;
+ else if (Features[i] == "+hwdiv")
+ HWDiv |= HWDivThumb;
+ else if (Features[i] == "+hwdiv-arm")
+ HWDiv |= HWDivARM;
+ else if (Features[i] == "+crc")
+ CRC = 1;
+ }
+
+ if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
+ Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
+ return false;
}
+ if (FPMath == FP_Neon)
+ Features.push_back("+neonfp");
+ else if (FPMath == FP_VFP)
+ Features.push_back("-neonfp");
+
// Remove front-end specific options which the backend handles differently.
std::vector<std::string>::iterator it;
it = std::find(Features.begin(), Features.end(), "+soft-float");
@@ -3706,6 +3889,7 @@ public:
it = std::find(Features.begin(), Features.end(), "+soft-float-abi");
if (it != Features.end())
Features.erase(it);
+ return true;
}
virtual bool hasFeature(StringRef Feature) const {
@@ -3713,8 +3897,9 @@ public:
.Case("arm", true)
.Case("softfloat", SoftFloat)
.Case("thumb", IsThumb)
- .Case("neon", FPU == NeonFPU && !SoftFloat &&
- StringRef(getCPUDefineSuffix(CPU)).startswith("7"))
+ .Case("neon", (FPU & NeonFPU) && !SoftFloat)
+ .Case("hwdiv", HWDiv & HWDivThumb)
+ .Case("hwdiv-arm", HWDiv & HWDivARM)
.Default(false);
}
// FIXME: Should we actually have some table instead of these switches?
@@ -3735,19 +3920,22 @@ public:
.Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
.Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
.Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A")
- .Cases("cortex-a9", "cortex-a15", "7A")
- .Case("cortex-r5", "7R")
+ .Cases("cortex-a9", "cortex-a12", "cortex-a15", "7A")
+ .Cases("cortex-r4", "cortex-r5", "7R")
.Case("cortex-a9-mp", "7F")
.Case("swift", "7S")
.Cases("cortex-m3", "cortex-m4", "7M")
.Case("cortex-m0", "6M")
+ .Cases("cortex-a53", "cortex-a57", "8A")
.Default(0);
}
static const char *getCPUProfile(StringRef Name) {
return llvm::StringSwitch<const char*>(Name)
- .Cases("cortex-a8", "cortex-a9", "A")
+ .Cases("cortex-a5", "cortex-a7", "cortex-a8", "A")
+ .Cases("cortex-a9", "cortex-a12", "cortex-a15", "A")
+ .Cases("cortex-a53", "cortex-a57", "A")
.Cases("cortex-m3", "cortex-m4", "cortex-m0", "M")
- .Case("cortex-r5", "R")
+ .Cases("cortex-r4", "cortex-r5", "R")
.Default("");
}
virtual bool setCPU(const std::string &Name) {
@@ -3757,6 +3945,7 @@ public:
CPU = Name;
return true;
}
+ virtual bool setFPMath(StringRef Name);
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
// Target identification.
@@ -3769,6 +3958,10 @@ public:
Builder.defineMacro("__REGISTER_PREFIX__", "");
StringRef CPUArch = getCPUDefineSuffix(CPU);
+ unsigned int CPUArchVer;
+ if(CPUArch.substr(0, 1).getAsInteger<unsigned int>(10, CPUArchVer)) {
+ llvm_unreachable("Invalid char for architecture version number");
+ }
Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
StringRef CPUProfile = getCPUProfile(CPU);
@@ -3779,12 +3972,12 @@ public:
// FIXME: It's more complicated than this and we don't really support
// interworking.
- if ('5' <= CPUArch[0] && CPUArch[0] <= '7')
+ if (5 <= CPUArchVer && CPUArchVer <= 7)
Builder.defineMacro("__THUMB_INTERWORK__");
if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
- // M-class CPUs on Darwin follow AAPCS, but not EABI.
- if (!(getTriple().isOSDarwin() && CPUProfile == "M"))
+ // Embedded targets on Darwin follow AAPCS, but not EABI.
+ if (!getTriple().isOSDarwin())
Builder.defineMacro("__ARM_EABI__");
Builder.defineMacro("__ARM_PCS", "1");
@@ -3798,13 +3991,14 @@ public:
if (CPU == "xscale")
Builder.defineMacro("__XSCALE__");
- bool IsARMv7 = CPUArch.startswith("7");
if (IsThumb) {
Builder.defineMacro("__THUMBEL__");
Builder.defineMacro("__thumb__");
- if (CPUArch == "6T2" || IsARMv7)
+ if (CPUArch == "6T2" || CPUArchVer == 7)
Builder.defineMacro("__thumb2__");
}
+ if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb))
+ Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
// Note, this is always on in gcc, even though it doesn't make sense.
Builder.defineMacro("__APCS_32__");
@@ -3823,8 +4017,18 @@ public:
// the VFP define, hence the soft float and arch check. This is subtly
// different from gcc, we follow the intent which was that it should be set
// when Neon instructions are actually available.
- if ((FPU & NeonFPU) && !SoftFloat && IsARMv7)
+ if ((FPU & NeonFPU) && !SoftFloat && CPUArchVer >= 7)
Builder.defineMacro("__ARM_NEON__");
+
+ if (CRC)
+ Builder.defineMacro("__ARM_FEATURE_CRC32");
+
+ if (CPUArchVer >= 6 && CPUArch != "6M") {
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+ }
}
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
@@ -3902,8 +4106,7 @@ public:
case 'r': {
switch (Modifier) {
default:
- return isInOut || (isOutput && Size >= 32) ||
- (!isOutput && !isInOut && Size <= 32);
+ return (isInOut || isOutput || Size <= 64);
case 'q':
// A register of size 32 cannot fit a vector type.
return false;
@@ -3929,6 +4132,18 @@ public:
}
};
+bool ARMTargetInfo::setFPMath(StringRef Name) {
+ if (Name == "neon") {
+ FPMath = FP_Neon;
+ return true;
+ } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
+ Name == "vfp4") {
+ FPMath = FP_VFP;
+ return true;
+ }
+ return false;
+}
+
const char * const ARMTargetInfo::GCCRegNames[] = {
// Integer registers
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -4002,8 +4217,8 @@ protected:
}
public:
- DarwinARMTargetInfo(const std::string& triple)
- : DarwinTargetInfo<ARMTargetInfo>(triple) {
+ DarwinARMTargetInfo(const llvm::Triple &Triple)
+ : DarwinTargetInfo<ARMTargetInfo>(Triple) {
HasAlignMac68kSupport = true;
// iOS always has 64-bit atomic instructions.
// FIXME: This should be based off of the target features in ARMTargetInfo.
@@ -4024,7 +4239,7 @@ class HexagonTargetInfo : public TargetInfo {
static const TargetInfo::GCCRegAlias GCCRegAliases[];
std::string CPU;
public:
- HexagonTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ HexagonTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
BigEndian = false;
DescriptionString = ("e-p:32:32:32-"
"i64:64:64-i32:32:32-i16:16:16-i1:32:32-"
@@ -4177,23 +4392,15 @@ class SparcTargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
bool SoftFloat;
public:
- SparcTargetInfo(const std::string &triple) : TargetInfo(triple) {}
-
- virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const {
- if (Name == "soft-float")
- Features[Name] = Enabled;
- else
- return false;
+ SparcTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {}
- return true;
- }
- virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+ virtual bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
SoftFloat = false;
for (unsigned i = 0, e = Features.size(); i != e; ++i)
if (Features[i] == "+soft-float")
SoftFloat = true;
+ return true;
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
@@ -4290,7 +4497,7 @@ void SparcTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
// SPARC v8 is the 32-bit mode selected by Triple::sparc.
class SparcV8TargetInfo : public SparcTargetInfo {
public:
- SparcV8TargetInfo(const std::string& triple) : SparcTargetInfo(triple) {
+ SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
// FIXME: Support Sparc quad-precision long double?
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
@@ -4306,10 +4513,22 @@ public:
// SPARC v9 is the 64-bit mode selected by Triple::sparcv9.
class SparcV9TargetInfo : public SparcTargetInfo {
public:
- SparcV9TargetInfo(const std::string& triple) : SparcTargetInfo(triple) {
+ SparcV9TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
// FIXME: Support Sparc quad-precision long double?
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32:64-S128";
+ // This is an LP64 platform.
+ LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+
+ // OpenBSD uses long long for int64_t and intmax_t.
+ if (getTriple().getOS() == llvm::Triple::OpenBSD) {
+ IntMaxType = SignedLongLong;
+ UIntMaxType = UnsignedLongLong;
+ } else {
+ IntMaxType = SignedLong;
+ UIntMaxType = UnsignedLong;
+ }
+ Int64Type = IntMaxType;
}
virtual void getTargetDefines(const LangOptions &Opts,
@@ -4333,16 +4552,16 @@ public:
namespace {
class AuroraUXSparcV8TargetInfo : public AuroraUXTargetInfo<SparcV8TargetInfo> {
public:
- AuroraUXSparcV8TargetInfo(const std::string& triple) :
- AuroraUXTargetInfo<SparcV8TargetInfo>(triple) {
+ AuroraUXSparcV8TargetInfo(const llvm::Triple &Triple)
+ : AuroraUXTargetInfo<SparcV8TargetInfo>(Triple) {
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
}
};
class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
public:
- SolarisSparcV8TargetInfo(const std::string& triple) :
- SolarisTargetInfo<SparcV8TargetInfo>(triple) {
+ SolarisSparcV8TargetInfo(const llvm::Triple &Triple)
+ : SolarisTargetInfo<SparcV8TargetInfo>(Triple) {
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
}
@@ -4354,7 +4573,7 @@ namespace {
static const char *const GCCRegNames[];
public:
- SystemZTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ SystemZTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
TLSSupported = true;
IntWidth = IntAlign = 32;
LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
@@ -4398,6 +4617,17 @@ namespace {
virtual BuiltinVaListKind getBuiltinVaListKind() const {
return TargetInfo::SystemZBuiltinVaList;
}
+ virtual bool setCPU(const std::string &Name) {
+ bool CPUKnown = llvm::StringSwitch<bool>(Name)
+ .Case("z10", true)
+ .Case("z196", true)
+ .Case("zEC12", true)
+ .Default(false);
+
+ // No need to store the CPU yet. There aren't any CPU-specific
+ // macros to define.
+ return CPUKnown;
+ }
};
const char *const SystemZTargetInfo::GCCRegNames[] = {
@@ -4447,7 +4677,7 @@ namespace {
class MSP430TargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
public:
- MSP430TargetInfo(const std::string& triple) : TargetInfo(triple) {
+ MSP430TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
BigEndian = false;
TLSSupported = false;
IntWidth = 16; IntAlign = 16;
@@ -4456,9 +4686,9 @@ namespace {
PointerWidth = 16; PointerAlign = 16;
SuitableAlign = 16;
SizeType = UnsignedInt;
- IntMaxType = SignedLong;
- UIntMaxType = UnsignedLong;
- IntPtrType = SignedShort;
+ IntMaxType = SignedLongLong;
+ UIntMaxType = UnsignedLongLong;
+ IntPtrType = SignedInt;
PtrDiffType = SignedInt;
SigAtomicType = SignedLong;
DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
@@ -4534,7 +4764,7 @@ namespace {
class TCETargetInfo : public TargetInfo{
public:
- TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
+ TCETargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
TLSSupported = false;
IntWidth = 32;
LongWidth = LongLongWidth = 32;
@@ -4562,6 +4792,7 @@ namespace {
"f32:32:32-f64:32:32-v64:32:32-"
"v128:32:32-a0:0:32-n32";
AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
+ UseAddrSpaceMapMangling = true;
}
virtual void getTargetDefines(const LangOptions &Opts,
@@ -4595,10 +4826,13 @@ namespace {
namespace {
class MipsTargetInfoBase : public TargetInfo {
+ virtual void setDescriptionString() = 0;
+
static const Builtin::Info BuiltinInfo[];
std::string CPU;
bool IsMips16;
bool IsMicromips;
+ bool IsNan2008;
bool IsSingleFloat;
enum MipsFloatABI {
HardFloat, SoftFloat
@@ -4606,23 +4840,18 @@ class MipsTargetInfoBase : public TargetInfo {
enum DspRevEnum {
NoDSP, DSP1, DSP2
} DspRev;
+ bool HasMSA;
protected:
+ bool HasFP64;
std::string ABI;
public:
- MipsTargetInfoBase(const std::string& triple,
- const std::string& ABIStr,
- const std::string& CPUStr)
- : TargetInfo(triple),
- CPU(CPUStr),
- IsMips16(false),
- IsMicromips(false),
- IsSingleFloat(false),
- FloatABI(HardFloat),
- DspRev(NoDSP),
- ABI(ABIStr)
- {}
+ MipsTargetInfoBase(const llvm::Triple &Triple, const std::string &ABIStr,
+ const std::string &CPUStr)
+ : TargetInfo(Triple), CPU(CPUStr), IsMips16(false), IsMicromips(false),
+ IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
+ DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {}
virtual const char *getABI() const { return ABI.c_str(); }
virtual bool setABI(const std::string &Name) = 0;
@@ -4653,12 +4882,19 @@ public:
if (IsSingleFloat)
Builder.defineMacro("__mips_single_float", Twine(1));
+ Builder.defineMacro("__mips_fpr", HasFP64 ? Twine(64) : Twine(32));
+ Builder.defineMacro("_MIPS_FPSET",
+ Twine(32 / (HasFP64 || IsSingleFloat ? 1 : 2)));
+
if (IsMips16)
Builder.defineMacro("__mips16", Twine(1));
if (IsMicromips)
Builder.defineMacro("__mips_micromips", Twine(1));
+ if (IsNan2008)
+ Builder.defineMacro("__mips_nan2008", Twine(1));
+
switch (DspRev) {
default:
break;
@@ -4673,6 +4909,9 @@ public:
break;
}
+ if (HasMSA)
+ Builder.defineMacro("__mips_msa", Twine(1));
+
Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
@@ -4687,14 +4926,17 @@ public:
NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;
}
virtual bool hasFeature(StringRef Feature) const {
- return Feature == "mips";
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("mips", true)
+ .Case("fp64", HasFP64)
+ .Default(false);
}
virtual BuiltinVaListKind getBuiltinVaListKind() const {
return TargetInfo::VoidPtrBuiltinVaList;
}
virtual void getGCCRegNames(const char * const *&Names,
unsigned &NumNames) const {
- static const char * const GCCRegNames[] = {
+ static const char *const GCCRegNames[] = {
// CPU register names
// Must match second column of GCCRegAliases
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
@@ -4708,7 +4950,15 @@ public:
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
// Hi/lo and condition register names
"hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
- "$fcc5","$fcc6","$fcc7"
+ "$fcc5","$fcc6","$fcc7",
+ // MSA register names
+ "$w0", "$w1", "$w2", "$w3", "$w4", "$w5", "$w6", "$w7",
+ "$w8", "$w9", "$w10", "$w11", "$w12", "$w13", "$w14", "$w15",
+ "$w16", "$w17", "$w18", "$w19", "$w20", "$w21", "$w22", "$w23",
+ "$w24", "$w25", "$w26", "$w27", "$w28", "$w29", "$w30", "$w31",
+ // MSA control register names
+ "$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify",
+ "$msarequest", "$msamap", "$msaunmap"
};
Names = GCCRegNames;
NumNames = llvm::array_lengthof(GCCRegNames);
@@ -4741,33 +4991,15 @@ public:
return "";
}
- virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
- StringRef Name,
- bool Enabled) const {
- if (Name == "soft-float" || Name == "single-float" ||
- Name == "o32" || Name == "n32" || Name == "n64" || Name == "eabi" ||
- Name == "mips32" || Name == "mips32r2" ||
- Name == "mips64" || Name == "mips64r2" ||
- Name == "mips16" || Name == "micromips" ||
- Name == "dsp" || Name == "dspr2") {
- Features[Name] = Enabled;
- return true;
- } else if (Name == "32") {
- Features["o32"] = Enabled;
- return true;
- } else if (Name == "64") {
- Features["n64"] = Enabled;
- return true;
- }
- return false;
- }
-
- virtual void HandleTargetFeatures(std::vector<std::string> &Features) {
+ virtual bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
IsMips16 = false;
IsMicromips = false;
+ IsNan2008 = false;
IsSingleFloat = false;
FloatABI = HardFloat;
DspRev = NoDSP;
+ HasFP64 = ABI == "n32" || ABI == "n64" || ABI == "64";
for (std::vector<std::string>::iterator it = Features.begin(),
ie = Features.end(); it != ie; ++it) {
@@ -4783,13 +5015,28 @@ public:
DspRev = std::max(DspRev, DSP1);
else if (*it == "+dspr2")
DspRev = std::max(DspRev, DSP2);
+ else if (*it == "+msa")
+ HasMSA = true;
+ else if (*it == "+fp64")
+ HasFP64 = true;
+ else if (*it == "-fp64")
+ HasFP64 = false;
+ else if (*it == "+nan2008")
+ IsNan2008 = true;
}
- // Remove front-end specific option.
+ // Remove front-end specific options.
std::vector<std::string>::iterator it =
std::find(Features.begin(), Features.end(), "+soft-float");
if (it != Features.end())
Features.erase(it);
+ it = std::find(Features.begin(), Features.end(), "+nan2008");
+ if (it != Features.end())
+ Features.erase(it);
+
+ setDescriptionString();
+
+ return true;
}
virtual int getEHDataRegisterNumber(unsigned RegNo) const {
@@ -4808,8 +5055,8 @@ const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
class Mips32TargetInfoBase : public MipsTargetInfoBase {
public:
- Mips32TargetInfoBase(const std::string& triple) :
- MipsTargetInfoBase(triple, "o32", "mips32") {
+ Mips32TargetInfoBase(const llvm::Triple &Triple)
+ : MipsTargetInfoBase(Triple, "o32", "mips32") {
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
@@ -4879,11 +5126,15 @@ public:
};
class Mips32EBTargetInfo : public Mips32TargetInfoBase {
-public:
- Mips32EBTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
+ virtual void setDescriptionString() {
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
}
+
+public:
+ Mips32EBTargetInfo(const llvm::Triple &Triple)
+ : Mips32TargetInfoBase(Triple) {
+ }
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
DefineStd(Builder, "MIPSEB", Opts);
@@ -4893,12 +5144,16 @@ public:
};
class Mips32ELTargetInfo : public Mips32TargetInfoBase {
-public:
- Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
- BigEndian = false;
+ virtual void setDescriptionString() {
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
}
+
+public:
+ Mips32ELTargetInfo(const llvm::Triple &Triple)
+ : Mips32TargetInfoBase(Triple) {
+ BigEndian = false;
+ }
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
DefineStd(Builder, "MIPSEL", Opts);
@@ -4908,10 +5163,9 @@ public:
};
class Mips64TargetInfoBase : public MipsTargetInfoBase {
- virtual void SetDescriptionString(const std::string &Name) = 0;
public:
- Mips64TargetInfoBase(const std::string& triple) :
- MipsTargetInfoBase(triple, "n64", "mips64") {
+ Mips64TargetInfoBase(const llvm::Triple &Triple)
+ : MipsTargetInfoBase(Triple, "n64", "mips64") {
LongWidth = LongAlign = 64;
PointerWidth = PointerAlign = 64;
LongDoubleWidth = LongDoubleAlign = 128;
@@ -4924,7 +5178,6 @@ public:
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
}
virtual bool setABI(const std::string &Name) {
- SetDescriptionString(Name);
if (Name == "n32") {
LongWidth = LongAlign = 32;
PointerWidth = PointerAlign = 32;
@@ -5000,20 +5253,21 @@ public:
};
class Mips64EBTargetInfo : public Mips64TargetInfoBase {
- virtual void SetDescriptionString(const std::string &Name) {
- // Change DescriptionString only if ABI is n32.
- if (Name == "n32")
+ virtual void setDescriptionString() {
+ if (ABI == "n32")
DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
"v64:64:64-n32:64-S128";
+ else
+ DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
+ "v64:64:64-n32:64-S128";
+
}
+
public:
- Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
- // Default ABI is n64.
- DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
- "v64:64:64-n32:64-S128";
- }
+ Mips64EBTargetInfo(const llvm::Triple &Triple)
+ : Mips64TargetInfoBase(Triple) {}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
DefineStd(Builder, "MIPSEB", Opts);
@@ -5023,20 +5277,21 @@ public:
};
class Mips64ELTargetInfo : public Mips64TargetInfoBase {
- virtual void SetDescriptionString(const std::string &Name) {
- // Change DescriptionString only if ABI is n32.
- if (Name == "n32")
+ virtual void setDescriptionString() {
+ if (ABI == "n32")
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-f128:128:128"
"-v64:64:64-n32:64-S128";
+ else
+ DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
+ "v64:64:64-n32:64-S128";
}
public:
- Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
+ Mips64ELTargetInfo(const llvm::Triple &Triple)
+ : Mips64TargetInfoBase(Triple) {
// Default ABI is n64.
BigEndian = false;
- DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
- "v64:64:64-n32:64-S128";
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
@@ -5050,7 +5305,7 @@ public:
namespace {
class PNaClTargetInfo : public TargetInfo {
public:
- PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ PNaClTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
BigEndian = false;
this->UserLabelPrefix = "";
this->LongAlign = 32;
@@ -5129,11 +5384,8 @@ namespace {
0 // cuda_shared
};
class SPIRTargetInfo : public TargetInfo {
- static const char * const GCCRegNames[];
- static const Builtin::Info BuiltinInfo[];
- std::vector<StringRef> AvailableFeatures;
public:
- SPIRTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ SPIRTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
"SPIR target must use unknown OS");
assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
@@ -5142,6 +5394,7 @@ namespace {
TLSSupported = false;
LongWidth = LongAlign = 64;
AddrSpaceMap = &SPIRAddrSpaceMap;
+ UseAddrSpaceMapMangling = true;
// Define available target features
// These must be defined in sorted order!
NoAsmVariants = true;
@@ -5175,7 +5428,7 @@ namespace {
class SPIR32TargetInfo : public SPIRTargetInfo {
public:
- SPIR32TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) {
+ SPIR32TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) {
PointerWidth = PointerAlign = 32;
SizeType = TargetInfo::UnsignedInt;
PtrDiffType = IntPtrType = TargetInfo::SignedInt;
@@ -5193,7 +5446,7 @@ namespace {
class SPIR64TargetInfo : public SPIRTargetInfo {
public:
- SPIR64TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) {
+ SPIR64TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) {
PointerWidth = PointerAlign = 64;
SizeType = TargetInfo::UnsignedLong;
PtrDiffType = IntPtrType = TargetInfo::SignedLong;
@@ -5210,300 +5463,374 @@ namespace {
};
}
+namespace {
+class XCoreTargetInfo : public TargetInfo {
+ static const Builtin::Info BuiltinInfo[];
+public:
+ XCoreTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
+ BigEndian = false;
+ NoAsmVariants = true;
+ LongLongAlign = 32;
+ SuitableAlign = 32;
+ DoubleAlign = LongDoubleAlign = 32;
+ SizeType = UnsignedInt;
+ PtrDiffType = SignedInt;
+ IntPtrType = SignedInt;
+ WCharType = UnsignedChar;
+ WIntType = UnsignedInt;
+ UseZeroLengthBitfieldAlignment = true;
+ DescriptionString = "e-p:32:32:32-a0:0:32-n32"
+ "-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32"
+ "-f16:16:32-f32:32:32-f64:32:32";
+ }
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("__XS1B__");
+ }
+ virtual void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const {
+ Records = BuiltinInfo;
+ NumRecords = clang::XCore::LastTSBuiltin-Builtin::FirstTSBuiltin;
+ }
+ virtual BuiltinVaListKind getBuiltinVaListKind() const {
+ return TargetInfo::VoidPtrBuiltinVaList;
+ }
+ virtual const char *getClobbers() const {
+ return "";
+ }
+ virtual void getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const {
+ static const char * const GCCRegNames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "cp", "dp", "sp", "lr"
+ };
+ Names = GCCRegNames;
+ NumNames = llvm::array_lengthof(GCCRegNames);
+ }
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const {
+ Aliases = NULL;
+ NumAliases = 0;
+ }
+ virtual bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const {
+ return false;
+ }
+};
+
+const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
+ ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsXCore.def"
+};
+} // end anonymous namespace.
+
//===----------------------------------------------------------------------===//
// Driver code
//===----------------------------------------------------------------------===//
-static TargetInfo *AllocateTarget(const std::string &T) {
- llvm::Triple Triple(T);
+static TargetInfo *AllocateTarget(const llvm::Triple &Triple) {
llvm::Triple::OSType os = Triple.getOS();
switch (Triple.getArch()) {
default:
return NULL;
+ case llvm::Triple::xcore:
+ return new XCoreTargetInfo(Triple);
+
case llvm::Triple::hexagon:
- return new HexagonTargetInfo(T);
+ return new HexagonTargetInfo(Triple);
case llvm::Triple::aarch64:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<AArch64TargetInfo>(T);
+ return new LinuxTargetInfo<AArch64TargetInfo>(Triple);
default:
- return new AArch64TargetInfo(T);
+ return new AArch64TargetInfo(Triple);
}
case llvm::Triple::arm:
case llvm::Triple::thumb:
if (Triple.isOSDarwin())
- return new DarwinARMTargetInfo(T);
+ return new DarwinARMTargetInfo(Triple);
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<ARMTargetInfo>(T);
+ return new LinuxTargetInfo<ARMTargetInfo>(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<ARMTargetInfo>(T);
+ return new FreeBSDTargetInfo<ARMTargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<ARMTargetInfo>(T);
+ return new NetBSDTargetInfo<ARMTargetInfo>(Triple);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<ARMTargetInfo>(T);
+ return new OpenBSDTargetInfo<ARMTargetInfo>(Triple);
case llvm::Triple::Bitrig:
- return new BitrigTargetInfo<ARMTargetInfo>(T);
+ return new BitrigTargetInfo<ARMTargetInfo>(Triple);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<ARMTargetInfo>(T);
+ return new RTEMSTargetInfo<ARMTargetInfo>(Triple);
case llvm::Triple::NaCl:
- return new NaClTargetInfo<ARMTargetInfo>(T);
+ return new NaClTargetInfo<ARMTargetInfo>(Triple);
default:
- return new ARMTargetInfo(T);
+ return new ARMTargetInfo(Triple);
}
case llvm::Triple::msp430:
- return new MSP430TargetInfo(T);
+ return new MSP430TargetInfo(Triple);
case llvm::Triple::mips:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<Mips32EBTargetInfo>(T);
+ return new LinuxTargetInfo<Mips32EBTargetInfo>(Triple);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<Mips32EBTargetInfo>(T);
+ return new RTEMSTargetInfo<Mips32EBTargetInfo>(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<Mips32EBTargetInfo>(T);
+ return new FreeBSDTargetInfo<Mips32EBTargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<Mips32EBTargetInfo>(T);
+ return new NetBSDTargetInfo<Mips32EBTargetInfo>(Triple);
default:
- return new Mips32EBTargetInfo(T);
+ return new Mips32EBTargetInfo(Triple);
}
case llvm::Triple::mipsel:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<Mips32ELTargetInfo>(T);
+ return new LinuxTargetInfo<Mips32ELTargetInfo>(Triple);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<Mips32ELTargetInfo>(T);
+ return new RTEMSTargetInfo<Mips32ELTargetInfo>(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<Mips32ELTargetInfo>(T);
+ return new FreeBSDTargetInfo<Mips32ELTargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<Mips32ELTargetInfo>(T);
+ return new NetBSDTargetInfo<Mips32ELTargetInfo>(Triple);
+ case llvm::Triple::NaCl:
+ return new NaClTargetInfo<Mips32ELTargetInfo>(Triple);
default:
- return new Mips32ELTargetInfo(T);
+ return new Mips32ELTargetInfo(Triple);
}
case llvm::Triple::mips64:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<Mips64EBTargetInfo>(T);
+ return new LinuxTargetInfo<Mips64EBTargetInfo>(Triple);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<Mips64EBTargetInfo>(T);
+ return new RTEMSTargetInfo<Mips64EBTargetInfo>(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T);
+ return new FreeBSDTargetInfo<Mips64EBTargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<Mips64EBTargetInfo>(T);
+ return new NetBSDTargetInfo<Mips64EBTargetInfo>(Triple);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<Mips64EBTargetInfo>(T);
+ return new OpenBSDTargetInfo<Mips64EBTargetInfo>(Triple);
default:
- return new Mips64EBTargetInfo(T);
+ return new Mips64EBTargetInfo(Triple);
}
case llvm::Triple::mips64el:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<Mips64ELTargetInfo>(T);
+ return new LinuxTargetInfo<Mips64ELTargetInfo>(Triple);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<Mips64ELTargetInfo>(T);
+ return new RTEMSTargetInfo<Mips64ELTargetInfo>(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T);
+ return new FreeBSDTargetInfo<Mips64ELTargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<Mips64ELTargetInfo>(T);
+ return new NetBSDTargetInfo<Mips64ELTargetInfo>(Triple);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<Mips64ELTargetInfo>(T);
+ return new OpenBSDTargetInfo<Mips64ELTargetInfo>(Triple);
default:
- return new Mips64ELTargetInfo(T);
+ return new Mips64ELTargetInfo(Triple);
}
case llvm::Triple::le32:
switch (os) {
case llvm::Triple::NaCl:
- return new NaClTargetInfo<PNaClTargetInfo>(T);
+ return new NaClTargetInfo<PNaClTargetInfo>(Triple);
default:
return NULL;
}
case llvm::Triple::ppc:
if (Triple.isOSDarwin())
- return new DarwinPPC32TargetInfo(T);
+ return new DarwinPPC32TargetInfo(Triple);
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<PPC32TargetInfo>(T);
+ return new LinuxTargetInfo<PPC32TargetInfo>(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
+ return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<PPC32TargetInfo>(T);
+ return new NetBSDTargetInfo<PPC32TargetInfo>(Triple);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<PPC32TargetInfo>(T);
+ return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<PPC32TargetInfo>(T);
+ return new RTEMSTargetInfo<PPC32TargetInfo>(Triple);
default:
- return new PPC32TargetInfo(T);
+ return new PPC32TargetInfo(Triple);
}
case llvm::Triple::ppc64:
if (Triple.isOSDarwin())
- return new DarwinPPC64TargetInfo(T);
+ return new DarwinPPC64TargetInfo(Triple);
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<PPC64TargetInfo>(T);
+ return new LinuxTargetInfo<PPC64TargetInfo>(Triple);
case llvm::Triple::Lv2:
- return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
+ return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
+ return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<PPC64TargetInfo>(T);
+ return new NetBSDTargetInfo<PPC64TargetInfo>(Triple);
+ default:
+ return new PPC64TargetInfo(Triple);
+ }
+
+ case llvm::Triple::ppc64le:
+ switch (os) {
+ case llvm::Triple::Linux:
+ return new LinuxTargetInfo<PPC64TargetInfo>(Triple);
default:
- return new PPC64TargetInfo(T);
+ return new PPC64TargetInfo(Triple);
}
case llvm::Triple::nvptx:
- return new NVPTX32TargetInfo(T);
+ return new NVPTX32TargetInfo(Triple);
case llvm::Triple::nvptx64:
- return new NVPTX64TargetInfo(T);
-
- case llvm::Triple::mblaze:
- return new MBlazeTargetInfo(T);
+ return new NVPTX64TargetInfo(Triple);
case llvm::Triple::r600:
- return new R600TargetInfo(T);
+ return new R600TargetInfo(Triple);
case llvm::Triple::sparc:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<SparcV8TargetInfo>(T);
+ return new LinuxTargetInfo<SparcV8TargetInfo>(Triple);
case llvm::Triple::AuroraUX:
- return new AuroraUXSparcV8TargetInfo(T);
+ return new AuroraUXSparcV8TargetInfo(Triple);
case llvm::Triple::Solaris:
- return new SolarisSparcV8TargetInfo(T);
+ return new SolarisSparcV8TargetInfo(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<SparcV8TargetInfo>(T);
+ return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<SparcV8TargetInfo>(T);
+ return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<SparcV8TargetInfo>(T);
+ return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple);
default:
- return new SparcV8TargetInfo(T);
+ return new SparcV8TargetInfo(Triple);
}
case llvm::Triple::sparcv9:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<SparcV9TargetInfo>(T);
+ return new LinuxTargetInfo<SparcV9TargetInfo>(Triple);
case llvm::Triple::AuroraUX:
- return new AuroraUXTargetInfo<SparcV9TargetInfo>(T);
+ return new AuroraUXTargetInfo<SparcV9TargetInfo>(Triple);
case llvm::Triple::Solaris:
- return new SolarisTargetInfo<SparcV9TargetInfo>(T);
+ return new SolarisTargetInfo<SparcV9TargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<SparcV9TargetInfo>(T);
+ return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<SparcV9TargetInfo>(T);
+ return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<SparcV9TargetInfo>(T);
+ return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple);
default:
- return new SparcV9TargetInfo(T);
+ return new SparcV9TargetInfo(Triple);
}
case llvm::Triple::systemz:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<SystemZTargetInfo>(T);
+ return new LinuxTargetInfo<SystemZTargetInfo>(Triple);
default:
- return new SystemZTargetInfo(T);
+ return new SystemZTargetInfo(Triple);
}
case llvm::Triple::tce:
- return new TCETargetInfo(T);
+ return new TCETargetInfo(Triple);
case llvm::Triple::x86:
if (Triple.isOSDarwin())
- return new DarwinI386TargetInfo(T);
+ return new DarwinI386TargetInfo(Triple);
switch (os) {
case llvm::Triple::AuroraUX:
- return new AuroraUXTargetInfo<X86_32TargetInfo>(T);
+ return new AuroraUXTargetInfo<X86_32TargetInfo>(Triple);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<X86_32TargetInfo>(T);
+ return new LinuxTargetInfo<X86_32TargetInfo>(Triple);
case llvm::Triple::DragonFly:
- return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
+ return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDI386TargetInfo(T);
+ return new NetBSDI386TargetInfo(Triple);
case llvm::Triple::OpenBSD:
- return new OpenBSDI386TargetInfo(T);
+ return new OpenBSDI386TargetInfo(Triple);
case llvm::Triple::Bitrig:
- return new BitrigI386TargetInfo(T);
+ return new BitrigI386TargetInfo(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
+ return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple);
+ case llvm::Triple::KFreeBSD:
+ return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple);
case llvm::Triple::Minix:
- return new MinixTargetInfo<X86_32TargetInfo>(T);
+ return new MinixTargetInfo<X86_32TargetInfo>(Triple);
case llvm::Triple::Solaris:
- return new SolarisTargetInfo<X86_32TargetInfo>(T);
+ return new SolarisTargetInfo<X86_32TargetInfo>(Triple);
case llvm::Triple::Cygwin:
- return new CygwinX86_32TargetInfo(T);
+ return new CygwinX86_32TargetInfo(Triple);
case llvm::Triple::MinGW32:
- return new MinGWX86_32TargetInfo(T);
+ return new MinGWX86_32TargetInfo(Triple);
case llvm::Triple::Win32:
- return new VisualStudioWindowsX86_32TargetInfo(T);
+ return new VisualStudioWindowsX86_32TargetInfo(Triple);
case llvm::Triple::Haiku:
- return new HaikuX86_32TargetInfo(T);
+ return new HaikuX86_32TargetInfo(Triple);
case llvm::Triple::RTEMS:
- return new RTEMSX86_32TargetInfo(T);
+ return new RTEMSX86_32TargetInfo(Triple);
case llvm::Triple::NaCl:
- return new NaClTargetInfo<X86_32TargetInfo>(T);
+ return new NaClTargetInfo<X86_32TargetInfo>(Triple);
default:
- return new X86_32TargetInfo(T);
+ return new X86_32TargetInfo(Triple);
}
case llvm::Triple::x86_64:
if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO)
- return new DarwinX86_64TargetInfo(T);
+ return new DarwinX86_64TargetInfo(Triple);
switch (os) {
case llvm::Triple::AuroraUX:
- return new AuroraUXTargetInfo<X86_64TargetInfo>(T);
+ return new AuroraUXTargetInfo<X86_64TargetInfo>(Triple);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<X86_64TargetInfo>(T);
+ return new LinuxTargetInfo<X86_64TargetInfo>(Triple);
case llvm::Triple::DragonFly:
- return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(T);
+ return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<X86_64TargetInfo>(T);
+ return new NetBSDTargetInfo<X86_64TargetInfo>(Triple);
case llvm::Triple::OpenBSD:
- return new OpenBSDX86_64TargetInfo(T);
+ return new OpenBSDX86_64TargetInfo(Triple);
case llvm::Triple::Bitrig:
- return new BitrigX86_64TargetInfo(T);
+ return new BitrigX86_64TargetInfo(Triple);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
+ return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple);
+ case llvm::Triple::KFreeBSD:
+ return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple);
case llvm::Triple::Solaris:
- return new SolarisTargetInfo<X86_64TargetInfo>(T);
+ return new SolarisTargetInfo<X86_64TargetInfo>(Triple);
case llvm::Triple::MinGW32:
- return new MinGWX86_64TargetInfo(T);
+ return new MinGWX86_64TargetInfo(Triple);
case llvm::Triple::Win32: // This is what Triple.h supports now.
- return new VisualStudioWindowsX86_64TargetInfo(T);
+ return new VisualStudioWindowsX86_64TargetInfo(Triple);
case llvm::Triple::NaCl:
- return new NaClTargetInfo<X86_64TargetInfo>(T);
+ return new NaClTargetInfo<X86_64TargetInfo>(Triple);
default:
- return new X86_64TargetInfo(T);
+ return new X86_64TargetInfo(Triple);
}
case llvm::Triple::spir: {
- llvm::Triple Triple(T);
if (Triple.getOS() != llvm::Triple::UnknownOS ||
- Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
+ Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
return NULL;
- return new SPIR32TargetInfo(T);
+ return new SPIR32TargetInfo(Triple);
}
case llvm::Triple::spir64: {
- llvm::Triple Triple(T);
if (Triple.getOS() != llvm::Triple::UnknownOS ||
- Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
+ Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
return NULL;
- return new SPIR64TargetInfo(T);
+ return new SPIR64TargetInfo(Triple);
}
}
}
@@ -5515,7 +5842,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
llvm::Triple Triple(Opts->Triple);
// Construct the target
- OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str()));
+ OwningPtr<TargetInfo> Target(AllocateTarget(Triple));
if (!Target) {
Diags.Report(diag::err_target_unknown_triple) << Triple.str();
return 0;
@@ -5540,45 +5867,24 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
return 0;
}
+ // Set the fp math unit.
+ if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) {
+ Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath;
+ return 0;
+ }
+
// Compute the default target features, we need the target to handle this
// because features may have dependencies on one another.
llvm::StringMap<bool> Features;
Target->getDefaultFeatures(Features);
// Apply the user specified deltas.
- // First the enables.
- for (std::vector<std::string>::const_iterator
- it = Opts->FeaturesAsWritten.begin(),
- ie = Opts->FeaturesAsWritten.end();
- it != ie; ++it) {
- const char *Name = it->c_str();
-
- if (Name[0] != '+')
- continue;
-
+ for (unsigned I = 0, N = Opts->FeaturesAsWritten.size();
+ I < N; ++I) {
+ const char *Name = Opts->FeaturesAsWritten[I].c_str();
// Apply the feature via the target.
- if (!Target->setFeatureEnabled(Features, Name + 1, true)) {
- Diags.Report(diag::err_target_invalid_feature) << Name;
- return 0;
- }
- }
-
- // Then the disables.
- for (std::vector<std::string>::const_iterator
- it = Opts->FeaturesAsWritten.begin(),
- ie = Opts->FeaturesAsWritten.end();
- it != ie; ++it) {
- const char *Name = it->c_str();
-
- if (Name[0] == '+')
- continue;
-
- // Apply the feature via the target.
- if (Name[0] != '-' ||
- !Target->setFeatureEnabled(Features, Name + 1, false)) {
- Diags.Report(diag::err_target_invalid_feature) << Name;
- return 0;
- }
+ bool Enabled = Name[0] == '+';
+ Target->setFeatureEnabled(Features, Name + 1, Enabled);
}
// Add the features to the compile options.
@@ -5589,7 +5895,8 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
ie = Features.end(); it != ie; ++it)
Opts->Features.push_back((it->second ? "+" : "-") + it->first().str());
- Target->HandleTargetFeatures(Opts->Features);
+ if (!Target->handleTargetFeatures(Opts->Features, Diags))
+ return 0;
return Target.take();
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp
index 36be059..17a8e35 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.
- static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final/lib/Basic/Version.cpp $");
+ StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_34/final/lib/Basic/Version.cpp $");
if (URL.empty()) {
URL = SVNRepository.slice(SVNRepository.find(':'),
SVNRepository.find("/lib/Basic"));
OpenPOWER on IntegriCloud