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