aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Basic
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Basic')
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Attributes.cpp61
-rw-r--r--contrib/llvm-project/clang/lib/Basic/BuiltinTargetFeatures.h95
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Builtins.cpp141
-rw-r--r--contrib/llvm-project/clang/lib/Basic/CLWarnings.cpp29
-rw-r--r--contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp37
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Cuda.cpp165
-rw-r--r--contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp59
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp155
-rw-r--r--contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp95
-rw-r--r--contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Basic/FileManager.cpp310
-rw-r--r--contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp339
-rw-r--r--contrib/llvm-project/clang/lib/Basic/LangOptions.cpp163
-rw-r--r--contrib/llvm-project/clang/lib/Basic/LangStandards.cpp66
-rw-r--r--contrib/llvm-project/clang/lib/Basic/MakeSupport.cpp35
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Module.cpp138
-rw-r--r--contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp45
-rw-r--r--contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp259
-rw-r--r--contrib/llvm-project/clang/lib/Basic/ParsedAttrInfo.cpp32
-rw-r--r--contrib/llvm-project/clang/lib/Basic/ProfileList.cpp64
-rw-r--r--contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp5
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp2
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Sarif.cpp425
-rw-r--r--contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp17
-rw-r--r--contrib/llvm-project/clang/lib/Basic/SourceManager.cpp656
-rw-r--r--contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp136
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Stack.cpp1
-rw-r--r--contrib/llvm-project/clang/lib/Basic/TargetID.cpp58
-rw-r--r--contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp166
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets.cpp524
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets.h4
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp939
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h157
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp271
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h118
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/ARC.h16
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp234
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/ARM.h32
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp714
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/AVR.h34
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp43
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/BPF.h13
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp315
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/CSKY.h107
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/DirectX.cpp22
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/DirectX.h103
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp43
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h7
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp4
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h10
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp1
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Le64.h10
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp299
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h154
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp72
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/M68k.h10
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp3
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h8
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp56
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Mips.h30
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp74
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h35
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp184
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h350
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h10
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp210
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/PPC.h86
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp438
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h93
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp26
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h238
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp82
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h17
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp27
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h73
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/TCE.h18
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp20
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/VE.h9
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp76
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h52
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp451
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/X86.h183
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp10
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Targets/XCore.h11
-rw-r--r--contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp9
-rw-r--r--contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp14
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Version.cpp24
-rw-r--r--contrib/llvm-project/clang/lib/Basic/Warnings.cpp16
90 files changed, 8004 insertions, 2952 deletions
diff --git a/contrib/llvm-project/clang/lib/Basic/Attributes.cpp b/contrib/llvm-project/clang/lib/Basic/Attributes.cpp
index 62eea9c59082..44a4f1890d39 100644
--- a/contrib/llvm-project/clang/lib/Basic/Attributes.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Attributes.cpp
@@ -1,16 +1,39 @@
+//===--- Attributes.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the AttributeCommonInfo interface.
+//
+//===----------------------------------------------------------------------===//
+
#include "clang/Basic/Attributes.h"
#include "clang/Basic/AttrSubjectMatchRules.h"
-#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/ParsedAttrInfo.h"
+#include "clang/Basic/TargetInfo.h"
+
using namespace clang;
-int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
- const IdentifierInfo *Attr, const TargetInfo &Target,
- const LangOptions &LangOpts) {
+static int hasAttributeImpl(AttributeCommonInfo::Syntax Syntax, StringRef Name,
+ StringRef ScopeName, const TargetInfo &Target,
+ const LangOptions &LangOpts) {
+
+#include "clang/Basic/AttrHasAttributeImpl.inc"
+
+ return 0;
+}
+
+int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
+ const IdentifierInfo *Scope, const IdentifierInfo *Attr,
+ const TargetInfo &Target, const LangOptions &LangOpts) {
StringRef Name = Attr->getName();
// Normalize the attribute name, __foo__ becomes foo.
- if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
+ if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__"))
Name = Name.substr(2, Name.size() - 4);
// Normalize the scope name, but only for gnu and clang attributes.
@@ -24,11 +47,17 @@ int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
// attributes. We support those, but not through the typical attribute
// machinery that goes through TableGen. We support this in all OpenMP modes
// so long as double square brackets are enabled.
- if (LangOpts.OpenMP && LangOpts.DoubleSquareBracketAttributes &&
- ScopeName == "omp")
+ if (LangOpts.OpenMP && ScopeName == "omp")
return (Name == "directive" || Name == "sequence") ? 1 : 0;
-#include "clang/Basic/AttrHasAttributeImpl.inc"
+ int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts);
+ if (res)
+ return res;
+
+ // Check if any plugin provides this attribute.
+ for (auto &Ptr : getAttributePluginInstances())
+ if (Ptr->hasSpelling(Syntax, Name))
+ return 1;
return 0;
}
@@ -53,7 +82,7 @@ normalizeAttrScopeName(const IdentifierInfo *Scope,
// to be "clang".
StringRef ScopeName = Scope->getName();
if (SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
- SyntaxUsed == AttributeCommonInfo::AS_C2x) {
+ SyntaxUsed == AttributeCommonInfo::AS_C23) {
if (ScopeName == "__gnu__")
ScopeName = "gnu";
else if (ScopeName == "_Clang")
@@ -70,12 +99,12 @@ static StringRef normalizeAttrName(const IdentifierInfo *Name,
bool ShouldNormalize =
SyntaxUsed == AttributeCommonInfo::AS_GNU ||
((SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
- SyntaxUsed == AttributeCommonInfo::AS_C2x) &&
+ SyntaxUsed == AttributeCommonInfo::AS_C23) &&
(NormalizedScopeName.empty() || NormalizedScopeName == "gnu" ||
NormalizedScopeName == "clang"));
StringRef AttrName = Name->getName();
- if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") &&
- AttrName.endswith("__"))
+ if (ShouldNormalize && AttrName.size() >= 4 && AttrName.starts_with("__") &&
+ AttrName.ends_with("__"))
AttrName = AttrName.slice(2, AttrName.size() - 2);
return AttrName;
@@ -85,6 +114,10 @@ bool AttributeCommonInfo::isGNUScope() const {
return ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"));
}
+bool AttributeCommonInfo::isClangScope() const {
+ return ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang"));
+}
+
#include "clang/Sema/AttrParsedAttrKinds.inc"
static SmallString<64> normalizeName(const IdentifierInfo *Name,
@@ -96,7 +129,7 @@ static SmallString<64> normalizeName(const IdentifierInfo *Name,
SmallString<64> FullName = ScopeName;
if (!ScopeName.empty()) {
assert(SyntaxUsed == AttributeCommonInfo::AS_CXX11 ||
- SyntaxUsed == AttributeCommonInfo::AS_C2x);
+ SyntaxUsed == AttributeCommonInfo::AS_C23);
FullName += "::";
}
FullName += AttrName;
diff --git a/contrib/llvm-project/clang/lib/Basic/BuiltinTargetFeatures.h b/contrib/llvm-project/clang/lib/Basic/BuiltinTargetFeatures.h
new file mode 100644
index 000000000000..9754acda2a68
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/BuiltinTargetFeatures.h
@@ -0,0 +1,95 @@
+//===-- CodeGenFunction.h - Target features for builtin ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the internal required target features for builtin.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H
+#define LLVM_CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+
+using llvm::StringRef;
+
+namespace clang {
+namespace Builtin {
+/// TargetFeatures - This class is used to check whether the builtin function
+/// has the required tagert specific features. It is able to support the
+/// combination of ','(and), '|'(or), and '()'. By default, the priority of
+/// ',' is higher than that of '|' .
+/// E.g:
+/// A,B|C means the builtin function requires both A and B, or C.
+/// If we want the builtin function requires both A and B, or both A and C,
+/// there are two ways: A,B|A,C or A,(B|C).
+/// The FeaturesList should not contain spaces, and brackets must appear in
+/// pairs.
+class TargetFeatures {
+ struct FeatureListStatus {
+ bool HasFeatures;
+ StringRef CurFeaturesList;
+ };
+
+ const llvm::StringMap<bool> &CallerFeatureMap;
+
+ FeatureListStatus getAndFeatures(StringRef FeatureList) {
+ int InParentheses = 0;
+ bool HasFeatures = true;
+ size_t SubexpressionStart = 0;
+ for (size_t i = 0, e = FeatureList.size(); i < e; ++i) {
+ char CurrentToken = FeatureList[i];
+ switch (CurrentToken) {
+ default:
+ break;
+ case '(':
+ if (InParentheses == 0)
+ SubexpressionStart = i + 1;
+ ++InParentheses;
+ break;
+ case ')':
+ --InParentheses;
+ assert(InParentheses >= 0 && "Parentheses are not in pair");
+ [[fallthrough]];
+ case '|':
+ case ',':
+ if (InParentheses == 0) {
+ if (HasFeatures && i != SubexpressionStart) {
+ StringRef F = FeatureList.slice(SubexpressionStart, i);
+ HasFeatures = CurrentToken == ')' ? hasRequiredFeatures(F)
+ : CallerFeatureMap.lookup(F);
+ }
+ SubexpressionStart = i + 1;
+ if (CurrentToken == '|') {
+ return {HasFeatures, FeatureList.substr(SubexpressionStart)};
+ }
+ }
+ break;
+ }
+ }
+ assert(InParentheses == 0 && "Parentheses are not in pair");
+ if (HasFeatures && SubexpressionStart != FeatureList.size())
+ HasFeatures =
+ CallerFeatureMap.lookup(FeatureList.substr(SubexpressionStart));
+ return {HasFeatures, StringRef()};
+ }
+
+public:
+ bool hasRequiredFeatures(StringRef FeatureList) {
+ FeatureListStatus FS = {false, FeatureList};
+ while (!FS.HasFeatures && !FS.CurFeaturesList.empty())
+ FS = getAndFeatures(FS.CurFeaturesList);
+ return FS.HasFeatures;
+ }
+
+ TargetFeatures(const llvm::StringMap<bool> &CallerFeatureMap)
+ : CallerFeatureMap(CallerFeatureMap) {}
+};
+
+} // namespace Builtin
+} // namespace clang
+#endif /* CLANG_LIB_BASIC_BUILTINTARGETFEATURES_H */
diff --git a/contrib/llvm-project/clang/lib/Basic/Builtins.cpp b/contrib/llvm-project/clang/lib/Basic/Builtins.cpp
index 7118aa9dc210..d366989bafc5 100644
--- a/contrib/llvm-project/clang/lib/Basic/Builtins.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Builtins.cpp
@@ -11,20 +11,33 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/Builtins.h"
+#include "BuiltinTargetFeatures.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/StringRef.h"
using namespace clang;
-static const Builtin::Info BuiltinInfo[] = {
- { "not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,nullptr},
+const char *HeaderDesc::getName() const {
+ switch (ID) {
+#define HEADER(ID, NAME) \
+ case ID: \
+ return NAME;
+#include "clang/Basic/BuiltinHeaders.def"
+#undef HEADER
+ };
+ llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
+}
+
+static constexpr Builtin::Info BuiltinInfo[] = {
+ {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+ ALL_LANGUAGES},
#define BUILTIN(ID, TYPE, ATTRS) \
- { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \
- { #ID, TYPE, ATTRS, nullptr, LANGS, nullptr },
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS) \
- { #ID, TYPE, ATTRS, HEADER, LANGS, nullptr },
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
#include "clang/Basic/Builtins.def"
};
@@ -48,43 +61,65 @@ void Builtin::Context::InitializeTarget(const TargetInfo &Target,
}
bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) {
- for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; ++i)
- if (FuncName.equals(BuiltinInfo[i].Name))
+ bool InStdNamespace = FuncName.consume_front("std-");
+ for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin;
+ ++i) {
+ if (FuncName.equals(BuiltinInfo[i].Name) &&
+ (bool)strchr(BuiltinInfo[i].Attributes, 'z') == InStdNamespace)
return strchr(BuiltinInfo[i].Attributes, 'f') != nullptr;
+ }
return false;
}
-bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo,
- const LangOptions &LangOpts) {
- bool BuiltinsUnsupported =
- (LangOpts.NoBuiltin || LangOpts.isNoBuiltinFunc(BuiltinInfo.Name)) &&
- strchr(BuiltinInfo.Attributes, 'f');
- bool CorBuiltinsUnsupported =
- !LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG);
- bool MathBuiltinsUnsupported =
- LangOpts.NoMathBuiltin && BuiltinInfo.HeaderName &&
- llvm::StringRef(BuiltinInfo.HeaderName).equals("math.h");
- bool GnuModeUnsupported = !LangOpts.GNUMode && (BuiltinInfo.Langs & GNU_LANG);
- bool MSModeUnsupported =
- !LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG);
- bool ObjCUnsupported = !LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG;
- bool OclC1Unsupported = (LangOpts.OpenCLVersion / 100) != 1 &&
- (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES ) == OCLC1X_LANG;
- bool OclC2Unsupported =
- (LangOpts.OpenCLVersion != 200 && !LangOpts.OpenCLCPlusPlus) &&
- (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES) == OCLC20_LANG;
- bool OclCUnsupported = !LangOpts.OpenCL &&
- (BuiltinInfo.Langs & ALL_OCLC_LANGUAGES);
- bool OpenMPUnsupported = !LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG;
- bool CUDAUnsupported = !LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG;
- bool CPlusPlusUnsupported =
- !LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG;
- return !BuiltinsUnsupported && !CorBuiltinsUnsupported &&
- !MathBuiltinsUnsupported && !OclCUnsupported && !OclC1Unsupported &&
- !OclC2Unsupported && !OpenMPUnsupported && !GnuModeUnsupported &&
- !MSModeUnsupported && !ObjCUnsupported && !CPlusPlusUnsupported &&
- !CUDAUnsupported;
+/// Is this builtin supported according to the given language options?
+static bool builtinIsSupported(const Builtin::Info &BuiltinInfo,
+ const LangOptions &LangOpts) {
+ /* Builtins Unsupported */
+ if (LangOpts.NoBuiltin && strchr(BuiltinInfo.Attributes, 'f') != nullptr)
+ return false;
+ /* CorBuiltins Unsupported */
+ if (!LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG))
+ return false;
+ /* MathBuiltins Unsupported */
+ if (LangOpts.NoMathBuiltin && BuiltinInfo.Header.ID == HeaderDesc::MATH_H)
+ return false;
+ /* GnuMode Unsupported */
+ if (!LangOpts.GNUMode && (BuiltinInfo.Langs & GNU_LANG))
+ return false;
+ /* MSMode Unsupported */
+ if (!LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG))
+ return false;
+ /* ObjC Unsupported */
+ if (!LangOpts.ObjC && BuiltinInfo.Langs == OBJC_LANG)
+ return false;
+ /* OpenCLC Unsupported */
+ if (!LangOpts.OpenCL && (BuiltinInfo.Langs & ALL_OCL_LANGUAGES))
+ return false;
+ /* OopenCL GAS Unsupported */
+ if (!LangOpts.OpenCLGenericAddressSpace && (BuiltinInfo.Langs & OCL_GAS))
+ return false;
+ /* OpenCL Pipe Unsupported */
+ if (!LangOpts.OpenCLPipes && (BuiltinInfo.Langs & OCL_PIPE))
+ return false;
+
+ // Device side enqueue is not supported until OpenCL 2.0. In 2.0 and higher
+ // support is indicated with language option for blocks.
+
+ /* OpenCL DSE Unsupported */
+ if ((LangOpts.getOpenCLCompatibleVersion() < 200 || !LangOpts.Blocks) &&
+ (BuiltinInfo.Langs & OCL_DSE))
+ return false;
+ /* OpenMP Unsupported */
+ if (!LangOpts.OpenMP && BuiltinInfo.Langs == OMP_LANG)
+ return false;
+ /* CUDA Unsupported */
+ if (!LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG)
+ return false;
+ /* CPlusPlus Unsupported */
+ if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG)
+ return false;
+ return true;
}
/// initializeBuiltins - Mark the identifiers for all the builtins with their
@@ -107,6 +142,19 @@ void Builtin::Context::initializeBuiltins(IdentifierTable &Table,
for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i)
Table.get(AuxTSRecords[i].Name)
.setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size());
+
+ // Step #4: Unregister any builtins specified by -fno-builtin-foo.
+ for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) {
+ bool InStdNamespace = Name.consume_front("std-");
+ auto NameIt = Table.find(Name);
+ if (NameIt != Table.end()) {
+ unsigned ID = NameIt->second->getBuiltinID();
+ if (ID != Builtin::NotBuiltin && isPredefinedLibFunction(ID) &&
+ isInStdNamespace(ID) == InStdNamespace) {
+ NameIt->second->clearBuiltinID();
+ }
+ }
+ }
}
unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const {
@@ -186,8 +234,19 @@ bool Builtin::Context::performsCallback(unsigned ID,
}
bool Builtin::Context::canBeRedeclared(unsigned ID) const {
- return ID == Builtin::NotBuiltin ||
- ID == Builtin::BI__va_start ||
- (!hasReferenceArgsOrResult(ID) &&
- !hasCustomTypechecking(ID));
+ return ID == Builtin::NotBuiltin || ID == Builtin::BI__va_start ||
+ ID == Builtin::BI__builtin_assume_aligned ||
+ (!hasReferenceArgsOrResult(ID) && !hasCustomTypechecking(ID)) ||
+ isInStdNamespace(ID);
+}
+
+bool Builtin::evaluateRequiredTargetFeatures(
+ StringRef RequiredFeatures, const llvm::StringMap<bool> &TargetFetureMap) {
+ // Return true if the builtin doesn't have any required features.
+ if (RequiredFeatures.empty())
+ return true;
+ assert(!RequiredFeatures.contains(' ') && "Space in feature list");
+
+ TargetFeatures TF(TargetFetureMap);
+ return TF.hasRequiredFeatures(RequiredFeatures);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/CLWarnings.cpp b/contrib/llvm-project/clang/lib/Basic/CLWarnings.cpp
new file mode 100644
index 000000000000..5449d8f59fcf
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/CLWarnings.cpp
@@ -0,0 +1,29 @@
+//===--- CLWarnings.h - Maps some cl.exe warning ids -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Diagnostic-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/CLWarnings.h"
+#include "clang/Basic/DiagnosticCategories.h"
+#include <optional>
+
+using namespace clang;
+
+std::optional<diag::Group>
+clang::diagGroupFromCLWarningID(unsigned CLWarningID) {
+ switch (CLWarningID) {
+ case 4005: return diag::Group::MacroRedefined;
+ case 4018: return diag::Group::SignCompare;
+ case 4100: return diag::Group::UnusedParameter;
+ case 4910: return diag::Group::DllexportExplicitInstantiationDecl;
+ case 4996: return diag::Group::DeprecatedDeclarations;
+ }
+ return {};
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp b/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp
index 0c609cfa61de..79d715305ef2 100644
--- a/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/CodeGenOptions.cpp
@@ -20,4 +20,41 @@ CodeGenOptions::CodeGenOptions() {
memcpy(CoverageVersion, "408*", 4);
}
+void CodeGenOptions::resetNonModularOptions(StringRef ModuleFormat) {
+ // First reset all CodeGen options only. The Debug options are handled later.
+#define DEBUGOPT(Name, Bits, Default)
+#define VALUE_DEBUGOPT(Name, Bits, Default)
+#define ENUM_DEBUGOPT(Name, Type, Bits, Default)
+#define CODEGENOPT(Name, Bits, Default) Name = Default;
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default);
+// Do not reset AST affecting code generation options.
+#define AFFECTING_VALUE_CODEGENOPT(Name, Bits, Default)
+#include "clang/Basic/CodeGenOptions.def"
+
+ // Next reset all debug options that can always be reset, because they never
+ // affect the PCM.
+#define DEBUGOPT(Name, Bits, Default)
+#define VALUE_DEBUGOPT(Name, Bits, Default)
+#define ENUM_DEBUGOPT(Name, Type, Bits, Default)
+#define BENIGN_DEBUGOPT(Name, Bits, Default) Name = Default;
+#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default) Name = Default;
+#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default) set##Name(Default);
+#include "clang/Basic/DebugOptions.def"
+
+ // Conditionally reset debug options that only matter when the debug info is
+ // emitted into the PCM (-gmodules).
+ if (ModuleFormat == "raw" && !DebugTypeExtRefs) {
+#define DEBUGOPT(Name, Bits, Default) Name = Default;
+#define VALUE_DEBUGOPT(Name, Bits, Default) Name = Default;
+#define ENUM_DEBUGOPT(Name, Type, Bits, Default) set##Name(Default);
+#define BENIGN_DEBUGOPT(Name, Bits, Default)
+#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default)
+#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default)
+#include "clang/Basic/DebugOptions.def"
+ }
+
+ RelocationModel = llvm::Reloc::PIC_;
+ memcpy(CoverageVersion, "408*", 4);
+}
+
} // end namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/Cuda.cpp b/contrib/llvm-project/clang/lib/Basic/Cuda.cpp
index 766135bcb376..1b1da6a1356f 100644
--- a/contrib/llvm-project/clang/lib/Basic/Cuda.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Cuda.cpp
@@ -1,60 +1,72 @@
#include "clang/Basic/Cuda.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/VersionTuple.h"
namespace clang {
-const char *CudaVersionToString(CudaVersion V) {
- switch (V) {
- case CudaVersion::UNKNOWN:
- return "unknown";
- case CudaVersion::CUDA_70:
- return "7.0";
- case CudaVersion::CUDA_75:
- return "7.5";
- case CudaVersion::CUDA_80:
- return "8.0";
- case CudaVersion::CUDA_90:
- return "9.0";
- case CudaVersion::CUDA_91:
- return "9.1";
- case CudaVersion::CUDA_92:
- return "9.2";
- case CudaVersion::CUDA_100:
- return "10.0";
- case CudaVersion::CUDA_101:
- return "10.1";
- case CudaVersion::CUDA_102:
- return "10.2";
- case CudaVersion::CUDA_110:
- return "11.0";
- case CudaVersion::CUDA_111:
- return "11.1";
- case CudaVersion::CUDA_112:
- return "11.2";
+struct CudaVersionMapEntry {
+ const char *Name;
+ CudaVersion Version;
+ llvm::VersionTuple TVersion;
+};
+#define CUDA_ENTRY(major, minor) \
+ { \
+#major "." #minor, CudaVersion::CUDA_##major##minor, \
+ llvm::VersionTuple(major, minor) \
}
- llvm_unreachable("invalid enum");
+
+static const CudaVersionMapEntry CudaNameVersionMap[] = {
+ CUDA_ENTRY(7, 0),
+ CUDA_ENTRY(7, 5),
+ CUDA_ENTRY(8, 0),
+ CUDA_ENTRY(9, 0),
+ CUDA_ENTRY(9, 1),
+ CUDA_ENTRY(9, 2),
+ CUDA_ENTRY(10, 0),
+ CUDA_ENTRY(10, 1),
+ CUDA_ENTRY(10, 2),
+ CUDA_ENTRY(11, 0),
+ CUDA_ENTRY(11, 1),
+ CUDA_ENTRY(11, 2),
+ CUDA_ENTRY(11, 3),
+ CUDA_ENTRY(11, 4),
+ CUDA_ENTRY(11, 5),
+ CUDA_ENTRY(11, 6),
+ CUDA_ENTRY(11, 7),
+ CUDA_ENTRY(11, 8),
+ CUDA_ENTRY(12, 0),
+ CUDA_ENTRY(12, 1),
+ CUDA_ENTRY(12, 2),
+ CUDA_ENTRY(12, 3),
+ {"", CudaVersion::NEW, llvm::VersionTuple(std::numeric_limits<int>::max())},
+ {"unknown", CudaVersion::UNKNOWN, {}} // End of list tombstone.
+};
+#undef CUDA_ENTRY
+
+const char *CudaVersionToString(CudaVersion V) {
+ for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
+ if (I->Version == V)
+ return I->Name;
+
+ return CudaVersionToString(CudaVersion::UNKNOWN);
}
CudaVersion CudaStringToVersion(const llvm::Twine &S) {
- return llvm::StringSwitch<CudaVersion>(S.str())
- .Case("7.0", CudaVersion::CUDA_70)
- .Case("7.5", CudaVersion::CUDA_75)
- .Case("8.0", CudaVersion::CUDA_80)
- .Case("9.0", CudaVersion::CUDA_90)
- .Case("9.1", CudaVersion::CUDA_91)
- .Case("9.2", CudaVersion::CUDA_92)
- .Case("10.0", CudaVersion::CUDA_100)
- .Case("10.1", CudaVersion::CUDA_101)
- .Case("10.2", CudaVersion::CUDA_102)
- .Case("11.0", CudaVersion::CUDA_110)
- .Case("11.1", CudaVersion::CUDA_111)
- .Case("11.2", CudaVersion::CUDA_112)
- .Default(CudaVersion::UNKNOWN);
+ std::string VS = S.str();
+ for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
+ if (I->Name == VS)
+ return I->Version;
+ return CudaVersion::UNKNOWN;
+}
+
+CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
+ for (auto *I = CudaNameVersionMap; I->Version != CudaVersion::UNKNOWN; ++I)
+ if (I->TVersion == Version)
+ return I->Version;
+ return CudaVersion::UNKNOWN;
}
namespace {
@@ -80,6 +92,10 @@ static const CudaArchToStringMap arch_names[] = {
SM(70), SM(72), // Volta
SM(75), // Turing
SM(80), SM(86), // Ampere
+ SM(87), // Jetson/Drive AGX Orin
+ SM(89), // Ada Lovelace
+ SM(90), // Hopper
+ SM(90a), // Hopper
GFX(600), // gfx600
GFX(601), // gfx601
GFX(602), // gfx602
@@ -102,6 +118,9 @@ static const CudaArchToStringMap arch_names[] = {
GFX(909), // gfx909
GFX(90a), // gfx90a
GFX(90c), // gfx90c
+ GFX(940), // gfx940
+ GFX(941), // gfx941
+ GFX(942), // gfx942
GFX(1010), // gfx1010
GFX(1011), // gfx1011
GFX(1012), // gfx1012
@@ -112,6 +131,16 @@ static const CudaArchToStringMap arch_names[] = {
GFX(1033), // gfx1033
GFX(1034), // gfx1034
GFX(1035), // gfx1035
+ GFX(1036), // gfx1036
+ GFX(1100), // gfx1100
+ GFX(1101), // gfx1101
+ GFX(1102), // gfx1102
+ GFX(1103), // gfx1103
+ GFX(1150), // gfx1150
+ GFX(1151), // gfx1151
+ GFX(1200), // gfx1200
+ GFX(1201), // gfx1201
+ {CudaArch::Generic, "generic", ""},
// clang-format on
};
#undef SM
@@ -178,6 +207,13 @@ CudaVersion MinVersionForCudaArch(CudaArch A) {
return CudaVersion::CUDA_110;
case CudaArch::SM_86:
return CudaVersion::CUDA_111;
+ case CudaArch::SM_87:
+ return CudaVersion::CUDA_114;
+ case CudaArch::SM_89:
+ case CudaArch::SM_90:
+ return CudaVersion::CUDA_118;
+ case CudaArch::SM_90a:
+ return CudaVersion::CUDA_120;
default:
llvm_unreachable("invalid enum");
}
@@ -186,7 +222,7 @@ CudaVersion MinVersionForCudaArch(CudaArch A) {
CudaVersion MaxVersionForCudaArch(CudaArch A) {
// AMD GPUs do not depend on CUDA versions.
if (IsAMDGpuArch(A))
- return CudaVersion::LATEST;
+ return CudaVersion::NEW;
switch (A) {
case CudaArch::UNKNOWN:
@@ -194,41 +230,14 @@ CudaVersion MaxVersionForCudaArch(CudaArch A) {
case CudaArch::SM_20:
case CudaArch::SM_21:
return CudaVersion::CUDA_80;
- default:
- return CudaVersion::LATEST;
- }
-}
-
-CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
- int IVer =
- Version.getMajor() * 10 + Version.getMinor().getValueOr(0);
- switch(IVer) {
- case 70:
- return CudaVersion::CUDA_70;
- case 75:
- return CudaVersion::CUDA_75;
- case 80:
- return CudaVersion::CUDA_80;
- case 90:
- return CudaVersion::CUDA_90;
- case 91:
- return CudaVersion::CUDA_91;
- case 92:
- return CudaVersion::CUDA_92;
- case 100:
- return CudaVersion::CUDA_100;
- case 101:
- return CudaVersion::CUDA_101;
- case 102:
+ case CudaArch::SM_30:
+ case CudaArch::SM_32:
return CudaVersion::CUDA_102;
- case 110:
- return CudaVersion::CUDA_110;
- case 111:
- return CudaVersion::CUDA_111;
- case 112:
- return CudaVersion::CUDA_112;
+ case CudaArch::SM_35:
+ case CudaArch::SM_37:
+ return CudaVersion::CUDA_118;
default:
- return CudaVersion::UNKNOWN;
+ return CudaVersion::NEW;
}
}
diff --git a/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp b/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp
index fe35f77782c9..00aa5f9e63cd 100644
--- a/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/DarwinSDKInfo.cpp
@@ -11,12 +11,13 @@
#include "llvm/Support/JSON.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
+#include <optional>
using namespace clang;
-Optional<VersionTuple> DarwinSDKInfo::RelatedTargetVersionMapping::map(
+std::optional<VersionTuple> DarwinSDKInfo::RelatedTargetVersionMapping::map(
const VersionTuple &Key, const VersionTuple &MinimumValue,
- Optional<VersionTuple> MaximumValue) const {
+ std::optional<VersionTuple> MaximumValue) const {
if (Key < MinimumKeyVersion)
return MinimumValue;
if (Key > MaximumKeyVersion)
@@ -29,11 +30,11 @@ Optional<VersionTuple> DarwinSDKInfo::RelatedTargetVersionMapping::map(
// the major-only check.
if (Key.getMinor())
return map(VersionTuple(Key.getMajor()), MinimumValue, MaximumValue);
- // If this a major only key, return None for a missing entry.
- return None;
+ // If this a major only key, return std::nullopt for a missing entry.
+ return std::nullopt;
}
-Optional<DarwinSDKInfo::RelatedTargetVersionMapping>
+std::optional<DarwinSDKInfo::RelatedTargetVersionMapping>
DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(
const llvm::json::Object &Obj, VersionTuple MaximumDeploymentTarget) {
VersionTuple Min = VersionTuple(std::numeric_limits<unsigned>::max());
@@ -45,7 +46,7 @@ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(
llvm::VersionTuple KeyVersion;
llvm::VersionTuple ValueVersion;
if (KeyVersion.tryParse(KV.getFirst()) || ValueVersion.tryParse(*Val))
- return None;
+ return std::nullopt;
Mapping[KeyVersion.normalize()] = ValueVersion;
if (KeyVersion < Min)
Min = KeyVersion;
@@ -56,39 +57,59 @@ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON(
}
}
if (Mapping.empty())
- return None;
+ return std::nullopt;
return RelatedTargetVersionMapping(
Min, Max, MinValue, MaximumDeploymentTarget, std::move(Mapping));
}
-static Optional<VersionTuple> getVersionKey(const llvm::json::Object &Obj,
- StringRef Key) {
+static std::optional<VersionTuple> getVersionKey(const llvm::json::Object &Obj,
+ StringRef Key) {
auto Value = Obj.getString(Key);
if (!Value)
- return None;
+ return std::nullopt;
VersionTuple Version;
if (Version.tryParse(*Value))
- return None;
+ return std::nullopt;
return Version;
}
-Optional<DarwinSDKInfo>
+std::optional<DarwinSDKInfo>
DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) {
auto Version = getVersionKey(*Obj, "Version");
if (!Version)
- return None;
+ return std::nullopt;
auto MaximumDeploymentVersion =
getVersionKey(*Obj, "MaximumDeploymentTarget");
if (!MaximumDeploymentVersion)
- return None;
- llvm::DenseMap<OSEnvPair::StorageType, Optional<RelatedTargetVersionMapping>>
+ return std::nullopt;
+ llvm::DenseMap<OSEnvPair::StorageType,
+ std::optional<RelatedTargetVersionMapping>>
VersionMappings;
if (const auto *VM = Obj->getObject("VersionMap")) {
+ // FIXME: Generalize this out beyond iOS-deriving targets.
+ // Look for ios_<targetos> version mapping for targets that derive from ios.
+ for (const auto &KV : *VM) {
+ auto Pair = StringRef(KV.getFirst()).split("_");
+ if (Pair.first.compare_insensitive("ios") == 0) {
+ llvm::Triple TT(llvm::Twine("--") + Pair.second.lower());
+ if (TT.getOS() != llvm::Triple::UnknownOS) {
+ auto Mapping = RelatedTargetVersionMapping::parseJSON(
+ *KV.getSecond().getAsObject(), *MaximumDeploymentVersion);
+ if (Mapping)
+ VersionMappings[OSEnvPair(llvm::Triple::IOS,
+ llvm::Triple::UnknownEnvironment,
+ TT.getOS(),
+ llvm::Triple::UnknownEnvironment)
+ .Value] = std::move(Mapping);
+ }
+ }
+ }
+
if (const auto *Mapping = VM->getObject("macOS_iOSMac")) {
auto VersionMap = RelatedTargetVersionMapping::parseJSON(
*Mapping, *MaximumDeploymentVersion);
if (!VersionMap)
- return None;
+ return std::nullopt;
VersionMappings[OSEnvPair::macOStoMacCatalystPair().Value] =
std::move(VersionMap);
}
@@ -96,7 +117,7 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) {
auto VersionMap = RelatedTargetVersionMapping::parseJSON(
*Mapping, *MaximumDeploymentVersion);
if (!VersionMap)
- return None;
+ return std::nullopt;
VersionMappings[OSEnvPair::macCatalystToMacOSPair().Value] =
std::move(VersionMap);
}
@@ -107,7 +128,7 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) {
std::move(VersionMappings));
}
-Expected<Optional<DarwinSDKInfo>>
+Expected<std::optional<DarwinSDKInfo>>
clang::parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath) {
llvm::SmallString<256> Filepath = SDKRootPath;
llvm::sys::path::append(Filepath, "SDKSettings.json");
@@ -115,7 +136,7 @@ clang::parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath) {
VFS.getBufferForFile(Filepath);
if (!File) {
// If the file couldn't be read, assume it just doesn't exist.
- return None;
+ return std::nullopt;
}
Expected<llvm::json::Value> Result =
llvm::json::parse(File.get()->getBuffer());
diff --git a/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp
index d3b2122e9c59..0208ccc31bd7 100644
--- a/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Diagnostic.cpp
@@ -25,8 +25,9 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/CrashRecoveryContext.h"
-#include "llvm/Support/Locale.h"
+#include "llvm/Support/Unicode.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -42,28 +43,12 @@ using namespace clang;
const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
DiagNullabilityKind nullability) {
- StringRef string;
- switch (nullability.first) {
- case NullabilityKind::NonNull:
- string = nullability.second ? "'nonnull'" : "'_Nonnull'";
- break;
-
- case NullabilityKind::Nullable:
- string = nullability.second ? "'nullable'" : "'_Nullable'";
- break;
-
- case NullabilityKind::Unspecified:
- string = nullability.second ? "'null_unspecified'" : "'_Null_unspecified'";
- break;
-
- case NullabilityKind::NullableResult:
- assert(!nullability.second &&
- "_Nullable_result isn't supported as context-sensitive keyword");
- string = "_Nullable_result";
- break;
- }
-
- DB.AddString(string);
+ DB.AddString(
+ ("'" +
+ getNullabilitySpelling(nullability.first,
+ /*isContextSensitive=*/nullability.second) +
+ "'")
+ .str());
return DB;
}
@@ -130,7 +115,7 @@ bool DiagnosticsEngine::popMappings(SourceLocation Loc) {
return true;
}
-void DiagnosticsEngine::Reset() {
+void DiagnosticsEngine::Reset(bool soft /*=false*/) {
ErrorOccurred = false;
UncompilableErrorOccurred = false;
FatalErrorOccurred = false;
@@ -145,15 +130,17 @@ void DiagnosticsEngine::Reset() {
LastDiagLevel = DiagnosticIDs::Ignored;
DelayedDiagID = 0;
- // Clear state related to #pragma diagnostic.
- DiagStates.clear();
- DiagStatesByLoc.clear();
- DiagStateOnPushStack.clear();
+ if (!soft) {
+ // Clear state related to #pragma diagnostic.
+ DiagStates.clear();
+ DiagStatesByLoc.clear();
+ DiagStateOnPushStack.clear();
- // Create a DiagState and DiagStatePoint representing diagnostic changes
- // through command-line.
- DiagStates.emplace_back();
- DiagStatesByLoc.appendFirst(&DiagStates.back());
+ // Create a DiagState and DiagStatePoint representing diagnostic changes
+ // through command-line.
+ DiagStates.emplace_back();
+ DiagStatesByLoc.appendFirst(&DiagStates.back());
+ }
}
void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
@@ -173,6 +160,18 @@ void DiagnosticsEngine::ReportDelayed() {
Report(ID) << DelayedDiagArg1 << DelayedDiagArg2 << DelayedDiagArg3;
}
+DiagnosticMapping &
+DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
+ std::pair<iterator, bool> Result =
+ DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
+
+ // Initialize the entry if we added it.
+ if (Result.second)
+ Result.first->second = DiagnosticIDs::getDefaultMapping(Diag);
+
+ return Result.first->second;
+}
+
void DiagnosticsEngine::DiagStateMap::appendFirst(DiagState *State) {
assert(Files.empty() && "not first");
FirstDiagState = CurDiagState = State;
@@ -374,6 +373,12 @@ void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
DiagnosticMapping Mapping = makeUserMapping(Map, L);
Mapping.setUpgradedFromWarning(WasUpgradedFromWarning);
+ // Make sure we propagate the NoWarningAsError flag from an existing
+ // mapping (which may be the default mapping).
+ DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
+ Mapping.setNoWarningAsError(Info.hasNoWarningAsError() ||
+ Mapping.hasNoWarningAsError());
+
// Common case; setting all the diagnostics of a group in one place.
if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) &&
DiagStatesByLoc.getCurDiagState()) {
@@ -408,6 +413,14 @@ bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
return false;
}
+bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
+ diag::Group Group,
+ diag::Severity Map,
+ SourceLocation Loc) {
+ return setSeverityForGroup(Flavor, Diags->getWarningOptionForGroup(Group),
+ Map, Loc);
+}
+
bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
bool Enabled) {
// If we are enabling this feature, just set the diagnostic mappings to map to
@@ -776,8 +789,8 @@ static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) {
/// array.
void Diagnostic::
FormatDiagnostic(SmallVectorImpl<char> &OutStr) const {
- if (!StoredDiagMessage.empty()) {
- OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end());
+ if (StoredDiagMessage.has_value()) {
+ OutStr.append(StoredDiagMessage->begin(), StoredDiagMessage->end());
return;
}
@@ -787,6 +800,51 @@ FormatDiagnostic(SmallVectorImpl<char> &OutStr) const {
FormatDiagnostic(Diag.begin(), Diag.end(), OutStr);
}
+/// EscapeStringForDiagnostic - Append Str to the diagnostic buffer,
+/// escaping non-printable characters and ill-formed code unit sequences.
+void clang::EscapeStringForDiagnostic(StringRef Str,
+ SmallVectorImpl<char> &OutStr) {
+ OutStr.reserve(OutStr.size() + Str.size());
+ auto *Begin = reinterpret_cast<const unsigned char *>(Str.data());
+ llvm::raw_svector_ostream OutStream(OutStr);
+ const unsigned char *End = Begin + Str.size();
+ while (Begin != End) {
+ // ASCII case
+ if (isPrintable(*Begin) || isWhitespace(*Begin)) {
+ OutStream << *Begin;
+ ++Begin;
+ continue;
+ }
+ if (llvm::isLegalUTF8Sequence(Begin, End)) {
+ llvm::UTF32 CodepointValue;
+ llvm::UTF32 *CpPtr = &CodepointValue;
+ const unsigned char *CodepointBegin = Begin;
+ const unsigned char *CodepointEnd =
+ Begin + llvm::getNumBytesForUTF8(*Begin);
+ llvm::ConversionResult Res = llvm::ConvertUTF8toUTF32(
+ &Begin, CodepointEnd, &CpPtr, CpPtr + 1, llvm::strictConversion);
+ (void)Res;
+ assert(
+ llvm::conversionOK == Res &&
+ "the sequence is legal UTF-8 but we couldn't convert it to UTF-32");
+ assert(Begin == CodepointEnd &&
+ "we must be further along in the string now");
+ if (llvm::sys::unicode::isPrintable(CodepointValue) ||
+ llvm::sys::unicode::isFormatting(CodepointValue)) {
+ OutStr.append(CodepointBegin, CodepointEnd);
+ continue;
+ }
+ // Unprintable code point.
+ OutStream << "<U+" << llvm::format_hex_no_prefix(CodepointValue, 4, true)
+ << ">";
+ continue;
+ }
+ // Invalid code unit.
+ OutStream << "<" << llvm::format_hex_no_prefix(*Begin, 2, true) << ">";
+ ++Begin;
+ }
+}
+
void Diagnostic::
FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
SmallVectorImpl<char> &OutStr) const {
@@ -797,11 +855,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
StringRef(DiagStr, DiagEnd - DiagStr).equals("%0") &&
getArgKind(0) == DiagnosticsEngine::ak_std_string) {
const std::string &S = getArgStdStr(0);
- for (char c : S) {
- if (llvm::sys::locale::isPrint(c) || c == '\t') {
- OutStr.push_back(c);
- }
- }
+ EscapeStringForDiagnostic(S, OutStr);
return;
}
@@ -908,7 +962,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
case DiagnosticsEngine::ak_std_string: {
const std::string &S = getArgStdStr(ArgNo);
assert(ModifierLen == 0 && "No modifiers for strings yet");
- OutStr.append(S.begin(), S.end());
+ EscapeStringForDiagnostic(S, OutStr);
break;
}
case DiagnosticsEngine::ak_c_string: {
@@ -918,13 +972,12 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
// Don't crash if get passed a null pointer by accident.
if (!S)
S = "(null)";
-
- OutStr.append(S, S + strlen(S));
+ EscapeStringForDiagnostic(S, OutStr);
break;
}
// ---- INTEGERS ----
case DiagnosticsEngine::ak_sint: {
- int Val = getArgSInt(ArgNo);
+ int64_t Val = getArgSInt(ArgNo);
if (ModifierIs(Modifier, ModifierLen, "select")) {
HandleSelectModifier(*this, (unsigned)Val, Argument, ArgumentLen,
@@ -943,7 +996,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
break;
}
case DiagnosticsEngine::ak_uint: {
- unsigned Val = getArgUInt(ArgNo);
+ uint64_t Val = getArgUInt(ArgNo);
if (ModifierIs(Modifier, ModifierLen, "select")) {
HandleSelectModifier(*this, Val, Argument, ArgumentLen, OutStr);
@@ -969,13 +1022,13 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
if (const char *S = tok::getPunctuatorSpelling(Kind))
// Quoted token spelling for punctuators.
Out << '\'' << S << '\'';
- else if (const char *S = tok::getKeywordSpelling(Kind))
+ else if ((S = tok::getKeywordSpelling(Kind)))
// Unquoted token spelling for keywords.
Out << S;
- else if (const char *S = getTokenDescForDiagnostic(Kind))
+ else if ((S = getTokenDescForDiagnostic(Kind)))
// Unquoted translatable token name.
Out << S;
- else if (const char *S = tok::getTokenName(Kind))
+ else if ((S = tok::getTokenName(Kind)))
// Debug name, shouldn't appear in user-facing diagnostics.
Out << '<' << S << '>';
else
@@ -1124,6 +1177,14 @@ StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
{
}
+llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
+ const StoredDiagnostic &SD) {
+ if (SD.getLocation().hasManager())
+ OS << SD.getLocation().printToString(SD.getLocation().getManager()) << ": ";
+ OS << SD.getMessage();
+ return OS;
+}
+
/// IncludeInDiagnosticCounts - This method (whose default implementation
/// returns true) indicates whether the diagnostics handled by this
/// DiagnosticConsumer should be included in the number of diagnostics
diff --git a/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp
index c333076d2efc..6c7bd50eefb7 100644
--- a/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/DiagnosticIDs.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
#include <map>
+#include <optional>
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -33,7 +34,7 @@ struct StaticDiagInfoRec;
// platforms. See "How To Write Shared Libraries" by Ulrich Drepper.
struct StaticDiagInfoDescriptionStringTable {
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
- SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
+ SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
char ENUM##_desc[sizeof(DESC)];
// clang-format off
#include "clang/Basic/DiagnosticCommonKinds.inc"
@@ -54,7 +55,7 @@ struct StaticDiagInfoDescriptionStringTable {
const StaticDiagInfoDescriptionStringTable StaticDiagInfoDescriptions = {
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
- SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
+ SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
DESC,
// clang-format off
#include "clang/Basic/DiagnosticCommonKinds.inc"
@@ -79,7 +80,7 @@ extern const StaticDiagInfoRec StaticDiagInfo[];
// StaticDiagInfoRec would have extra padding on 64-bit platforms.
const uint32_t StaticDiagInfoDescriptionOffsets[] = {
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
- SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
+ SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
offsetof(StaticDiagInfoDescriptionStringTable, ENUM##_desc),
// clang-format off
#include "clang/Basic/DiagnosticCommonKinds.inc"
@@ -115,6 +116,7 @@ struct StaticDiagInfoRec {
uint8_t Category : 6;
uint8_t WarnNoWerror : 1;
uint8_t WarnShowInSystemHeader : 1;
+ uint8_t WarnShowInSystemMacro : 1;
uint16_t OptionGroupIndex : 15;
uint16_t Deferrable : 1;
@@ -170,7 +172,7 @@ VALIDATE_DIAG_SIZE(REFACTORING)
const StaticDiagInfoRec StaticDiagInfo[] = {
// clang-format off
#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
- SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
+ SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \
{ \
diag::ENUM, \
DEFAULT_SEVERITY, \
@@ -179,6 +181,7 @@ const StaticDiagInfoRec StaticDiagInfo[] = {
CATEGORY, \
NOWERROR, \
SHOWINSYSHEADER, \
+ SHOWINSYSMACRO, \
GROUP, \
DEFERRABLE, \
STR_SIZE(DESC, uint16_t)},
@@ -200,7 +203,7 @@ const StaticDiagInfoRec StaticDiagInfo[] = {
} // namespace
-static const unsigned StaticDiagInfoSize = llvm::array_lengthof(StaticDiagInfo);
+static const unsigned StaticDiagInfoSize = std::size(StaticDiagInfo);
/// GetDiagInfo - Return the StaticDiagInfoRec entry for the specified DiagID,
/// or null if the ID is invalid.
@@ -253,7 +256,7 @@ CATEGORY(REFACTORING, ANALYSIS)
return Found;
}
-static DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) {
+DiagnosticMapping DiagnosticIDs::getDefaultMapping(unsigned DiagID) {
DiagnosticMapping Info = DiagnosticMapping::Make(
diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false);
@@ -290,21 +293,6 @@ namespace {
};
}
-// Unfortunately, the split between DiagnosticIDs and Diagnostic is not
-// particularly clean, but for now we just implement this method here so we can
-// access GetDefaultDiagMapping.
-DiagnosticMapping &
-DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
- std::pair<iterator, bool> Result =
- DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
-
- // Initialize the entry if we added it.
- if (Result.second)
- Result.first->second = GetDefaultDiagMapping(Diag);
-
- return Result.first->second;
-}
-
static const StaticDiagCategoryRec CategoryNameTable[] = {
#define GET_CATEGORY_TABLE
#define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
@@ -315,7 +303,7 @@ static const StaticDiagCategoryRec CategoryNameTable[] = {
/// getNumberOfCategories - Return the number of categories
unsigned DiagnosticIDs::getNumberOfCategories() {
- return llvm::array_lengthof(CategoryNameTable) - 1;
+ return std::size(CategoryNameTable) - 1;
}
/// getCategoryNameFromID - Given a category ID, return the name of the
@@ -446,7 +434,7 @@ bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
return false;
EnabledByDefault =
- GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored;
+ getDefaultMapping(DiagID).getSeverity() != diag::Severity::Ignored;
return true;
}
@@ -454,7 +442,7 @@ bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) {
if (DiagID >= diag::DIAG_UPPER_LIMIT)
return false;
- return GetDefaultDiagMapping(DiagID).getSeverity() >= diag::Severity::Error;
+ return getDefaultMapping(DiagID).getSeverity() >= diag::Severity::Error;
}
/// getDescription - Given a diagnostic ID, return a description of the
@@ -544,7 +532,7 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
if (Result == diag::Severity::Ignored)
return Result;
- // Honor -w: this disables all messages which which are not Error/Fatal by
+ // Honor -w: this disables all messages which are not Error/Fatal by
// default (disregarding attempts to upgrade severity from Warning to Error),
// as well as disabling all messages which are currently mapped to Warning
// (whether by default or downgraded from Error via e.g. -Wno-error or #pragma
@@ -586,6 +574,13 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
Diag.getSourceManager().getExpansionLoc(Loc)))
return diag::Severity::Ignored;
+ // We also ignore warnings due to system macros
+ bool ShowInSystemMacro =
+ !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemMacro;
+ if (State->SuppressSystemWarnings && !ShowInSystemMacro && Loc.isValid() &&
+ Diag.getSourceManager().isInSystemMacro(Loc))
+ return diag::Severity::Ignored;
+
return Result;
}
@@ -598,6 +593,7 @@ namespace {
uint16_t NameOffset;
uint16_t Members;
uint16_t SubGroups;
+ StringRef Documentation;
// String is stored with a pascal-style length byte.
StringRef getName() const {
@@ -609,22 +605,47 @@ namespace {
// Second the table of options, sorted by name for fast binary lookup.
static const WarningOption OptionTable[] = {
-#define GET_DIAG_TABLE
+#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
+ {FlagNameOffset, Members, SubGroups, Docs},
#include "clang/Basic/DiagnosticGroups.inc"
-#undef GET_DIAG_TABLE
+#undef DIAG_ENTRY
};
+/// Given a diagnostic group ID, return its documentation.
+StringRef DiagnosticIDs::getWarningOptionDocumentation(diag::Group Group) {
+ return OptionTable[static_cast<int>(Group)].Documentation;
+}
+
+StringRef DiagnosticIDs::getWarningOptionForGroup(diag::Group Group) {
+ return OptionTable[static_cast<int>(Group)].getName();
+}
+
+std::optional<diag::Group>
+DiagnosticIDs::getGroupForWarningOption(StringRef Name) {
+ const auto *Found = llvm::partition_point(
+ OptionTable, [=](const WarningOption &O) { return O.getName() < Name; });
+ if (Found == std::end(OptionTable) || Found->getName() != Name)
+ return std::nullopt;
+ return static_cast<diag::Group>(Found - OptionTable);
+}
+
+std::optional<diag::Group> DiagnosticIDs::getGroupForDiag(unsigned DiagID) {
+ if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
+ return static_cast<diag::Group>(Info->getOptionGroupIndex());
+ return std::nullopt;
+}
+
/// getWarningOptionForDiag - Return the lowest-level warning option that
/// enables the specified diagnostic. If there is no -Wfoo flag that controls
/// the diagnostic, this returns null.
StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
- if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return OptionTable[Info->getOptionGroupIndex()].getName();
+ if (auto G = getGroupForDiag(DiagID))
+ return getWarningOptionForGroup(*G);
return StringRef();
}
std::vector<std::string> DiagnosticIDs::getDiagnosticFlags() {
- std::vector<std::string> Res;
+ std::vector<std::string> Res{"-W", "-Wno-"};
for (size_t I = 1; DiagGroupNames[I] != '\0';) {
std::string Diag(DiagGroupNames + I + 1, DiagGroupNames[I]);
I += DiagGroupNames[I] + 1;
@@ -668,12 +689,10 @@ static bool getDiagnosticsInGroup(diag::Flavor Flavor,
bool
DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
SmallVectorImpl<diag::kind> &Diags) const {
- auto Found = llvm::partition_point(
- OptionTable, [=](const WarningOption &O) { return O.getName() < Group; });
- if (Found == std::end(OptionTable) || Found->getName() != Group)
- return true; // Option not found.
-
- return ::getDiagnosticsInGroup(Flavor, Found, Diags);
+ if (std::optional<diag::Group> G = getGroupForWarningOption(Group))
+ return ::getDiagnosticsInGroup(
+ Flavor, &OptionTable[static_cast<unsigned>(*G)], Diags);
+ return true;
}
void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor,
@@ -686,7 +705,7 @@ void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor,
StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor,
StringRef Group) {
StringRef Best;
- unsigned BestDistance = Group.size() + 1; // Sanity threshold.
+ unsigned BestDistance = Group.size() + 1; // Maximum threshold.
for (const WarningOption &O : OptionTable) {
// Don't suggest ignored warning flags.
if (!O.Members && !O.SubGroups)
@@ -834,5 +853,5 @@ bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
bool DiagnosticIDs::isARCDiagnostic(unsigned DiagID) {
unsigned cat = getCategoryNumberForDiag(DiagID);
- return DiagnosticIDs::getCategoryNameFromID(cat).startswith("ARC ");
+ return DiagnosticIDs::getCategoryNameFromID(cat).starts_with("ARC ");
}
diff --git a/contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp b/contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp
index 68571f2cf94f..12e47ea0231e 100644
--- a/contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/DiagnosticOptions.cpp
@@ -17,7 +17,7 @@
namespace clang {
raw_ostream &operator<<(raw_ostream &Out, DiagnosticLevelMask M) {
- using UT = std::underlying_type<DiagnosticLevelMask>::type;
+ using UT = std::underlying_type_t<DiagnosticLevelMask>;
return Out << static_cast<UT>(M);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
index 74cd2f295be6..974c8c22598f 100644
--- a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp
@@ -31,6 +31,7 @@
#include <climits>
#include <cstdint>
#include <cstdlib>
+#include <optional>
#include <string>
#include <utility>
@@ -105,10 +106,10 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) {
return;
// Add the virtual directory to the cache.
- auto UDE = std::make_unique<DirectoryEntry>();
+ auto *UDE = new (DirsAlloc.Allocate()) DirectoryEntry();
UDE->Name = NamedDirEnt.first();
- NamedDirEnt.second = *UDE.get();
- VirtualDirectoryEntries.push_back(std::move(UDE));
+ NamedDirEnt.second = *UDE;
+ VirtualDirectoryEntries.push_back(UDE);
// Recursively add the other ancestors.
addAncestorsAsVirtualDirs(DirName);
@@ -123,16 +124,16 @@ FileManager::getDirectoryRef(StringRef DirName, bool CacheFailure) {
DirName != llvm::sys::path::root_path(DirName) &&
llvm::sys::path::is_separator(DirName.back()))
DirName = DirName.substr(0, DirName.size()-1);
-#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;
- if (DirName.size() > 1 && DirName.back() == ':' &&
- DirName.equals_insensitive(llvm::sys::path::root_name(DirName))) {
- DirNameStr = DirName.str() + '.';
- DirName = DirNameStr;
+ std::optional<std::string> DirNameStr;
+ if (is_style_windows(llvm::sys::path::Style::native)) {
+ // Fixing a problem with "clang C:test.c" on Windows.
+ // Stat("C:") does not recognize "C:" as a valid directory
+ if (DirName.size() > 1 && DirName.back() == ':' &&
+ DirName.equals_insensitive(llvm::sys::path::root_name(DirName))) {
+ DirNameStr = DirName.str() + '.';
+ DirName = *DirNameStr;
+ }
}
-#endif
++NumDirLookups;
@@ -172,14 +173,15 @@ FileManager::getDirectoryRef(StringRef DirName, bool CacheFailure) {
// same inode (this occurs on Unix-like systems when one dir is
// symlinked to another, for example) or the same path (on
// Windows).
- DirectoryEntry &UDE = UniqueRealDirs[Status.getUniqueID()];
+ DirectoryEntry *&UDE = UniqueRealDirs[Status.getUniqueID()];
- NamedDirEnt.second = UDE;
- if (UDE.getName().empty()) {
+ if (!UDE) {
// We don't have this directory yet, add it. We use the string
// key from the SeenDirEntries map as the string.
- UDE.Name = InterndDirName;
+ UDE = new (DirsAlloc.Allocate()) DirectoryEntry();
+ UDE->Name = InterndDirName;
}
+ NamedDirEnt.second = *UDE;
return DirectoryEntryRef(NamedDirEnt);
}
@@ -211,13 +213,7 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
if (!SeenFileInsertResult.first->second)
return llvm::errorCodeToError(
SeenFileInsertResult.first->second.getError());
- // Construct and return and FileEntryRef, unless it's a redirect to another
- // filename.
- FileEntryRef::MapValue Value = *SeenFileInsertResult.first->second;
- if (LLVM_LIKELY(Value.V.is<FileEntry *>()))
- return FileEntryRef(*SeenFileInsertResult.first);
- return FileEntryRef(*reinterpret_cast<const FileEntryRef::MapEntry *>(
- Value.V.get<const void *>()));
+ return FileEntryRef(*SeenFileInsertResult.first);
}
// We've not seen this before. Fill it in.
@@ -268,42 +264,77 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
// It exists. See if we have already opened a file with the same inode.
// This occurs when one dir is symlinked to another, for example.
- FileEntry &UFE = UniqueRealFiles[Status.getUniqueID()];
-
- if (Status.getName() == Filename) {
- // The name matches. Set the FileEntry.
- NamedFileEnt->second = FileEntryRef::MapValue(UFE, DirInfo);
+ FileEntry *&UFE = UniqueRealFiles[Status.getUniqueID()];
+ bool ReusingEntry = UFE != nullptr;
+ if (!UFE)
+ UFE = new (FilesAlloc.Allocate()) FileEntry();
+
+ if (!Status.ExposesExternalVFSPath || Status.getName() == Filename) {
+ // Use the requested name. Set the FileEntry.
+ NamedFileEnt->second = FileEntryRef::MapValue(*UFE, DirInfo);
} else {
// Name mismatch. We need a redirect. First grab the actual entry we want
// to return.
+ //
+ // This redirection logic intentionally leaks the external name of a
+ // redirected file that uses 'use-external-name' in \a
+ // vfs::RedirectionFileSystem. This allows clang to report the external
+ // name to users (in diagnostics) and to tools that don't have access to
+ // the VFS (in debug info and dependency '.d' files).
+ //
+ // FIXME: This is pretty complex and has some very complicated interactions
+ // with the rest of clang. It's also inconsistent with how "real"
+ // filesystems behave and confuses parts of clang expect to see the
+ // name-as-accessed on the \a FileEntryRef.
+ //
+ // A potential plan to remove this is as follows -
+ // - Update callers such as `HeaderSearch::findUsableModuleForHeader()`
+ // to explicitly use the `getNameAsRequested()` rather than just using
+ // `getName()`.
+ // - Add a `FileManager::getExternalPath` API for explicitly getting the
+ // remapped external filename when there is one available. Adopt it in
+ // callers like diagnostics/deps reporting instead of calling
+ // `getName()` directly.
+ // - Switch the meaning of `FileEntryRef::getName()` to get the requested
+ // name, not the external name. Once that sticks, revert callers that
+ // want the requested name back to calling `getName()`.
+ // - Update the VFS to always return the requested name. This could also
+ // return the external name, or just have an API to request it
+ // lazily. The latter has the benefit of making accesses of the
+ // external path easily tracked, but may also require extra work than
+ // just returning up front.
+ // - (Optionally) Add an API to VFS to get the external filename lazily
+ // and update `FileManager::getExternalPath()` to use it instead. This
+ // has the benefit of making such accesses easily tracked, though isn't
+ // necessarily required (and could cause extra work than just adding to
+ // eg. `vfs::Status` up front).
auto &Redirection =
*SeenFileEntries
- .insert({Status.getName(), FileEntryRef::MapValue(UFE, DirInfo)})
+ .insert({Status.getName(), FileEntryRef::MapValue(*UFE, DirInfo)})
.first;
assert(Redirection.second->V.is<FileEntry *>() &&
"filename redirected to a non-canonical filename?");
- assert(Redirection.second->V.get<FileEntry *>() == &UFE &&
+ assert(Redirection.second->V.get<FileEntry *>() == UFE &&
"filename from getStatValue() refers to wrong file");
// Cache the redirection in the previously-inserted entry, still available
// in the tentative return value.
- NamedFileEnt->second = FileEntryRef::MapValue(Redirection);
-
- // Fix the tentative return value.
- NamedFileEnt = &Redirection;
+ NamedFileEnt->second = FileEntryRef::MapValue(Redirection, DirInfo);
}
FileEntryRef ReturnedRef(*NamedFileEnt);
- if (UFE.isValid()) { // Already have an entry with this inode, return it.
+ if (ReusingEntry) { // Already have an entry with this inode, return it.
- // FIXME: this hack ensures that if we look up a file by a virtual path in
- // the VFS that the getDir() will have the virtual path, even if we found
- // the file by a 'real' path first. This is required in order to find a
- // module's structure when its headers/module map are mapped in the VFS.
- // We should remove this as soon as we can properly support a file having
- // multiple names.
- if (&DirInfo.getDirEntry() != UFE.Dir && Status.IsVFSMapped)
- UFE.Dir = &DirInfo.getDirEntry();
+ // FIXME: This hack ensures that `getDir()` will use the path that was
+ // used to lookup this file, even if we found a file by different path
+ // first. This is required in order to find a module's structure when its
+ // headers/module map are mapped in the VFS.
+ //
+ // See above for how this will eventually be removed. `IsVFSMapped`
+ // *cannot* be narrowed to `ExposesExternalVFSPath` as crash reproducers
+ // also depend on this logic and they have `use-external-paths: false`.
+ if (&DirInfo.getDirEntry() != UFE->Dir && Status.IsVFSMapped)
+ UFE->Dir = &DirInfo.getDirEntry();
// Always update LastRef to the last name by which a file was accessed.
// FIXME: Neither this nor always using the first reference is correct; we
@@ -312,28 +343,27 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) {
// corresponding FileEntry.
// FIXME: LastRef should be removed from FileEntry once all clients adopt
// FileEntryRef.
- UFE.LastRef = ReturnedRef;
+ UFE->LastRef = ReturnedRef;
return ReturnedRef;
}
// Otherwise, we don't have this file yet, add it.
- UFE.LastRef = ReturnedRef;
- UFE.Size = Status.getSize();
- UFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
- UFE.Dir = &DirInfo.getDirEntry();
- UFE.UID = NextFileUID++;
- UFE.UniqueID = Status.getUniqueID();
- UFE.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
- UFE.File = std::move(F);
- UFE.IsValid = true;
-
- if (UFE.File) {
- if (auto PathName = UFE.File->getName())
- fillRealPathName(&UFE, *PathName);
+ UFE->LastRef = ReturnedRef;
+ UFE->Size = Status.getSize();
+ UFE->ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
+ UFE->Dir = &DirInfo.getDirEntry();
+ UFE->UID = NextFileUID++;
+ UFE->UniqueID = Status.getUniqueID();
+ UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
+ UFE->File = std::move(F);
+
+ if (UFE->File) {
+ if (auto PathName = UFE->File->getName())
+ fillRealPathName(UFE, *PathName);
} else if (!openFile) {
// We should still fill the path even if we aren't opening the file.
- fillRealPathName(&UFE, InterndFileName);
+ fillRealPathName(UFE, InterndFileName);
}
return ReturnedRef;
}
@@ -373,8 +403,7 @@ FileEntryRef FileManager::getVirtualFileRef(StringRef Filename, off_t Size,
FileEntryRef::MapValue Value = *NamedFileEnt.second;
if (LLVM_LIKELY(Value.V.is<FileEntry *>()))
return FileEntryRef(NamedFileEnt);
- return FileEntryRef(*reinterpret_cast<const FileEntryRef::MapEntry *>(
- Value.V.get<const void *>()));
+ return FileEntryRef(*Value.V.get<const FileEntryRef::MapEntry *>());
}
// We've not seen this before, or the file is cached as non-existent.
@@ -397,52 +426,55 @@ FileEntryRef FileManager::getVirtualFileRef(StringRef Filename, off_t Size,
llvm::vfs::Status Status;
const char *InterndFileName = NamedFileEnt.first().data();
if (!getStatValue(InterndFileName, Status, true, nullptr)) {
- UFE = &UniqueRealFiles[Status.getUniqueID()];
Status = llvm::vfs::Status(
Status.getName(), Status.getUniqueID(),
llvm::sys::toTimePoint(ModificationTime),
Status.getUser(), Status.getGroup(), Size,
Status.getType(), Status.getPermissions());
- NamedFileEnt.second = FileEntryRef::MapValue(*UFE, *DirInfo);
-
- // If we had already opened this file, close it now so we don't
- // leak the descriptor. We're not going to use the file
- // descriptor anyway, since this is a virtual file.
- if (UFE->File)
- UFE->closeFile();
-
- // If we already have an entry with this inode, return it.
- //
- // FIXME: Surely this should add a reference by the new name, and return
- // it instead...
- if (UFE->isValid())
+ auto &RealFE = UniqueRealFiles[Status.getUniqueID()];
+ if (RealFE) {
+ // If we had already opened this file, close it now so we don't
+ // leak the descriptor. We're not going to use the file
+ // descriptor anyway, since this is a virtual file.
+ if (RealFE->File)
+ RealFE->closeFile();
+ // If we already have an entry with this inode, return it.
+ //
+ // FIXME: Surely this should add a reference by the new name, and return
+ // it instead...
+ NamedFileEnt.second = FileEntryRef::MapValue(*RealFE, *DirInfo);
return FileEntryRef(NamedFileEnt);
-
- UFE->UniqueID = Status.getUniqueID();
- UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
- fillRealPathName(UFE, Status.getName());
+ }
+ // File exists, but no entry - create it.
+ RealFE = new (FilesAlloc.Allocate()) FileEntry();
+ RealFE->UniqueID = Status.getUniqueID();
+ RealFE->IsNamedPipe =
+ Status.getType() == llvm::sys::fs::file_type::fifo_file;
+ fillRealPathName(RealFE, Status.getName());
+
+ UFE = RealFE;
} else {
- VirtualFileEntries.push_back(std::make_unique<FileEntry>());
- UFE = VirtualFileEntries.back().get();
- NamedFileEnt.second = FileEntryRef::MapValue(*UFE, *DirInfo);
+ // File does not exist, create a virtual entry.
+ UFE = new (FilesAlloc.Allocate()) FileEntry();
+ VirtualFileEntries.push_back(UFE);
}
+ NamedFileEnt.second = FileEntryRef::MapValue(*UFE, *DirInfo);
UFE->LastRef = FileEntryRef(NamedFileEnt);
UFE->Size = Size;
UFE->ModTime = ModificationTime;
UFE->Dir = &DirInfo->getDirEntry();
UFE->UID = NextFileUID++;
- UFE->IsValid = true;
UFE->File.reset();
return FileEntryRef(NamedFileEnt);
}
-llvm::Optional<FileEntryRef> FileManager::getBypassFile(FileEntryRef VF) {
+OptionalFileEntryRef FileManager::getBypassFile(FileEntryRef VF) {
// Stat of the file and return nullptr if it doesn't exist.
llvm::vfs::Status Status;
if (getStatValue(VF.getName(), Status, /*isFile=*/true, /*F=*/nullptr))
- return None;
+ return std::nullopt;
if (!SeenBypassFileEntries)
SeenBypassFileEntries = std::make_unique<
@@ -455,16 +487,14 @@ llvm::Optional<FileEntryRef> FileManager::getBypassFile(FileEntryRef VF) {
return FileEntryRef(*Insertion.first);
// Fill in the new entry from the stat.
- BypassFileEntries.push_back(std::make_unique<FileEntry>());
- const FileEntry &VFE = VF.getFileEntry();
- FileEntry &BFE = *BypassFileEntries.back();
- Insertion.first->second = FileEntryRef::MapValue(BFE, VF.getDir());
- BFE.LastRef = FileEntryRef(*Insertion.first);
- BFE.Size = Status.getSize();
- BFE.Dir = VFE.Dir;
- BFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
- BFE.UID = NextFileUID++;
- BFE.IsValid = true;
+ FileEntry *BFE = new (FilesAlloc.Allocate()) FileEntry();
+ BypassFileEntries.push_back(BFE);
+ Insertion.first->second = FileEntryRef::MapValue(*BFE, VF.getDir());
+ BFE->LastRef = FileEntryRef(*Insertion.first);
+ BFE->Size = Status.getSize();
+ BFE->Dir = VF.getFileEntry().Dir;
+ BFE->ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
+ BFE->UID = NextFileUID++;
// Save the entry in the bypass table and return.
return FileEntryRef(*Insertion.first);
@@ -502,12 +532,13 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
// misleading. We need to clean up the interface here.
makeAbsolutePath(AbsPath);
llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
- UFE->RealPathName = std::string(AbsPath.str());
+ UFE->RealPathName = std::string(AbsPath);
}
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
+FileManager::getBufferForFile(FileEntryRef FE, bool isVolatile,
bool RequiresNullTerminator) {
+ const FileEntry *Entry = &FE.getFileEntry();
// If the content is living on the file entry, return a reference to it.
if (Entry->Content)
return llvm::MemoryBuffer::getMemBuffer(Entry->Content->getMemBufferRef());
@@ -518,7 +549,7 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
if (isVolatile || Entry->isNamedPipe())
FileSize = -1;
- StringRef Filename = Entry->getName();
+ StringRef Filename = FE.getName();
// If the file is already open, use the open file descriptor.
if (Entry->File) {
auto Result = Entry->File->getBuffer(Filename, FileSize,
@@ -581,55 +612,66 @@ FileManager::getNoncachedStatValue(StringRef Path,
}
void FileManager::GetUniqueIDMapping(
- SmallVectorImpl<const FileEntry *> &UIDToFiles) const {
+ SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const {
UIDToFiles.clear();
UIDToFiles.resize(NextFileUID);
- // Map file entries
- for (llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>,
- llvm::BumpPtrAllocator>::const_iterator
- FE = SeenFileEntries.begin(),
- FEEnd = SeenFileEntries.end();
- FE != FEEnd; ++FE)
- if (llvm::ErrorOr<FileEntryRef::MapValue> Entry = FE->getValue()) {
- if (const auto *FE = Entry->V.dyn_cast<FileEntry *>())
- UIDToFiles[FE->getUID()] = FE;
- }
-
- // Map virtual file entries
- for (const auto &VFE : VirtualFileEntries)
- UIDToFiles[VFE->getUID()] = VFE.get();
+ for (const auto &Entry : SeenFileEntries) {
+ // Only return files that exist and are not redirected.
+ if (!Entry.getValue() || !Entry.getValue()->V.is<FileEntry *>())
+ continue;
+ FileEntryRef FE(Entry);
+ // Add this file if it's the first one with the UID, or if its name is
+ // better than the existing one.
+ OptionalFileEntryRef &ExistingFE = UIDToFiles[FE.getUID()];
+ if (!ExistingFE || FE.getName() < ExistingFE->getName())
+ ExistingFE = FE;
+ }
}
-StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) {
- llvm::DenseMap<const void *, llvm::StringRef>::iterator Known
- = CanonicalNames.find(Dir);
- if (Known != CanonicalNames.end())
- return Known->second;
-
- StringRef CanonicalName(Dir->getName());
-
- SmallString<4096> CanonicalNameBuf;
- if (!FS->getRealPath(Dir->getName(), CanonicalNameBuf))
- CanonicalName = CanonicalNameBuf.str().copy(CanonicalNameStorage);
+StringRef FileManager::getCanonicalName(DirectoryEntryRef Dir) {
+ return getCanonicalName(Dir, Dir.getName());
+}
- CanonicalNames.insert({Dir, CanonicalName});
- return CanonicalName;
+StringRef FileManager::getCanonicalName(FileEntryRef File) {
+ return getCanonicalName(File, File.getName());
}
-StringRef FileManager::getCanonicalName(const FileEntry *File) {
- llvm::DenseMap<const void *, llvm::StringRef>::iterator Known
- = CanonicalNames.find(File);
+StringRef FileManager::getCanonicalName(const void *Entry, StringRef Name) {
+ llvm::DenseMap<const void *, llvm::StringRef>::iterator Known =
+ CanonicalNames.find(Entry);
if (Known != CanonicalNames.end())
return Known->second;
- StringRef CanonicalName(File->getName());
-
- SmallString<4096> CanonicalNameBuf;
- if (!FS->getRealPath(File->getName(), CanonicalNameBuf))
- CanonicalName = CanonicalNameBuf.str().copy(CanonicalNameStorage);
+ // Name comes from FileEntry/DirectoryEntry::getName(), so it is safe to
+ // store it in the DenseMap below.
+ StringRef CanonicalName(Name);
+
+ SmallString<256> AbsPathBuf;
+ SmallString<256> RealPathBuf;
+ if (!FS->getRealPath(Name, RealPathBuf)) {
+ if (is_style_windows(llvm::sys::path::Style::native)) {
+ // For Windows paths, only use the real path if it doesn't resolve
+ // a substitute drive, as those are used to avoid MAX_PATH issues.
+ AbsPathBuf = Name;
+ if (!FS->makeAbsolute(AbsPathBuf)) {
+ if (llvm::sys::path::root_name(RealPathBuf) ==
+ llvm::sys::path::root_name(AbsPathBuf)) {
+ CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage);
+ } else {
+ // Fallback to using the absolute path.
+ // Simplifying /../ is semantically valid on Windows even in the
+ // presence of symbolic links.
+ llvm::sys::path::remove_dots(AbsPathBuf, /*remove_dot_dot=*/true);
+ CanonicalName = AbsPathBuf.str().copy(CanonicalNameStorage);
+ }
+ }
+ } else {
+ CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage);
+ }
+ }
- CanonicalNames.insert({File, CanonicalName});
+ CanonicalNames.insert({Entry, CanonicalName});
return CanonicalName;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp
index d811aeec84a0..d0d8316385b4 100644
--- a/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp
@@ -13,6 +13,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/DiagnosticLex.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
@@ -24,7 +25,6 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdio>
@@ -51,8 +51,7 @@ namespace {
/// A simple identifier lookup iterator that represents an
/// empty sequence of identifiers.
-class EmptyLookupIterator : public IdentifierIterator
-{
+class EmptyLookupIterator : public IdentifierIterator {
public:
StringRef Next() override { return StringRef(); }
};
@@ -82,7 +81,7 @@ IdentifierTable::IdentifierTable(const LangOptions &LangOpts,
// Constants for TokenKinds.def
namespace {
- enum {
+ enum TokenKey : unsigned {
KEYC99 = 0x1,
KEYCXX = 0x2,
KEYCXX11 = 0x4,
@@ -93,72 +92,158 @@ namespace {
KEYNOCXX = 0x80,
KEYBORLAND = 0x100,
KEYOPENCLC = 0x200,
- KEYC11 = 0x400,
+ KEYC23 = 0x400,
KEYNOMS18 = 0x800,
KEYNOOPENCL = 0x1000,
WCHARSUPPORT = 0x2000,
HALFSUPPORT = 0x4000,
CHAR8SUPPORT = 0x8000,
- KEYCONCEPTS = 0x10000,
- KEYOBJC = 0x20000,
- KEYZVECTOR = 0x40000,
- KEYCOROUTINES = 0x80000,
- KEYMODULES = 0x100000,
- KEYCXX20 = 0x200000,
- KEYOPENCLCXX = 0x400000,
- KEYMSCOMPAT = 0x800000,
- KEYSYCL = 0x1000000,
+ KEYOBJC = 0x10000,
+ KEYZVECTOR = 0x20000,
+ KEYCOROUTINES = 0x40000,
+ KEYMODULES = 0x80000,
+ KEYCXX20 = 0x100000,
+ KEYOPENCLCXX = 0x200000,
+ KEYMSCOMPAT = 0x400000,
+ KEYSYCL = 0x800000,
+ KEYCUDA = 0x1000000,
+ KEYHLSL = 0x2000000,
+ KEYFIXEDPOINT = 0x4000000,
+ KEYMAX = KEYFIXEDPOINT, // The maximum key
KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX20,
- KEYALL = (0x1ffffff & ~KEYNOMS18 &
- ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude.
+ KEYALL = (KEYMAX | (KEYMAX-1)) & ~KEYNOMS18 &
+ ~KEYNOOPENCL // KEYNOMS18 and KEYNOOPENCL are used to exclude.
};
- /// How a keyword is treated in the selected standard.
+ /// How a keyword is treated in the selected standard. This enum is ordered
+ /// intentionally so that the value that 'wins' is the most 'permissive'.
enum KeywordStatus {
+ KS_Unknown, // Not yet calculated. Used when figuring out the status.
KS_Disabled, // Disabled
+ KS_Future, // Is a keyword in future standard
KS_Extension, // Is an extension
KS_Enabled, // Enabled
- KS_Future // Is a keyword in future standard
};
} // namespace
+// This works on a single TokenKey flag and checks the LangOpts to get the
+// KeywordStatus based exclusively on this flag, so that it can be merged in
+// getKeywordStatus. Most should be enabled/disabled, but some might imply
+// 'future' versions, or extensions. Returns 'unknown' unless this is KNOWN to
+// be disabled, and the calling function makes it 'disabled' if no other flag
+// changes it. This is necessary for the KEYNOCXX and KEYNOOPENCL flags.
+static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts,
+ TokenKey Flag) {
+ // Flag is a single bit version of TokenKey (that is, not
+ // KEYALL/KEYALLCXX/etc), so we can check with == throughout this function.
+ assert((Flag & ~(Flag - 1)) == Flag && "Multiple bits set?");
+
+ switch (Flag) {
+ case KEYC99:
+ if (LangOpts.C99)
+ return KS_Enabled;
+ return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
+ case KEYC23:
+ if (LangOpts.C23)
+ return KS_Enabled;
+ return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
+ case KEYCXX:
+ return LangOpts.CPlusPlus ? KS_Enabled : KS_Unknown;
+ case KEYCXX11:
+ if (LangOpts.CPlusPlus11)
+ return KS_Enabled;
+ return LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
+ case KEYCXX20:
+ if (LangOpts.CPlusPlus20)
+ return KS_Enabled;
+ return LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
+ case KEYGNU:
+ return LangOpts.GNUKeywords ? KS_Extension : KS_Unknown;
+ case KEYMS:
+ return LangOpts.MicrosoftExt ? KS_Extension : KS_Unknown;
+ case BOOLSUPPORT:
+ if (LangOpts.Bool) return KS_Enabled;
+ return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
+ case KEYALTIVEC:
+ return LangOpts.AltiVec ? KS_Enabled : KS_Unknown;
+ case KEYBORLAND:
+ return LangOpts.Borland ? KS_Extension : KS_Unknown;
+ case KEYOPENCLC:
+ return LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus ? KS_Enabled
+ : KS_Unknown;
+ case WCHARSUPPORT:
+ return LangOpts.WChar ? KS_Enabled : KS_Unknown;
+ case HALFSUPPORT:
+ return LangOpts.Half ? KS_Enabled : KS_Unknown;
+ case CHAR8SUPPORT:
+ if (LangOpts.Char8) return KS_Enabled;
+ if (LangOpts.CPlusPlus20) return KS_Unknown;
+ if (LangOpts.CPlusPlus) return KS_Future;
+ return KS_Unknown;
+ case KEYOBJC:
+ // We treat bridge casts as objective-C keywords so we can warn on them
+ // in non-arc mode.
+ return LangOpts.ObjC ? KS_Enabled : KS_Unknown;
+ case KEYZVECTOR:
+ return LangOpts.ZVector ? KS_Enabled : KS_Unknown;
+ case KEYCOROUTINES:
+ return LangOpts.Coroutines ? KS_Enabled : KS_Unknown;
+ case KEYMODULES:
+ return KS_Unknown;
+ case KEYOPENCLCXX:
+ return LangOpts.OpenCLCPlusPlus ? KS_Enabled : KS_Unknown;
+ case KEYMSCOMPAT:
+ return LangOpts.MSVCCompat ? KS_Enabled : KS_Unknown;
+ case KEYSYCL:
+ return LangOpts.isSYCL() ? KS_Enabled : KS_Unknown;
+ case KEYCUDA:
+ return LangOpts.CUDA ? KS_Enabled : KS_Unknown;
+ case KEYHLSL:
+ return LangOpts.HLSL ? KS_Enabled : KS_Unknown;
+ case KEYNOCXX:
+ // This is enabled in all non-C++ modes, but might be enabled for other
+ // reasons as well.
+ return LangOpts.CPlusPlus ? KS_Unknown : KS_Enabled;
+ case KEYNOOPENCL:
+ // The disable behavior for this is handled in getKeywordStatus.
+ return KS_Unknown;
+ case KEYNOMS18:
+ // The disable behavior for this is handled in getKeywordStatus.
+ return KS_Unknown;
+ case KEYFIXEDPOINT:
+ return LangOpts.FixedPoint ? KS_Enabled : KS_Disabled;
+ default:
+ llvm_unreachable("Unknown KeywordStatus flag");
+ }
+}
+
/// Translates flags as specified in TokenKinds.def into keyword status
/// in the given language standard.
static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
unsigned Flags) {
+ // KEYALL means always enabled, so special case this one.
if (Flags == KEYALL) return KS_Enabled;
- if (LangOpts.CPlusPlus && (Flags & KEYCXX)) return KS_Enabled;
- if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) return KS_Enabled;
- if (LangOpts.CPlusPlus20 && (Flags & KEYCXX20)) return KS_Enabled;
- if (LangOpts.C99 && (Flags & KEYC99)) return KS_Enabled;
- if (LangOpts.GNUKeywords && (Flags & KEYGNU)) return KS_Extension;
- if (LangOpts.MicrosoftExt && (Flags & KEYMS)) return KS_Extension;
- if (LangOpts.MSVCCompat && (Flags & KEYMSCOMPAT)) return KS_Enabled;
- if (LangOpts.Borland && (Flags & KEYBORLAND)) return KS_Extension;
- 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.ZVector && (Flags & KEYZVECTOR)) 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
- // in non-arc mode.
- if (LangOpts.ObjC && (Flags & KEYOBJC)) return KS_Enabled;
- if (LangOpts.CPlusPlus20 && (Flags & KEYCONCEPTS)) return KS_Enabled;
- if (LangOpts.Coroutines && (Flags & KEYCOROUTINES)) return KS_Enabled;
- if (LangOpts.ModulesTS && (Flags & KEYMODULES)) return KS_Enabled;
- if (LangOpts.CPlusPlus && (Flags & KEYALLCXX)) return KS_Future;
- if (LangOpts.CPlusPlus && !LangOpts.CPlusPlus20 && (Flags & CHAR8SUPPORT))
- return KS_Future;
- if (LangOpts.isSYCL() && (Flags & KEYSYCL))
- return KS_Enabled;
- return KS_Disabled;
+ // These are tests that need to 'always win', as they are special in that they
+ // disable based on certain conditions.
+ if (LangOpts.OpenCL && (Flags & KEYNOOPENCL)) return KS_Disabled;
+ if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
+ !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
+ return KS_Disabled;
+
+ KeywordStatus CurStatus = KS_Unknown;
+
+ while (Flags != 0) {
+ unsigned CurFlag = Flags & ~(Flags - 1);
+ Flags = Flags & ~CurFlag;
+ CurStatus = std::max(
+ CurStatus,
+ getKeywordStatusHelper(LangOpts, static_cast<TokenKey>(CurFlag)));
+ }
+
+ if (CurStatus == KS_Unknown)
+ return KS_Disabled;
+ return CurStatus;
}
/// AddKeyword - This method is used to associate a token ID with specific
@@ -169,15 +254,6 @@ static void AddKeyword(StringRef Keyword,
const LangOptions &LangOpts, IdentifierTable &Table) {
KeywordStatus AddResult = getKeywordStatus(LangOpts, Flags);
- // Don't add this keyword under MSVCCompat.
- if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
- !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
- return;
-
- // Don't add this keyword under OpenCL.
- if (LangOpts.OpenCL && (Flags & KEYNOOPENCL))
- return;
-
// Don't add this keyword if disabled in this language.
if (AddResult == KS_Disabled) return;
@@ -204,6 +280,16 @@ static void AddObjCKeyword(StringRef Name,
Table.get(Name).setObjCKeywordID(ObjCID);
}
+static void AddInterestingIdentifier(StringRef Name,
+ tok::InterestingIdentifierKind BTID,
+ IdentifierTable &Table) {
+ // Don't add 'not_interesting' identifier.
+ if (BTID != tok::not_interesting) {
+ IdentifierInfo &Info = Table.get(Name, tok::identifier);
+ Info.setInterestingIdentifierID(BTID);
+ }
+}
+
/// AddKeywords - Add all keywords to the symbol table.
///
void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
@@ -220,6 +306,9 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
#define OBJC_AT_KEYWORD(NAME) \
if (LangOpts.ObjC) \
AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
+#define INTERESTING_IDENTIFIER(NAME) \
+ AddInterestingIdentifier(StringRef(#NAME), tok::NAME, *this);
+
#define TESTING_KEYWORD(NAME, FLAGS)
#include "clang/Basic/TokenKinds.def"
@@ -309,6 +398,27 @@ IdentifierInfo::isReserved(const LangOptions &LangOpts) const {
return ReservedIdentifierStatus::NotReserved;
}
+ReservedLiteralSuffixIdStatus
+IdentifierInfo::isReservedLiteralSuffixId() const {
+ StringRef Name = getName();
+
+ if (Name[0] != '_')
+ return ReservedLiteralSuffixIdStatus::NotStartsWithUnderscore;
+
+ if (Name.contains("__"))
+ return ReservedLiteralSuffixIdStatus::ContainsDoubleUnderscore;
+
+ return ReservedLiteralSuffixIdStatus::NotReserved;
+}
+
+StringRef IdentifierInfo::deuglifiedName() const {
+ StringRef Name = getName();
+ if (Name.size() >= 2 && Name.front() == '_' &&
+ (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
+ return Name.ltrim('_');
+ return Name;
+}
+
tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
// We use a perfect hash function here involving the length of the keyword,
// the first and third character. For preprocessor ID's there are no
@@ -405,63 +515,6 @@ unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) {
return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr());
}
-namespace clang {
-
-/// One of these variable length records is kept for each
-/// selector containing more than one keyword. We use a folding set
-/// to unique aggregate names (keyword selectors in ObjC parlance). Access to
-/// this class is provided strictly through Selector.
-class alignas(IdentifierInfoAlignment) MultiKeywordSelector
- : public detail::DeclarationNameExtra,
- public llvm::FoldingSetNode {
- MultiKeywordSelector(unsigned nKeys) : DeclarationNameExtra(nKeys) {}
-
-public:
- // Constructor for keyword selectors.
- MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV)
- : DeclarationNameExtra(nKeys) {
- assert((nKeys > 1) && "not a multi-keyword selector");
-
- // Fill in the trailing keyword array.
- IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this + 1);
- for (unsigned i = 0; i != nKeys; ++i)
- KeyInfo[i] = IIV[i];
- }
-
- // getName - Derive the full selector name and return it.
- std::string getName() const;
-
- using DeclarationNameExtra::getNumArgs;
-
- using keyword_iterator = IdentifierInfo *const *;
-
- keyword_iterator keyword_begin() const {
- return reinterpret_cast<keyword_iterator>(this + 1);
- }
-
- keyword_iterator keyword_end() const {
- return keyword_begin() + getNumArgs();
- }
-
- IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
- assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
- return keyword_begin()[i];
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys,
- unsigned NumArgs) {
- ID.AddInteger(NumArgs);
- for (unsigned i = 0; i != NumArgs; ++i)
- ID.AddPointer(ArgTys[i]);
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, keyword_begin(), getNumArgs());
- }
-};
-
-} // namespace clang.
-
bool Selector::isKeywordSelector(ArrayRef<StringRef> Names) const {
assert(!Names.empty() && "must have >= 1 selector slots");
if (getNumArgs() != Names.size())
@@ -517,7 +570,7 @@ std::string MultiKeywordSelector::getName() const {
}
std::string Selector::getAsString() const {
- if (InfoPtr == 0)
+ if (isNull())
return "<null selector>";
if (getIdentifierInfoFlag() < MultiArg) {
@@ -551,7 +604,7 @@ LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); }
static bool startsWithWord(StringRef name, StringRef word) {
if (name.size() < word.size()) return false;
return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
- name.startswith(word));
+ name.starts_with(word));
}
ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
@@ -575,8 +628,7 @@ ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
return OMF_performSelector;
// The other method families may begin with a prefix of underscores.
- while (!name.empty() && name.front() == '_')
- name = name.substr(1);
+ name = name.ltrim('_');
if (name.empty()) return OMF_None;
switch (name.front()) {
@@ -689,7 +741,7 @@ SelectorTable::constructSetterSelector(IdentifierTable &Idents,
std::string SelectorTable::getPropertyNameFromSetterSelector(Selector Sel) {
StringRef Name = Sel.getNameForSlot(0);
- assert(Name.startswith("set") && "invalid setter name");
+ assert(Name.starts_with("set") && "invalid setter name");
return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();
}
@@ -765,3 +817,50 @@ StringRef clang::getNullabilitySpelling(NullabilityKind kind,
}
llvm_unreachable("Unknown nullability kind.");
}
+
+llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
+ NullabilityKind NK) {
+ switch (NK) {
+ case NullabilityKind::NonNull:
+ return OS << "NonNull";
+ case NullabilityKind::Nullable:
+ return OS << "Nullable";
+ case NullabilityKind::NullableResult:
+ return OS << "NullableResult";
+ case NullabilityKind::Unspecified:
+ return OS << "Unspecified";
+ }
+ llvm_unreachable("Unknown nullability kind.");
+}
+
+diag::kind
+IdentifierTable::getFutureCompatDiagKind(const IdentifierInfo &II,
+ const LangOptions &LangOpts) {
+ assert(II.isFutureCompatKeyword() && "diagnostic should not be needed");
+
+ unsigned Flags = llvm::StringSwitch<unsigned>(II.getName())
+#define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)
+#include "clang/Basic/TokenKinds.def"
+#undef KEYWORD
+ ;
+
+ if (LangOpts.CPlusPlus) {
+ if ((Flags & KEYCXX11) == KEYCXX11)
+ return diag::warn_cxx11_keyword;
+
+ // char8_t is not modeled as a CXX20_KEYWORD because it's not
+ // unconditionally enabled in C++20 mode. (It can be disabled
+ // by -fno-char8_t.)
+ if (((Flags & KEYCXX20) == KEYCXX20) ||
+ ((Flags & CHAR8SUPPORT) == CHAR8SUPPORT))
+ return diag::warn_cxx20_keyword;
+ } else {
+ if ((Flags & KEYC99) == KEYC99)
+ return diag::warn_c99_keyword;
+ if ((Flags & KEYC23) == KEYC23)
+ return diag::warn_c23_keyword;
+ }
+
+ llvm_unreachable(
+ "Keyword not known to come from a newer Standard or proposed Standard");
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/LangOptions.cpp b/contrib/llvm-project/clang/lib/Basic/LangOptions.cpp
index bebf3178426f..a0adfbf61840 100644
--- a/contrib/llvm-project/clang/lib/Basic/LangOptions.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/LangOptions.cpp
@@ -29,6 +29,14 @@ void LangOptions::resetNonModularOptions() {
Name = static_cast<unsigned>(Default);
#include "clang/Basic/LangOptions.def"
+ // Reset "benign" options with implied values (Options.td ImpliedBy relations)
+ // rather than their defaults. This avoids unexpected combinations and
+ // invocations that cannot be round-tripped to arguments.
+ // FIXME: we should derive this automatically from ImpliedBy in tablegen.
+ AllowFPReassoc = UnsafeFPMath;
+ NoHonorNaNs = FiniteMathOnly;
+ NoHonorInfs = FiniteMathOnly;
+
// These options do not affect AST generation.
NoSanitizeFiles.clear();
XRayAlwaysInstrumentFiles.clear();
@@ -47,20 +55,173 @@ bool LangOptions::isNoBuiltinFunc(StringRef FuncName) const {
VersionTuple LangOptions::getOpenCLVersionTuple() const {
const int Ver = OpenCLCPlusPlus ? OpenCLCPlusPlusVersion : OpenCLVersion;
+ if (OpenCLCPlusPlus && Ver != 100)
+ return VersionTuple(Ver / 100);
return VersionTuple(Ver / 100, (Ver % 100) / 10);
}
-void LangOptions::remapPathPrefix(SmallString<256> &Path) const {
+unsigned LangOptions::getOpenCLCompatibleVersion() const {
+ if (!OpenCLCPlusPlus)
+ return OpenCLVersion;
+ if (OpenCLCPlusPlusVersion == 100)
+ return 200;
+ if (OpenCLCPlusPlusVersion == 202100)
+ return 300;
+ llvm_unreachable("Unknown OpenCL version");
+}
+
+void LangOptions::remapPathPrefix(SmallVectorImpl<char> &Path) const {
for (const auto &Entry : MacroPrefixMap)
if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second))
break;
}
+std::string LangOptions::getOpenCLVersionString() const {
+ std::string Result;
+ {
+ llvm::raw_string_ostream Out(Result);
+ Out << (OpenCLCPlusPlus ? "C++ for OpenCL" : "OpenCL C") << " version "
+ << getOpenCLVersionTuple().getAsString();
+ }
+ return Result;
+}
+
+void LangOptions::setLangDefaults(LangOptions &Opts, Language Lang,
+ const llvm::Triple &T,
+ std::vector<std::string> &Includes,
+ LangStandard::Kind LangStd) {
+ // Set some properties which depend solely on the input kind; it would be nice
+ // to move these to the language standard, and have the driver resolve the
+ // input kind + language standard.
+ //
+ // FIXME: Perhaps a better model would be for a single source file to have
+ // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std)
+ // simultaneously active?
+ if (Lang == Language::Asm) {
+ Opts.AsmPreprocessor = 1;
+ } else if (Lang == Language::ObjC || Lang == Language::ObjCXX) {
+ Opts.ObjC = 1;
+ }
+
+ if (LangStd == LangStandard::lang_unspecified)
+ LangStd = getDefaultLanguageStandard(Lang, T);
+ const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
+ Opts.LangStd = LangStd;
+ Opts.LineComment = Std.hasLineComments();
+ Opts.C99 = Std.isC99();
+ Opts.C11 = Std.isC11();
+ Opts.C17 = Std.isC17();
+ Opts.C23 = Std.isC23();
+ Opts.CPlusPlus = Std.isCPlusPlus();
+ Opts.CPlusPlus11 = Std.isCPlusPlus11();
+ Opts.CPlusPlus14 = Std.isCPlusPlus14();
+ Opts.CPlusPlus17 = Std.isCPlusPlus17();
+ Opts.CPlusPlus20 = Std.isCPlusPlus20();
+ Opts.CPlusPlus23 = Std.isCPlusPlus23();
+ Opts.CPlusPlus26 = Std.isCPlusPlus26();
+ Opts.GNUMode = Std.isGNUMode();
+ Opts.GNUCVersion = 0;
+ Opts.HexFloats = Std.hasHexFloats();
+ Opts.WChar = Std.isCPlusPlus();
+ Opts.Digraphs = Std.hasDigraphs();
+
+ Opts.HLSL = Lang == Language::HLSL;
+ if (Opts.HLSL && Opts.IncludeDefaultHeader)
+ Includes.push_back("hlsl.h");
+
+ // Set OpenCL Version.
+ Opts.OpenCL = Std.isOpenCL();
+ if (LangStd == LangStandard::lang_opencl10)
+ Opts.OpenCLVersion = 100;
+ else if (LangStd == LangStandard::lang_opencl11)
+ Opts.OpenCLVersion = 110;
+ else if (LangStd == LangStandard::lang_opencl12)
+ Opts.OpenCLVersion = 120;
+ else if (LangStd == LangStandard::lang_opencl20)
+ Opts.OpenCLVersion = 200;
+ else if (LangStd == LangStandard::lang_opencl30)
+ Opts.OpenCLVersion = 300;
+ else if (LangStd == LangStandard::lang_openclcpp10)
+ Opts.OpenCLCPlusPlusVersion = 100;
+ else if (LangStd == LangStandard::lang_openclcpp2021)
+ Opts.OpenCLCPlusPlusVersion = 202100;
+ else if (LangStd == LangStandard::lang_hlsl2015)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2015;
+ else if (LangStd == LangStandard::lang_hlsl2016)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2016;
+ else if (LangStd == LangStandard::lang_hlsl2017)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2017;
+ else if (LangStd == LangStandard::lang_hlsl2018)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2018;
+ else if (LangStd == LangStandard::lang_hlsl2021)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2021;
+ else if (LangStd == LangStandard::lang_hlsl202x)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_202x;
+
+ // OpenCL has some additional defaults.
+ if (Opts.OpenCL) {
+ Opts.AltiVec = 0;
+ Opts.ZVector = 0;
+ Opts.setDefaultFPContractMode(LangOptions::FPM_On);
+ Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
+ Opts.OpenCLPipes = Opts.getOpenCLCompatibleVersion() == 200;
+ Opts.OpenCLGenericAddressSpace = Opts.getOpenCLCompatibleVersion() == 200;
+
+ // Include default header file for OpenCL.
+ if (Opts.IncludeDefaultHeader) {
+ if (Opts.DeclareOpenCLBuiltins) {
+ // Only include base header file for builtin types and constants.
+ Includes.push_back("opencl-c-base.h");
+ } else {
+ Includes.push_back("opencl-c.h");
+ }
+ }
+ }
+
+ Opts.HIP = Lang == Language::HIP;
+ Opts.CUDA = Lang == Language::CUDA || Opts.HIP;
+ if (Opts.HIP) {
+ // HIP toolchain does not support 'Fast' FPOpFusion in backends since it
+ // fuses multiplication/addition instructions without contract flag from
+ // device library functions in LLVM bitcode, which causes accuracy loss in
+ // certain math functions, e.g. tan(-1e20) becomes -0.933 instead of 0.8446.
+ // For device library functions in bitcode to work, 'Strict' or 'Standard'
+ // FPOpFusion options in backends is needed. Therefore 'fast-honor-pragmas'
+ // FP contract option is used to allow fuse across statements in frontend
+ // whereas respecting contract flag in backend.
+ Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
+ } else if (Opts.CUDA) {
+ if (T.isSPIRV()) {
+ // Emit OpenCL version metadata in LLVM IR when targeting SPIR-V.
+ Opts.OpenCLVersion = 200;
+ }
+ // Allow fuse across statements disregarding pragmas.
+ Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
+ }
+
+ Opts.RenderScript = Lang == Language::RenderScript;
+
+ // OpenCL, C++ and C23 have bool, true, false keywords.
+ Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C23;
+
+ // OpenCL and HLSL have half keyword
+ Opts.Half = Opts.OpenCL || Opts.HLSL;
+}
+
FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) {
FPOptions result(LO);
return result;
}
+FPOptionsOverride FPOptions::getChangesSlow(const FPOptions &Base) const {
+ FPOptions::storage_type OverrideMask = 0;
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
+ if (get##NAME() != Base.get##NAME()) \
+ OverrideMask |= NAME##Mask;
+#include "clang/Basic/FPOptions.def"
+ return FPOptionsOverride(*this, OverrideMask);
+}
+
LLVM_DUMP_METHOD void FPOptions::dump() {
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
llvm::errs() << "\n " #NAME " " << get##NAME();
diff --git a/contrib/llvm-project/clang/lib/Basic/LangStandards.cpp b/contrib/llvm-project/clang/lib/Basic/LangStandards.cpp
index ee27bfd12113..ab09c7221dda 100644
--- a/contrib/llvm-project/clang/lib/Basic/LangStandards.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/LangStandards.cpp
@@ -7,10 +7,45 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/LangStandard.h"
+#include "clang/Config/config.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/TargetParser/Triple.h"
using namespace clang;
+StringRef clang::languageToString(Language L) {
+ switch (L) {
+ case Language::Unknown:
+ return "Unknown";
+ case Language::Asm:
+ return "Asm";
+ case Language::LLVM_IR:
+ return "LLVM IR";
+ case Language::C:
+ return "C";
+ case Language::CXX:
+ return "C++";
+ case Language::ObjC:
+ return "Objective-C";
+ case Language::ObjCXX:
+ return "Objective-C++";
+ case Language::OpenCL:
+ return "OpenCL";
+ case Language::OpenCLCXX:
+ return "OpenCLC++";
+ case Language::CUDA:
+ return "CUDA";
+ case Language::RenderScript:
+ return "RenderScript";
+ case Language::HIP:
+ return "HIP";
+ case Language::HLSL:
+ return "HLSL";
+ }
+
+ llvm_unreachable("unhandled language kind");
+}
+
#define LANGSTANDARD(id, name, lang, desc, features) \
static const LangStandard Lang_##id = {name, desc, features, Language::lang};
#include "clang/Basic/LangStandards.def"
@@ -42,4 +77,33 @@ const LangStandard *LangStandard::getLangStandardForName(StringRef Name) {
return &getLangStandardForKind(K);
}
-
+LangStandard::Kind clang::getDefaultLanguageStandard(clang::Language Lang,
+ const llvm::Triple &T) {
+ switch (Lang) {
+ case Language::Unknown:
+ case Language::LLVM_IR:
+ llvm_unreachable("Invalid input kind!");
+ case Language::OpenCL:
+ return LangStandard::lang_opencl12;
+ case Language::OpenCLCXX:
+ return LangStandard::lang_openclcpp10;
+ case Language::Asm:
+ case Language::C:
+ // The PS4 uses C99 as the default C standard.
+ if (T.isPS4())
+ return LangStandard::lang_gnu99;
+ return LangStandard::lang_gnu17;
+ case Language::ObjC:
+ return LangStandard::lang_gnu11;
+ case Language::CXX:
+ case Language::ObjCXX:
+ case Language::CUDA:
+ case Language::HIP:
+ return LangStandard::lang_gnucxx17;
+ case Language::RenderScript:
+ return LangStandard::lang_c99;
+ case Language::HLSL:
+ return LangStandard::lang_hlsl2021;
+ }
+ llvm_unreachable("unhandled Language kind!");
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/MakeSupport.cpp b/contrib/llvm-project/clang/lib/Basic/MakeSupport.cpp
new file mode 100644
index 000000000000..4ddfcc350410
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/MakeSupport.cpp
@@ -0,0 +1,35 @@
+//===-- MakeSuport.cpp --------------------------------------------------*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/MakeSupport.h"
+
+void clang::quoteMakeTarget(StringRef Target, SmallVectorImpl<char> &Res) {
+ for (unsigned i = 0, e = Target.size(); i != e; ++i) {
+ switch (Target[i]) {
+ case ' ':
+ case '\t':
+ // Escape the preceding backslashes
+ for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
+ Res.push_back('\\');
+
+ // Escape the space/tab
+ Res.push_back('\\');
+ break;
+ case '$':
+ Res.push_back('$');
+ break;
+ case '#':
+ Res.push_back('\\');
+ break;
+ default:
+ break;
+ }
+
+ Res.push_back(Target[i]);
+ }
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Module.cpp b/contrib/llvm-project/clang/lib/Basic/Module.cpp
index b6cf1624ef01..0dac8748a98a 100644
--- a/contrib/llvm-project/clang/lib/Basic/Module.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Module.cpp
@@ -44,7 +44,7 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
InferSubmodules(false), InferExplicitSubmodules(false),
InferExportWildcard(false), ConfigMacrosExhaustive(false),
NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
- NameVisibility(Hidden) {
+ NamedModuleHasInit(true), NameVisibility(Hidden) {
if (Parent) {
IsAvailable = Parent->isAvailable();
IsUnimportable = Parent->isUnimportable();
@@ -59,9 +59,8 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
}
Module::~Module() {
- for (submodule_iterator I = submodule_begin(), IEnd = submodule_end();
- I != IEnd; ++I) {
- delete *I;
+ for (auto *Submodule : SubModules) {
+ delete Submodule;
}
}
@@ -90,7 +89,7 @@ static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
// where both are valid examples of the same platform+environment but in the
// variant (2) the simulator is hardcoded as part of the platform name. Both
// forms above should match for "iossimulator" requirement.
- if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator"))
+ if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with("simulator"))
return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
return PlatformEnv == Feature;
@@ -108,9 +107,13 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
.Case("cplusplus11", LangOpts.CPlusPlus11)
.Case("cplusplus14", LangOpts.CPlusPlus14)
.Case("cplusplus17", LangOpts.CPlusPlus17)
+ .Case("cplusplus20", LangOpts.CPlusPlus20)
+ .Case("cplusplus23", LangOpts.CPlusPlus23)
+ .Case("cplusplus26", LangOpts.CPlusPlus26)
.Case("c99", LangOpts.C99)
.Case("c11", LangOpts.C11)
.Case("c17", LangOpts.C17)
+ .Case("c23", LangOpts.C23)
.Case("freestanding", LangOpts.Freestanding)
.Case("gnuinlineasm", LangOpts.GNUAsm)
.Case("objc", LangOpts.ObjC)
@@ -121,9 +124,7 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
.Default(Target.hasFeature(Feature) ||
isPlatformEnvironment(Target, Feature));
if (!HasFeature)
- HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
- LangOpts.ModuleFeatures.end(),
- Feature) != LangOpts.ModuleFeatures.end();
+ HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature);
return HasFeature;
}
@@ -150,6 +151,28 @@ bool Module::isUnimportable(const LangOptions &LangOpts,
llvm_unreachable("could not find a reason why module is unimportable");
}
+// The -fmodule-name option tells the compiler to textually include headers in
+// the specified module, meaning Clang won't build the specified module. This
+// is useful in a number of situations, for instance, when building a library
+// that vends a module map, one might want to avoid hitting intermediate build
+// products containing the module map or avoid finding the system installed
+// modulemap for that library.
+bool Module::isForBuilding(const LangOptions &LangOpts) const {
+ StringRef TopLevelName = getTopLevelModuleName();
+ StringRef CurrentModule = LangOpts.CurrentModule;
+
+ // When building the implementation of framework Foo, we want to make sure
+ // that Foo *and* Foo_Private are textually included and no modules are built
+ // for either.
+ if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework &&
+ CurrentModule == LangOpts.ModuleName &&
+ !CurrentModule.ends_with("_Private") &&
+ TopLevelName.ends_with("_Private"))
+ TopLevelName = TopLevelName.drop_back(8);
+
+ return TopLevelName == CurrentModule;
+}
+
bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
Requirement &Req,
UnresolvedHeaderDirective &MissingHeader,
@@ -203,7 +226,7 @@ static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
OS << ".";
StringRef Name = getModuleNameFromComponent(*It);
- if (!AllowStringLiterals || isValidIdentifier(Name))
+ if (!AllowStringLiterals || isValidAsciiIdentifier(Name))
OS << Name;
else {
OS << '"';
@@ -243,33 +266,31 @@ bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
return nameParts.empty();
}
-Module::DirectoryName Module::getUmbrellaDir() const {
- if (Header U = getUmbrellaHeader())
- return {"", "", U.Entry->getDir()};
-
- return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory,
- Umbrella.dyn_cast<const DirectoryEntry *>()};
+OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
+ if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
+ return Hdr->getDir();
+ if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
+ return *Dir;
+ return std::nullopt;
}
-void Module::addTopHeader(const FileEntry *File) {
+void Module::addTopHeader(FileEntryRef File) {
assert(File);
TopHeaders.insert(File);
}
-ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) {
+ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
if (!TopHeaderNames.empty()) {
- for (std::vector<std::string>::iterator
- I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
- if (auto FE = FileMgr.getFile(*I))
+ for (StringRef TopHeaderName : TopHeaderNames)
+ if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName))
TopHeaders.insert(*FE);
- }
TopHeaderNames.clear();
}
- return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
+ return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
}
-bool Module::directlyUses(const Module *Requested) const {
+bool Module::directlyUses(const Module *Requested) {
auto *Top = getTopLevelModule();
// A top-level module implicitly uses itself.
@@ -280,10 +301,14 @@ bool Module::directlyUses(const Module *Requested) const {
if (Requested->isSubModuleOf(Use))
return true;
- // Anyone is allowed to use our builtin stddef.h and its accompanying module.
- if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t")
+ // Anyone is allowed to use our builtin stddef.h and its accompanying modules.
+ if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
+ Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
return true;
+ if (NoUndeclaredIncludes)
+ UndeclaredUses.insert(Requested);
+
return false;
}
@@ -318,11 +343,9 @@ void Module::markUnavailable(bool Unimportable) {
Current->IsAvailable = false;
Current->IsUnimportable |= Unimportable;
- for (submodule_iterator Sub = Current->submodule_begin(),
- SubEnd = Current->submodule_end();
- Sub != SubEnd; ++Sub) {
- if (needUpdate(*Sub))
- Stack.push_back(*Sub);
+ for (auto *Submodule : Current->submodules()) {
+ if (needUpdate(Submodule))
+ Stack.push_back(Submodule);
}
}
}
@@ -350,6 +373,28 @@ Module *Module::findOrInferSubmodule(StringRef Name) {
return Result;
}
+Module *Module::getGlobalModuleFragment() const {
+ assert(isNamedModuleUnit() && "We should only query the global module "
+ "fragment from the C++ 20 Named modules");
+
+ for (auto *SubModule : SubModules)
+ if (SubModule->isExplicitGlobalModule())
+ return SubModule;
+
+ return nullptr;
+}
+
+Module *Module::getPrivateModuleFragment() const {
+ assert(isNamedModuleUnit() && "We should only query the private module "
+ "fragment from the C++ 20 Named modules");
+
+ for (auto *SubModule : SubModules)
+ if (SubModule->isPrivateModule())
+ return SubModule;
+
+ return nullptr;
+}
+
void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
// All non-explicit submodules are exported.
for (std::vector<Module *>::const_iterator I = SubModules.begin(),
@@ -462,15 +507,15 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
OS << "\n";
}
- if (Header H = getUmbrellaHeader()) {
+ if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) {
OS.indent(Indent + 2);
OS << "umbrella header \"";
- OS.write_escaped(H.NameAsWritten);
+ OS.write_escaped(H->NameAsWritten);
OS << "\"\n";
- } else if (DirectoryName D = getUmbrellaDir()) {
+ } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
OS.indent(Indent + 2);
OS << "umbrella \"";
- OS.write_escaped(D.NameAsWritten);
+ OS.write_escaped(D->NameAsWritten);
OS << "\"\n";
}
@@ -502,8 +547,8 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
OS.indent(Indent + 2);
OS << K.Prefix << "header \"";
OS.write_escaped(H.NameAsWritten);
- OS << "\" { size " << H.Entry->getSize()
- << " mtime " << H.Entry->getModificationTime() << " }\n";
+ OS << "\" { size " << H.Entry.getSize()
+ << " mtime " << H.Entry.getModificationTime() << " }\n";
}
}
for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
@@ -529,14 +574,13 @@ void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
OS << "export_as" << ExportAsModule << "\n";
}
- for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
- MI != MIEnd; ++MI)
+ for (auto *Submodule : submodules())
// Print inferred subframework modules so that we don't need to re-infer
// them (requires expensive directory iteration + stat calls) when we build
// the module. Regular inferred submodules are OK, as we need to look at all
// those header files anyway.
- if (!(*MI)->IsInferred || (*MI)->IsFramework)
- (*MI)->print(OS, Indent + 2, Dump);
+ if (!Submodule->IsInferred || Submodule->IsFramework)
+ Submodule->print(OS, Indent + 2, Dump);
for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
OS.indent(Indent + 2);
@@ -632,7 +676,9 @@ LLVM_DUMP_METHOD void Module::dump() const {
void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
VisibleCallback Vis, ConflictCallback Cb) {
- assert(Loc.isValid() && "setVisible expects a valid import location");
+ // We can't import a global module fragment so the location can be invalid.
+ assert((M->isGlobalModule() || Loc.isValid()) &&
+ "setVisible expects a valid import location");
if (isVisible(M))
return;
@@ -652,7 +698,7 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
return;
ImportLocs[ID] = Loc;
- Vis(M);
+ Vis(V.M);
// Make any exported modules visible.
SmallVector<Module *, 16> Exports;
@@ -675,6 +721,14 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
VisitModule({M, nullptr});
}
+void VisibleModuleSet::makeTransitiveImportsVisible(Module *M,
+ SourceLocation Loc,
+ VisibleCallback Vis,
+ ConflictCallback Cb) {
+ for (auto *I : M->Imports)
+ setVisible(I, Loc, Vis, Cb);
+}
+
ASTSourceDescriptor::ASTSourceDescriptor(Module &M)
: Signature(M.Signature), ClangModule(&M) {
if (M.Directory)
diff --git a/contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp b/contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp
index 3efd613b0d33..e7e63c1f419e 100644
--- a/contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/NoSanitizeList.cpp
@@ -47,6 +47,11 @@ bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName,
return SSCL->inSection(Mask, "src", FileName, Category);
}
+bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName,
+ StringRef Category) const {
+ return SSCL->inSection(Mask, "mainfile", FileName, Category);
+}
+
bool NoSanitizeList::containsLocation(SanitizerMask Mask, SourceLocation Loc,
StringRef Category) const {
return Loc.isValid() &&
diff --git a/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp b/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp
index b7408f39bdab..d39686ea688e 100644
--- a/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/OpenCLOptions.cpp
@@ -12,8 +12,21 @@
namespace clang {
+// First feature in a pair requires the second one to be supported.
+static const std::pair<StringRef, StringRef> DependentFeaturesList[] = {
+ {"__opencl_c_read_write_images", "__opencl_c_images"},
+ {"__opencl_c_3d_image_writes", "__opencl_c_images"},
+ {"__opencl_c_pipes", "__opencl_c_generic_address_space"},
+ {"__opencl_c_device_enqueue", "__opencl_c_generic_address_space"},
+ {"__opencl_c_device_enqueue", "__opencl_c_program_scope_global_variables"}};
+
+// Extensions and equivalent feature pairs.
+static const std::pair<StringRef, StringRef> FeatureExtensionMap[] = {
+ {"cl_khr_fp64", "__opencl_c_fp64"},
+ {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}};
+
bool OpenCLOptions::isKnown(llvm::StringRef Ext) const {
- return OptMap.find(Ext) != OptMap.end();
+ return OptMap.contains(Ext);
}
bool OpenCLOptions::isAvailableOption(llvm::StringRef Ext,
@@ -108,42 +121,32 @@ void OpenCLOptions::disableAll() {
bool OpenCLOptions::diagnoseUnsupportedFeatureDependencies(
const TargetInfo &TI, DiagnosticsEngine &Diags) {
- // Feature pairs. First feature in a pair requires the second one to be
- // supported.
- static const llvm::StringMap<llvm::StringRef> DependentFeaturesMap = {
- {"__opencl_c_read_write_images", "__opencl_c_images"},
- {"__opencl_c_3d_image_writes", "__opencl_c_images"},
- {"__opencl_c_pipes", "__opencl_c_generic_address_space"}};
-
auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
bool IsValid = true;
- for (auto &FeaturePair : DependentFeaturesMap)
- if (TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getKey()) &&
- !TI.hasFeatureEnabled(OpenCLFeaturesMap, FeaturePair.getValue())) {
+ for (auto &FeaturePair : DependentFeaturesList) {
+ auto Feature = FeaturePair.first;
+ auto Dep = FeaturePair.second;
+ if (TI.hasFeatureEnabled(OpenCLFeaturesMap, Feature) &&
+ !TI.hasFeatureEnabled(OpenCLFeaturesMap, Dep)) {
IsValid = false;
- Diags.Report(diag::err_opencl_feature_requires)
- << FeaturePair.getKey() << FeaturePair.getValue();
+ Diags.Report(diag::err_opencl_feature_requires) << Feature << Dep;
}
+ }
return IsValid;
}
bool OpenCLOptions::diagnoseFeatureExtensionDifferences(
const TargetInfo &TI, DiagnosticsEngine &Diags) {
- // Extensions and equivalent feature pairs.
- static const llvm::StringMap<llvm::StringRef> FeatureExtensionMap = {
- {"cl_khr_fp64", "__opencl_c_fp64"},
- {"cl_khr_3d_image_writes", "__opencl_c_3d_image_writes"}};
-
auto OpenCLFeaturesMap = TI.getSupportedOpenCLOpts();
bool IsValid = true;
for (auto &ExtAndFeat : FeatureExtensionMap)
- if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getKey()) !=
- TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.getValue())) {
+ if (TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) !=
+ TI.hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) {
IsValid = false;
Diags.Report(diag::err_opencl_extension_and_feature_differs)
- << ExtAndFeat.getKey() << ExtAndFeat.getValue();
+ << ExtAndFeat.first << ExtAndFeat.second;
}
return IsValid;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp
index cfdba09eb1ec..6c31b0824eb8 100644
--- a/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp
@@ -21,7 +21,7 @@ using namespace clang;
using namespace llvm::omp;
unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
- unsigned OpenMPVersion) {
+ const LangOptions &LangOpts) {
switch (Kind) {
case OMPC_default:
return llvm::StringSwitch<unsigned>(Str)
@@ -41,11 +41,20 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
.Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_MODIFIER_##Name))
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_SCHEDULE_unknown);
- case OMPC_depend:
- return llvm::StringSwitch<OpenMPDependClauseKind>(Str)
+ case OMPC_depend: {
+ unsigned Type = llvm::StringSwitch<unsigned>(Str)
#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)
#include "clang/Basic/OpenMPKinds.def"
- .Default(OMPC_DEPEND_unknown);
+ .Default(OMPC_DEPEND_unknown);
+ if (LangOpts.OpenMP < 51 && Type == OMPC_DEPEND_inoutset)
+ return OMPC_DEPEND_unknown;
+ return Type;
+ }
+ case OMPC_doacross:
+ return llvm::StringSwitch<OpenMPDoacrossClauseModifier>(Str)
+#define OPENMP_DOACROSS_MODIFIER(Name) .Case(#Name, OMPC_DOACROSS_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_DOACROSS_unknown);
case OMPC_linear:
return llvm::StringSwitch<OpenMPLinearClauseKind>(Str)
#define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name)
@@ -59,7 +68,9 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
.Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name))
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_MAP_unknown);
- if (OpenMPVersion < 51 && Type == OMPC_MAP_MODIFIER_present)
+ if (LangOpts.OpenMP < 51 && Type == OMPC_MAP_MODIFIER_present)
+ return OMPC_MAP_MODIFIER_unknown;
+ if (!LangOpts.OpenMPExtensions && Type == OMPC_MAP_MODIFIER_ompx_hold)
return OMPC_MAP_MODIFIER_unknown;
return Type;
}
@@ -70,7 +81,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
.Case(#Name, static_cast<unsigned>(OMPC_MOTION_MODIFIER_##Name))
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_MOTION_MODIFIER_unknown);
- if (OpenMPVersion < 51 && Type == OMPC_MOTION_MODIFIER_present)
+ if (LangOpts.OpenMP < 51 && Type == OMPC_MOTION_MODIFIER_present)
return OMPC_MOTION_MODIFIER_unknown;
return Type;
}
@@ -93,19 +104,37 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
.Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown);
+ case OMPC_fail:
+ return static_cast<unsigned int>(llvm::StringSwitch<llvm::omp::Clause>(Str)
+#define OPENMP_ATOMIC_FAIL_MODIFIER(Name) .Case(#Name, OMPC_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_unknown));
case OMPC_device_type:
return llvm::StringSwitch<OpenMPDeviceType>(Str)
#define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_DEVICE_TYPE_unknown);
+ case OMPC_at:
+ return llvm::StringSwitch<OpenMPAtClauseKind>(Str)
+#define OPENMP_AT_KIND(Name) .Case(#Name, OMPC_AT_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_AT_unknown);
+ case OMPC_severity:
+ return llvm::StringSwitch<OpenMPSeverityClauseKind>(Str)
+#define OPENMP_SEVERITY_KIND(Name) .Case(#Name, OMPC_SEVERITY_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_SEVERITY_unknown);
case OMPC_lastprivate:
return llvm::StringSwitch<OpenMPLastprivateModifier>(Str)
#define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_LASTPRIVATE_unknown);
case OMPC_order:
- return llvm::StringSwitch<OpenMPOrderClauseKind>(Str)
-#define OPENMP_ORDER_KIND(Name) .Case(#Name, OMPC_ORDER_##Name)
+ return llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_ORDER_KIND(Name) \
+ .Case(#Name, static_cast<unsigned>(OMPC_ORDER_##Name))
+#define OPENMP_ORDER_MODIFIER(Name) \
+ .Case(#Name, static_cast<unsigned>(OMPC_ORDER_MODIFIER_##Name))
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_ORDER_unknown);
case OMPC_update:
@@ -123,6 +152,34 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
#define OPENMP_REDUCTION_MODIFIER(Name) .Case(#Name, OMPC_REDUCTION_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_REDUCTION_unknown);
+ case OMPC_adjust_args:
+ return llvm::StringSwitch<OpenMPAdjustArgsOpKind>(Str)
+#define OPENMP_ADJUST_ARGS_KIND(Name) .Case(#Name, OMPC_ADJUST_ARGS_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_ADJUST_ARGS_unknown);
+ case OMPC_bind:
+ return llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_BIND_KIND(Name) .Case(#Name, OMPC_BIND_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_BIND_unknown);
+ case OMPC_grainsize: {
+ unsigned Type = llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_GRAINSIZE_MODIFIER(Name) .Case(#Name, OMPC_GRAINSIZE_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_GRAINSIZE_unknown);
+ if (LangOpts.OpenMP < 51)
+ return OMPC_GRAINSIZE_unknown;
+ return Type;
+ }
+ case OMPC_num_tasks: {
+ unsigned Type = llvm::StringSwitch<unsigned>(Str)
+#define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_NUMTASKS_unknown);
+ if (LangOpts.OpenMP < 51)
+ return OMPC_NUMTASKS_unknown;
+ return Type;
+ }
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -151,6 +208,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
case OMPC_read:
case OMPC_write:
case OMPC_capture:
+ case OMPC_compare:
case OMPC_seq_cst:
case OMPC_acq_rel:
case OMPC_acquire:
@@ -161,14 +219,13 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
case OMPC_num_teams:
case OMPC_thread_limit:
case OMPC_priority:
- case OMPC_grainsize:
case OMPC_nogroup:
- case OMPC_num_tasks:
case OMPC_hint:
case OMPC_uniform:
case OMPC_use_device_ptr:
case OMPC_use_device_addr:
case OMPC_is_device_ptr:
+ case OMPC_has_device_addr:
case OMPC_unified_address:
case OMPC_unified_shared_memory:
case OMPC_reverse_offload:
@@ -183,6 +240,8 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
case OMPC_exclusive:
case OMPC_uses_allocators:
case OMPC_affinity:
+ case OMPC_when:
+ case OMPC_append_args:
break;
default:
break;
@@ -233,6 +292,16 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'depend' clause type");
+ case OMPC_doacross:
+ switch (Type) {
+ case OMPC_DOACROSS_unknown:
+ return "unknown";
+#define OPENMP_DOACROSS_MODIFIER(Name) \
+ case OMPC_DOACROSS_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'doacross' clause type");
case OMPC_linear:
switch (Type) {
case OMPC_LINEAR_unknown:
@@ -316,6 +385,26 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'device_type' clause type");
+ case OMPC_at:
+ switch (Type) {
+ case OMPC_AT_unknown:
+ return "unknown";
+#define OPENMP_AT_KIND(Name) \
+ case OMPC_AT_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'at' clause type");
+ case OMPC_severity:
+ switch (Type) {
+ case OMPC_SEVERITY_unknown:
+ return "unknown";
+#define OPENMP_SEVERITY_KIND(Name) \
+ case OMPC_SEVERITY_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'severity' clause type");
case OMPC_lastprivate:
switch (Type) {
case OMPC_LASTPRIVATE_unknown:
@@ -329,10 +418,14 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_order:
switch (Type) {
case OMPC_ORDER_unknown:
+ case OMPC_ORDER_MODIFIER_last:
return "unknown";
#define OPENMP_ORDER_KIND(Name) \
- case OMPC_ORDER_##Name: \
- return #Name;
+ case OMPC_ORDER_##Name: \
+ return #Name;
+#define OPENMP_ORDER_MODIFIER(Name) \
+ case OMPC_ORDER_MODIFIER_##Name: \
+ return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'order' clause type");
@@ -346,6 +439,11 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'depend' clause type");
+ case OMPC_fail: {
+ OpenMPClauseKind CK = static_cast<OpenMPClauseKind>(Type);
+ return getOpenMPClauseName(CK).data();
+ llvm_unreachable("Invalid OpenMP 'fail' clause modifier");
+ }
case OMPC_device:
switch (Type) {
case OMPC_DEVICE_unknown:
@@ -366,6 +464,46 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'reduction' clause modifier");
+ case OMPC_adjust_args:
+ switch (Type) {
+ case OMPC_ADJUST_ARGS_unknown:
+ return "unknown";
+#define OPENMP_ADJUST_ARGS_KIND(Name) \
+ case OMPC_ADJUST_ARGS_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind");
+ case OMPC_bind:
+ switch (Type) {
+ case OMPC_BIND_unknown:
+ return "unknown";
+#define OPENMP_BIND_KIND(Name) \
+ case OMPC_BIND_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'bind' clause type");
+ case OMPC_grainsize:
+ switch (Type) {
+ case OMPC_GRAINSIZE_unknown:
+ return "unknown";
+#define OPENMP_GRAINSIZE_MODIFIER(Name) \
+ case OMPC_GRAINSIZE_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier");
+ case OMPC_num_tasks:
+ switch (Type) {
+ case OMPC_NUMTASKS_unknown:
+ return "unknown";
+#define OPENMP_NUMTASKS_MODIFIER(Name) \
+ case OMPC_NUMTASKS_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -394,6 +532,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_read:
case OMPC_write:
case OMPC_capture:
+ case OMPC_compare:
case OMPC_seq_cst:
case OMPC_acq_rel:
case OMPC_acquire:
@@ -404,14 +543,13 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_num_teams:
case OMPC_thread_limit:
case OMPC_priority:
- case OMPC_grainsize:
case OMPC_nogroup:
- case OMPC_num_tasks:
case OMPC_hint:
case OMPC_uniform:
case OMPC_use_device_ptr:
case OMPC_use_device_addr:
case OMPC_is_device_ptr:
+ case OMPC_has_device_addr:
case OMPC_unified_address:
case OMPC_unified_shared_memory:
case OMPC_reverse_offload:
@@ -426,6 +564,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_exclusive:
case OMPC_uses_allocators:
case OMPC_affinity:
+ case OMPC_when:
+ case OMPC_append_args:
break;
default:
break;
@@ -440,7 +580,10 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd ||
DKind == OMPD_parallel_master_taskloop ||
DKind == OMPD_parallel_master_taskloop_simd ||
- DKind == OMPD_distribute || DKind == OMPD_target_parallel_for ||
+ DKind == OMPD_masked_taskloop || DKind == OMPD_masked_taskloop_simd ||
+ DKind == OMPD_parallel_masked_taskloop || DKind == OMPD_distribute ||
+ DKind == OMPD_parallel_masked_taskloop_simd ||
+ DKind == OMPD_target_parallel_for ||
DKind == OMPD_distribute_parallel_for ||
DKind == OMPD_distribute_parallel_for_simd ||
DKind == OMPD_distribute_simd ||
@@ -453,7 +596,9 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_simd || DKind == OMPD_tile ||
- DKind == OMPD_unroll;
+ DKind == OMPD_unroll || DKind == OMPD_loop ||
+ DKind == OMPD_teams_loop || DKind == OMPD_target_teams_loop ||
+ DKind == OMPD_parallel_loop || DKind == OMPD_target_parallel_loop;
}
bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
@@ -468,13 +613,18 @@ bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_teams_distribute_parallel_for_simd ||
DKind == OMPD_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for ||
- DKind == OMPD_target_teams_distribute_parallel_for_simd;
+ DKind == OMPD_target_teams_distribute_parallel_for_simd ||
+ DKind == OMPD_parallel_loop || DKind == OMPD_teams_loop ||
+ DKind == OMPD_target_parallel_loop || DKind == OMPD_target_teams_loop;
}
bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd ||
DKind == OMPD_master_taskloop || DKind == OMPD_master_taskloop_simd ||
DKind == OMPD_parallel_master_taskloop ||
+ DKind == OMPD_masked_taskloop || DKind == OMPD_masked_taskloop_simd ||
+ DKind == OMPD_parallel_masked_taskloop ||
+ DKind == OMPD_parallel_masked_taskloop_simd ||
DKind == OMPD_parallel_master_taskloop_simd;
}
@@ -489,9 +639,13 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_teams_distribute_parallel_for_simd ||
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
- DKind == OMPD_parallel_master ||
+ DKind == OMPD_parallel_master || DKind == OMPD_parallel_masked ||
DKind == OMPD_parallel_master_taskloop ||
- DKind == OMPD_parallel_master_taskloop_simd;
+ DKind == OMPD_parallel_master_taskloop_simd ||
+ DKind == OMPD_parallel_masked_taskloop ||
+ DKind == OMPD_parallel_masked_taskloop_simd ||
+ DKind == OMPD_parallel_loop || DKind == OMPD_target_parallel_loop ||
+ DKind == OMPD_teams_loop;
}
bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
@@ -501,7 +655,8 @@ bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute ||
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
- DKind == OMPD_target_teams_distribute_simd;
+ DKind == OMPD_target_teams_distribute_simd ||
+ DKind == OMPD_target_teams_loop || DKind == OMPD_target_parallel_loop;
}
bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
@@ -513,22 +668,26 @@ bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_teams || DKind == OMPD_teams_distribute ||
DKind == OMPD_teams_distribute_simd ||
DKind == OMPD_teams_distribute_parallel_for_simd ||
- DKind == OMPD_teams_distribute_parallel_for;
+ DKind == OMPD_teams_distribute_parallel_for ||
+ DKind == OMPD_teams_loop;
}
bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
- return isOpenMPNestingTeamsDirective(DKind) ||
- DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute ||
+ return isOpenMPNestingTeamsDirective(DKind) || DKind == OMPD_target_teams ||
+ DKind == OMPD_target_teams_distribute ||
DKind == OMPD_target_teams_distribute_parallel_for ||
DKind == OMPD_target_teams_distribute_parallel_for_simd ||
- DKind == OMPD_target_teams_distribute_simd;
+ DKind == OMPD_target_teams_distribute_simd ||
+ DKind == OMPD_target_teams_loop;
}
bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_simd || DKind == OMPD_for_simd ||
DKind == OMPD_parallel_for_simd || DKind == OMPD_taskloop_simd ||
DKind == OMPD_master_taskloop_simd ||
+ DKind == OMPD_masked_taskloop_simd ||
DKind == OMPD_parallel_master_taskloop_simd ||
+ DKind == OMPD_parallel_masked_taskloop_simd ||
DKind == OMPD_distribute_parallel_for_simd ||
DKind == OMPD_distribute_simd || DKind == OMPD_target_simd ||
DKind == OMPD_teams_distribute_simd ||
@@ -556,6 +715,12 @@ bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
Kind == OMPD_target_teams_distribute_simd;
}
+bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {
+ return Kind == OMPD_loop || Kind == OMPD_teams_loop ||
+ Kind == OMPD_target_teams_loop || Kind == OMPD_parallel_loop ||
+ Kind == OMPD_target_parallel_loop;
+}
+
bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
return Kind == OMPC_private || Kind == OMPC_firstprivate ||
Kind == OMPC_lastprivate || Kind == OMPC_linear ||
@@ -577,25 +742,46 @@ bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
Kind == OMPD_teams_distribute_parallel_for_simd ||
Kind == OMPD_teams_distribute_parallel_for ||
Kind == OMPD_target_teams_distribute_parallel_for ||
- Kind == OMPD_target_teams_distribute_parallel_for_simd;
+ Kind == OMPD_target_teams_distribute_parallel_for_simd ||
+ Kind == OMPD_teams_loop || Kind == OMPD_target_teams_loop;
}
bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) {
return DKind == OMPD_tile || DKind == OMPD_unroll;
}
+bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) {
+ return DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||
+ DKind == OMPD_parallel_master ||
+ DKind == OMPD_parallel_master_taskloop ||
+ DKind == OMPD_parallel_master_taskloop_simd ||
+ DKind == OMPD_parallel_sections;
+}
+
+bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind) {
+ return DKind == OMPD_target || DKind == OMPD_target_parallel ||
+ DKind == OMPD_target_parallel_for ||
+ DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
+ DKind == OMPD_target_parallel_loop;
+}
+
void clang::getOpenMPCaptureRegions(
SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
OpenMPDirectiveKind DKind) {
assert(unsigned(DKind) < llvm::omp::Directive_enumSize);
switch (DKind) {
+ case OMPD_metadirective:
+ CaptureRegions.push_back(OMPD_metadirective);
+ break;
case OMPD_parallel:
case OMPD_parallel_for:
case OMPD_parallel_for_simd:
case OMPD_parallel_master:
+ case OMPD_parallel_masked:
case OMPD_parallel_sections:
case OMPD_distribute_parallel_for:
case OMPD_distribute_parallel_for_simd:
+ case OMPD_parallel_loop:
CaptureRegions.push_back(OMPD_parallel);
break;
case OMPD_target_teams:
@@ -615,6 +801,7 @@ void clang::getOpenMPCaptureRegions(
CaptureRegions.push_back(OMPD_task);
CaptureRegions.push_back(OMPD_target);
break;
+ case OMPD_teams_loop:
case OMPD_teams_distribute_parallel_for:
case OMPD_teams_distribute_parallel_for_simd:
CaptureRegions.push_back(OMPD_teams);
@@ -623,6 +810,7 @@ void clang::getOpenMPCaptureRegions(
case OMPD_target_parallel:
case OMPD_target_parallel_for:
case OMPD_target_parallel_for_simd:
+ case OMPD_target_parallel_loop:
CaptureRegions.push_back(OMPD_task);
CaptureRegions.push_back(OMPD_target);
CaptureRegions.push_back(OMPD_parallel);
@@ -637,13 +825,18 @@ void clang::getOpenMPCaptureRegions(
case OMPD_taskloop_simd:
case OMPD_master_taskloop:
case OMPD_master_taskloop_simd:
+ case OMPD_masked_taskloop:
+ case OMPD_masked_taskloop_simd:
CaptureRegions.push_back(OMPD_taskloop);
break;
+ case OMPD_parallel_masked_taskloop:
+ case OMPD_parallel_masked_taskloop_simd:
case OMPD_parallel_master_taskloop:
case OMPD_parallel_master_taskloop_simd:
CaptureRegions.push_back(OMPD_parallel);
CaptureRegions.push_back(OMPD_taskloop);
break;
+ case OMPD_target_teams_loop:
case OMPD_target_teams_distribute_parallel_for:
case OMPD_target_teams_distribute_parallel_for_simd:
CaptureRegions.push_back(OMPD_task);
@@ -651,6 +844,13 @@ void clang::getOpenMPCaptureRegions(
CaptureRegions.push_back(OMPD_teams);
CaptureRegions.push_back(OMPD_parallel);
break;
+ case OMPD_nothing:
+ CaptureRegions.push_back(OMPD_nothing);
+ break;
+ case OMPD_loop:
+ // TODO: 'loop' may require different capture regions depending on the bind
+ // clause or the parent directive when there is no bind clause. Use
+ // OMPD_unknown for now.
case OMPD_simd:
case OMPD_for:
case OMPD_for_simd:
@@ -665,6 +865,7 @@ void clang::getOpenMPCaptureRegions(
case OMPD_atomic:
case OMPD_target_data:
case OMPD_distribute_simd:
+ case OMPD_scope:
case OMPD_dispatch:
CaptureRegions.push_back(OMPD_unknown);
break;
@@ -676,6 +877,7 @@ void clang::getOpenMPCaptureRegions(
case OMPD_allocate:
case OMPD_taskyield:
case OMPD_barrier:
+ case OMPD_error:
case OMPD_taskwait:
case OMPD_cancellation_point:
case OMPD_cancel:
@@ -697,3 +899,10 @@ void clang::getOpenMPCaptureRegions(
llvm_unreachable("Unknown OpenMP directive");
}
}
+
+bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter) {
+ return FailClauseParameter == llvm::omp::OMPC_acquire ||
+ FailClauseParameter == llvm::omp::OMPC_relaxed ||
+ FailClauseParameter == llvm::omp::OMPC_seq_cst;
+}
+
diff --git a/contrib/llvm-project/clang/lib/Basic/ParsedAttrInfo.cpp b/contrib/llvm-project/clang/lib/Basic/ParsedAttrInfo.cpp
new file mode 100644
index 000000000000..16fa314b642b
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/ParsedAttrInfo.cpp
@@ -0,0 +1,32 @@
+//===- ParsedAttrInfo.cpp - Registry for attribute plugins ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the Registry of attributes added by plugins which
+// derive the ParsedAttrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/ParsedAttrInfo.h"
+#include "llvm/Support/ManagedStatic.h"
+#include <list>
+#include <memory>
+
+using namespace clang;
+
+LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry)
+
+const std::list<std::unique_ptr<ParsedAttrInfo>> &
+clang::getAttributePluginInstances() {
+ static llvm::ManagedStatic<std::list<std::unique_ptr<ParsedAttrInfo>>>
+ PluginAttrInstances;
+ if (PluginAttrInstances->empty())
+ for (const auto &It : ParsedAttrInfoRegistry::entries())
+ PluginAttrInstances->emplace_back(It.instantiate());
+
+ return *PluginAttrInstances;
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp b/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp
index 2cb05c1c3c07..8fa16e2eb069 100644
--- a/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/ProfileList.cpp
@@ -17,6 +17,7 @@
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/raw_ostream.h"
+#include <optional>
using namespace clang;
@@ -35,8 +36,8 @@ public:
bool isEmpty() const { return Sections.empty(); }
bool hasPrefix(StringRef Prefix) const {
- for (auto &SectionIter : Sections)
- if (SectionIter.Entries.count(Prefix) > 0)
+ for (const auto &It : Sections)
+ if (It.second.Entries.count(Prefix) > 0)
return true;
return false;
}
@@ -58,7 +59,7 @@ ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
std::string Error;
if (auto PSCL = create(Paths, VFS, Error))
return PSCL;
- llvm::report_fatal_error(Error);
+ llvm::report_fatal_error(llvm::Twine(Error));
}
}
@@ -66,8 +67,7 @@ ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
ProfileList::ProfileList(ArrayRef<std::string> Paths, SourceManager &SM)
: SCL(ProfileSpecialCaseList::createOrDie(
Paths, SM.getFileManager().getVirtualFileSystem())),
- Empty(SCL->isEmpty()),
- Default(SCL->hasPrefix("fun") || SCL->hasPrefix("src")), SM(SM) {}
+ Empty(SCL->isEmpty()), SM(SM) {}
ProfileList::~ProfileList() = default;
@@ -85,30 +85,66 @@ static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) {
llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum");
}
-llvm::Optional<bool>
+ProfileList::ExclusionType
+ProfileList::getDefault(CodeGenOptions::ProfileInstrKind Kind) const {
+ StringRef Section = getSectionName(Kind);
+ // Check for "default:<type>"
+ if (SCL->inSection(Section, "default", "allow"))
+ return Allow;
+ if (SCL->inSection(Section, "default", "skip"))
+ return Skip;
+ if (SCL->inSection(Section, "default", "forbid"))
+ return Forbid;
+ // If any cases use "fun" or "src", set the default to FORBID.
+ if (SCL->hasPrefix("fun") || SCL->hasPrefix("src"))
+ return Forbid;
+ return Allow;
+}
+
+std::optional<ProfileList::ExclusionType>
+ProfileList::inSection(StringRef Section, StringRef Prefix,
+ StringRef Query) const {
+ if (SCL->inSection(Section, Prefix, Query, "allow"))
+ return Allow;
+ if (SCL->inSection(Section, Prefix, Query, "skip"))
+ return Skip;
+ if (SCL->inSection(Section, Prefix, Query, "forbid"))
+ return Forbid;
+ if (SCL->inSection(Section, Prefix, Query))
+ return Allow;
+ return std::nullopt;
+}
+
+std::optional<ProfileList::ExclusionType>
ProfileList::isFunctionExcluded(StringRef FunctionName,
CodeGenOptions::ProfileInstrKind Kind) const {
StringRef Section = getSectionName(Kind);
+ // Check for "function:<regex>=<case>"
+ if (auto V = inSection(Section, "function", FunctionName))
+ return V;
if (SCL->inSection(Section, "!fun", FunctionName))
- return true;
+ return Forbid;
if (SCL->inSection(Section, "fun", FunctionName))
- return false;
- return None;
+ return Allow;
+ return std::nullopt;
}
-llvm::Optional<bool>
+std::optional<ProfileList::ExclusionType>
ProfileList::isLocationExcluded(SourceLocation Loc,
CodeGenOptions::ProfileInstrKind Kind) const {
return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind);
}
-llvm::Optional<bool>
+std::optional<ProfileList::ExclusionType>
ProfileList::isFileExcluded(StringRef FileName,
CodeGenOptions::ProfileInstrKind Kind) const {
StringRef Section = getSectionName(Kind);
+ // Check for "source:<regex>=<case>"
+ if (auto V = inSection(Section, "source", FileName))
+ return V;
if (SCL->inSection(Section, "!src", FileName))
- return true;
+ return Forbid;
if (SCL->inSection(Section, "src", FileName))
- return false;
- return None;
+ return Allow;
+ return std::nullopt;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp
index 5bf8d39ffd95..b02e868cdaa4 100644
--- a/contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/SanitizerSpecialCaseList.cpp
@@ -33,11 +33,12 @@ SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
std::string Error;
if (auto SSCL = create(Paths, VFS, Error))
return SSCL;
- llvm::report_fatal_error(Error);
+ llvm::report_fatal_error(StringRef(Error));
}
void SanitizerSpecialCaseList::createSanitizerSections() {
- for (auto &S : Sections) {
+ for (auto &It : Sections) {
+ auto &S = It.second;
SanitizerMask Mask;
#define SANITIZER(NAME, ID) \
diff --git a/contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp b/contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp
index 7d903c8fdf5e..62ccdf8e9bbf 100644
--- a/contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Sanitizers.cpp
@@ -61,7 +61,7 @@ namespace clang {
unsigned SanitizerMask::countPopulation() const {
unsigned total = 0;
for (const auto &Val : maskLoToHigh)
- total += llvm::countPopulation(Val);
+ total += llvm::popcount(Val);
return total;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Sarif.cpp b/contrib/llvm-project/clang/lib/Basic/Sarif.cpp
new file mode 100644
index 000000000000..1cae7b937bc6
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/Sarif.cpp
@@ -0,0 +1,425 @@
+//===-- clang/Basic/Sarif.cpp - SarifDocumentWriter class definition ------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of the SARIFDocumentWriter class, and
+/// associated builders such as:
+/// - \ref SarifArtifact
+/// - \ref SarifArtifactLocation
+/// - \ref SarifRule
+/// - \ref SarifResult
+//===----------------------------------------------------------------------===//
+#include "clang/Basic/Sarif.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/Path.h"
+
+#include <optional>
+#include <string>
+#include <utility>
+
+using namespace clang;
+using namespace llvm;
+
+using clang::detail::SarifArtifact;
+using clang::detail::SarifArtifactLocation;
+
+static StringRef getFileName(FileEntryRef FE) {
+ StringRef Filename = FE.getFileEntry().tryGetRealPathName();
+ if (Filename.empty())
+ Filename = FE.getName();
+ return Filename;
+}
+/// \name URI
+/// @{
+
+/// \internal
+/// \brief
+/// Return the RFC3986 encoding of the input character.
+///
+/// \param C Character to encode to RFC3986.
+///
+/// \return The RFC3986 representation of \c C.
+static std::string percentEncodeURICharacter(char C) {
+ // RFC 3986 claims alpha, numeric, and this handful of
+ // characters are not reserved for the path component and
+ // should be written out directly. Otherwise, percent
+ // encode the character and write that out instead of the
+ // reserved character.
+ if (llvm::isAlnum(C) ||
+ StringRef::npos != StringRef("-._~:@!$&'()*+,;=").find(C))
+ return std::string(&C, 1);
+ return "%" + llvm::toHex(StringRef(&C, 1));
+}
+
+/// \internal
+/// \brief Return a URI representing the given file name.
+///
+/// \param Filename The filename to be represented as URI.
+///
+/// \return RFC3986 URI representing the input file name.
+static std::string fileNameToURI(StringRef Filename) {
+ SmallString<32> Ret = StringRef("file://");
+
+ // Get the root name to see if it has a URI authority.
+ StringRef Root = sys::path::root_name(Filename);
+ if (Root.starts_with("//")) {
+ // There is an authority, so add it to the URI.
+ Ret += Root.drop_front(2).str();
+ } else if (!Root.empty()) {
+ // There is no authority, so end the component and add the root to the URI.
+ Ret += Twine("/" + Root).str();
+ }
+
+ auto Iter = sys::path::begin(Filename), End = sys::path::end(Filename);
+ assert(Iter != End && "Expected there to be a non-root path component.");
+ // Add the rest of the path components, encoding any reserved characters;
+ // we skip past the first path component, as it was handled it above.
+ for (StringRef Component : llvm::make_range(++Iter, End)) {
+ // For reasons unknown to me, we may get a backslash with Windows native
+ // paths for the initial backslash following the drive component, which
+ // we need to ignore as a URI path part.
+ if (Component == "\\")
+ continue;
+
+ // Add the separator between the previous path part and the one being
+ // currently processed.
+ Ret += "/";
+
+ // URI encode the part.
+ for (char C : Component) {
+ Ret += percentEncodeURICharacter(C);
+ }
+ }
+
+ return std::string(Ret);
+}
+/// @}
+
+/// \brief Calculate the column position expressed in the number of UTF-8 code
+/// points from column start to the source location
+///
+/// \param Loc The source location whose column needs to be calculated.
+/// \param TokenLen Optional hint for when the token is multiple bytes long.
+///
+/// \return The column number as a UTF-8 aware byte offset from column start to
+/// the effective source location.
+static unsigned int adjustColumnPos(FullSourceLoc Loc,
+ unsigned int TokenLen = 0) {
+ assert(!Loc.isInvalid() && "invalid Loc when adjusting column position");
+
+ std::pair<FileID, unsigned> LocInfo = Loc.getDecomposedExpansionLoc();
+ std::optional<MemoryBufferRef> Buf =
+ Loc.getManager().getBufferOrNone(LocInfo.first);
+ assert(Buf && "got an invalid buffer for the location's file");
+ assert(Buf->getBufferSize() >= (LocInfo.second + TokenLen) &&
+ "token extends past end of buffer?");
+
+ // Adjust the offset to be the start of the line, since we'll be counting
+ // Unicode characters from there until our column offset.
+ unsigned int Off = LocInfo.second - (Loc.getExpansionColumnNumber() - 1);
+ unsigned int Ret = 1;
+ while (Off < (LocInfo.second + TokenLen)) {
+ Off += getNumBytesForUTF8(Buf->getBuffer()[Off]);
+ Ret++;
+ }
+
+ return Ret;
+}
+
+/// \name SARIF Utilities
+/// @{
+
+/// \internal
+json::Object createMessage(StringRef Text) {
+ return json::Object{{"text", Text.str()}};
+}
+
+/// \internal
+/// \pre CharSourceRange must be a token range
+static json::Object createTextRegion(const SourceManager &SM,
+ const CharSourceRange &R) {
+ FullSourceLoc BeginCharLoc{R.getBegin(), SM};
+ FullSourceLoc EndCharLoc{R.getEnd(), SM};
+ json::Object Region{{"startLine", BeginCharLoc.getExpansionLineNumber()},
+ {"startColumn", adjustColumnPos(BeginCharLoc)}};
+
+ if (BeginCharLoc == EndCharLoc) {
+ Region["endColumn"] = adjustColumnPos(BeginCharLoc);
+ } else {
+ Region["endLine"] = EndCharLoc.getExpansionLineNumber();
+ Region["endColumn"] = adjustColumnPos(EndCharLoc);
+ }
+ return Region;
+}
+
+static json::Object createLocation(json::Object &&PhysicalLocation,
+ StringRef Message = "") {
+ json::Object Ret{{"physicalLocation", std::move(PhysicalLocation)}};
+ if (!Message.empty())
+ Ret.insert({"message", createMessage(Message)});
+ return Ret;
+}
+
+static StringRef importanceToStr(ThreadFlowImportance I) {
+ switch (I) {
+ case ThreadFlowImportance::Important:
+ return "important";
+ case ThreadFlowImportance::Essential:
+ return "essential";
+ case ThreadFlowImportance::Unimportant:
+ return "unimportant";
+ }
+ llvm_unreachable("Fully covered switch is not so fully covered");
+}
+
+static StringRef resultLevelToStr(SarifResultLevel R) {
+ switch (R) {
+ case SarifResultLevel::None:
+ return "none";
+ case SarifResultLevel::Note:
+ return "note";
+ case SarifResultLevel::Warning:
+ return "warning";
+ case SarifResultLevel::Error:
+ return "error";
+ }
+ llvm_unreachable("Potentially un-handled SarifResultLevel. "
+ "Is the switch not fully covered?");
+}
+
+static json::Object
+createThreadFlowLocation(json::Object &&Location,
+ const ThreadFlowImportance &Importance) {
+ return json::Object{{"location", std::move(Location)},
+ {"importance", importanceToStr(Importance)}};
+}
+/// @}
+
+json::Object
+SarifDocumentWriter::createPhysicalLocation(const CharSourceRange &R) {
+ assert(R.isValid() &&
+ "Cannot create a physicalLocation from invalid SourceRange!");
+ assert(R.isCharRange() &&
+ "Cannot create a physicalLocation from a token range!");
+ FullSourceLoc Start{R.getBegin(), SourceMgr};
+ OptionalFileEntryRef FE = Start.getExpansionLoc().getFileEntryRef();
+ assert(FE && "Diagnostic does not exist within a valid file!");
+
+ const std::string &FileURI = fileNameToURI(getFileName(*FE));
+ auto I = CurrentArtifacts.find(FileURI);
+
+ if (I == CurrentArtifacts.end()) {
+ uint32_t Idx = static_cast<uint32_t>(CurrentArtifacts.size());
+ const SarifArtifactLocation &Location =
+ SarifArtifactLocation::create(FileURI).setIndex(Idx);
+ const SarifArtifact &Artifact = SarifArtifact::create(Location)
+ .setRoles({"resultFile"})
+ .setLength(FE->getSize())
+ .setMimeType("text/plain");
+ auto StatusIter = CurrentArtifacts.insert({FileURI, Artifact});
+ // If inserted, ensure the original iterator points to the newly inserted
+ // element, so it can be used downstream.
+ if (StatusIter.second)
+ I = StatusIter.first;
+ }
+ assert(I != CurrentArtifacts.end() && "Failed to insert new artifact");
+ const SarifArtifactLocation &Location = I->second.Location;
+ json::Object ArtifactLocationObject{{"uri", Location.URI}};
+ if (Location.Index.has_value())
+ ArtifactLocationObject["index"] = *Location.Index;
+ return json::Object{{{"artifactLocation", std::move(ArtifactLocationObject)},
+ {"region", createTextRegion(SourceMgr, R)}}};
+}
+
+json::Object &SarifDocumentWriter::getCurrentTool() {
+ assert(!Closed && "SARIF Document is closed. "
+ "Need to call createRun() before using getcurrentTool!");
+
+ // Since Closed = false here, expect there to be at least 1 Run, anything
+ // else is an invalid state.
+ assert(!Runs.empty() && "There are no runs associated with the document!");
+
+ return *Runs.back().getAsObject()->get("tool")->getAsObject();
+}
+
+void SarifDocumentWriter::reset() {
+ CurrentRules.clear();
+ CurrentArtifacts.clear();
+}
+
+void SarifDocumentWriter::endRun() {
+ // Exit early if trying to close a closed Document.
+ if (Closed) {
+ reset();
+ return;
+ }
+
+ // Since Closed = false here, expect there to be at least 1 Run, anything
+ // else is an invalid state.
+ assert(!Runs.empty() && "There are no runs associated with the document!");
+
+ // Flush all the rules.
+ json::Object &Tool = getCurrentTool();
+ json::Array Rules;
+ for (const SarifRule &R : CurrentRules) {
+ json::Object Config{
+ {"enabled", R.DefaultConfiguration.Enabled},
+ {"level", resultLevelToStr(R.DefaultConfiguration.Level)},
+ {"rank", R.DefaultConfiguration.Rank}};
+ json::Object Rule{
+ {"name", R.Name},
+ {"id", R.Id},
+ {"fullDescription", json::Object{{"text", R.Description}}},
+ {"defaultConfiguration", std::move(Config)}};
+ if (!R.HelpURI.empty())
+ Rule["helpUri"] = R.HelpURI;
+ Rules.emplace_back(std::move(Rule));
+ }
+ json::Object &Driver = *Tool.getObject("driver");
+ Driver["rules"] = std::move(Rules);
+
+ // Flush all the artifacts.
+ json::Object &Run = getCurrentRun();
+ json::Array *Artifacts = Run.getArray("artifacts");
+ SmallVector<std::pair<StringRef, SarifArtifact>, 0> Vec;
+ for (const auto &[K, V] : CurrentArtifacts)
+ Vec.emplace_back(K, V);
+ llvm::sort(Vec, llvm::less_first());
+ for (const auto &[_, A] : Vec) {
+ json::Object Loc{{"uri", A.Location.URI}};
+ if (A.Location.Index.has_value()) {
+ Loc["index"] = static_cast<int64_t>(*A.Location.Index);
+ }
+ json::Object Artifact;
+ Artifact["location"] = std::move(Loc);
+ if (A.Length.has_value())
+ Artifact["length"] = static_cast<int64_t>(*A.Length);
+ if (!A.Roles.empty())
+ Artifact["roles"] = json::Array(A.Roles);
+ if (!A.MimeType.empty())
+ Artifact["mimeType"] = A.MimeType;
+ if (A.Offset.has_value())
+ Artifact["offset"] = *A.Offset;
+ Artifacts->push_back(json::Value(std::move(Artifact)));
+ }
+
+ // Clear, reset temporaries before next run.
+ reset();
+
+ // Mark the document as closed.
+ Closed = true;
+}
+
+json::Array
+SarifDocumentWriter::createThreadFlows(ArrayRef<ThreadFlow> ThreadFlows) {
+ json::Object Ret{{"locations", json::Array{}}};
+ json::Array Locs;
+ for (const auto &ThreadFlow : ThreadFlows) {
+ json::Object PLoc = createPhysicalLocation(ThreadFlow.Range);
+ json::Object Loc = createLocation(std::move(PLoc), ThreadFlow.Message);
+ Locs.emplace_back(
+ createThreadFlowLocation(std::move(Loc), ThreadFlow.Importance));
+ }
+ Ret["locations"] = std::move(Locs);
+ return json::Array{std::move(Ret)};
+}
+
+json::Object
+SarifDocumentWriter::createCodeFlow(ArrayRef<ThreadFlow> ThreadFlows) {
+ return json::Object{{"threadFlows", createThreadFlows(ThreadFlows)}};
+}
+
+void SarifDocumentWriter::createRun(StringRef ShortToolName,
+ StringRef LongToolName,
+ StringRef ToolVersion) {
+ // Clear resources associated with a previous run.
+ endRun();
+
+ // Signify a new run has begun.
+ Closed = false;
+
+ json::Object Tool{
+ {"driver",
+ json::Object{{"name", ShortToolName},
+ {"fullName", LongToolName},
+ {"language", "en-US"},
+ {"version", ToolVersion},
+ {"informationUri",
+ "https://clang.llvm.org/docs/UsersManual.html"}}}};
+ json::Object TheRun{{"tool", std::move(Tool)},
+ {"results", {}},
+ {"artifacts", {}},
+ {"columnKind", "unicodeCodePoints"}};
+ Runs.emplace_back(std::move(TheRun));
+}
+
+json::Object &SarifDocumentWriter::getCurrentRun() {
+ assert(!Closed &&
+ "SARIF Document is closed. "
+ "Can only getCurrentRun() if document is opened via createRun(), "
+ "create a run first");
+
+ // Since Closed = false here, expect there to be at least 1 Run, anything
+ // else is an invalid state.
+ assert(!Runs.empty() && "There are no runs associated with the document!");
+ return *Runs.back().getAsObject();
+}
+
+size_t SarifDocumentWriter::createRule(const SarifRule &Rule) {
+ size_t Ret = CurrentRules.size();
+ CurrentRules.emplace_back(Rule);
+ return Ret;
+}
+
+void SarifDocumentWriter::appendResult(const SarifResult &Result) {
+ size_t RuleIdx = Result.RuleIdx;
+ assert(RuleIdx < CurrentRules.size() &&
+ "Trying to reference a rule that doesn't exist");
+ const SarifRule &Rule = CurrentRules[RuleIdx];
+ assert(Rule.DefaultConfiguration.Enabled &&
+ "Cannot add a result referencing a disabled Rule");
+ json::Object Ret{{"message", createMessage(Result.DiagnosticMessage)},
+ {"ruleIndex", static_cast<int64_t>(RuleIdx)},
+ {"ruleId", Rule.Id}};
+ if (!Result.Locations.empty()) {
+ json::Array Locs;
+ for (auto &Range : Result.Locations) {
+ Locs.emplace_back(createLocation(createPhysicalLocation(Range)));
+ }
+ Ret["locations"] = std::move(Locs);
+ }
+ if (!Result.ThreadFlows.empty())
+ Ret["codeFlows"] = json::Array{createCodeFlow(Result.ThreadFlows)};
+
+ Ret["level"] = resultLevelToStr(
+ Result.LevelOverride.value_or(Rule.DefaultConfiguration.Level));
+
+ json::Object &Run = getCurrentRun();
+ json::Array *Results = Run.getArray("results");
+ Results->emplace_back(std::move(Ret));
+}
+
+json::Object SarifDocumentWriter::createDocument() {
+ // Flush all temporaries to their destinations if needed.
+ endRun();
+
+ json::Object Doc{
+ {"$schema", SchemaURI},
+ {"version", SchemaVersion},
+ };
+ if (!Runs.empty())
+ Doc["runs"] = json::Array(Runs);
+ return Doc;
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp
index 6986fcd322f2..37baf643a0a9 100644
--- a/contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/SourceLocation.cpp
@@ -42,11 +42,11 @@ void PrettyStackTraceLoc::print(raw_ostream &OS) const {
// SourceLocation
//===----------------------------------------------------------------------===//
-static_assert(std::is_trivially_destructible<SourceLocation>::value,
+static_assert(std::is_trivially_destructible_v<SourceLocation>,
"SourceLocation must be trivially destructible because it is "
"used in unions");
-static_assert(std::is_trivially_destructible<SourceRange>::value,
+static_assert(std::is_trivially_destructible_v<SourceRange>,
"SourceRange must be trivially destructible because it is "
"used in unions");
@@ -90,7 +90,7 @@ SourceLocation::printToString(const SourceManager &SM) const {
std::string S;
llvm::raw_string_ostream OS(S);
print(OS, SM);
- return OS.str();
+ return S;
}
LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const {
@@ -149,7 +149,7 @@ SourceRange::printToString(const SourceManager &SM) const {
std::string S;
llvm::raw_string_ostream OS(S);
print(OS, SM);
- return OS.str();
+ return S;
}
//===----------------------------------------------------------------------===//
@@ -166,6 +166,10 @@ FullSourceLoc FullSourceLoc::getExpansionLoc() const {
return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr);
}
+std::pair<FileID, unsigned> FullSourceLoc::getDecomposedExpansionLoc() const {
+ return SrcMgr->getDecomposedExpansionLoc(*this);
+}
+
FullSourceLoc FullSourceLoc::getSpellingLoc() const {
assert(isValid());
return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
@@ -223,6 +227,11 @@ const FileEntry *FullSourceLoc::getFileEntry() const {
return SrcMgr->getFileEntryForID(getFileID());
}
+OptionalFileEntryRef FullSourceLoc::getFileEntryRef() const {
+ assert(isValid());
+ return SrcMgr->getFileEntryRefForID(getFileID());
+}
+
unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const {
assert(isValid());
return SrcMgr->getExpansionLineNumber(*this, Invalid);
diff --git a/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp b/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp
index 8cba379aa0f8..37734d3b10e7 100644
--- a/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/SourceManager.cpp
@@ -17,8 +17,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManagerInternals.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -38,6 +37,7 @@
#include <cstddef>
#include <cstdint>
#include <memory>
+#include <optional>
#include <tuple>
#include <utility>
#include <vector>
@@ -59,12 +59,10 @@ unsigned ContentCache::getSizeBytesMapped() const {
/// Returns the kind of memory used to back the memory buffer for
/// this content cache. This is used for performance analysis.
llvm::MemoryBuffer::BufferKind ContentCache::getMemoryBufferKind() const {
- assert(Buffer);
-
- // Should be unreachable, but keep for sanity.
- if (!Buffer)
+ if (Buffer == nullptr) {
+ assert(0 && "Buffer should never be null");
return llvm::MemoryBuffer::MemoryBuffer_Malloc;
-
+ }
return Buffer->getBufferKind();
}
@@ -100,23 +98,23 @@ const char *ContentCache::getInvalidBOM(StringRef BufStr) {
return InvalidBOM;
}
-llvm::Optional<llvm::MemoryBufferRef>
+std::optional<llvm::MemoryBufferRef>
ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM,
SourceLocation Loc) const {
// Lazily create the Buffer for ContentCaches that wrap files. If we already
// computed it, just return what we have.
if (IsBufferInvalid)
- return None;
+ return std::nullopt;
if (Buffer)
return Buffer->getMemBufferRef();
if (!ContentsEntry)
- return None;
+ return std::nullopt;
// Start with the assumption that the buffer is invalid to simplify early
// return paths.
IsBufferInvalid = true;
- auto BufferOrError = FM.getBufferForFile(ContentsEntry, IsFileVolatile);
+ auto BufferOrError = FM.getBufferForFile(*ContentsEntry, IsFileVolatile);
// If we were unable to open the file, then we are in an inconsistent
// situation where the content cache referenced a file which no longer
@@ -132,7 +130,7 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM,
Diag.Report(Loc, diag::err_cannot_open_file)
<< ContentsEntry->getName() << BufferOrError.getError().message();
- return None;
+ return std::nullopt;
}
Buffer = std::move(*BufferOrError);
@@ -154,7 +152,7 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM,
Diag.Report(Loc, diag::err_file_too_large)
<< ContentsEntry->getName();
- return None;
+ return std::nullopt;
}
// Unless this is a named pipe (in which case we can handle a mismatch),
@@ -169,7 +167,7 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM,
Diag.Report(Loc, diag::err_file_modified)
<< ContentsEntry->getName();
- return None;
+ return std::nullopt;
}
// If the buffer is valid, check to see if it has a UTF Byte Order Mark
@@ -181,7 +179,7 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM,
if (InvalidBOM) {
Diag.Report(Loc, diag::err_unsupported_bom)
<< InvalidBOM << ContentsEntry->getName();
- return None;
+ return std::nullopt;
}
// Buffer has been validated.
@@ -207,28 +205,30 @@ void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, unsigned LineNo,
SrcMgr::CharacteristicKind FileKind) {
std::vector<LineEntry> &Entries = LineEntries[FID];
- // An unspecified FilenameID means use the last filename if available, or the
- // main source file otherwise.
- if (FilenameID == -1 && !Entries.empty())
- FilenameID = Entries.back().FilenameID;
-
assert((Entries.empty() || Entries.back().FileOffset < Offset) &&
"Adding line entries out of order!");
unsigned IncludeOffset = 0;
- if (EntryExit == 0) { // No #include stack change.
- IncludeOffset = Entries.empty() ? 0 : Entries.back().IncludeOffset;
- } else if (EntryExit == 1) {
+ if (EntryExit == 1) {
+ // Push #include
IncludeOffset = Offset-1;
- } else if (EntryExit == 2) {
- assert(!Entries.empty() && Entries.back().IncludeOffset &&
- "PPDirectives should have caught case when popping empty include stack");
-
- // Get the include loc of the last entries' include loc as our include loc.
- IncludeOffset = 0;
- if (const LineEntry *PrevEntry =
- FindNearestLineEntry(FID, Entries.back().IncludeOffset))
+ } else {
+ const auto *PrevEntry = Entries.empty() ? nullptr : &Entries.back();
+ if (EntryExit == 2) {
+ // Pop #include
+ assert(PrevEntry && PrevEntry->IncludeOffset &&
+ "PPDirectives should have caught case when popping empty include "
+ "stack");
+ PrevEntry = FindNearestLineEntry(FID, PrevEntry->IncludeOffset);
+ }
+ if (PrevEntry) {
IncludeOffset = PrevEntry->IncludeOffset;
+ if (FilenameID == -1) {
+ // An unspecified FilenameID means use the previous (or containing)
+ // filename if available, or the main source file otherwise.
+ FilenameID = PrevEntry->FilenameID;
+ }
+ }
}
Entries.push_back(LineEntry::get(Offset, LineNo, FilenameID, FileKind,
@@ -324,8 +324,7 @@ SourceManager::~SourceManager() {
ContentCacheAlloc.Deallocate(MemBufferInfos[i]);
}
}
- for (llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::iterator
- I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
+ for (auto I = FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
if (I->second) {
I->second->~ContentCache();
ContentCacheAlloc.Deallocate(I->second);
@@ -338,6 +337,7 @@ void SourceManager::clearIDTables() {
LocalSLocEntryTable.clear();
LoadedSLocEntryTable.clear();
SLocEntryLoaded.clear();
+ SLocEntryOffsetLoaded.clear();
LastLineNoFileIDQuery = FileID();
LastLineNoContentCache = nullptr;
LastFileIDLookup = FileID();
@@ -399,8 +399,7 @@ ContentCache &SourceManager::getOrCreateContentCache(FileEntryRef FileEnt,
if (OverriddenFilesInfo) {
// If the file contents are overridden with contents from another file,
// pass that file to ContentCache.
- llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
- overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
+ auto overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
if (overI == OverriddenFilesInfo->OverriddenFiles.end())
new (Entry) ContentCache(FileEnt);
else
@@ -455,13 +454,17 @@ SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries,
SourceLocation::UIntTy TotalSize) {
assert(ExternalSLocEntries && "Don't have an external sloc source");
// Make sure we're not about to run out of source locations.
- if (CurrentLoadedOffset - TotalSize < NextLocalOffset)
+ if (CurrentLoadedOffset < TotalSize ||
+ CurrentLoadedOffset - TotalSize < NextLocalOffset) {
return std::make_pair(0, 0);
+ }
LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
+ SLocEntryOffsetLoaded.resize(LoadedSLocEntryTable.size());
CurrentLoadedOffset -= TotalSize;
- int ID = LoadedSLocEntryTable.size();
- return std::make_pair(-ID - 1, CurrentLoadedOffset);
+ int BaseID = -int(LoadedSLocEntryTable.size()) - 1;
+ LoadedSLocEntryAllocBegin.push_back(FileID::get(BaseID));
+ return std::make_pair(BaseID, CurrentLoadedOffset);
}
/// As part of recovering from missing or changed content, produce a
@@ -527,17 +530,6 @@ FileID SourceManager::getNextFileID(FileID FID) const {
/// Create a new FileID that represents the specified file
/// being \#included from the specified IncludePosition.
-///
-/// This translates NULL into standard input.
-FileID SourceManager::createFileID(const FileEntry *SourceFile,
- SourceLocation IncludePos,
- SrcMgr::CharacteristicKind FileCharacter,
- int LoadedID,
- SourceLocation::UIntTy LoadedOffset) {
- return createFileID(SourceFile->getLastRef(), IncludePos, FileCharacter,
- LoadedID, LoadedOffset);
-}
-
FileID SourceManager::createFileID(FileEntryRef SourceFile,
SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter,
@@ -585,7 +577,7 @@ FileID SourceManager::createFileID(const llvm::MemoryBufferRef &Buffer,
/// Get the FileID for \p SourceFile if it exists. Otherwise, create a
/// new FileID for the \p SourceFile.
FileID
-SourceManager::getOrCreateFileID(const FileEntry *SourceFile,
+SourceManager::getOrCreateFileID(FileEntryRef SourceFile,
SrcMgr::CharacteristicKind FileCharacter) {
FileID ID = translateFile(SourceFile);
return ID.isValid() ? ID : createFileID(SourceFile, SourceLocation(),
@@ -607,13 +599,14 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename,
assert(!SLocEntryLoaded[Index] && "FileID already loaded");
LoadedSLocEntryTable[Index] = SLocEntry::get(
LoadedOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename));
- SLocEntryLoaded[Index] = true;
+ SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] = true;
return FileID::get(LoadedID);
}
unsigned FileSize = File.getSize();
if (!(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset)) {
- Diag.Report(IncludePos, diag::err_include_too_large);
+ Diag.Report(IncludePos, diag::err_sloc_space_too_large);
+ noteSLocAddressSpaceUsage(Diag);
return FileID();
}
LocalSLocEntryTable.push_back(
@@ -629,23 +622,21 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename,
return LastFileIDLookup = FID;
}
-SourceLocation
-SourceManager::createMacroArgExpansionLoc(SourceLocation SpellingLoc,
- SourceLocation ExpansionLoc,
- unsigned TokLength) {
+SourceLocation SourceManager::createMacroArgExpansionLoc(
+ SourceLocation SpellingLoc, SourceLocation ExpansionLoc, unsigned Length) {
ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
ExpansionLoc);
- return createExpansionLocImpl(Info, TokLength);
+ return createExpansionLocImpl(Info, Length);
}
SourceLocation SourceManager::createExpansionLoc(
SourceLocation SpellingLoc, SourceLocation ExpansionLocStart,
- SourceLocation ExpansionLocEnd, unsigned TokLength,
+ SourceLocation ExpansionLocEnd, unsigned Length,
bool ExpansionIsTokenRange, int LoadedID,
SourceLocation::UIntTy LoadedOffset) {
ExpansionInfo Info = ExpansionInfo::create(
SpellingLoc, ExpansionLocStart, ExpansionLocEnd, ExpansionIsTokenRange);
- return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
+ return createExpansionLocImpl(Info, Length, LoadedID, LoadedOffset);
}
SourceLocation SourceManager::createTokenSplitLoc(SourceLocation Spelling,
@@ -660,7 +651,7 @@ SourceLocation SourceManager::createTokenSplitLoc(SourceLocation Spelling,
SourceLocation
SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
- unsigned TokLength, int LoadedID,
+ unsigned Length, int LoadedID,
SourceLocation::UIntTy LoadedOffset) {
if (LoadedID < 0) {
assert(LoadedID != -1 && "Loading sentinel FileID");
@@ -668,27 +659,34 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
assert(!SLocEntryLoaded[Index] && "FileID already loaded");
LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
- SLocEntryLoaded[Index] = true;
+ SLocEntryLoaded[Index] = SLocEntryOffsetLoaded[Index] = true;
return SourceLocation::getMacroLoc(LoadedOffset);
}
LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
- assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
- NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
- "Ran out of source locations!");
+ if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+ NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+ Diag.Report(SourceLocation(), diag::err_sloc_space_too_large);
+ // FIXME: call `noteSLocAddressSpaceUsage` to report details to users and
+ // use a source location from `Info` to point at an error.
+ // Currently, both cause Clang to run indefinitely, this needs to be fixed.
+ // FIXME: return an error instead of crashing. Returning invalid source
+ // locations causes compiler to run indefinitely.
+ llvm::report_fatal_error("ran out of source locations");
+ }
// See createFileID for that +1.
- NextLocalOffset += TokLength + 1;
- return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
+ NextLocalOffset += Length + 1;
+ return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));
}
-llvm::Optional<llvm::MemoryBufferRef>
-SourceManager::getMemoryBufferForFileOrNone(const FileEntry *File) {
- SrcMgr::ContentCache &IR = getOrCreateContentCache(File->getLastRef());
+std::optional<llvm::MemoryBufferRef>
+SourceManager::getMemoryBufferForFileOrNone(FileEntryRef File) {
+ SrcMgr::ContentCache &IR = getOrCreateContentCache(File);
return IR.getBufferOrNone(Diag, getFileManager(), SourceLocation());
}
void SourceManager::overrideFileContents(
- const FileEntry *SourceFile, std::unique_ptr<llvm::MemoryBuffer> Buffer) {
- SrcMgr::ContentCache &IR = getOrCreateContentCache(SourceFile->getLastRef());
+ FileEntryRef SourceFile, std::unique_ptr<llvm::MemoryBuffer> Buffer) {
+ SrcMgr::ContentCache &IR = getOrCreateContentCache(SourceFile);
IR.setBuffer(std::move(Buffer));
IR.BufferOverridden = true;
@@ -697,39 +695,43 @@ void SourceManager::overrideFileContents(
}
void SourceManager::overrideFileContents(const FileEntry *SourceFile,
- const FileEntry *NewFile) {
- assert(SourceFile->getSize() == NewFile->getSize() &&
+ FileEntryRef NewFile) {
+ assert(SourceFile->getSize() == NewFile.getSize() &&
"Different sizes, use the FileManager to create a virtual file with "
"the correct size");
- assert(FileInfos.count(SourceFile) == 0 &&
+ assert(FileInfos.find_as(SourceFile) == FileInfos.end() &&
"This function should be called at the initialization stage, before "
"any parsing occurs.");
- getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
+ // FileEntryRef is not default-constructible.
+ auto Pair = getOverriddenFilesInfo().OverriddenFiles.insert(
+ std::make_pair(SourceFile, NewFile));
+ if (!Pair.second)
+ Pair.first->second = NewFile;
}
-Optional<FileEntryRef>
+OptionalFileEntryRef
SourceManager::bypassFileContentsOverride(FileEntryRef File) {
assert(isFileOverridden(&File.getFileEntry()));
- llvm::Optional<FileEntryRef> BypassFile = FileMgr.getBypassFile(File);
+ OptionalFileEntryRef BypassFile = FileMgr.getBypassFile(File);
// If the file can't be found in the FS, give up.
if (!BypassFile)
- return None;
+ return std::nullopt;
(void)getOrCreateContentCache(*BypassFile);
return BypassFile;
}
-void SourceManager::setFileIsTransient(const FileEntry *File) {
- getOrCreateContentCache(File->getLastRef()).IsTransient = true;
+void SourceManager::setFileIsTransient(FileEntryRef File) {
+ getOrCreateContentCache(File).IsTransient = true;
}
-Optional<StringRef>
+std::optional<StringRef>
SourceManager::getNonBuiltinFilenameForID(FileID FID) const {
if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID))
if (Entry->getFile().getContentCache().OrigEntry)
return Entry->getFile().getName();
- return None;
+ return std::nullopt;
}
StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
@@ -739,19 +741,19 @@ StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
return B ? *B : "<<<<<INVALID SOURCE LOCATION>>>>>";
}
-llvm::Optional<StringRef>
+std::optional<StringRef>
SourceManager::getBufferDataIfLoaded(FileID FID) const {
if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID))
return Entry->getFile().getContentCache().getBufferDataIfLoaded();
- return None;
+ return std::nullopt;
}
-llvm::Optional<StringRef> SourceManager::getBufferDataOrNone(FileID FID) const {
+std::optional<StringRef> SourceManager::getBufferDataOrNone(FileID FID) const {
if (const SrcMgr::SLocEntry *Entry = getSLocEntryForFile(FID))
if (auto B = Entry->getFile().getContentCache().getBufferOrNone(
Diag, getFileManager(), SourceLocation()))
return B->getBuffer();
- return None;
+ return std::nullopt;
}
//===----------------------------------------------------------------------===//
@@ -792,24 +794,28 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
// See if this is near the file point - worst case we start scanning from the
// most newly created FileID.
- const SrcMgr::SLocEntry *I;
- if (LastFileIDLookup.ID < 0 ||
- LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
- // Neither loc prunes our search.
- I = LocalSLocEntryTable.end();
- } else {
- // Perhaps it is near the file point.
- I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
+ // LessIndex - This is the lower bound of the range that we're searching.
+ // We know that the offset corresponding to the FileID is less than
+ // SLocOffset.
+ unsigned LessIndex = 0;
+ // upper bound of the search range.
+ unsigned GreaterIndex = LocalSLocEntryTable.size();
+ if (LastFileIDLookup.ID >= 0) {
+ // Use the LastFileIDLookup to prune the search space.
+ if (LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset)
+ LessIndex = LastFileIDLookup.ID;
+ else
+ GreaterIndex = LastFileIDLookup.ID;
}
- // Find the FileID that contains this. "I" is an iterator that points to a
- // FileID whose offset is known to be larger than SLocOffset.
+ // Find the FileID that contains this.
unsigned NumProbes = 0;
while (true) {
- --I;
- if (I->getOffset() <= SLocOffset) {
- FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin()));
+ --GreaterIndex;
+ assert(GreaterIndex < LocalSLocEntryTable.size());
+ if (LocalSLocEntryTable[GreaterIndex].getOffset() <= SLocOffset) {
+ FileID Res = FileID::get(int(GreaterIndex));
// Remember it. We have good locality across FileID lookups.
LastFileIDLookup = Res;
NumLinearScans += NumProbes+1;
@@ -819,13 +825,6 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
break;
}
- // Convert "I" back into an index. We know that it is an entry whose index is
- // larger than the offset we are looking for.
- unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
- // LessIndex - This is the lower bound of the range that we're searching.
- // We know that the offset corresponding to the FileID is is less than
- // SLocOffset.
- unsigned LessIndex = 0;
NumProbes = 0;
while (true) {
unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
@@ -862,74 +861,12 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
/// This function knows that the SourceLocation is in a loaded buffer, not a
/// local one.
FileID SourceManager::getFileIDLoaded(SourceLocation::UIntTy SLocOffset) const {
- // Sanity checking, otherwise a bug may lead to hanging in release build.
if (SLocOffset < CurrentLoadedOffset) {
assert(0 && "Invalid SLocOffset or bad function choice");
return FileID();
}
- // Essentially the same as the local case, but the loaded array is sorted
- // in the other direction.
-
- // First do a linear scan from the last lookup position, if possible.
- unsigned I;
- int LastID = LastFileIDLookup.ID;
- if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
- I = 0;
- else
- I = (-LastID - 2) + 1;
-
- unsigned NumProbes;
- for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) {
- // Make sure the entry is loaded!
- const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I);
- if (E.getOffset() <= SLocOffset) {
- FileID Res = FileID::get(-int(I) - 2);
- LastFileIDLookup = Res;
- NumLinearScans += NumProbes + 1;
- return Res;
- }
- }
-
- // Linear scan failed. Do the binary search. Note the reverse sorting of the
- // table: GreaterIndex is the one where the offset is greater, which is
- // actually a lower index!
- unsigned GreaterIndex = I;
- unsigned LessIndex = LoadedSLocEntryTable.size();
- NumProbes = 0;
- while (true) {
- ++NumProbes;
- unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
- const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex);
- if (E.getOffset() == 0)
- return FileID(); // invalid entry.
-
- ++NumProbes;
-
- if (E.getOffset() > SLocOffset) {
- // Sanity checking, otherwise a bug may lead to hanging in release build.
- if (GreaterIndex == MiddleIndex) {
- assert(0 && "binary search missed the entry");
- return FileID();
- }
- GreaterIndex = MiddleIndex;
- continue;
- }
-
- if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) {
- FileID Res = FileID::get(-int(MiddleIndex) - 2);
- LastFileIDLookup = Res;
- NumBinaryProbes += NumProbes;
- return Res;
- }
-
- // Sanity checking, otherwise a bug may lead to hanging in release build.
- if (LessIndex == MiddleIndex) {
- assert(0 && "binary search missed the entry");
- return FileID();
- }
- LessIndex = MiddleIndex;
- }
+ return FileID::get(ExternalSLocEntries->getSLocEntryID(SLocOffset));
}
SourceLocation SourceManager::
@@ -1016,7 +953,7 @@ SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{
/// Return the filename of the file containing a SourceLocation.
StringRef SourceManager::getFilename(SourceLocation SpellingLoc) const {
- if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc)))
+ if (OptionalFileEntryRef F = getFileEntryRefForID(getFileID(SpellingLoc)))
return F->getName();
return StringRef();
}
@@ -1169,7 +1106,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL,
return "<<<<INVALID BUFFER>>>>";
}
- llvm::Optional<llvm::MemoryBufferRef> Buffer =
+ std::optional<llvm::MemoryBufferRef> Buffer =
Entry.getFile().getContentCache().getBufferOrNone(Diag, getFileManager(),
SourceLocation());
if (Invalid)
@@ -1182,7 +1119,7 @@ const char *SourceManager::getCharacterData(SourceLocation SL,
/// this is significantly cheaper to compute than the line number.
unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
bool *Invalid) const {
- llvm::Optional<llvm::MemoryBufferRef> MemBuf = getBufferOrNone(FID);
+ std::optional<llvm::MemoryBufferRef> MemBuf = getBufferOrNone(FID);
if (Invalid)
*Invalid = !MemBuf;
@@ -1278,22 +1215,21 @@ LineOffsetMapping LineOffsetMapping::get(llvm::MemoryBufferRef Buffer,
// Line #1 starts at char 0.
LineOffsets.push_back(0);
- const unsigned char *Buf = (const unsigned char *)Buffer.getBufferStart();
+ const unsigned char *Start = (const unsigned char *)Buffer.getBufferStart();
const unsigned char *End = (const unsigned char *)Buffer.getBufferEnd();
- const std::size_t BufLen = End - Buf;
+ const unsigned char *Buf = Start;
- unsigned I = 0;
uint64_t Word;
// scan sizeof(Word) bytes at a time for new lines.
// This is much faster than scanning each byte independently.
- if (BufLen > sizeof(Word)) {
+ if ((unsigned long)(End - Start) > sizeof(Word)) {
do {
- Word = llvm::support::endian::read64(Buf + I, llvm::support::little);
+ Word = llvm::support::endian::read64(Buf, llvm::endianness::little);
// no new line => jump over sizeof(Word) bytes.
auto Mask = likelyhasbetween(Word, '\n', '\r');
if (!Mask) {
- I += sizeof(Word);
+ Buf += sizeof(Word);
continue;
}
@@ -1301,33 +1237,35 @@ LineOffsetMapping LineOffsetMapping::get(llvm::MemoryBufferRef Buffer,
// in [\n, \r + 1 [
// Scan for the next newline - it's very likely there's one.
- unsigned N =
- llvm::countTrailingZeros(Mask) - 7; // -7 because 0x80 is the marker
+ unsigned N = llvm::countr_zero(Mask) - 7; // -7 because 0x80 is the marker
Word >>= N;
- I += N / 8 + 1;
+ Buf += N / 8 + 1;
unsigned char Byte = Word;
- if (Byte == '\n') {
- LineOffsets.push_back(I);
- } else if (Byte == '\r') {
+ switch (Byte) {
+ case '\r':
// If this is \r\n, skip both characters.
- if (Buf[I] == '\n')
- ++I;
- LineOffsets.push_back(I);
- }
- } while (I < BufLen - sizeof(Word) - 1);
+ if (*Buf == '\n') {
+ ++Buf;
+ }
+ [[fallthrough]];
+ case '\n':
+ LineOffsets.push_back(Buf - Start);
+ };
+ } while (Buf < End - sizeof(Word) - 1);
}
// Handle tail using a regular check.
- while (I < BufLen) {
- if (Buf[I] == '\n') {
- LineOffsets.push_back(I + 1);
- } else if (Buf[I] == '\r') {
+ while (Buf < End) {
+ if (*Buf == '\n') {
+ LineOffsets.push_back(Buf - Start + 1);
+ } else if (*Buf == '\r') {
// If this is \r\n, skip both characters.
- if (I + 1 < BufLen && Buf[I + 1] == '\n')
- ++I;
- LineOffsets.push_back(I + 1);
+ if (Buf + 1 < End && Buf[1] == '\n') {
+ ++Buf;
+ }
+ LineOffsets.push_back(Buf - Start + 1);
}
- ++I;
+ ++Buf;
}
return LineOffsetMapping(LineOffsets, Alloc);
@@ -1368,9 +1306,9 @@ unsigned SourceManager::getLineNumber(FileID FID, unsigned FilePos,
}
// If this is the first use of line information for this buffer, compute the
- /// SourceLineCache for it on demand.
+ // SourceLineCache for it on demand.
if (!Content->SourceLineCache) {
- llvm::Optional<llvm::MemoryBufferRef> Buffer =
+ std::optional<llvm::MemoryBufferRef> Buffer =
Content->getBufferOrNone(Diag, getFileManager(), SourceLocation());
if (Invalid)
*Invalid = !Buffer;
@@ -1720,7 +1658,7 @@ SourceLocation SourceManager::translateLineCol(FileID FID,
// If this is the first use of line information for this buffer, compute the
// SourceLineCache for it on demand.
- llvm::Optional<llvm::MemoryBufferRef> Buffer =
+ std::optional<llvm::MemoryBufferRef> Buffer =
Content->getBufferOrNone(Diag, getFileManager());
if (!Buffer)
return SourceLocation();
@@ -1797,11 +1735,11 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache,
if (Entry.getFile().NumCreatedFIDs)
ID += Entry.getFile().NumCreatedFIDs - 1 /*because of next ++ID*/;
continue;
- } else if (IncludeLoc.isValid()) {
- // If file was included but not from FID, there is no more files/macros
- // that may be "contained" in this file.
- return;
}
+ // If file was included but not from FID, there is no more files/macros
+ // that may be "contained" in this file.
+ if (IncludeLoc.isValid())
+ return;
continue;
}
@@ -1973,14 +1911,39 @@ SourceManager::getDecomposedIncludedLoc(FileID FID) const {
return DecompLoc;
}
+bool SourceManager::isInTheSameTranslationUnitImpl(
+ const std::pair<FileID, unsigned> &LOffs,
+ const std::pair<FileID, unsigned> &ROffs) const {
+ // If one is local while the other is loaded.
+ if (isLoadedFileID(LOffs.first) != isLoadedFileID(ROffs.first))
+ return false;
+
+ if (isLoadedFileID(LOffs.first) && isLoadedFileID(ROffs.first)) {
+ auto FindSLocEntryAlloc = [this](FileID FID) {
+ // Loaded FileIDs are negative, we store the lowest FileID from each
+ // allocation, later allocations have lower FileIDs.
+ return llvm::lower_bound(LoadedSLocEntryAllocBegin, FID,
+ std::greater<FileID>{});
+ };
+
+ // If both are loaded from different AST files.
+ if (FindSLocEntryAlloc(LOffs.first) != FindSLocEntryAlloc(ROffs.first))
+ return false;
+ }
+
+ return true;
+}
+
/// Given a decomposed source location, move it up the include/expansion stack
-/// to the parent source location. If this is possible, return the decomposed
-/// version of the parent in Loc and return false. If Loc is the top-level
-/// entry, return true and don't modify it.
-static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc,
- const SourceManager &SM) {
+/// to the parent source location within the same translation unit. If this is
+/// possible, return the decomposed version of the parent in Loc and return
+/// false. If Loc is a top-level entry, return true and don't modify it.
+static bool
+MoveUpTranslationUnitIncludeHierarchy(std::pair<FileID, unsigned> &Loc,
+ const SourceManager &SM) {
std::pair<FileID, unsigned> UpperLoc = SM.getDecomposedIncludedLoc(Loc.first);
- if (UpperLoc.first.isInvalid())
+ if (UpperLoc.first.isInvalid() ||
+ !SM.isInTheSameTranslationUnitImpl(UpperLoc, Loc))
return true; // We reached the top.
Loc = UpperLoc;
@@ -1994,6 +1957,7 @@ InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID,
// This is a magic number for limiting the cache size. It was experimentally
// derived from a small Objective-C project (where the cache filled
// out to ~250 items). We can make it larger if necessary.
+ // FIXME: this is almost certainly full these days. Use an LRU cache?
enum { MagicCacheSize = 300 };
IsBeforeInTUCacheKey Key(LFID, RFID);
@@ -2002,7 +1966,7 @@ InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID,
// use. When they update the value, the cache will get automatically
// updated as well.
if (IBTUCache.size() < MagicCacheSize)
- return IBTUCache[Key];
+ return IBTUCache.try_emplace(Key, LFID, RFID).first->second;
// Otherwise, do a lookup that will not construct a new value.
InBeforeInTUCache::iterator I = IBTUCache.find(Key);
@@ -2010,6 +1974,7 @@ InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID,
return I->second;
// Fall back to the overflow value.
+ IBTUCacheOverflow.setQueryFIDs(LFID, RFID);
return IBTUCacheOverflow;
}
@@ -2034,45 +1999,18 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
std::pair<bool, bool> InSameTU = isInTheSameTranslationUnit(LOffs, ROffs);
if (InSameTU.first)
return InSameTU.second;
-
- // If we arrived here, the location is either in a built-ins buffer or
- // associated with global inline asm. PR5662 and PR22576 are examples.
-
- StringRef LB = getBufferOrFake(LOffs.first).getBufferIdentifier();
- StringRef RB = getBufferOrFake(ROffs.first).getBufferIdentifier();
- bool LIsBuiltins = LB == "<built-in>";
- bool RIsBuiltins = RB == "<built-in>";
- // Sort built-in before non-built-in.
- if (LIsBuiltins || RIsBuiltins) {
- if (LIsBuiltins != RIsBuiltins)
- return LIsBuiltins;
- // Both are in built-in buffers, but from different files. We just claim that
- // lower IDs come first.
- return LOffs.first < ROffs.first;
- }
- bool LIsAsm = LB == "<inline asm>";
- bool RIsAsm = RB == "<inline asm>";
- // Sort assembler after built-ins, but before the rest.
- if (LIsAsm || RIsAsm) {
- if (LIsAsm != RIsAsm)
- return RIsAsm;
- assert(LOffs.first == ROffs.first);
- return false;
- }
- bool LIsScratch = LB == "<scratch space>";
- bool RIsScratch = RB == "<scratch space>";
- // Sort scratch after inline asm, but before the rest.
- if (LIsScratch || RIsScratch) {
- if (LIsScratch != RIsScratch)
- return LIsScratch;
- return LOffs.second < ROffs.second;
- }
- llvm_unreachable("Unsortable locations found");
+ // TODO: This should be unreachable, but some clients are calling this
+ // function before making sure LHS and RHS are in the same TU.
+ return LOffs.first < ROffs.first;
}
std::pair<bool, bool> SourceManager::isInTheSameTranslationUnit(
std::pair<FileID, unsigned> &LOffs,
std::pair<FileID, unsigned> &ROffs) const {
+ // If the source locations are not in the same TU, return early.
+ if (!isInTheSameTranslationUnitImpl(LOffs, ROffs))
+ return std::make_pair(false, false);
+
// If the source locations are in the same file, just compare offsets.
if (LOffs.first == ROffs.first)
return std::make_pair(true, LOffs.second < ROffs.second);
@@ -2084,58 +2022,115 @@ std::pair<bool, bool> SourceManager::isInTheSameTranslationUnit(
// If we are comparing a source location with multiple locations in the same
// file, we get a big win by caching the result.
- if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first))
+ if (IsBeforeInTUCache.isCacheValid())
return std::make_pair(
true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second));
- // Okay, we missed in the cache, start updating the cache for this query.
- IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first,
- /*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID);
-
+ // Okay, we missed in the cache, we'll compute the answer and populate it.
// We need to find the common ancestor. The only way of doing this is to
// build the complete include chain for one and then walking up the chain
// of the other looking for a match.
- // We use a map from FileID to Offset to store the chain. Easier than writing
- // a custom set hash info that only depends on the first part of a pair.
- using LocSet = llvm::SmallDenseMap<FileID, unsigned, 16>;
- LocSet LChain;
+
+ // A location within a FileID on the path up from LOffs to the main file.
+ struct Entry {
+ std::pair<FileID, unsigned> DecomposedLoc; // FileID redundant, but clearer.
+ FileID ChildFID; // Used for breaking ties. Invalid for the initial loc.
+ };
+ llvm::SmallDenseMap<FileID, Entry, 16> LChain;
+
+ FileID LChild;
do {
- LChain.insert(LOffs);
+ LChain.try_emplace(LOffs.first, Entry{LOffs, LChild});
// We catch the case where LOffs is in a file included by ROffs and
// quit early. The other way round unfortunately remains suboptimal.
- } while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this));
- LocSet::iterator I;
- while((I = LChain.find(ROffs.first)) == LChain.end()) {
- if (MoveUpIncludeHierarchy(ROffs, *this))
- break; // Met at topmost file.
+ if (LOffs.first == ROffs.first)
+ break;
+ LChild = LOffs.first;
+ } while (!MoveUpTranslationUnitIncludeHierarchy(LOffs, *this));
+
+ FileID RChild;
+ do {
+ auto LIt = LChain.find(ROffs.first);
+ if (LIt != LChain.end()) {
+ // Compare the locations within the common file and cache them.
+ LOffs = LIt->second.DecomposedLoc;
+ LChild = LIt->second.ChildFID;
+ // The relative order of LChild and RChild is a tiebreaker when
+ // - locs expand to the same location (occurs in macro arg expansion)
+ // - one loc is a parent of the other (we consider the parent as "first")
+ // For the parent entry to be first, its invalid child file ID must
+ // compare smaller to the valid child file ID of the other entry.
+ // However loaded FileIDs are <0, so we perform *unsigned* comparison!
+ // This changes the relative order of local vs loaded FileIDs, but it
+ // doesn't matter as these are never mixed in macro expansion.
+ unsigned LChildID = LChild.ID;
+ unsigned RChildID = RChild.ID;
+ assert(((LOffs.second != ROffs.second) ||
+ (LChildID == 0 || RChildID == 0) ||
+ isInSameSLocAddrSpace(getComposedLoc(LChild, 0),
+ getComposedLoc(RChild, 0), nullptr)) &&
+ "Mixed local/loaded FileIDs with same include location?");
+ IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second,
+ LChildID < RChildID);
+ return std::make_pair(
+ true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second));
+ }
+ RChild = ROffs.first;
+ } while (!MoveUpTranslationUnitIncludeHierarchy(ROffs, *this));
+
+ // If we found no match, the location is either in a built-ins buffer or
+ // associated with global inline asm. PR5662 and PR22576 are examples.
+
+ StringRef LB = getBufferOrFake(LOffs.first).getBufferIdentifier();
+ StringRef RB = getBufferOrFake(ROffs.first).getBufferIdentifier();
+
+ bool LIsBuiltins = LB == "<built-in>";
+ bool RIsBuiltins = RB == "<built-in>";
+ // Sort built-in before non-built-in.
+ if (LIsBuiltins || RIsBuiltins) {
+ if (LIsBuiltins != RIsBuiltins)
+ return std::make_pair(true, LIsBuiltins);
+ // Both are in built-in buffers, but from different files. We just claim
+ // that lower IDs come first.
+ return std::make_pair(true, LOffs.first < ROffs.first);
}
- if (I != LChain.end())
- LOffs = *I;
- // If we exited because we found a nearest common ancestor, compare the
- // locations within the common file and cache them.
- if (LOffs.first == ROffs.first) {
- IsBeforeInTUCache.setCommonLoc(LOffs.first, LOffs.second, ROffs.second);
- return std::make_pair(
- true, IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second));
+ bool LIsAsm = LB == "<inline asm>";
+ bool RIsAsm = RB == "<inline asm>";
+ // Sort assembler after built-ins, but before the rest.
+ if (LIsAsm || RIsAsm) {
+ if (LIsAsm != RIsAsm)
+ return std::make_pair(true, RIsAsm);
+ assert(LOffs.first == ROffs.first);
+ return std::make_pair(true, false);
+ }
+
+ bool LIsScratch = LB == "<scratch space>";
+ bool RIsScratch = RB == "<scratch space>";
+ // Sort scratch after inline asm, but before the rest.
+ if (LIsScratch || RIsScratch) {
+ if (LIsScratch != RIsScratch)
+ return std::make_pair(true, LIsScratch);
+ return std::make_pair(true, LOffs.second < ROffs.second);
}
- // Clear the lookup cache, it depends on a common location.
- IsBeforeInTUCache.clear();
- return std::make_pair(false, false);
+
+ llvm_unreachable("Unsortable locations found");
}
void SourceManager::PrintStats() const {
llvm::errs() << "\n*** Source Manager Stats:\n";
llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
<< " mem buffers mapped.\n";
- llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntry's allocated ("
+ llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntries allocated ("
<< llvm::capacity_in_bytes(LocalSLocEntryTable)
- << " bytes of capacity), "
- << NextLocalOffset << "B of Sloc address space used.\n";
+ << " bytes of capacity), " << NextLocalOffset
+ << "B of SLoc address space used.\n";
llvm::errs() << LoadedSLocEntryTable.size()
- << " loaded SLocEntries allocated, "
+ << " loaded SLocEntries allocated ("
+ << llvm::capacity_in_bytes(LoadedSLocEntryTable)
+ << " bytes of capacity), "
<< MaxLoadedOffset - CurrentLoadedOffset
- << "B of Sloc address space used.\n";
+ << "B of SLoc address space used.\n";
unsigned NumLineNumsComputed = 0;
unsigned NumFileBytesMapped = 0;
@@ -2156,7 +2151,7 @@ LLVM_DUMP_METHOD void SourceManager::dump() const {
llvm::raw_ostream &out = llvm::errs();
auto DumpSLocEntry = [&](int ID, const SrcMgr::SLocEntry &Entry,
- llvm::Optional<SourceLocation::UIntTy> NextStart) {
+ std::optional<SourceLocation::UIntTy> NextStart) {
out << "SLocEntry <FileID " << ID << "> " << (Entry.isFile() ? "file" : "expansion")
<< " <SourceLocation " << Entry.getOffset() << ":";
if (NextStart)
@@ -2196,15 +2191,103 @@ LLVM_DUMP_METHOD void SourceManager::dump() const {
: LocalSLocEntryTable[ID + 1].getOffset());
}
// Dump loaded SLocEntries.
- llvm::Optional<SourceLocation::UIntTy> NextStart;
+ std::optional<SourceLocation::UIntTy> NextStart;
for (unsigned Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
int ID = -(int)Index - 2;
if (SLocEntryLoaded[Index]) {
DumpSLocEntry(ID, LoadedSLocEntryTable[Index], NextStart);
NextStart = LoadedSLocEntryTable[Index].getOffset();
} else {
- NextStart = None;
+ NextStart = std::nullopt;
+ }
+ }
+}
+
+void SourceManager::noteSLocAddressSpaceUsage(
+ DiagnosticsEngine &Diag, std::optional<unsigned> MaxNotes) const {
+ struct Info {
+ // A location where this file was entered.
+ SourceLocation Loc;
+ // Number of times this FileEntry was entered.
+ unsigned Inclusions = 0;
+ // Size usage from the file itself.
+ uint64_t DirectSize = 0;
+ // Total size usage from the file and its macro expansions.
+ uint64_t TotalSize = 0;
+ };
+ using UsageMap = llvm::MapVector<const FileEntry*, Info>;
+
+ UsageMap Usage;
+ uint64_t CountedSize = 0;
+
+ auto AddUsageForFileID = [&](FileID ID) {
+ // The +1 here is because getFileIDSize doesn't include the extra byte for
+ // the one-past-the-end location.
+ unsigned Size = getFileIDSize(ID) + 1;
+
+ // Find the file that used this address space, either directly or by
+ // macro expansion.
+ SourceLocation FileStart = getFileLoc(getComposedLoc(ID, 0));
+ FileID FileLocID = getFileID(FileStart);
+ const FileEntry *Entry = getFileEntryForID(FileLocID);
+
+ Info &EntryInfo = Usage[Entry];
+ if (EntryInfo.Loc.isInvalid())
+ EntryInfo.Loc = FileStart;
+ if (ID == FileLocID) {
+ ++EntryInfo.Inclusions;
+ EntryInfo.DirectSize += Size;
}
+ EntryInfo.TotalSize += Size;
+ CountedSize += Size;
+ };
+
+ // Loaded SLocEntries have indexes counting downwards from -2.
+ for (size_t Index = 0; Index != LoadedSLocEntryTable.size(); ++Index) {
+ AddUsageForFileID(FileID::get(-2 - Index));
+ }
+ // Local SLocEntries have indexes counting upwards from 0.
+ for (size_t Index = 0; Index != LocalSLocEntryTable.size(); ++Index) {
+ AddUsageForFileID(FileID::get(Index));
+ }
+
+ // Sort the usage by size from largest to smallest. Break ties by raw source
+ // location.
+ auto SortedUsage = Usage.takeVector();
+ auto Cmp = [](const UsageMap::value_type &A, const UsageMap::value_type &B) {
+ return A.second.TotalSize > B.second.TotalSize ||
+ (A.second.TotalSize == B.second.TotalSize &&
+ A.second.Loc < B.second.Loc);
+ };
+ auto SortedEnd = SortedUsage.end();
+ if (MaxNotes && SortedUsage.size() > *MaxNotes) {
+ SortedEnd = SortedUsage.begin() + *MaxNotes;
+ std::nth_element(SortedUsage.begin(), SortedEnd, SortedUsage.end(), Cmp);
+ }
+ std::sort(SortedUsage.begin(), SortedEnd, Cmp);
+
+ // Produce note on sloc address space usage total.
+ uint64_t LocalUsage = NextLocalOffset;
+ uint64_t LoadedUsage = MaxLoadedOffset - CurrentLoadedOffset;
+ int UsagePercent = static_cast<int>(100.0 * double(LocalUsage + LoadedUsage) /
+ MaxLoadedOffset);
+ Diag.Report(SourceLocation(), diag::note_total_sloc_usage)
+ << LocalUsage << LoadedUsage << (LocalUsage + LoadedUsage) << UsagePercent;
+
+ // Produce notes on sloc address space usage for each file with a high usage.
+ uint64_t ReportedSize = 0;
+ for (auto &[Entry, FileInfo] :
+ llvm::make_range(SortedUsage.begin(), SortedEnd)) {
+ Diag.Report(FileInfo.Loc, diag::note_file_sloc_usage)
+ << FileInfo.Inclusions << FileInfo.DirectSize
+ << (FileInfo.TotalSize - FileInfo.DirectSize);
+ ReportedSize += FileInfo.TotalSize;
+ }
+
+ // Describe any remaining usage not reported in the per-file usage.
+ if (ReportedSize != CountedSize) {
+ Diag.Report(SourceLocation(), diag::note_file_misc_sloc_usage)
+ << (SortedUsage.end() - SortedEnd) << CountedSize - ReportedSize;
}
}
@@ -2231,11 +2314,11 @@ SourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const {
}
size_t SourceManager::getDataStructureSizes() const {
- size_t size = llvm::capacity_in_bytes(MemBufferInfos)
- + llvm::capacity_in_bytes(LocalSLocEntryTable)
- + llvm::capacity_in_bytes(LoadedSLocEntryTable)
- + llvm::capacity_in_bytes(SLocEntryLoaded)
- + llvm::capacity_in_bytes(FileInfos);
+ size_t size = llvm::capacity_in_bytes(MemBufferInfos) +
+ llvm::capacity_in_bytes(LocalSLocEntryTable) +
+ llvm::capacity_in_bytes(LoadedSLocEntryTable) +
+ llvm::capacity_in_bytes(SLocEntryLoaded) +
+ llvm::capacity_in_bytes(FileInfos);
if (OverriddenFilesInfo)
size += llvm::capacity_in_bytes(OverriddenFilesInfo->OverriddenFiles);
@@ -2263,8 +2346,9 @@ SourceManagerForFile::SourceManagerForFile(StringRef FileName,
IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
new DiagnosticOptions);
SourceMgr = std::make_unique<SourceManager>(*Diagnostics, *FileMgr);
- FileID ID = SourceMgr->createFileID(*FileMgr->getFile(FileName),
- SourceLocation(), clang::SrcMgr::C_User);
+ FileEntryRef FE = llvm::cantFail(FileMgr->getFileRef(FileName));
+ FileID ID =
+ SourceMgr->createFileID(FE, SourceLocation(), clang::SrcMgr::C_User);
assert(ID.isValid());
SourceMgr->setMainFileID(ID);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp b/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp
new file mode 100644
index 000000000000..e39e4de9d42d
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/SourceMgrAdapter.cpp
@@ -0,0 +1,136 @@
+//=== SourceMgrAdapter.cpp - SourceMgr to SourceManager Adapter -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the adapter that maps diagnostics from llvm::SourceMgr
+// to Clang's SourceManager.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/SourceMgrAdapter.h"
+#include "clang/Basic/Diagnostic.h"
+
+using namespace clang;
+
+void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag,
+ void *Context) {
+ static_cast<SourceMgrAdapter *>(Context)->handleDiag(Diag);
+}
+
+SourceMgrAdapter::SourceMgrAdapter(SourceManager &SM,
+ DiagnosticsEngine &Diagnostics,
+ unsigned ErrorDiagID, unsigned WarningDiagID,
+ unsigned NoteDiagID,
+ OptionalFileEntryRef DefaultFile)
+ : SrcMgr(SM), Diagnostics(Diagnostics), ErrorDiagID(ErrorDiagID),
+ WarningDiagID(WarningDiagID), NoteDiagID(NoteDiagID),
+ DefaultFile(DefaultFile) {}
+
+SourceMgrAdapter::~SourceMgrAdapter() {}
+
+SourceLocation SourceMgrAdapter::mapLocation(const llvm::SourceMgr &LLVMSrcMgr,
+ llvm::SMLoc Loc) {
+ // Map invalid locations.
+ if (!Loc.isValid())
+ return SourceLocation();
+
+ // Find the buffer containing the location.
+ unsigned BufferID = LLVMSrcMgr.FindBufferContainingLoc(Loc);
+ if (!BufferID)
+ return SourceLocation();
+
+ // If we haven't seen this buffer before, copy it over.
+ auto Buffer = LLVMSrcMgr.getMemoryBuffer(BufferID);
+ auto KnownBuffer = FileIDMapping.find(std::make_pair(&LLVMSrcMgr, BufferID));
+ if (KnownBuffer == FileIDMapping.end()) {
+ FileID FileID;
+ if (DefaultFile) {
+ // Map to the default file.
+ FileID = SrcMgr.getOrCreateFileID(*DefaultFile, SrcMgr::C_User);
+
+ // Only do this once.
+ DefaultFile = std::nullopt;
+ } else {
+ // Make a copy of the memory buffer.
+ StringRef bufferName = Buffer->getBufferIdentifier();
+ auto bufferCopy = std::unique_ptr<llvm::MemoryBuffer>(
+ llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(),
+ bufferName));
+
+ // Add this memory buffer to the Clang source manager.
+ FileID = SrcMgr.createFileID(std::move(bufferCopy));
+ }
+
+ // Save the mapping.
+ KnownBuffer = FileIDMapping
+ .insert(std::make_pair(
+ std::make_pair(&LLVMSrcMgr, BufferID), FileID))
+ .first;
+ }
+
+ // Translate the offset into the file.
+ unsigned Offset = Loc.getPointer() - Buffer->getBufferStart();
+ return SrcMgr.getLocForStartOfFile(KnownBuffer->second)
+ .getLocWithOffset(Offset);
+}
+
+SourceRange SourceMgrAdapter::mapRange(const llvm::SourceMgr &LLVMSrcMgr,
+ llvm::SMRange Range) {
+ if (!Range.isValid())
+ return SourceRange();
+
+ SourceLocation Start = mapLocation(LLVMSrcMgr, Range.Start);
+ SourceLocation End = mapLocation(LLVMSrcMgr, Range.End);
+ return SourceRange(Start, End);
+}
+
+void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &Diag) {
+ // Map the location.
+ SourceLocation Loc;
+ if (auto *LLVMSrcMgr = Diag.getSourceMgr())
+ Loc = mapLocation(*LLVMSrcMgr, Diag.getLoc());
+
+ // Extract the message.
+ StringRef Message = Diag.getMessage();
+
+ // Map the diagnostic kind.
+ unsigned DiagID;
+ switch (Diag.getKind()) {
+ case llvm::SourceMgr::DK_Error:
+ DiagID = ErrorDiagID;
+ break;
+
+ case llvm::SourceMgr::DK_Warning:
+ DiagID = WarningDiagID;
+ break;
+
+ case llvm::SourceMgr::DK_Remark:
+ llvm_unreachable("remarks not implemented");
+
+ case llvm::SourceMgr::DK_Note:
+ DiagID = NoteDiagID;
+ break;
+ }
+
+ // Report the diagnostic.
+ DiagnosticBuilder Builder = Diagnostics.Report(Loc, DiagID) << Message;
+
+ if (auto *LLVMSrcMgr = Diag.getSourceMgr()) {
+ // Translate ranges.
+ SourceLocation StartOfLine = Loc.getLocWithOffset(-Diag.getColumnNo());
+ for (auto Range : Diag.getRanges()) {
+ Builder << SourceRange(StartOfLine.getLocWithOffset(Range.first),
+ StartOfLine.getLocWithOffset(Range.second));
+ }
+
+ // Translate Fix-Its.
+ for (const llvm::SMFixIt &FixIt : Diag.getFixIts()) {
+ CharSourceRange Range(mapRange(*LLVMSrcMgr, FixIt.getRange()), false);
+ Builder << FixItHint::CreateReplacement(Range, FixIt.getText());
+ }
+ }
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Stack.cpp b/contrib/llvm-project/clang/lib/Basic/Stack.cpp
index 5e4750931500..aa15d8e66950 100644
--- a/contrib/llvm-project/clang/lib/Basic/Stack.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Stack.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/Stack.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/Support/CrashRecoveryContext.h"
#ifdef _MSC_VER
diff --git a/contrib/llvm-project/clang/lib/Basic/TargetID.cpp b/contrib/llvm-project/clang/lib/Basic/TargetID.cpp
index 59d416f0e015..3c06d9bad1dc 100644
--- a/contrib/llvm-project/clang/lib/Basic/TargetID.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/TargetID.cpp
@@ -8,14 +8,15 @@
#include "clang/Basic/TargetID.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/TargetParser.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/TargetParser.h"
+#include "llvm/TargetParser/Triple.h"
#include <map>
+#include <optional>
namespace clang {
-static const llvm::SmallVector<llvm::StringRef, 4>
+static llvm::SmallVector<llvm::StringRef, 4>
getAllPossibleAMDGPUTargetIDFeatures(const llvm::Triple &T,
llvm::StringRef Proc) {
// Entries in returned vector should be in alphabetical order.
@@ -33,7 +34,7 @@ getAllPossibleAMDGPUTargetIDFeatures(const llvm::Triple &T,
return Ret;
}
-const llvm::SmallVector<llvm::StringRef, 4>
+llvm::SmallVector<llvm::StringRef, 4>
getAllPossibleTargetIDFeatures(const llvm::Triple &T,
llvm::StringRef Processor) {
llvm::SmallVector<llvm::StringRef, 4> Ret;
@@ -62,7 +63,7 @@ llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T,
// A target ID is a processor name followed by a list of target features
// delimited by colon. Each target feature is a string post-fixed by a plus
// or minus sign, e.g. gfx908:sramecc+:xnack-.
-static llvm::Optional<llvm::StringRef>
+static std::optional<llvm::StringRef>
parseTargetIDWithFormatCheckingOnly(llvm::StringRef TargetID,
llvm::StringMap<bool> *FeatureMap) {
llvm::StringRef Processor;
@@ -73,7 +74,7 @@ parseTargetIDWithFormatCheckingOnly(llvm::StringRef TargetID,
auto Split = TargetID.split(':');
Processor = Split.first;
if (Processor.empty())
- return llvm::None;
+ return std::nullopt;
auto Features = Split.second;
if (Features.empty())
@@ -88,31 +89,30 @@ parseTargetIDWithFormatCheckingOnly(llvm::StringRef TargetID,
auto Sign = Splits.first.back();
auto Feature = Splits.first.drop_back();
if (Sign != '+' && Sign != '-')
- return llvm::None;
+ return std::nullopt;
bool IsOn = Sign == '+';
auto Loc = FeatureMap->find(Feature);
// Each feature can only show up at most once in target ID.
if (Loc != FeatureMap->end())
- return llvm::None;
+ return std::nullopt;
(*FeatureMap)[Feature] = IsOn;
Features = Splits.second;
}
return Processor;
}
-llvm::Optional<llvm::StringRef>
+std::optional<llvm::StringRef>
parseTargetID(const llvm::Triple &T, llvm::StringRef TargetID,
llvm::StringMap<bool> *FeatureMap) {
auto OptionalProcessor =
parseTargetIDWithFormatCheckingOnly(TargetID, FeatureMap);
if (!OptionalProcessor)
- return llvm::None;
+ return std::nullopt;
- llvm::StringRef Processor =
- getCanonicalProcessorName(T, OptionalProcessor.getValue());
+ llvm::StringRef Processor = getCanonicalProcessorName(T, *OptionalProcessor);
if (Processor.empty())
- return llvm::None;
+ return std::nullopt;
llvm::SmallSet<llvm::StringRef, 4> AllFeatures;
for (auto &&F : getAllPossibleTargetIDFeatures(T, Processor))
@@ -120,7 +120,7 @@ parseTargetID(const llvm::Triple &T, llvm::StringRef TargetID,
for (auto &&F : *FeatureMap)
if (!AllFeatures.count(F.first()))
- return llvm::None;
+ return std::nullopt;
return Processor;
}
@@ -133,7 +133,7 @@ std::string getCanonicalTargetID(llvm::StringRef Processor,
std::map<const llvm::StringRef, bool> OrderedMap;
for (const auto &F : Features)
OrderedMap[F.first()] = F.second;
- for (auto F : OrderedMap)
+ for (const auto &F : OrderedMap)
TargetID = TargetID + ':' + F.first.str() + (F.second ? "+" : "-");
return TargetID;
}
@@ -141,7 +141,7 @@ std::string getCanonicalTargetID(llvm::StringRef Processor,
// For a specific processor, a feature either shows up in all target IDs, or
// does not show up in any target IDs. Otherwise the target ID combination
// is invalid.
-llvm::Optional<std::pair<llvm::StringRef, llvm::StringRef>>
+std::optional<std::pair<llvm::StringRef, llvm::StringRef>>
getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs) {
struct Info {
llvm::StringRef TargetID;
@@ -150,8 +150,7 @@ getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs) {
llvm::StringMap<Info> FeatureMap;
for (auto &&ID : TargetIDs) {
llvm::StringMap<bool> Features;
- llvm::StringRef Proc =
- parseTargetIDWithFormatCheckingOnly(ID, &Features).getValue();
+ llvm::StringRef Proc = *parseTargetIDWithFormatCheckingOnly(ID, &Features);
auto Loc = FeatureMap.find(Proc);
if (Loc == FeatureMap.end())
FeatureMap[Proc] = Info{ID, Features};
@@ -163,7 +162,28 @@ getConflictTargetIDCombination(const std::set<llvm::StringRef> &TargetIDs) {
return std::make_pair(Loc->second.TargetID, ID);
}
}
- return llvm::None;
+ return std::nullopt;
+}
+
+bool isCompatibleTargetID(llvm::StringRef Provided, llvm::StringRef Requested) {
+ llvm::StringMap<bool> ProvidedFeatures, RequestedFeatures;
+ llvm::StringRef ProvidedProc =
+ *parseTargetIDWithFormatCheckingOnly(Provided, &ProvidedFeatures);
+ llvm::StringRef RequestedProc =
+ *parseTargetIDWithFormatCheckingOnly(Requested, &RequestedFeatures);
+ if (ProvidedProc != RequestedProc)
+ return false;
+ for (const auto &F : ProvidedFeatures) {
+ auto Loc = RequestedFeatures.find(F.first());
+ // The default (unspecified) value of a feature is 'All', which can match
+ // either 'On' or 'Off'.
+ if (Loc == RequestedFeatures.end())
+ return false;
+ // If a feature is specified, it must have exact match.
+ if (Loc->second != F.second)
+ return false;
+ }
+ return true;
}
} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp
index 5f8e04c2bd6c..96b3ad9ba2f2 100644
--- a/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/TargetInfo.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements the TargetInfo and TargetInfoImpl interfaces.
+// This file implements the TargetInfo interface.
//
//===----------------------------------------------------------------------===//
@@ -14,18 +14,44 @@
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/TargetParser.h"
+#include "llvm/TargetParser/TargetParser.h"
#include <cstdlib>
using namespace clang;
static const LangASMap DefaultAddrSpaceMap = {0};
+// The fake address space map must have a distinct entry for each
+// language-specific address space.
+static const LangASMap FakeAddrSpaceMap = {
+ 0, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 0, // opencl_private
+ 4, // opencl_generic
+ 5, // opencl_global_device
+ 6, // opencl_global_host
+ 7, // cuda_device
+ 8, // cuda_constant
+ 9, // cuda_shared
+ 1, // sycl_global
+ 5, // sycl_global_device
+ 6, // sycl_global_host
+ 3, // sycl_local
+ 0, // sycl_private
+ 10, // ptr32_sptr
+ 11, // ptr32_uptr
+ 12, // ptr64
+ 13, // hlsl_groupshared
+ 20, // wasm_funcref
+};
// TargetInfo Constructor.
-TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
+TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
// Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or
// SPARC. These should be overridden by concrete targets as needed.
BigEndian = !T.isLittleEndian();
@@ -33,15 +59,21 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
VLASupported = true;
NoAsmVariants = false;
HasLegalHalfType = false;
+ HalfArgsAndReturns = false;
HasFloat128 = false;
+ HasIbm128 = false;
HasFloat16 = false;
HasBFloat16 = false;
+ HasFullBFloat16 = false;
+ HasLongDouble = true;
+ HasFPReturn = true;
HasStrictFP = false;
PointerWidth = PointerAlign = 32;
BoolWidth = BoolAlign = 8;
IntWidth = IntAlign = 32;
LongWidth = LongAlign = 32;
LongLongWidth = LongLongAlign = 64;
+ Int128Align = 128;
// Fixed point default bit widths
ShortAccumWidth = ShortAccumAlign = 16;
@@ -66,11 +98,12 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
// From the glibc documentation, on GNU systems, malloc guarantees 16-byte
// alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See
// https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.
- // This alignment guarantee also applies to Windows and Android. On Darwin,
- // the alignment is 16 bytes on both 64-bit and 32-bit systems.
- if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid())
+ // This alignment guarantee also applies to Windows and Android. On Darwin
+ // and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems.
+ if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() ||
+ T.isOHOSFamily())
NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;
- else if (T.isOSDarwin())
+ else if (T.isOSDarwin() || T.isOSOpenBSD())
NewAlign = 128;
else
NewAlign = 0; // Infer from basic type alignment.
@@ -83,12 +116,12 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
LongDoubleWidth = 64;
LongDoubleAlign = 64;
Float128Align = 128;
+ Ibm128Align = 128;
LargeArrayMinWidth = 0;
LargeArrayAlign = 0;
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
MaxVectorAlign = 0;
MaxTLSAlign = 0;
- SimdDefaultAlign = 0;
SizeType = UnsignedLong;
PtrDiffType = SignedLong;
IntMaxType = SignedLongLong;
@@ -113,6 +146,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
DoubleFormat = &llvm::APFloat::IEEEdouble();
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
Float128Format = &llvm::APFloat::IEEEquad();
+ Ibm128Format = &llvm::APFloat::PPCDoubleDouble();
MCountName = "mcount";
UserLabelPrefix = "_";
RegParmMax = 0;
@@ -126,7 +160,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
ARMCDECoprocMask = 0;
// Default to no types using fpret.
- RealTypeUsesObjCFPRet = 0;
+ RealTypeUsesObjCFPRetMask = 0;
// Default to not using fp2ret for __Complex long double
ComplexLongDoubleUsesFP2Ret = false;
@@ -145,6 +179,8 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
PlatformMinVersion = VersionTuple();
MaxOpenCLWorkGroupSize = 1024;
+
+ MaxBitIntWidth.reset();
}
// Out of line virtual dtor for TargetInfo.
@@ -198,11 +234,11 @@ const char *TargetInfo::getTypeConstantSuffix(IntType T) const {
case UnsignedChar:
if (getCharWidth() < getIntWidth())
return "";
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case UnsignedShort:
if (getShortWidth() < getIntWidth())
return "";
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case UnsignedInt: return "U";
case UnsignedLong: return "UL";
case UnsignedLongLong: return "ULL";
@@ -276,32 +312,38 @@ TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
return NoInt;
}
-TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth,
- bool ExplicitIEEE) const {
+FloatModeKind TargetInfo::getRealTypeByWidth(unsigned BitWidth,
+ FloatModeKind ExplicitType) const {
+ if (getHalfWidth() == BitWidth)
+ return FloatModeKind::Half;
if (getFloatWidth() == BitWidth)
- return Float;
+ return FloatModeKind::Float;
if (getDoubleWidth() == BitWidth)
- return Double;
+ return FloatModeKind::Double;
switch (BitWidth) {
case 96:
if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended())
- return LongDouble;
+ return FloatModeKind::LongDouble;
break;
case 128:
// The caller explicitly asked for an IEEE compliant type but we still
// have to check if the target supports it.
- if (ExplicitIEEE)
- return hasFloat128Type() ? Float128 : NoFloat;
+ if (ExplicitType == FloatModeKind::Float128)
+ return hasFloat128Type() ? FloatModeKind::Float128
+ : FloatModeKind::NoFloat;
+ if (ExplicitType == FloatModeKind::Ibm128)
+ return hasIbm128Type() ? FloatModeKind::Ibm128
+ : FloatModeKind::NoFloat;
if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() ||
&getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
- return LongDouble;
+ return FloatModeKind::LongDouble;
if (hasFloat128Type())
- return Float128;
+ return FloatModeKind::Float128;
break;
}
- return NoFloat;
+ return FloatModeKind::NoFloat;
}
/// getTypeAlign - Return the alignment (in bits) of the specified integer type
@@ -406,12 +448,14 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
// for OpenCL C 2.0 but with no access to target capabilities. Target
// should be immutable once created and thus these language options need
// to be defined only once.
- if (Opts.OpenCLVersion == 300) {
+ if (Opts.getOpenCLCompatibleVersion() == 300) {
const auto &OpenCLFeaturesMap = getSupportedOpenCLOpts();
Opts.OpenCLGenericAddressSpace = hasFeatureEnabled(
OpenCLFeaturesMap, "__opencl_c_generic_address_space");
Opts.OpenCLPipes =
hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_pipes");
+ Opts.Blocks =
+ hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue");
}
}
@@ -437,6 +481,20 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
} else if (Opts.LongDoubleSize == 128) {
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::IEEEquad();
+ } else if (Opts.LongDoubleSize == 80) {
+ LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
+ if (getTriple().isWindowsMSVCEnvironment()) {
+ LongDoubleWidth = 128;
+ LongDoubleAlign = 128;
+ } else { // Linux
+ if (getTriple().getArch() == llvm::Triple::x86) {
+ LongDoubleWidth = 96;
+ LongDoubleAlign = 32;
+ } else {
+ LongDoubleWidth = 128;
+ LongDoubleAlign = 128;
+ }
+ }
}
}
@@ -452,6 +510,12 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";
Opts.ProtectParens = false;
}
+
+ if (Opts.MaxBitIntWidth)
+ MaxBitIntWidth = static_cast<unsigned>(Opts.MaxBitIntWidth);
+
+ if (Opts.FakeAddressSpaceMap)
+ AddrSpaceMap = &FakeAddrSpaceMap;
}
bool TargetInfo::initFeatureMap(
@@ -459,21 +523,73 @@ bool TargetInfo::initFeatureMap(
const std::vector<std::string> &FeatureVec) const {
for (const auto &F : FeatureVec) {
StringRef Name = F;
+ if (Name.empty())
+ continue;
// Apply the feature via the target.
- bool Enabled = Name[0] == '+';
- setFeatureEnabled(Features, Name.substr(1), Enabled);
+ if (Name[0] != '+' && Name[0] != '-')
+ Diags.Report(diag::warn_fe_backend_invalid_feature_flag) << Name;
+ else
+ setFeatureEnabled(Features, Name.substr(1), Name[0] == '+');
}
return true;
}
+ParsedTargetAttr TargetInfo::parseTargetAttr(StringRef Features) const {
+ ParsedTargetAttr Ret;
+ if (Features == "default")
+ return Ret;
+ SmallVector<StringRef, 1> AttrFeatures;
+ Features.split(AttrFeatures, ",");
+
+ // Grab the various features and prepend a "+" to turn on the feature to
+ // the backend and add them to our existing set of features.
+ for (auto &Feature : AttrFeatures) {
+ // Go ahead and trim whitespace rather than either erroring or
+ // accepting it weirdly.
+ Feature = Feature.trim();
+
+ // TODO: Support the fpmath option. It will require checking
+ // overall feature validity for the function with the rest of the
+ // attributes on the function.
+ if (Feature.starts_with("fpmath="))
+ continue;
+
+ if (Feature.starts_with("branch-protection=")) {
+ Ret.BranchProtection = Feature.split('=').second.trim();
+ continue;
+ }
+
+ // While we're here iterating check for a different target cpu.
+ if (Feature.starts_with("arch=")) {
+ if (!Ret.CPU.empty())
+ Ret.Duplicate = "arch=";
+ else
+ Ret.CPU = Feature.split("=").second.trim();
+ } else if (Feature.starts_with("tune=")) {
+ if (!Ret.Tune.empty())
+ Ret.Duplicate = "tune=";
+ else
+ Ret.Tune = Feature.split("=").second.trim();
+ } else if (Feature.starts_with("no-"))
+ Ret.Features.push_back("-" + Feature.split("-").second.str());
+ else
+ Ret.Features.push_back("+" + Feature.str());
+ }
+ return Ret;
+}
+
TargetInfo::CallingConvKind
TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
if (getCXXABI() != TargetCXXABI::Microsoft &&
- (ClangABICompat4 || getTriple().getOS() == llvm::Triple::PS4))
+ (ClangABICompat4 || getTriple().isPS4()))
return CCK_ClangABI4OrPS4;
return CCK_Default;
}
+bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const {
+ return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15;
+}
+
LangAS TargetInfo::getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const {
switch (TK) {
case OCLTK_Image:
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets.cpp b/contrib/llvm-project/clang/lib/Basic/Targets.cpp
index ba91d0439968..e3283510c6aa 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets.cpp
@@ -19,9 +19,12 @@
#include "Targets/ARM.h"
#include "Targets/AVR.h"
#include "Targets/BPF.h"
+#include "Targets/CSKY.h"
+#include "Targets/DirectX.h"
#include "Targets/Hexagon.h"
#include "Targets/Lanai.h"
#include "Targets/Le64.h"
+#include "Targets/LoongArch.h"
#include "Targets/M68k.h"
#include "Targets/MSP430.h"
#include "Targets/Mips.h"
@@ -39,8 +42,9 @@
#include "Targets/X86.h"
#include "Targets/XCore.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticFrontend.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/TargetParser/Triple.h"
using namespace clang;
@@ -78,9 +82,10 @@ void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, bool Tuning) {
void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) {
// Mingw and cygwin define __declspec(a) to __attribute__((a)). Clang
- // supports __declspec natively under -fms-extensions, but we define a no-op
- // __declspec macro anyway for pre-processor compatibility.
- if (Opts.MicrosoftExt)
+ // supports __declspec natively under -fdeclspec (also enabled with
+ // -fms-extensions), but we define a no-op __declspec macro anyway for
+ // pre-processor compatibility.
+ if (Opts.DeclSpecKeyword)
Builder.defineMacro("__declspec", "__declspec");
else
Builder.defineMacro("__declspec(a)", "__attribute__((a))");
@@ -104,8 +109,8 @@ void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) {
// Driver code
//===----------------------------------------------------------------------===//
-TargetInfo *AllocateTarget(const llvm::Triple &Triple,
- const TargetOptions &Opts) {
+std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
+ const TargetOptions &Opts) {
llvm::Triple::OSType os = Triple.getOS();
switch (Triple.getArch()) {
@@ -113,498 +118,564 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return nullptr;
case llvm::Triple::arc:
- return new ARCTargetInfo(Triple, Opts);
+ return std::make_unique<ARCTargetInfo>(Triple, Opts);
case llvm::Triple::xcore:
- return new XCoreTargetInfo(Triple, Opts);
+ return std::make_unique<XCoreTargetInfo>(Triple, Opts);
case llvm::Triple::hexagon:
if (os == llvm::Triple::Linux &&
Triple.getEnvironment() == llvm::Triple::Musl)
- return new LinuxTargetInfo<HexagonTargetInfo>(Triple, Opts);
- return new HexagonTargetInfo(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<HexagonTargetInfo>>(Triple, Opts);
+ return std::make_unique<HexagonTargetInfo>(Triple, Opts);
case llvm::Triple::lanai:
- return new LanaiTargetInfo(Triple, Opts);
+ return std::make_unique<LanaiTargetInfo>(Triple, Opts);
case llvm::Triple::aarch64_32:
if (Triple.isOSDarwin())
- return new DarwinAArch64TargetInfo(Triple, Opts);
+ return std::make_unique<DarwinAArch64TargetInfo>(Triple, Opts);
return nullptr;
case llvm::Triple::aarch64:
if (Triple.isOSDarwin())
- return new DarwinAArch64TargetInfo(Triple, Opts);
+ return std::make_unique<DarwinAArch64TargetInfo>(Triple, Opts);
switch (os) {
- case llvm::Triple::CloudABI:
- return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<AArch64leTargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Fuchsia:
- return new FuchsiaTargetInfo<AArch64leTargetInfo>(Triple, Opts);
+ return std::make_unique<FuchsiaTargetInfo<AArch64leTargetInfo>>(Triple,
+ Opts);
+ case llvm::Triple::Haiku:
+ return std::make_unique<HaikuTargetInfo<AArch64leTargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts);
+ switch (Triple.getEnvironment()) {
+ default:
+ return std::make_unique<LinuxTargetInfo<AArch64leTargetInfo>>(Triple,
+ Opts);
+ case llvm::Triple::OpenHOS:
+ return std::make_unique<OHOSTargetInfo<AArch64leTargetInfo>>(Triple,
+ Opts);
+ }
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<AArch64leTargetInfo>>(Triple,
+ Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<AArch64leTargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Win32:
switch (Triple.getEnvironment()) {
case llvm::Triple::GNU:
- return new MinGWARM64TargetInfo(Triple, Opts);
+ return std::make_unique<MinGWARM64TargetInfo>(Triple, Opts);
case llvm::Triple::MSVC:
default: // Assume MSVC for unknown environments
- return new MicrosoftARM64TargetInfo(Triple, Opts);
+ return std::make_unique<MicrosoftARM64TargetInfo>(Triple, Opts);
}
default:
- return new AArch64leTargetInfo(Triple, Opts);
+ return std::make_unique<AArch64leTargetInfo>(Triple, Opts);
}
case llvm::Triple::aarch64_be:
switch (os) {
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<AArch64beTargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Fuchsia:
- return new FuchsiaTargetInfo<AArch64beTargetInfo>(Triple, Opts);
+ return std::make_unique<FuchsiaTargetInfo<AArch64beTargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<AArch64beTargetInfo>>(Triple,
+ Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<AArch64beTargetInfo>>(Triple,
+ Opts);
default:
- return new AArch64beTargetInfo(Triple, Opts);
+ return std::make_unique<AArch64beTargetInfo>(Triple, Opts);
}
case llvm::Triple::arm:
case llvm::Triple::thumb:
if (Triple.isOSBinFormatMachO())
- return new DarwinARMTargetInfo(Triple, Opts);
+ return std::make_unique<DarwinARMTargetInfo>(Triple, Opts);
switch (os) {
- case llvm::Triple::CloudABI:
- return new CloudABITargetInfo<ARMleTargetInfo>(Triple, Opts);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts);
+ switch (Triple.getEnvironment()) {
+ default:
+ return std::make_unique<LinuxTargetInfo<ARMleTargetInfo>>(Triple, Opts);
+ case llvm::Triple::OpenHOS:
+ return std::make_unique<OHOSTargetInfo<ARMleTargetInfo>>(Triple, Opts);
+ }
+ case llvm::Triple::LiteOS:
+ return std::make_unique<OHOSTargetInfo<ARMleTargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<ARMleTargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<ARMleTargetInfo>>(Triple, Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<ARMleTargetInfo>>(Triple, Opts);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<ARMleTargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<ARMleTargetInfo>>(Triple, Opts);
+ case llvm::Triple::Haiku:
+ return std::make_unique<HaikuTargetInfo<ARMleTargetInfo>>(Triple, Opts);
case llvm::Triple::NaCl:
- return new NaClTargetInfo<ARMleTargetInfo>(Triple, Opts);
+ return std::make_unique<NaClTargetInfo<ARMleTargetInfo>>(Triple, Opts);
case llvm::Triple::Win32:
switch (Triple.getEnvironment()) {
case llvm::Triple::Cygnus:
- return new CygwinARMTargetInfo(Triple, Opts);
+ return std::make_unique<CygwinARMTargetInfo>(Triple, Opts);
case llvm::Triple::GNU:
- return new MinGWARMTargetInfo(Triple, Opts);
+ return std::make_unique<MinGWARMTargetInfo>(Triple, Opts);
case llvm::Triple::Itanium:
- return new ItaniumWindowsARMleTargetInfo(Triple, Opts);
+ return std::make_unique<ItaniumWindowsARMleTargetInfo>(Triple, Opts);
case llvm::Triple::MSVC:
default: // Assume MSVC for unknown environments
- return new MicrosoftARMleTargetInfo(Triple, Opts);
+ return std::make_unique<MicrosoftARMleTargetInfo>(Triple, Opts);
}
default:
- return new ARMleTargetInfo(Triple, Opts);
+ return std::make_unique<ARMleTargetInfo>(Triple, Opts);
}
case llvm::Triple::armeb:
case llvm::Triple::thumbeb:
if (Triple.isOSDarwin())
- return new DarwinARMTargetInfo(Triple, Opts);
+ return std::make_unique<DarwinARMTargetInfo>(Triple, Opts);
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts);
- case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<ARMbeTargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
- case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<ARMbeTargetInfo>>(Triple, Opts);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<ARMbeTargetInfo>>(Triple, Opts);
case llvm::Triple::NaCl:
- return new NaClTargetInfo<ARMbeTargetInfo>(Triple, Opts);
+ return std::make_unique<NaClTargetInfo<ARMbeTargetInfo>>(Triple, Opts);
default:
- return new ARMbeTargetInfo(Triple, Opts);
+ return std::make_unique<ARMbeTargetInfo>(Triple, Opts);
}
case llvm::Triple::avr:
- return new AVRTargetInfo(Triple, Opts);
+ return std::make_unique<AVRTargetInfo>(Triple, Opts);
case llvm::Triple::bpfeb:
case llvm::Triple::bpfel:
- return new BPFTargetInfo(Triple, Opts);
+ return std::make_unique<BPFTargetInfo>(Triple, Opts);
case llvm::Triple::msp430:
- return new MSP430TargetInfo(Triple, Opts);
+ return std::make_unique<MSP430TargetInfo>(Triple, Opts);
case llvm::Triple::mips:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
default:
- return new MipsTargetInfo(Triple, Opts);
+ return std::make_unique<MipsTargetInfo>(Triple, Opts);
}
case llvm::Triple::mipsel:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
+ switch (Triple.getEnvironment()) {
+ default:
+ return std::make_unique<LinuxTargetInfo<MipsTargetInfo>>(Triple, Opts);
+ case llvm::Triple::OpenHOS:
+ return std::make_unique<OHOSTargetInfo<MipsTargetInfo>>(Triple, Opts);
+ }
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::NaCl:
- return new NaClTargetInfo<NaClMips32TargetInfo>(Triple, Opts);
+ return std::make_unique<NaClTargetInfo<NaClMips32TargetInfo>>(Triple,
+ Opts);
default:
- return new MipsTargetInfo(Triple, Opts);
+ return std::make_unique<MipsTargetInfo>(Triple, Opts);
}
case llvm::Triple::mips64:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
default:
- return new MipsTargetInfo(Triple, Opts);
+ return std::make_unique<MipsTargetInfo>(Triple, Opts);
}
case llvm::Triple::mips64el:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<MipsTargetInfo>>(Triple, Opts);
default:
- return new MipsTargetInfo(Triple, Opts);
+ return std::make_unique<MipsTargetInfo>(Triple, Opts);
}
case llvm::Triple::m68k:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<M68kTargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<M68kTargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<M68kTargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<M68kTargetInfo>>(Triple, Opts);
default:
- return new M68kTargetInfo(Triple, Opts);
+ return std::make_unique<M68kTargetInfo>(Triple, Opts);
}
case llvm::Triple::le32:
switch (os) {
case llvm::Triple::NaCl:
- return new NaClTargetInfo<PNaClTargetInfo>(Triple, Opts);
+ return std::make_unique<NaClTargetInfo<PNaClTargetInfo>>(Triple, Opts);
default:
return nullptr;
}
case llvm::Triple::le64:
- return new Le64TargetInfo(Triple, Opts);
+ return std::make_unique<Le64TargetInfo>(Triple, Opts);
case llvm::Triple::ppc:
- if (Triple.isOSDarwin())
- return new DarwinPPC32TargetInfo(Triple, Opts);
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<PPC32TargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<PPC32TargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<PPC32TargetInfo>>(Triple, Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<PPC32TargetInfo>>(Triple, Opts);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<PPC32TargetInfo>>(Triple, Opts);
case llvm::Triple::AIX:
- return new AIXPPC32TargetInfo(Triple, Opts);
+ return std::make_unique<AIXPPC32TargetInfo>(Triple, Opts);
default:
- return new PPC32TargetInfo(Triple, Opts);
+ return std::make_unique<PPC32TargetInfo>(Triple, Opts);
}
case llvm::Triple::ppcle:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<PPC32TargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<PPC32TargetInfo>>(Triple, Opts);
default:
- return new PPC32TargetInfo(Triple, Opts);
+ return std::make_unique<PPC32TargetInfo>(Triple, Opts);
}
case llvm::Triple::ppc64:
- if (Triple.isOSDarwin())
- return new DarwinPPC64TargetInfo(Triple, Opts);
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<PPC64TargetInfo>>(Triple, Opts);
case llvm::Triple::Lv2:
- return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<PS3PPUTargetInfo<PPC64TargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts);
case llvm::Triple::AIX:
- return new AIXPPC64TargetInfo(Triple, Opts);
+ return std::make_unique<AIXPPC64TargetInfo>(Triple, Opts);
default:
- return new PPC64TargetInfo(Triple, Opts);
+ return std::make_unique<PPC64TargetInfo>(Triple, Opts);
}
case llvm::Triple::ppc64le:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<PPC64TargetInfo>>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<PPC64TargetInfo>>(Triple, Opts);
default:
- return new PPC64TargetInfo(Triple, Opts);
+ return std::make_unique<PPC64TargetInfo>(Triple, Opts);
}
case llvm::Triple::nvptx:
- return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32);
+ return std::make_unique<NVPTXTargetInfo>(Triple, Opts,
+ /*TargetPointerWidth=*/32);
case llvm::Triple::nvptx64:
- return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64);
+ return std::make_unique<NVPTXTargetInfo>(Triple, Opts,
+ /*TargetPointerWidth=*/64);
case llvm::Triple::amdgcn:
case llvm::Triple::r600:
- return new AMDGPUTargetInfo(Triple, Opts);
+ return std::make_unique<AMDGPUTargetInfo>(Triple, Opts);
case llvm::Triple::riscv32:
- // TODO: add cases for NetBSD, RTEMS once tested.
switch (os) {
- case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<RISCV32TargetInfo>(Triple, Opts);
+ case llvm::Triple::NetBSD:
+ return std::make_unique<NetBSDTargetInfo<RISCV32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<RISCV32TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<RISCV32TargetInfo>>(Triple, Opts);
default:
- return new RISCV32TargetInfo(Triple, Opts);
+ return std::make_unique<RISCV32TargetInfo>(Triple, Opts);
}
case llvm::Triple::riscv64:
- // TODO: add cases for NetBSD, RTEMS once tested.
switch (os) {
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<RISCV64TargetInfo>>(Triple,
+ Opts);
+ case llvm::Triple::NetBSD:
+ return std::make_unique<NetBSDTargetInfo<RISCV64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<RISCV64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Fuchsia:
- return new FuchsiaTargetInfo<RISCV64TargetInfo>(Triple, Opts);
+ return std::make_unique<FuchsiaTargetInfo<RISCV64TargetInfo>>(Triple,
+ Opts);
+ case llvm::Triple::Haiku:
+ return std::make_unique<HaikuTargetInfo<RISCV64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts);
+ switch (Triple.getEnvironment()) {
+ default:
+ return std::make_unique<LinuxTargetInfo<RISCV64TargetInfo>>(Triple,
+ Opts);
+ case llvm::Triple::OpenHOS:
+ return std::make_unique<OHOSTargetInfo<RISCV64TargetInfo>>(Triple,
+ Opts);
+ }
default:
- return new RISCV64TargetInfo(Triple, Opts);
+ return std::make_unique<RISCV64TargetInfo>(Triple, Opts);
}
case llvm::Triple::sparc:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<SparcV8TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<SparcV8TargetInfo>>(Triple, Opts);
case llvm::Triple::Solaris:
- return new SolarisTargetInfo<SparcV8TargetInfo>(Triple, Opts);
+ return std::make_unique<SolarisTargetInfo<SparcV8TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<SparcV8TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<SparcV8TargetInfo>>(Triple, Opts);
default:
- return new SparcV8TargetInfo(Triple, Opts);
+ return std::make_unique<SparcV8TargetInfo>(Triple, Opts);
}
- // The 'sparcel' architecture copies all the above cases except for Solaris.
case llvm::Triple::sparcel:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
- case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<SparcV8elTargetInfo>>(Triple,
+ Opts);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
+ return std::make_unique<RTEMSTargetInfo<SparcV8elTargetInfo>>(Triple,
+ Opts);
default:
- return new SparcV8elTargetInfo(Triple, Opts);
+ return std::make_unique<SparcV8elTargetInfo>(Triple, Opts);
}
case llvm::Triple::sparcv9:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<SparcV9TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<SparcV9TargetInfo>>(Triple, Opts);
case llvm::Triple::Solaris:
- return new SolarisTargetInfo<SparcV9TargetInfo>(Triple, Opts);
+ return std::make_unique<SolarisTargetInfo<SparcV9TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<SparcV9TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
+ return std::make_unique<OpenBSDTargetInfo<SparcV9TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<SparcV9TargetInfo>>(Triple,
+ Opts);
default:
- return new SparcV9TargetInfo(Triple, Opts);
+ return std::make_unique<SparcV9TargetInfo>(Triple, Opts);
}
case llvm::Triple::systemz:
switch (os) {
case llvm::Triple::Linux:
- return new LinuxTargetInfo<SystemZTargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<SystemZTargetInfo>>(Triple, Opts);
case llvm::Triple::ZOS:
- return new ZOSTargetInfo<SystemZTargetInfo>(Triple, Opts);
+ return std::make_unique<ZOSTargetInfo<SystemZTargetInfo>>(Triple, Opts);
default:
- return new SystemZTargetInfo(Triple, Opts);
+ return std::make_unique<SystemZTargetInfo>(Triple, Opts);
}
case llvm::Triple::tce:
- return new TCETargetInfo(Triple, Opts);
+ return std::make_unique<TCETargetInfo>(Triple, Opts);
case llvm::Triple::tcele:
- return new TCELETargetInfo(Triple, Opts);
+ return std::make_unique<TCELETargetInfo>(Triple, Opts);
case llvm::Triple::x86:
if (Triple.isOSDarwin())
- return new DarwinI386TargetInfo(Triple, Opts);
+ return std::make_unique<DarwinI386TargetInfo>(Triple, Opts);
switch (os) {
- case llvm::Triple::Ananas:
- return new AnanasTargetInfo<X86_32TargetInfo>(Triple, Opts);
- case llvm::Triple::CloudABI:
- return new CloudABITargetInfo<X86_32TargetInfo>(Triple, Opts);
case llvm::Triple::Linux: {
switch (Triple.getEnvironment()) {
default:
- return new LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<X86_32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Android:
- return new AndroidX86_32TargetInfo(Triple, Opts);
+ return std::make_unique<AndroidX86_32TargetInfo>(Triple, Opts);
}
}
case llvm::Triple::DragonFly:
- return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ return std::make_unique<DragonFlyBSDTargetInfo<X86_32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::NetBSD:
- return new NetBSDI386TargetInfo(Triple, Opts);
+ return std::make_unique<NetBSDI386TargetInfo>(Triple, Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDI386TargetInfo(Triple, Opts);
+ return std::make_unique<OpenBSDI386TargetInfo>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<X86_32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Fuchsia:
- return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ return std::make_unique<FuchsiaTargetInfo<X86_32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::KFreeBSD:
- return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
- case llvm::Triple::Minix:
- return new MinixTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ return std::make_unique<KFreeBSDTargetInfo<X86_32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Solaris:
- return new SolarisTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ return std::make_unique<SolarisTargetInfo<X86_32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Win32: {
switch (Triple.getEnvironment()) {
case llvm::Triple::Cygnus:
- return new CygwinX86_32TargetInfo(Triple, Opts);
+ return std::make_unique<CygwinX86_32TargetInfo>(Triple, Opts);
case llvm::Triple::GNU:
- return new MinGWX86_32TargetInfo(Triple, Opts);
+ return std::make_unique<MinGWX86_32TargetInfo>(Triple, Opts);
case llvm::Triple::Itanium:
case llvm::Triple::MSVC:
default: // Assume MSVC for unknown environments
- return new MicrosoftX86_32TargetInfo(Triple, Opts);
+ return std::make_unique<MicrosoftX86_32TargetInfo>(Triple, Opts);
}
}
case llvm::Triple::Haiku:
- return new HaikuX86_32TargetInfo(Triple, Opts);
+ return std::make_unique<HaikuX86_32TargetInfo>(Triple, Opts);
case llvm::Triple::RTEMS:
- return new RTEMSX86_32TargetInfo(Triple, Opts);
+ return std::make_unique<RTEMSX86_32TargetInfo>(Triple, Opts);
case llvm::Triple::NaCl:
- return new NaClTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ return std::make_unique<NaClTargetInfo<X86_32TargetInfo>>(Triple, Opts);
case llvm::Triple::ELFIAMCU:
- return new MCUX86_32TargetInfo(Triple, Opts);
+ return std::make_unique<MCUX86_32TargetInfo>(Triple, Opts);
case llvm::Triple::Hurd:
- return new HurdTargetInfo<X86_32TargetInfo>(Triple, Opts);
+ return std::make_unique<HurdTargetInfo<X86_32TargetInfo>>(Triple, Opts);
default:
- return new X86_32TargetInfo(Triple, Opts);
+ return std::make_unique<X86_32TargetInfo>(Triple, Opts);
}
case llvm::Triple::x86_64:
if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO())
- return new DarwinX86_64TargetInfo(Triple, Opts);
+ return std::make_unique<DarwinX86_64TargetInfo>(Triple, Opts);
switch (os) {
- case llvm::Triple::Ananas:
- return new AnanasTargetInfo<X86_64TargetInfo>(Triple, Opts);
- case llvm::Triple::CloudABI:
- return new CloudABITargetInfo<X86_64TargetInfo>(Triple, Opts);
case llvm::Triple::Linux: {
switch (Triple.getEnvironment()) {
default:
- return new LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<X86_64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Android:
- return new AndroidX86_64TargetInfo(Triple, Opts);
+ return std::make_unique<AndroidX86_64TargetInfo>(Triple, Opts);
+ case llvm::Triple::OpenHOS:
+ return std::make_unique<OHOSX86_64TargetInfo>(Triple, Opts);
}
}
case llvm::Triple::DragonFly:
- return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<DragonFlyBSDTargetInfo<X86_64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<NetBSDTargetInfo<X86_64TargetInfo>>(Triple, Opts);
case llvm::Triple::OpenBSD:
- return new OpenBSDX86_64TargetInfo(Triple, Opts);
+ return std::make_unique<OpenBSDX86_64TargetInfo>(Triple, Opts);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<FreeBSDTargetInfo<X86_64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Fuchsia:
- return new FuchsiaTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<FuchsiaTargetInfo<X86_64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::KFreeBSD:
- return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<KFreeBSDTargetInfo<X86_64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Solaris:
- return new SolarisTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<SolarisTargetInfo<X86_64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Win32: {
switch (Triple.getEnvironment()) {
case llvm::Triple::Cygnus:
- return new CygwinX86_64TargetInfo(Triple, Opts);
+ return std::make_unique<CygwinX86_64TargetInfo>(Triple, Opts);
case llvm::Triple::GNU:
- return new MinGWX86_64TargetInfo(Triple, Opts);
+ return std::make_unique<MinGWX86_64TargetInfo>(Triple, Opts);
case llvm::Triple::MSVC:
default: // Assume MSVC for unknown environments
- return new MicrosoftX86_64TargetInfo(Triple, Opts);
+ return std::make_unique<MicrosoftX86_64TargetInfo>(Triple, Opts);
}
}
case llvm::Triple::Haiku:
- return new HaikuTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<HaikuTargetInfo<X86_64TargetInfo>>(Triple, Opts);
case llvm::Triple::NaCl:
- return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<NaClTargetInfo<X86_64TargetInfo>>(Triple, Opts);
case llvm::Triple::PS4:
- return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
+ return std::make_unique<PS4OSTargetInfo<X86_64TargetInfo>>(Triple, Opts);
+ case llvm::Triple::PS5:
+ return std::make_unique<PS5OSTargetInfo<X86_64TargetInfo>>(Triple, Opts);
+ case llvm::Triple::Hurd:
+ return std::make_unique<HurdTargetInfo<X86_64TargetInfo>>(Triple, Opts);
default:
- return new X86_64TargetInfo(Triple, Opts);
+ return std::make_unique<X86_64TargetInfo>(Triple, Opts);
}
case llvm::Triple::spir: {
if (os != llvm::Triple::UnknownOS ||
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
return nullptr;
- return new SPIR32TargetInfo(Triple, Opts);
+ return std::make_unique<SPIR32TargetInfo>(Triple, Opts);
}
case llvm::Triple::spir64: {
if (os != llvm::Triple::UnknownOS ||
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
return nullptr;
- return new SPIR64TargetInfo(Triple, Opts);
+ return std::make_unique<SPIR64TargetInfo>(Triple, Opts);
+ }
+ case llvm::Triple::spirv: {
+ return std::make_unique<SPIRVTargetInfo>(Triple, Opts);
+ }
+ case llvm::Triple::spirv32: {
+ if (os != llvm::Triple::UnknownOS ||
+ Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
+ return nullptr;
+ return std::make_unique<SPIRV32TargetInfo>(Triple, Opts);
+ }
+ case llvm::Triple::spirv64: {
+ if (os != llvm::Triple::UnknownOS ||
+ Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
+ return nullptr;
+ return std::make_unique<SPIRV64TargetInfo>(Triple, Opts);
}
case llvm::Triple::wasm32:
if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
@@ -613,11 +684,14 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return nullptr;
switch (os) {
case llvm::Triple::WASI:
- return new WASITargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
+ return std::make_unique<WASITargetInfo<WebAssembly32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Emscripten:
- return new EmscriptenTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
+ return std::make_unique<EmscriptenTargetInfo<WebAssembly32TargetInfo>>(
+ Triple, Opts);
case llvm::Triple::UnknownOS:
- return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
+ return std::make_unique<WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>>(
+ Triple, Opts);
default:
return nullptr;
}
@@ -628,22 +702,53 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return nullptr;
switch (os) {
case llvm::Triple::WASI:
- return new WASITargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
+ return std::make_unique<WASITargetInfo<WebAssembly64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::Emscripten:
- return new EmscriptenTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
+ return std::make_unique<EmscriptenTargetInfo<WebAssembly64TargetInfo>>(
+ Triple, Opts);
case llvm::Triple::UnknownOS:
- return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
+ return std::make_unique<WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>>(
+ Triple, Opts);
default:
return nullptr;
}
+ case llvm::Triple::dxil:
+ return std::make_unique<DirectXTargetInfo>(Triple, Opts);
case llvm::Triple::renderscript32:
- return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<RenderScript32TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::renderscript64:
- return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<RenderScript64TargetInfo>>(Triple,
+ Opts);
case llvm::Triple::ve:
- return new LinuxTargetInfo<VETargetInfo>(Triple, Opts);
+ return std::make_unique<LinuxTargetInfo<VETargetInfo>>(Triple, Opts);
+
+ case llvm::Triple::csky:
+ switch (os) {
+ case llvm::Triple::Linux:
+ return std::make_unique<LinuxTargetInfo<CSKYTargetInfo>>(Triple, Opts);
+ default:
+ return std::make_unique<CSKYTargetInfo>(Triple, Opts);
+ }
+ case llvm::Triple::loongarch32:
+ switch (os) {
+ case llvm::Triple::Linux:
+ return std::make_unique<LinuxTargetInfo<LoongArch32TargetInfo>>(Triple,
+ Opts);
+ default:
+ return std::make_unique<LoongArch32TargetInfo>(Triple, Opts);
+ }
+ case llvm::Triple::loongarch64:
+ switch (os) {
+ case llvm::Triple::Linux:
+ return std::make_unique<LinuxTargetInfo<LoongArch64TargetInfo>>(Triple,
+ Opts);
+ default:
+ return std::make_unique<LoongArch64TargetInfo>(Triple, Opts);
+ }
}
}
} // namespace targets
@@ -658,7 +763,7 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
llvm::Triple Triple(Opts->Triple);
// Construct the target
- std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple, *Opts));
+ std::unique_ptr<TargetInfo> Target = AllocateTarget(Triple, *Opts);
if (!Target) {
Diags.Report(diag::err_target_unknown_triple) << Triple.str();
return nullptr;
@@ -700,6 +805,13 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
// Compute the default target features, we need the target to handle this
// because features may have dependencies on one another.
+ llvm::erase_if(Opts->FeaturesAsWritten, [&](StringRef Name) {
+ if (Target->isReadOnlyFeature(Name.substr(1))) {
+ Diags.Report(diag::warn_fe_backend_readonly_feature_flag) << Name;
+ return true;
+ }
+ return false;
+ });
if (!Target->initFeatureMap(Opts->FeatureMap, Diags, Opts->CPU,
Opts->FeaturesAsWritten))
return nullptr;
@@ -719,6 +831,10 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
Target->setCommandLineOpenCLOpts();
Target->setMaxAtomicWidth();
+ if (!Opts->DarwinTargetVariantTriple.empty())
+ Target->DarwinTargetVariantTriple =
+ llvm::Triple(Opts->DarwinTargetVariantTriple);
+
if (!Target->validateTarget(Diags))
return nullptr;
@@ -745,7 +861,7 @@ bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts,
// Validate that feature macros are set properly for OpenCL C 3.0.
// In other cases assume that target is always valid.
- if (Opts.OpenCLCPlusPlus || Opts.OpenCLVersion < 300)
+ if (Opts.getOpenCLCompatibleVersion() < 300)
return true;
return OpenCLOptions::diagnoseUnsupportedFeatureDependencies(*this, Diags) &&
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets.h b/contrib/llvm-project/clang/lib/Basic/Targets.h
index a063204e69e6..b4d2486b5d2b 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets.h
@@ -24,8 +24,8 @@ namespace clang {
namespace targets {
LLVM_LIBRARY_VISIBILITY
-clang::TargetInfo *AllocateTarget(const llvm::Triple &Triple,
- const clang::TargetOptions &Opts);
+std::unique_ptr<clang::TargetInfo>
+AllocateTarget(const llvm::Triple &Triple, const clang::TargetOptions &Opts);
/// DefineStd - Define a macro name and standard variants. For example if
/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
index e163ebfa2348..f5a5d689fa09 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
@@ -17,29 +17,116 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/AArch64TargetParser.h"
+#include "llvm/TargetParser/AArch64TargetParser.h"
+#include "llvm/TargetParser/ARMTargetParserCommon.h"
+#include <optional>
using namespace clang;
using namespace clang::targets;
-const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsNEON.def"
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsSVE.def"
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#include "clang/Basic/BuiltinsSME.def"
+
+#define BUILTIN(ID, TYPE, ATTRS) \
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
- {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
- {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
#include "clang/Basic/BuiltinsAArch64.def"
};
+void AArch64TargetInfo::setArchFeatures() {
+ if (*ArchInfo == llvm::AArch64::ARMV8R) {
+ HasDotProd = true;
+ HasDIT = true;
+ HasFlagM = true;
+ HasRCPC = true;
+ FPU |= NeonMode;
+ HasCCPP = true;
+ HasCRC = true;
+ HasLSE = true;
+ HasRDM = true;
+ } else if (ArchInfo->Version.getMajor() == 8) {
+ if (ArchInfo->Version.getMinor() >= 7u) {
+ HasWFxT = true;
+ }
+ if (ArchInfo->Version.getMinor() >= 6u) {
+ HasBFloat16 = true;
+ HasMatMul = true;
+ }
+ if (ArchInfo->Version.getMinor() >= 5u) {
+ HasAlternativeNZCV = true;
+ HasFRInt3264 = true;
+ HasSSBS = true;
+ HasSB = true;
+ HasPredRes = true;
+ HasBTI = true;
+ }
+ if (ArchInfo->Version.getMinor() >= 4u) {
+ HasDotProd = true;
+ HasDIT = true;
+ HasFlagM = true;
+ }
+ if (ArchInfo->Version.getMinor() >= 3u) {
+ HasRCPC = true;
+ FPU |= NeonMode;
+ }
+ if (ArchInfo->Version.getMinor() >= 2u) {
+ HasCCPP = true;
+ }
+ if (ArchInfo->Version.getMinor() >= 1u) {
+ HasCRC = true;
+ HasLSE = true;
+ HasRDM = true;
+ }
+ } else if (ArchInfo->Version.getMajor() == 9) {
+ if (ArchInfo->Version.getMinor() >= 2u) {
+ HasWFxT = true;
+ }
+ if (ArchInfo->Version.getMinor() >= 1u) {
+ HasBFloat16 = true;
+ HasMatMul = true;
+ }
+ FPU |= SveMode;
+ HasSVE2 = true;
+ HasFullFP16 = true;
+ HasAlternativeNZCV = true;
+ HasFRInt3264 = true;
+ HasSSBS = true;
+ HasSB = true;
+ HasPredRes = true;
+ HasBTI = true;
+ HasDotProd = true;
+ HasDIT = true;
+ HasFlagM = true;
+ HasRCPC = true;
+ FPU |= NeonMode;
+ HasCCPP = true;
+ HasCRC = true;
+ HasLSE = true;
+ HasRDM = true;
+ }
+}
+
AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: TargetInfo(Triple), ABI("aapcs") {
@@ -56,7 +143,9 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
// All AArch64 implementations support ARMv8 FP, which makes half a legal type.
HasLegalHalfType = true;
+ HalfArgsAndReturns = true;
HasFloat16 = true;
+ HasStrictFP = true;
if (Triple.isArch64Bit())
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
@@ -117,11 +206,11 @@ bool AArch64TargetInfo::setABI(const std::string &Name) {
return true;
}
-bool AArch64TargetInfo::validateBranchProtection(StringRef Spec,
+bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef,
BranchProtectionInfo &BPI,
StringRef &Err) const {
- llvm::AArch64::ParsedBranchProtection PBP;
- if (!llvm::AArch64::parseBranchProtection(Spec, PBP, Err))
+ llvm::ARM::ParsedBranchProtection PBP;
+ if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
return false;
BPI.SignReturnAddr =
@@ -136,12 +225,13 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec,
BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey;
BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
+ BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
+ BPI.GuardedControlStack = PBP.GuardedControlStack;
return true;
}
bool AArch64TargetInfo::isValidCPUName(StringRef Name) const {
- return Name == "generic" ||
- llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID;
+ return Name == "generic" || llvm::AArch64::parseCpu(Name);
}
bool AArch64TargetInfo::setCPU(const std::string &Name) {
@@ -156,8 +246,6 @@ void AArch64TargetInfo::fillValidCPUList(
void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
- Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1");
- Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
}
void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
@@ -183,6 +271,7 @@ void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts,
void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__ARM_FEATURE_FRINT", "1");
+ Builder.defineMacro("__ARM_FEATURE_BTI", "1");
// Also include the Armv8.4 defines
getTargetDefinesARMV84A(Opts, Builder);
}
@@ -203,21 +292,72 @@ void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts,
getTargetDefinesARMV86A(Opts, Builder);
}
+void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Also include the Armv8.7 defines
+ getTargetDefinesARMV87A(Opts, Builder);
+}
+
+void AArch64TargetInfo::getTargetDefinesARMV89A(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Also include the Armv8.8 defines
+ getTargetDefinesARMV88A(Opts, Builder);
+}
+
+void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Armv9-A maps to Armv8.5-A
+ getTargetDefinesARMV85A(Opts, Builder);
+}
+
+void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Armv9.1-A maps to Armv8.6-A
+ getTargetDefinesARMV86A(Opts, Builder);
+}
+
+void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Armv9.2-A maps to Armv8.7-A
+ getTargetDefinesARMV87A(Opts, Builder);
+}
+
+void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Armv9.3-A maps to Armv8.8-A
+ getTargetDefinesARMV88A(Opts, Builder);
+}
+
+void AArch64TargetInfo::getTargetDefinesARMV94A(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Armv9.4-A maps to Armv8.9-A
+ getTargetDefinesARMV89A(Opts, Builder);
+}
+
+void AArch64TargetInfo::getTargetDefinesARMV95A(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Armv9.5-A does not have a v8.* equivalent, but is a superset of v9.4-A.
+ getTargetDefinesARMV94A(Opts, Builder);
+}
+
void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
// Target identification.
- Builder.defineMacro("__aarch64__");
- // For bare-metal.
- if (getTriple().getOS() == llvm::Triple::UnknownOS &&
- getTriple().isOSBinFormatELF())
- Builder.defineMacro("__ELF__");
-
- // Target properties.
- if (!getTriple().isOSWindows() && getTriple().isArch64Bit()) {
- Builder.defineMacro("_LP64");
- Builder.defineMacro("__LP64__");
+ if (getTriple().isWindowsArm64EC()) {
+ // Define the same set of macros as would be defined on x86_64 to ensure that
+ // ARM64EC datatype layouts match those of x86_64 compiled code
+ Builder.defineMacro("__amd64__");
+ Builder.defineMacro("__amd64");
+ Builder.defineMacro("__x86_64");
+ Builder.defineMacro("__x86_64__");
+ Builder.defineMacro("__arm64ec__");
+ } else {
+ Builder.defineMacro("__aarch64__");
}
+ // Inline assembly supports AArch64 flag outputs.
+ Builder.defineMacro("__GCC_ASM_FLAG_OUTPUTS__");
+
std::string CodeModel = getTargetOpts().CodeModel;
if (CodeModel == "default")
CodeModel = "small";
@@ -227,8 +367,10 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
// ACLE predefines. Many can only have one possible value on v8 AArch64.
Builder.defineMacro("__ARM_ACLE", "200");
- Builder.defineMacro("__ARM_ARCH", "8");
- Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
+ Builder.defineMacro("__ARM_ARCH",
+ std::to_string(ArchInfo->Version.getMajor()));
+ Builder.defineMacro("__ARM_ARCH_PROFILE",
+ std::string("'") + (char)ArchInfo->Profile + "'");
Builder.defineMacro("__ARM_64BIT_STATE", "1");
Builder.defineMacro("__ARM_PCS_AAPCS64", "1");
@@ -244,8 +386,14 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
+ // These macros are set when Clang can parse declarations with these
+ // attributes.
+ Builder.defineMacro("__ARM_STATE_ZA", "1");
+ Builder.defineMacro("__ARM_STATE_ZT0", "1");
+
// 0xe implies support for half, single and double precision operations.
- Builder.defineMacro("__ARM_FP", "0xE");
+ if (FPU & FPUMode)
+ Builder.defineMacro("__ARM_FP", "0xE");
// PCS specifies this for SysV variants, which is all we support. Other ABIs
// may choose __ARM_FP16_FORMAT_ALTERNATIVE.
@@ -269,6 +417,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (FPU & SveMode)
Builder.defineMacro("__ARM_FEATURE_SVE", "1");
+ if ((FPU & NeonMode) && (FPU & SveMode))
+ Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1");
+
if (HasSVE2)
Builder.defineMacro("__ARM_FEATURE_SVE2", "1");
@@ -284,9 +435,28 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasSVE2 && HasSVE2SM4)
Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1");
+ if (HasSME) {
+ Builder.defineMacro("__ARM_FEATURE_SME");
+ Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
+ }
+
+ if (HasSME2) {
+ Builder.defineMacro("__ARM_FEATURE_SME");
+ Builder.defineMacro("__ARM_FEATURE_SME2");
+ Builder.defineMacro("__ARM_FEATURE_LOCALLY_STREAMING", "1");
+ }
+
if (HasCRC)
Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
+ if (HasRCPC3)
+ Builder.defineMacro("__ARM_FEATURE_RCPC", "3");
+ else if (HasRCPC)
+ Builder.defineMacro("__ARM_FEATURE_RCPC", "1");
+
+ if (HasFMV)
+ Builder.defineMacro("__HAVE_FUNCTION_MULTI_VERSIONING", "1");
+
// The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature
// macros for AES, SHA2, SHA3 and SM4
if (HasAES && HasSHA2)
@@ -308,6 +478,9 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__ARM_FEATURE_SM4", "1");
}
+ if (HasPAuth)
+ Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
+
if (HasUnaligned)
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
@@ -375,178 +548,416 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (Opts.BranchTargetEnforcement)
Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
+ if (Opts.GuardedControlStack)
+ Builder.defineMacro("__ARM_FEATURE_GCS_DEFAULT", "1");
+
if (HasLS64)
Builder.defineMacro("__ARM_FEATURE_LS64", "1");
if (HasRandGen)
Builder.defineMacro("__ARM_FEATURE_RNG", "1");
- switch (ArchKind) {
- default:
- break;
- case llvm::AArch64::ArchKind::ARMV8_1A:
+ if (HasMOPS)
+ Builder.defineMacro("__ARM_FEATURE_MOPS", "1");
+
+ if (HasD128)
+ Builder.defineMacro("__ARM_FEATURE_SYSREG128", "1");
+
+ if (HasGCS)
+ Builder.defineMacro("__ARM_FEATURE_GCS", "1");
+
+ if (*ArchInfo == llvm::AArch64::ARMV8_1A)
getTargetDefinesARMV81A(Opts, Builder);
- break;
- case llvm::AArch64::ArchKind::ARMV8_2A:
+ else if (*ArchInfo == llvm::AArch64::ARMV8_2A)
getTargetDefinesARMV82A(Opts, Builder);
- break;
- case llvm::AArch64::ArchKind::ARMV8_3A:
+ else if (*ArchInfo == llvm::AArch64::ARMV8_3A)
getTargetDefinesARMV83A(Opts, Builder);
- break;
- case llvm::AArch64::ArchKind::ARMV8_4A:
+ else if (*ArchInfo == llvm::AArch64::ARMV8_4A)
getTargetDefinesARMV84A(Opts, Builder);
- break;
- case llvm::AArch64::ArchKind::ARMV8_5A:
+ else if (*ArchInfo == llvm::AArch64::ARMV8_5A)
getTargetDefinesARMV85A(Opts, Builder);
- break;
- case llvm::AArch64::ArchKind::ARMV8_6A:
+ else if (*ArchInfo == llvm::AArch64::ARMV8_6A)
getTargetDefinesARMV86A(Opts, Builder);
- break;
- case llvm::AArch64::ArchKind::ARMV8_7A:
+ else if (*ArchInfo == llvm::AArch64::ARMV8_7A)
getTargetDefinesARMV87A(Opts, Builder);
- break;
- }
-
- // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work.
+ else if (*ArchInfo == llvm::AArch64::ARMV8_8A)
+ getTargetDefinesARMV88A(Opts, Builder);
+ else if (*ArchInfo == llvm::AArch64::ARMV8_9A)
+ getTargetDefinesARMV89A(Opts, Builder);
+ else if (*ArchInfo == llvm::AArch64::ARMV9A)
+ getTargetDefinesARMV9A(Opts, Builder);
+ else if (*ArchInfo == llvm::AArch64::ARMV9_1A)
+ getTargetDefinesARMV91A(Opts, Builder);
+ else if (*ArchInfo == llvm::AArch64::ARMV9_2A)
+ getTargetDefinesARMV92A(Opts, Builder);
+ else if (*ArchInfo == llvm::AArch64::ARMV9_3A)
+ getTargetDefinesARMV93A(Opts, Builder);
+ else if (*ArchInfo == llvm::AArch64::ARMV9_4A)
+ getTargetDefinesARMV94A(Opts, Builder);
+ else if (*ArchInfo == llvm::AArch64::ARMV9_5A)
+ getTargetDefinesARMV95A(Opts, Builder);
+
+ // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8|16) builtins work.
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
+
+ // Allow detection of fast FMA support.
+ Builder.defineMacro("__FP_FAST_FMA", "1");
+ Builder.defineMacro("__FP_FAST_FMAF", "1");
+
+ // C/C++ operators work on both VLS and VLA SVE types
+ if (FPU & SveMode)
+ Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS", "2");
- if (Opts.ArmSveVectorBits) {
- Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.ArmSveVectorBits));
- Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS");
+ if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax) {
+ Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128));
}
}
ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
+ Builtin::FirstTSBuiltin);
+}
+
+std::optional<std::pair<unsigned, unsigned>>
+AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
+ if (LangOpts.VScaleMin || LangOpts.VScaleMax)
+ return std::pair<unsigned, unsigned>(
+ LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax);
+
+ if (hasFeature("sve"))
+ return std::pair<unsigned, unsigned>(1, 16);
+
+ return std::nullopt;
+}
+
+unsigned AArch64TargetInfo::multiVersionSortPriority(StringRef Name) const {
+ if (Name == "default")
+ return 0;
+ if (auto Ext = llvm::AArch64::parseArchExtension(Name))
+ return Ext->FmvPriority;
+ return 0;
+}
+
+unsigned AArch64TargetInfo::multiVersionFeatureCost() const {
+ // Take the maximum priority as per feature cost, so more features win.
+ return llvm::AArch64::ExtensionInfo::MaxFMVPriority;
+}
+
+bool AArch64TargetInfo::doesFeatureAffectCodeGen(StringRef Name) const {
+ if (auto Ext = llvm::AArch64::parseArchExtension(Name))
+ return !Ext->DependentFeatures.empty();
+ return false;
+}
+
+StringRef AArch64TargetInfo::getFeatureDependencies(StringRef Name) const {
+ if (auto Ext = llvm::AArch64::parseArchExtension(Name))
+ return Ext->DependentFeatures;
+ return StringRef();
+}
+
+bool AArch64TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
+ return llvm::AArch64::parseArchExtension(FeatureStr).has_value();
}
bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
- return Feature == "aarch64" || Feature == "arm64" || Feature == "arm" ||
- (Feature == "neon" && (FPU & NeonMode)) ||
- ((Feature == "sve" || Feature == "sve2" || Feature == "sve2-bitperm" ||
- Feature == "sve2-aes" || Feature == "sve2-sha3" ||
- Feature == "sve2-sm4" || Feature == "f64mm" || Feature == "f32mm" ||
- Feature == "i8mm" || Feature == "bf16") &&
- (FPU & SveMode)) ||
- (Feature == "ls64" && HasLS64);
+ return llvm::StringSwitch<bool>(Feature)
+ .Cases("aarch64", "arm64", "arm", true)
+ .Case("fmv", HasFMV)
+ .Cases("neon", "fp", "simd", FPU & NeonMode)
+ .Case("jscvt", HasJSCVT)
+ .Case("fcma", HasFCMA)
+ .Case("rng", HasRandGen)
+ .Case("flagm", HasFlagM)
+ .Case("flagm2", HasAlternativeNZCV)
+ .Case("fp16fml", HasFP16FML)
+ .Case("dotprod", HasDotProd)
+ .Case("sm4", HasSM4)
+ .Case("rdm", HasRDM)
+ .Case("lse", HasLSE)
+ .Case("crc", HasCRC)
+ .Case("sha2", HasSHA2)
+ .Case("sha3", HasSHA3)
+ .Cases("aes", "pmull", HasAES)
+ .Cases("fp16", "fullfp16", HasFullFP16)
+ .Case("dit", HasDIT)
+ .Case("dpb", HasCCPP)
+ .Case("dpb2", HasCCDP)
+ .Case("rcpc", HasRCPC)
+ .Case("frintts", HasFRInt3264)
+ .Case("i8mm", HasMatMul)
+ .Case("bf16", HasBFloat16)
+ .Case("sve", FPU & SveMode)
+ .Case("sve-bf16", FPU & SveMode && HasBFloat16)
+ .Case("sve-i8mm", FPU & SveMode && HasMatMul)
+ .Case("f32mm", FPU & SveMode && HasMatmulFP32)
+ .Case("f64mm", FPU & SveMode && HasMatmulFP64)
+ .Case("sve2", FPU & SveMode && HasSVE2)
+ .Case("sve2-pmull128", FPU & SveMode && HasSVE2AES)
+ .Case("sve2-bitperm", FPU & SveMode && HasSVE2BitPerm)
+ .Case("sve2-sha3", FPU & SveMode && HasSVE2SHA3)
+ .Case("sve2-sm4", FPU & SveMode && HasSVE2SM4)
+ .Case("sme", HasSME)
+ .Case("sme2", HasSME2)
+ .Case("sme-f64f64", HasSMEF64F64)
+ .Case("sme-i16i64", HasSMEI16I64)
+ .Case("sme-fa64", HasSMEFA64)
+ .Cases("memtag", "memtag2", HasMTE)
+ .Case("sb", HasSB)
+ .Case("predres", HasPredRes)
+ .Cases("ssbs", "ssbs2", HasSSBS)
+ .Case("bti", HasBTI)
+ .Cases("ls64", "ls64_v", "ls64_accdata", HasLS64)
+ .Case("wfxt", HasWFxT)
+ .Case("rcpc3", HasRCPC3)
+ .Default(false);
+}
+
+void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
+ StringRef Name, bool Enabled) const {
+ Features[Name] = Enabled;
+ // If the feature is an architecture feature (like v8.2a), add all previous
+ // architecture versions and any dependant target features.
+ const std::optional<llvm::AArch64::ArchInfo> ArchInfo =
+ llvm::AArch64::ArchInfo::findBySubArch(Name);
+
+ if (!ArchInfo)
+ return; // Not an architecture, nothing more to do.
+
+ // Disabling an architecture feature does not affect dependent features
+ if (!Enabled)
+ return;
+
+ for (const auto *OtherArch : llvm::AArch64::ArchInfos)
+ if (ArchInfo->implies(*OtherArch))
+ Features[OtherArch->getSubArch()] = true;
+
+ // Set any features implied by the architecture
+ std::vector<StringRef> CPUFeats;
+ if (llvm::AArch64::getExtensionFeatures(ArchInfo->DefaultExts, CPUFeats)) {
+ for (auto F : CPUFeats) {
+ assert(F[0] == '+' && "Expected + in target feature!");
+ Features[F.drop_front(1)] = true;
+ }
+ }
}
bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) {
- FPU = FPUMode;
- HasCRC = false;
- HasCrypto = false;
- HasAES = false;
- HasSHA2 = false;
- HasSHA3 = false;
- HasSM4 = false;
- HasUnaligned = true;
- HasFullFP16 = false;
- HasDotProd = false;
- HasFP16FML = false;
- HasMTE = false;
- HasTME = false;
- HasLS64 = false;
- HasRandGen = false;
- HasMatMul = false;
- HasBFloat16 = false;
- HasSVE2 = false;
- HasSVE2AES = false;
- HasSVE2SHA3 = false;
- HasSVE2SM4 = false;
- HasSVE2BitPerm = false;
- HasMatmulFP64 = false;
- HasMatmulFP32 = false;
- HasLSE = false;
-
- ArchKind = llvm::AArch64::ArchKind::ARMV8A;
-
for (const auto &Feature : Features) {
- if (Feature == "+neon")
+ if (Feature == "-fp-armv8")
+ HasNoFP = true;
+ if (Feature == "-neon")
+ HasNoNeon = true;
+ if (Feature == "-sve")
+ HasNoSVE = true;
+
+ if (Feature == "+neon" || Feature == "+fp-armv8")
+ FPU |= NeonMode;
+ if (Feature == "+jscvt") {
+ HasJSCVT = true;
+ FPU |= NeonMode;
+ }
+ if (Feature == "+fcma") {
+ HasFCMA = true;
FPU |= NeonMode;
+ }
+
if (Feature == "+sve") {
+ FPU |= NeonMode;
FPU |= SveMode;
- HasFullFP16 = 1;
+ HasFullFP16 = true;
}
if (Feature == "+sve2") {
+ FPU |= NeonMode;
FPU |= SveMode;
- HasFullFP16 = 1;
- HasSVE2 = 1;
+ HasFullFP16 = true;
+ HasSVE2 = true;
}
if (Feature == "+sve2-aes") {
+ FPU |= NeonMode;
FPU |= SveMode;
- HasFullFP16 = 1;
- HasSVE2 = 1;
- HasSVE2AES = 1;
+ HasFullFP16 = true;
+ HasSVE2 = true;
+ HasSVE2AES = true;
}
if (Feature == "+sve2-sha3") {
+ FPU |= NeonMode;
FPU |= SveMode;
- HasFullFP16 = 1;
- HasSVE2 = 1;
- HasSVE2SHA3 = 1;
+ HasFullFP16 = true;
+ HasSVE2 = true;
+ HasSVE2SHA3 = true;
}
if (Feature == "+sve2-sm4") {
+ FPU |= NeonMode;
FPU |= SveMode;
- HasFullFP16 = 1;
- HasSVE2 = 1;
- HasSVE2SM4 = 1;
+ HasFullFP16 = true;
+ HasSVE2 = true;
+ HasSVE2SM4 = true;
}
if (Feature == "+sve2-bitperm") {
+ FPU |= NeonMode;
FPU |= SveMode;
- HasFullFP16 = 1;
- HasSVE2 = 1;
- HasSVE2BitPerm = 1;
+ HasFullFP16 = true;
+ HasSVE2 = true;
+ HasSVE2BitPerm = true;
}
if (Feature == "+f32mm") {
+ FPU |= NeonMode;
FPU |= SveMode;
+ HasFullFP16 = true;
HasMatmulFP32 = true;
}
if (Feature == "+f64mm") {
+ FPU |= NeonMode;
FPU |= SveMode;
+ HasFullFP16 = true;
HasMatmulFP64 = true;
}
+ if (Feature == "+sme") {
+ HasSME = true;
+ HasBFloat16 = true;
+ HasFullFP16 = true;
+ }
+ if (Feature == "+sme2") {
+ HasSME = true;
+ HasSME2 = true;
+ HasBFloat16 = true;
+ HasFullFP16 = true;
+ }
+ if (Feature == "+sme-f64f64") {
+ HasSME = true;
+ HasSMEF64F64 = true;
+ HasBFloat16 = true;
+ HasFullFP16 = true;
+ }
+ if (Feature == "+sme-i16i64") {
+ HasSME = true;
+ HasSMEI16I64 = true;
+ HasBFloat16 = true;
+ HasFullFP16 = true;
+ }
+ if (Feature == "+sme-fa64") {
+ FPU |= NeonMode;
+ FPU |= SveMode;
+ HasSME = true;
+ HasSVE2 = true;
+ HasSMEFA64 = true;
+ }
+ if (Feature == "+sb")
+ HasSB = true;
+ if (Feature == "+predres")
+ HasPredRes = true;
+ if (Feature == "+ssbs")
+ HasSSBS = true;
+ if (Feature == "+bti")
+ HasBTI = true;
+ if (Feature == "+wfxt")
+ HasWFxT = true;
+ if (Feature == "-fmv")
+ HasFMV = false;
if (Feature == "+crc")
HasCRC = true;
- if (Feature == "+crypto")
- HasCrypto = true;
- if (Feature == "+aes")
+ if (Feature == "+rcpc")
+ HasRCPC = true;
+ if (Feature == "+aes") {
+ FPU |= NeonMode;
HasAES = true;
- if (Feature == "+sha2")
+ }
+ if (Feature == "+sha2") {
+ FPU |= NeonMode;
HasSHA2 = true;
+ }
if (Feature == "+sha3") {
+ FPU |= NeonMode;
HasSHA2 = true;
HasSHA3 = true;
}
- if (Feature == "+sm4")
+ if (Feature == "+rdm") {
+ FPU |= NeonMode;
+ HasRDM = true;
+ }
+ if (Feature == "+dit")
+ HasDIT = true;
+ if (Feature == "+cccp")
+ HasCCPP = true;
+ if (Feature == "+ccdp") {
+ HasCCPP = true;
+ HasCCDP = true;
+ }
+ if (Feature == "+fptoint")
+ HasFRInt3264 = true;
+ if (Feature == "+sm4") {
+ FPU |= NeonMode;
HasSM4 = true;
+ }
if (Feature == "+strict-align")
HasUnaligned = false;
- if (Feature == "+v8.1a")
- ArchKind = llvm::AArch64::ArchKind::ARMV8_1A;
- if (Feature == "+v8.2a")
- ArchKind = llvm::AArch64::ArchKind::ARMV8_2A;
- if (Feature == "+v8.3a")
- ArchKind = llvm::AArch64::ArchKind::ARMV8_3A;
- if (Feature == "+v8.4a")
- ArchKind = llvm::AArch64::ArchKind::ARMV8_4A;
- if (Feature == "+v8.5a")
- ArchKind = llvm::AArch64::ArchKind::ARMV8_5A;
- if (Feature == "+v8.6a")
- ArchKind = llvm::AArch64::ArchKind::ARMV8_6A;
- if (Feature == "+v8.7a")
- ArchKind = llvm::AArch64::ArchKind::ARMV8_7A;
+ // All predecessor archs are added but select the latest one for ArchKind.
+ if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8A;
+ if (Feature == "+v8.1a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_1A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_1A;
+ if (Feature == "+v8.2a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_2A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_2A;
+ if (Feature == "+v8.3a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_3A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_3A;
+ if (Feature == "+v8.4a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_4A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_4A;
+ if (Feature == "+v8.5a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_5A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_5A;
+ if (Feature == "+v8.6a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_6A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_6A;
+ if (Feature == "+v8.7a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_7A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_7A;
+ if (Feature == "+v8.8a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_8A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_8A;
+ if (Feature == "+v8.9a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV8_9A.Version)
+ ArchInfo = &llvm::AArch64::ARMV8_9A;
+ if (Feature == "+v9a" && ArchInfo->Version < llvm::AArch64::ARMV9A.Version)
+ ArchInfo = &llvm::AArch64::ARMV9A;
+ if (Feature == "+v9.1a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV9_1A.Version)
+ ArchInfo = &llvm::AArch64::ARMV9_1A;
+ if (Feature == "+v9.2a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV9_2A.Version)
+ ArchInfo = &llvm::AArch64::ARMV9_2A;
+ if (Feature == "+v9.3a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV9_3A.Version)
+ ArchInfo = &llvm::AArch64::ARMV9_3A;
+ if (Feature == "+v9.4a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV9_4A.Version)
+ ArchInfo = &llvm::AArch64::ARMV9_4A;
+ if (Feature == "+v9.5a" &&
+ ArchInfo->Version < llvm::AArch64::ARMV9_5A.Version)
+ ArchInfo = &llvm::AArch64::ARMV9_5A;
if (Feature == "+v8r")
- ArchKind = llvm::AArch64::ArchKind::ARMV8R;
- if (Feature == "+fullfp16")
+ ArchInfo = &llvm::AArch64::ARMV8R;
+ if (Feature == "+fullfp16") {
+ FPU |= NeonMode;
HasFullFP16 = true;
- if (Feature == "+dotprod")
+ }
+ if (Feature == "+dotprod") {
+ FPU |= NeonMode;
HasDotProd = true;
- if (Feature == "+fp16fml")
+ }
+ if (Feature == "+fp16fml") {
+ FPU |= NeonMode;
+ HasFullFP16 = true;
HasFP16FML = true;
+ }
if (Feature == "+mte")
HasMTE = true;
if (Feature == "+tme")
@@ -565,10 +976,188 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasRandGen = true;
if (Feature == "+flagm")
HasFlagM = true;
+ if (Feature == "+altnzcv") {
+ HasFlagM = true;
+ HasAlternativeNZCV = true;
+ }
+ if (Feature == "+mops")
+ HasMOPS = true;
+ if (Feature == "+d128")
+ HasD128 = true;
+ if (Feature == "+gcs")
+ HasGCS = true;
+ if (Feature == "+rcpc3")
+ HasRCPC3 = true;
+ }
+
+ // Check features that are manually disabled by command line options.
+ // This needs to be checked after architecture-related features are handled,
+ // making sure they are properly disabled when required.
+ for (const auto &Feature : Features) {
+ if (Feature == "-d128")
+ HasD128 = false;
}
setDataLayout();
+ setArchFeatures();
+
+ if (HasNoFP) {
+ FPU &= ~FPUMode;
+ FPU &= ~NeonMode;
+ FPU &= ~SveMode;
+ }
+ if (HasNoNeon) {
+ FPU &= ~NeonMode;
+ FPU &= ~SveMode;
+ }
+ if (HasNoSVE)
+ FPU &= ~SveMode;
+
+ return true;
+}
+
+bool AArch64TargetInfo::initFeatureMap(
+ llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
+ const std::vector<std::string> &FeaturesVec) const {
+ std::vector<std::string> UpdatedFeaturesVec;
+ // Parse the CPU and add any implied features.
+ std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU);
+ if (CpuInfo) {
+ auto Exts = CpuInfo->getImpliedExtensions();
+ std::vector<StringRef> CPUFeats;
+ llvm::AArch64::getExtensionFeatures(Exts, CPUFeats);
+ for (auto F : CPUFeats) {
+ assert((F[0] == '+' || F[0] == '-') && "Expected +/- in target feature!");
+ UpdatedFeaturesVec.push_back(F.str());
+ }
+ }
+
+ // Process target and dependent features. This is done in two loops collecting
+ // them into UpdatedFeaturesVec: first to add dependent '+'features, second to
+ // add target '+/-'features that can later disable some of features added on
+ // the first loop. Function Multi Versioning features begin with '?'.
+ for (const auto &Feature : FeaturesVec)
+ if (((Feature[0] == '?' || Feature[0] == '+')) &&
+ AArch64TargetInfo::doesFeatureAffectCodeGen(Feature.substr(1))) {
+ StringRef DepFeatures =
+ AArch64TargetInfo::getFeatureDependencies(Feature.substr(1));
+ SmallVector<StringRef, 1> AttrFeatures;
+ DepFeatures.split(AttrFeatures, ",");
+ for (auto F : AttrFeatures)
+ UpdatedFeaturesVec.push_back(F.str());
+ }
+ for (const auto &Feature : FeaturesVec)
+ if (Feature[0] != '?') {
+ std::string UpdatedFeature = Feature;
+ if (Feature[0] == '+') {
+ std::optional<llvm::AArch64::ExtensionInfo> Extension =
+ llvm::AArch64::parseArchExtension(Feature.substr(1));
+ if (Extension)
+ UpdatedFeature = Extension->Feature.str();
+ }
+ UpdatedFeaturesVec.push_back(UpdatedFeature);
+ }
+
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
+}
+
+// Parse AArch64 Target attributes, which are a comma separated list of:
+// "arch=<arch>" - parsed to features as per -march=..
+// "cpu=<cpu>" - parsed to features as per -mcpu=.., with CPU set to <cpu>
+// "tune=<cpu>" - TuneCPU set to <cpu>
+// "feature", "no-feature" - Add (or remove) feature.
+// "+feature", "+nofeature" - Add (or remove) feature.
+ParsedTargetAttr AArch64TargetInfo::parseTargetAttr(StringRef Features) const {
+ ParsedTargetAttr Ret;
+ if (Features == "default")
+ return Ret;
+ SmallVector<StringRef, 1> AttrFeatures;
+ Features.split(AttrFeatures, ",");
+ bool FoundArch = false;
+
+ auto SplitAndAddFeatures = [](StringRef FeatString,
+ std::vector<std::string> &Features) {
+ SmallVector<StringRef, 8> SplitFeatures;
+ FeatString.split(SplitFeatures, StringRef("+"), -1, false);
+ for (StringRef Feature : SplitFeatures) {
+ StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
+ if (!FeatureName.empty())
+ Features.push_back(FeatureName.str());
+ else
+ // Pushing the original feature string to give a sema error later on
+ // when they get checked.
+ if (Feature.starts_with("no"))
+ Features.push_back("-" + Feature.drop_front(2).str());
+ else
+ Features.push_back("+" + Feature.str());
+ }
+ };
+
+ for (auto &Feature : AttrFeatures) {
+ Feature = Feature.trim();
+ if (Feature.starts_with("fpmath="))
+ continue;
+
+ if (Feature.starts_with("branch-protection=")) {
+ Ret.BranchProtection = Feature.split('=').second.trim();
+ continue;
+ }
+
+ if (Feature.starts_with("arch=")) {
+ if (FoundArch)
+ Ret.Duplicate = "arch=";
+ FoundArch = true;
+ std::pair<StringRef, StringRef> Split =
+ Feature.split("=").second.trim().split("+");
+ const llvm::AArch64::ArchInfo *AI = llvm::AArch64::parseArch(Split.first);
+
+ // Parse the architecture version, adding the required features to
+ // Ret.Features.
+ if (!AI)
+ continue;
+ Ret.Features.push_back(AI->ArchFeature.str());
+ // Add any extra features, after the +
+ SplitAndAddFeatures(Split.second, Ret.Features);
+ } else if (Feature.starts_with("cpu=")) {
+ if (!Ret.CPU.empty())
+ Ret.Duplicate = "cpu=";
+ else {
+ // Split the cpu string into "cpu=", "cortex-a710" and any remaining
+ // "+feat" features.
+ std::pair<StringRef, StringRef> Split =
+ Feature.split("=").second.trim().split("+");
+ Ret.CPU = Split.first;
+ SplitAndAddFeatures(Split.second, Ret.Features);
+ }
+ } else if (Feature.starts_with("tune=")) {
+ if (!Ret.Tune.empty())
+ Ret.Duplicate = "tune=";
+ else
+ Ret.Tune = Feature.split("=").second.trim();
+ } else if (Feature.starts_with("+")) {
+ SplitAndAddFeatures(Feature, Ret.Features);
+ } else if (Feature.starts_with("no-")) {
+ StringRef FeatureName =
+ llvm::AArch64::getArchExtFeature(Feature.split("-").second);
+ if (!FeatureName.empty())
+ Ret.Features.push_back("-" + FeatureName.drop_front(1).str());
+ else
+ Ret.Features.push_back("-" + Feature.split("-").second.str());
+ } else {
+ // Try parsing the string to the internal target feature name. If it is
+ // invalid, add the original string (which could already be an internal
+ // name). These should be checked later by isValidFeatureName.
+ StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
+ if (!FeatureName.empty())
+ Ret.Features.push_back(FeatureName.str());
+ else
+ Ret.Features.push_back("+" + Feature.str());
+ }
+ }
+ return Ret;
+}
+bool AArch64TargetInfo::hasBFloat16Type() const {
return true;
}
@@ -582,6 +1171,7 @@ AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
case CC_PreserveAll:
case CC_OpenCLKernel:
case CC_AArch64VectorCall:
+ case CC_AArch64SVEPCS:
case CC_Win64:
return CCCR_OK;
default:
@@ -596,6 +1186,8 @@ TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const {
}
const char *const AArch64TargetInfo::GCCRegNames[] = {
+ // clang-format off
+
// 32-bit Integer registers
"w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11",
"w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22",
@@ -628,11 +1220,20 @@ const char *const AArch64TargetInfo::GCCRegNames[] = {
// SVE predicate registers
"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10",
- "p11", "p12", "p13", "p14", "p15"
+ "p11", "p12", "p13", "p14", "p15",
+
+ // SVE predicate-as-counter registers
+ "pn0", "pn1", "pn2", "pn3", "pn4", "pn5", "pn6", "pn7", "pn8",
+ "pn9", "pn10", "pn11", "pn12", "pn13", "pn14", "pn15",
+
+ // SME registers
+ "za", "zt0",
+
+ // clang-format on
};
ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
@@ -675,7 +1276,53 @@ const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
};
ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const {
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
+}
+
+// Returns the length of cc constraint.
+static unsigned matchAsmCCConstraint(const char *Name) {
+ constexpr unsigned len = 5;
+ auto RV = llvm::StringSwitch<unsigned>(Name)
+ .Case("@cceq", len)
+ .Case("@ccne", len)
+ .Case("@cchs", len)
+ .Case("@cccs", len)
+ .Case("@cccc", len)
+ .Case("@cclo", len)
+ .Case("@ccmi", len)
+ .Case("@ccpl", len)
+ .Case("@ccvs", len)
+ .Case("@ccvc", len)
+ .Case("@cchi", len)
+ .Case("@ccls", len)
+ .Case("@ccge", len)
+ .Case("@cclt", len)
+ .Case("@ccgt", len)
+ .Case("@ccle", len)
+ .Default(0);
+ return RV;
+}
+
+std::string
+AArch64TargetInfo::convertConstraint(const char *&Constraint) const {
+ std::string R;
+ switch (*Constraint) {
+ case 'U': // Three-character constraint; add "@3" hint for later parsing.
+ R = std::string("@3") + std::string(Constraint, 3);
+ Constraint += 2;
+ break;
+ case '@':
+ if (const unsigned Len = matchAsmCCConstraint(Constraint)) {
+ std::string Converted = "{" + std::string(Constraint, Len) + "}";
+ Constraint += Len - 1;
+ return Converted;
+ }
+ return std::string(1, *Constraint);
+ default:
+ R = TargetInfo::convertConstraint(Constraint);
+ break;
+ }
+ return R;
}
bool AArch64TargetInfo::validateAsmConstraint(
@@ -702,8 +1349,15 @@ bool AArch64TargetInfo::validateAsmConstraint(
Info.setAllowsRegister();
return true;
case 'U':
- if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a')) {
- // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7)
+ if (Name[1] == 'p' &&
+ (Name[2] == 'l' || Name[2] == 'a' || Name[2] == 'h')) {
+ // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7, "Uph"=P8-P15)
+ Info.setAllowsRegister();
+ Name += 2;
+ return true;
+ }
+ if (Name[1] == 'c' && (Name[2] == 'i' || Name[2] == 'j')) {
+ // Gpr registers ("Uci"=w8-11, "Ucj"=w12-15)
Info.setAllowsRegister();
Name += 2;
return true;
@@ -725,6 +1379,13 @@ bool AArch64TargetInfo::validateAsmConstraint(
case 'y': // SVE registers (V0-V7)
Info.setAllowsRegister();
return true;
+ case '@':
+ // CC condition
+ if (const unsigned Len = matchAsmCCConstraint(Name)) {
+ Name += Len - 1;
+ Info.setAllowsRegister();
+ return true;
+ }
}
return false;
}
@@ -733,8 +1394,7 @@ bool AArch64TargetInfo::validateConstraintModifier(
StringRef Constraint, char Modifier, unsigned Size,
std::string &SuggestedModifier) const {
// Strip off constraint modifiers.
- while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
- Constraint = Constraint.substr(1);
+ Constraint = Constraint.ltrim("=+&");
switch (Constraint[0]) {
default:
@@ -763,7 +1423,7 @@ bool AArch64TargetInfo::validateConstraintModifier(
}
}
-const char *AArch64TargetInfo::getClobbers() const { return ""; }
+std::string_view AArch64TargetInfo::getClobbers() const { return ""; }
int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
if (RegNo == 0)
@@ -872,7 +1532,13 @@ MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
WindowsARM64TargetInfo::getTargetDefines(Opts, Builder);
- Builder.defineMacro("_M_ARM64", "1");
+ if (getTriple().isWindowsArm64EC()) {
+ Builder.defineMacro("_M_X64", "100");
+ Builder.defineMacro("_M_AMD64", "100");
+ Builder.defineMacro("_M_ARM64EC", "1");
+ } else {
+ Builder.defineMacro("_M_ARM64", "1");
+ }
}
TargetInfo::CallingConvKind
@@ -936,7 +1602,6 @@ void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts,
else
Builder.defineMacro("__ARM64_ARCH_8__");
Builder.defineMacro("__ARM_NEON__");
- Builder.defineMacro("__LITTLE_ENDIAN__");
Builder.defineMacro("__REGISTER_PREFIX__", "");
Builder.defineMacro("__arm64", "1");
Builder.defineMacro("__arm64__", "1");
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h
index 46882a808336..9699222b0bf7 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AArch64.h
@@ -15,7 +15,8 @@
#include "OSTargets.h"
#include "clang/Basic/TargetBuiltins.h"
-#include "llvm/Support/TargetParser.h"
+#include "llvm/TargetParser/AArch64TargetParser.h"
+#include <optional>
namespace clang {
namespace targets {
@@ -25,38 +26,67 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
static const TargetInfo::GCCRegAlias GCCRegAliases[];
static const char *const GCCRegNames[];
- enum FPUModeEnum { FPUMode, NeonMode = (1 << 0), SveMode = (1 << 1) };
-
- unsigned FPU;
- bool HasCRC;
- bool HasCrypto;
- bool HasAES;
- bool HasSHA2;
- bool HasSHA3;
- bool HasSM4;
- bool HasUnaligned;
- bool HasFullFP16;
- bool HasDotProd;
- bool HasFP16FML;
- bool HasMTE;
- bool HasTME;
- bool HasPAuth;
- bool HasLS64;
- bool HasRandGen;
- bool HasMatMul;
- bool HasSVE2;
- bool HasSVE2AES;
- bool HasSVE2SHA3;
- bool HasSVE2SM4;
- bool HasSVE2BitPerm;
- bool HasMatmulFP64;
- bool HasMatmulFP32;
- bool HasLSE;
- bool HasFlagM;
-
- llvm::AArch64::ArchKind ArchKind;
-
- static const Builtin::Info BuiltinInfo[];
+ enum FPUModeEnum {
+ FPUMode = (1 << 0),
+ NeonMode = (1 << 1),
+ SveMode = (1 << 2),
+ };
+
+ unsigned FPU = FPUMode;
+ bool HasCRC = false;
+ bool HasAES = false;
+ bool HasSHA2 = false;
+ bool HasSHA3 = false;
+ bool HasSM4 = false;
+ bool HasUnaligned = true;
+ bool HasFullFP16 = false;
+ bool HasDotProd = false;
+ bool HasFP16FML = false;
+ bool HasMTE = false;
+ bool HasTME = false;
+ bool HasPAuth = false;
+ bool HasLS64 = false;
+ bool HasRandGen = false;
+ bool HasMatMul = false;
+ bool HasBFloat16 = false;
+ bool HasSVE2 = false;
+ bool HasSVE2AES = false;
+ bool HasSVE2SHA3 = false;
+ bool HasSVE2SM4 = false;
+ bool HasSVE2BitPerm = false;
+ bool HasMatmulFP64 = false;
+ bool HasMatmulFP32 = false;
+ bool HasLSE = false;
+ bool HasFlagM = false;
+ bool HasAlternativeNZCV = false;
+ bool HasMOPS = false;
+ bool HasD128 = false;
+ bool HasRCPC = false;
+ bool HasRDM = false;
+ bool HasDIT = false;
+ bool HasCCPP = false;
+ bool HasCCDP = false;
+ bool HasFRInt3264 = false;
+ bool HasSME = false;
+ bool HasSME2 = false;
+ bool HasSMEF64F64 = false;
+ bool HasSMEI16I64 = false;
+ bool HasSB = false;
+ bool HasPredRes = false;
+ bool HasSSBS = false;
+ bool HasBTI = false;
+ bool HasWFxT = false;
+ bool HasJSCVT = false;
+ bool HasFCMA = false;
+ bool HasNoFP = false;
+ bool HasNoNeon = false;
+ bool HasNoSVE = false;
+ bool HasFMV = true;
+ bool HasGCS = false;
+ bool HasRCPC3 = false;
+ bool HasSMEFA64 = false;
+
+ const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
std::string ABI;
@@ -66,17 +96,27 @@ public:
StringRef getABI() const override;
bool setABI(const std::string &Name) override;
- bool validateBranchProtection(StringRef, BranchProtectionInfo &,
- StringRef &) const override;
+ bool validateBranchProtection(StringRef Spec, StringRef Arch,
+ BranchProtectionInfo &BPI,
+ StringRef &Err) const override;
bool isValidCPUName(StringRef Name) const override;
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override;
+ unsigned multiVersionSortPriority(StringRef Name) const override;
+ unsigned multiVersionFeatureCost() const override;
+
+ bool
+ initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
+ StringRef CPU,
+ const std::vector<std::string> &FeaturesVec) const override;
bool useFP16ConversionIntrinsics() const override {
return false;
}
+ void setArchFeatures();
+
void getTargetDefinesARMV81A(const LangOptions &Opts,
MacroBuilder &Builder) const;
void getTargetDefinesARMV82A(const LangOptions &Opts,
@@ -91,14 +131,43 @@ public:
MacroBuilder &Builder) const;
void getTargetDefinesARMV87A(const LangOptions &Opts,
MacroBuilder &Builder) const;
+ void getTargetDefinesARMV88A(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+ void getTargetDefinesARMV89A(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+ void getTargetDefinesARMV9A(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+ void getTargetDefinesARMV91A(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+ void getTargetDefinesARMV92A(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+ void getTargetDefinesARMV93A(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+ void getTargetDefinesARMV94A(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+ void getTargetDefinesARMV95A(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+ std::optional<std::pair<unsigned, unsigned>>
+ getVScaleRange(const LangOptions &LangOpts) const override;
+ bool doesFeatureAffectCodeGen(StringRef Name) const override;
+ StringRef getFeatureDependencies(StringRef Name) const override;
+ bool validateCpuSupports(StringRef FeatureStr) const override;
bool hasFeature(StringRef Feature) const override;
+ void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
+ bool Enabled) const override;
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override;
+ ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
+ bool supportsTargetAttributeTune() const override { return true; }
+
+ bool checkArithmeticFenceSupported() const override { return true; }
+
+ bool hasBFloat16Type() const override;
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
@@ -109,26 +178,14 @@ public:
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
- std::string convertConstraint(const char *&Constraint) const override {
- std::string R;
- switch (*Constraint) {
- case 'U': // Three-character constraint; add "@3" hint for later parsing.
- R = std::string("@3") + std::string(Constraint, 3);
- Constraint += 2;
- break;
- default:
- R = TargetInfo::convertConstraint(Constraint);
- break;
- }
- return R;
- }
+ std::string convertConstraint(const char *&Constraint) const override;
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override;
bool
validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
std::string &SuggestedModifier) const override;
- const char *getClobbers() const override;
+ std::string_view getClobbers() const override;
StringRef getConstraintRegister(StringRef Constraint,
StringRef Expression) const override {
@@ -140,7 +197,7 @@ public:
const char *getBFloat16Mangling() const override { return "u6__bf16"; };
bool hasInt128Type() const override;
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
};
class LLVM_LIBRARY_VISIBILITY AArch64leTargetInfo : public AArch64TargetInfo {
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp
index fac786dbcf9e..6f3a4908623d 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.cpp
@@ -13,12 +13,10 @@
#include "AMDGPU.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CodeGenOptions.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetBuiltins.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Frontend/OpenMP/OMPGridValues.h"
-
using namespace clang;
using namespace clang::targets;
@@ -34,63 +32,66 @@ static const char *const DataLayoutStringR600 =
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"
+ "-p7:160:256:256:32-p8:128:128-p9:192:256:256: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-S32-A5-G1"
- "-ni:7";
+ "-ni:7:8:9";
const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
- Generic, // Default
- Global, // opencl_global
- Local, // opencl_local
- Constant, // opencl_constant
- Private, // opencl_private
- Generic, // opencl_generic
- Global, // opencl_global_device
- Global, // opencl_global_host
- Global, // cuda_device
- Constant, // cuda_constant
- Local, // cuda_shared
- Global, // sycl_global
- Global, // sycl_global_device
- Global, // sycl_global_host
- Local, // sycl_local
- Private, // sycl_private
- Generic, // ptr32_sptr
- Generic, // ptr32_uptr
- Generic // ptr64
+ llvm::AMDGPUAS::FLAT_ADDRESS, // Default
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global
+ llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local
+ llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant
+ llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private
+ llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device
+ llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant
+ llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_device
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // sycl_global_host
+ llvm::AMDGPUAS::LOCAL_ADDRESS, // sycl_local
+ llvm::AMDGPUAS::PRIVATE_ADDRESS, // sycl_private
+ llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr
+ llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr
+ llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
+ llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared
};
const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
- Private, // Default
- Global, // opencl_global
- Local, // opencl_local
- Constant, // opencl_constant
- Private, // opencl_private
- Generic, // opencl_generic
- Global, // opencl_global_device
- Global, // opencl_global_host
- Global, // cuda_device
- Constant, // cuda_constant
- Local, // cuda_shared
+ llvm::AMDGPUAS::PRIVATE_ADDRESS, // Default
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global
+ llvm::AMDGPUAS::LOCAL_ADDRESS, // opencl_local
+ llvm::AMDGPUAS::CONSTANT_ADDRESS, // opencl_constant
+ llvm::AMDGPUAS::PRIVATE_ADDRESS, // opencl_private
+ llvm::AMDGPUAS::FLAT_ADDRESS, // opencl_generic
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_device
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // opencl_global_host
+ llvm::AMDGPUAS::GLOBAL_ADDRESS, // cuda_device
+ llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant
+ llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared
// SYCL address space values for this map are dummy
- Generic, // sycl_global
- Generic, // sycl_global_device
- Generic, // sycl_global_host
- Generic, // sycl_local
- Generic, // sycl_private
- Generic, // ptr32_sptr
- Generic, // ptr32_uptr
- Generic // ptr64
+ llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global
+ llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_device
+ llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_host
+ llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local
+ llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private
+ llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr
+ llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr
+ llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64
+ llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared
};
} // namespace targets
} // namespace clang
-const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsAMDGPU.def"
};
@@ -172,7 +173,7 @@ const char *const AMDGPUTargetInfo::GCCRegNames[] = {
};
ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
bool AMDGPUTargetInfo::initFeatureMap(
@@ -180,136 +181,18 @@ bool AMDGPUTargetInfo::initFeatureMap(
const std::vector<std::string> &FeatureVec) const {
using namespace llvm::AMDGPU;
-
- // XXX - What does the member GPU mean if device name string passed here?
- if (isAMDGCN(getTriple())) {
- switch (llvm::AMDGPU::parseArchAMDGCN(CPU)) {
- case GK_GFX1035:
- case GK_GFX1034:
- case GK_GFX1033:
- case GK_GFX1032:
- case GK_GFX1031:
- case GK_GFX1030:
- Features["ci-insts"] = true;
- Features["dot1-insts"] = true;
- Features["dot2-insts"] = true;
- Features["dot5-insts"] = true;
- Features["dot6-insts"] = true;
- Features["dot7-insts"] = true;
- Features["dl-insts"] = true;
- Features["flat-address-space"] = true;
- Features["16-bit-insts"] = true;
- Features["dpp"] = true;
- Features["gfx8-insts"] = true;
- Features["gfx9-insts"] = true;
- Features["gfx10-insts"] = true;
- Features["gfx10-3-insts"] = true;
- Features["s-memrealtime"] = true;
- Features["s-memtime-inst"] = true;
- break;
- case GK_GFX1012:
- case GK_GFX1011:
- Features["dot1-insts"] = true;
- Features["dot2-insts"] = true;
- Features["dot5-insts"] = true;
- Features["dot6-insts"] = true;
- Features["dot7-insts"] = true;
- LLVM_FALLTHROUGH;
- case GK_GFX1013:
- case GK_GFX1010:
- Features["dl-insts"] = true;
- Features["ci-insts"] = true;
- Features["flat-address-space"] = true;
- Features["16-bit-insts"] = true;
- Features["dpp"] = true;
- Features["gfx8-insts"] = true;
- Features["gfx9-insts"] = true;
- Features["gfx10-insts"] = true;
- Features["s-memrealtime"] = true;
- Features["s-memtime-inst"] = true;
- break;
- case GK_GFX90A:
- Features["gfx90a-insts"] = true;
- LLVM_FALLTHROUGH;
- case GK_GFX908:
- Features["dot3-insts"] = true;
- Features["dot4-insts"] = true;
- Features["dot5-insts"] = true;
- Features["dot6-insts"] = true;
- Features["mai-insts"] = true;
- LLVM_FALLTHROUGH;
- case GK_GFX906:
- Features["dl-insts"] = true;
- Features["dot1-insts"] = true;
- Features["dot2-insts"] = true;
- Features["dot7-insts"] = true;
- LLVM_FALLTHROUGH;
- case GK_GFX90C:
- case GK_GFX909:
- case GK_GFX904:
- case GK_GFX902:
- case GK_GFX900:
- Features["gfx9-insts"] = true;
- LLVM_FALLTHROUGH;
- case GK_GFX810:
- case GK_GFX805:
- case GK_GFX803:
- case GK_GFX802:
- case GK_GFX801:
- Features["gfx8-insts"] = true;
- Features["16-bit-insts"] = true;
- Features["dpp"] = true;
- Features["s-memrealtime"] = true;
- LLVM_FALLTHROUGH;
- case GK_GFX705:
- case GK_GFX704:
- case GK_GFX703:
- case GK_GFX702:
- case GK_GFX701:
- case GK_GFX700:
- Features["ci-insts"] = true;
- Features["flat-address-space"] = true;
- LLVM_FALLTHROUGH;
- case GK_GFX602:
- case GK_GFX601:
- case GK_GFX600:
- Features["s-memtime-inst"] = true;
- break;
- case GK_NONE:
- break;
- default:
- llvm_unreachable("Unhandled GPU!");
- }
- } else {
- if (CPU.empty())
- CPU = "r600";
-
- switch (llvm::AMDGPU::parseArchR600(CPU)) {
- case GK_CAYMAN:
- case GK_CYPRESS:
- case GK_RV770:
- case GK_RV670:
- // TODO: Add fp64 when implemented.
- break;
- 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 GPU!");
- }
+ fillAMDGPUFeatureMap(CPU, getTriple(), Features);
+ if (!TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec))
+ return false;
+
+ // TODO: Should move this logic into TargetParser
+ std::string ErrorMsg;
+ if (!insertWaveSizeFeature(CPU, getTriple(), Features, ErrorMsg)) {
+ Diags.Report(diag::err_invalid_feature_combination) << ErrorMsg;
+ return false;
}
- return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec);
+ return true;
}
void AMDGPUTargetInfo::fillValidCPUList(
@@ -335,19 +218,24 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
llvm::AMDGPU::getArchAttrR600(GPUKind)) {
resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN
: DataLayoutStringR600);
- GridValues = llvm::omp::AMDGPUGpuGridValues;
setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D ||
!isAMDGCN(Triple));
UseAddrSpaceMapMangling = true;
+ if (isAMDGCN(Triple)) {
+ // __bf16 is always available as a load/store only type on AMDGCN.
+ BFloat16Width = BFloat16Align = 16;
+ BFloat16Format = &llvm::APFloat::BFloat();
+ }
+
HasLegalHalfType = true;
HasFloat16 = true;
WavefrontSize = GPUFeatures & llvm::AMDGPU::FEATURE_WAVE32 ? 32 : 64;
AllowAMDGPUUnsafeFPAtomics = Opts.AllowAMDGPUUnsafeFPAtomics;
- // Set pointer width and alignment for target address space 0.
- PointerWidth = PointerAlign = getPointerWidthV(Generic);
+ // Set pointer width and alignment for the generic address space.
+ PointerWidth = PointerAlign = getPointerWidthV(LangAS::Default);
if (getMaxPointerWidth() == 64) {
LongWidth = LongAlign = 64;
SizeType = UnsignedLong;
@@ -356,6 +244,10 @@ AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
}
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ CUMode = !(GPUFeatures & llvm::AMDGPU::FEATURE_WGP);
+ for (auto F : {"image-insts", "gws"})
+ ReadOnlyFeatures.insert(F);
+ HalfArgsAndReturns = true;
}
void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
@@ -368,8 +260,8 @@ void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
}
ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
@@ -386,12 +278,17 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
StringRef CanonName = isAMDGCN(getTriple()) ?
getArchNameAMDGCN(GPUKind) : getArchNameR600(GPUKind);
Builder.defineMacro(Twine("__") + Twine(CanonName) + Twine("__"));
+ // Emit macros for gfx family e.g. gfx906 -> __GFX9__, gfx1030 -> __GFX10___
+ if (isAMDGCN(getTriple())) {
+ assert(CanonName.starts_with("gfx") && "Invalid amdgcn canonical name");
+ Builder.defineMacro(Twine("__") + Twine(CanonName.drop_back(2).upper()) +
+ Twine("__"));
+ }
if (isAMDGCN(getTriple())) {
Builder.defineMacro("__amdgcn_processor__",
Twine("\"") + Twine(CanonName) + Twine("\""));
Builder.defineMacro("__amdgcn_target_id__",
- Twine("\"") + Twine(getTargetID().getValue()) +
- Twine("\""));
+ Twine("\"") + Twine(*getTargetID()) + Twine("\""));
for (auto F : getAllPossibleTargetIDFeatures(getTriple(), CanonName)) {
auto Loc = OffloadArchFeatures.find(F);
if (Loc != OffloadArchFeatures.end()) {
@@ -405,6 +302,9 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
}
}
+ if (AllowAMDGPUUnsafeFPAtomics)
+ Builder.defineMacro("__AMDGCN_UNSAFE_FP_ATOMICS__");
+
// TODO: __HAS_FMAF__, __HAS_LDEXPF__, __HAS_FP64__ are deprecated and will be
// removed in the near future.
if (hasFMAF())
@@ -418,7 +318,10 @@ void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
if (hasFastFMA())
Builder.defineMacro("FP_FAST_FMA");
+ Builder.defineMacro("__AMDGCN_WAVEFRONT_SIZE__", Twine(WavefrontSize));
+ // ToDo: deprecate this macro for naming consistency.
Builder.defineMacro("__AMDGCN_WAVEFRONT_SIZE", Twine(WavefrontSize));
+ Builder.defineMacro("__AMDGCN_CUMODE__", Twine(CUMode));
}
void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) {
@@ -431,9 +334,13 @@ void AMDGPUTargetInfo::setAuxTarget(const TargetInfo *Aux) {
// supported by AMDGPU. Therefore keep its own format for these two types.
auto SaveLongDoubleFormat = LongDoubleFormat;
auto SaveFloat128Format = Float128Format;
+ auto SaveLongDoubleWidth = LongDoubleWidth;
+ auto SaveLongDoubleAlign = LongDoubleAlign;
copyAuxTarget(Aux);
LongDoubleFormat = SaveLongDoubleFormat;
Float128Format = SaveFloat128Format;
+ LongDoubleWidth = SaveLongDoubleWidth;
+ LongDoubleAlign = SaveLongDoubleAlign;
// For certain builtin types support on the host target, claim they are
// support to pass the compilation of the host code during the device-side
// compilation.
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h
index 2e580ecf2425..90a1516ecdd2 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AMDGPU.h
@@ -17,25 +17,19 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/Support/AMDGPUAddrSpace.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/TargetParser.h"
+#include "llvm/TargetParser/TargetParser.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
namespace clang {
namespace targets {
class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
static const char *const GCCRegNames[];
- enum AddrSpace {
- Generic = 0,
- Global = 1,
- Local = 3,
- Constant = 4,
- Private = 5
- };
static const LangASMap AMDGPUDefIsGenMap;
static const LangASMap AMDGPUDefIsPrivMap;
@@ -43,6 +37,12 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
unsigned GPUFeatures;
unsigned WavefrontSize;
+ /// Whether to use cumode or WGP mode. True for cumode. False for WGP mode.
+ bool CUMode;
+
+ /// Whether having image instructions.
+ bool HasImage = false;
+
/// Target ID is device name followed by optional feature name postfixed
/// by plus or minus sign delimitted by colon, e.g. gfx908:xnack+:sramecc-.
/// If the target ID contains feature+, map it to true.
@@ -95,17 +95,19 @@ public:
void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
- uint64_t getPointerWidthV(unsigned AddrSpace) const override {
+ uint64_t getPointerWidthV(LangAS AS) const override {
if (isR600(getTriple()))
return 32;
+ unsigned TargetAS = getTargetAddressSpace(AS);
- if (AddrSpace == Private || AddrSpace == Local)
+ if (TargetAS == llvm::AMDGPUAS::PRIVATE_ADDRESS ||
+ TargetAS == llvm::AMDGPUAS::LOCAL_ADDRESS)
return 32;
return 64;
}
- uint64_t getPointerAlignV(unsigned AddrSpace) const override {
+ uint64_t getPointerAlignV(LangAS AddrSpace) const override {
return getPointerWidthV(AddrSpace);
}
@@ -113,12 +115,14 @@ public:
return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
}
- const char *getClobbers() const override { return ""; }
+ bool hasBFloat16Type() const override { return isAMDGCN(getTriple()); }
+
+ std::string_view getClobbers() const override { return ""; }
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
/// Accepted register names: (n, m is unsigned integer, n < m)
@@ -165,10 +169,8 @@ public:
}
bool HasLeftParen = false;
- if (S.front() == '{') {
+ if (S.consume_front("{"))
HasLeftParen = true;
- S = S.drop_front();
- }
if (S.empty())
return false;
if (S.front() != 'v' && S.front() != 's' && S.front() != 'a') {
@@ -195,29 +197,24 @@ public:
return true;
}
bool HasLeftBracket = false;
- if (!S.empty() && S.front() == '[') {
+ if (S.consume_front("["))
HasLeftBracket = true;
- S = S.drop_front();
- }
unsigned long long N;
if (S.empty() || consumeUnsignedInteger(S, 10, N))
return false;
- if (!S.empty() && S.front() == ':') {
+ if (S.consume_front(":")) {
if (!HasLeftBracket)
return false;
- S = S.drop_front();
unsigned long long M;
if (consumeUnsignedInteger(S, 10, M) || N >= M)
return false;
}
if (HasLeftBracket) {
- if (S.empty() || S.front() != ']')
+ if (!S.consume_front("]"))
return false;
- S = S.drop_front();
}
- if (S.empty() || S.front() != '}')
+ if (!S.consume_front("}"))
return false;
- S = S.drop_front();
if (!S.empty())
return false;
// Found {vn}, {sn}, {an}, {v[n]}, {s[n]}, {a[n]}, {v[n:m]}, {s[n:m]}
@@ -352,34 +349,56 @@ public:
}
LangAS getCUDABuiltinAddressSpace(unsigned AS) const override {
- return LangAS::Default;
+ switch (AS) {
+ case 0:
+ return LangAS::Default;
+ case 1:
+ return LangAS::cuda_device;
+ case 3:
+ return LangAS::cuda_shared;
+ case 4:
+ return LangAS::cuda_constant;
+ default:
+ return getLangASFromTargetAS(AS);
+ }
+ }
+
+ std::optional<LangAS> getConstantAddressSpace() const override {
+ return getLangASFromTargetAS(llvm::AMDGPUAS::CONSTANT_ADDRESS);
}
- llvm::Optional<LangAS> getConstantAddressSpace() const override {
- return getLangASFromTargetAS(Constant);
+ const llvm::omp::GV &getGridValue() const override {
+ switch (WavefrontSize) {
+ case 32:
+ return llvm::omp::getAMDGPUGridValues<32>();
+ case 64:
+ return llvm::omp::getAMDGPUGridValues<64>();
+ default:
+ llvm_unreachable("getGridValue not implemented for this wavesize");
+ }
}
/// \returns Target specific vtbl ptr address space.
unsigned getVtblPtrAddressSpace() const override {
- return static_cast<unsigned>(Constant);
+ return static_cast<unsigned>(llvm::AMDGPUAS::CONSTANT_ADDRESS);
}
/// \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
/// corresponding target specific DWARF address space.
///
- /// \returns Otherwise return None and no conversion will be emitted in the
- /// DWARF.
- Optional<unsigned>
+ /// \returns Otherwise return std::nullopt and no conversion will be emitted
+ /// in the DWARF.
+ std::optional<unsigned>
getDWARFAddressSpace(unsigned AddressSpace) const override {
const unsigned DWARF_Private = 1;
const unsigned DWARF_Local = 2;
- if (AddressSpace == Private) {
+ if (AddressSpace == llvm::AMDGPUAS::PRIVATE_ADDRESS) {
return DWARF_Private;
- } else if (AddressSpace == Local) {
+ } else if (AddressSpace == llvm::AMDGPUAS::LOCAL_ADDRESS) {
return DWARF_Local;
} else {
- return None;
+ return std::nullopt;
}
}
@@ -389,6 +408,7 @@ public:
return CCCR_Warning;
case CC_C:
case CC_OpenCLKernel:
+ case CC_AMDGPUKernelCall:
return CCCR_OK;
}
}
@@ -404,7 +424,7 @@ public:
void setAuxTarget(const TargetInfo *Aux) override;
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
// Record offload arch features since they are needed for defining the
// pre-defined macros.
@@ -412,23 +432,29 @@ public:
DiagnosticsEngine &Diags) override {
auto TargetIDFeatures =
getAllPossibleTargetIDFeatures(getTriple(), getArchNameAMDGCN(GPUKind));
- llvm::for_each(Features, [&](const auto &F) {
+ for (const auto &F : Features) {
assert(F.front() == '+' || F.front() == '-');
if (F == "+wavefrontsize64")
WavefrontSize = 64;
+ else if (F == "+cumode")
+ CUMode = true;
+ else if (F == "-cumode")
+ CUMode = false;
+ else if (F == "+image-insts")
+ HasImage = true;
bool IsOn = F.front() == '+';
StringRef Name = StringRef(F).drop_front();
- if (llvm::find(TargetIDFeatures, Name) == TargetIDFeatures.end())
- return;
- assert(OffloadArchFeatures.find(Name) == OffloadArchFeatures.end());
+ if (!llvm::is_contained(TargetIDFeatures, Name))
+ continue;
+ assert(!OffloadArchFeatures.contains(Name));
OffloadArchFeatures[Name] = IsOn;
- });
+ }
return true;
}
- Optional<std::string> getTargetID() const override {
+ std::optional<std::string> getTargetID() const override {
if (!isAMDGCN(getTriple()))
- return llvm::None;
+ return std::nullopt;
// When -target-cpu is not set, we assume generic code that it is valid
// for all GPU and use an empty string as target ID to represent that.
if (GPUKind == llvm::AMDGPU::GK_NONE)
@@ -436,6 +462,8 @@ public:
return getCanonicalTargetID(getArchNameAMDGCN(GPUKind),
OffloadArchFeatures);
}
+
+ bool hasHIPImageSupport() const override { return HasImage; }
};
} // namespace targets
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARC.h b/contrib/llvm-project/clang/lib/Basic/Targets/ARC.h
index b314c42be1e9..fcbfdd6eec58 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/ARC.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARC.h
@@ -15,8 +15,8 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -40,13 +40,15 @@ public:
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
- ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+ return std::nullopt;
+ }
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
ArrayRef<const char *> getGCCRegNames() const override {
static const char *const GCCRegNames[] = {
@@ -54,11 +56,11 @@ public:
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "gp", "sp", "fp", "ilink1", "r30", "blink"};
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
bool validateAsmConstraint(const char *&Name,
@@ -66,7 +68,9 @@ public:
return false;
}
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
+
+ bool isCLZForZeroUndef() const override { return false; }
};
} // namespace targets
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
index 0e4048f8d5ff..55b71557452f 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/TargetParser/ARMTargetParser.h"
using namespace clang;
using namespace clang::targets;
@@ -212,6 +213,22 @@ StringRef ARMTargetInfo::getCPUAttr() const {
return "8_6A";
case llvm::ARM::ArchKind::ARMV8_7A:
return "8_7A";
+ case llvm::ARM::ArchKind::ARMV8_8A:
+ return "8_8A";
+ case llvm::ARM::ArchKind::ARMV8_9A:
+ return "8_9A";
+ case llvm::ARM::ArchKind::ARMV9A:
+ return "9A";
+ case llvm::ARM::ArchKind::ARMV9_1A:
+ return "9_1A";
+ case llvm::ARM::ArchKind::ARMV9_2A:
+ return "9_2A";
+ case llvm::ARM::ArchKind::ARMV9_3A:
+ return "9_3A";
+ case llvm::ARM::ArchKind::ARMV9_4A:
+ return "9_4A";
+ case llvm::ARM::ArchKind::ARMV9_5A:
+ return "9_5A";
case llvm::ARM::ArchKind::ARMV8MBaseline:
return "8M_BASE";
case llvm::ARM::ArchKind::ARMV8MMainline:
@@ -240,8 +257,11 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
HW_FP(0) {
+ bool IsFreeBSD = Triple.isOSFreeBSD();
bool IsOpenBSD = Triple.isOSOpenBSD();
bool IsNetBSD = Triple.isOSNetBSD();
+ bool IsHaiku = Triple.isOSHaiku();
+ bool IsOHOS = Triple.isOHOSFamily();
// FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
// environment where size_t is `unsigned long` rather than `unsigned int`
@@ -295,6 +315,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
case llvm::Triple::GNUEABIHF:
case llvm::Triple::MuslEABI:
case llvm::Triple::MuslEABIHF:
+ case llvm::Triple::OpenHOS:
setABI("aapcs-linux");
break;
case llvm::Triple::EABIHF:
@@ -307,7 +328,7 @@ ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
default:
if (IsNetBSD)
setABI("apcs-gnu");
- else if (IsOpenBSD)
+ else if (IsFreeBSD || IsOpenBSD || IsHaiku || IsOHOS)
setABI("aapcs-linux");
else
setABI("aapcs");
@@ -361,6 +382,50 @@ bool ARMTargetInfo::setABI(const std::string &Name) {
return false;
}
+bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
+ llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
+ if (CPUArch == llvm::ARM::ArchKind::INVALID)
+ CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
+
+ if (CPUArch == llvm::ARM::ArchKind::INVALID)
+ return false;
+
+ StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
+ auto a =
+ llvm::Triple(ArchFeature, getTriple().getVendorName(),
+ getTriple().getOSName(), getTriple().getEnvironmentName());
+
+ StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
+ llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
+ return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
+}
+
+bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
+ BranchProtectionInfo &BPI,
+ StringRef &Err) const {
+ llvm::ARM::ParsedBranchProtection PBP;
+ if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
+ return false;
+
+ if (!isBranchProtectionSupportedArch(Arch))
+ return false;
+
+ BPI.SignReturnAddr =
+ llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
+ .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
+ .Case("all", LangOptions::SignReturnAddressScopeKind::All)
+ .Default(LangOptions::SignReturnAddressScopeKind::None);
+
+ // Don't care for the sign key, beyond issuing a warning.
+ if (PBP.Key == "b_key")
+ Err = "b-key";
+ BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
+
+ BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
+ BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR;
+ return true;
+}
+
// FIXME: This should be based on Arch attributes, not CPU names.
bool ARMTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
@@ -378,10 +443,23 @@ bool ARMTargetInfo::initFeatureMap(
if (CPUArch != llvm::ARM::ArchKind::INVALID) {
ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
TargetFeatures.push_back(ArchFeature);
+
+ // These features are added to allow arm_neon.h target(..) attributes to
+ // match with both arm and aarch64. We need to add all previous architecture
+ // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
+ // v8.x counterparts are added too. We only need these for anything > 8.0-A.
+ for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);
+ I != llvm::ARM::ArchKind::INVALID; --I)
+ Features[llvm::ARM::getSubArch(I)] = true;
+ if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&
+ CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)
+ for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;
+ --I)
+ Features[llvm::ARM::getSubArch(I)] = true;
}
// get default FPU features
- unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
+ llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
// get default Extension features
@@ -437,9 +515,13 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HWDiv = 0;
DotProd = 0;
HasMatMul = 0;
+ HasPAC = 0;
+ HasBTI = 0;
HasFloat16 = true;
ARMCDECoprocMask = 0;
HasBFloat16 = false;
+ HasFullBFloat16 = false;
+ FPRegsDisabled = false;
// This does not diagnose illegal cases like having both
// "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
@@ -516,9 +598,18 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
ARMCDECoprocMask |= (1U << Coproc);
} else if (Feature == "+bf16") {
HasBFloat16 = true;
+ } else if (Feature == "-fpregs") {
+ FPRegsDisabled = true;
+ } else if (Feature == "+pacbti") {
+ HasPAC = 1;
+ HasBTI = 1;
+ } else if (Feature == "+fullbf16") {
+ HasFullBFloat16 = true;
}
}
+ HalfArgsAndReturns = true;
+
switch (ArchVersion) {
case 6:
if (ArchProfile == llvm::ARM::ProfileKind::M)
@@ -535,6 +626,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
break;
case 8:
+ case 9:
LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
}
@@ -566,7 +658,8 @@ bool ARMTargetInfo::hasFeature(StringRef Feature) const {
}
bool ARMTargetInfo::hasBFloat16Type() const {
- return HasBFloat16 && !SoftFloat;
+ // The __bf16 type is generally available so long as we have any fp registers.
+ return HasBFloat16 || (FPU && !SoftFloat);
}
bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
@@ -627,8 +720,10 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
// For bare-metal none-eabi.
if (getTriple().getOS() == llvm::Triple::UnknownOS &&
(getTriple().getEnvironment() == llvm::Triple::EABI ||
- getTriple().getEnvironment() == llvm::Triple::EABIHF))
- Builder.defineMacro("__ELF__");
+ getTriple().getEnvironment() == llvm::Triple::EABIHF) &&
+ Opts.CPlusPlus) {
+ Builder.defineMacro("_GNU_SOURCE");
+ }
// Target properties.
Builder.defineMacro("__REGISTER_PREFIX__", "");
@@ -736,7 +831,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
Builder.defineMacro("__ARM_PCS_VFP", "1");
- if (SoftFloat)
+ if (SoftFloat || (SoftFloatABI && !FPU))
Builder.defineMacro("__SOFTFP__");
// ACLE position independent code macros.
@@ -745,6 +840,70 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
if (Opts.RWPI)
Builder.defineMacro("__ARM_RWPI", "1");
+ // Macros for enabling co-proc intrinsics
+ uint64_t FeatureCoprocBF = 0;
+ switch (ArchKind) {
+ default:
+ break;
+ case llvm::ARM::ArchKind::ARMV4:
+ case llvm::ARM::ArchKind::ARMV4T:
+ // Filter __arm_ldcl and __arm_stcl in acle.h
+ FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1;
+ break;
+ case llvm::ARM::ArchKind::ARMV5T:
+ FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1 | FEATURE_COPROC_B2;
+ break;
+ case llvm::ARM::ArchKind::ARMV5TE:
+ case llvm::ARM::ArchKind::ARMV5TEJ:
+ if (!isThumb())
+ FeatureCoprocBF =
+ FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | FEATURE_COPROC_B3;
+ break;
+ case llvm::ARM::ArchKind::ARMV6:
+ case llvm::ARM::ArchKind::ARMV6K:
+ case llvm::ARM::ArchKind::ARMV6KZ:
+ case llvm::ARM::ArchKind::ARMV6T2:
+ if (!isThumb() || ArchKind == llvm::ARM::ArchKind::ARMV6T2)
+ FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
+ FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
+ break;
+ case llvm::ARM::ArchKind::ARMV7A:
+ case llvm::ARM::ArchKind::ARMV7R:
+ case llvm::ARM::ArchKind::ARMV7M:
+ case llvm::ARM::ArchKind::ARMV7S:
+ case llvm::ARM::ArchKind::ARMV7EM:
+ FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
+ FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
+ break;
+ case llvm::ARM::ArchKind::ARMV8A:
+ case llvm::ARM::ArchKind::ARMV8R:
+ case llvm::ARM::ArchKind::ARMV8_1A:
+ case llvm::ARM::ArchKind::ARMV8_2A:
+ case llvm::ARM::ArchKind::ARMV8_3A:
+ case llvm::ARM::ArchKind::ARMV8_4A:
+ case llvm::ARM::ArchKind::ARMV8_5A:
+ case llvm::ARM::ArchKind::ARMV8_6A:
+ case llvm::ARM::ArchKind::ARMV8_7A:
+ case llvm::ARM::ArchKind::ARMV8_8A:
+ case llvm::ARM::ArchKind::ARMV8_9A:
+ case llvm::ARM::ArchKind::ARMV9A:
+ case llvm::ARM::ArchKind::ARMV9_1A:
+ case llvm::ARM::ArchKind::ARMV9_2A:
+ case llvm::ARM::ArchKind::ARMV9_3A:
+ case llvm::ARM::ArchKind::ARMV9_4A:
+ case llvm::ARM::ArchKind::ARMV9_5A:
+ // Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h
+ FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3;
+ break;
+ case llvm::ARM::ArchKind::ARMV8MMainline:
+ case llvm::ARM::ArchKind::ARMV8_1MMainline:
+ FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 |
+ FEATURE_COPROC_B3 | FEATURE_COPROC_B4;
+ break;
+ }
+ Builder.defineMacro("__ARM_FEATURE_COPROC",
+ "0x" + Twine::utohexstr(FeatureCoprocBF));
+
if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Builder.defineMacro("__XSCALE__");
@@ -858,12 +1017,28 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasMatMul)
Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
+ if (HasPAC)
+ Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
+
+ if (HasBTI)
+ Builder.defineMacro("__ARM_FEATURE_BTI", "1");
+
if (HasBFloat16) {
Builder.defineMacro("__ARM_FEATURE_BF16", "1");
Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
}
+ if (Opts.BranchTargetEnforcement)
+ Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
+
+ if (Opts.hasSignReturnAddress()) {
+ unsigned Value = 1;
+ if (Opts.isSignReturnAddressScopeAll())
+ Value |= 1 << 2;
+ Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));
+ }
+
switch (ArchKind) {
default:
break;
@@ -877,32 +1052,45 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
case llvm::ARM::ArchKind::ARMV8_4A:
case llvm::ARM::ArchKind::ARMV8_5A:
case llvm::ARM::ArchKind::ARMV8_6A:
+ case llvm::ARM::ArchKind::ARMV8_7A:
+ case llvm::ARM::ArchKind::ARMV8_8A:
+ case llvm::ARM::ArchKind::ARMV8_9A:
+ case llvm::ARM::ArchKind::ARMV9A:
+ case llvm::ARM::ArchKind::ARMV9_1A:
+ case llvm::ARM::ArchKind::ARMV9_2A:
+ case llvm::ARM::ArchKind::ARMV9_3A:
+ case llvm::ARM::ArchKind::ARMV9_4A:
+ case llvm::ARM::ArchKind::ARMV9_5A:
getTargetDefinesARMV83A(Opts, Builder);
break;
}
}
-const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsNEON.def"
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
- {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
- {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
#include "clang/Basic/BuiltinsARM.def"
};
ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
@@ -933,7 +1121,7 @@ const char *const ARMTargetInfo::GCCRegNames[] = {
"q12", "q13", "q14", "q15"};
ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
@@ -946,7 +1134,7 @@ const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
};
ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
bool ARMTargetInfo::validateAsmConstraint(
@@ -968,6 +1156,8 @@ bool ARMTargetInfo::validateAsmConstraint(
case 't': // s0-s31, d0-d31, or q0-q15
case 'w': // s0-s15, d0-d7, or q0-q3
case 'x': // s0-s31, d0-d15, or q0-q7
+ if (FPRegsDisabled)
+ return false;
Info.setAllowsRegister();
return true;
case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
@@ -1108,8 +1298,7 @@ bool ARMTargetInfo::validateConstraintModifier(
bool isInOut = (Constraint[0] == '+');
// Strip off constraint modifiers.
- while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
- Constraint = Constraint.substr(1);
+ Constraint = Constraint.ltrim("=+&");
switch (Constraint[0]) {
default:
@@ -1127,7 +1316,7 @@ bool ARMTargetInfo::validateConstraintModifier(
return true;
}
-const char *ARMTargetInfo::getClobbers() const {
+std::string_view ARMTargetInfo::getClobbers() const {
// FIXME: Is this really right?
return "";
}
@@ -1289,11 +1478,6 @@ DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
HasAlignMac68kSupport = true;
- // iOS always has 64-bit atomic instructions.
- // FIXME: This should be based off of the target features in
- // ARMleTargetInfo.
- MaxAtomicInlineWidth = 64;
-
if (Triple.isWatchABI()) {
// Darwin on iOS uses a variant of the ARM C++ ABI.
TheCXXABI.set(TargetCXXABI::WatchOS);
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h
index 0910064a033b..9802eb01abf3 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/ARM.h
@@ -16,9 +16,10 @@
#include "OSTargets.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/TargetParser.h"
+#include "llvm/TargetParser/ARMTargetParser.h"
+#include "llvm/TargetParser/ARMTargetParserCommon.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -78,6 +79,9 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
unsigned Unaligned : 1;
unsigned DotProd : 1;
unsigned HasMatMul : 1;
+ unsigned FPRegsDisabled : 1;
+ unsigned HasPAC : 1;
+ unsigned HasBTI : 1;
enum {
LDREX_B = (1 << 0), /// byte (8-bit)
@@ -96,7 +100,18 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
};
uint32_t HW_FP;
- static const Builtin::Info BuiltinInfo[];
+ enum {
+ /// __arm_cdp __arm_ldc, __arm_ldcl, __arm_stc,
+ /// __arm_stcl, __arm_mcr and __arm_mrc
+ FEATURE_COPROC_B1 = (1 << 0),
+ /// __arm_cdp2, __arm_ldc2, __arm_stc2, __arm_ldc2l,
+ /// __arm_stc2l, __arm_mcr2 and __arm_mrc2
+ FEATURE_COPROC_B2 = (1 << 1),
+ /// __arm_mcrr, __arm_mrrc
+ FEATURE_COPROC_B3 = (1 << 2),
+ /// __arm_mcrr2, __arm_mrrc2
+ FEATURE_COPROC_B4 = (1 << 3),
+ };
void setABIAAPCS();
void setABIAPCS(bool IsAAPCS16);
@@ -122,6 +137,11 @@ public:
StringRef getABI() const override;
bool setABI(const std::string &Name) override;
+ bool isBranchProtectionSupportedArch(StringRef Arch) const override;
+ bool validateBranchProtection(StringRef Spec, StringRef Arch,
+ BranchProtectionInfo &BPI,
+ StringRef &Err) const override;
+
// FIXME: This should be based on Arch attributes, not CPU names.
bool
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
@@ -174,7 +194,7 @@ public:
bool
validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
std::string &SuggestedModifier) const override;
- const char *getClobbers() const override;
+ std::string_view getClobbers() const override;
StringRef getConstraintRegister(StringRef Constraint,
StringRef Expression) const override {
@@ -187,8 +207,8 @@ public:
bool hasSjLjLowering() const override;
- bool hasExtIntType() const override { return true; }
-
+ bool hasBitIntType() const override { return true; }
+
const char *getBFloat16Mangling() const override { return "u6__bf16"; };
};
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp
index e87b7338c4d6..85ca4bc30c46 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.cpp
@@ -24,297 +24,475 @@ namespace targets {
struct LLVM_LIBRARY_VISIBILITY MCUInfo {
const char *Name;
const char *DefineName;
+ StringRef Arch; // The __AVR_ARCH__ value.
+ const int NumFlashBanks; // Set to 0 for the devices do not support LPM/ELPM.
};
-// This list should be kept up-to-date with AVRDevices.td in LLVM.
+// NOTE: This list has been synchronized with gcc-avr 5.4.0 and avr-libc 2.0.0.
static MCUInfo AVRMcus[] = {
- {"at90s1200", "__AVR_AT90S1200__"},
- {"attiny11", "__AVR_ATtiny11__"},
- {"attiny12", "__AVR_ATtiny12__"},
- {"attiny15", "__AVR_ATtiny15__"},
- {"attiny28", "__AVR_ATtiny28__"},
- {"at90s2313", "__AVR_AT90S2313__"},
- {"at90s2323", "__AVR_AT90S2323__"},
- {"at90s2333", "__AVR_AT90S2333__"},
- {"at90s2343", "__AVR_AT90S2343__"},
- {"attiny22", "__AVR_ATtiny22__"},
- {"attiny26", "__AVR_ATtiny26__"},
- {"at86rf401", "__AVR_AT86RF401__"},
- {"at90s4414", "__AVR_AT90S4414__"},
- {"at90s4433", "__AVR_AT90S4433__"},
- {"at90s4434", "__AVR_AT90S4434__"},
- {"at90s8515", "__AVR_AT90S8515__"},
- {"at90c8534", "__AVR_AT90c8534__"},
- {"at90s8535", "__AVR_AT90S8535__"},
- {"ata5272", "__AVR_ATA5272__"},
- {"attiny13", "__AVR_ATtiny13__"},
- {"attiny13a", "__AVR_ATtiny13A__"},
- {"attiny2313", "__AVR_ATtiny2313__"},
- {"attiny2313a", "__AVR_ATtiny2313A__"},
- {"attiny24", "__AVR_ATtiny24__"},
- {"attiny24a", "__AVR_ATtiny24A__"},
- {"attiny4313", "__AVR_ATtiny4313__"},
- {"attiny44", "__AVR_ATtiny44__"},
- {"attiny44a", "__AVR_ATtiny44A__"},
- {"attiny84", "__AVR_ATtiny84__"},
- {"attiny84a", "__AVR_ATtiny84A__"},
- {"attiny25", "__AVR_ATtiny25__"},
- {"attiny45", "__AVR_ATtiny45__"},
- {"attiny85", "__AVR_ATtiny85__"},
- {"attiny261", "__AVR_ATtiny261__"},
- {"attiny261a", "__AVR_ATtiny261A__"},
- {"attiny441", "__AVR_ATtiny441__"},
- {"attiny461", "__AVR_ATtiny461__"},
- {"attiny461a", "__AVR_ATtiny461A__"},
- {"attiny841", "__AVR_ATtiny841__"},
- {"attiny861", "__AVR_ATtiny861__"},
- {"attiny861a", "__AVR_ATtiny861A__"},
- {"attiny87", "__AVR_ATtiny87__"},
- {"attiny43u", "__AVR_ATtiny43U__"},
- {"attiny48", "__AVR_ATtiny48__"},
- {"attiny88", "__AVR_ATtiny88__"},
- {"attiny828", "__AVR_ATtiny828__"},
- {"at43usb355", "__AVR_AT43USB355__"},
- {"at76c711", "__AVR_AT76C711__"},
- {"atmega103", "__AVR_ATmega103__"},
- {"at43usb320", "__AVR_AT43USB320__"},
- {"attiny167", "__AVR_ATtiny167__"},
- {"at90usb82", "__AVR_AT90USB82__"},
- {"at90usb162", "__AVR_AT90USB162__"},
- {"ata5505", "__AVR_ATA5505__"},
- {"atmega8u2", "__AVR_ATmega8U2__"},
- {"atmega16u2", "__AVR_ATmega16U2__"},
- {"atmega32u2", "__AVR_ATmega32U2__"},
- {"attiny1634", "__AVR_ATtiny1634__"},
- {"atmega8", "__AVR_ATmega8__"},
- {"ata6289", "__AVR_ATA6289__"},
- {"atmega8a", "__AVR_ATmega8A__"},
- {"ata6285", "__AVR_ATA6285__"},
- {"ata6286", "__AVR_ATA6286__"},
- {"atmega48", "__AVR_ATmega48__"},
- {"atmega48a", "__AVR_ATmega48A__"},
- {"atmega48pa", "__AVR_ATmega48PA__"},
- {"atmega48pb", "__AVR_ATmega48PB__"},
- {"atmega48p", "__AVR_ATmega48P__"},
- {"atmega88", "__AVR_ATmega88__"},
- {"atmega88a", "__AVR_ATmega88A__"},
- {"atmega88p", "__AVR_ATmega88P__"},
- {"atmega88pa", "__AVR_ATmega88PA__"},
- {"atmega88pb", "__AVR_ATmega88PB__"},
- {"atmega8515", "__AVR_ATmega8515__"},
- {"atmega8535", "__AVR_ATmega8535__"},
- {"atmega8hva", "__AVR_ATmega8HVA__"},
- {"at90pwm1", "__AVR_AT90PWM1__"},
- {"at90pwm2", "__AVR_AT90PWM2__"},
- {"at90pwm2b", "__AVR_AT90PWM2B__"},
- {"at90pwm3", "__AVR_AT90PWM3__"},
- {"at90pwm3b", "__AVR_AT90PWM3B__"},
- {"at90pwm81", "__AVR_AT90PWM81__"},
- {"ata5790", "__AVR_ATA5790__"},
- {"ata5795", "__AVR_ATA5795__"},
- {"atmega16", "__AVR_ATmega16__"},
- {"atmega16a", "__AVR_ATmega16A__"},
- {"atmega161", "__AVR_ATmega161__"},
- {"atmega162", "__AVR_ATmega162__"},
- {"atmega163", "__AVR_ATmega163__"},
- {"atmega164a", "__AVR_ATmega164A__"},
- {"atmega164p", "__AVR_ATmega164P__"},
- {"atmega164pa", "__AVR_ATmega164PA__"},
- {"atmega165", "__AVR_ATmega165__"},
- {"atmega165a", "__AVR_ATmega165A__"},
- {"atmega165p", "__AVR_ATmega165P__"},
- {"atmega165pa", "__AVR_ATmega165PA__"},
- {"atmega168", "__AVR_ATmega168__"},
- {"atmega168a", "__AVR_ATmega168A__"},
- {"atmega168p", "__AVR_ATmega168P__"},
- {"atmega168pa", "__AVR_ATmega168PA__"},
- {"atmega168pb", "__AVR_ATmega168PB__"},
- {"atmega169", "__AVR_ATmega169__"},
- {"atmega169a", "__AVR_ATmega169A__"},
- {"atmega169p", "__AVR_ATmega169P__"},
- {"atmega169pa", "__AVR_ATmega169PA__"},
- {"atmega32", "__AVR_ATmega32__"},
- {"atmega32a", "__AVR_ATmega32A__"},
- {"atmega323", "__AVR_ATmega323__"},
- {"atmega324a", "__AVR_ATmega324A__"},
- {"atmega324p", "__AVR_ATmega324P__"},
- {"atmega324pa", "__AVR_ATmega324PA__"},
- {"atmega324pb", "__AVR_ATmega324PB__"},
- {"atmega325", "__AVR_ATmega325__"},
- {"atmega325a", "__AVR_ATmega325A__"},
- {"atmega325p", "__AVR_ATmega325P__"},
- {"atmega325pa", "__AVR_ATmega325PA__"},
- {"atmega3250", "__AVR_ATmega3250__"},
- {"atmega3250a", "__AVR_ATmega3250A__"},
- {"atmega3250p", "__AVR_ATmega3250P__"},
- {"atmega3250pa", "__AVR_ATmega3250PA__"},
- {"atmega328", "__AVR_ATmega328__"},
- {"atmega328p", "__AVR_ATmega328P__"},
- {"atmega328pb", "__AVR_ATmega328PB__"},
- {"atmega329", "__AVR_ATmega329__"},
- {"atmega329a", "__AVR_ATmega329A__"},
- {"atmega329p", "__AVR_ATmega329P__"},
- {"atmega329pa", "__AVR_ATmega329PA__"},
- {"atmega3290", "__AVR_ATmega3290__"},
- {"atmega3290a", "__AVR_ATmega3290A__"},
- {"atmega3290p", "__AVR_ATmega3290P__"},
- {"atmega3290pa", "__AVR_ATmega3290PA__"},
- {"atmega406", "__AVR_ATmega406__"},
- {"atmega64", "__AVR_ATmega64__"},
- {"atmega64a", "__AVR_ATmega64A__"},
- {"atmega640", "__AVR_ATmega640__"},
- {"atmega644", "__AVR_ATmega644__"},
- {"atmega644a", "__AVR_ATmega644A__"},
- {"atmega644p", "__AVR_ATmega644P__"},
- {"atmega644pa", "__AVR_ATmega644PA__"},
- {"atmega645", "__AVR_ATmega645__"},
- {"atmega645a", "__AVR_ATmega645A__"},
- {"atmega645p", "__AVR_ATmega645P__"},
- {"atmega649", "__AVR_ATmega649__"},
- {"atmega649a", "__AVR_ATmega649A__"},
- {"atmega649p", "__AVR_ATmega649P__"},
- {"atmega6450", "__AVR_ATmega6450__"},
- {"atmega6450a", "__AVR_ATmega6450A__"},
- {"atmega6450p", "__AVR_ATmega6450P__"},
- {"atmega6490", "__AVR_ATmega6490__"},
- {"atmega6490a", "__AVR_ATmega6490A__"},
- {"atmega6490p", "__AVR_ATmega6490P__"},
- {"atmega64rfr2", "__AVR_ATmega64RFR2__"},
- {"atmega644rfr2", "__AVR_ATmega644RFR2__"},
- {"atmega16hva", "__AVR_ATmega16HVA__"},
- {"atmega16hva2", "__AVR_ATmega16HVA2__"},
- {"atmega16hvb", "__AVR_ATmega16HVB__"},
- {"atmega16hvbrevb", "__AVR_ATmega16HVBREVB__"},
- {"atmega32hvb", "__AVR_ATmega32HVB__"},
- {"atmega32hvbrevb", "__AVR_ATmega32HVBREVB__"},
- {"atmega64hve", "__AVR_ATmega64HVE__"},
- {"at90can32", "__AVR_AT90CAN32__"},
- {"at90can64", "__AVR_AT90CAN64__"},
- {"at90pwm161", "__AVR_AT90PWM161__"},
- {"at90pwm216", "__AVR_AT90PWM216__"},
- {"at90pwm316", "__AVR_AT90PWM316__"},
- {"atmega32c1", "__AVR_ATmega32C1__"},
- {"atmega64c1", "__AVR_ATmega64C1__"},
- {"atmega16m1", "__AVR_ATmega16M1__"},
- {"atmega32m1", "__AVR_ATmega32M1__"},
- {"atmega64m1", "__AVR_ATmega64M1__"},
- {"atmega16u4", "__AVR_ATmega16U4__"},
- {"atmega32u4", "__AVR_ATmega32U4__"},
- {"atmega32u6", "__AVR_ATmega32U6__"},
- {"at90usb646", "__AVR_AT90USB646__"},
- {"at90usb647", "__AVR_AT90USB647__"},
- {"at90scr100", "__AVR_AT90SCR100__"},
- {"at94k", "__AVR_AT94K__"},
- {"m3000", "__AVR_AT000__"},
- {"atmega128", "__AVR_ATmega128__"},
- {"atmega128a", "__AVR_ATmega128A__"},
- {"atmega1280", "__AVR_ATmega1280__"},
- {"atmega1281", "__AVR_ATmega1281__"},
- {"atmega1284", "__AVR_ATmega1284__"},
- {"atmega1284p", "__AVR_ATmega1284P__"},
- {"atmega128rfa1", "__AVR_ATmega128RFA1__"},
- {"atmega128rfr2", "__AVR_ATmega128RFR2__"},
- {"atmega1284rfr2", "__AVR_ATmega1284RFR2__"},
- {"at90can128", "__AVR_AT90CAN128__"},
- {"at90usb1286", "__AVR_AT90USB1286__"},
- {"at90usb1287", "__AVR_AT90USB1287__"},
- {"atmega2560", "__AVR_ATmega2560__"},
- {"atmega2561", "__AVR_ATmega2561__"},
- {"atmega256rfr2", "__AVR_ATmega256RFR2__"},
- {"atmega2564rfr2", "__AVR_ATmega2564RFR2__"},
- {"atxmega16a4", "__AVR_ATxmega16A4__"},
- {"atxmega16a4u", "__AVR_ATxmega16a4U__"},
- {"atxmega16c4", "__AVR_ATxmega16C4__"},
- {"atxmega16d4", "__AVR_ATxmega16D4__"},
- {"atxmega32a4", "__AVR_ATxmega32A4__"},
- {"atxmega32a4u", "__AVR_ATxmega32A4U__"},
- {"atxmega32c4", "__AVR_ATxmega32C4__"},
- {"atxmega32d4", "__AVR_ATxmega32D4__"},
- {"atxmega32e5", "__AVR_ATxmega32E5__"},
- {"atxmega16e5", "__AVR_ATxmega16E5__"},
- {"atxmega8e5", "__AVR_ATxmega8E5__"},
- {"atxmega32x1", "__AVR_ATxmega32X1__"},
- {"atxmega64a3", "__AVR_ATxmega64A3__"},
- {"atxmega64a3u", "__AVR_ATxmega64A3U__"},
- {"atxmega64a4u", "__AVR_ATxmega64A4U__"},
- {"atxmega64b1", "__AVR_ATxmega64B1__"},
- {"atxmega64b3", "__AVR_ATxmega64B3__"},
- {"atxmega64c3", "__AVR_ATxmega64C3__"},
- {"atxmega64d3", "__AVR_ATxmega64D3__"},
- {"atxmega64d4", "__AVR_ATxmega64D4__"},
- {"atxmega64a1", "__AVR_ATxmega64A1__"},
- {"atxmega64a1u", "__AVR_ATxmega64A1U__"},
- {"atxmega128a3", "__AVR_ATxmega128A3__"},
- {"atxmega128a3u", "__AVR_ATxmega128A3U__"},
- {"atxmega128b1", "__AVR_ATxmega128B1__"},
- {"atxmega128b3", "__AVR_ATxmega128B3__"},
- {"atxmega128c3", "__AVR_ATxmega128C3__"},
- {"atxmega128d3", "__AVR_ATxmega128D3__"},
- {"atxmega128d4", "__AVR_ATxmega128D4__"},
- {"atxmega192a3", "__AVR_ATxmega192A3__"},
- {"atxmega192a3u", "__AVR_ATxmega192A3U__"},
- {"atxmega192c3", "__AVR_ATxmega192C3__"},
- {"atxmega192d3", "__AVR_ATxmega192D3__"},
- {"atxmega256a3", "__AVR_ATxmega256A3__"},
- {"atxmega256a3u", "__AVR_ATxmega256A3U__"},
- {"atxmega256a3b", "__AVR_ATxmega256A3B__"},
- {"atxmega256a3bu", "__AVR_ATxmega256A3BU__"},
- {"atxmega256c3", "__AVR_ATxmega256C3__"},
- {"atxmega256d3", "__AVR_ATxmega256D3__"},
- {"atxmega384c3", "__AVR_ATxmega384C3__"},
- {"atxmega384d3", "__AVR_ATxmega384D3__"},
- {"atxmega128a1", "__AVR_ATxmega128A1__"},
- {"atxmega128a1u", "__AVR_ATxmega128A1U__"},
- {"atxmega128a4u", "__AVR_ATxmega128a4U__"},
- {"attiny4", "__AVR_ATtiny4__"},
- {"attiny5", "__AVR_ATtiny5__"},
- {"attiny9", "__AVR_ATtiny9__"},
- {"attiny10", "__AVR_ATtiny10__"},
- {"attiny20", "__AVR_ATtiny20__"},
- {"attiny40", "__AVR_ATtiny40__"},
- {"attiny102", "__AVR_ATtiny102__"},
- {"attiny104", "__AVR_ATtiny104__"},
+ {"avr1", NULL, "1", 0},
+ {"at90s1200", "__AVR_AT90S1200__", "1", 0},
+ {"attiny11", "__AVR_ATtiny11__", "1", 0},
+ {"attiny12", "__AVR_ATtiny12__", "1", 0},
+ {"attiny15", "__AVR_ATtiny15__", "1", 0},
+ {"attiny28", "__AVR_ATtiny28__", "1", 0},
+ {"avr2", NULL, "2", 1},
+ {"at90s2313", "__AVR_AT90S2313__", "2", 1},
+ {"at90s2323", "__AVR_AT90S2323__", "2", 1},
+ {"at90s2333", "__AVR_AT90S2333__", "2", 1},
+ {"at90s2343", "__AVR_AT90S2343__", "2", 1},
+ {"attiny22", "__AVR_ATtiny22__", "2", 1},
+ {"attiny26", "__AVR_ATtiny26__", "2", 1},
+ {"at86rf401", "__AVR_AT86RF401__", "25", 1},
+ {"at90s4414", "__AVR_AT90S4414__", "2", 1},
+ {"at90s4433", "__AVR_AT90S4433__", "2", 1},
+ {"at90s4434", "__AVR_AT90S4434__", "2", 1},
+ {"at90s8515", "__AVR_AT90S8515__", "2", 1},
+ {"at90c8534", "__AVR_AT90c8534__", "2", 1},
+ {"at90s8535", "__AVR_AT90S8535__", "2", 1},
+ {"avr25", NULL, "25", 1},
+ {"ata5272", "__AVR_ATA5272__", "25", 1},
+ {"ata6616c", "__AVR_ATA6616c__", "25", 1},
+ {"attiny13", "__AVR_ATtiny13__", "25", 1},
+ {"attiny13a", "__AVR_ATtiny13A__", "25", 1},
+ {"attiny2313", "__AVR_ATtiny2313__", "25", 1},
+ {"attiny2313a", "__AVR_ATtiny2313A__", "25", 1},
+ {"attiny24", "__AVR_ATtiny24__", "25", 1},
+ {"attiny24a", "__AVR_ATtiny24A__", "25", 1},
+ {"attiny4313", "__AVR_ATtiny4313__", "25", 1},
+ {"attiny44", "__AVR_ATtiny44__", "25", 1},
+ {"attiny44a", "__AVR_ATtiny44A__", "25", 1},
+ {"attiny84", "__AVR_ATtiny84__", "25", 1},
+ {"attiny84a", "__AVR_ATtiny84A__", "25", 1},
+ {"attiny25", "__AVR_ATtiny25__", "25", 1},
+ {"attiny45", "__AVR_ATtiny45__", "25", 1},
+ {"attiny85", "__AVR_ATtiny85__", "25", 1},
+ {"attiny261", "__AVR_ATtiny261__", "25", 1},
+ {"attiny261a", "__AVR_ATtiny261A__", "25", 1},
+ {"attiny441", "__AVR_ATtiny441__", "25", 1},
+ {"attiny461", "__AVR_ATtiny461__", "25", 1},
+ {"attiny461a", "__AVR_ATtiny461A__", "25", 1},
+ {"attiny841", "__AVR_ATtiny841__", "25", 1},
+ {"attiny861", "__AVR_ATtiny861__", "25", 1},
+ {"attiny861a", "__AVR_ATtiny861A__", "25", 1},
+ {"attiny87", "__AVR_ATtiny87__", "25", 1},
+ {"attiny43u", "__AVR_ATtiny43U__", "25", 1},
+ {"attiny48", "__AVR_ATtiny48__", "25", 1},
+ {"attiny88", "__AVR_ATtiny88__", "25", 1},
+ {"attiny828", "__AVR_ATtiny828__", "25", 1},
+ {"avr3", NULL, "3", 1},
+ {"at43usb355", "__AVR_AT43USB355__", "3", 1},
+ {"at76c711", "__AVR_AT76C711__", "3", 1},
+ {"avr31", NULL, "31", 1},
+ {"atmega103", "__AVR_ATmega103__", "31", 1},
+ {"at43usb320", "__AVR_AT43USB320__", "31", 1},
+ {"avr35", NULL, "35", 1},
+ {"attiny167", "__AVR_ATtiny167__", "35", 1},
+ {"at90usb82", "__AVR_AT90USB82__", "35", 1},
+ {"at90usb162", "__AVR_AT90USB162__", "35", 1},
+ {"ata5505", "__AVR_ATA5505__", "35", 1},
+ {"ata6617c", "__AVR_ATA6617C__", "35", 1},
+ {"ata664251", "__AVR_ATA664251__", "35", 1},
+ {"atmega8u2", "__AVR_ATmega8U2__", "35", 1},
+ {"atmega16u2", "__AVR_ATmega16U2__", "35", 1},
+ {"atmega32u2", "__AVR_ATmega32U2__", "35", 1},
+ {"attiny1634", "__AVR_ATtiny1634__", "35", 1},
+ {"avr4", NULL, "4", 1},
+ {"atmega8", "__AVR_ATmega8__", "4", 1},
+ {"ata6289", "__AVR_ATA6289__", "4", 1},
+ {"atmega8a", "__AVR_ATmega8A__", "4", 1},
+ {"ata6285", "__AVR_ATA6285__", "4", 1},
+ {"ata6286", "__AVR_ATA6286__", "4", 1},
+ {"ata6612c", "__AVR_ATA6612C__", "4", 1},
+ {"atmega48", "__AVR_ATmega48__", "4", 1},
+ {"atmega48a", "__AVR_ATmega48A__", "4", 1},
+ {"atmega48pa", "__AVR_ATmega48PA__", "4", 1},
+ {"atmega48pb", "__AVR_ATmega48PB__", "4", 1},
+ {"atmega48p", "__AVR_ATmega48P__", "4", 1},
+ {"atmega88", "__AVR_ATmega88__", "4", 1},
+ {"atmega88a", "__AVR_ATmega88A__", "4", 1},
+ {"atmega88p", "__AVR_ATmega88P__", "4", 1},
+ {"atmega88pa", "__AVR_ATmega88PA__", "4", 1},
+ {"atmega88pb", "__AVR_ATmega88PB__", "4", 1},
+ {"atmega8515", "__AVR_ATmega8515__", "4", 1},
+ {"atmega8535", "__AVR_ATmega8535__", "4", 1},
+ {"atmega8hva", "__AVR_ATmega8HVA__", "4", 1},
+ {"at90pwm1", "__AVR_AT90PWM1__", "4", 1},
+ {"at90pwm2", "__AVR_AT90PWM2__", "4", 1},
+ {"at90pwm2b", "__AVR_AT90PWM2B__", "4", 1},
+ {"at90pwm3", "__AVR_AT90PWM3__", "4", 1},
+ {"at90pwm3b", "__AVR_AT90PWM3B__", "4", 1},
+ {"at90pwm81", "__AVR_AT90PWM81__", "4", 1},
+ {"avr5", NULL, "5", 1},
+ {"ata5702m322", "__AVR_ATA5702M322__", "5", 1},
+ {"ata5782", "__AVR_ATA5782__", "5", 1},
+ {"ata5790", "__AVR_ATA5790__", "5", 1},
+ {"ata5790n", "__AVR_ATA5790N__", "5", 1},
+ {"ata5791", "__AVR_ATA5791__", "5", 1},
+ {"ata5795", "__AVR_ATA5795__", "5", 1},
+ {"ata5831", "__AVR_ATA5831__", "5", 1},
+ {"ata6613c", "__AVR_ATA6613C__", "5", 1},
+ {"ata6614q", "__AVR_ATA6614Q__", "5", 1},
+ {"ata8210", "__AVR_ATA8210__", "5", 1},
+ {"ata8510", "__AVR_ATA8510__", "5", 1},
+ {"atmega16", "__AVR_ATmega16__", "5", 1},
+ {"atmega16a", "__AVR_ATmega16A__", "5", 1},
+ {"atmega161", "__AVR_ATmega161__", "5", 1},
+ {"atmega162", "__AVR_ATmega162__", "5", 1},
+ {"atmega163", "__AVR_ATmega163__", "5", 1},
+ {"atmega164a", "__AVR_ATmega164A__", "5", 1},
+ {"atmega164p", "__AVR_ATmega164P__", "5", 1},
+ {"atmega164pa", "__AVR_ATmega164PA__", "5", 1},
+ {"atmega165", "__AVR_ATmega165__", "5", 1},
+ {"atmega165a", "__AVR_ATmega165A__", "5", 1},
+ {"atmega165p", "__AVR_ATmega165P__", "5", 1},
+ {"atmega165pa", "__AVR_ATmega165PA__", "5", 1},
+ {"atmega168", "__AVR_ATmega168__", "5", 1},
+ {"atmega168a", "__AVR_ATmega168A__", "5", 1},
+ {"atmega168p", "__AVR_ATmega168P__", "5", 1},
+ {"atmega168pa", "__AVR_ATmega168PA__", "5", 1},
+ {"atmega168pb", "__AVR_ATmega168PB__", "5", 1},
+ {"atmega169", "__AVR_ATmega169__", "5", 1},
+ {"atmega169a", "__AVR_ATmega169A__", "5", 1},
+ {"atmega169p", "__AVR_ATmega169P__", "5", 1},
+ {"atmega169pa", "__AVR_ATmega169PA__", "5", 1},
+ {"atmega32", "__AVR_ATmega32__", "5", 1},
+ {"atmega32a", "__AVR_ATmega32A__", "5", 1},
+ {"atmega323", "__AVR_ATmega323__", "5", 1},
+ {"atmega324a", "__AVR_ATmega324A__", "5", 1},
+ {"atmega324p", "__AVR_ATmega324P__", "5", 1},
+ {"atmega324pa", "__AVR_ATmega324PA__", "5", 1},
+ {"atmega324pb", "__AVR_ATmega324PB__", "5", 1},
+ {"atmega325", "__AVR_ATmega325__", "5", 1},
+ {"atmega325a", "__AVR_ATmega325A__", "5", 1},
+ {"atmega325p", "__AVR_ATmega325P__", "5", 1},
+ {"atmega325pa", "__AVR_ATmega325PA__", "5", 1},
+ {"atmega3250", "__AVR_ATmega3250__", "5", 1},
+ {"atmega3250a", "__AVR_ATmega3250A__", "5", 1},
+ {"atmega3250p", "__AVR_ATmega3250P__", "5", 1},
+ {"atmega3250pa", "__AVR_ATmega3250PA__", "5", 1},
+ {"atmega328", "__AVR_ATmega328__", "5", 1},
+ {"atmega328p", "__AVR_ATmega328P__", "5", 1},
+ {"atmega328pb", "__AVR_ATmega328PB__", "5", 1},
+ {"atmega329", "__AVR_ATmega329__", "5", 1},
+ {"atmega329a", "__AVR_ATmega329A__", "5", 1},
+ {"atmega329p", "__AVR_ATmega329P__", "5", 1},
+ {"atmega329pa", "__AVR_ATmega329PA__", "5", 1},
+ {"atmega3290", "__AVR_ATmega3290__", "5", 1},
+ {"atmega3290a", "__AVR_ATmega3290A__", "5", 1},
+ {"atmega3290p", "__AVR_ATmega3290P__", "5", 1},
+ {"atmega3290pa", "__AVR_ATmega3290PA__", "5", 1},
+ {"atmega406", "__AVR_ATmega406__", "5", 1},
+ {"atmega64", "__AVR_ATmega64__", "5", 1},
+ {"atmega64a", "__AVR_ATmega64A__", "5", 1},
+ {"atmega640", "__AVR_ATmega640__", "5", 1},
+ {"atmega644", "__AVR_ATmega644__", "5", 1},
+ {"atmega644a", "__AVR_ATmega644A__", "5", 1},
+ {"atmega644p", "__AVR_ATmega644P__", "5", 1},
+ {"atmega644pa", "__AVR_ATmega644PA__", "5", 1},
+ {"atmega645", "__AVR_ATmega645__", "5", 1},
+ {"atmega645a", "__AVR_ATmega645A__", "5", 1},
+ {"atmega645p", "__AVR_ATmega645P__", "5", 1},
+ {"atmega649", "__AVR_ATmega649__", "5", 1},
+ {"atmega649a", "__AVR_ATmega649A__", "5", 1},
+ {"atmega649p", "__AVR_ATmega649P__", "5", 1},
+ {"atmega6450", "__AVR_ATmega6450__", "5", 1},
+ {"atmega6450a", "__AVR_ATmega6450A__", "5", 1},
+ {"atmega6450p", "__AVR_ATmega6450P__", "5", 1},
+ {"atmega6490", "__AVR_ATmega6490__", "5", 1},
+ {"atmega6490a", "__AVR_ATmega6490A__", "5", 1},
+ {"atmega6490p", "__AVR_ATmega6490P__", "5", 1},
+ {"atmega64rfr2", "__AVR_ATmega64RFR2__", "5", 1},
+ {"atmega644rfr2", "__AVR_ATmega644RFR2__", "5", 1},
+ {"atmega16hva", "__AVR_ATmega16HVA__", "5", 1},
+ {"atmega16hva2", "__AVR_ATmega16HVA2__", "5", 1},
+ {"atmega16hvb", "__AVR_ATmega16HVB__", "5", 1},
+ {"atmega16hvbrevb", "__AVR_ATmega16HVBREVB__", "5", 1},
+ {"atmega32hvb", "__AVR_ATmega32HVB__", "5", 1},
+ {"atmega32hvbrevb", "__AVR_ATmega32HVBREVB__", "5", 1},
+ {"atmega64hve", "__AVR_ATmega64HVE__", "5", 1},
+ {"atmega64hve2", "__AVR_ATmega64HVE2__", "5", 1},
+ {"at90can32", "__AVR_AT90CAN32__", "5", 1},
+ {"at90can64", "__AVR_AT90CAN64__", "5", 1},
+ {"at90pwm161", "__AVR_AT90PWM161__", "5", 1},
+ {"at90pwm216", "__AVR_AT90PWM216__", "5", 1},
+ {"at90pwm316", "__AVR_AT90PWM316__", "5", 1},
+ {"atmega32c1", "__AVR_ATmega32C1__", "5", 1},
+ {"atmega64c1", "__AVR_ATmega64C1__", "5", 1},
+ {"atmega16m1", "__AVR_ATmega16M1__", "5", 1},
+ {"atmega32m1", "__AVR_ATmega32M1__", "5", 1},
+ {"atmega64m1", "__AVR_ATmega64M1__", "5", 1},
+ {"atmega16u4", "__AVR_ATmega16U4__", "5", 1},
+ {"atmega32u4", "__AVR_ATmega32U4__", "5", 1},
+ {"atmega32u6", "__AVR_ATmega32U6__", "5", 1},
+ {"at90usb646", "__AVR_AT90USB646__", "5", 1},
+ {"at90usb647", "__AVR_AT90USB647__", "5", 1},
+ {"at90scr100", "__AVR_AT90SCR100__", "5", 1},
+ {"at94k", "__AVR_AT94K__", "5", 1},
+ {"m3000", "__AVR_AT000__", "5", 1},
+ {"avr51", NULL, "51", 2},
+ {"atmega128", "__AVR_ATmega128__", "51", 2},
+ {"atmega128a", "__AVR_ATmega128A__", "51", 2},
+ {"atmega1280", "__AVR_ATmega1280__", "51", 2},
+ {"atmega1281", "__AVR_ATmega1281__", "51", 2},
+ {"atmega1284", "__AVR_ATmega1284__", "51", 2},
+ {"atmega1284p", "__AVR_ATmega1284P__", "51", 2},
+ {"atmega128rfa1", "__AVR_ATmega128RFA1__", "51", 2},
+ {"atmega128rfr2", "__AVR_ATmega128RFR2__", "51", 2},
+ {"atmega1284rfr2", "__AVR_ATmega1284RFR2__", "51", 2},
+ {"at90can128", "__AVR_AT90CAN128__", "51", 2},
+ {"at90usb1286", "__AVR_AT90USB1286__", "51", 2},
+ {"at90usb1287", "__AVR_AT90USB1287__", "51", 2},
+ {"avr6", NULL, "6", 4},
+ {"atmega2560", "__AVR_ATmega2560__", "6", 4},
+ {"atmega2561", "__AVR_ATmega2561__", "6", 4},
+ {"atmega256rfr2", "__AVR_ATmega256RFR2__", "6", 4},
+ {"atmega2564rfr2", "__AVR_ATmega2564RFR2__", "6", 4},
+ {"avrxmega2", NULL, "102", 1},
+ {"atxmega16a4", "__AVR_ATxmega16A4__", "102", 1},
+ {"atxmega16a4u", "__AVR_ATxmega16A4U__", "102", 1},
+ {"atxmega16c4", "__AVR_ATxmega16C4__", "102", 1},
+ {"atxmega16d4", "__AVR_ATxmega16D4__", "102", 1},
+ {"atxmega32a4", "__AVR_ATxmega32A4__", "102", 1},
+ {"atxmega32a4u", "__AVR_ATxmega32A4U__", "102", 1},
+ {"atxmega32c3", "__AVR_ATxmega32C3__", "102", 1},
+ {"atxmega32c4", "__AVR_ATxmega32C4__", "102", 1},
+ {"atxmega32d3", "__AVR_ATxmega32D3__", "102", 1},
+ {"atxmega32d4", "__AVR_ATxmega32D4__", "102", 1},
+ {"atxmega32e5", "__AVR_ATxmega32E5__", "102", 1},
+ {"atxmega16e5", "__AVR_ATxmega16E5__", "102", 1},
+ {"atxmega8e5", "__AVR_ATxmega8E5__", "102", 1},
+ {"avrxmega4", NULL, "104", 1},
+ {"atxmega64a3", "__AVR_ATxmega64A3__", "104", 1},
+ {"atxmega64a3u", "__AVR_ATxmega64A3U__", "104", 1},
+ {"atxmega64a4u", "__AVR_ATxmega64A4U__", "104", 1},
+ {"atxmega64b1", "__AVR_ATxmega64B1__", "104", 1},
+ {"atxmega64b3", "__AVR_ATxmega64B3__", "104", 1},
+ {"atxmega64c3", "__AVR_ATxmega64C3__", "104", 1},
+ {"atxmega64d3", "__AVR_ATxmega64D3__", "104", 1},
+ {"atxmega64d4", "__AVR_ATxmega64D4__", "104", 1},
+ {"avrxmega5", NULL, "105", 1},
+ {"atxmega64a1", "__AVR_ATxmega64A1__", "105", 1},
+ {"atxmega64a1u", "__AVR_ATxmega64A1U__", "105", 1},
+ {"avrxmega6", NULL, "106", 6},
+ {"atxmega128a3", "__AVR_ATxmega128A3__", "106", 2},
+ {"atxmega128a3u", "__AVR_ATxmega128A3U__", "106", 2},
+ {"atxmega128b1", "__AVR_ATxmega128B1__", "106", 2},
+ {"atxmega128b3", "__AVR_ATxmega128B3__", "106", 2},
+ {"atxmega128c3", "__AVR_ATxmega128C3__", "106", 2},
+ {"atxmega128d3", "__AVR_ATxmega128D3__", "106", 2},
+ {"atxmega128d4", "__AVR_ATxmega128D4__", "106", 2},
+ {"atxmega192a3", "__AVR_ATxmega192A3__", "106", 3},
+ {"atxmega192a3u", "__AVR_ATxmega192A3U__", "106", 3},
+ {"atxmega192c3", "__AVR_ATxmega192C3__", "106", 3},
+ {"atxmega192d3", "__AVR_ATxmega192D3__", "106", 3},
+ {"atxmega256a3", "__AVR_ATxmega256A3__", "106", 4},
+ {"atxmega256a3u", "__AVR_ATxmega256A3U__", "106", 4},
+ {"atxmega256a3b", "__AVR_ATxmega256A3B__", "106", 4},
+ {"atxmega256a3bu", "__AVR_ATxmega256A3BU__", "106", 4},
+ {"atxmega256c3", "__AVR_ATxmega256C3__", "106", 4},
+ {"atxmega256d3", "__AVR_ATxmega256D3__", "106", 4},
+ {"atxmega384c3", "__AVR_ATxmega384C3__", "106", 6},
+ {"atxmega384d3", "__AVR_ATxmega384D3__", "106", 6},
+ {"avrxmega7", NULL, "107", 2},
+ {"atxmega128a1", "__AVR_ATxmega128A1__", "107", 2},
+ {"atxmega128a1u", "__AVR_ATxmega128A1U__", "107", 2},
+ {"atxmega128a4u", "__AVR_ATxmega128A4U__", "107", 2},
+ {"avrtiny", NULL, "100", 0},
+ {"attiny4", "__AVR_ATtiny4__", "100", 0},
+ {"attiny5", "__AVR_ATtiny5__", "100", 0},
+ {"attiny9", "__AVR_ATtiny9__", "100", 0},
+ {"attiny10", "__AVR_ATtiny10__", "100", 0},
+ {"attiny20", "__AVR_ATtiny20__", "100", 0},
+ {"attiny40", "__AVR_ATtiny40__", "100", 0},
+ {"attiny102", "__AVR_ATtiny102__", "100", 0},
+ {"attiny104", "__AVR_ATtiny104__", "100", 0},
+ {"avrxmega3", NULL, "103", 1},
+ {"attiny202", "__AVR_ATtiny202__", "103", 1},
+ {"attiny402", "__AVR_ATtiny402__", "103", 1},
+ {"attiny204", "__AVR_ATtiny204__", "103", 1},
+ {"attiny404", "__AVR_ATtiny404__", "103", 1},
+ {"attiny804", "__AVR_ATtiny804__", "103", 1},
+ {"attiny1604", "__AVR_ATtiny1604__", "103", 1},
+ {"attiny406", "__AVR_ATtiny406__", "103", 1},
+ {"attiny806", "__AVR_ATtiny806__", "103", 1},
+ {"attiny1606", "__AVR_ATtiny1606__", "103", 1},
+ {"attiny807", "__AVR_ATtiny807__", "103", 1},
+ {"attiny1607", "__AVR_ATtiny1607__", "103", 1},
+ {"attiny212", "__AVR_ATtiny212__", "103", 1},
+ {"attiny412", "__AVR_ATtiny412__", "103", 1},
+ {"attiny214", "__AVR_ATtiny214__", "103", 1},
+ {"attiny414", "__AVR_ATtiny414__", "103", 1},
+ {"attiny814", "__AVR_ATtiny814__", "103", 1},
+ {"attiny1614", "__AVR_ATtiny1614__", "103", 1},
+ {"attiny416", "__AVR_ATtiny416__", "103", 1},
+ {"attiny816", "__AVR_ATtiny816__", "103", 1},
+ {"attiny1616", "__AVR_ATtiny1616__", "103", 1},
+ {"attiny3216", "__AVR_ATtiny3216__", "103", 1},
+ {"attiny417", "__AVR_ATtiny417__", "103", 1},
+ {"attiny817", "__AVR_ATtiny817__", "103", 1},
+ {"attiny1617", "__AVR_ATtiny1617__", "103", 1},
+ {"attiny3217", "__AVR_ATtiny3217__", "103", 1},
+ {"attiny1624", "__AVR_ATtiny1624__", "103", 1},
+ {"attiny1626", "__AVR_ATtiny1626__", "103", 1},
+ {"attiny1627", "__AVR_ATtiny1627__", "103", 1},
+ {"atmega808", "__AVR_ATmega808__", "103", 1},
+ {"atmega809", "__AVR_ATmega809__", "103", 1},
+ {"atmega1608", "__AVR_ATmega1608__", "103", 1},
+ {"atmega1609", "__AVR_ATmega1609__", "103", 1},
+ {"atmega3208", "__AVR_ATmega3208__", "103", 1},
+ {"atmega3209", "__AVR_ATmega3209__", "103", 1},
+ {"atmega4808", "__AVR_ATmega4808__", "103", 1},
+ {"atmega4809", "__AVR_ATmega4809__", "103", 1},
};
} // 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"};
+static bool ArchHasELPM(StringRef Arch) {
+ return llvm::StringSwitch<bool>(Arch)
+ .Cases("31", "51", "6", true)
+ .Cases("102", "104", "105", "106", "107", true)
+ .Default(false);
+}
-bool AVRTargetInfo::isValidCPUName(StringRef Name) const {
- bool IsFamily =
- llvm::find(ValidFamilyNames, Name) != std::end(ValidFamilyNames);
+static bool ArchHasELPMX(StringRef Arch) {
+ return llvm::StringSwitch<bool>(Arch)
+ .Cases("51", "6", true)
+ .Cases("102", "104", "105", "106", "107", true)
+ .Default(false);
+}
+
+static bool ArchHasMOVW(StringRef Arch) {
+ return llvm::StringSwitch<bool>(Arch)
+ .Cases("25", "35", "4", "5", "51", "6", true)
+ .Cases("102", "103", "104", "105", "106", "107", true)
+ .Default(false);
+}
+
+static bool ArchHasLPMX(StringRef Arch) {
+ return ArchHasMOVW(Arch); // same architectures
+}
+
+static bool ArchHasMUL(StringRef Arch) {
+ return llvm::StringSwitch<bool>(Arch)
+ .Cases("4", "5", "51", "6", true)
+ .Cases("102", "103", "104", "105", "106", "107", true)
+ .Default(false);
+}
+
+static bool ArchHasJMPCALL(StringRef Arch) {
+ return llvm::StringSwitch<bool>(Arch)
+ .Cases("3", "31", "35", "5", "51", "6", true)
+ .Cases("102", "103", "104", "105", "106", "107", true)
+ .Default(false);
+}
+
+static bool ArchHas3BytePC(StringRef Arch) {
+ // These devices have more than 128kB of program memory.
+ // Note:
+ // - Not fully correct for arch 106: only about half the chips have more
+ // than 128kB program memory and therefore a 3 byte PC.
+ // - Doesn't match GCC entirely: avr-gcc thinks arch 107 goes beyond 128kB
+ // but in fact it doesn't.
+ return llvm::StringSwitch<bool>(Arch)
+ .Case("6", true)
+ .Case("106", true)
+ .Default(false);
+}
- bool IsMCU =
- llvm::find_if(AVRMcus, [&](const MCUInfo &Info) {
- return Info.Name == Name;
- }) != std::end(AVRMcus);
- return IsFamily || IsMCU;
+bool AVRTargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::any_of(
+ AVRMcus, [&](const MCUInfo &Info) { return Info.Name == Name; });
}
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);
}
+bool AVRTargetInfo::setCPU(const std::string &Name) {
+ // Set the ABI field based on the device or family name.
+ auto It = llvm::find_if(
+ AVRMcus, [&](const MCUInfo &Info) { return Info.Name == Name; });
+ if (It != std::end(AVRMcus)) {
+ CPU = Name;
+ ABI = (It->Arch == "100") ? "avrtiny" : "avr";
+ DefineName = It->DefineName;
+ Arch = It->Arch;
+ NumFlashBanks = It->NumFlashBanks;
+ return true;
+ }
+
+ // Parameter Name is neither valid family name nor valid device name.
+ return false;
+}
+
+std::optional<std::string>
+AVRTargetInfo::handleAsmEscapedChar(char EscChar) const {
+ switch (EscChar) {
+ // "%~" represents for 'r' depends on the device has long jump/call.
+ case '~':
+ return ArchHasJMPCALL(Arch) ? std::string("") : std::string(1, 'r');
+
+ // "%!" represents for 'e' depends on the PC register size.
+ case '!':
+ return ArchHas3BytePC(Arch) ? std::string(1, 'e') : std::string("");
+
+ // This is an invalid escape character for AVR.
+ default:
+ return std::nullopt;
+ }
+}
+
void AVRTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("AVR");
Builder.defineMacro("__AVR");
Builder.defineMacro("__AVR__");
- Builder.defineMacro("__ELF__");
- Builder.defineMacro("__flash", "__attribute__((address_space(1)))");
- if (!this->CPU.empty()) {
- auto It = llvm::find_if(
- AVRMcus, [&](const MCUInfo &Info) { return Info.Name == this->CPU; });
+ if (ABI == "avrtiny")
+ Builder.defineMacro("__AVR_TINY__", "1");
- if (It != std::end(AVRMcus))
- Builder.defineMacro(It->DefineName);
+ if (DefineName.size() != 0)
+ Builder.defineMacro(DefineName);
+
+ Builder.defineMacro("__AVR_ARCH__", Arch);
+
+ // TODO: perhaps we should use the information from AVRDevices.td instead?
+ if (ArchHasELPM(Arch))
+ Builder.defineMacro("__AVR_HAVE_ELPM__");
+ if (ArchHasELPMX(Arch))
+ Builder.defineMacro("__AVR_HAVE_ELPMX__");
+ if (ArchHasMOVW(Arch))
+ Builder.defineMacro("__AVR_HAVE_MOVW__");
+ if (ArchHasLPMX(Arch))
+ Builder.defineMacro("__AVR_HAVE_LPMX__");
+ if (ArchHasMUL(Arch))
+ Builder.defineMacro("__AVR_HAVE_MUL__");
+ if (ArchHasJMPCALL(Arch))
+ Builder.defineMacro("__AVR_HAVE_JMP_CALL__");
+ if (ArchHas3BytePC(Arch)) {
+ // Note: some devices do support eijmp/eicall even though this macro isn't
+ // set. This is the case if they have less than 128kB flash and so
+ // eijmp/eicall isn't very useful anyway. (This matches gcc, although it's
+ // debatable whether we should be bug-compatible in this case).
+ Builder.defineMacro("__AVR_HAVE_EIJMP_EICALL__");
+ Builder.defineMacro("__AVR_3_BYTE_PC__");
+ } else {
+ Builder.defineMacro("__AVR_2_BYTE_PC__");
}
+
+ if (NumFlashBanks >= 1)
+ Builder.defineMacro("__flash", "__attribute__((__address_space__(1)))");
+ if (NumFlashBanks >= 2)
+ Builder.defineMacro("__flash1", "__attribute__((__address_space__(2)))");
+ if (NumFlashBanks >= 3)
+ Builder.defineMacro("__flash2", "__attribute__((__address_space__(3)))");
+ if (NumFlashBanks >= 4)
+ Builder.defineMacro("__flash3", "__attribute__((__address_space__(4)))");
+ if (NumFlashBanks >= 5)
+ Builder.defineMacro("__flash4", "__attribute__((__address_space__(5)))");
+ if (NumFlashBanks >= 6)
+ Builder.defineMacro("__flash5", "__attribute__((__address_space__(6)))");
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h
index 89a80ca6a39a..9376c46cd98c 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/AVR.h
@@ -15,8 +15,8 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -61,25 +61,26 @@ public:
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
- ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+ return std::nullopt;
+ }
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
ArrayRef<const char *> getGCCRegNames() const override {
static const char *const GCCRegNames[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
"r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
- "r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP"
- };
- return llvm::makeArrayRef(GCCRegNames);
+ "r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP"};
+ return llvm::ArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {
@@ -89,7 +90,7 @@ public:
{{"r30", "r31"}, 28},
{{"SPL", "SPH"}, 29},
};
- return llvm::makeArrayRef(AddlRegNames);
+ return llvm::ArrayRef(AddlRegNames);
}
bool validateAsmConstraint(const char *&Name,
@@ -145,7 +146,9 @@ public:
case 'R': // Integer constant (Range: -6 to 5)
Info.setRequiresImmediate(-6, 5);
return true;
- case 'G': // Floating point constant
+ case 'G': // Floating point constant 0.0
+ Info.setRequiresImmediate(0);
+ return true;
case 'Q': // A memory address based on Y or Z pointer with displacement.
return true;
}
@@ -168,15 +171,16 @@ 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)
- CPU = Name;
- return isValid;
- }
+ bool setCPU(const std::string &Name) override;
+ std::optional<std::string> handleAsmEscapedChar(char EscChar) const override;
+ StringRef getABI() const override { return ABI; }
protected:
std::string CPU;
+ StringRef ABI;
+ StringRef DefineName;
+ StringRef Arch;
+ int NumFlashBanks = 0;
};
} // namespace targets
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp
index 0b0298df30a5..e713e0847922 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/BPF.cpp
@@ -19,9 +19,9 @@
using namespace clang;
using namespace clang::targets;
-const Builtin::Info BPFTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsBPF.def"
};
@@ -29,13 +29,44 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__bpf__");
Builder.defineMacro("__BPF__");
+
+ std::string CPU = getTargetOpts().CPU;
+ if (CPU == "probe") {
+ Builder.defineMacro("__BPF_CPU_VERSION__", "0");
+ return;
+ }
+ if (CPU.empty() || CPU == "generic" || CPU == "v1") {
+ Builder.defineMacro("__BPF_CPU_VERSION__", "1");
+ return;
+ }
+
+ std::string CpuVerNumStr = CPU.substr(1);
+ Builder.defineMacro("__BPF_CPU_VERSION__", CpuVerNumStr);
+
+ int CpuVerNum = std::stoi(CpuVerNumStr);
+ if (CpuVerNum >= 2)
+ Builder.defineMacro("__BPF_FEATURE_JMP_EXT");
+
+ if (CpuVerNum >= 3) {
+ Builder.defineMacro("__BPF_FEATURE_JMP32");
+ Builder.defineMacro("__BPF_FEATURE_ALU32");
+ }
+
+ if (CpuVerNum >= 4) {
+ Builder.defineMacro("__BPF_FEATURE_LDSX");
+ Builder.defineMacro("__BPF_FEATURE_MOVSX");
+ Builder.defineMacro("__BPF_FEATURE_BSWAP");
+ Builder.defineMacro("__BPF_FEATURE_SDIV_SMOD");
+ Builder.defineMacro("__BPF_FEATURE_GOTOL");
+ Builder.defineMacro("__BPF_FEATURE_ST");
+ }
}
static constexpr llvm::StringLiteral ValidCPUNames[] = {"generic", "v1", "v2",
- "v3", "probe"};
+ "v3", "v4", "probe"};
bool BPFTargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
+ return llvm::is_contained(ValidCPUNames, Name);
}
void BPFTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
@@ -43,8 +74,8 @@ void BPFTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
}
ArrayRef<Builtin::Info> BPFTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::BPF::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
bool BPFTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/BPF.h b/contrib/llvm-project/clang/lib/Basic/Targets/BPF.h
index 393a91ff53a5..489f29fc4fea 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/BPF.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/BPF.h
@@ -15,14 +15,13 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
bool HasAlu32 = false;
public:
@@ -61,14 +60,16 @@ public:
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
bool isValidGCCRegisterName(StringRef Name) const override { return true; }
- ArrayRef<const char *> getGCCRegNames() const override { return None; }
+ ArrayRef<const char *> getGCCRegNames() const override {
+ return std::nullopt;
+ }
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override {
@@ -85,7 +86,7 @@ public:
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
bool allowDebugInfoForExternalRef() const override { return true; }
@@ -105,7 +106,7 @@ public:
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override {
- if (Name == "v3") {
+ if (Name == "v3" || Name == "v4") {
HasAlu32 = true;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp
new file mode 100644
index 000000000000..851f27dbb1e5
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.cpp
@@ -0,0 +1,315 @@
+//===--- CSKY.cpp - Implement CSKY target feature support -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements CSKY TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CSKY.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+bool CSKYTargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::CSKY::parseCPUArch(Name) != llvm::CSKY::ArchKind::INVALID;
+}
+
+bool CSKYTargetInfo::setCPU(const std::string &Name) {
+ llvm::CSKY::ArchKind archKind = llvm::CSKY::parseCPUArch(Name);
+ bool isValid = (archKind != llvm::CSKY::ArchKind::INVALID);
+
+ if (isValid) {
+ CPU = Name;
+ Arch = archKind;
+ }
+
+ return isValid;
+}
+
+void CSKYTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("__csky__", "2");
+ Builder.defineMacro("__CSKY__", "2");
+ Builder.defineMacro("__ckcore__", "2");
+ Builder.defineMacro("__CKCORE__", "2");
+
+ Builder.defineMacro("__CSKYABI__", ABI == "abiv2" ? "2" : "1");
+ Builder.defineMacro("__cskyabi__", ABI == "abiv2" ? "2" : "1");
+
+ StringRef ArchName = "ck810";
+ StringRef CPUName = "ck810";
+
+ if (Arch != llvm::CSKY::ArchKind::INVALID) {
+ ArchName = llvm::CSKY::getArchName(Arch);
+ CPUName = CPU;
+ }
+
+ Builder.defineMacro("__" + ArchName.upper() + "__");
+ Builder.defineMacro("__" + ArchName.lower() + "__");
+ if (ArchName != CPUName) {
+ Builder.defineMacro("__" + CPUName.upper() + "__");
+ Builder.defineMacro("__" + CPUName.lower() + "__");
+ }
+
+ // TODO: Add support for BE if BE was supported later
+ StringRef endian = "__cskyLE__";
+
+ Builder.defineMacro(endian);
+ Builder.defineMacro(endian.upper());
+ Builder.defineMacro(endian.lower());
+
+ if (DSPV2) {
+ StringRef dspv2 = "__CSKY_DSPV2__";
+ Builder.defineMacro(dspv2);
+ Builder.defineMacro(dspv2.lower());
+ }
+
+ if (VDSPV2) {
+ StringRef vdspv2 = "__CSKY_VDSPV2__";
+ Builder.defineMacro(vdspv2);
+ Builder.defineMacro(vdspv2.lower());
+
+ if (HardFloat) {
+ StringRef vdspv2_f = "__CSKY_VDSPV2_F__";
+ Builder.defineMacro(vdspv2_f);
+ Builder.defineMacro(vdspv2_f.lower());
+ }
+ }
+ if (VDSPV1) {
+ StringRef vdspv1_64 = "__CSKY_VDSP64__";
+ StringRef vdspv1_128 = "__CSKY_VDSP128__";
+
+ Builder.defineMacro(vdspv1_64);
+ Builder.defineMacro(vdspv1_64.lower());
+ Builder.defineMacro(vdspv1_128);
+ Builder.defineMacro(vdspv1_128.lower());
+ }
+ if (is3E3R1) {
+ StringRef is3e3r1 = "__CSKY_3E3R1__";
+ Builder.defineMacro(is3e3r1);
+ Builder.defineMacro(is3e3r1.lower());
+ }
+}
+
+bool CSKYTargetInfo::hasFeature(StringRef Feature) const {
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("hard-float", HardFloat)
+ .Case("hard-float-abi", HardFloatABI)
+ .Case("fpuv2_sf", FPUV2_SF)
+ .Case("fpuv2_df", FPUV2_DF)
+ .Case("fpuv3_sf", FPUV3_SF)
+ .Case("fpuv3_df", FPUV3_DF)
+ .Case("vdspv2", VDSPV2)
+ .Case("dspv2", DSPV2)
+ .Case("vdspv1", VDSPV1)
+ .Case("3e3r1", is3E3R1)
+ .Default(false);
+}
+
+bool CSKYTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) {
+ for (const auto &Feature : Features) {
+ if (Feature == "+hard-float")
+ HardFloat = true;
+ if (Feature == "+hard-float-abi")
+ HardFloatABI = true;
+ if (Feature == "+fpuv2_sf")
+ FPUV2_SF = true;
+ if (Feature == "+fpuv2_df")
+ FPUV2_DF = true;
+ if (Feature == "+fpuv3_sf")
+ FPUV3_SF = true;
+ if (Feature == "+fpuv3_df")
+ FPUV3_DF = true;
+ if (Feature == "+vdspv2")
+ VDSPV2 = true;
+ if (Feature == "+dspv2")
+ DSPV2 = true;
+ if (Feature == "+vdspv1")
+ VDSPV1 = true;
+ if (Feature == "+3e3r1")
+ is3E3R1 = true;
+ }
+
+ return true;
+}
+
+ArrayRef<Builtin::Info> CSKYTargetInfo::getTargetBuiltins() const {
+ return ArrayRef<Builtin::Info>();
+}
+
+ArrayRef<const char *> CSKYTargetInfo::getGCCRegNames() const {
+ static const char *const 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",
+
+ // Floating point registers
+ "fr0",
+ "fr1",
+ "fr2",
+ "fr3",
+ "fr4",
+ "fr5",
+ "fr6",
+ "fr7",
+ "fr8",
+ "fr9",
+ "fr10",
+ "fr11",
+ "fr12",
+ "fr13",
+ "fr14",
+ "fr15",
+ "fr16",
+ "fr17",
+ "fr18",
+ "fr19",
+ "fr20",
+ "fr21",
+ "fr22",
+ "fr23",
+ "fr24",
+ "fr25",
+ "fr26",
+ "fr27",
+ "fr28",
+ "fr29",
+ "fr30",
+ "fr31",
+
+ };
+ return llvm::ArrayRef(GCCRegNames);
+}
+
+ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const {
+ static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+ {{"a0"}, "r0"},
+ {{"a1"}, "r1"},
+ {{"a2"}, "r2"},
+ {{"a3"}, "r3"},
+ {{"l0"}, "r4"},
+ {{"l1"}, "r5"},
+ {{"l2"}, "r6"},
+ {{"l3"}, "r7"},
+ {{"l4"}, "r8"},
+ {{"l5"}, "r9"},
+ {{"l6"}, "r10"},
+ {{"l7"}, "r11"},
+ {{"t0"}, "r12"},
+ {{"t1"}, "r13"},
+ {{"sp"}, "r14"},
+ {{"lr"}, "r15"},
+ {{"l8"}, "r16"},
+ {{"l9"}, "r17"},
+ {{"t2"}, "r18"},
+ {{"t3"}, "r19"},
+ {{"t4"}, "r20"},
+ {{"t5"}, "r21"},
+ {{"t6"}, "r22"},
+ {{"t7", "fp"}, "r23"},
+ {{"t8", "top"}, "r24"},
+ {{"t9", "bsp"}, "r25"},
+ {{"r26"}, "r26"},
+ {{"r27"}, "r27"},
+ {{"gb", "rgb", "rdb"}, "r28"},
+ {{"tb", "rtb"}, "r29"},
+ {{"svbr"}, "r30"},
+ {{"tls"}, "r31"},
+
+ {{"vr0"}, "fr0"},
+ {{"vr1"}, "fr1"},
+ {{"vr2"}, "fr2"},
+ {{"vr3"}, "fr3"},
+ {{"vr4"}, "fr4"},
+ {{"vr5"}, "fr5"},
+ {{"vr6"}, "fr6"},
+ {{"vr7"}, "fr7"},
+ {{"vr8"}, "fr8"},
+ {{"vr9"}, "fr9"},
+ {{"vr10"}, "fr10"},
+ {{"vr11"}, "fr11"},
+ {{"vr12"}, "fr12"},
+ {{"vr13"}, "fr13"},
+ {{"vr14"}, "fr14"},
+ {{"vr15"}, "fr15"},
+ {{"vr16"}, "fr16"},
+ {{"vr17"}, "fr17"},
+ {{"vr18"}, "fr18"},
+ {{"vr19"}, "fr19"},
+ {{"vr20"}, "fr20"},
+ {{"vr21"}, "fr21"},
+ {{"vr22"}, "fr22"},
+ {{"vr23"}, "fr23"},
+ {{"vr24"}, "fr24"},
+ {{"vr25"}, "fr25"},
+ {{"vr26"}, "fr26"},
+ {{"vr27"}, "fr27"},
+ {{"vr28"}, "fr28"},
+ {{"vr29"}, "fr29"},
+ {{"vr30"}, "fr30"},
+ {{"vr31"}, "fr31"},
+
+ };
+ return llvm::ArrayRef(GCCRegAliases);
+}
+
+bool CSKYTargetInfo::validateAsmConstraint(
+ const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+ switch (*Name) {
+ default:
+ return false;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'y':
+ case 'l':
+ case 'h':
+ case 'w':
+ case 'v': // A floating-point and vector register.
+ case 'z':
+ Info.setAllowsRegister();
+ return true;
+ }
+}
+
+unsigned CSKYTargetInfo::getMinGlobalAlign(uint64_t Size) const {
+ if (Size >= 32)
+ return 32;
+ return 0;
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.h b/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.h
new file mode 100644
index 000000000000..11404e37db36
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/CSKY.h
@@ -0,0 +1,107 @@
+//===--- CSKY.h - Declare CSKY target feature support -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares CSKY TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H
+
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/TargetParser/CSKYTargetParser.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY CSKYTargetInfo : public TargetInfo {
+protected:
+ std::string ABI;
+ llvm::CSKY::ArchKind Arch = llvm::CSKY::ArchKind::INVALID;
+ std::string CPU;
+
+ bool HardFloat = false;
+ bool HardFloatABI = false;
+ bool FPUV2_SF = false;
+ bool FPUV2_DF = false;
+ bool FPUV3_SF = false;
+ bool FPUV3_DF = false;
+ bool VDSPV2 = false;
+ bool VDSPV1 = false;
+ bool DSPV2 = false;
+ bool is3E3R1 = false;
+
+public:
+ CSKYTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : TargetInfo(Triple) {
+ NoAsmVariants = true;
+ LongLongAlign = 32;
+ SuitableAlign = 32;
+ DoubleAlign = LongDoubleAlign = 32;
+ SizeType = UnsignedInt;
+ PtrDiffType = SignedInt;
+ IntPtrType = SignedInt;
+ WCharType = SignedInt;
+ WIntType = UnsignedInt;
+
+ UseZeroLengthBitfieldAlignment = true;
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
+ resetDataLayout("e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-"
+ "v64:32:32-v128:32:32-a:0:32-Fi32-n32");
+
+ setABI("abiv2");
+ }
+
+ StringRef getABI() const override { return ABI; }
+ bool setABI(const std::string &Name) override {
+ if (Name == "abiv2" || Name == "abiv1") {
+ ABI = Name;
+ return true;
+ }
+ return false;
+ }
+
+ bool setCPU(const std::string &Name) override;
+
+ bool isValidCPUName(StringRef Name) const override;
+
+ unsigned getMinGlobalAlign(uint64_t) const override;
+
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ return VoidPtrBuiltinVaList;
+ }
+
+ bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &info) const override;
+
+ std::string_view getClobbers() const override { return ""; }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+ bool hasFeature(StringRef Feature) const override;
+ bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) override;
+
+ /// Whether target allows to overalign ABI-specified preferred alignment
+ bool allowsLargerPreferedTypeAlignment() const override { return false; }
+
+ bool hasBitIntType() const override { return true; }
+
+protected:
+ ArrayRef<const char *> getGCCRegNames() const override;
+
+ ArrayRef<GCCRegAlias> getGCCRegAliases() const override;
+};
+
+} // namespace targets
+} // namespace clang
+
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_CSKY_H
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.cpp
new file mode 100644
index 000000000000..0dd27e6e93b3
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.cpp
@@ -0,0 +1,22 @@
+//===--- DirectX.cpp - Implement DirectX target feature support -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements DirectX TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DirectX.h"
+#include "Targets.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+void DirectXTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "DIRECTX", Opts);
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.h b/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.h
new file mode 100644
index 000000000000..acfcc8c47ba9
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/DirectX.h
@@ -0,0 +1,103 @@
+//===--- DirectX.h - Declare DirectX target feature support -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares DXIL TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_DIRECTX_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_DIRECTX_H
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace clang {
+namespace targets {
+
+static const unsigned DirectXAddrSpaceMap[] = {
+ 0, // Default
+ 1, // opencl_global
+ 3, // opencl_local
+ 2, // opencl_constant
+ 0, // opencl_private
+ 4, // opencl_generic
+ 5, // opencl_global_device
+ 6, // opencl_global_host
+ 0, // cuda_device
+ 0, // cuda_constant
+ 0, // cuda_shared
+ // SYCL address space values for this map are dummy
+ 0, // sycl_global
+ 0, // sycl_global_device
+ 0, // sycl_global_host
+ 0, // sycl_local
+ 0, // sycl_private
+ 0, // ptr32_sptr
+ 0, // ptr32_uptr
+ 0, // ptr64
+ 3, // hlsl_groupshared
+ // Wasm address space values for this target are dummy values,
+ // as it is only enabled for Wasm targets.
+ 20, // wasm_funcref
+};
+
+class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
+public:
+ DirectXTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+ : TargetInfo(Triple) {
+ TLSSupported = false;
+ VLASupported = false;
+ LongWidth = LongAlign = 64;
+ AddrSpaceMap = &DirectXAddrSpaceMap;
+ UseAddrSpaceMapMangling = true;
+ HasLegalHalfType = true;
+ HasFloat16 = true;
+ NoAsmVariants = true;
+ PlatformMinVersion = Triple.getOSVersion();
+ PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
+ resetDataLayout("e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:"
+ "32-f64:64-n8:16:32:64");
+ TheCXXABI.set(TargetCXXABI::Microsoft);
+ }
+ bool useFP16ConversionIntrinsics() const override { return false; }
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ bool hasFeature(StringRef Feature) const override {
+ return Feature == "directx";
+ }
+
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+ return std::nullopt;
+ }
+
+ std::string_view getClobbers() const override { return ""; }
+
+ ArrayRef<const char *> getGCCRegNames() const override {
+ return std::nullopt;
+ }
+
+ bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &info) const override {
+ return true;
+ }
+
+ ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
+ return std::nullopt;
+ }
+
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ return TargetInfo::VoidPtrBuiltinVaList;
+ }
+};
+
+} // namespace targets
+} // namespace clang
+
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_DIRECTX_H
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp
index 9c37dee7e89a..ac747e371fb4 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.cpp
@@ -24,8 +24,6 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__qdsp6__", "1");
Builder.defineMacro("__hexagon__", "1");
- Builder.defineMacro("__ELF__");
-
// The macro __HVXDBL__ is deprecated.
bool DefineHvxDbl = false;
@@ -68,6 +66,18 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
} else if (CPU == "hexagonv68") {
Builder.defineMacro("__HEXAGON_V68__");
Builder.defineMacro("__HEXAGON_ARCH__", "68");
+ } else if (CPU == "hexagonv69") {
+ Builder.defineMacro("__HEXAGON_V69__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "69");
+ } else if (CPU == "hexagonv71") {
+ Builder.defineMacro("__HEXAGON_V71__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "71");
+ } else if (CPU == "hexagonv71t") {
+ Builder.defineMacro("__HEXAGON_V71T__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "71");
+ } else if (CPU == "hexagonv73") {
+ Builder.defineMacro("__HEXAGON_V73__");
+ Builder.defineMacro("__HEXAGON_ARCH__", "73");
}
if (hasFeature("hvx-length64b")) {
@@ -90,6 +100,11 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts,
std::string NumPhySlots = isTinyCore() ? "3" : "4";
Builder.defineMacro("__HEXAGON_PHYSICAL_SLOTS__", NumPhySlots);
+
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
}
bool HexagonTargetInfo::initFeatureMap(
@@ -128,6 +143,10 @@ bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
else if (F == "+audio")
HasAudio = true;
}
+ if (CPU.compare("hexagonv68") >= 0) {
+ HasLegalHalfType = true;
+ HasFloat16 = true;
+ }
return true;
}
@@ -166,7 +185,7 @@ const char *const HexagonTargetInfo::GCCRegNames[] = {
};
ArrayRef<const char *> HexagonTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
@@ -176,16 +195,16 @@ const TargetInfo::GCCRegAlias HexagonTargetInfo::GCCRegAliases[] = {
};
ArrayRef<TargetInfo::GCCRegAlias> HexagonTargetInfo::getGCCRegAliases() const {
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
-const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsHexagon.def"
};
@@ -214,7 +233,9 @@ static constexpr CPUSuffix Suffixes[] = {
{{"hexagonv60"}, {"60"}}, {{"hexagonv62"}, {"62"}},
{{"hexagonv65"}, {"65"}}, {{"hexagonv66"}, {"66"}},
{{"hexagonv67"}, {"67"}}, {{"hexagonv67t"}, {"67t"}},
- {{"hexagonv68"}, {"68"}},
+ {{"hexagonv68"}, {"68"}}, {{"hexagonv69"}, {"69"}},
+ {{"hexagonv71"}, {"71"}}, {{"hexagonv71t"}, {"71t"}},
+ {{"hexagonv73"}, {"73"}},
};
const char *HexagonTargetInfo::getHexagonCPUSuffix(StringRef Name) {
@@ -232,6 +253,6 @@ void HexagonTargetInfo::fillValidCPUList(
}
ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
+ Builtin::FirstTSBuiltin);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h b/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h
index d6c7da5f1e40..cdb47dbae799 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Hexagon.h
@@ -15,8 +15,8 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -24,7 +24,6 @@ namespace targets {
// Hexagon abstract base class
class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
static const char *const GCCRegNames[];
static const TargetInfo::GCCRegAlias GCCRegAliases[];
std::string CPU;
@@ -113,7 +112,7 @@ public:
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
static const char *getHexagonCPUSuffix(StringRef Name);
@@ -139,7 +138,7 @@ public:
return CPU.find('t') != std::string::npos;
}
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp
index bb1872083c09..8722a369ed87 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.cpp
@@ -24,7 +24,7 @@ const char *const LanaiTargetInfo::GCCRegNames[] = {
};
ArrayRef<const char *> LanaiTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
const TargetInfo::GCCRegAlias LanaiTargetInfo::GCCRegAliases[] = {
@@ -33,7 +33,7 @@ const TargetInfo::GCCRegAlias LanaiTargetInfo::GCCRegAliases[] = {
};
ArrayRef<TargetInfo::GCCRegAlias> LanaiTargetInfo::getGCCRegAliases() const {
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
bool LanaiTargetInfo::isValidCPUName(StringRef Name) const {
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h b/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h
index 9af5427b81c4..144cbc7de989 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Lanai.h
@@ -15,8 +15,8 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -78,16 +78,18 @@ public:
return TargetInfo::VoidPtrBuiltinVaList;
}
- ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+ return std::nullopt;
+ }
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override {
return false;
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp
index 5c961ff81e05..f7afa0e747d6 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Le64.cpp
@@ -27,5 +27,4 @@ void Le64TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
DefineStd(Builder, "unix", Opts);
defineCPUMacros(Builder, "le64", /*Tuning=*/false);
- Builder.defineMacro("__ELF__");
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Le64.h b/contrib/llvm-project/clang/lib/Basic/Targets/Le64.h
index 13a0b04d9f09..45f6a4e9dd75 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Le64.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Le64.h
@@ -15,8 +15,8 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -41,12 +41,14 @@ public:
return TargetInfo::PNaClABIBuiltinVaList;
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
- ArrayRef<const char *> getGCCRegNames() const override { return None; }
+ ArrayRef<const char *> getGCCRegNames() const override {
+ return std::nullopt;
+ }
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
bool validateAsmConstraint(const char *&Name,
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp
new file mode 100644
index 000000000000..88537989a051
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.cpp
@@ -0,0 +1,299 @@
+//===--- LoongArch.cpp - Implement LoongArch target feature support -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements LoongArch TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LoongArch.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/TargetBuiltins.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/LoongArchTargetParser.h"
+
+using namespace clang;
+using namespace clang::targets;
+
+ArrayRef<const char *> LoongArchTargetInfo::getGCCRegNames() const {
+ static const char *const GCCRegNames[] = {
+ // General purpose 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",
+ // 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",
+ // Condition flag registers.
+ "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7",
+ // 128-bit vector registers.
+ "$vr0", "$vr1", "$vr2", "$vr3", "$vr4", "$vr5", "$vr6", "$vr7", "$vr8",
+ "$vr9", "$vr10", "$vr11", "$vr12", "$vr13", "$vr14", "$vr15", "$vr16",
+ "$vr17", "$vr18", "$vr19", "$vr20", "$vr21", "$vr22", "$vr23", "$vr24",
+ "$vr25", "$vr26", "$vr27", "$vr28", "$vr29", "$vr30", "$vr31",
+ // 256-bit vector registers.
+ "$xr0", "$xr1", "$xr2", "$xr3", "$xr4", "$xr5", "$xr6", "$xr7", "$xr8",
+ "$xr9", "$xr10", "$xr11", "$xr12", "$xr13", "$xr14", "$xr15", "$xr16",
+ "$xr17", "$xr18", "$xr19", "$xr20", "$xr21", "$xr22", "$xr23", "$xr24",
+ "$xr25", "$xr26", "$xr27", "$xr28", "$xr29", "$xr30", "$xr31"};
+ return llvm::ArrayRef(GCCRegNames);
+}
+
+ArrayRef<TargetInfo::GCCRegAlias>
+LoongArchTargetInfo::getGCCRegAliases() const {
+ static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+ {{"zero", "$zero", "r0"}, "$r0"},
+ {{"ra", "$ra", "r1"}, "$r1"},
+ {{"tp", "$tp", "r2"}, "$r2"},
+ {{"sp", "$sp", "r3"}, "$r3"},
+ {{"a0", "$a0", "r4"}, "$r4"},
+ {{"a1", "$a1", "r5"}, "$r5"},
+ {{"a2", "$a2", "r6"}, "$r6"},
+ {{"a3", "$a3", "r7"}, "$r7"},
+ {{"a4", "$a4", "r8"}, "$r8"},
+ {{"a5", "$a5", "r9"}, "$r9"},
+ {{"a6", "$a6", "r10"}, "$r10"},
+ {{"a7", "$a7", "r11"}, "$r11"},
+ {{"t0", "$t0", "r12"}, "$r12"},
+ {{"t1", "$t1", "r13"}, "$r13"},
+ {{"t2", "$t2", "r14"}, "$r14"},
+ {{"t3", "$t3", "r15"}, "$r15"},
+ {{"t4", "$t4", "r16"}, "$r16"},
+ {{"t5", "$t5", "r17"}, "$r17"},
+ {{"t6", "$t6", "r18"}, "$r18"},
+ {{"t7", "$t7", "r19"}, "$r19"},
+ {{"t8", "$t8", "r20"}, "$r20"},
+ {{"r21"}, "$r21"},
+ {{"s9", "$s9", "r22", "fp", "$fp"}, "$r22"},
+ {{"s0", "$s0", "r23"}, "$r23"},
+ {{"s1", "$s1", "r24"}, "$r24"},
+ {{"s2", "$s2", "r25"}, "$r25"},
+ {{"s3", "$s3", "r26"}, "$r26"},
+ {{"s4", "$s4", "r27"}, "$r27"},
+ {{"s5", "$s5", "r28"}, "$r28"},
+ {{"s6", "$s6", "r29"}, "$r29"},
+ {{"s7", "$s7", "r30"}, "$r30"},
+ {{"s8", "$s8", "r31"}, "$r31"},
+ {{"$fa0"}, "$f0"},
+ {{"$fa1"}, "$f1"},
+ {{"$fa2"}, "$f2"},
+ {{"$fa3"}, "$f3"},
+ {{"$fa4"}, "$f4"},
+ {{"$fa5"}, "$f5"},
+ {{"$fa6"}, "$f6"},
+ {{"$fa7"}, "$f7"},
+ {{"$ft0"}, "$f8"},
+ {{"$ft1"}, "$f9"},
+ {{"$ft2"}, "$f10"},
+ {{"$ft3"}, "$f11"},
+ {{"$ft4"}, "$f12"},
+ {{"$ft5"}, "$f13"},
+ {{"$ft6"}, "$f14"},
+ {{"$ft7"}, "$f15"},
+ {{"$ft8"}, "$f16"},
+ {{"$ft9"}, "$f17"},
+ {{"$ft10"}, "$f18"},
+ {{"$ft11"}, "$f19"},
+ {{"$ft12"}, "$f20"},
+ {{"$ft13"}, "$f21"},
+ {{"$ft14"}, "$f22"},
+ {{"$ft15"}, "$f23"},
+ {{"$fs0"}, "$f24"},
+ {{"$fs1"}, "$f25"},
+ {{"$fs2"}, "$f26"},
+ {{"$fs3"}, "$f27"},
+ {{"$fs4"}, "$f28"},
+ {{"$fs5"}, "$f29"},
+ {{"$fs6"}, "$f30"},
+ {{"$fs7"}, "$f31"},
+ };
+ return llvm::ArrayRef(GCCRegAliases);
+}
+
+bool LoongArchTargetInfo::validateAsmConstraint(
+ const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+ // See the GCC definitions here:
+ // https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html
+ // Note that the 'm' constraint is handled in TargetInfo.
+ switch (*Name) {
+ default:
+ return false;
+ case 'f':
+ // A floating-point register (if available).
+ Info.setAllowsRegister();
+ return true;
+ case 'k':
+ // A memory operand whose address is formed by a base register and
+ // (optionally scaled) index register.
+ Info.setAllowsMemory();
+ return true;
+ case 'l':
+ // A signed 16-bit constant.
+ Info.setRequiresImmediate(-32768, 32767);
+ return true;
+ case 'I':
+ // A signed 12-bit constant (for arithmetic instructions).
+ Info.setRequiresImmediate(-2048, 2047);
+ return true;
+ case 'J':
+ // Integer zero.
+ Info.setRequiresImmediate(0);
+ return true;
+ case 'K':
+ // An unsigned 12-bit constant (for logic instructions).
+ Info.setRequiresImmediate(0, 4095);
+ return true;
+ case 'Z':
+ // ZB: An address that is held in a general-purpose register. The offset is
+ // zero.
+ // ZC: A memory operand whose address is formed by a base register
+ // and offset that is suitable for use in instructions with the same
+ // addressing mode as ll.w and sc.w.
+ if (Name[1] == 'C' || Name[1] == 'B') {
+ Info.setAllowsMemory();
+ ++Name; // Skip over 'Z'.
+ return true;
+ }
+ return false;
+ }
+}
+
+std::string
+LoongArchTargetInfo::convertConstraint(const char *&Constraint) const {
+ std::string R;
+ switch (*Constraint) {
+ case 'Z':
+ // "ZC"/"ZB" are two-character constraints; add "^" hint for later
+ // parsing.
+ R = "^" + std::string(Constraint, 2);
+ ++Constraint;
+ break;
+ default:
+ R = TargetInfo::convertConstraint(Constraint);
+ break;
+ }
+ return R;
+}
+
+void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("__loongarch__");
+ unsigned GRLen = getRegisterWidth();
+ Builder.defineMacro("__loongarch_grlen", Twine(GRLen));
+ if (GRLen == 64)
+ Builder.defineMacro("__loongarch64");
+
+ if (HasFeatureD)
+ Builder.defineMacro("__loongarch_frlen", "64");
+ else if (HasFeatureF)
+ Builder.defineMacro("__loongarch_frlen", "32");
+ else
+ Builder.defineMacro("__loongarch_frlen", "0");
+
+ // Define __loongarch_arch.
+ StringRef ArchName = getCPU();
+ Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"'));
+
+ // Define __loongarch_tune.
+ StringRef TuneCPU = getTargetOpts().TuneCPU;
+ if (TuneCPU.empty())
+ TuneCPU = ArchName;
+ Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"'));
+
+ if (HasFeatureLSX)
+ Builder.defineMacro("__loongarch_sx", Twine(1));
+ if (HasFeatureLASX)
+ Builder.defineMacro("__loongarch_asx", Twine(1));
+
+ StringRef ABI = getABI();
+ if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s")
+ Builder.defineMacro("__loongarch_lp64");
+
+ if (ABI == "lp64d" || ABI == "ilp32d") {
+ Builder.defineMacro("__loongarch_hard_float");
+ Builder.defineMacro("__loongarch_double_float");
+ } else if (ABI == "lp64f" || ABI == "ilp32f") {
+ Builder.defineMacro("__loongarch_hard_float");
+ Builder.defineMacro("__loongarch_single_float");
+ } else if (ABI == "lp64s" || ABI == "ilp32s") {
+ Builder.defineMacro("__loongarch_soft_float");
+ }
+
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ if (GRLen == 64)
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+}
+
+static constexpr Builtin::Info BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#include "clang/Basic/BuiltinsLoongArch.def"
+};
+
+bool LoongArchTargetInfo::initFeatureMap(
+ llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
+ const std::vector<std::string> &FeaturesVec) const {
+ if (getTriple().getArch() == llvm::Triple::loongarch64)
+ Features["64bit"] = true;
+ if (getTriple().getArch() == llvm::Triple::loongarch32)
+ Features["32bit"] = true;
+
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
+}
+
+/// Return true if has this feature.
+bool LoongArchTargetInfo::hasFeature(StringRef Feature) const {
+ bool Is64Bit = getTriple().getArch() == llvm::Triple::loongarch64;
+ // TODO: Handle more features.
+ return llvm::StringSwitch<bool>(Feature)
+ .Case("loongarch32", !Is64Bit)
+ .Case("loongarch64", Is64Bit)
+ .Case("32bit", !Is64Bit)
+ .Case("64bit", Is64Bit)
+ .Case("lsx", HasFeatureLSX)
+ .Case("lasx", HasFeatureLASX)
+ .Default(false);
+}
+
+ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const {
+ return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin -
+ Builtin::FirstTSBuiltin);
+}
+
+bool LoongArchTargetInfo::handleTargetFeatures(
+ std::vector<std::string> &Features, DiagnosticsEngine &Diags) {
+ for (const auto &Feature : Features) {
+ if (Feature == "+d" || Feature == "+f") {
+ // "d" implies "f".
+ HasFeatureF = true;
+ if (Feature == "+d") {
+ HasFeatureD = true;
+ }
+ } else if (Feature == "+lsx")
+ HasFeatureLSX = true;
+ else if (Feature == "+lasx")
+ HasFeatureLASX = true;
+ }
+ return true;
+}
+
+bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const {
+ return llvm::LoongArch::isValidCPUName(Name);
+}
+
+void LoongArchTargetInfo::fillValidCPUList(
+ SmallVectorImpl<StringRef> &Values) const {
+ llvm::LoongArch::fillValidCPUList(Values);
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h
new file mode 100644
index 000000000000..3313102492cb
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/LoongArch.h
@@ -0,0 +1,154 @@
+//===-- LoongArch.h - Declare LoongArch target feature support --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares LoongArch TargetInfo objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H
+#define LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
+
+namespace clang {
+namespace targets {
+
+class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
+protected:
+ std::string ABI;
+ std::string CPU;
+ bool HasFeatureD;
+ bool HasFeatureF;
+ bool HasFeatureLSX;
+ bool HasFeatureLASX;
+
+public:
+ LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+ : TargetInfo(Triple) {
+ HasFeatureD = false;
+ HasFeatureF = false;
+ HasFeatureLSX = false;
+ HasFeatureLASX = false;
+ LongDoubleWidth = 128;
+ LongDoubleAlign = 128;
+ LongDoubleFormat = &llvm::APFloat::IEEEquad();
+ MCountName = "_mcount";
+ SuitableAlign = 128;
+ WCharType = SignedInt;
+ WIntType = UnsignedInt;
+ }
+
+ bool setCPU(const std::string &Name) override {
+ if (!isValidCPUName(Name))
+ return false;
+ CPU = Name;
+ return true;
+ }
+
+ StringRef getCPU() const { return CPU; }
+
+ StringRef getABI() const override { return ABI; }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override;
+
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ return TargetInfo::VoidPtrBuiltinVaList;
+ }
+
+ std::string_view getClobbers() const override { return ""; }
+
+ ArrayRef<const char *> getGCCRegNames() const override;
+
+ int getEHDataRegisterNumber(unsigned RegNo) const override {
+ if (RegNo == 0)
+ return 4;
+ if (RegNo == 1)
+ return 5;
+ return -1;
+ }
+
+ ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
+
+ bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const override;
+ std::string convertConstraint(const char *&Constraint) const override;
+
+ bool hasBitIntType() const override { return true; }
+
+ bool handleTargetFeatures(std::vector<std::string> &Features,
+ DiagnosticsEngine &Diags) override;
+
+ bool
+ initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
+ StringRef CPU,
+ const std::vector<std::string> &FeaturesVec) const override;
+
+ bool hasFeature(StringRef Feature) const override;
+
+ bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo
+ : public LoongArchTargetInfo {
+public:
+ LoongArch32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : LoongArchTargetInfo(Triple, Opts) {
+ IntPtrType = SignedInt;
+ PtrDiffType = SignedInt;
+ SizeType = UnsignedInt;
+ resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128");
+ // TODO: select appropriate ABI.
+ setABI("ilp32d");
+ }
+
+ bool setABI(const std::string &Name) override {
+ if (Name == "ilp32d" || Name == "ilp32f" || Name == "ilp32s") {
+ ABI = Name;
+ return true;
+ }
+ return false;
+ }
+ void setMaxAtomicWidth() override {
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
+ }
+};
+
+class LLVM_LIBRARY_VISIBILITY LoongArch64TargetInfo
+ : public LoongArchTargetInfo {
+public:
+ LoongArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : LoongArchTargetInfo(Triple, Opts) {
+ LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+ IntMaxType = Int64Type = SignedLong;
+ resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128");
+ // TODO: select appropriate ABI.
+ setABI("lp64d");
+ }
+
+ bool setABI(const std::string &Name) override {
+ if (Name == "lp64d" || Name == "lp64f" || Name == "lp64s") {
+ ABI = Name;
+ return true;
+ }
+ return false;
+ }
+ void setMaxAtomicWidth() override {
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ }
+};
+} // end namespace targets
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_BASIC_TARGETS_LOONGARCH_H
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp
index c0cd8fa90ed6..1b7e0a7f32c9 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.cpp
@@ -17,19 +17,20 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/TargetParser.h"
+#include "llvm/TargetParser/TargetParser.h"
#include <cstdint>
#include <cstring>
#include <limits>
+#include <optional>
namespace clang {
namespace targets {
M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,
- const TargetOptions &)
- : TargetInfo(Triple) {
+ const TargetOptions &Opts)
+ : TargetInfo(Triple), TargetOpts(Opts) {
- std::string Layout = "";
+ std::string Layout;
// M68k is Big Endian
Layout += "E";
@@ -79,45 +80,44 @@ void M68kTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__m68k__");
- Builder.defineMacro("mc68000");
- Builder.defineMacro("__mc68000");
- Builder.defineMacro("__mc68000__");
+ DefineStd(Builder, "mc68000", Opts);
// For sub-architecture
switch (CPU) {
case CK_68010:
- Builder.defineMacro("mc68010");
- Builder.defineMacro("__mc68010");
- Builder.defineMacro("__mc68010__");
+ DefineStd(Builder, "mc68010", Opts);
break;
case CK_68020:
- Builder.defineMacro("mc68020");
- Builder.defineMacro("__mc68020");
- Builder.defineMacro("__mc68020__");
+ DefineStd(Builder, "mc68020", Opts);
break;
case CK_68030:
- Builder.defineMacro("mc68030");
- Builder.defineMacro("__mc68030");
- Builder.defineMacro("__mc68030__");
+ DefineStd(Builder, "mc68030", Opts);
break;
case CK_68040:
- Builder.defineMacro("mc68040");
- Builder.defineMacro("__mc68040");
- Builder.defineMacro("__mc68040__");
+ DefineStd(Builder, "mc68040", Opts);
break;
case CK_68060:
- Builder.defineMacro("mc68060");
- Builder.defineMacro("__mc68060");
- Builder.defineMacro("__mc68060__");
+ DefineStd(Builder, "mc68060", Opts);
break;
default:
break;
}
+
+ if (CPU >= CK_68020) {
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ }
+
+ // Floating point
+ if (TargetOpts.FeatureMap.lookup("isa-68881") ||
+ TargetOpts.FeatureMap.lookup("isa-68882"))
+ Builder.defineMacro("__HAVE_68881__");
}
ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const {
// FIXME: Implement.
- return None;
+ return std::nullopt;
}
bool M68kTargetInfo::hasFeature(StringRef Feature) const {
@@ -131,12 +131,12 @@ const char *const M68kTargetInfo::GCCRegNames[] = {
"pc"};
ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const {
// No aliases.
- return None;
+ return std::nullopt;
}
bool M68kTargetInfo::validateAsmConstraint(
@@ -185,13 +185,19 @@ bool M68kTargetInfo::validateAsmConstraint(
break;
}
break;
+ case 'Q': // address register indirect addressing
+ case 'U': // address register indirect w/ constant offset addressing
+ // TODO: Handle 'S' (basically 'm' when pc-rel is enforced) when
+ // '-mpcrel' flag is properly handled by the driver.
+ info.setAllowsMemory();
+ return true;
default:
break;
}
return false;
}
-llvm::Optional<std::string>
+std::optional<std::string>
M68kTargetInfo::handleAsmEscapedChar(char EscChar) const {
char C;
switch (EscChar) {
@@ -209,7 +215,7 @@ M68kTargetInfo::handleAsmEscapedChar(char EscChar) const {
C = 'd';
break;
default:
- return llvm::None;
+ return std::nullopt;
}
return std::string(1, C);
@@ -223,7 +229,7 @@ std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const {
return std::string(1, *Constraint);
}
-const char *M68kTargetInfo::getClobbers() const {
+std::string_view M68kTargetInfo::getClobbers() const {
// FIXME: Is this really right?
return "";
}
@@ -232,5 +238,15 @@ TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const {
return TargetInfo::VoidPtrBuiltinVaList;
}
+TargetInfo::CallingConvCheckResult
+M68kTargetInfo::checkCallingConvention(CallingConv CC) const {
+ switch (CC) {
+ case CC_C:
+ case CC_M68kRTD:
+ return CCCR_OK;
+ default:
+ return TargetInfo::checkCallingConvention(CC);
+ }
+}
} // namespace targets
} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.h b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.h
index a42ca674ef9c..a9c262e62fba 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/M68k.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/M68k.h
@@ -16,8 +16,9 @@
#include "OSTargets.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
namespace clang {
namespace targets {
@@ -35,6 +36,8 @@ class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo {
CK_68060
} CPU = CK_Unknown;
+ const TargetOptions &TargetOpts;
+
public:
M68kTargetInfo(const llvm::Triple &Triple, const TargetOptions &);
@@ -47,10 +50,11 @@ public:
std::string convertConstraint(const char *&Constraint) const override;
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override;
- llvm::Optional<std::string> handleAsmEscapedChar(char EscChar) const override;
- const char *getClobbers() const override;
+ std::optional<std::string> handleAsmEscapedChar(char EscChar) const override;
+ std::string_view getClobbers() const override;
BuiltinVaListKind getBuiltinVaListKind() const override;
bool setCPU(const std::string &Name) override;
+ CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
};
} // namespace targets
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp
index 90890500ae27..844f5d3af703 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.cpp
@@ -22,13 +22,12 @@ const char *const MSP430TargetInfo::GCCRegNames[] = {
};
ArrayRef<const char *> MSP430TargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
void MSP430TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("MSP430");
Builder.defineMacro("__MSP430__");
- Builder.defineMacro("__ELF__");
// FIXME: defines for different 'flavours' of MCU
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h b/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h
index 9d42e4d4bb18..25639b8c1e0a 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/MSP430.h
@@ -15,8 +15,8 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -52,7 +52,7 @@ public:
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
// FIXME: Implement.
- return None;
+ return std::nullopt;
}
bool allowsLargerPreferedTypeAlignment() const override { return false; }
@@ -71,7 +71,7 @@ public:
{{"r2"}, "sr"},
{{"r3"}, "cg"},
};
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
bool validateAsmConstraint(const char *&Name,
@@ -87,7 +87,7 @@ public:
return false;
}
- const char *getClobbers() const override {
+ std::string_view getClobbers() const override {
// FIXME: Is this really right?
return "";
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp
index 3a32fd492c6b..3a65f53c5248 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Mips.cpp
@@ -20,11 +20,11 @@
using namespace clang;
using namespace clang::targets;
-const Builtin::Info MipsTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsMips.def"
};
@@ -50,7 +50,7 @@ static constexpr llvm::StringLiteral ValidCPUNames[] = {
{"octeon"}, {"octeon+"}, {"p5600"}};
bool MipsTargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
+ return llvm::is_contained(ValidCPUNames, Name);
}
void MipsTargetInfo::fillValidCPUList(
@@ -149,6 +149,10 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("_MIPS_FPSET", Twine(32));
else
Builder.defineMacro("_MIPS_FPSET", Twine(16));
+ if (NoOddSpreg)
+ Builder.defineMacro("_MIPS_SPFPSET", Twine(16));
+ else
+ Builder.defineMacro("_MIPS_SPFPSET", Twine(32));
if (IsMips16)
Builder.defineMacro("__mips16", Twine(1));
@@ -182,7 +186,7 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
if (DisableMadd4)
Builder.defineMacro("__mips_no_madd4", Twine(1));
- Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(0)));
+ Builder.defineMacro("_MIPS_SZPTR", Twine(getPointerWidth(LangAS::Default)));
Builder.defineMacro("_MIPS_SZINT", Twine(getIntWidth()));
Builder.defineMacro("_MIPS_SZLONG", Twine(getLongWidth()));
@@ -192,14 +196,14 @@ void MipsTargetInfo::getTargetDefines(const LangOptions &Opts,
else
Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
- if (StringRef(CPU).startswith("octeon"))
+ if (StringRef(CPU).starts_with("octeon"))
Builder.defineMacro("__OCTEON__");
- // These shouldn't be defined for MIPS-I but there's no need to check
- // for that since MIPS-I isn't supported.
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
- Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ if (CPU != "mips1") {
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ }
// 32-bit MIPS processors don't have the necessary lld/scd instructions
// found in 64-bit processors. In the case of O32 on a 64-bit processor,
@@ -220,8 +224,8 @@ bool MipsTargetInfo::hasFeature(StringRef Feature) const {
}
ArrayRef<Builtin::Info> MipsTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::Mips::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
unsigned MipsTargetInfo::getUnwindWordWidth() const {
@@ -229,7 +233,7 @@ unsigned MipsTargetInfo::getUnwindWordWidth() const {
.Case("o32", 32)
.Case("n32", 64)
.Case("n64", 64)
- .Default(getPointerWidth(0));
+ .Default(getPointerWidth(LangAS::Default));
}
bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
@@ -238,12 +242,6 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
Diags.Report(diag::err_target_unsupported_cpu_for_micromips) << CPU;
return false;
}
- // FIXME: It's valid to use O32 on a 64-bit CPU but the backend can't handle
- // this yet. It's better to fail here than on the backend assertion.
- if (processorSupportsGPR64() && ABI == "o32") {
- Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU;
- return false;
- }
// 64-bit ABI's require 64-bit CPU's.
if (!processorSupportsGPR64() && (ABI == "n32" || ABI == "n64")) {
@@ -251,24 +249,6 @@ bool MipsTargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
return false;
}
- // 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().isMIPS64() && ABI == "o32") {
- Diags.Report(diag::err_target_unsupported_abi_for_triple)
- << ABI << getTriple().str();
- return false;
- }
-
- // 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().isMIPS32() && (ABI == "n32" || ABI == "n64")) {
- Diags.Report(diag::err_target_unsupported_abi_for_triple)
- << ABI << getTriple().str();
- return false;
- }
-
// -fpxx is valid only for the o32 ABI
if (FPMode == FPXX && (ABI == "n32" || ABI == "n64")) {
Diags.Report(diag::err_unsupported_abi_for_opt) << "-mfpxx" << "o32";
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Mips.h b/contrib/llvm-project/clang/lib/Basic/Targets/Mips.h
index b475c03889a1..23d4e1b598fa 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Mips.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Mips.h
@@ -15,8 +15,8 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -40,7 +40,6 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
resetDataLayout(("e-" + Layout).str());
}
- static const Builtin::Info BuiltinInfo[];
std::string CPU;
bool IsMips16;
bool IsMicromips;
@@ -54,6 +53,7 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
bool HasMSA;
bool DisableMadd4;
bool UseIndirectJumpHazard;
+ bool NoOddSpreg;
protected:
enum FPModeEnum { FPXX, FP32, FP64 } FPMode;
@@ -226,7 +226,7 @@ public:
"$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify",
"$msarequest", "$msamap", "$msaunmap"
};
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
bool validateAsmConstraint(const char *&Name,
@@ -237,12 +237,14 @@ public:
case 'r': // CPU registers.
case 'd': // Equivalent to "r" unless generating MIPS16 code.
case 'y': // Equivalent to "r", backward compatibility only.
- case 'f': // floating-point registers.
case 'c': // $25 for indirect jumps
case 'l': // lo register
case 'x': // hilo register pair
Info.setAllowsRegister();
return true;
+ case 'f': // floating-point registers.
+ Info.setAllowsRegister();
+ return FloatABI != SoftFloat;
case 'I': // Signed 16-bit constant
case 'J': // Integer 0
case 'K': // Unsigned 16-bit constant
@@ -279,7 +281,7 @@ public:
return TargetInfo::convertConstraint(Constraint);
}
- const char *getClobbers() const override {
+ std::string_view getClobbers() const override {
// In GCC, $1 is not widely used in generated code (it's used only in a few
// specific situations), so there is no real need for users to add it to
// the clobbers list if they want to use it in their inline assembly code.
@@ -314,6 +316,8 @@ public:
FloatABI = HardFloat;
DspRev = NoDSP;
FPMode = isFP64Default() ? FP64 : FPXX;
+ NoOddSpreg = false;
+ bool OddSpregGiven = false;
for (const auto &Feature : Features) {
if (Feature == "+single-float")
@@ -350,8 +354,18 @@ public:
IsNoABICalls = true;
else if (Feature == "+use-indirect-jump-hazard")
UseIndirectJumpHazard = true;
+ else if (Feature == "+nooddspreg") {
+ NoOddSpreg = true;
+ OddSpregGiven = false;
+ } else if (Feature == "-nooddspreg") {
+ NoOddSpreg = false;
+ OddSpregGiven = true;
+ }
}
+ if (FPMode == FPXX && !OddSpregGiven)
+ NoOddSpreg = true;
+
setDataLayout();
return true;
@@ -395,8 +409,8 @@ public:
{{"ra"}, "$31"}
};
if (ABI == "o32")
- return llvm::makeArrayRef(O32RegAliases);
- return llvm::makeArrayRef(NewABIRegAliases);
+ return llvm::ArrayRef(O32RegAliases);
+ return llvm::ArrayRef(NewABIRegAliases);
}
bool hasInt128Type() const override {
@@ -406,7 +420,7 @@ public:
unsigned getUnwindWordWidth() const override;
bool validateTarget(DiagnosticsEngine &Diags) const override;
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp
index 56f8a179db3c..c0b5db795e27 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp
@@ -16,18 +16,17 @@
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetBuiltins.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Frontend/OpenMP/OMPGridValues.h"
using namespace clang;
using namespace clang::targets;
-const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsNVPTX.def"
};
@@ -42,31 +41,20 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
PTXVersion = 32;
for (const StringRef Feature : Opts.FeaturesAsWritten) {
- if (!Feature.startswith("+ptx"))
+ int PTXV;
+ if (!Feature.starts_with("+ptx") ||
+ Feature.drop_front(4).getAsInteger(10, PTXV))
continue;
- PTXVersion = llvm::StringSwitch<unsigned>(Feature)
- .Case("+ptx72", 72)
- .Case("+ptx71", 71)
- .Case("+ptx70", 70)
- .Case("+ptx65", 65)
- .Case("+ptx64", 64)
- .Case("+ptx63", 63)
- .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);
+ PTXVersion = PTXV; // TODO: should it be max(PTXVersion, PTXV)?
}
TLSSupported = false;
VLASupported = false;
AddrSpaceMap = &NVPTXAddrSpaceMap;
- GridValues = llvm::omp::NVPTXGpuGridValues;
UseAddrSpaceMapMangling = true;
+ // __bf16 is always available as a load/store only type.
+ BFloat16Width = BFloat16Align = 16;
+ BFloat16Format = &llvm::APFloat::BFloat();
// Define available target features
// These must be defined in sorted order!
@@ -85,7 +73,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
// types.
llvm::Triple HostTriple(Opts.HostTriple);
if (!HostTriple.isNVPTX())
- HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
+ HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);
// If no host target, make some guesses about the data layout and return.
if (!HostTarget) {
@@ -105,12 +93,14 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
default:
llvm_unreachable("TargetPointerWidth must be 32 or 64");
}
+
+ MaxAtomicInlineWidth = TargetPointerWidth;
return;
}
// Copy properties from host target.
- PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0);
- PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0);
+ PointerWidth = HostTarget->getPointerWidth(LangAS::Default);
+ PointerAlign = HostTarget->getPointerAlign(LangAS::Default);
BoolWidth = HostTarget->getBoolWidth();
BoolAlign = HostTarget->getBoolAlign();
IntWidth = HostTarget->getIntWidth();
@@ -131,7 +121,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
HostTarget->getDefaultAlignForAttributeAligned();
SizeType = HostTarget->getSizeType();
IntMaxType = HostTarget->getIntMaxType();
- PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0);
+ PtrDiffType = HostTarget->getPtrDiffType(LangAS::Default);
IntPtrType = HostTarget->getIntPtrType();
WCharType = HostTarget->getWCharType();
WIntType = HostTarget->getWIntType();
@@ -165,7 +155,7 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
}
ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {
@@ -178,7 +168,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
Builder.defineMacro("__PTX__");
Builder.defineMacro("__NVPTX__");
- if (Opts.CUDAIsDevice) {
+ if (Opts.CUDAIsDevice || Opts.OpenMPIsTargetDevice || !HostTarget) {
// Set __CUDA_ARCH__ for the GPU specified.
std::string CUDAArchCode = [this] {
switch (GPU) {
@@ -204,6 +194,9 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
case CudaArch::GFX909:
case CudaArch::GFX90a:
case CudaArch::GFX90c:
+ case CudaArch::GFX940:
+ case CudaArch::GFX941:
+ case CudaArch::GFX942:
case CudaArch::GFX1010:
case CudaArch::GFX1011:
case CudaArch::GFX1012:
@@ -214,6 +207,16 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
case CudaArch::GFX1033:
case CudaArch::GFX1034:
case CudaArch::GFX1035:
+ case CudaArch::GFX1036:
+ case CudaArch::GFX1100:
+ case CudaArch::GFX1101:
+ case CudaArch::GFX1102:
+ case CudaArch::GFX1103:
+ case CudaArch::GFX1150:
+ case CudaArch::GFX1151:
+ case CudaArch::GFX1200:
+ case CudaArch::GFX1201:
+ case CudaArch::Generic:
case CudaArch::LAST:
break;
case CudaArch::UNUSED:
@@ -254,14 +257,23 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
return "800";
case CudaArch::SM_86:
return "860";
+ case CudaArch::SM_87:
+ return "870";
+ case CudaArch::SM_89:
+ return "890";
+ case CudaArch::SM_90:
+ case CudaArch::SM_90a:
+ return "900";
}
llvm_unreachable("unhandled CudaArch");
}();
Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
+ if (GPU == CudaArch::SM_90a)
+ Builder.defineMacro("__CUDA_ARCH_FEAT_SM90_ALL", "1");
}
}
ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h
index c7db3cdaaf10..20d76b702a94 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h
@@ -16,8 +16,9 @@
#include "clang/Basic/Cuda.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
namespace clang {
namespace targets {
@@ -42,7 +43,11 @@ static const unsigned NVPTXAddrSpaceMap[] = {
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ 0, // hlsl_groupshared
+ // Wasm address space values for this target are dummy values,
+ // as it is only enabled for Wasm targets.
+ 20, // wasm_funcref
};
/// The DWARF address class. Taken from
@@ -57,7 +62,6 @@ static const int NVPTXDWARFAddrSpaceMap[] = {
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;
@@ -86,7 +90,7 @@ public:
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
// No aliases.
- return None;
+ return std::nullopt;
}
bool validateAsmConstraint(const char *&Name,
@@ -105,7 +109,7 @@ public:
}
}
- const char *getClobbers() const override {
+ std::string_view getClobbers() const override {
// FIXME: Is this really right?
return "";
}
@@ -121,7 +125,7 @@ public:
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override {
for (int i = static_cast<int>(CudaArch::SM_20);
- i < static_cast<int>(CudaArch::LAST); ++i)
+ i < static_cast<int>(CudaArch::Generic); ++i)
Values.emplace_back(CudaArchToString(static_cast<CudaArch>(i)));
}
@@ -147,17 +151,21 @@ public:
Opts["cl_khr_local_int32_extended_atomics"] = true;
}
+ const llvm::omp::GV &getGridValue() const override {
+ return llvm::omp::NVPTXGridValues;
+ }
+
/// \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
/// corresponding target specific DWARF address space.
///
- /// \returns Otherwise return None and no conversion will be emitted in the
- /// DWARF.
- Optional<unsigned>
+ /// \returns Otherwise return std::nullopt and no conversion will be emitted
+ /// in the DWARF.
+ std::optional<unsigned>
getDWARFAddressSpace(unsigned AddressSpace) const override {
- if (AddressSpace >= llvm::array_lengthof(NVPTXDWARFAddrSpaceMap) ||
+ if (AddressSpace >= std::size(NVPTXDWARFAddrSpaceMap) ||
NVPTXDWARFAddrSpaceMap[AddressSpace] < 0)
- return llvm::None;
+ return std::nullopt;
return NVPTXDWARFAddrSpaceMap[AddressSpace];
}
@@ -171,7 +179,10 @@ public:
return CCCR_Warning;
}
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
+ bool hasBFloat16Type() const override { return true; }
+
+ CudaArch getGPU() const { return GPU; }
};
} // namespace targets
} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp
index 7cd4a5190120..899aefa6173a 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.cpp
@@ -48,12 +48,12 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
Builder.defineMacro("_REENTRANT");
// Get the platform type and version number from the triple.
- unsigned Maj, Min, Rev;
+ VersionTuple OsVersion;
if (Triple.isMacOSX()) {
- Triple.getMacOSXVersion(Maj, Min, Rev);
+ Triple.getMacOSXVersion(OsVersion);
PlatformName = "macos";
} else {
- Triple.getOSVersion(Maj, Min, Rev);
+ OsVersion = Triple.getOSVersion();
PlatformName = llvm::Triple::getOSTypeName(Triple.getOS());
if (PlatformName == "ios" && Triple.isMacCatalystEnvironment())
PlatformName = "maccatalyst";
@@ -63,78 +63,63 @@ void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
// generating code for Win32 ABI. No need to emit
// __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
if (PlatformName == "win32") {
- PlatformMinVersion = VersionTuple(Maj, Min, Rev);
+ PlatformMinVersion = OsVersion;
return;
}
- // Set the appropriate OS version define.
- if (Triple.isiOS()) {
- assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
- char Str[7];
- if (Maj < 10) {
- Str[0] = '0' + Maj;
- Str[1] = '0' + (Min / 10);
- Str[2] = '0' + (Min % 10);
- Str[3] = '0' + (Rev / 10);
- Str[4] = '0' + (Rev % 10);
- Str[5] = '\0';
- } else {
- // Handle versions >= 10.
- Str[0] = '0' + (Maj / 10);
- Str[1] = '0' + (Maj % 10);
- Str[2] = '0' + (Min / 10);
- Str[3] = '0' + (Min % 10);
- Str[4] = '0' + (Rev / 10);
- Str[5] = '0' + (Rev % 10);
- Str[6] = '\0';
- }
- if (Triple.isTvOS())
- Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);
- else
- Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
- Str);
+ assert(OsVersion < VersionTuple(100) && "Invalid version!");
+ char Str[7];
+ if (Triple.isMacOSX() && OsVersion < VersionTuple(10, 10)) {
+ Str[0] = '0' + (OsVersion.getMajor() / 10);
+ Str[1] = '0' + (OsVersion.getMajor() % 10);
+ Str[2] = '0' + std::min(OsVersion.getMinor().value_or(0), 9U);
+ Str[3] = '0' + std::min(OsVersion.getSubminor().value_or(0), 9U);
+ Str[4] = '\0';
+ } else if (!Triple.isMacOSX() && OsVersion.getMajor() < 10) {
+ Str[0] = '0' + OsVersion.getMajor();
+ Str[1] = '0' + (OsVersion.getMinor().value_or(0) / 10);
+ Str[2] = '0' + (OsVersion.getMinor().value_or(0) % 10);
+ Str[3] = '0' + (OsVersion.getSubminor().value_or(0) / 10);
+ Str[4] = '0' + (OsVersion.getSubminor().value_or(0) % 10);
+ Str[5] = '\0';
+ } else {
+ // Handle versions >= 10.
+ Str[0] = '0' + (OsVersion.getMajor() / 10);
+ Str[1] = '0' + (OsVersion.getMajor() % 10);
+ Str[2] = '0' + (OsVersion.getMinor().value_or(0) / 10);
+ Str[3] = '0' + (OsVersion.getMinor().value_or(0) % 10);
+ Str[4] = '0' + (OsVersion.getSubminor().value_or(0) / 10);
+ Str[5] = '0' + (OsVersion.getSubminor().value_or(0) % 10);
+ Str[6] = '\0';
+ }
+ // Set the appropriate OS version define.
+ if (Triple.isTvOS()) {
+ Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);
+ } else if (Triple.isiOS()) {
+ Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
} else if (Triple.isWatchOS()) {
- assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
- char Str[6];
- Str[0] = '0' + Maj;
- Str[1] = '0' + (Min / 10);
- Str[2] = '0' + (Min % 10);
- Str[3] = '0' + (Rev / 10);
- Str[4] = '0' + (Rev % 10);
- Str[5] = '\0';
Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str);
+ } else if (Triple.isDriverKit()) {
+ assert(OsVersion.getMinor().value_or(0) < 100 &&
+ OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!");
+ Builder.defineMacro("__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__", Str);
} else if (Triple.isMacOSX()) {
- // Note that the Driver allows versions which aren't representable in the
- // define (because we only get a single digit for the minor and micro
- // revision numbers). So, we limit them to the maximum representable
- // version.
- assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
- char Str[7];
- if (Maj < 10 || (Maj == 10 && Min < 10)) {
- Str[0] = '0' + (Maj / 10);
- Str[1] = '0' + (Maj % 10);
- Str[2] = '0' + std::min(Min, 9U);
- Str[3] = '0' + std::min(Rev, 9U);
- Str[4] = '\0';
- } else {
- // Handle versions > 10.9.
- Str[0] = '0' + (Maj / 10);
- Str[1] = '0' + (Maj % 10);
- Str[2] = '0' + (Min / 10);
- Str[3] = '0' + (Min % 10);
- Str[4] = '0' + (Rev / 10);
- Str[5] = '0' + (Rev % 10);
- Str[6] = '\0';
- }
Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
}
- // Tell users about the kernel if there is one.
- if (Triple.isOSDarwin())
+ if (Triple.isOSDarwin()) {
+ // Any darwin OS defines a general darwin OS version macro in addition
+ // to the other OS specific macros.
+ assert(OsVersion.getMinor().value_or(0) < 100 &&
+ OsVersion.getSubminor().value_or(0) < 100 && "Invalid version!");
+ Builder.defineMacro("__ENVIRONMENT_OS_VERSION_MIN_REQUIRED__", Str);
+
+ // Tell users about the kernel if there is one.
Builder.defineMacro("__MACH__");
+ }
- PlatformMinVersion = VersionTuple(Maj, Min, Rev);
+ PlatformMinVersion = OsVersion;
}
static void addMinGWDefines(const llvm::Triple &Triple, const LangOptions &Opts,
@@ -165,6 +150,54 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
if (!Opts.CharIsSigned)
Builder.defineMacro("_CHAR_UNSIGNED");
+ // "The /fp:contract option allows the compiler to generate floating-point
+ // contractions [...]"
+ if (Opts.getDefaultFPContractMode() != LangOptions::FPModeKind::FPM_Off)
+ Builder.defineMacro("_M_FP_CONTRACT");
+
+ // "The /fp:except option generates code to ensures that any unmasked
+ // floating-point exceptions are raised at the exact point at which they
+ // occur, and that no other floating-point exceptions are raised."
+ if (Opts.getDefaultExceptionMode() ==
+ LangOptions::FPExceptionModeKind::FPE_Strict)
+ Builder.defineMacro("_M_FP_EXCEPT");
+
+ // "The /fp:fast option allows the compiler to reorder, combine, or simplify
+ // floating-point operations to optimize floating-point code for speed and
+ // space. The compiler may omit rounding at assignment statements,
+ // typecasts, or function calls. It may reorder operations or make algebraic
+ // transforms, for example, by use of associative and distributive laws. It
+ // may reorder code even if such transformations result in observably
+ // different rounding behavior."
+ //
+ // "Under /fp:precise and /fp:strict, the compiler doesn't do any mathematical
+ // transformation unless the transformation is guaranteed to produce a bitwise
+ // identical result."
+ const bool any_imprecise_flags =
+ Opts.FastMath || Opts.FiniteMathOnly || Opts.UnsafeFPMath ||
+ Opts.AllowFPReassoc || Opts.NoHonorNaNs || Opts.NoHonorInfs ||
+ Opts.NoSignedZero || Opts.AllowRecip || Opts.ApproxFunc;
+
+ // "Under both /fp:precise and /fp:fast, the compiler generates code intended
+ // to run in the default floating-point environment."
+ //
+ // "[The] default floating point environment [...] sets the rounding mode
+ // to round to nearest."
+ if (Opts.getDefaultRoundingMode() ==
+ LangOptions::RoundingMode::NearestTiesToEven) {
+ if (any_imprecise_flags) {
+ Builder.defineMacro("_M_FP_FAST");
+ } else {
+ Builder.defineMacro("_M_FP_PRECISE");
+ }
+ } else if (!any_imprecise_flags && Opts.getDefaultRoundingMode() ==
+ LangOptions::RoundingMode::Dynamic) {
+ // "Under /fp:strict, the compiler generates code that allows the
+ // program to safely unmask floating-point exceptions, read or write
+ // floating-point status registers, or change rounding modes."
+ Builder.defineMacro("_M_FP_STRICT");
+ }
+
// FIXME: POSIXThreads isn't exactly the option this should be defined for,
// but it works for now.
if (Opts.POSIXThreads)
@@ -181,13 +214,19 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));
if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
- if (Opts.CPlusPlus20)
- Builder.defineMacro("_MSVC_LANG", "201705L");
+ if (Opts.CPlusPlus23)
+ // TODO update to the proper value.
+ Builder.defineMacro("_MSVC_LANG", "202004L");
+ else if (Opts.CPlusPlus20)
+ Builder.defineMacro("_MSVC_LANG", "202002L");
else if (Opts.CPlusPlus17)
Builder.defineMacro("_MSVC_LANG", "201703L");
else if (Opts.CPlusPlus14)
Builder.defineMacro("_MSVC_LANG", "201402L");
}
+
+ if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2022_3))
+ Builder.defineMacro("_MSVC_CONSTEXPR_ATTRIBUTE");
}
if (Opts.MicrosoftExt) {
@@ -200,7 +239,22 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
}
}
+ if (!Opts.MSVolatile)
+ Builder.defineMacro("_ISO_VOLATILE");
+
+ if (Opts.Kernel)
+ Builder.defineMacro("_KERNEL_MODE");
+
Builder.defineMacro("_INTEGRAL_MAX_BITS", "64");
+ Builder.defineMacro("__STDC_NO_THREADS__");
+
+ // Starting with VS 2022 17.1, MSVC predefines the below macro to inform
+ // users of the execution character set defined at compile time.
+ // The value given is the Windows Code Page Identifier:
+ // https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
+ //
+ // Clang currently only supports UTF-8, so we'll use 65001
+ Builder.defineMacro("_MSVC_EXECUTION_CHARACTER_SET", "65001");
}
void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h
index 3fe39ed64d9c..4366c1149e40 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/OSTargets.h
@@ -34,42 +34,6 @@ public:
}
};
-// CloudABI Target
-template <typename Target>
-class LLVM_LIBRARY_VISIBILITY CloudABITargetInfo : public OSTargetInfo<Target> {
-protected:
- void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
- MacroBuilder &Builder) const override {
- Builder.defineMacro("__CloudABI__");
- Builder.defineMacro("__ELF__");
-
- // CloudABI uses ISO/IEC 10646:2012 for wchar_t, char16_t and char32_t.
- Builder.defineMacro("__STDC_ISO_10646__", "201206L");
- Builder.defineMacro("__STDC_UTF_16__");
- Builder.defineMacro("__STDC_UTF_32__");
- }
-
-public:
- CloudABITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
- : OSTargetInfo<Target>(Triple, Opts) {}
-};
-
-// Ananas target
-template <typename Target>
-class LLVM_LIBRARY_VISIBILITY AnanasTargetInfo : public OSTargetInfo<Target> {
-protected:
- void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
- MacroBuilder &Builder) const override {
- // Ananas defines
- Builder.defineMacro("__Ananas__");
- Builder.defineMacro("__ELF__");
- }
-
-public:
- AnanasTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
- : OSTargetInfo<Target>(Triple, Opts) {}
-};
-
void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
const llvm::Triple &Triple, StringRef &PlatformName,
VersionTuple &PlatformMinVersion);
@@ -108,7 +72,10 @@ public:
this->TLSSupported = !Triple.isOSVersionLT(2);
else
this->TLSSupported = !Triple.isOSVersionLT(3);
- }
+ } else if (Triple.isDriverKit()) {
+ // No TLS on DriverKit.
+ } else if (Triple.isXROS())
+ this->TLSSupported = true;
this->MCountName = "\01mcount";
}
@@ -143,14 +110,15 @@ public:
case llvm::Triple::WatchOS: // Earliest supporting version is 5.0.0.
MinVersion = llvm::VersionTuple(5U);
break;
+ case llvm::Triple::XROS:
+ MinVersion = llvm::VersionTuple(0);
+ break;
default:
// Conservatively return 8 bytes if OS is unknown.
return 64;
}
- unsigned Major, Minor, Micro;
- T.getOSVersion(Major, Minor, Micro);
- if (llvm::VersionTuple(Major, Minor, Micro) < MinVersion)
+ if (T.getOSVersion() < MinVersion)
return 64;
return OSTargetInfo<Target>::getExnObjectAlignment();
}
@@ -163,6 +131,10 @@ public:
: TargetInfo::UnsignedLongLong)
: TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
}
+
+ bool areDefaultedSMFStillPOD(const LangOptions &) const override {
+ return false;
+ }
};
// DragonFlyBSD Target
@@ -175,10 +147,11 @@ protected:
// DragonFly defines; list based off of gcc output
Builder.defineMacro("__DragonFly__");
Builder.defineMacro("__DragonFly_cc_version", "100001");
- Builder.defineMacro("__ELF__");
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
Builder.defineMacro("__tune_i386__");
DefineStd(Builder, "unix", Opts);
+ if (this->HasFloat128)
+ Builder.defineMacro("__FLOAT128__");
}
public:
@@ -188,6 +161,7 @@ public:
default:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
+ this->HasFloat128 = true;
this->MCountName = ".mcount";
break;
}
@@ -217,7 +191,8 @@ protected:
Builder.defineMacro("__FreeBSD_cc_version", Twine(CCVersion));
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
DefineStd(Builder, "unix", Opts);
- Builder.defineMacro("__ELF__");
+ if (this->HasFloat128)
+ Builder.defineMacro("__FLOAT128__");
// On FreeBSD, wchar_t contains the number of the code point as
// used by the character set of the locale. These character sets are
@@ -235,9 +210,11 @@ public:
FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: OSTargetInfo<Target>(Triple, Opts) {
switch (Triple.getArch()) {
- default:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
+ this->HasFloat128 = true;
+ [[fallthrough]];
+ default:
this->MCountName = ".mcount";
break;
case llvm::Triple::mips:
@@ -269,7 +246,6 @@ protected:
DefineStd(Builder, "unix", Opts);
Builder.defineMacro("__FreeBSD_kernel__");
Builder.defineMacro("__GLIBC__");
- Builder.defineMacro("__ELF__");
if (Opts.POSIXThreads)
Builder.defineMacro("_REENTRANT");
if (Opts.CPlusPlus)
@@ -277,8 +253,7 @@ protected:
}
public:
- KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
- : OSTargetInfo<Target>(Triple, Opts) {}
+ using OSTargetInfo<Target>::OSTargetInfo;
};
// Haiku Target
@@ -289,9 +264,8 @@ protected:
MacroBuilder &Builder) const override {
// Haiku defines; list based off of gcc output
Builder.defineMacro("__HAIKU__");
- Builder.defineMacro("__ELF__");
DefineStd(Builder, "unix", Opts);
- if (this->HasFloat128)
+ if (this->HasFloat128)
Builder.defineMacro("__FLOAT128__");
}
@@ -302,7 +276,6 @@ public:
this->IntPtrType = TargetInfo::SignedLong;
this->PtrDiffType = TargetInfo::SignedLong;
this->ProcessIDType = TargetInfo::SignedLong;
- this->TLSSupported = false;
switch (Triple.getArch()) {
default:
break;
@@ -326,39 +299,13 @@ protected:
Builder.defineMacro("__gnu_hurd__");
Builder.defineMacro("__MACH__");
Builder.defineMacro("__GLIBC__");
- Builder.defineMacro("__ELF__");
if (Opts.POSIXThreads)
Builder.defineMacro("_REENTRANT");
if (Opts.CPlusPlus)
Builder.defineMacro("_GNU_SOURCE");
}
public:
- HurdTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
- : OSTargetInfo<Target>(Triple, Opts) {}
-};
-
-// Minix Target
-template <typename Target>
-class LLVM_LIBRARY_VISIBILITY MinixTargetInfo : public OSTargetInfo<Target> {
-protected:
- void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
- MacroBuilder &Builder) const override {
- // Minix defines
-
- Builder.defineMacro("__minix", "3");
- Builder.defineMacro("_EM_WSIZE", "4");
- Builder.defineMacro("_EM_PSIZE", "4");
- Builder.defineMacro("_EM_SSIZE", "2");
- Builder.defineMacro("_EM_LSIZE", "4");
- Builder.defineMacro("_EM_FSIZE", "4");
- Builder.defineMacro("_EM_DSIZE", "8");
- Builder.defineMacro("__ELF__");
- DefineStd(Builder, "unix", Opts);
- }
-
-public:
- MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
- : OSTargetInfo<Target>(Triple, Opts) {}
+ using OSTargetInfo<Target>::OSTargetInfo;
};
// Linux target
@@ -370,13 +317,11 @@ protected:
// Linux defines; list based off of gcc output
DefineStd(Builder, "unix", Opts);
DefineStd(Builder, "linux", Opts);
- Builder.defineMacro("__ELF__");
if (Triple.isAndroid()) {
Builder.defineMacro("__ANDROID__", "1");
- unsigned Maj, Min, Rev;
- Triple.getEnvironmentVersion(Maj, Min, Rev);
this->PlatformName = "android";
- this->PlatformMinVersion = VersionTuple(Maj, Min, Rev);
+ this->PlatformMinVersion = Triple.getEnvironmentVersion();
+ const unsigned Maj = this->PlatformMinVersion.getMajor();
if (Maj) {
Builder.defineMacro("__ANDROID_MIN_SDK_VERSION__", Twine(Maj));
// This historical but ambiguous name for the minSdkVersion macro. Keep
@@ -433,15 +378,24 @@ protected:
// NetBSD defines; list based off of gcc output
Builder.defineMacro("__NetBSD__");
Builder.defineMacro("__unix__");
- Builder.defineMacro("__ELF__");
if (Opts.POSIXThreads)
Builder.defineMacro("_REENTRANT");
+ if (this->HasFloat128)
+ Builder.defineMacro("__FLOAT128__");
}
public:
NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: OSTargetInfo<Target>(Triple, Opts) {
this->MCountName = "__mcount";
+ switch (Triple.getArch()) {
+ default:
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ this->HasFloat128 = true;
+ break;
+ }
}
};
@@ -455,16 +409,13 @@ protected:
Builder.defineMacro("__OpenBSD__");
DefineStd(Builder, "unix", Opts);
- Builder.defineMacro("__ELF__");
if (Opts.POSIXThreads)
Builder.defineMacro("_REENTRANT");
if (this->HasFloat128)
Builder.defineMacro("__FLOAT128__");
- if (Opts.C11) {
- Builder.defineMacro("__STDC_NO_ATOMICS__");
+ if (Opts.C11)
Builder.defineMacro("__STDC_NO_THREADS__");
- }
}
public:
@@ -477,7 +428,7 @@ public:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
this->HasFloat128 = true;
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
default:
this->MCountName = "__mcount";
break;
@@ -496,23 +447,6 @@ public:
}
};
-// PSP Target
-template <typename Target>
-class LLVM_LIBRARY_VISIBILITY PSPTargetInfo : public OSTargetInfo<Target> {
-protected:
- void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
- MacroBuilder &Builder) const override {
- // PSP defines; list based on the output of the pspdev gcc toolchain.
- Builder.defineMacro("PSP");
- Builder.defineMacro("_PSP");
- Builder.defineMacro("__psp__");
- Builder.defineMacro("__ELF__");
- }
-
-public:
- PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {}
-};
-
// PS3 PPU Target
template <typename Target>
class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo<Target> {
@@ -520,10 +454,8 @@ protected:
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
MacroBuilder &Builder) const override {
// PS3 PPU defines.
- Builder.defineMacro("__PPC__");
Builder.defineMacro("__PPU__");
Builder.defineMacro("__CELLOS_LV2__");
- Builder.defineMacro("__ELF__");
Builder.defineMacro("__LP32__");
Builder.defineMacro("_ARCH_PPC64");
Builder.defineMacro("__powerpc64__");
@@ -537,12 +469,13 @@ public:
this->IntMaxType = TargetInfo::SignedLongLong;
this->Int64Type = TargetInfo::SignedLongLong;
this->SizeType = TargetInfo::UnsignedInt;
- this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64");
+ this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-n32:64");
}
};
+// Common base class for PS4/PS5 targets.
template <typename Target>
-class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public OSTargetInfo<Target> {
+class LLVM_LIBRARY_VISIBILITY PSOSTargetInfo : public OSTargetInfo<Target> {
protected:
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
MacroBuilder &Builder) const override {
@@ -550,35 +483,69 @@ protected:
Builder.defineMacro("__FreeBSD_cc_version", "900001");
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
DefineStd(Builder, "unix", Opts);
- Builder.defineMacro("__ELF__");
Builder.defineMacro("__SCE__");
- Builder.defineMacro("__ORBIS__");
+ Builder.defineMacro("__STDC_NO_COMPLEX__");
+ Builder.defineMacro("__STDC_NO_THREADS__");
}
public:
- PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ PSOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: OSTargetInfo<Target>(Triple, Opts) {
this->WCharType = TargetInfo::UnsignedShort;
- // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits).
+ // On PS4/PS5, TLS variable cannot be aligned to more than 32 bytes (256
+ // bits).
this->MaxTLSAlign = 256;
- // On PS4, do not honor explicit bit field alignment,
+ // On PS4/PS5, do not honor explicit bit field alignment,
// as in "__attribute__((aligned(2))) int b : 1;".
this->UseExplicitBitFieldAlignment = false;
- switch (Triple.getArch()) {
- default:
- case llvm::Triple::x86_64:
- this->MCountName = ".mcount";
- this->NewAlign = 256;
- break;
- }
+ this->MCountName = ".mcount";
+ this->NewAlign = 256;
+ this->SuitableAlign = 256;
}
+
TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const override {
return (CC == CC_C) ? TargetInfo::CCCR_OK : TargetInfo::CCCR_Error;
}
+
+ bool areDefaultedSMFStillPOD(const LangOptions &) const override {
+ return false;
+ }
+};
+
+// PS4 Target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY PS4OSTargetInfo : public PSOSTargetInfo<Target> {
+protected:
+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const override {
+ // Start with base class defines.
+ PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
+
+ Builder.defineMacro("__ORBIS__");
+ }
+
+public:
+ using PSOSTargetInfo<Target>::PSOSTargetInfo;
+};
+
+// PS5 Target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY PS5OSTargetInfo : public PSOSTargetInfo<Target> {
+protected:
+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const override {
+ // Start with base class defines.
+ PSOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
+
+ Builder.defineMacro("__PROSPERO__");
+ }
+
+public:
+ using PSOSTargetInfo<Target>::PSOSTargetInfo;
};
// RTEMS Target
@@ -590,7 +557,6 @@ protected:
// RTEMS defines; list based off of gcc output
Builder.defineMacro("__rtems__");
- Builder.defineMacro("__ELF__");
if (Opts.CPlusPlus)
Builder.defineMacro("_GNU_SOURCE");
}
@@ -625,7 +591,6 @@ protected:
MacroBuilder &Builder) const override {
DefineStd(Builder, "sun", Opts);
DefineStd(Builder, "unix", Opts);
- Builder.defineMacro("__ELF__");
Builder.defineMacro("__svr4__");
Builder.defineMacro("__SVR4");
// Solaris headers require _XOPEN_SOURCE to be set to 600 for C99 and
@@ -678,9 +643,11 @@ protected:
DefineStd(Builder, "unix", Opts);
Builder.defineMacro("_IBMR2");
Builder.defineMacro("_POWER");
+ Builder.defineMacro("__THW_BIG_ENDIAN__");
Builder.defineMacro("_AIX");
Builder.defineMacro("__TOS_AIX__");
+ Builder.defineMacro("__HOS_AIX__");
if (Opts.C11) {
Builder.defineMacro("__STDC_NO_ATOMICS__");
@@ -690,23 +657,32 @@ protected:
if (Opts.EnableAIXExtendedAltivecABI)
Builder.defineMacro("__EXTABI__");
- unsigned Major, Minor, Micro;
- Triple.getOSVersion(Major, Minor, Micro);
+ VersionTuple OsVersion = Triple.getOSVersion();
// Define AIX OS-Version Macros.
// Includes logic for legacy versions of AIX; no specific intent to support.
- std::pair<int, int> OsVersion = {Major, Minor};
- if (OsVersion >= std::make_pair(3, 2)) Builder.defineMacro("_AIX32");
- if (OsVersion >= std::make_pair(4, 1)) Builder.defineMacro("_AIX41");
- if (OsVersion >= std::make_pair(4, 3)) Builder.defineMacro("_AIX43");
- if (OsVersion >= std::make_pair(5, 0)) Builder.defineMacro("_AIX50");
- if (OsVersion >= std::make_pair(5, 1)) Builder.defineMacro("_AIX51");
- if (OsVersion >= std::make_pair(5, 2)) Builder.defineMacro("_AIX52");
- if (OsVersion >= std::make_pair(5, 3)) Builder.defineMacro("_AIX53");
- if (OsVersion >= std::make_pair(6, 1)) Builder.defineMacro("_AIX61");
- if (OsVersion >= std::make_pair(7, 1)) Builder.defineMacro("_AIX71");
- if (OsVersion >= std::make_pair(7, 2)) Builder.defineMacro("_AIX72");
- if (OsVersion >= std::make_pair(7, 3)) Builder.defineMacro("_AIX73");
+ if (OsVersion >= VersionTuple(3, 2))
+ Builder.defineMacro("_AIX32");
+ if (OsVersion >= VersionTuple(4, 1))
+ Builder.defineMacro("_AIX41");
+ if (OsVersion >= VersionTuple(4, 3))
+ Builder.defineMacro("_AIX43");
+ if (OsVersion >= VersionTuple(5, 0))
+ Builder.defineMacro("_AIX50");
+ if (OsVersion >= VersionTuple(5, 1))
+ Builder.defineMacro("_AIX51");
+ if (OsVersion >= VersionTuple(5, 2))
+ Builder.defineMacro("_AIX52");
+ if (OsVersion >= VersionTuple(5, 3))
+ Builder.defineMacro("_AIX53");
+ if (OsVersion >= VersionTuple(6, 1))
+ Builder.defineMacro("_AIX61");
+ if (OsVersion >= VersionTuple(7, 1))
+ Builder.defineMacro("_AIX71");
+ if (OsVersion >= VersionTuple(7, 2))
+ Builder.defineMacro("_AIX72");
+ if (OsVersion >= VersionTuple(7, 3))
+ Builder.defineMacro("_AIX73");
// FIXME: Do not define _LONG_LONG when -fno-long-long is specified.
Builder.defineMacro("_LONG_LONG");
@@ -729,6 +705,7 @@ protected:
public:
AIXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: OSTargetInfo<Target>(Triple, Opts) {
+ this->MCountName = "__mcount";
this->TheCXXABI.set(TargetCXXABI::XL);
if (this->PointerWidth == 64) {
@@ -740,10 +717,15 @@ public:
}
// AIX sets FLT_EVAL_METHOD to be 1.
- unsigned getFloatEvalMethod() const override { return 1; }
- bool hasInt128Type() const override { return false; }
+ LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
+ return LangOptions::FPEvalMethodKind::FEM_Double;
+ }
bool defaultsToAIXPowerAlignment() const override { return true; }
+
+ bool areDefaultedSMFStillPOD(const LangOptions &) const override {
+ return false;
+ }
};
// z/OS target
@@ -754,13 +736,11 @@ protected:
MacroBuilder &Builder) const override {
// FIXME: _LONG_LONG should not be defined under -std=c89.
Builder.defineMacro("_LONG_LONG");
- Builder.defineMacro("_OPEN_DEFAULT");
- // _UNIX03_WITHDRAWN is required to build libcxx.
- Builder.defineMacro("_UNIX03_WITHDRAWN");
Builder.defineMacro("__370__");
Builder.defineMacro("__BFP__");
// FIXME: __BOOL__ should not be defined under -std=c89.
Builder.defineMacro("__BOOL__");
+ Builder.defineMacro("__COMPILER_VER__", "0x50000000");
Builder.defineMacro("__LONGNAME__");
Builder.defineMacro("__MVS__");
Builder.defineMacro("__THW_370__");
@@ -772,17 +752,6 @@ protected:
if (this->PointerWidth == 64)
Builder.defineMacro("__64BIT__");
- if (Opts.CPlusPlus) {
- Builder.defineMacro("__DLL__");
- // _XOPEN_SOURCE=600 is required to build libcxx.
- Builder.defineMacro("_XOPEN_SOURCE", "600");
- }
-
- if (Opts.GNUMode) {
- Builder.defineMacro("_MI_BUILTIN");
- Builder.defineMacro("_EXT");
- }
-
if (Opts.CPlusPlus && Opts.WChar) {
// Macro __wchar_t is defined so that the wchar_t data
// type is not declared as a typedef in system headers.
@@ -801,7 +770,11 @@ public:
this->UseZeroLengthBitfieldAlignment = true;
this->UseLeadingZeroLengthBitfield = false;
this->ZeroLengthBitfieldBoundary = 32;
- this->DefaultAlignForAttributeAligned = 128;
+ this->TheCXXABI.set(TargetCXXABI::XL);
+ }
+
+ bool areDefaultedSMFStillPOD(const LangOptions &) const override {
+ return false;
}
};
@@ -836,7 +809,6 @@ protected:
Builder.defineMacro("_GNU_SOURCE");
DefineStd(Builder, "unix", Opts);
- Builder.defineMacro("__ELF__");
Builder.defineMacro("__native_client__");
}
@@ -863,10 +835,10 @@ public:
// Handled in ARM's setABI().
} else if (Triple.getArch() == llvm::Triple::x86) {
this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
- "i64:64-n8:16:32-S128");
+ "i64:64-i128:128-n8:16:32-S128");
} else if (Triple.getArch() == llvm::Triple::x86_64) {
this->resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
- "i64:64-n8:16:32:64-S128");
+ "i64:64-i128:128-n8:16:32:64-S128");
} else if (Triple.getArch() == llvm::Triple::mipsel) {
// Handled on mips' setDataLayout.
} else {
@@ -883,12 +855,14 @@ protected:
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
MacroBuilder &Builder) const override {
Builder.defineMacro("__Fuchsia__");
- Builder.defineMacro("__ELF__");
if (Opts.POSIXThreads)
Builder.defineMacro("_REENTRANT");
// Required by the libc++ locale support.
if (Opts.CPlusPlus)
Builder.defineMacro("_GNU_SOURCE");
+ Builder.defineMacro("__Fuchsia_API_level__", Twine(Opts.FuchsiaAPILevel));
+ this->PlatformName = "fuchsia";
+ this->PlatformMinVersion = VersionTuple(Opts.FuchsiaAPILevel);
}
public:
@@ -937,8 +911,7 @@ class LLVM_LIBRARY_VISIBILITY WASITargetInfo
}
public:
- explicit WASITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
- : WebAssemblyOSTargetInfo<Target>(Triple, Opts) {}
+ using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo;
};
// Emscripten target
@@ -948,6 +921,7 @@ class LLVM_LIBRARY_VISIBILITY EmscriptenTargetInfo
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
MacroBuilder &Builder) const final {
WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
+ DefineStd(Builder, "unix", Opts);
Builder.defineMacro("__EMSCRIPTEN__");
if (Opts.POSIXThreads)
Builder.defineMacro("__EMSCRIPTEN_PTHREADS__");
@@ -966,6 +940,66 @@ public:
}
};
+// OHOS target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY OHOSTargetInfo : public OSTargetInfo<Target> {
+protected:
+ void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+ MacroBuilder &Builder) const override {
+ // Linux defines; list based off of gcc output
+ DefineStd(Builder, "unix", Opts);
+
+ // Generic OHOS target defines
+ if (Triple.isOHOSFamily()) {
+ Builder.defineMacro("__OHOS_FAMILY__", "1");
+
+ auto Version = Triple.getEnvironmentVersion();
+ this->PlatformName = "ohos";
+ this->PlatformMinVersion = Version;
+ Builder.defineMacro("__OHOS_Major__", Twine(Version.getMajor()));
+ if (auto Minor = Version.getMinor())
+ Builder.defineMacro("__OHOS_Minor__", Twine(*Minor));
+ if (auto Subminor = Version.getSubminor())
+ Builder.defineMacro("__OHOS_Micro__", Twine(*Subminor));
+ }
+
+ if (Triple.isOpenHOS())
+ Builder.defineMacro("__OHOS__");
+
+ if (Triple.isOSLinux()) {
+ DefineStd(Builder, "linux", Opts);
+ } else if (Triple.isOSLiteOS()) {
+ Builder.defineMacro("__LITEOS__");
+ }
+
+ if (Opts.POSIXThreads)
+ Builder.defineMacro("_REENTRANT");
+ if (Opts.CPlusPlus)
+ Builder.defineMacro("_GNU_SOURCE");
+ if (this->HasFloat128)
+ Builder.defineMacro("__FLOAT128__");
+ }
+
+public:
+ OHOSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : OSTargetInfo<Target>(Triple, Opts) {
+ this->WIntType = TargetInfo::UnsignedInt;
+
+ switch (Triple.getArch()) {
+ default:
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ this->HasFloat128 = true;
+ break;
+ }
+ }
+
+ const char *getStaticInitSectionSpecifier() const override {
+ return ".text.startup";
+ }
+};
+
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp
index 60e9467193a8..51b6452b0c20 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.cpp
@@ -16,10 +16,12 @@
using namespace clang;
using namespace clang::targets;
-ArrayRef<const char *> PNaClTargetInfo::getGCCRegNames() const { return None; }
+ArrayRef<const char *> PNaClTargetInfo::getGCCRegNames() const {
+ return std::nullopt;
+}
ArrayRef<TargetInfo::GCCRegAlias> PNaClTargetInfo::getGCCRegAliases() const {
- return None;
+ return std::nullopt;
}
void PNaClTargetInfo::getArchDefines(const LangOptions &Opts,
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h b/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h
index d5bfc369583f..595c4d83b1d1 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/PNaCl.h
@@ -16,8 +16,8 @@
#include "Mips.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -52,7 +52,9 @@ public:
return Feature == "pnacl";
}
- ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+ return std::nullopt;
+ }
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::PNaClABIBuiltinVaList;
@@ -67,9 +69,9 @@ public:
return false;
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
};
// We attempt to use PNaCl (le32) frontend and Mips32EL backend.
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp
index ecfbe284fb2e..41935abfb65d 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.cpp
@@ -18,11 +18,13 @@
using namespace clang;
using namespace clang::targets;
-const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsPPC.def"
};
@@ -36,6 +38,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasAltivec = true;
} else if (Feature == "+vsx") {
HasVSX = true;
+ } else if (Feature == "+crbits") {
+ UseCRBits = true;
} else if (Feature == "+bpermd") {
HasBPERMD = true;
} else if (Feature == "+extdiv") {
@@ -49,7 +53,7 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
} else if (Feature == "+htm") {
HasHTM = true;
} else if (Feature == "+float128") {
- HasFloat128 = true;
+ HasFloat128 = !getTriple().isOSAIX();
} else if (Feature == "+power9-vector") {
HasP9Vector = true;
} else if (Feature == "+power10-vector") {
@@ -73,12 +77,18 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasROPProtect = true;
} else if (Feature == "+privileged") {
HasPrivileged = true;
+ } else if (Feature == "+aix-small-local-exec-tls") {
+ HasAIXSmallLocalExecTLS = true;
+ } else if (Feature == "+isa-v206-instructions") {
+ IsISA2_06 = true;
} else if (Feature == "+isa-v207-instructions") {
IsISA2_07 = true;
} else if (Feature == "+isa-v30-instructions") {
IsISA3_0 = true;
} else if (Feature == "+isa-v31-instructions") {
IsISA3_1 = true;
+ } else if (Feature == "+quadword-atomics") {
+ HasQuadwordAtomics = true;
}
// TODO: Finish this list and add an assert that we've handled them
// all.
@@ -202,8 +212,10 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
Builder.defineMacro("__darn_32", "__builtin_darn_32");
Builder.defineMacro("__darn_raw", "__builtin_darn_raw");
Builder.defineMacro("__dcbf", "__builtin_dcbf");
+ Builder.defineMacro("__fence", "__builtin_ppc_fence");
Builder.defineMacro("__fmadd", "__builtin_fma");
Builder.defineMacro("__fmadds", "__builtin_fmaf");
+ Builder.defineMacro("__abs", "__builtin_abs");
Builder.defineMacro("__labs", "__builtin_labs");
Builder.defineMacro("__llabs", "__builtin_llabs");
Builder.defineMacro("__popcnt4", "__builtin_popcount");
@@ -236,6 +248,27 @@ static void defineXLCompatMacros(MacroBuilder &Builder) {
Builder.defineMacro("__frsqrtes", "__builtin_ppc_frsqrtes");
Builder.defineMacro("__fsqrt", "__builtin_ppc_fsqrt");
Builder.defineMacro("__fsqrts", "__builtin_ppc_fsqrts");
+ Builder.defineMacro("__addex", "__builtin_ppc_addex");
+ Builder.defineMacro("__cmplxl", "__builtin_complex");
+ Builder.defineMacro("__compare_exp_uo", "__builtin_ppc_compare_exp_uo");
+ Builder.defineMacro("__compare_exp_lt", "__builtin_ppc_compare_exp_lt");
+ Builder.defineMacro("__compare_exp_gt", "__builtin_ppc_compare_exp_gt");
+ Builder.defineMacro("__compare_exp_eq", "__builtin_ppc_compare_exp_eq");
+ Builder.defineMacro("__test_data_class", "__builtin_ppc_test_data_class");
+ Builder.defineMacro("__swdiv", "__builtin_ppc_swdiv");
+ Builder.defineMacro("__swdivs", "__builtin_ppc_swdivs");
+ Builder.defineMacro("__fnabs", "__builtin_ppc_fnabs");
+ Builder.defineMacro("__fnabss", "__builtin_ppc_fnabss");
+ Builder.defineMacro("__builtin_maxfe", "__builtin_ppc_maxfe");
+ Builder.defineMacro("__builtin_maxfl", "__builtin_ppc_maxfl");
+ Builder.defineMacro("__builtin_maxfs", "__builtin_ppc_maxfs");
+ Builder.defineMacro("__builtin_minfe", "__builtin_ppc_minfe");
+ Builder.defineMacro("__builtin_minfl", "__builtin_ppc_minfl");
+ Builder.defineMacro("__builtin_minfs", "__builtin_ppc_minfs");
+ Builder.defineMacro("__builtin_mffs", "__builtin_ppc_mffs");
+ Builder.defineMacro("__builtin_mffsl", "__builtin_ppc_mffsl");
+ Builder.defineMacro("__builtin_mtfsf", "__builtin_ppc_mtfsf");
+ Builder.defineMacro("__builtin_set_fpscr_rn", "__builtin_ppc_set_fpscr_rn");
}
/// PPCTargetInfo::getTargetDefines - Return a set of the PowerPC-specific
@@ -257,8 +290,16 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
if (PointerWidth == 64) {
Builder.defineMacro("_ARCH_PPC64");
Builder.defineMacro("__powerpc64__");
- Builder.defineMacro("__ppc64__");
Builder.defineMacro("__PPC64__");
+ } else if (getTriple().isOSAIX()) {
+ // The XL compilers on AIX define _ARCH_PPC64 for both 32 and 64-bit modes.
+ Builder.defineMacro("_ARCH_PPC64");
+ }
+ if (getTriple().isOSAIX()) {
+ Builder.defineMacro("__THW_PPC__");
+ // Define __PPC and __powerpc for AIX XL C/C++ compatibility
+ Builder.defineMacro("__PPC");
+ Builder.defineMacro("__powerpc");
}
// Target properties.
@@ -304,9 +345,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__LONGDOUBLE64");
}
- // Define this for elfv2 (64-bit only) or 64-bit darwin.
- if (ABI == "elfv2" ||
- (getTriple().getOS() == llvm::Triple::Darwin && PointerWidth == 64))
+ // Define this for elfv2 (64-bit only).
+ if (ABI == "elfv2")
Builder.defineMacro("__STRUCT_PARM_ALIGN__", "16");
if (ArchDefs & ArchDefineName)
@@ -370,8 +410,6 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__MMA__");
if (HasROPProtect)
Builder.defineMacro("__ROP_PROTECT__");
- if (HasPrivileged)
- Builder.defineMacro("__PRIVILEGED__");
if (HasP10Vector)
Builder.defineMacro("__POWER10_VECTOR__");
if (HasPCRelativeMemops)
@@ -419,11 +457,11 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags,
const std::vector<std::string> &FeaturesVec) {
// vsx was not explicitly turned off.
- if (llvm::find(FeaturesVec, "-vsx") == FeaturesVec.end())
+ if (!llvm::is_contained(FeaturesVec, "-vsx"))
return true;
auto FindVSXSubfeature = [&](StringRef Feature, StringRef Option) {
- if (llvm::find(FeaturesVec, Feature) != FeaturesVec.end()) {
+ if (llvm::is_contained(FeaturesVec, Feature)) {
Diags.Report(diag::err_opt_not_valid_with_opt) << Option << "-mno-vsx";
return true;
}
@@ -488,6 +526,11 @@ bool PPCTargetInfo::initFeatureMap(
.Case("pwr9", true)
.Case("pwr8", true)
.Default(false);
+ Features["crbits"] = llvm::StringSwitch<bool>(CPU)
+ .Case("ppc64le", true)
+ .Case("pwr9", true)
+ .Case("pwr8", true)
+ .Default(false);
Features["vsx"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
@@ -505,11 +548,23 @@ bool PPCTargetInfo::initFeatureMap(
// Privileged instructions are off by default.
Features["privileged"] = false;
+ // The code generated by the -maix-small-local-exec-tls option is turned
+ // off by default.
+ Features["aix-small-local-exec-tls"] = false;
+
Features["spe"] = llvm::StringSwitch<bool>(CPU)
.Case("8548", true)
.Case("e500", true)
.Default(false);
+ Features["isa-v206-instructions"] = llvm::StringSwitch<bool>(CPU)
+ .Case("ppc64le", true)
+ .Case("pwr9", true)
+ .Case("pwr8", true)
+ .Case("pwr7", true)
+ .Case("a2", true)
+ .Default(false);
+
Features["isa-v207-instructions"] = llvm::StringSwitch<bool>(CPU)
.Case("ppc64le", true)
.Case("pwr9", true)
@@ -519,6 +574,12 @@ bool PPCTargetInfo::initFeatureMap(
Features["isa-v30-instructions"] =
llvm::StringSwitch<bool>(CPU).Case("pwr9", true).Default(false);
+ Features["quadword-atomics"] =
+ getTriple().isArch64Bit() && llvm::StringSwitch<bool>(CPU)
+ .Case("pwr9", true)
+ .Case("pwr8", true)
+ .Default(false);
+
// Power10 includes all the same features as Power9 plus any features specific
// to the Power10 core.
if (CPU == "pwr10" || CPU == "power10") {
@@ -536,33 +597,63 @@ bool PPCTargetInfo::initFeatureMap(
if (!ppcUserFeaturesCheck(Diags, FeaturesVec))
return false;
- if (!(ArchDefs & ArchDefinePwr9) && (ArchDefs & ArchDefinePpcgr) &&
- llvm::find(FeaturesVec, "+float128") != FeaturesVec.end()) {
- // We have __float128 on PPC but not power 9 and above.
+ if (!(ArchDefs & ArchDefinePwr7) && (ArchDefs & ArchDefinePpcgr) &&
+ llvm::is_contained(FeaturesVec, "+float128")) {
+ // We have __float128 on PPC but not pre-VSX targets.
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" << CPU;
return false;
}
- if (!(ArchDefs & ArchDefinePwr10) &&
- llvm::find(FeaturesVec, "+mma") != FeaturesVec.end()) {
- // We have MMA on PPC but not power 10 and above.
- Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU;
- return false;
+ if (!(ArchDefs & ArchDefinePwr10)) {
+ if (llvm::is_contained(FeaturesVec, "+mma")) {
+ // MMA operations are not available pre-Power10.
+ Diags.Report(diag::err_opt_not_valid_with_opt) << "-mmma" << CPU;
+ return false;
+ }
+ if (llvm::is_contained(FeaturesVec, "+pcrel")) {
+ // PC-Relative instructions are not available pre-Power10,
+ // and these instructions also require prefixed instructions support.
+ Diags.Report(diag::err_opt_not_valid_without_opt)
+ << "-mpcrel"
+ << "-mcpu=pwr10 -mprefixed";
+ return false;
+ }
+ if (llvm::is_contained(FeaturesVec, "+prefixed")) {
+ // Prefixed instructions are not available pre-Power10.
+ Diags.Report(diag::err_opt_not_valid_without_opt) << "-mprefixed"
+ << "-mcpu=pwr10";
+ return false;
+ }
+ if (llvm::is_contained(FeaturesVec, "+paired-vector-memops")) {
+ // Paired vector memops are not available pre-Power10.
+ Diags.Report(diag::err_opt_not_valid_without_opt)
+ << "-mpaired-vector-memops"
+ << "-mcpu=pwr10";
+ return false;
+ }
}
if (!(ArchDefs & ArchDefinePwr8) &&
- llvm::find(FeaturesVec, "+rop-protect") != FeaturesVec.end()) {
+ llvm::is_contained(FeaturesVec, "+rop-protect")) {
// We can turn on ROP Protect on Power 8 and above.
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mrop-protect" << CPU;
return false;
}
if (!(ArchDefs & ArchDefinePwr8) &&
- llvm::find(FeaturesVec, "+privileged") != FeaturesVec.end()) {
+ llvm::is_contained(FeaturesVec, "+privileged")) {
Diags.Report(diag::err_opt_not_valid_with_opt) << "-mprivileged" << CPU;
return false;
}
+ if (llvm::is_contained(FeaturesVec, "+aix-small-local-exec-tls")) {
+ if (!getTriple().isOSAIX() || !getTriple().isArch64Bit()) {
+ Diags.Report(diag::err_opt_not_valid_on_target)
+ << "-maix-small-local-exec-tls";
+ return false;
+ }
+ }
+
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
}
@@ -576,20 +667,18 @@ void PPCTargetInfo::addP10SpecificFeatures(
Features["pcrelative-memops"] = true;
Features["prefix-instrs"] = true;
Features["isa-v31-instructions"] = true;
- return;
}
// Add features specific to the "Future" CPU.
void PPCTargetInfo::addFutureSpecificFeatures(
- llvm::StringMap<bool> &Features) const {
- return;
-}
+ llvm::StringMap<bool> &Features) const {}
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
return llvm::StringSwitch<bool>(Feature)
.Case("powerpc", true)
.Case("altivec", HasAltivec)
.Case("vsx", HasVSX)
+ .Case("crbits", UseCRBits)
.Case("power8-vector", HasP8Vector)
.Case("crypto", HasP8Crypto)
.Case("direct-move", HasDirectMove)
@@ -606,9 +695,12 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
.Case("mma", HasMMA)
.Case("rop-protect", HasROPProtect)
.Case("privileged", HasPrivileged)
+ .Case("aix-small-local-exec-tls", HasAIXSmallLocalExecTLS)
+ .Case("isa-v206-instructions", IsISA2_06)
.Case("isa-v207-instructions", IsISA2_07)
.Case("isa-v30-instructions", IsISA3_0)
.Case("isa-v31-instructions", IsISA3_1)
+ .Case("quadword-atomics", HasQuadwordAtomics)
.Default(false);
}
@@ -666,6 +758,8 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
}
}
+// Make sure that registers are added in the correct array index which should be
+// the DWARF number for PPC registers.
const char *const PPCTargetInfo::GCCRegNames[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
"r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
@@ -683,41 +777,47 @@ const char *const PPCTargetInfo::GCCRegNames[] = {
};
ArrayRef<const char *> PPCTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
const TargetInfo::GCCRegAlias PPCTargetInfo::GCCRegAliases[] = {
// While some of these aliases do map to different registers
// they still share the same register name.
- {{"0"}, "r0"}, {{"1"}, "r1"}, {{"2"}, "r2"}, {{"3"}, "r3"},
- {{"4"}, "r4"}, {{"5"}, "r5"}, {{"6"}, "r6"}, {{"7"}, "r7"},
- {{"8"}, "r8"}, {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"},
- {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"}, {{"15"}, "r15"},
- {{"16"}, "r16"}, {{"17"}, "r17"}, {{"18"}, "r18"}, {{"19"}, "r19"},
- {{"20"}, "r20"}, {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"},
- {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"}, {{"27"}, "r27"},
- {{"28"}, "r28"}, {{"29"}, "r29"}, {{"30"}, "r30"}, {{"31"}, "r31"},
- {{"fr0"}, "f0"}, {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"},
- {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"}, {{"fr7"}, "f7"},
- {{"fr8"}, "f8"}, {{"fr9"}, "f9"}, {{"fr10"}, "f10"}, {{"fr11"}, "f11"},
- {{"fr12"}, "f12"}, {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"},
- {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"}, {{"fr19"}, "f19"},
- {{"fr20"}, "f20"}, {{"fr21"}, "f21"}, {{"fr22"}, "f22"}, {{"fr23"}, "f23"},
- {{"fr24"}, "f24"}, {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"},
- {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"}, {{"fr31"}, "f31"},
- {{"cc"}, "cr0"},
+ {{"0"}, "r0"}, {{"1", "sp"}, "r1"}, {{"2"}, "r2"},
+ {{"3"}, "r3"}, {{"4"}, "r4"}, {{"5"}, "r5"},
+ {{"6"}, "r6"}, {{"7"}, "r7"}, {{"8"}, "r8"},
+ {{"9"}, "r9"}, {{"10"}, "r10"}, {{"11"}, "r11"},
+ {{"12"}, "r12"}, {{"13"}, "r13"}, {{"14"}, "r14"},
+ {{"15"}, "r15"}, {{"16"}, "r16"}, {{"17"}, "r17"},
+ {{"18"}, "r18"}, {{"19"}, "r19"}, {{"20"}, "r20"},
+ {{"21"}, "r21"}, {{"22"}, "r22"}, {{"23"}, "r23"},
+ {{"24"}, "r24"}, {{"25"}, "r25"}, {{"26"}, "r26"},
+ {{"27"}, "r27"}, {{"28"}, "r28"}, {{"29"}, "r29"},
+ {{"30"}, "r30"}, {{"31"}, "r31"}, {{"fr0"}, "f0"},
+ {{"fr1"}, "f1"}, {{"fr2"}, "f2"}, {{"fr3"}, "f3"},
+ {{"fr4"}, "f4"}, {{"fr5"}, "f5"}, {{"fr6"}, "f6"},
+ {{"fr7"}, "f7"}, {{"fr8"}, "f8"}, {{"fr9"}, "f9"},
+ {{"fr10"}, "f10"}, {{"fr11"}, "f11"}, {{"fr12"}, "f12"},
+ {{"fr13"}, "f13"}, {{"fr14"}, "f14"}, {{"fr15"}, "f15"},
+ {{"fr16"}, "f16"}, {{"fr17"}, "f17"}, {{"fr18"}, "f18"},
+ {{"fr19"}, "f19"}, {{"fr20"}, "f20"}, {{"fr21"}, "f21"},
+ {{"fr22"}, "f22"}, {{"fr23"}, "f23"}, {{"fr24"}, "f24"},
+ {{"fr25"}, "f25"}, {{"fr26"}, "f26"}, {{"fr27"}, "f27"},
+ {{"fr28"}, "f28"}, {{"fr29"}, "f29"}, {{"fr30"}, "f30"},
+ {{"fr31"}, "f31"}, {{"cc"}, "cr0"},
};
ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const {
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
-// PPC ELFABIv2 DWARF Definitoin "Table 2.26. Mappings of Common Registers".
+// PPC ELFABIv2 DWARF Definition "Table 2.26. Mappings of Common Registers".
// vs0 ~ vs31 is mapping to 32 - 63,
-// vs32 ~ vs63 is mapping to 77 - 108.
+// vs32 ~ vs63 is mapping to 77 - 108.
+// And this mapping applies to all OSes which run on powerpc.
const TargetInfo::AddlRegName GCCAddlRegNames[] = {
// Table of additional register names to use in user input.
- {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35},
+ {{"vs0"}, 32}, {{"vs1"}, 33}, {{"vs2"}, 34}, {{"vs3"}, 35},
{{"vs4"}, 36}, {{"vs5"}, 37}, {{"vs6"}, 38}, {{"vs7"}, 39},
{{"vs8"}, 40}, {{"vs9"}, 41}, {{"vs10"}, 42}, {{"vs11"}, 43},
{{"vs12"}, 44}, {{"vs13"}, 45}, {{"vs14"}, 46}, {{"vs15"}, 47},
@@ -736,10 +836,7 @@ const TargetInfo::AddlRegName GCCAddlRegNames[] = {
};
ArrayRef<TargetInfo::AddlRegName> PPCTargetInfo::getGCCAddlRegNames() const {
- if (ABI == "elfv2")
- return llvm::makeArrayRef(GCCAddlRegNames);
- else
- return TargetInfo::getGCCAddlRegNames();
+ return llvm::ArrayRef(GCCAddlRegNames);
}
static constexpr llvm::StringLiteral ValidCPUNames[] = {
@@ -756,7 +853,7 @@ static constexpr llvm::StringLiteral ValidCPUNames[] = {
{"powerpc64le"}, {"ppc64le"}, {"future"}};
bool PPCTargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
+ return llvm::is_contained(ValidCPUNames, Name);
}
void PPCTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
@@ -772,9 +869,12 @@ void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
? &llvm::APFloat::IEEEquad()
: &llvm::APFloat::PPCDoubleDouble();
Opts.IEEE128 = 1;
+ if (getTriple().isOSAIX() && Opts.EnableAIXQuadwordAtomicsABI &&
+ HasQuadwordAtomics)
+ MaxAtomicInlineWidth = 128;
}
ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::PPC::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h
index 7c14a4eb9410..4d62673ba7fb 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/PPC.h
@@ -16,9 +16,9 @@
#include "OSTargets.h"
#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"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -50,7 +50,6 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
} ArchDefineTypes;
ArchDefineTypes ArchDefs = ArchDefineNone;
- static const Builtin::Info BuiltinInfo[];
static const char *const GCCRegNames[];
static const TargetInfo::GCCRegAlias GCCRegAliases[];
std::string CPU;
@@ -61,7 +60,9 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
bool HasMMA = false;
bool HasROPProtect = false;
bool HasPrivileged = false;
+ bool HasAIXSmallLocalExecTLS = false;
bool HasVSX = false;
+ bool UseCRBits = false;
bool HasP8Vector = false;
bool HasP8Crypto = false;
bool HasDirectMove = false;
@@ -74,9 +75,11 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
bool HasP10Vector = false;
bool HasPCRelativeMemops = false;
bool HasPrefixInstrs = false;
+ bool IsISA2_06 = false;
bool IsISA2_07 = false;
bool IsISA3_0 = false;
bool IsISA3_1 = false;
+ bool HasQuadwordAtomics = false;
protected:
std::string ABI;
@@ -85,10 +88,10 @@ public:
PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
SuitableAlign = 128;
- SimdDefaultAlign = 128;
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
HasStrictFP = true;
+ HasIbm128 = true;
}
// Set the language option for altivec based on our value.
@@ -195,6 +198,8 @@ public:
void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name,
bool Enabled) const override;
+ bool supportsTargetAttributeTune() const override { return true; }
+
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
@@ -212,7 +217,7 @@ public:
// Don't use floating point registers on soft float ABI.
if (FloatABI == SoftFloat)
return false;
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case 'b': // Base register
Info.setAllowsRegister();
break;
@@ -291,7 +296,7 @@ public:
case 'Q': // Memory operand that is an offset from a register (it is
// usually better to use `m' or `es' in asm statements)
Info.setAllowsRegister();
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case 'Z': // Memory operand that is an indexed or indirect from a
// register (it is usually better to use `m' or `es' in
// asm statements)
@@ -328,7 +333,7 @@ public:
return R;
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
int getEHDataRegisterNumber(unsigned RegNo) const override {
if (RegNo == 0)
return 3;
@@ -347,8 +352,9 @@ public:
: "u9__ieee128";
}
const char *getFloat128Mangling() const override { return "u9__ieee128"; }
+ const char *getIbm128Mangling() const override { return "g"; }
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
bool isSPRegName(StringRef RegName) const override {
return RegName.equals("r1") || RegName.equals("x1");
@@ -360,11 +366,11 @@ public:
PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: PPCTargetInfo(Triple, Opts) {
if (Triple.isOSAIX())
- resetDataLayout("E-m:a-p:32:32-i64:64-n32");
+ resetDataLayout("E-m:a-p:32:32-Fi32-i64:64-n32");
else if (Triple.getArch() == llvm::Triple::ppcle)
- resetDataLayout("e-m:e-p:32:32-i64:64-n32");
+ resetDataLayout("e-m:e-p:32:32-Fn32-i64:64-n32");
else
- resetDataLayout("E-m:e-p:32:32-i64:64-n32");
+ resetDataLayout("E-m:e-p:32:32-Fn32-i64:64-n32");
switch (getTriple().getOS()) {
case llvm::Triple::Linux:
@@ -397,7 +403,7 @@ public:
}
BuiltinVaListKind getBuiltinVaListKind() const override {
- // This is the ELF definition, and is overridden by the Darwin sub-target
+ // This is the ELF definition
return TargetInfo::PowerABIBuiltinVaList;
}
};
@@ -411,20 +417,27 @@ public:
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
IntMaxType = SignedLong;
Int64Type = SignedLong;
- std::string DataLayout = "";
+ std::string DataLayout;
if (Triple.isOSAIX()) {
// TODO: Set appropriate ABI for AIX platform.
- DataLayout = "E-m:a-i64:64-n32:64";
+ DataLayout = "E-m:a-Fi64-i64:64-n32:64";
LongDoubleWidth = 64;
LongDoubleAlign = DoubleAlign = 32;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
} else if ((Triple.getArch() == llvm::Triple::ppc64le)) {
- DataLayout = "e-m:e-i64:64-n32:64";
+ DataLayout = "e-m:e-Fn32-i64:64-n32:64";
ABI = "elfv2";
} else {
- DataLayout = "E-m:e-i64:64-n32:64";
- ABI = "elfv1";
+ DataLayout = "E-m:e";
+ if (Triple.isPPC64ELFv2ABI()) {
+ ABI = "elfv2";
+ DataLayout += "-Fn32";
+ } else {
+ ABI = "elfv1";
+ DataLayout += "-Fi64";
+ }
+ DataLayout += "-i64:64-n32:64";
}
if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) {
@@ -436,8 +449,18 @@ public:
DataLayout += "-S128-v256:256:256-v512:512:512";
resetDataLayout(DataLayout);
- // PPC64 supports atomics up to 8 bytes.
- MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ // Newer PPC64 instruction sets support atomics up to 16 bytes.
+ MaxAtomicPromoteWidth = 128;
+ // Baseline PPC64 supports inlining atomics up to 8 bytes.
+ MaxAtomicInlineWidth = 64;
+ }
+
+ void setMaxAtomicWidth() override {
+ // For power8 and up, backend is able to inline 16-byte atomic lock free
+ // code.
+ // TODO: We should allow AIX to inline quadword atomics in the future.
+ if (!getTriple().isOSAIX() && hasFeature("quadword-atomics"))
+ MaxAtomicInlineWidth = 128;
}
BuiltinVaListKind getBuiltinVaListKind() const override {
@@ -465,33 +488,6 @@ public:
}
};
-class LLVM_LIBRARY_VISIBILITY DarwinPPC32TargetInfo
- : public DarwinTargetInfo<PPC32TargetInfo> {
-public:
- DarwinPPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
- : DarwinTargetInfo<PPC32TargetInfo>(Triple, Opts) {
- HasAlignMac68kSupport = true;
- BoolWidth = BoolAlign = 32; // XXX support -mone-byte-bool?
- PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726
- LongLongAlign = 32;
- resetDataLayout("E-m:o-p:32:32-f64:32:64-n32", "_");
- }
-
- BuiltinVaListKind getBuiltinVaListKind() const override {
- return TargetInfo::CharPtrBuiltinVaList;
- }
-};
-
-class LLVM_LIBRARY_VISIBILITY DarwinPPC64TargetInfo
- : public DarwinTargetInfo<PPC64TargetInfo> {
-public:
- DarwinPPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
- : DarwinTargetInfo<PPC64TargetInfo>(Triple, Opts) {
- HasAlignMac68kSupport = true;
- resetDataLayout("E-m:o-i64:64-n32:64", "_");
- }
-};
-
class LLVM_LIBRARY_VISIBILITY AIXPPC32TargetInfo :
public AIXTargetInfo<PPC32TargetInfo> {
public:
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
index 9705129b39d8..c71b2e9eeb6c 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.cpp
@@ -1,4 +1,4 @@
-//===--- RISCV.cpp - Implement RISCV target feature support ---------------===//
+//===--- RISCV.cpp - Implement RISC-V target feature support --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,20 +6,24 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements RISCV TargetInfo objects.
+// This file implements RISC-V TargetInfo objects.
//
//===----------------------------------------------------------------------===//
#include "RISCV.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetBuiltins.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/TargetParser.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/RISCVTargetParser.h"
+#include <optional>
using namespace clang;
using namespace clang::targets;
ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
+ // clang-format off
static const char *const GCCRegNames[] = {
// Integer registers
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
@@ -37,8 +41,13 @@ ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
- "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
- return llvm::makeArrayRef(GCCRegNames);
+ "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
+
+ // CSRs
+ "fflags", "frm", "vtype", "vl", "vxsat", "vxrm"
+ };
+ // clang-format on
+ return llvm::ArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
@@ -59,7 +68,7 @@ ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
{{"fs4"}, "f20"}, {{"fs5"}, "f21"}, {{"fs6"}, "f22"}, {{"fs7"}, "f23"},
{{"fs8"}, "f24"}, {{"fs9"}, "f25"}, {{"fs10"}, "f26"}, {{"fs11"}, "f27"},
{{"ft8"}, "f28"}, {{"ft9"}, "f29"}, {{"ft10"}, "f30"}, {{"ft11"}, "f31"}};
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
bool RISCVTargetInfo::validateAsmConstraint(
@@ -105,7 +114,7 @@ std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
std::string R;
switch (*Constraint) {
case 'v':
- R = std::string("v");
+ R = std::string("^") + std::string(Constraint, 2);
Constraint += 1;
break;
default:
@@ -115,13 +124,20 @@ std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
return R;
}
+static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) {
+ return MajorVersion * 1000000 + MinorVersion * 1000;
+}
+
void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
- Builder.defineMacro("__ELF__");
Builder.defineMacro("__riscv");
- bool Is64Bit = getTriple().getArch() == llvm::Triple::riscv64;
+ bool Is64Bit = getTriple().isRISCV64();
Builder.defineMacro("__riscv_xlen", Is64Bit ? "64" : "32");
StringRef CodeModel = getTargetOpts().CodeModel;
+ unsigned FLen = ISAInfo->getFLen();
+ unsigned MinVLen = ISAInfo->getMinVLen();
+ unsigned MaxELen = ISAInfo->getMaxELen();
+ unsigned MaxELenFp = ISAInfo->getMaxELenFp();
if (CodeModel == "default")
CodeModel = "small";
@@ -138,21 +154,28 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
else
Builder.defineMacro("__riscv_float_abi_soft");
- if (ABIName == "ilp32e")
+ if (ABIName == "ilp32e" || ABIName == "lp64e")
Builder.defineMacro("__riscv_abi_rve");
Builder.defineMacro("__riscv_arch_test");
- Builder.defineMacro("__riscv_i", "2000000");
- if (HasM) {
- Builder.defineMacro("__riscv_m", "2000000");
+ for (auto &Extension : ISAInfo->getExtensions()) {
+ auto ExtName = Extension.first;
+ auto ExtInfo = Extension.second;
+
+ Builder.defineMacro(Twine("__riscv_", ExtName),
+ Twine(getVersionValue(ExtInfo.Major, ExtInfo.Minor)));
+ }
+
+ if (ISAInfo->hasExtension("m") || ISAInfo->hasExtension("zmmul"))
Builder.defineMacro("__riscv_mul");
+
+ if (ISAInfo->hasExtension("m")) {
Builder.defineMacro("__riscv_div");
Builder.defineMacro("__riscv_muldiv");
}
- if (HasA) {
- Builder.defineMacro("__riscv_a", "2000000");
+ if (ISAInfo->hasExtension("a")) {
Builder.defineMacro("__riscv_atomic");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
@@ -161,218 +184,285 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
}
- if (HasF || HasD) {
- Builder.defineMacro("__riscv_f", "2000000");
- Builder.defineMacro("__riscv_flen", HasD ? "64" : "32");
+ if (FLen) {
+ Builder.defineMacro("__riscv_flen", Twine(FLen));
Builder.defineMacro("__riscv_fdiv");
Builder.defineMacro("__riscv_fsqrt");
}
- if (HasD)
- Builder.defineMacro("__riscv_d", "2000000");
-
- if (HasC) {
- Builder.defineMacro("__riscv_c", "2000000");
- Builder.defineMacro("__riscv_compressed");
+ if (MinVLen) {
+ Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen));
+ Builder.defineMacro("__riscv_v_elen", Twine(MaxELen));
+ Builder.defineMacro("__riscv_v_elen_fp", Twine(MaxELenFp));
}
- if (HasB) {
- Builder.defineMacro("__riscv_b", "93000");
- Builder.defineMacro("__riscv_bitmanip");
- }
+ if (ISAInfo->hasExtension("c"))
+ Builder.defineMacro("__riscv_compressed");
- if (HasV) {
- Builder.defineMacro("__riscv_v", "10000");
+ if (ISAInfo->hasExtension("zve32x")) {
Builder.defineMacro("__riscv_vector");
+ // Currently we support the v0.12 RISC-V V intrinsics.
+ Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 12)));
}
- if (HasZba)
- Builder.defineMacro("__riscv_zba", "93000");
-
- if (HasZbb)
- Builder.defineMacro("__riscv_zbb", "93000");
-
- if (HasZbc)
- Builder.defineMacro("__riscv_zbc", "93000");
-
- if (HasZbe)
- Builder.defineMacro("__riscv_zbe", "93000");
+ auto VScale = getVScaleRange(Opts);
+ if (VScale && VScale->first && VScale->first == VScale->second)
+ Builder.defineMacro("__riscv_v_fixed_vlen",
+ Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock));
- if (HasZbf)
- Builder.defineMacro("__riscv_zbf", "93000");
-
- if (HasZbm)
- Builder.defineMacro("__riscv_zbm", "93000");
-
- if (HasZbp)
- Builder.defineMacro("__riscv_zbp", "93000");
-
- if (HasZbproposedc)
- Builder.defineMacro("__riscv_zbproposedc", "93000");
-
- if (HasZbr)
- Builder.defineMacro("__riscv_zbr", "93000");
-
- if (HasZbs)
- Builder.defineMacro("__riscv_zbs", "93000");
-
- if (HasZbt)
- Builder.defineMacro("__riscv_zbt", "93000");
-
- if (HasZfh)
- Builder.defineMacro("__riscv_zfh", "1000");
-
- if (HasZvamo)
- Builder.defineMacro("__riscv_zvamo", "10000");
+ if (FastUnalignedAccess)
+ Builder.defineMacro("__riscv_misaligned_fast");
+ else
+ Builder.defineMacro("__riscv_misaligned_avoid");
- if (HasZvlsseg)
- Builder.defineMacro("__riscv_zvlsseg", "10000");
+ if (ISAInfo->hasExtension("e")) {
+ if (Is64Bit)
+ Builder.defineMacro("__riscv_64e");
+ else
+ Builder.defineMacro("__riscv_32e");
+ }
}
-const Builtin::Info RISCVTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#include "clang/Basic/BuiltinsRISCVVector.def"
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsRISCV.def"
};
ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::RISCV::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
bool RISCVTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
- if (getTriple().getArch() == llvm::Triple::riscv64)
+ unsigned XLen = 32;
+
+ if (getTriple().isRISCV64()) {
Features["64bit"] = true;
+ XLen = 64;
+ } else {
+ Features["32bit"] = true;
+ }
+
+ // If a target attribute specified a full arch string, override all the ISA
+ // extension target features.
+ const auto I = llvm::find(FeaturesVec, "__RISCV_TargetAttrNeedOverride");
+ if (I != FeaturesVec.end()) {
+ std::vector<std::string> OverrideFeatures(std::next(I), FeaturesVec.end());
+
+ // Add back any non ISA extension features, e.g. +relax.
+ auto IsNonISAExtFeature = [](StringRef Feature) {
+ assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-'));
+ StringRef Ext = Feature.substr(1); // drop the +/-
+ return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext);
+ };
+ llvm::copy_if(llvm::make_range(FeaturesVec.begin(), I),
+ std::back_inserter(OverrideFeatures), IsNonISAExtFeature);
+
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, OverrideFeatures);
+ }
+
+ // Otherwise, parse the features and add any implied extensions.
+ std::vector<std::string> AllFeatures = FeaturesVec;
+ auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesVec);
+ if (!ParseResult) {
+ std::string Buffer;
+ llvm::raw_string_ostream OutputErrMsg(Buffer);
+ handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
+ OutputErrMsg << ErrMsg.getMessage();
+ });
+ Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
+ return false;
+ }
- return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
+ // Append all features, not just new ones, so we override any negatives.
+ llvm::append_range(AllFeatures, (*ParseResult)->toFeatures());
+ return TargetInfo::initFeatureMap(Features, Diags, CPU, AllFeatures);
+}
+
+std::optional<std::pair<unsigned, unsigned>>
+RISCVTargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
+ // RISCV::RVVBitsPerBlock is 64.
+ unsigned VScaleMin = ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock;
+
+ if (LangOpts.VScaleMin || LangOpts.VScaleMax) {
+ // Treat Zvl*b as a lower bound on vscale.
+ VScaleMin = std::max(VScaleMin, LangOpts.VScaleMin);
+ unsigned VScaleMax = LangOpts.VScaleMax;
+ if (VScaleMax != 0 && VScaleMax < VScaleMin)
+ VScaleMax = VScaleMin;
+ return std::pair<unsigned, unsigned>(VScaleMin ? VScaleMin : 1, VScaleMax);
+ }
+
+ if (VScaleMin > 0) {
+ unsigned VScaleMax = ISAInfo->getMaxVLen() / llvm::RISCV::RVVBitsPerBlock;
+ return std::make_pair(VScaleMin, VScaleMax);
+ }
+
+ return std::nullopt;
}
/// 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("64bit", Is64Bit)
- .Case("m", HasM)
- .Case("a", HasA)
- .Case("f", HasF)
- .Case("d", HasD)
- .Case("c", HasC)
- .Case("experimental-b", HasB)
- .Case("experimental-v", HasV)
- .Case("experimental-zba", HasZba)
- .Case("experimental-zbb", HasZbb)
- .Case("experimental-zbc", HasZbc)
- .Case("experimental-zbe", HasZbe)
- .Case("experimental-zbf", HasZbf)
- .Case("experimental-zbm", HasZbm)
- .Case("experimental-zbp", HasZbp)
- .Case("experimental-zbproposedc", HasZbproposedc)
- .Case("experimental-zbr", HasZbr)
- .Case("experimental-zbs", HasZbs)
- .Case("experimental-zbt", HasZbt)
- .Case("experimental-zfh", HasZfh)
- .Case("experimental-zvamo", HasZvamo)
- .Case("experimental-zvlsseg", HasZvlsseg)
- .Default(false);
+ bool Is64Bit = getTriple().isRISCV64();
+ auto Result = llvm::StringSwitch<std::optional<bool>>(Feature)
+ .Case("riscv", true)
+ .Case("riscv32", !Is64Bit)
+ .Case("riscv64", Is64Bit)
+ .Case("32bit", !Is64Bit)
+ .Case("64bit", Is64Bit)
+ .Case("experimental", HasExperimental)
+ .Default(std::nullopt);
+ if (Result)
+ return *Result;
+
+ return ISAInfo->hasExtension(Feature);
}
/// 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;
- else if (Feature == "+experimental-b")
- HasB = true;
- else if (Feature == "+experimental-v")
- HasV = true;
- else if (Feature == "+experimental-zba")
- HasZba = true;
- else if (Feature == "+experimental-zbb")
- HasZbb = true;
- else if (Feature == "+experimental-zbc")
- HasZbc = true;
- else if (Feature == "+experimental-zbe")
- HasZbe = true;
- else if (Feature == "+experimental-zbf")
- HasZbf = true;
- else if (Feature == "+experimental-zbm")
- HasZbm = true;
- else if (Feature == "+experimental-zbp")
- HasZbp = true;
- else if (Feature == "+experimental-zbproposedc")
- HasZbproposedc = true;
- else if (Feature == "+experimental-zbr")
- HasZbr = true;
- else if (Feature == "+experimental-zbs")
- HasZbs = true;
- else if (Feature == "+experimental-zbt")
- HasZbt = true;
- else if (Feature == "+experimental-zfh")
- HasZfh = true;
- else if (Feature == "+experimental-zvamo")
- HasZvamo = true;
- else if (Feature == "+experimental-zvlsseg")
- HasZvlsseg = true;
+ unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
+ auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
+ if (!ParseResult) {
+ std::string Buffer;
+ llvm::raw_string_ostream OutputErrMsg(Buffer);
+ handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
+ OutputErrMsg << ErrMsg.getMessage();
+ });
+ Diags.Report(diag::err_invalid_feature_combination) << OutputErrMsg.str();
+ return false;
+ } else {
+ ISAInfo = std::move(*ParseResult);
}
- return true;
-}
+ if (ABI.empty())
+ ABI = ISAInfo->computeDefaultABI().str();
-bool RISCV32TargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
- /*Is64Bit=*/false);
-}
+ if (ISAInfo->hasExtension("zfh") || ISAInfo->hasExtension("zhinx"))
+ HasLegalHalfType = true;
-void RISCV32TargetInfo::fillValidCPUList(
- SmallVectorImpl<StringRef> &Values) const {
- llvm::RISCV::fillValidCPUArchList(Values, false);
+ FastUnalignedAccess = llvm::is_contained(Features, "+fast-unaligned-access");
+
+ if (llvm::is_contained(Features, "+experimental"))
+ HasExperimental = true;
+
+ if (ABI == "ilp32e" && ISAInfo->hasExtension("d")) {
+ Diags.Report(diag::err_invalid_feature_combination)
+ << "ILP32E cannot be used with the D ISA extension";
+ return false;
+ }
+ return true;
}
-bool RISCV32TargetInfo::isValidTuneCPUName(StringRef Name) const {
- return llvm::RISCV::checkTuneCPUKind(
- llvm::RISCV::parseTuneCPUKind(Name, false),
- /*Is64Bit=*/false);
+bool RISCVTargetInfo::isValidCPUName(StringRef Name) const {
+ bool Is64Bit = getTriple().isArch64Bit();
+ return llvm::RISCV::parseCPU(Name, Is64Bit);
}
-void RISCV32TargetInfo::fillValidTuneCPUList(
+void RISCVTargetInfo::fillValidCPUList(
SmallVectorImpl<StringRef> &Values) const {
- llvm::RISCV::fillValidTuneCPUArchList(Values, false);
+ bool Is64Bit = getTriple().isArch64Bit();
+ llvm::RISCV::fillValidCPUArchList(Values, Is64Bit);
}
-bool RISCV64TargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
- /*Is64Bit=*/true);
+bool RISCVTargetInfo::isValidTuneCPUName(StringRef Name) const {
+ bool Is64Bit = getTriple().isArch64Bit();
+ return llvm::RISCV::parseTuneCPU(Name, Is64Bit);
}
-void RISCV64TargetInfo::fillValidCPUList(
+void RISCVTargetInfo::fillValidTuneCPUList(
SmallVectorImpl<StringRef> &Values) const {
- llvm::RISCV::fillValidCPUArchList(Values, true);
+ bool Is64Bit = getTriple().isArch64Bit();
+ llvm::RISCV::fillValidTuneCPUArchList(Values, Is64Bit);
}
-bool RISCV64TargetInfo::isValidTuneCPUName(StringRef Name) const {
- return llvm::RISCV::checkTuneCPUKind(
- llvm::RISCV::parseTuneCPUKind(Name, true),
- /*Is64Bit=*/true);
+static void handleFullArchString(StringRef FullArchStr,
+ std::vector<std::string> &Features) {
+ Features.push_back("__RISCV_TargetAttrNeedOverride");
+ auto RII = llvm::RISCVISAInfo::parseArchString(
+ FullArchStr, /* EnableExperimentalExtension */ true);
+ if (llvm::errorToBool(RII.takeError())) {
+ // Forward the invalid FullArchStr.
+ Features.push_back("+" + FullArchStr.str());
+ } else {
+ // Append a full list of features, including any negative extensions so that
+ // we override the CPU's features.
+ std::vector<std::string> FeatStrings =
+ (*RII)->toFeatures(/* AddAllExtensions */ true);
+ Features.insert(Features.end(), FeatStrings.begin(), FeatStrings.end());
+ }
}
-void RISCV64TargetInfo::fillValidTuneCPUList(
- SmallVectorImpl<StringRef> &Values) const {
- llvm::RISCV::fillValidTuneCPUArchList(Values, true);
+ParsedTargetAttr RISCVTargetInfo::parseTargetAttr(StringRef Features) const {
+ ParsedTargetAttr Ret;
+ if (Features == "default")
+ return Ret;
+ SmallVector<StringRef, 1> AttrFeatures;
+ Features.split(AttrFeatures, ";");
+ bool FoundArch = false;
+
+ for (auto &Feature : AttrFeatures) {
+ Feature = Feature.trim();
+ StringRef AttrString = Feature.split("=").second.trim();
+
+ if (Feature.starts_with("arch=")) {
+ // Override last features
+ Ret.Features.clear();
+ if (FoundArch)
+ Ret.Duplicate = "arch=";
+ FoundArch = true;
+
+ if (AttrString.starts_with("+")) {
+ // EXTENSION like arch=+v,+zbb
+ SmallVector<StringRef, 1> Exts;
+ AttrString.split(Exts, ",");
+ for (auto Ext : Exts) {
+ if (Ext.empty())
+ continue;
+
+ StringRef ExtName = Ext.substr(1);
+ std::string TargetFeature =
+ llvm::RISCVISAInfo::getTargetFeatureForExtension(ExtName);
+ if (!TargetFeature.empty())
+ Ret.Features.push_back(Ext.front() + TargetFeature);
+ else
+ Ret.Features.push_back(Ext.str());
+ }
+ } else {
+ // full-arch-string like arch=rv64gcv
+ handleFullArchString(AttrString, Ret.Features);
+ }
+ } else if (Feature.starts_with("cpu=")) {
+ if (!Ret.CPU.empty())
+ Ret.Duplicate = "cpu=";
+
+ Ret.CPU = AttrString;
+
+ if (!FoundArch) {
+ // Update Features with CPU's features
+ StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(Ret.CPU);
+ if (MarchFromCPU != "") {
+ Ret.Features.clear();
+ handleFullArchString(MarchFromCPU, Ret.Features);
+ }
+ }
+ } else if (Feature.starts_with("tune=")) {
+ if (!Ret.Tune.empty())
+ Ret.Duplicate = "tune=";
+
+ Ret.Tune = AttrString;
+ }
+ }
+ return Ret;
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
index 7e0846581ca1..bfbdafb682c8 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/RISCV.h
@@ -1,4 +1,4 @@
-//===--- RISCV.h - Declare RISCV target feature support ---------*- C++ -*-===//
+//===--- RISCV.h - Declare RISC-V target feature support --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares RISCV TargetInfo objects.
+// This file declares RISC-V TargetInfo objects.
//
//===----------------------------------------------------------------------===//
@@ -15,8 +15,10 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/RISCVISAInfo.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
namespace clang {
namespace targets {
@@ -25,33 +27,18 @@ namespace targets {
class RISCVTargetInfo : public TargetInfo {
protected:
std::string ABI, CPU;
- bool HasM = false;
- bool HasA = false;
- bool HasF = false;
- bool HasD = false;
- bool HasC = false;
- bool HasB = false;
- bool HasV = false;
- bool HasZba = false;
- bool HasZbb = false;
- bool HasZbc = false;
- bool HasZbe = false;
- bool HasZbf = false;
- bool HasZbm = false;
- bool HasZbp = false;
- bool HasZbproposedc = false;
- bool HasZbr = false;
- bool HasZbs = false;
- bool HasZbt = false;
- bool HasZfh = false;
- bool HasZvamo = false;
- bool HasZvlsseg = false;
-
- static const Builtin::Info BuiltinInfo[];
+ std::unique_ptr<llvm::RISCVISAInfo> ISAInfo;
+
+private:
+ bool FastUnalignedAccess;
+ bool HasExperimental = false;
public:
RISCVTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
+ BFloat16Width = 16;
+ BFloat16Align = 16;
+ BFloat16Format = &llvm::APFloat::BFloat();
LongDoubleWidth = 128;
LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::IEEEquad();
@@ -61,6 +48,7 @@ public:
HasRISCVVTypes = true;
MCountName = "_mcount";
HasFloat16 = true;
+ HasStrictFP = true;
}
bool setCPU(const std::string &Name) override {
@@ -80,7 +68,12 @@ public:
return TargetInfo::VoidPtrBuiltinVaList;
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
+
+ StringRef getConstraintRegister(StringRef Constraint,
+ StringRef Expression) const override {
+ return Expression;
+ }
ArrayRef<const char *> getGCCRegNames() const override;
@@ -105,12 +98,28 @@ public:
StringRef CPU,
const std::vector<std::string> &FeaturesVec) const override;
+ std::optional<std::pair<unsigned, unsigned>>
+ getVScaleRange(const LangOptions &LangOpts) const override;
+
bool hasFeature(StringRef Feature) const override;
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override;
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
+
+ bool hasBFloat16Type() const override { return true; }
+
+ bool useFP16ConversionIntrinsics() const override {
+ return false;
+ }
+
+ bool isValidCPUName(StringRef Name) const override;
+ void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+ bool isValidTuneCPUName(StringRef Name) const override;
+ void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
+ bool supportsTargetAttributeTune() const override { return true; }
+ ParsedTargetAttr parseTargetAttr(StringRef Str) const override;
};
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
public:
@@ -123,6 +132,12 @@ public:
}
bool setABI(const std::string &Name) override {
+ if (Name == "ilp32e") {
+ ABI = Name;
+ resetDataLayout("e-m:e-p:32:32-i64:64-n32-S32");
+ return true;
+ }
+
if (Name == "ilp32" || Name == "ilp32f" || Name == "ilp32d") {
ABI = Name;
return true;
@@ -130,15 +145,10 @@ public:
return false;
}
- bool isValidCPUName(StringRef Name) const override;
- void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
- bool isValidTuneCPUName(StringRef Name) const override;
- void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
-
void setMaxAtomicWidth() override {
MaxAtomicPromoteWidth = 128;
- if (HasA)
+ if (ISAInfo->hasExtension("a"))
MaxAtomicInlineWidth = 32;
}
};
@@ -148,10 +158,16 @@ public:
: RISCVTargetInfo(Triple, Opts) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
IntMaxType = Int64Type = SignedLong;
- resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128");
+ resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
}
bool setABI(const std::string &Name) override {
+ if (Name == "lp64e") {
+ ABI = Name;
+ resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S64");
+ return true;
+ }
+
if (Name == "lp64" || Name == "lp64f" || Name == "lp64d") {
ABI = Name;
return true;
@@ -159,15 +175,10 @@ public:
return false;
}
- bool isValidCPUName(StringRef Name) const override;
- void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
- bool isValidTuneCPUName(StringRef Name) const override;
- void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
-
void setMaxAtomicWidth() override {
MaxAtomicPromoteWidth = 128;
- if (HasA)
+ if (ISAInfo->hasExtension("a"))
MaxAtomicInlineWidth = 64;
}
};
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp
index 9b7aab85314a..dc920177d3a9 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.cpp
@@ -1,4 +1,4 @@
-//===--- SPIR.cpp - Implement SPIR target feature support -----------------===//
+//===--- SPIR.cpp - Implement SPIR and SPIR-V target feature support ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements SPIR TargetInfo objects.
+// This file implements SPIR and SPIR-V TargetInfo objects.
//
//===----------------------------------------------------------------------===//
@@ -32,3 +32,25 @@ void SPIR64TargetInfo::getTargetDefines(const LangOptions &Opts,
SPIRTargetInfo::getTargetDefines(Opts, Builder);
DefineStd(Builder, "SPIR64", Opts);
}
+
+void BaseSPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "SPIRV", Opts);
+}
+
+void SPIRVTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
+}
+
+void SPIRV32TargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
+ DefineStd(Builder, "SPIRV32", Opts);
+}
+
+void SPIRV64TargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ BaseSPIRVTargetInfo::getTargetDefines(Opts, Builder);
+ DefineStd(Builder, "SPIRV64", Opts);
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
index 50f34abd6630..fa4a3bb1c82e 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h
@@ -1,4 +1,4 @@
-//===--- SPIR.h - Declare SPIR target feature support -----------*- C++ -*-===//
+//===--- SPIR.h - Declare SPIR and SPIR-V target feature support *- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,21 +6,25 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares SPIR TargetInfo objects.
+// This file declares SPIR and SPIR-V TargetInfo objects.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
#define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
+#include "Targets.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/TargetParser/Triple.h"
+#include <optional>
namespace clang {
namespace targets {
+// Used by both the SPIR and SPIR-V targets.
static const unsigned SPIRDefIsPrivMap[] = {
0, // Default
1, // opencl_global
@@ -41,9 +45,14 @@ static const unsigned SPIRDefIsPrivMap[] = {
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ 0, // hlsl_groupshared
+ // Wasm address space values for this target are dummy values,
+ // as it is only enabled for Wasm targets.
+ 20, // wasm_funcref
};
+// Used by both the SPIR and SPIR-V targets.
static const unsigned SPIRDefIsGenMap[] = {
4, // Default
// OpenCL address space values for this map are dummy and they can't be used
@@ -54,9 +63,14 @@ static const unsigned SPIRDefIsGenMap[] = {
0, // opencl_generic
0, // opencl_global_device
0, // opencl_global_host
- 0, // cuda_device
- 0, // cuda_constant
- 0, // cuda_shared
+ // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V
+ // translation). This mapping is enabled when the language mode is HIP.
+ 1, // cuda_device
+ // cuda_constant pointer can be casted to default/"flat" pointer, but in
+ // SPIR-V casts between constant and generic pointers are not allowed. For
+ // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.
+ 1, // cuda_constant
+ 3, // cuda_shared
1, // sycl_global
5, // sycl_global_device
6, // sycl_global_host
@@ -64,17 +78,22 @@ static const unsigned SPIRDefIsGenMap[] = {
0, // sycl_private
0, // ptr32_sptr
0, // ptr32_uptr
- 0 // ptr64
+ 0, // ptr64
+ 0, // hlsl_groupshared
+ // Wasm address space values for this target are dummy values,
+ // as it is only enabled for Wasm targets.
+ 20, // wasm_funcref
};
-class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
-public:
- SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
+// Base class for SPIR and SPIR-V target info.
+class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
+ std::unique_ptr<TargetInfo> HostTarget;
+
+protected:
+ BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: TargetInfo(Triple) {
- assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
- "SPIR target must use unknown OS");
- assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
- "SPIR target must use unknown environment type");
+ assert((Triple.isSPIR() || Triple.isSPIRV()) &&
+ "Invalid architecture for SPIR or SPIR-V.");
TLSSupported = false;
VLASupported = false;
LongWidth = LongAlign = 64;
@@ -85,24 +104,68 @@ public:
// Define available target features
// These must be defined in sorted order!
NoAsmVariants = true;
- }
- void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const override;
+ llvm::Triple HostTriple(Opts.HostTriple);
+ if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() &&
+ HostTriple.getArch() != llvm::Triple::UnknownArch) {
+ HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);
- bool hasFeature(StringRef Feature) const override {
- return Feature == "spir";
+ // Copy properties from host target.
+ BoolWidth = HostTarget->getBoolWidth();
+ BoolAlign = HostTarget->getBoolAlign();
+ IntWidth = HostTarget->getIntWidth();
+ IntAlign = HostTarget->getIntAlign();
+ HalfWidth = HostTarget->getHalfWidth();
+ HalfAlign = HostTarget->getHalfAlign();
+ FloatWidth = HostTarget->getFloatWidth();
+ FloatAlign = HostTarget->getFloatAlign();
+ DoubleWidth = HostTarget->getDoubleWidth();
+ DoubleAlign = HostTarget->getDoubleAlign();
+ LongWidth = HostTarget->getLongWidth();
+ LongAlign = HostTarget->getLongAlign();
+ LongLongWidth = HostTarget->getLongLongWidth();
+ LongLongAlign = HostTarget->getLongLongAlign();
+ MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
+ NewAlign = HostTarget->getNewAlign();
+ DefaultAlignForAttributeAligned =
+ HostTarget->getDefaultAlignForAttributeAligned();
+ IntMaxType = HostTarget->getIntMaxType();
+ WCharType = HostTarget->getWCharType();
+ WIntType = HostTarget->getWIntType();
+ Char16Type = HostTarget->getChar16Type();
+ Char32Type = HostTarget->getChar32Type();
+ Int64Type = HostTarget->getInt64Type();
+ SigAtomicType = HostTarget->getSigAtomicType();
+ ProcessIDType = HostTarget->getProcessIDType();
+
+ UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
+ UseZeroLengthBitfieldAlignment =
+ HostTarget->useZeroLengthBitfieldAlignment();
+ UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
+ ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
+
+ // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
+ // we need those macros to be identical on host and device, because (among
+ // other things) they affect which standard library classes are defined,
+ // and we need all classes to be defined on both the host and device.
+ MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
+ }
}
+public:
// 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; }
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+ return std::nullopt;
+ }
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
- ArrayRef<const char *> getGCCRegNames() const override { return None; }
+ ArrayRef<const char *> getGCCRegNames() const override {
+ return std::nullopt;
+ }
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override {
@@ -110,14 +173,14 @@ public:
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
- Optional<unsigned>
+ std::optional<unsigned>
getDWARFAddressSpace(unsigned AddressSpace) const override {
return AddressSpace;
}
@@ -140,28 +203,56 @@ public:
// FIXME: SYCL specification considers unannotated pointers and references
// to be pointing to the generic address space. See section 5.9.3 of
// SYCL 2020 specification.
- // Currently, there is no way of representing SYCL's default address space
- // language semantic along with the semantics of embedded C's default
- // address space in the same address space map. Hence the map needs to be
- // reset to allow mapping to the desired value of 'Default' entry for SYCL.
- setAddressSpaceMap(/*DefaultIsGeneric=*/Opts.SYCLIsDevice);
+ // Currently, there is no way of representing SYCL's and HIP/CUDA's default
+ // address space language semantic along with the semantics of embedded C's
+ // default address space in the same address space map. Hence the map needs
+ // to be reset to allow mapping to the desired value of 'Default' entry for
+ // SYCL and HIP/CUDA.
+ setAddressSpaceMap(
+ /*DefaultIsGeneric=*/Opts.SYCLIsDevice ||
+ // The address mapping from HIP/CUDA language for device code is only
+ // defined for SPIR-V.
+ (getTriple().isSPIRV() && Opts.CUDAIsDevice));
}
void setSupportedOpenCLOpts() override {
// Assume all OpenCL extensions and optional core features are supported
- // for SPIR since it is a generic target.
+ // for SPIR and SPIR-V since they are generic targets.
supportAllOpenCLOpts();
}
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
bool hasInt128Type() const override { return false; }
};
+class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
+public:
+ SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRTargetInfo(Triple, Opts) {
+ assert(Triple.isSPIR() && "Invalid architecture for SPIR.");
+ assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
+ "SPIR target must use unknown OS");
+ assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
+ "SPIR target must use unknown environment type");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+
+ bool hasFeature(StringRef Feature) const override {
+ return Feature == "spir";
+ }
+
+ bool checkArithmeticFenceSupported() const override { return true; }
+};
+
class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
public:
SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: SPIRTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spir &&
+ "Invalid architecture for 32-bit SPIR.");
PointerWidth = PointerAlign = 32;
SizeType = TargetInfo::UnsignedInt;
PtrDiffType = IntPtrType = TargetInfo::SignedInt;
@@ -177,6 +268,8 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
public:
SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: SPIRTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spir64 &&
+ "Invalid architecture for 64-bit SPIR.");
PointerWidth = PointerAlign = 64;
SizeType = TargetInfo::UnsignedLong;
PtrDiffType = IntPtrType = TargetInfo::SignedLong;
@@ -187,6 +280,87 @@ public:
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
+
+class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {
+public:
+ BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRTargetInfo(Triple, Opts) {
+ assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
+ }
+
+ bool hasFeature(StringRef Feature) const override {
+ return Feature == "spirv";
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
+public:
+ SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRVTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spirv &&
+ "Invalid architecture for Logical SPIR-V.");
+ assert(Triple.getOS() == llvm::Triple::Vulkan &&
+ Triple.getVulkanVersion() != llvm::VersionTuple(0) &&
+ "Logical SPIR-V requires a valid Vulkan environment.");
+ assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&
+ Triple.getEnvironment() <= llvm::Triple::Amplification &&
+ "Logical SPIR-V environment must be a valid shader stage.");
+
+ // SPIR-V IDs are represented with a single 32-bit word.
+ SizeType = TargetInfo::UnsignedInt;
+ resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
+ "v96:128-v192:256-v256:256-v512:512-v1024:1024");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {
+public:
+ SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRVTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spirv32 &&
+ "Invalid architecture for 32-bit SPIR-V.");
+ assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
+ "32-bit SPIR-V target must use unknown OS");
+ assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
+ "32-bit SPIR-V target must use unknown environment type");
+ PointerWidth = PointerAlign = 32;
+ SizeType = TargetInfo::UnsignedInt;
+ PtrDiffType = IntPtrType = TargetInfo::SignedInt;
+ resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
+ "v96:128-v192:256-v256:256-v512:512-v1024:1024");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
+class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
+public:
+ SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : BaseSPIRVTargetInfo(Triple, Opts) {
+ assert(Triple.getArch() == llvm::Triple::spirv64 &&
+ "Invalid architecture for 64-bit SPIR-V.");
+ assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
+ "64-bit SPIR-V target must use unknown OS");
+ assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
+ "64-bit SPIR-V target must use unknown environment type");
+ PointerWidth = PointerAlign = 64;
+ SizeType = TargetInfo::UnsignedLong;
+ PtrDiffType = IntPtrType = TargetInfo::SignedLong;
+ resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
+ "v96:128-v192:256-v256:256-v512:512-v1024:1024");
+ }
+
+ void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const override;
+};
+
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp
index 5eeb77406c34..d1a891092b0f 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.cpp
@@ -33,7 +33,7 @@ const char *const SparcTargetInfo::GCCRegNames[] = {
};
ArrayRef<const char *> SparcTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
@@ -48,7 +48,7 @@ const TargetInfo::GCCRegAlias SparcTargetInfo::GCCRegAliases[] = {
};
ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const {
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
bool SparcTargetInfo::hasFeature(StringRef Feature) const {
@@ -93,12 +93,6 @@ static constexpr SparcCPUInfo CPUInfo[] = {
{{"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},
@@ -147,7 +141,7 @@ void SparcTargetInfo::getTargetDefines(const LangOptions &Opts,
void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
SparcTargetInfo::getTargetDefines(Opts, Builder);
- if (getTriple().getOS() == llvm::Triple::Solaris)
+ if (getTriple().isOSSolaris())
Builder.defineMacro("__sparcv8");
else {
switch (getCPUGeneration(CPU)) {
@@ -156,78 +150,10 @@ void SparcV8TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__sparcv8__");
break;
case CG_V9:
- Builder.defineMacro("__sparcv9");
- Builder.defineMacro("__sparcv9__");
Builder.defineMacro("__sparc_v9__");
break;
}
}
- if (getTriple().getVendor() == llvm::Triple::Myriad) {
- std::string MyriadArchValue, Myriad2Value;
- Builder.defineMacro("__sparc_v8__");
- Builder.defineMacro("__leon__");
- switch (CPU) {
- case CK_MYRIAD2100:
- MyriadArchValue = "__ma2100";
- Myriad2Value = "1";
- break;
- case CK_MYRIAD2150:
- MyriadArchValue = "__ma2150";
- Myriad2Value = "2";
- break;
- case CK_MYRIAD2155:
- MyriadArchValue = "__ma2155";
- Myriad2Value = "2";
- break;
- case CK_MYRIAD2450:
- MyriadArchValue = "__ma2450";
- Myriad2Value = "2";
- break;
- case CK_MYRIAD2455:
- MyriadArchValue = "__ma2455";
- Myriad2Value = "2";
- break;
- case CK_MYRIAD2x5x:
- Myriad2Value = "2";
- break;
- case CK_MYRIAD2080:
- MyriadArchValue = "__ma2080";
- Myriad2Value = "3";
- break;
- case CK_MYRIAD2085:
- MyriadArchValue = "__ma2085";
- Myriad2Value = "3";
- break;
- case CK_MYRIAD2480:
- MyriadArchValue = "__ma2480";
- Myriad2Value = "3";
- break;
- case CK_MYRIAD2485:
- MyriadArchValue = "__ma2485";
- Myriad2Value = "3";
- break;
- case CK_MYRIAD2x8x:
- Myriad2Value = "3";
- break;
- default:
- MyriadArchValue = "__ma2100";
- Myriad2Value = "1";
- break;
- }
- if (!MyriadArchValue.empty()) {
- 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);
- }
if (getCPUGeneration(CPU) == CG_V9) {
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
@@ -242,7 +168,7 @@ void SparcV9TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__sparcv9");
Builder.defineMacro("__arch64__");
// Solaris doesn't need these variants, but the BSDs do.
- if (getTriple().getOS() != llvm::Triple::Solaris) {
+ if (!getTriple().isOSSolaris()) {
Builder.defineMacro("__sparc64__");
Builder.defineMacro("__sparc_v9__");
Builder.defineMacro("__sparcv9__");
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h
index 07844abafe11..214fef88e1dc 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h
@@ -14,8 +14,8 @@
#define LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
// Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).
@@ -39,10 +39,8 @@ public:
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override {
// Check if software floating point is enabled
- auto Feature = llvm::find(Features, "+soft-float");
- if (Feature != Features.end()) {
+ if (llvm::is_contained(Features, "+soft-float"))
SoftFloat = true;
- }
return true;
}
void getTargetDefines(const LangOptions &Opts,
@@ -50,11 +48,9 @@ public:
bool hasFeature(StringRef Feature) const override;
- bool hasSjLjLowering() const override { return true; }
-
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
// FIXME: Implement!
- return None;
+ return std::nullopt;
}
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
@@ -81,7 +77,7 @@ public:
}
return false;
}
- const char *getClobbers() const override {
+ std::string_view getClobbers() const override {
// FIXME: Implement!
return "";
}
@@ -180,8 +176,7 @@ public:
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
- bool hasSjLjLowering() const override { return true; }
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
};
// SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.
@@ -234,7 +229,7 @@ public:
return getCPUGeneration(CPU) == CG_V9;
}
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp
index e3e0da21f8d5..a9b5ca483861 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.cpp
@@ -20,11 +20,11 @@
using namespace clang;
using namespace clang::targets;
-const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsSystemZ.def"
};
@@ -46,11 +46,11 @@ const TargetInfo::AddlRegName GCCAddlRegNames[] = {
};
ArrayRef<const char *> SystemZTargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::AddlRegName> SystemZTargetInfo::getGCCAddlRegNames() const {
- return llvm::makeArrayRef(GCCAddlRegNames);
+ return llvm::ArrayRef(GCCAddlRegNames);
}
bool SystemZTargetInfo::validateAsmConstraint(
@@ -59,6 +59,17 @@ bool SystemZTargetInfo::validateAsmConstraint(
default:
return false;
+ case 'Z':
+ switch (Name[1]) {
+ default:
+ return false;
+ case 'Q': // Address with base and unsigned 12-bit displacement
+ case 'R': // Likewise, plus an index
+ case 'S': // Address with base and signed 20-bit displacement
+ case 'T': // Likewise, plus an index
+ break;
+ }
+ [[fallthrough]];
case 'a': // Address register
case 'd': // Data register (equivalent to 'r')
case 'f': // Floating-point register
@@ -93,7 +104,7 @@ static constexpr ISANameRevision ISARevisions[] = {
{{"arch11"}, 11}, {{"z13"}, 11},
{{"arch12"}, 12}, {{"z14"}, 12},
{{"arch13"}, 13}, {{"z15"}, 13},
- {{"arch14"}, 14}
+ {{"arch14"}, 14}, {{"z16"}, 14},
};
int SystemZTargetInfo::getISARevision(StringRef Name) const {
@@ -150,6 +161,6 @@ void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts,
}
ArrayRef<Builtin::Info> SystemZTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin -
+ Builtin::FirstTSBuiltin);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h b/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h
index b749c3f75d18..e4ec338880f2 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/SystemZ.h
@@ -15,15 +15,14 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
static const char *const GCCRegNames[];
std::string CPU;
int ISARevision;
@@ -37,17 +36,31 @@ public:
HasTransactionalExecution(false), HasVector(false), SoftFloat(false) {
IntMaxType = SignedLong;
Int64Type = SignedLong;
- TLSSupported = true;
IntWidth = IntAlign = 32;
LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
+ Int128Align = 64;
PointerWidth = PointerAlign = 64;
LongDoubleWidth = 128;
LongDoubleAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEquad();
DefaultAlignForAttributeAligned = 64;
MinGlobalAlign = 16;
- resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64");
- MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+ if (Triple.isOSzOS()) {
+ TLSSupported = false;
+ // All vector types are default aligned on an 8-byte boundary, even if the
+ // vector facility is not available. That is different from Linux.
+ MaxVectorAlign = 64;
+ // Compared to Linux/ELF, the data layout differs only in some details:
+ // - name mangling is GOFF.
+ // - 32 bit pointers, either as default or special address space
+ resetDataLayout("E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
+ "a:8:16-n32:64");
+ } else {
+ TLSSupported = true;
+ resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"
+ "-v128:64-a:8:16-n32:64");
+ }
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128;
HasStrictFP = true;
}
@@ -60,7 +73,7 @@ public:
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
// No aliases.
- return None;
+ return std::nullopt;
}
ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
@@ -72,7 +85,31 @@ public:
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override;
- const char *getClobbers() const override {
+ std::string convertConstraint(const char *&Constraint) const override {
+ switch (Constraint[0]) {
+ case 'p': // Keep 'p' constraint.
+ return std::string("p");
+ case 'Z':
+ switch (Constraint[1]) {
+ case 'Q': // Address with base and unsigned 12-bit displacement
+ case 'R': // Likewise, plus an index
+ case 'S': // Address with base and signed 20-bit displacement
+ case 'T': // Likewise, plus an index
+ // "^" hints llvm that this is a 2 letter constraint.
+ // "Constraint++" is used to promote the string iterator
+ // to the next constraint.
+ return std::string("^") + std::string(Constraint++, 2);
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return TargetInfo::convertConstraint(Constraint);
+ }
+
+ std::string_view getClobbers() const override {
// FIXME: Is this really right?
return "";
}
@@ -89,6 +126,14 @@ public:
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
+ bool isValidTuneCPUName(StringRef Name) const override {
+ return isValidCPUName(Name);
+ }
+
+ void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override {
+ fillValidCPUList(Values);
+ }
+
bool setCPU(const std::string &Name) override {
CPU = Name;
ISARevision = getISARevision(CPU);
@@ -128,12 +173,14 @@ public:
}
HasVector &= !SoftFloat;
- // If we use the vector ABI, vector types are 64-bit aligned.
- if (HasVector) {
+ // If we use the vector ABI, vector types are 64-bit aligned. The
+ // DataLayout string is always set to this alignment as it is not a
+ // requirement that it follows the alignment emitted by the front end. It
+ // is assumed generally that the Datalayout should reflect only the
+ // target triple and not any specific feature.
+ if (HasVector && !getTriple().isOSzOS())
MaxVectorAlign = 64;
- resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"
- "-v128:64-a:8:16-n32:64");
- }
+
return true;
}
@@ -160,7 +207,7 @@ public:
const char *getLongDoubleMangling() const override { return "g"; }
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
int getEHDataRegisterNumber(unsigned RegNo) const override {
return RegNo < 4 ? 6 + RegNo : -1;
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/TCE.h b/contrib/llvm-project/clang/lib/Basic/Targets/TCE.h
index 251b4d4b56f7..dcf684fe6dbc 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/TCE.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/TCE.h
@@ -15,8 +15,8 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
@@ -50,6 +50,10 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
0, // ptr32_sptr
0, // ptr32_uptr
0, // ptr64
+ 0, // hlsl_groupshared
+ // Wasm address space values for this target are dummy values,
+ // as it is only enabled for Wasm targets.
+ 20, // wasm_funcref
};
class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo {
@@ -91,15 +95,19 @@ public:
bool hasFeature(StringRef Feature) const override { return Feature == "tce"; }
- ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
+ ArrayRef<Builtin::Info> getTargetBuiltins() const override {
+ return std::nullopt;
+ }
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
}
- ArrayRef<const char *> getGCCRegNames() const override { return None; }
+ ArrayRef<const char *> getGCCRegNames() const override {
+ return std::nullopt;
+ }
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override {
@@ -107,7 +115,7 @@ public:
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
};
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp
index 22223654e8ad..67cae8faf605 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/VE.cpp
@@ -18,22 +18,28 @@
using namespace clang;
using namespace clang::targets;
+static constexpr Builtin::Info BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#include "clang/Basic/BuiltinsVE.def"
+};
+
void VETargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
- Builder.defineMacro("_LP64", "1");
- Builder.defineMacro("unix", "1");
- Builder.defineMacro("__unix__", "1");
- Builder.defineMacro("__linux__", "1");
Builder.defineMacro("__ve", "1");
Builder.defineMacro("__ve__", "1");
- Builder.defineMacro("__STDC_HOSTED__", "1");
- Builder.defineMacro("__STDC__", "1");
Builder.defineMacro("__NEC__", "1");
// FIXME: define __FAST_MATH__ 1 if -ffast-math is enabled
// FIXME: define __OPTIMIZE__ n if -On is enabled
// FIXME: define __VECTOR__ n 1 if automatic vectorization is enabled
+
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
}
ArrayRef<Builtin::Info> VETargetInfo::getTargetBuiltins() const {
- return ArrayRef<Builtin::Info>();
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/VE.h b/contrib/llvm-project/clang/lib/Basic/Targets/VE.h
index 71d6fc08d859..ea9a092cad80 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/VE.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/VE.h
@@ -15,14 +15,13 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
public:
VETargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -70,7 +69,7 @@ public:
}
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
ArrayRef<const char *> getGCCRegNames() const override {
static const char *const GCCRegNames[] = {
@@ -84,7 +83,7 @@ public:
"sx48", "sx49", "sx50", "sx51", "sx52", "sx53", "sx54", "sx55",
"sx56", "sx57", "sx58", "sx59", "sx60", "sx61", "sx62", "sx63",
};
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
@@ -154,7 +153,7 @@ public:
{{"s62"}, "sx62"},
{{"s63"}, "sx63"},
};
- return llvm::makeArrayRef(GCCRegAliases);
+ return llvm::ArrayRef(GCCRegAliases);
}
bool validateAsmConstraint(const char *&Name,
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp
index 7ef79849cb75..f1c925d90cb6 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.cpp
@@ -20,13 +20,13 @@
using namespace clang;
using namespace clang::targets;
-const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsWebAssembly.def"
};
@@ -46,6 +46,7 @@ bool WebAssemblyTargetInfo::setABI(const std::string &Name) {
bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
return llvm::StringSwitch<bool>(Feature)
.Case("simd128", SIMDLevel >= SIMD128)
+ .Case("relaxed-simd", SIMDLevel >= RelaxedSIMD)
.Case("nontrapping-fptoint", HasNontrappingFPToInt)
.Case("sign-ext", HasSignExt)
.Case("exception-handling", HasExceptionHandling)
@@ -55,11 +56,13 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
.Case("multivalue", HasMultivalue)
.Case("tail-call", HasTailCall)
.Case("reference-types", HasReferenceTypes)
+ .Case("extended-const", HasExtendedConst)
+ .Case("multimemory", HasMultiMemory)
.Default(false);
}
bool WebAssemblyTargetInfo::isValidCPUName(StringRef Name) const {
- return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames);
+ return llvm::is_contained(ValidCPUNames, Name);
}
void WebAssemblyTargetInfo::fillValidCPUList(
@@ -72,6 +75,8 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
defineCPUMacros(Builder, "wasm", /*Tuning=*/false);
if (SIMDLevel >= SIMD128)
Builder.defineMacro("__wasm_simd128__");
+ if (SIMDLevel >= RelaxedSIMD)
+ Builder.defineMacro("__wasm_relaxed_simd__");
if (HasNontrappingFPToInt)
Builder.defineMacro("__wasm_nontrapping_fptoint__");
if (HasSignExt)
@@ -90,15 +95,27 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__wasm_tail_call__");
if (HasReferenceTypes)
Builder.defineMacro("__wasm_reference_types__");
+ if (HasExtendedConst)
+ Builder.defineMacro("__wasm_extended_const__");
+ if (HasMultiMemory)
+ Builder.defineMacro("__wasm_multimemory__");
+
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
}
void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features,
SIMDEnum Level, bool Enabled) {
if (Enabled) {
switch (Level) {
+ case RelaxedSIMD:
+ Features["relaxed-simd"] = true;
+ [[fallthrough]];
case SIMD128:
Features["simd128"] = true;
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case NoSIMD:
break;
}
@@ -109,6 +126,9 @@ void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap<bool> &Features,
case NoSIMD:
case SIMD128:
Features["simd128"] = false;
+ [[fallthrough]];
+ case RelaxedSIMD:
+ Features["relaxed-simd"] = false;
break;
}
}
@@ -118,6 +138,8 @@ void WebAssemblyTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
bool Enabled) const {
if (Name == "simd128")
setSIMDLevel(Features, SIMD128, Enabled);
+ else if (Name == "relaxed-simd")
+ setSIMDLevel(Features, RelaxedSIMD, Enabled);
else
Features[Name] = Enabled;
}
@@ -132,7 +154,12 @@ bool WebAssemblyTargetInfo::initFeatureMap(
Features["atomics"] = true;
Features["mutable-globals"] = true;
Features["tail-call"] = true;
+ Features["reference-types"] = true;
+ Features["multimemory"] = true;
setSIMDLevel(Features, SIMD128, true);
+ } else if (CPU == "generic") {
+ Features["sign-ext"] = true;
+ Features["mutable-globals"] = true;
}
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
@@ -149,6 +176,14 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
SIMDLevel = std::min(SIMDLevel, SIMDEnum(SIMD128 - 1));
continue;
}
+ if (Feature == "+relaxed-simd") {
+ SIMDLevel = std::max(SIMDLevel, RelaxedSIMD);
+ continue;
+ }
+ if (Feature == "-relaxed-simd") {
+ SIMDLevel = std::min(SIMDLevel, SIMDEnum(RelaxedSIMD - 1));
+ continue;
+ }
if (Feature == "+nontrapping-fptoint") {
HasNontrappingFPToInt = true;
continue;
@@ -221,6 +256,22 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
HasReferenceTypes = false;
continue;
}
+ if (Feature == "+extended-const") {
+ HasExtendedConst = true;
+ continue;
+ }
+ if (Feature == "-extended-const") {
+ HasExtendedConst = false;
+ continue;
+ }
+ if (Feature == "+multimemory") {
+ HasMultiMemory = true;
+ continue;
+ }
+ if (Feature == "-multimemory") {
+ HasMultiMemory = false;
+ continue;
+ }
Diags.Report(diag::err_opt_not_valid_with_opt)
<< Feature << "-target-feature";
@@ -230,17 +281,20 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
}
ArrayRef<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
+ Builtin::FirstTSBuiltin);
}
void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags,
LangOptions &Opts) {
- // If the Atomics feature isn't available, turn off POSIXThreads and
- // ThreadModel, so that we don't predefine _REENTRANT or __STDCPP_THREADS__.
- if (!HasAtomics) {
+ TargetInfo::adjust(Diags, Opts);
+ // Turn off POSIXThreads and ThreadModel so that we don't predefine _REENTRANT
+ // or __STDCPP_THREADS__ if we will eventually end up stripping atomics
+ // because they are unsupported.
+ if (!HasAtomics || !HasBulkMemory) {
Opts.POSIXThreads = false;
Opts.setThreadModel(LangOptions::ThreadModelKind::Single);
+ Opts.ThreadsafeStatics = false;
}
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h b/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h
index 4a5ba25c75e7..83b1711f9fdf 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/WebAssembly.h
@@ -15,18 +15,42 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
+static const unsigned WebAssemblyAddrSpaceMap[] = {
+ 0, // Default
+ 0, // opencl_global
+ 0, // opencl_local
+ 0, // opencl_constant
+ 0, // opencl_private
+ 0, // opencl_generic
+ 0, // opencl_global_device
+ 0, // opencl_global_host
+ 0, // cuda_device
+ 0, // cuda_constant
+ 0, // cuda_shared
+ 0, // sycl_global
+ 0, // sycl_global_device
+ 0, // sycl_global_host
+ 0, // sycl_local
+ 0, // sycl_private
+ 0, // ptr32_sptr
+ 0, // ptr32_uptr
+ 0, // ptr64
+ 0, // hlsl_groupshared
+ 20, // wasm_funcref
+};
+
class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
enum SIMDEnum {
NoSIMD,
SIMD128,
+ RelaxedSIMD,
} SIMDLevel = NoSIMD;
bool HasNontrappingFPToInt = false;
@@ -38,17 +62,19 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
bool HasMultivalue = false;
bool HasTailCall = false;
bool HasReferenceTypes = false;
+ bool HasExtendedConst = false;
+ bool HasMultiMemory = false;
std::string ABI;
public:
explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
: TargetInfo(T) {
+ AddrSpaceMap = &WebAssemblyAddrSpaceMap;
NoAsmVariants = true;
SuitableAlign = 128;
LargeArrayMinWidth = 128;
LargeArrayAlign = 128;
- SimdDefaultAlign = 128;
SigAtomicType = SignedLong;
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::IEEEquad();
@@ -94,10 +120,10 @@ private:
return VoidPtrBuiltinVaList;
}
- ArrayRef<const char *> getGCCRegNames() const final { return None; }
+ ArrayRef<const char *> getGCCRegNames() const final { return std::nullopt; }
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const final {
- return None;
+ return std::nullopt;
}
bool validateAsmConstraint(const char *&Name,
@@ -105,7 +131,7 @@ private:
return false;
}
- const char *getClobbers() const final { return ""; }
+ std::string_view getClobbers() const final { return ""; }
bool isCLZForZeroUndef() const final { return false; }
@@ -136,7 +162,7 @@ private:
}
}
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
bool hasProtectedVisibility() const override { return false; }
@@ -150,9 +176,11 @@ public:
const TargetOptions &Opts)
: WebAssemblyTargetInfo(T, Opts) {
if (T.isOSEmscripten())
- resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32:64-S128-ni:1:10:20");
+ resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
+ "S128-ni:1:10:20");
else
- resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20");
+ resetDataLayout(
+ "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
}
protected:
@@ -172,9 +200,11 @@ public:
PtrDiffType = SignedLong;
IntPtrType = SignedLong;
if (T.isOSEmscripten())
- resetDataLayout("e-m:e-p:64:64-i64:64-f128:64-n32:64-S128-ni:1:10:20");
+ resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-"
+ "S128-ni:1:10:20");
else
- resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128-ni:1:10:20");
+ resetDataLayout(
+ "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20");
}
protected:
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp
index 9db96c20250f..a68b662d9401 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/X86.cpp
@@ -17,26 +17,27 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/X86TargetParser.h"
+#include "llvm/TargetParser/X86TargetParser.h"
+#include <optional>
namespace clang {
namespace targets {
-const Builtin::Info BuiltinInfoX86[] = {
+static constexpr Builtin::Info BuiltinInfoX86[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
- {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
#include "clang/Basic/BuiltinsX86.def"
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
- {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
+ {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
#include "clang/Basic/BuiltinsX86_64.def"
};
@@ -118,6 +119,14 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabled(Features, F, true);
std::vector<std::string> UpdatedFeaturesVec;
+ std::vector<std::string> UpdatedAVX10FeaturesVec;
+ enum { FE_NOSET = -1, FE_FALSE, FE_TRUE };
+ int HasEVEX512 = FE_NOSET;
+ bool HasAVX512F = Features.lookup("avx512f");
+ bool HasAVX10 = Features.lookup("avx10.1-256");
+ bool HasAVX10_512 = Features.lookup("avx10.1-512");
+ std::string LastAVX10;
+ std::string LastAVX512;
for (const auto &Feature : FeaturesVec) {
// Expand general-regs-only to -x86, -mmx and -sse
if (Feature == "+general-regs-only") {
@@ -127,8 +136,51 @@ bool X86TargetInfo::initFeatureMap(
continue;
}
+ if (Feature.substr(1, 6) == "avx10.") {
+ if (Feature[0] == '+') {
+ HasAVX10 = true;
+ if (Feature.substr(Feature.size() - 3, 3) == "512")
+ HasAVX10_512 = true;
+ LastAVX10 = Feature;
+ } else if (HasAVX10 && Feature == "-avx10.1-256") {
+ HasAVX10 = false;
+ HasAVX10_512 = false;
+ } else if (HasAVX10_512 && Feature == "-avx10.1-512") {
+ HasAVX10_512 = false;
+ }
+ // Postpone AVX10 features handling after AVX512 settled.
+ UpdatedAVX10FeaturesVec.push_back(Feature);
+ continue;
+ } else if (!HasAVX512F && Feature.substr(0, 7) == "+avx512") {
+ HasAVX512F = true;
+ LastAVX512 = Feature;
+ } else if (HasAVX512F && Feature == "-avx512f") {
+ HasAVX512F = false;
+ } else if (HasEVEX512 != FE_TRUE && Feature == "+evex512") {
+ HasEVEX512 = FE_TRUE;
+ continue;
+ } else if (HasEVEX512 != FE_FALSE && Feature == "-evex512") {
+ HasEVEX512 = FE_FALSE;
+ continue;
+ }
+
UpdatedFeaturesVec.push_back(Feature);
}
+ llvm::append_range(UpdatedFeaturesVec, UpdatedAVX10FeaturesVec);
+ // HasEVEX512 is a three-states flag. We need to turn it into [+-]evex512
+ // according to other features.
+ if (HasAVX512F) {
+ UpdatedFeaturesVec.push_back(HasEVEX512 == FE_FALSE ? "-evex512"
+ : "+evex512");
+ if (HasAVX10 && !HasAVX10_512 && HasEVEX512 != FE_FALSE)
+ Diags.Report(diag::warn_invalid_feature_combination)
+ << LastAVX512 + " " + LastAVX10 + "; will be promoted to avx10.1-512";
+ } else if (HasAVX10) {
+ if (HasEVEX512 != FE_NOSET)
+ Diags.Report(diag::warn_invalid_feature_combination)
+ << LastAVX10 + (HasEVEX512 == FE_TRUE ? " +evex512" : " -evex512");
+ UpdatedFeaturesVec.push_back(HasAVX10_512 ? "+evex512" : "-evex512");
+ }
if (!TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec))
return false;
@@ -139,22 +191,28 @@ bool X86TargetInfo::initFeatureMap(
// Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled.
auto I = Features.find("sse4.2");
if (I != Features.end() && I->getValue() &&
- llvm::find(UpdatedFeaturesVec, "-popcnt") == UpdatedFeaturesVec.end())
+ !llvm::is_contained(UpdatedFeaturesVec, "-popcnt"))
Features["popcnt"] = true;
// Additionally, if SSE is enabled and mmx is not explicitly disabled,
// then enable MMX.
I = Features.find("sse");
if (I != Features.end() && I->getValue() &&
- llvm::find(UpdatedFeaturesVec, "-mmx") == UpdatedFeaturesVec.end())
+ !llvm::is_contained(UpdatedFeaturesVec, "-mmx"))
Features["mmx"] = true;
// Enable xsave if avx is enabled and xsave is not explicitly disabled.
I = Features.find("avx");
if (I != Features.end() && I->getValue() &&
- llvm::find(UpdatedFeaturesVec, "-xsave") == UpdatedFeaturesVec.end())
+ !llvm::is_contained(UpdatedFeaturesVec, "-xsave"))
Features["xsave"] = true;
+ // Enable CRC32 if SSE4.2 is enabled and CRC32 is not explicitly disabled.
+ I = Features.find("sse4.2");
+ if (I != Features.end() && I->getValue() &&
+ !llvm::is_contained(UpdatedFeaturesVec, "-crc32"))
+ Features["crc32"] = true;
+
return true;
}
@@ -221,6 +279,12 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasF16C = true;
} else if (Feature == "+gfni") {
HasGFNI = true;
+ } else if (Feature == "+evex512") {
+ HasEVEX512 = true;
+ } else if (Feature == "+avx10.1-256") {
+ HasAVX10_1 = true;
+ } else if (Feature == "+avx10.1-512") {
+ HasAVX10_1_512 = true;
} else if (Feature == "+avx512cd") {
HasAVX512CD = true;
} else if (Feature == "+avx512vpopcntdq") {
@@ -231,8 +295,13 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasAVX512BF16 = true;
} else if (Feature == "+avx512er") {
HasAVX512ER = true;
+ Diags.Report(diag::warn_knl_knm_isa_support_removed);
+ } else if (Feature == "+avx512fp16") {
+ HasAVX512FP16 = true;
+ HasLegalHalfType = true;
} else if (Feature == "+avx512pf") {
HasAVX512PF = true;
+ Diags.Report(diag::warn_knl_knm_isa_support_removed);
} else if (Feature == "+avx512dq") {
HasAVX512DQ = true;
} else if (Feature == "+avx512bitalg") {
@@ -251,8 +320,14 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasAVX512VP2INTERSECT = true;
} else if (Feature == "+sha") {
HasSHA = true;
+ } else if (Feature == "+sha512") {
+ HasSHA512 = true;
} else if (Feature == "+shstk") {
HasSHSTK = true;
+ } else if (Feature == "+sm3") {
+ HasSM3 = true;
+ } else if (Feature == "+sm4") {
+ HasSM4 = true;
} else if (Feature == "+movbe") {
HasMOVBE = true;
} else if (Feature == "+sgx") {
@@ -281,14 +356,19 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasCLWB = true;
} else if (Feature == "+wbnoinvd") {
HasWBNOINVD = true;
+ } else if (Feature == "+prefetchi") {
+ HasPREFETCHI = true;
} else if (Feature == "+prefetchwt1") {
HasPREFETCHWT1 = true;
+ Diags.Report(diag::warn_knl_knm_isa_support_removed);
} else if (Feature == "+clzero") {
HasCLZERO = true;
} else if (Feature == "+cldemote") {
HasCLDEMOTE = true;
} else if (Feature == "+rdpid") {
HasRDPID = true;
+ } else if (Feature == "+rdpru") {
+ HasRDPRU = true;
} else if (Feature == "+kl") {
HasKL = true;
} else if (Feature == "+widekl") {
@@ -315,18 +395,54 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasHRESET = true;
} else if (Feature == "+amx-bf16") {
HasAMXBF16 = true;
+ } else if (Feature == "+amx-fp16") {
+ HasAMXFP16 = true;
} else if (Feature == "+amx-int8") {
HasAMXINT8 = true;
} else if (Feature == "+amx-tile") {
HasAMXTILE = true;
+ } else if (Feature == "+amx-complex") {
+ HasAMXCOMPLEX = true;
+ } else if (Feature == "+cmpccxadd") {
+ HasCMPCCXADD = true;
+ } else if (Feature == "+raoint") {
+ HasRAOINT = true;
+ } else if (Feature == "+avxifma") {
+ HasAVXIFMA = true;
+ } else if (Feature == "+avxneconvert") {
+ HasAVXNECONVERT= true;
} else if (Feature == "+avxvnni") {
HasAVXVNNI = true;
+ } else if (Feature == "+avxvnniint16") {
+ HasAVXVNNIINT16 = true;
+ } else if (Feature == "+avxvnniint8") {
+ HasAVXVNNIINT8 = true;
} else if (Feature == "+serialize") {
HasSERIALIZE = true;
} else if (Feature == "+tsxldtrk") {
HasTSXLDTRK = true;
} else if (Feature == "+uintr") {
HasUINTR = true;
+ } else if (Feature == "+usermsr") {
+ HasUSERMSR = true;
+ } else if (Feature == "+crc32") {
+ HasCRC32 = true;
+ } else if (Feature == "+x87") {
+ HasX87 = true;
+ } else if (Feature == "+fullbf16") {
+ HasFullBFloat16 = true;
+ } else if (Feature == "+egpr") {
+ HasEGPR = true;
+ } else if (Feature == "+push2pop2") {
+ HasPush2Pop2 = true;
+ } else if (Feature == "+ppx") {
+ HasPPX = true;
+ } else if (Feature == "+ndd") {
+ HasNDD = true;
+ } else if (Feature == "+ccmp") {
+ HasCCMP = true;
+ } else if (Feature == "+cf") {
+ HasCF = true;
}
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
@@ -342,6 +458,19 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
.Default(NoSSE);
SSELevel = std::max(SSELevel, Level);
+ HasFloat16 = SSELevel >= SSE2;
+
+ // X86 target has bfloat16 emulation support in the backend, where
+ // bfloat16 is treated as a 32-bit float, arithmetic operations are
+ // performed in 32-bit, and the result is converted back to bfloat16.
+ // Truncation and extension between bfloat16 and 32-bit float are supported
+ // by the compiler-rt library. However, native bfloat16 support is currently
+ // not available in the X86 target. Hence, HasFullBFloat16 will be false
+ // until native bfloat16 support is available. HasFullBFloat16 is used to
+ // determine whether to automatically use excess floating point precision
+ // for bfloat16 arithmetic operations in the front-end.
+ HasBFloat16 = SSELevel >= SSE2;
+
MMX3DNowEnum ThreeDNowLevel = llvm::StringSwitch<MMX3DNowEnum>(Feature)
.Case("+3dnowa", AMD3DNowAthlon)
.Case("+3dnow", AMD3DNow)
@@ -366,8 +495,11 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
return false;
}
- SimdDefaultAlign =
- hasFeature("avx512f") ? 512 : hasFeature("avx") ? 256 : 128;
+ // FIXME: We should allow long double type on 32-bits to match with GCC.
+ // This requires backend to be able to lower f80 without x87 first.
+ if (!HasX87 && LongDoubleFormat == &llvm::APFloat::x87DoubleExtended())
+ HasLongDouble = false;
+
return true;
}
@@ -422,7 +554,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_PentiumMMX:
Builder.defineMacro("__pentium_mmx__");
Builder.defineMacro("__tune_pentium_mmx__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case CK_i586:
case CK_Pentium:
defineCPUMacros(Builder, "i586");
@@ -431,11 +563,11 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Pentium3:
case CK_PentiumM:
Builder.defineMacro("__tune_pentium3__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case CK_Pentium2:
case CK_C3_2:
Builder.defineMacro("__tune_pentium2__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case CK_PentiumPro:
case CK_i686:
defineCPUMacros(Builder, "i686");
@@ -468,6 +600,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Tremont:
defineCPUMacros(Builder, "tremont");
break;
+ // Gracemont and later atom-cores use P-core cpu macros.
+ case CK_Gracemont:
case CK_Nehalem:
case CK_Westmere:
case CK_SandyBridge:
@@ -485,6 +619,18 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_Tigerlake:
case CK_SapphireRapids:
case CK_Alderlake:
+ case CK_Raptorlake:
+ case CK_Meteorlake:
+ case CK_Arrowlake:
+ case CK_ArrowlakeS:
+ case CK_Lunarlake:
+ case CK_Pantherlake:
+ case CK_Sierraforest:
+ case CK_Grandridge:
+ case CK_Graniterapids:
+ case CK_GraniterapidsD:
+ case CK_Emeraldrapids:
+ case CK_Clearwaterforest:
// 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.
@@ -503,7 +649,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_K6_2:
Builder.defineMacro("__k6_2__");
Builder.defineMacro("__tune_k6_2__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case CK_K6_3:
if (CPU != CK_K6_2) { // In case of fallthrough
// FIXME: GCC may be enabling these in cases where some other k6
@@ -512,7 +658,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__k6_3__");
Builder.defineMacro("__tune_k6_3__");
}
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case CK_K6:
defineCPUMacros(Builder, "k6");
break;
@@ -563,6 +709,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
case CK_ZNVER3:
defineCPUMacros(Builder, "znver3");
break;
+ case CK_ZNVER4:
+ defineCPUMacros(Builder, "znver4");
+ break;
case CK_Geode:
defineCPUMacros(Builder, "geode");
break;
@@ -638,13 +787,13 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
switch (XOPLevel) {
case XOP:
Builder.defineMacro("__XOP__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case FMA4:
Builder.defineMacro("__FMA4__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case SSE4A:
Builder.defineMacro("__SSE4A__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case NoXOP:
break;
}
@@ -658,6 +807,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasGFNI)
Builder.defineMacro("__GFNI__");
+ if (HasEVEX512)
+ Builder.defineMacro("__EVEX512__");
+ if (HasAVX10_1)
+ Builder.defineMacro("__AVX10_1__");
+ if (HasAVX10_1_512)
+ Builder.defineMacro("__AVX10_1_512__");
if (HasAVX512CD)
Builder.defineMacro("__AVX512CD__");
if (HasAVX512VPOPCNTDQ)
@@ -668,6 +823,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__AVX512BF16__");
if (HasAVX512ER)
Builder.defineMacro("__AVX512ER__");
+ if (HasAVX512FP16)
+ Builder.defineMacro("__AVX512FP16__");
if (HasAVX512PF)
Builder.defineMacro("__AVX512PF__");
if (HasAVX512DQ)
@@ -676,8 +833,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__AVX512BITALG__");
if (HasAVX512BW)
Builder.defineMacro("__AVX512BW__");
- if (HasAVX512VL)
+ if (HasAVX512VL) {
Builder.defineMacro("__AVX512VL__");
+ Builder.defineMacro("__EVEX256__");
+ }
if (HasAVX512VBMI)
Builder.defineMacro("__AVX512VBMI__");
if (HasAVX512VBMI2)
@@ -688,6 +847,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__AVX512VP2INTERSECT__");
if (HasSHA)
Builder.defineMacro("__SHA__");
+ if (HasSHA512)
+ Builder.defineMacro("__SHA512__");
if (HasFXSR)
Builder.defineMacro("__FXSR__");
@@ -711,6 +872,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__SHSTK__");
if (HasSGX)
Builder.defineMacro("__SGX__");
+ if (HasSM3)
+ Builder.defineMacro("__SM3__");
+ if (HasSM4)
+ Builder.defineMacro("__SM4__");
+ if (HasPREFETCHI)
+ Builder.defineMacro("__PREFETCHI__");
if (HasPREFETCHWT1)
Builder.defineMacro("__PREFETCHWT1__");
if (HasCLZERO)
@@ -721,6 +888,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__WIDEKL__");
if (HasRDPID)
Builder.defineMacro("__RDPID__");
+ if (HasRDPRU)
+ Builder.defineMacro("__RDPRU__");
if (HasCLDEMOTE)
Builder.defineMacro("__CLDEMOTE__");
if (HasWAITPKG)
@@ -740,51 +909,83 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasHRESET)
Builder.defineMacro("__HRESET__");
if (HasAMXTILE)
- Builder.defineMacro("__AMXTILE__");
+ Builder.defineMacro("__AMX_TILE__");
if (HasAMXINT8)
- Builder.defineMacro("__AMXINT8__");
+ Builder.defineMacro("__AMX_INT8__");
if (HasAMXBF16)
- Builder.defineMacro("__AMXBF16__");
+ Builder.defineMacro("__AMX_BF16__");
+ if (HasAMXFP16)
+ Builder.defineMacro("__AMX_FP16__");
+ if (HasAMXCOMPLEX)
+ Builder.defineMacro("__AMX_COMPLEX__");
+ if (HasCMPCCXADD)
+ Builder.defineMacro("__CMPCCXADD__");
+ if (HasRAOINT)
+ Builder.defineMacro("__RAOINT__");
+ if (HasAVXIFMA)
+ Builder.defineMacro("__AVXIFMA__");
+ if (HasAVXNECONVERT)
+ Builder.defineMacro("__AVXNECONVERT__");
if (HasAVXVNNI)
Builder.defineMacro("__AVXVNNI__");
+ if (HasAVXVNNIINT16)
+ Builder.defineMacro("__AVXVNNIINT16__");
+ if (HasAVXVNNIINT8)
+ Builder.defineMacro("__AVXVNNIINT8__");
if (HasSERIALIZE)
Builder.defineMacro("__SERIALIZE__");
if (HasTSXLDTRK)
Builder.defineMacro("__TSXLDTRK__");
if (HasUINTR)
Builder.defineMacro("__UINTR__");
+ if (HasUSERMSR)
+ Builder.defineMacro("__USERMSR__");
+ if (HasCRC32)
+ Builder.defineMacro("__CRC32__");
+ if (HasEGPR)
+ Builder.defineMacro("__EGPR__");
+ if (HasPush2Pop2)
+ Builder.defineMacro("__PUSH2POP2__");
+ if (HasPPX)
+ Builder.defineMacro("__PPX__");
+ if (HasNDD)
+ Builder.defineMacro("__NDD__");
+ if (HasCCMP)
+ Builder.defineMacro("__CCMP__");
+ if (HasCF)
+ Builder.defineMacro("__CF__");
// Each case falls through to the previous one here.
switch (SSELevel) {
case AVX512F:
Builder.defineMacro("__AVX512F__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case AVX2:
Builder.defineMacro("__AVX2__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case AVX:
Builder.defineMacro("__AVX__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case SSE42:
Builder.defineMacro("__SSE4_2__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case SSE41:
Builder.defineMacro("__SSE4_1__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case SSSE3:
Builder.defineMacro("__SSSE3__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case SSE3:
Builder.defineMacro("__SSE3__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case SSE2:
Builder.defineMacro("__SSE2__");
Builder.defineMacro("__SSE2_MATH__"); // -mfp-math=sse always implied.
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case SSE1:
Builder.defineMacro("__SSE__");
Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case NoSSE:
break;
}
@@ -814,13 +1015,13 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
switch (MMX3DNowLevel) {
case AMD3DNowAthlon:
Builder.defineMacro("__3dNOW_A__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case AMD3DNow:
Builder.defineMacro("__3dNOW__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case MMX:
Builder.defineMacro("__MMX__");
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
case NoMMX3DNow:
break;
}
@@ -846,9 +1047,13 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("adx", true)
.Case("aes", true)
.Case("amx-bf16", true)
+ .Case("amx-complex", true)
+ .Case("amx-fp16", true)
.Case("amx-int8", true)
.Case("amx-tile", true)
.Case("avx", true)
+ .Case("avx10.1-256", true)
+ .Case("avx10.1-512", true)
.Case("avx2", true)
.Case("avx512f", true)
.Case("avx512cd", true)
@@ -856,6 +1061,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("avx512vnni", true)
.Case("avx512bf16", true)
.Case("avx512er", true)
+ .Case("avx512fp16", true)
.Case("avx512pf", true)
.Case("avx512dq", true)
.Case("avx512bitalg", true)
@@ -865,15 +1071,22 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("avx512vbmi2", true)
.Case("avx512ifma", true)
.Case("avx512vp2intersect", true)
+ .Case("avxifma", true)
+ .Case("avxneconvert", true)
.Case("avxvnni", true)
+ .Case("avxvnniint16", true)
+ .Case("avxvnniint8", true)
.Case("bmi", true)
.Case("bmi2", true)
.Case("cldemote", true)
.Case("clflushopt", true)
.Case("clwb", true)
.Case("clzero", true)
+ .Case("cmpccxadd", true)
+ .Case("crc32", true)
.Case("cx16", true)
.Case("enqcmd", true)
+ .Case("evex512", true)
.Case("f16c", true)
.Case("fma", true)
.Case("fma4", true)
@@ -896,10 +1109,13 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("pconfig", true)
.Case("pku", true)
.Case("popcnt", true)
+ .Case("prefetchi", true)
.Case("prefetchwt1", true)
.Case("prfchw", true)
.Case("ptwrite", true)
+ .Case("raoint", true)
.Case("rdpid", true)
+ .Case("rdpru", true)
.Case("rdrnd", true)
.Case("rdseed", true)
.Case("rtm", true)
@@ -907,7 +1123,10 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("serialize", true)
.Case("sgx", true)
.Case("sha", true)
+ .Case("sha512", true)
.Case("shstk", true)
+ .Case("sm3", true)
+ .Case("sm4", true)
.Case("sse", true)
.Case("sse2", true)
.Case("sse3", true)
@@ -919,6 +1138,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("tbm", true)
.Case("tsxldtrk", true)
.Case("uintr", true)
+ .Case("usermsr", true)
.Case("vaes", true)
.Case("vpclmulqdq", true)
.Case("wbnoinvd", true)
@@ -929,6 +1149,12 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("xsavec", true)
.Case("xsaves", true)
.Case("xsaveopt", true)
+ .Case("egpr", true)
+ .Case("push2pop2", true)
+ .Case("ppx", true)
+ .Case("ndd", true)
+ .Case("ccmp", true)
+ .Case("cf", true)
.Default(false);
}
@@ -937,10 +1163,13 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("adx", HasADX)
.Case("aes", HasAES)
.Case("amx-bf16", HasAMXBF16)
+ .Case("amx-complex", HasAMXCOMPLEX)
+ .Case("amx-fp16", HasAMXFP16)
.Case("amx-int8", HasAMXINT8)
.Case("amx-tile", HasAMXTILE)
- .Case("avxvnni", HasAVXVNNI)
.Case("avx", SSELevel >= AVX)
+ .Case("avx10.1-256", HasAVX10_1)
+ .Case("avx10.1-512", HasAVX10_1_512)
.Case("avx2", SSELevel >= AVX2)
.Case("avx512f", SSELevel >= AVX512F)
.Case("avx512cd", HasAVX512CD)
@@ -948,6 +1177,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("avx512vnni", HasAVX512VNNI)
.Case("avx512bf16", HasAVX512BF16)
.Case("avx512er", HasAVX512ER)
+ .Case("avx512fp16", HasAVX512FP16)
.Case("avx512pf", HasAVX512PF)
.Case("avx512dq", HasAVX512DQ)
.Case("avx512bitalg", HasAVX512BITALG)
@@ -957,15 +1187,23 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("avx512vbmi2", HasAVX512VBMI2)
.Case("avx512ifma", HasAVX512IFMA)
.Case("avx512vp2intersect", HasAVX512VP2INTERSECT)
+ .Case("avxifma", HasAVXIFMA)
+ .Case("avxneconvert", HasAVXNECONVERT)
+ .Case("avxvnni", HasAVXVNNI)
+ .Case("avxvnniint16", HasAVXVNNIINT16)
+ .Case("avxvnniint8", HasAVXVNNIINT8)
.Case("bmi", HasBMI)
.Case("bmi2", HasBMI2)
.Case("cldemote", HasCLDEMOTE)
.Case("clflushopt", HasCLFLUSHOPT)
.Case("clwb", HasCLWB)
.Case("clzero", HasCLZERO)
+ .Case("cmpccxadd", HasCMPCCXADD)
+ .Case("crc32", HasCRC32)
.Case("cx8", HasCX8)
.Case("cx16", HasCX16)
.Case("enqcmd", HasENQCMD)
+ .Case("evex512", HasEVEX512)
.Case("f16c", HasF16C)
.Case("fma", HasFMA)
.Case("fma4", XOPLevel >= FMA4)
@@ -989,10 +1227,13 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("pconfig", HasPCONFIG)
.Case("pku", HasPKU)
.Case("popcnt", HasPOPCNT)
+ .Case("prefetchi", HasPREFETCHI)
.Case("prefetchwt1", HasPREFETCHWT1)
.Case("prfchw", HasPRFCHW)
.Case("ptwrite", HasPTWRITE)
+ .Case("raoint", HasRAOINT)
.Case("rdpid", HasRDPID)
+ .Case("rdpru", HasRDPRU)
.Case("rdrnd", HasRDRND)
.Case("rdseed", HasRDSEED)
.Case("retpoline-external-thunk", HasRetpolineExternalThunk)
@@ -1001,7 +1242,10 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("serialize", HasSERIALIZE)
.Case("sgx", HasSGX)
.Case("sha", HasSHA)
+ .Case("sha512", HasSHA512)
.Case("shstk", HasSHSTK)
+ .Case("sm3", HasSM3)
+ .Case("sm4", HasSM4)
.Case("sse", SSELevel >= SSE1)
.Case("sse2", SSELevel >= SSE2)
.Case("sse3", SSELevel >= SSE3)
@@ -1012,6 +1256,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("tbm", HasTBM)
.Case("tsxldtrk", HasTSXLDTRK)
.Case("uintr", HasUINTR)
+ .Case("usermsr", HasUSERMSR)
.Case("vaes", HasVAES)
.Case("vpclmulqdq", HasVPCLMULQDQ)
.Case("wbnoinvd", HasWBNOINVD)
@@ -1019,11 +1264,19 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("x86", true)
.Case("x86_32", getTriple().getArch() == llvm::Triple::x86)
.Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64)
+ .Case("x87", HasX87)
.Case("xop", XOPLevel >= XOP)
.Case("xsave", HasXSAVE)
.Case("xsavec", HasXSAVEC)
.Case("xsaves", HasXSAVES)
.Case("xsaveopt", HasXSAVEOPT)
+ .Case("fullbf16", HasFullBFloat16)
+ .Case("egpr", HasEGPR)
+ .Case("push2pop2", HasPush2Pop2)
+ .Case("ppx", HasPPX)
+ .Case("ndd", HasNDD)
+ .Case("ccmp", HasCCMP)
+ .Case("cf", HasCF)
.Default(false);
}
@@ -1034,35 +1287,23 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
// X86TargetInfo::hasFeature for a somewhat comprehensive list).
bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const {
return llvm::StringSwitch<bool>(FeatureStr)
-#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, true)
-#include "llvm/Support/X86TargetParser.def"
+#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) .Case(STR, true)
+#define X86_MICROARCH_LEVEL(ENUM, STR, PRIORITY) .Case(STR, true)
+#include "llvm/TargetParser/X86TargetParser.def"
.Default(false);
}
static llvm::X86::ProcessorFeatures getFeature(StringRef Name) {
return llvm::StringSwitch<llvm::X86::ProcessorFeatures>(Name)
-#define X86_FEATURE_COMPAT(ENUM, STR) .Case(STR, llvm::X86::FEATURE_##ENUM)
-#include "llvm/Support/X86TargetParser.def"
+#define X86_FEATURE_COMPAT(ENUM, STR, PRIORITY) \
+ .Case(STR, llvm::X86::FEATURE_##ENUM)
+
+#include "llvm/TargetParser/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.
@@ -1079,35 +1320,19 @@ unsigned X86TargetInfo::multiVersionSortPriority(StringRef Name) const {
}
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);
+ return llvm::X86::validateCPUSpecificCPUDispatch(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);
+ return llvm::X86::getCPUDispatchMangling(Name);
}
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);
+ SmallVector<StringRef, 32> TargetCPUFeatures;
+ llvm::X86::getFeaturesForCPU(Name, TargetCPUFeatures, true);
+ for (auto &F : TargetCPUFeatures)
+ Features.push_back(F);
}
// We can't use a generic validation scheme for the cpus accepted here
@@ -1119,12 +1344,13 @@ bool X86TargetInfo::validateCpuIs(StringRef FeatureStr) const {
#define X86_VENDOR(ENUM, STRING) .Case(STRING, true)
#define X86_CPU_TYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
#define X86_CPU_TYPE(ENUM, STR) .Case(STR, true)
+#define X86_CPU_SUBTYPE_ALIAS(ENUM, ALIAS) .Case(ALIAS, true)
#define X86_CPU_SUBTYPE(ENUM, STR) .Case(STR, true)
-#include "llvm/Support/X86TargetParser.def"
+#include "llvm/TargetParser/X86TargetParser.def"
.Default(false);
}
-static unsigned matchAsmCCConstraint(const char *&Name) {
+static unsigned matchAsmCCConstraint(const char *Name) {
auto RV = llvm::StringSwitch<unsigned>(Name)
.Case("@cca", 4)
.Case("@ccae", 5)
@@ -1192,6 +1418,14 @@ bool X86TargetInfo::validateAsmConstraint(
case 'O':
Info.setRequiresImmediate(0, 127);
return true;
+ case 'W':
+ switch (*++Name) {
+ default:
+ return false;
+ case 's':
+ Info.setAllowsRegister();
+ return true;
+ }
// Register constraints.
case 'Y': // 'Y' is the first character for several 2-character constraints.
// Shift the pointer to the second character of the constraint.
@@ -1264,7 +1498,7 @@ bool X86TargetInfo::validateAsmConstraint(
// | Sandy Bridge | 64 | https://en.wikipedia.org/wiki/Sandy_Bridge and https://www.7-cpu.com/cpu/SandyBridge.html |
// | Ivy Bridge | 64 | https://blog.stuffedcow.net/2013/01/ivb-cache-replacement/ and https://www.7-cpu.com/cpu/IvyBridge.html |
// | Haswell | 64 | https://www.7-cpu.com/cpu/Haswell.html |
-// | Boadwell | 64 | https://www.7-cpu.com/cpu/Broadwell.html |
+// | Broadwell | 64 | https://www.7-cpu.com/cpu/Broadwell.html |
// | Skylake (including skylake-avx512) | 64 | https://www.nas.nasa.gov/hecc/support/kb/skylake-processors_550.html "Cache Hierarchy" |
// | Cascade Lake | 64 | https://www.nas.nasa.gov/hecc/support/kb/cascade-lake-processors_579.html "Cache Hierarchy" |
// | Skylake | 64 | https://en.wikichip.org/wiki/intel/microarchitectures/kaby_lake "Memory Hierarchy" |
@@ -1272,7 +1506,7 @@ bool X86TargetInfo::validateAsmConstraint(
// | Knights Landing | 64 | https://software.intel.com/en-us/articles/intel-xeon-phi-processor-7200-family-memory-management-optimizations "The Intel® Xeon Phi™ Processor Architecture" |
// | Knights Mill | 64 | https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf?countrylabel=Colombia "2.5.5.2 L1 DCache " |
// +------------------------------------+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
-Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
+std::optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
using namespace llvm::X86;
switch (CPU) {
// i386
@@ -1315,6 +1549,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
case CK_Goldmont:
case CK_GoldmontPlus:
case CK_Tremont:
+ case CK_Gracemont:
case CK_Westmere:
case CK_SandyBridge:
@@ -1333,6 +1568,18 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
case CK_Rocketlake:
case CK_IcelakeServer:
case CK_Alderlake:
+ case CK_Raptorlake:
+ case CK_Meteorlake:
+ case CK_Arrowlake:
+ case CK_ArrowlakeS:
+ case CK_Lunarlake:
+ case CK_Pantherlake:
+ case CK_Sierraforest:
+ case CK_Grandridge:
+ case CK_Graniterapids:
+ case CK_GraniterapidsD:
+ case CK_Emeraldrapids:
+ case CK_Clearwaterforest:
case CK_KNL:
case CK_KNM:
// K7
@@ -1354,6 +1601,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
case CK_ZNVER1:
case CK_ZNVER2:
case CK_ZNVER3:
+ case CK_ZNVER4:
// Deprecated
case CK_x86_64:
case CK_x86_64_v2:
@@ -1367,7 +1615,7 @@ Optional<unsigned> X86TargetInfo::getCPUCacheLineSize() const {
// The following currently have unknown cache line sizes (but they are probably all 64):
// Core
case CK_None:
- return None;
+ return std::nullopt;
}
llvm_unreachable("Unknown CPU kind");
}
@@ -1376,8 +1624,7 @@ bool X86TargetInfo::validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
StringRef Constraint,
unsigned Size) const {
// Strip off constraint modifiers.
- while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
- Constraint = Constraint.substr(1);
+ Constraint = Constraint.ltrim("=+&");
return validateOperandSize(FeatureMap, Constraint, Size);
}
@@ -1413,8 +1660,9 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
return Size <= 64;
case 'z':
// XMM0/YMM/ZMM0
- if (hasFeatureEnabled(FeatureMap, "avx512f"))
- // ZMM0 can be used if target supports AVX512F.
+ if (hasFeatureEnabled(FeatureMap, "avx512f") &&
+ hasFeatureEnabled(FeatureMap, "evex512"))
+ // ZMM0 can be used if target supports AVX512F and EVEX512 is set.
return Size <= 512U;
else if (hasFeatureEnabled(FeatureMap, "avx"))
// YMM0 can be used if target supports AVX.
@@ -1433,8 +1681,10 @@ bool X86TargetInfo::validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
break;
case 'v':
case 'x':
- if (hasFeatureEnabled(FeatureMap, "avx512f"))
- // 512-bit zmm registers can be used if target supports AVX512F.
+ if (hasFeatureEnabled(FeatureMap, "avx512f") &&
+ hasFeatureEnabled(FeatureMap, "evex512"))
+ // 512-bit zmm registers can be used if target supports AVX512F and
+ // EVEX512 is set.
return Size <= 512U;
else if (hasFeatureEnabled(FeatureMap, "avx"))
// 256-bit ymm registers can be used if target supports AVX.
@@ -1467,12 +1717,15 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
return std::string("{si}");
case 'D':
return std::string("{di}");
- case 'p': // address
- return std::string("im");
+ case 'p': // Keep 'p' constraint (address).
+ return std::string("p");
case 't': // top of floating point stack.
return std::string("{st}");
case 'u': // second from top of floating point stack.
return std::string("{st(1)}"); // second from top of floating point stack.
+ case 'W':
+ assert(Constraint[1] == 's');
+ return '^' + std::string(Constraint++, 2);
case 'Y':
switch (Constraint[1]) {
default:
@@ -1491,7 +1744,7 @@ std::string X86TargetInfo::convertConstraint(const char *&Constraint) const {
// to the next constraint.
return std::string("^") + std::string(Constraint++, 2);
}
- LLVM_FALLTHROUGH;
+ [[fallthrough]];
default:
return std::string(1, *Constraint);
}
@@ -1507,19 +1760,19 @@ void X86TargetInfo::fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) con
}
ArrayRef<const char *> X86TargetInfo::getGCCRegNames() const {
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::AddlRegName> X86TargetInfo::getGCCAddlRegNames() const {
- return llvm::makeArrayRef(AddlRegNames);
+ return llvm::ArrayRef(AddlRegNames);
}
ArrayRef<Builtin::Info> X86_32TargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
- Builtin::FirstTSBuiltin + 1);
+ return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin -
+ Builtin::FirstTSBuiltin + 1);
}
ArrayRef<Builtin::Info> X86_64TargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfoX86,
- X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfoX86,
+ X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/X86.h b/contrib/llvm-project/clang/lib/Basic/Targets/X86.h
index fcaaf50624e9..0ab1c10833db 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/X86.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/X86.h
@@ -14,11 +14,13 @@
#define LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
#include "OSTargets.h"
+#include "clang/Basic/BitmaskEnum.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/X86TargetParser.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/TargetParser/X86TargetParser.h"
+#include <optional>
namespace clang {
namespace targets {
@@ -42,7 +44,11 @@ static const unsigned X86AddrSpaceMap[] = {
0, // sycl_private
270, // ptr32_sptr
271, // ptr32_uptr
- 272 // ptr64
+ 272, // ptr64
+ 0, // hlsl_groupshared
+ // Wasm address space values for this target are dummy values,
+ // as it is only enabled for Wasm targets.
+ 20, // wasm_funcref
};
// X86 target abstract base class; x86-32 and x86-64 are very close, so
@@ -89,9 +95,13 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasLWP = false;
bool HasFMA = false;
bool HasF16C = false;
+ bool HasAVX10_1 = false;
+ bool HasAVX10_1_512 = false;
+ bool HasEVEX512 = false;
bool HasAVX512CD = false;
bool HasAVX512VPOPCNTDQ = false;
bool HasAVX512VNNI = false;
+ bool HasAVX512FP16 = false;
bool HasAVX512BF16 = false;
bool HasAVX512ER = false;
bool HasAVX512PF = false;
@@ -101,11 +111,15 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasAVX512VL = false;
bool HasAVX512VBMI = false;
bool HasAVX512VBMI2 = false;
+ bool HasAVXIFMA = false;
bool HasAVX512IFMA = false;
bool HasAVX512VP2INTERSECT = false;
bool HasSHA = false;
+ bool HasSHA512 = false;
bool HasSHSTK = false;
+ bool HasSM3 = false;
bool HasSGX = false;
+ bool HasSM4 = false;
bool HasCX8 = false;
bool HasCX16 = false;
bool HasFXSR = false;
@@ -121,8 +135,10 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasCLFLUSHOPT = false;
bool HasCLWB = false;
bool HasMOVBE = false;
+ bool HasPREFETCHI = false;
bool HasPREFETCHWT1 = false;
bool HasRDPID = false;
+ bool HasRDPRU = false;
bool HasRetpolineExternalThunk = false;
bool HasLAHFSAHF = false;
bool HasWBNOINVD = false;
@@ -132,6 +148,12 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasPTWRITE = false;
bool HasINVPCID = false;
bool HasENQCMD = false;
+ bool HasAVXVNNIINT16 = false;
+ bool HasAMXFP16 = false;
+ bool HasCMPCCXADD = false;
+ bool HasRAOINT = false;
+ bool HasAVXVNNIINT8 = false;
+ bool HasAVXNECONVERT = false;
bool HasKL = false; // For key locker
bool HasWIDEKL = false; // For wide key locker
bool HasHRESET = false;
@@ -139,9 +161,19 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasAMXTILE = false;
bool HasAMXINT8 = false;
bool HasAMXBF16 = false;
+ bool HasAMXCOMPLEX = false;
bool HasSERIALIZE = false;
bool HasTSXLDTRK = false;
+ bool HasUSERMSR = false;
bool HasUINTR = false;
+ bool HasCRC32 = false;
+ bool HasX87 = false;
+ bool HasEGPR = false;
+ bool HasPush2Pop2 = false;
+ bool HasPPX = false;
+ bool HasNDD = false;
+ bool HasCCMP = false;
+ bool HasCF = false;
protected:
llvm::X86::CPUKind CPU = llvm::X86::CK_None;
@@ -151,6 +183,8 @@ protected:
public:
X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
+ BFloat16Width = BFloat16Align = 16;
+ BFloat16Format = &llvm::APFloat::BFloat();
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
AddrSpaceMap = &X86AddrSpaceMap;
HasStrictFP = true;
@@ -165,15 +199,19 @@ public:
return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
}
- unsigned getFloatEvalMethod() const override {
+ LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
// X87 evaluates with 80 bits "long double" precision.
- return SSELevel == NoSSE ? 2 : 0;
+ return SSELevel == NoSSE ? LangOptions::FPEvalMethodKind::FEM_Extended
+ : LangOptions::FPEvalMethodKind::FEM_Source;
}
+ // EvalMethod `source` is not supported for targets with `NoSSE` feature.
+ bool supportSourceEvalMethod() const override { return SSELevel > NoSSE; }
+
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
@@ -182,9 +220,9 @@ public:
return RegName.equals("esp") || RegName.equals("rsp");
}
- bool validateCpuSupports(StringRef Name) const override;
+ bool validateCpuSupports(StringRef FeatureStr) const override;
- bool validateCpuIs(StringRef Name) const override;
+ bool validateCpuIs(StringRef FeatureStr) const override;
bool validateCPUSpecificCPUDispatch(StringRef Name) const override;
@@ -194,7 +232,7 @@ public:
StringRef Name,
llvm::SmallVectorImpl<StringRef> &Features) const override;
- Optional<unsigned> getCPUCacheLineSize() const override;
+ std::optional<unsigned> getCPUCacheLineSize() const override;
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const override;
@@ -218,21 +256,25 @@ public:
bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
StringRef Constraint, unsigned Size) const override;
- virtual bool
+ bool
checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const override {
- return true;
+ if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
+ return true;
+ return TargetInfo::checkCFProtectionReturnSupported(Diags);
};
- virtual bool
+ bool
checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
- return true;
+ if (CPU == llvm::X86::CK_None || CPU >= llvm::X86::CK_PentiumPro)
+ return true;
+ return TargetInfo::checkCFProtectionBranchSupported(Diags);
};
virtual bool validateOperandSize(const llvm::StringMap<bool> &FeatureMap,
StringRef Constraint, unsigned Size) const;
std::string convertConstraint(const char *&Constraint) const override;
- const char *getClobbers() const override {
+ std::string_view getClobbers() const override {
return "~{dirflag},~{fpsr},~{flags}";
}
@@ -374,17 +416,19 @@ public:
void setSupportedOpenCLOpts() override { supportAllOpenCLOpts(); }
- uint64_t getPointerWidthV(unsigned AddrSpace) const override {
- if (AddrSpace == ptr32_sptr || AddrSpace == ptr32_uptr)
+ uint64_t getPointerWidthV(LangAS AS) const override {
+ unsigned TargetAddrSpace = getTargetAddressSpace(AS);
+ if (TargetAddrSpace == ptr32_sptr || TargetAddrSpace == ptr32_uptr)
return 32;
- if (AddrSpace == ptr64)
+ if (TargetAddrSpace == ptr64)
return 64;
return PointerWidth;
}
- uint64_t getPointerAlignV(unsigned AddrSpace) const override {
+ uint64_t getPointerAlignV(LangAS AddrSpace) const override {
return getPointerWidthV(AddrSpace);
}
+
};
// X86-32 generic target
@@ -396,22 +440,21 @@ public:
LongDoubleWidth = 96;
LongDoubleAlign = 32;
SuitableAlign = 128;
- resetDataLayout(
- Triple.isOSBinFormatMachO()
- ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
- "f80:32-n8:16:32-S128"
- : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
- "f80:32-n8:16:32-S128",
- Triple.isOSBinFormatMachO() ? "_" : "");
+ resetDataLayout(Triple.isOSBinFormatMachO()
+ ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
+ "128-f64:32:64-f80:32-n8:16:32-S128"
+ : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:"
+ "128-f64:32:64-f80:32-n8:16:32-S128",
+ Triple.isOSBinFormatMachO() ? "_" : "");
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
IntPtrType = SignedInt;
RegParmMax = 3;
// Use fpret for all types.
- RealTypeUsesObjCFPRet =
- ((1 << TargetInfo::Float) | (1 << TargetInfo::Double) |
- (1 << TargetInfo::LongDouble));
+ RealTypeUsesObjCFPRetMask =
+ (unsigned)(FloatModeKind::Float | FloatModeKind::Double |
+ FloatModeKind::LongDouble);
// x86-32 has atomics up to 8 bytes
MaxAtomicPromoteWidth = 64;
@@ -459,7 +502,10 @@ public:
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
+ size_t getMaxBitIntWidth() const override {
+ return llvm::IntegerType::MAX_INT_BITS;
+ }
};
class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
@@ -468,14 +514,13 @@ public:
NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
- unsigned getFloatEvalMethod() const override {
- unsigned Major, Minor, Micro;
- getTriple().getOSVersion(Major, Minor, Micro);
+ LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
+ VersionTuple OsVersion = getTriple().getOSVersion();
// New NetBSD uses the default rounding mode.
- if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 26) || Major == 0)
- return X86_32TargetInfo::getFloatEvalMethod();
+ if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0)
+ return X86_32TargetInfo::getFPEvalMethod();
// NetBSD before 6.99.26 defaults to "double" rounding.
- return 1;
+ return LangOptions::FPEvalMethodKind::FEM_Double;
}
};
@@ -505,8 +550,9 @@ public:
UseSignedCharForObjCBool = false;
SizeType = UnsignedLong;
IntPtrType = SignedLong;
- resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-"
- "f80:128-n8:16:32-S128", "_");
+ resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-"
+ "f64:32:64-f80:128-n8:16:32-S128",
+ "_");
HasAlignMac68kSupport = true;
}
@@ -531,11 +577,12 @@ public:
DoubleAlign = LongLongAlign = 64;
bool IsWinCOFF =
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
- resetDataLayout(IsWinCOFF ? "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:"
- "64-i64:64-f80:32-n8:16:32-a:0:32-S32"
- : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:"
- "64-i64:64-f80:32-n8:16:32-a:0:32-S32",
- IsWinCOFF ? "_" : "");
+ bool IsMSVC = getTriple().isWindowsMSVCEnvironment();
+ std::string Layout = IsWinCOFF ? "e-m:x" : "e-m:e";
+ Layout += "-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-";
+ Layout += IsMSVC ? "f80:128" : "f80:32";
+ Layout += "-n8:16:32-a:0:32-S32";
+ resetDataLayout(Layout, IsWinCOFF ? "_" : "");
}
};
@@ -583,8 +630,8 @@ public:
: X86_32TargetInfo(Triple, Opts) {
this->WCharType = TargetInfo::UnsignedShort;
DoubleAlign = LongLongAlign = 64;
- resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:"
- "32-n8:16:32-a:0:32-S32",
+ resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-"
+ "i128:128-f80:32-n8:16:32-a:0:32-S32",
"_");
}
@@ -622,8 +669,8 @@ public:
: X86_32TargetInfo(Triple, Opts) {
LongDoubleWidth = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
- resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:"
- "32-f128:32-n8:16:32-a:0:32-S32");
+ resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-"
+ "f64:32-f128:32-n8:16:32-a:0:32-S32");
WIntType = UnsignedInt;
}
@@ -683,14 +730,14 @@ public:
// Pointers are 32-bit in x32.
resetDataLayout(IsX32 ? "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-"
- "i64:64-f80:128-n8:16:32:64-S128"
- : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:"
- "64-i64:64-f80:128-n8:16:32:64-S128"
- : "e-m:e-p270:32:32-p271:32:32-p272:64:"
- "64-i64:64-f80:128-n8:16:32:64-S128");
+ "i64:64-i128:128-f80:128-n8:16:32:64-S128"
+ : IsWinCOFF ? "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:"
+ "64-i128:128-f80:128-n8:16:32:64-S128"
+ : "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:"
+ "64-i128:128-f80:128-n8:16:32:64-S128");
// Use fpret only for long double.
- RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
+ RealTypeUsesObjCFPRetMask = (unsigned)FloatModeKind::LongDouble;
// Use fp2ret for _Complex long double.
ComplexLongDoubleUsesFP2Ret = true;
@@ -766,7 +813,10 @@ public:
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
+ size_t getMaxBitIntWidth() const override {
+ return llvm::IntegerType::MAX_INT_BITS;
+ }
};
// x86-64 Windows target
@@ -881,8 +931,9 @@ public:
llvm::Triple T = llvm::Triple(Triple);
if (T.isiOS())
UseSignedCharForObjCBool = false;
- resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:"
- "16:32:64-S128", "_");
+ resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-"
+ "f80:128-n8:16:32:64-S128",
+ "_");
}
bool handleTargetFeatures(std::vector<std::string> &Features,
@@ -928,6 +979,28 @@ public:
LongDoubleFormat = &llvm::APFloat::IEEEquad();
}
};
+
+// x86_32 OHOS target
+class LLVM_LIBRARY_VISIBILITY OHOSX86_32TargetInfo
+ : public OHOSTargetInfo<X86_32TargetInfo> {
+public:
+ OHOSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : OHOSTargetInfo<X86_32TargetInfo>(Triple, Opts) {
+ SuitableAlign = 32;
+ LongDoubleWidth = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+ }
+};
+
+// x86_64 OHOS target
+class LLVM_LIBRARY_VISIBILITY OHOSX86_64TargetInfo
+ : public OHOSTargetInfo<X86_64TargetInfo> {
+public:
+ OHOSX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+ : OHOSTargetInfo<X86_64TargetInfo>(Triple, Opts) {
+ LongDoubleFormat = &llvm::APFloat::IEEEquad();
+ }
+};
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_X86_H
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp b/contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp
index ba64f15f3394..fd377bbfb90e 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/XCore.cpp
@@ -18,11 +18,11 @@
using namespace clang;
using namespace clang::targets;
-const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = {
+static constexpr Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
- {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
- {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
+ {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
#include "clang/Basic/BuiltinsXCore.def"
};
@@ -33,6 +33,6 @@ void XCoreTargetInfo::getTargetDefines(const LangOptions &Opts,
}
ArrayRef<Builtin::Info> XCoreTargetInfo::getTargetBuiltins() const {
- return llvm::makeArrayRef(BuiltinInfo, clang::XCore::LastTSBuiltin -
- Builtin::FirstTSBuiltin);
+ return llvm::ArrayRef(BuiltinInfo,
+ clang::XCore::LastTSBuiltin - Builtin::FirstTSBuiltin);
}
diff --git a/contrib/llvm-project/clang/lib/Basic/Targets/XCore.h b/contrib/llvm-project/clang/lib/Basic/Targets/XCore.h
index c33766751aa1..a58d3e8acf47 100644
--- a/contrib/llvm-project/clang/lib/Basic/Targets/XCore.h
+++ b/contrib/llvm-project/clang/lib/Basic/Targets/XCore.h
@@ -15,14 +15,13 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/TargetParser/Triple.h"
namespace clang {
namespace targets {
class LLVM_LIBRARY_VISIBILITY XCoreTargetInfo : public TargetInfo {
- static const Builtin::Info BuiltinInfo[];
public:
XCoreTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -50,18 +49,18 @@ public:
return TargetInfo::VoidPtrBuiltinVaList;
}
- const char *getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return ""; }
ArrayRef<const char *> getGCCRegNames() const override {
static const char *const GCCRegNames[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "cp", "dp", "sp", "lr"
};
- return llvm::makeArrayRef(GCCRegNames);
+ return llvm::ArrayRef(GCCRegNames);
}
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
- return None;
+ return std::nullopt;
}
bool validateAsmConstraint(const char *&Name,
@@ -76,7 +75,7 @@ public:
bool allowsLargerPreferedTypeAlignment() const override { return false; }
- bool hasExtIntType() const override { return true; }
+ bool hasBitIntType() const override { return true; }
};
} // namespace targets
} // namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp b/contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp
index d55e176c72c4..c300175ce90b 100644
--- a/contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/TokenKinds.cpp
@@ -46,6 +46,15 @@ const char *tok::getKeywordSpelling(TokenKind Kind) {
return nullptr;
}
+const char *tok::getPPKeywordSpelling(tok::PPKeywordKind Kind) {
+ switch (Kind) {
+#define PPKEYWORD(x) case tok::pp_##x: return #x;
+#include "clang/Basic/TokenKinds.def"
+ default: break;
+ }
+ return nullptr;
+}
+
bool tok::isAnnotation(TokenKind Kind) {
switch (Kind) {
#define ANNOTATION(X) case annot_ ## X: return true;
diff --git a/contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp b/contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp
index 3b723afff70b..4dbf678dc395 100644
--- a/contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/TypeTraits.cpp
@@ -55,6 +55,15 @@ static constexpr const char *UnaryExprOrTypeTraitSpellings[] = {
#include "clang/Basic/TokenKinds.def"
};
+static constexpr const unsigned TypeTraitArities[] = {
+#define TYPE_TRAIT_1(Spelling, Name, Key) 1,
+#include "clang/Basic/TokenKinds.def"
+#define TYPE_TRAIT_2(Spelling, Name, Key) 2,
+#include "clang/Basic/TokenKinds.def"
+#define TYPE_TRAIT_N(Spelling, Name, Key) 0,
+#include "clang/Basic/TokenKinds.def"
+};
+
const char *clang::getTraitName(TypeTrait T) {
assert(T <= TT_Last && "invalid enum value!");
return TypeTraitNames[T];
@@ -84,3 +93,8 @@ const char *clang::getTraitSpelling(UnaryExprOrTypeTrait T) {
assert(T <= UETT_Last && "invalid enum value!");
return UnaryExprOrTypeTraitSpellings[T];
}
+
+unsigned clang::getTypeTraitArity(TypeTrait T) {
+ assert(T <= TT_Last && "invalid enum value!");
+ return TypeTraitArities[T];
+}
diff --git a/contrib/llvm-project/clang/lib/Basic/Version.cpp b/contrib/llvm-project/clang/lib/Basic/Version.cpp
index af3118b0f6da..4823f566bd77 100644
--- a/contrib/llvm-project/clang/lib/Basic/Version.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Version.cpp
@@ -57,6 +57,14 @@ std::string getLLVMRevision() {
#endif
}
+std::string getClangVendor() {
+#ifdef CLANG_VENDOR
+ return CLANG_VENDOR;
+#else
+ return "";
+#endif
+}
+
std::string getClangFullRepositoryVersion() {
std::string buf;
llvm::raw_string_ostream OS(buf);
@@ -82,7 +90,7 @@ std::string getClangFullRepositoryVersion() {
OS << LLVMRepo << ' ';
OS << LLVMRev << ')';
}
- return OS.str();
+ return buf;
}
std::string getClangFullVersion() {
@@ -92,17 +100,14 @@ std::string getClangFullVersion() {
std::string getClangToolFullVersion(StringRef ToolName) {
std::string buf;
llvm::raw_string_ostream OS(buf);
-#ifdef CLANG_VENDOR
- OS << CLANG_VENDOR;
-#endif
- OS << ToolName << " version " CLANG_VERSION_STRING;
+ OS << getClangVendor() << ToolName << " version " CLANG_VERSION_STRING;
std::string repo = getClangFullRepositoryVersion();
if (!repo.empty()) {
OS << " " << repo;
}
- return OS.str();
+ return buf;
}
std::string getClangFullCPPVersion() {
@@ -110,17 +115,14 @@ std::string getClangFullCPPVersion() {
// the one we report on the command line.
std::string buf;
llvm::raw_string_ostream OS(buf);
-#ifdef CLANG_VENDOR
- OS << CLANG_VENDOR;
-#endif
- OS << "Clang " CLANG_VERSION_STRING;
+ OS << getClangVendor() << "Clang " CLANG_VERSION_STRING;
std::string repo = getClangFullRepositoryVersion();
if (!repo.empty()) {
OS << " " << repo;
}
- return OS.str();
+ return buf;
}
} // end namespace clang
diff --git a/contrib/llvm-project/clang/lib/Basic/Warnings.cpp b/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
index cc8c138233ca..5a5ac5556338 100644
--- a/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
+++ b/contrib/llvm-project/clang/lib/Basic/Warnings.cpp
@@ -96,11 +96,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
// Check to see if this warning starts with "no-", if so, this is a
// negative form of the option.
- bool isPositive = true;
- if (Opt.startswith("no-")) {
- isPositive = false;
- Opt = Opt.substr(3);
- }
+ bool isPositive = !Opt.consume_front("no-");
// Figure out how this option affects the warning. If -Wfoo, map the
// diagnostic to a warning, if -Wno-foo, map it to ignore.
@@ -133,7 +129,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
// table. It also has the "specifier" form of -Werror=foo. GCC supports
// the deprecated -Werror-implicit-function-declaration which is used by
// a few projects.
- if (Opt.startswith("error")) {
+ if (Opt.starts_with("error")) {
StringRef Specifier;
if (Opt.size() > 5) { // Specifier must be present.
if (Opt[5] != '=' &&
@@ -162,7 +158,7 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
}
// -Wfatal-errors is yet another special case.
- if (Opt.startswith("fatal-errors")) {
+ if (Opt.starts_with("fatal-errors")) {
StringRef Specifier;
if (Opt.size() != 12) {
if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) {
@@ -198,14 +194,12 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
}
}
- for (unsigned i = 0, e = Opts.Remarks.size(); i != e; ++i) {
- StringRef Opt = Opts.Remarks[i];
+ for (StringRef Opt : Opts.Remarks) {
const auto Flavor = diag::Flavor::Remark;
// Check to see if this warning starts with "no-", if so, this is a
// negative form of the option.
- bool IsPositive = !Opt.startswith("no-");
- if (!IsPositive) Opt = Opt.substr(3);
+ bool IsPositive = !Opt.consume_front("no-");
auto Severity = IsPositive ? diag::Severity::Remark
: diag::Severity::Ignored;