summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/utils
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2017-04-02 17:24:58 +0000
committerdim <dim@FreeBSD.org>2017-04-02 17:24:58 +0000
commit60b571e49a90d38697b3aca23020d9da42fc7d7f (patch)
tree99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/llvm/tools/clang/utils
parentbea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff)
downloadFreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.zip
FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.tar.gz
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release:
MFC r309142 (by emaste): Add WITH_LLD_AS_LD build knob If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not capable of linking the world and kernel, but can self-host and link many substantial applications. GNU ld continues to be used for the world and kernel build, regardless of how this knob is set. It is on by default for arm64, and off for all other CPU architectures. Sponsored by: The FreeBSD Foundation MFC r310840: Reapply 310775, now it also builds correctly if lldb is disabled: Move llvm-objdump from CLANG_EXTRAS to installed by default We currently install three tools from binutils 2.17.50: as, ld, and objdump. Work is underway to migrate to a permissively-licensed tool-chain, with one goal being the retirement of binutils 2.17.50. LLVM's llvm-objdump is intended to be compatible with GNU objdump although it is currently missing some options and may have formatting differences. Enable it by default for testing and further investigation. It may later be changed to install as /usr/bin/objdump, it becomes a fully viable replacement. Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D8879 MFC r312855 (by emaste): Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC Reported by: Dan McGregor <dan.mcgregor usask.ca> MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines Don't check struct rtentry on FreeBSD, it is an internal kernel structure. On other systems it may be API structure for SIOCADDRT/SIOCDELRT. Reviewed by: emaste, dim MFC r314152 (by jkim): Remove an assembler flag, which is redundant since r309124. The upstream took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE. http://llvm.org/viewvc/llvm-project?rev=273500&view=rev Reviewed by: dim MFC r314564: Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 (branches/release_40 296509). The release will follow soon. Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11 support to build; see UPDATING for more information. Also note that as of 4.0.0, lld should be able to link the base system on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5). Though please be aware that this is work in progress. Release notes for llvm, clang and lld will be available here: <http://releases.llvm.org/4.0.0/docs/ReleaseNotes.html> <http://releases.llvm.org/4.0.0/tools/clang/docs/ReleaseNotes.html> <http://releases.llvm.org/4.0.0/tools/lld/docs/ReleaseNotes.html> Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for their help. Relnotes: yes Exp-run: antoine PR: 215969, 216008 MFC r314708: For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 This commit is the cause of excessive compile times on skein_block.c (and possibly other files) during kernel builds on amd64. We never saw the problematic behavior described in this upstream commit, so for now it is better to revert it. An upstream bug has been filed here: https://bugs.llvm.org/show_bug.cgi?id=32142 Reported by: mjg MFC r314795: Reapply r287232 from upstream llvm trunk (by Daniil Fukalov): [SCEV] limit recursion depth of CompareSCEVComplexity Summary: CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled loop) and runs almost infinite time. Added cache of "equal" SCEV pairs to earlier cutoff of further estimation. Recursion depth limit was also introduced as a parameter. Reviewers: sanjoy Subscribers: mzolotukhin, tstellarAMD, llvm-commits Differential Revision: https://reviews.llvm.org/D26389 Pull in r296992 from upstream llvm trunk (by Sanjoy Das): [SCEV] Decrease the recursion threshold for CompareValueComplexity Fixes PR32142. r287232 accidentally increased the recursion threshold for CompareValueComplexity from 2 to 32. This change reverses that change by introducing a separate flag for CompareValueComplexity's threshold. The latter revision fixes the excessive compile times for skein_block.c. MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines Unbreak ARMv6 world. The new compiler_rt library imported with clang 4.0.0 have several fatal issues (non-functional __udivsi3 for example) with ARM specific instrict functions. As temporary workaround, until upstream solve these problems, disable all thumb[1][2] related feature. MFC r315016: Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release. We were already very close to the last release candidate, so this is a pretty minor update. Relnotes: yes MFC r316005: Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by Weiming Zhao): builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA. Summary: Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation mode (-mthumb, -marm), it reflect's capability of given CPU. Due to this: - use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB - use '.thumb' directive consistently in all affected files - decorate all thumb functions using DEFINE_COMPILERRT_THUMB_FUNCTION() --------- Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 ! Reviewers: weimingz, rengolin, compnerd Subscribers: aemerson, dim Differential Revision: https://reviews.llvm.org/D30938 Discussed with: mmel
Diffstat (limited to 'contrib/llvm/tools/clang/utils')
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp2
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp157
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp449
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp98
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp10
-rw-r--r--contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h1
6 files changed, 607 insertions, 110 deletions
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp
index b17a4a3..b132dcb 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp
@@ -47,7 +47,7 @@ class ClangASTNodesEmitter {
if (&R == &Root && !BaseSuffix.empty())
return BaseSuffix;
- return R.getName() + BaseSuffix;
+ return R.getName().str() + BaseSuffix;
}
std::pair<Record *, Record *> EmitNode (const ChildMap &Tree, raw_ostream& OS,
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
index 50102af..27ab34c 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
@@ -120,12 +121,8 @@ static std::string WritePCHRecord(StringRef type, StringRef name) {
// underscores. For example, __foo, foo__, __foo__ would
// become foo.
static StringRef NormalizeAttrName(StringRef AttrName) {
- if (AttrName.startswith("__"))
- AttrName = AttrName.substr(2, AttrName.size());
-
- if (AttrName.endswith("__"))
- AttrName = AttrName.substr(0, AttrName.size() - 2);
-
+ AttrName.consume_front("__");
+ AttrName.consume_back("__");
return AttrName;
}
@@ -136,10 +133,9 @@ static StringRef NormalizeNameForSpellingComparison(StringRef Name) {
return Name.trim("_");
}
-// Normalize attribute spelling only if the spelling has both leading
-// and trailing underscores. For example, __ms_struct__ will be
-// normalized to "ms_struct"; __cdecl will remain intact.
-static StringRef NormalizeAttrSpelling(StringRef AttrSpelling) {
+// Normalize the spelling of a GNU attribute (i.e. "x" in "__attribute__((x))"),
+// removing "__" if it appears at the beginning and end of the attribute's name.
+static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) {
if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) {
AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4);
}
@@ -299,7 +295,13 @@ namespace {
OS << "\" << get" << getUpperName()
<< "()->getNameInfo().getAsString() << \"";
} else if (type == "IdentifierInfo *") {
- OS << "\" << get" << getUpperName() << "()->getName() << \"";
+ OS << "\";\n";
+ if (isOptional())
+ OS << " if (get" << getUpperName() << "()) ";
+ else
+ OS << " ";
+ OS << "OS << get" << getUpperName() << "()->getName();\n";
+ OS << " OS << \"";
} else if (type == "TypeSourceInfo *") {
OS << "\" << get" << getUpperName() << "().getAsString() << \"";
} else {
@@ -717,13 +719,10 @@ namespace {
std::vector<std::string>
uniqueEnumsInOrder(const std::vector<std::string> &enums) {
std::vector<std::string> uniques;
- std::set<std::string> unique_set(enums.begin(), enums.end());
+ SmallDenseSet<StringRef, 8> unique_set;
for (const auto &i : enums) {
- auto set_i = unique_set.find(i);
- if (set_i != unique_set.end()) {
+ if (unique_set.insert(i).second)
uniques.push_back(i);
- unique_set.erase(set_i);
- }
}
return uniques;
}
@@ -835,7 +834,7 @@ namespace {
OS << " static const char *Convert" << type << "ToStr("
<< type << " Val) {\n"
<< " switch(Val) {\n";
- std::set<std::string> Uniques;
+ SmallDenseSet<StringRef, 8> Uniques;
for (size_t I = 0; I < enums.size(); ++I) {
if (Uniques.insert(enums[I]).second)
OS << " case " << getAttrName() << "Attr::" << enums[I]
@@ -943,7 +942,7 @@ namespace {
OS << " static const char *Convert" << type << "ToStr("
<< type << " Val) {\n"
<< " switch(Val) {\n";
- std::set<std::string> Uniques;
+ SmallDenseSet<StringRef, 8> Uniques;
for (size_t I = 0; I < enums.size(); ++I) {
if (Uniques.insert(enums[I]).second)
OS << " case " << getAttrName() << "Attr::" << enums[I]
@@ -1312,6 +1311,9 @@ writePrettyPrintFunction(Record &R,
} else if (Variety == "Declspec") {
Prefix = " __declspec(";
Suffix = ")";
+ } else if (Variety == "Microsoft") {
+ Prefix = "[";
+ Suffix = "]";
} else if (Variety == "Keyword") {
Prefix = " ";
Suffix = "";
@@ -1344,11 +1346,8 @@ writePrettyPrintFunction(Record &R,
// Fake arguments aren't part of the parsed form and should not be
// pretty-printed.
- bool hasNonFakeArgs = false;
- for (const auto &arg : Args) {
- if (arg->isFake()) continue;
- hasNonFakeArgs = true;
- }
+ bool hasNonFakeArgs = llvm::any_of(
+ Args, [](const std::unique_ptr<Argument> &A) { return !A->isFake(); });
// FIXME: always printing the parenthesis isn't the correct behavior for
// attributes which have optional arguments that were not provided. For
@@ -1408,18 +1407,20 @@ getSpellingListIndex(const std::vector<FlattenedSpelling> &SpellingList,
static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) {
std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
+ if (Accessors.empty())
+ return;
+
+ const std::vector<FlattenedSpelling> SpellingList = GetFlattenedSpellings(R);
+ assert(!SpellingList.empty() &&
+ "Attribute with empty spelling list can't have accessors!");
for (const auto *Accessor : Accessors) {
std::string Name = Accessor->getValueAsString("Name");
- std::vector<FlattenedSpelling> Spellings =
- GetFlattenedSpellings(*Accessor);
- std::vector<FlattenedSpelling> SpellingList = GetFlattenedSpellings(R);
- assert(!SpellingList.empty() &&
- "Attribute with empty spelling list can't have accessors!");
+ std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Accessor);
OS << " bool " << Name << "() const { return SpellingListIndex == ";
for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
OS << getSpellingListIndex(SpellingList, Spellings[Index]);
- if (Index != Spellings.size() -1)
+ if (Index != Spellings.size() - 1)
OS << " ||\n SpellingListIndex == ";
else
OS << "; }\n";
@@ -1521,6 +1522,16 @@ static void emitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS)
OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
}
+template <typename Fn>
+static void forEachUniqueSpelling(const Record &Attr, Fn &&F) {
+ std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
+ SmallDenseSet<StringRef, 8> Seen;
+ for (const FlattenedSpelling &S : Spellings) {
+ if (Seen.insert(S.name()).second)
+ F(S);
+ }
+}
+
/// \brief Emits the first-argument-is-type property for attributes.
static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\n";
@@ -1536,12 +1547,9 @@ static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
continue;
// All these spellings take a single type argument.
- std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
- std::set<std::string> Emitted;
- for (const auto &S : Spellings) {
- if (Emitted.insert(S.name()).second)
- OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
- }
+ forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
+ OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
+ });
}
OS << "#endif // CLANG_ATTR_TYPE_ARG_LIST\n\n";
}
@@ -1558,12 +1566,9 @@ static void emitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS)
continue;
// All these spellings take are parsed unevaluated.
- std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
- std::set<std::string> Emitted;
- for (const auto &S : Spellings) {
- if (Emitted.insert(S.name()).second)
- OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
- }
+ forEachUniqueSpelling(Attr, [&](const FlattenedSpelling &S) {
+ OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
+ });
}
OS << "#endif // CLANG_ATTR_ARG_CONTEXT_LIST\n\n";
}
@@ -1589,12 +1594,9 @@ static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &O
continue;
// All these spellings take an identifier argument.
- std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
- std::set<std::string> Emitted;
- for (const auto &S : Spellings) {
- if (Emitted.insert(S.name()).second)
- OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
- }
+ forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
+ OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
+ });
}
OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n";
}
@@ -1882,8 +1884,7 @@ static void emitAttrList(raw_ostream &OS, StringRef Class,
// Determines if an attribute has a Pragma spelling.
static bool AttrHasPragmaSpelling(const Record *R) {
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
- return std::find_if(Spellings.begin(), Spellings.end(),
- [](const FlattenedSpelling &S) {
+ return llvm::find_if(Spellings, [](const FlattenedSpelling &S) {
return S.variety() == "Pragma";
}) != Spellings.end();
}
@@ -2295,7 +2296,7 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
// Separate all of the attributes out into four group: generic, C++11, GNU,
// and declspecs. Then generate a big switch statement for each of them.
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
- std::vector<Record *> Declspec, GNU, Pragma;
+ std::vector<Record *> Declspec, Microsoft, GNU, Pragma;
std::map<std::string, std::vector<Record *>> CXX;
// Walk over the list of all attributes, and split them out based on the
@@ -2308,6 +2309,8 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
GNU.push_back(R);
else if (Variety == "Declspec")
Declspec.push_back(R);
+ else if (Variety == "Microsoft")
+ Microsoft.push_back(R);
else if (Variety == "CXX11")
CXX[SI.nameSpace()].push_back(R);
else if (Variety == "Pragma")
@@ -2323,6 +2326,9 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
OS << "case AttrSyntax::Declspec:\n";
OS << " return llvm::StringSwitch<int>(Name)\n";
GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec");
+ OS << "case AttrSyntax::Microsoft:\n";
+ OS << " return llvm::StringSwitch<int>(Name)\n";
+ GenerateHasAttrSpellingStringSwitch(Microsoft, OS, "Microsoft");
OS << "case AttrSyntax::Pragma:\n";
OS << " return llvm::StringSwitch<int>(Name)\n";
GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
@@ -2361,8 +2367,9 @@ void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
.Case("GNU", 0)
.Case("CXX11", 1)
.Case("Declspec", 2)
- .Case("Keyword", 3)
- .Case("Pragma", 4)
+ .Case("Microsoft", 3)
+ .Case("Keyword", 4)
+ .Case("Pragma", 5)
.Default(0)
<< " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
<< " return " << I << ";\n";
@@ -2532,6 +2539,10 @@ static void emitArgInfo(const Record &R, std::stringstream &OS) {
unsigned ArgCount = 0, OptCount = 0;
bool HasVariadic = false;
for (const auto *Arg : Args) {
+ // If the arg is fake, it's the user's job to supply it: general parsing
+ // logic shouldn't need to know anything about it.
+ if (Arg->getValueAsBit("Fake"))
+ continue;
Arg->getValueAsBit("Optional") ? ++OptCount : ++ArgCount;
if (!HasVariadic && isArgVariadic(*Arg, R.getName()))
HasVariadic = true;
@@ -2675,7 +2686,7 @@ static std::string CalculateDiagnostic(const Record &S) {
}
static std::string GetSubjectWithSuffix(const Record *R) {
- std::string B = R->getName();
+ const std::string &B = R->getName();
if (B == "DeclBase")
return "Decl";
return B + "Decl";
@@ -2683,7 +2694,7 @@ static std::string GetSubjectWithSuffix(const Record *R) {
static std::string GenerateCustomAppertainsTo(const Record &Subject,
raw_ostream &OS) {
- std::string FnName = "is" + Subject.getName();
+ std::string FnName = "is" + Subject.getName().str();
// If this code has already been generated, simply return the previous
// instance of it.
@@ -2732,7 +2743,7 @@ static std::string GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
// Otherwise, generate an appertainsTo check specific to this attribute which
// checks all of the given subjects against the Decl passed in. Return the
// name of that check to the caller.
- std::string FnName = "check" + Attr.getName() + "AppertainsTo";
+ std::string FnName = "check" + Attr.getName().str() + "AppertainsTo";
std::stringstream SS;
SS << "static bool " << FnName << "(Sema &S, const AttributeList &Attr, ";
SS << "const Decl *D) {\n";
@@ -2790,8 +2801,10 @@ static std::string GenerateLangOptRequirements(const Record &R,
std::string FnName = "check", Test;
for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) {
std::string Part = (*I)->getValueAsString("Name");
- if ((*I)->getValueAsBit("Negated"))
+ if ((*I)->getValueAsBit("Negated")) {
+ FnName += "Not";
Test += "!";
+ }
Test += "S.LangOpts." + Part;
if (I + 1 != E)
Test += " || ";
@@ -2853,7 +2866,7 @@ static std::string GenerateTargetRequirements(const Record &Attr,
if (I.first == APK) {
std::vector<std::string> DA = I.second->getValueAsDef("Target")
->getValueAsListOfStrings("Arches");
- std::copy(DA.begin(), DA.end(), std::back_inserter(Arches));
+ std::move(DA.begin(), DA.end(), std::back_inserter(Arches));
}
}
}
@@ -2901,7 +2914,7 @@ static std::string GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
// Generate the enumeration we will use for the mapping.
SemanticSpellingMap SemanticToSyntacticMap;
std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
- std::string Name = Attr.getName() + "AttrSpellingMap";
+ std::string Name = Attr.getName().str() + "AttrSpellingMap";
OS << "static unsigned " << Name << "(const AttributeList &Attr) {\n";
OS << Enum;
@@ -2915,12 +2928,9 @@ static std::string GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
static bool IsKnownToGCC(const Record &Attr) {
// Look at the spellings for this subject; if there are any spellings which
// claim to be known to GCC, the attribute is known to GCC.
- std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
- for (const auto &I : Spellings) {
- if (I.knownToGCC())
- return true;
- }
- return false;
+ return llvm::any_of(
+ GetFlattenedSpellings(Attr),
+ [](const FlattenedSpelling &S) { return S.knownToGCC(); });
}
/// Emits the parsed attribute helpers
@@ -2982,7 +2992,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Attribute name matcher", OS);
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
- std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords, Pragma;
+ std::vector<StringMatcher::StringPair> GNU, Declspec, Microsoft, CXX11,
+ Keywords, Pragma;
std::set<std::string> Seen;
for (const auto *A : Attrs) {
const Record &Attr = *A;
@@ -3024,6 +3035,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
Matches = &GNU;
else if (Variety == "Declspec")
Matches = &Declspec;
+ else if (Variety == "Microsoft")
+ Matches = &Microsoft;
else if (Variety == "Keyword")
Matches = &Keywords;
else if (Variety == "Pragma")
@@ -3031,7 +3044,11 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
assert(Matches && "Unsupported spelling variety found");
- Spelling += NormalizeAttrSpelling(RawSpelling);
+ if (Variety == "GNU")
+ Spelling += NormalizeGNUAttrSpelling(RawSpelling);
+ else
+ Spelling += RawSpelling;
+
if (SemaHandler)
Matches->push_back(StringMatcher::StringPair(Spelling,
"return AttributeList::AT_" + AttrName + ";"));
@@ -3048,6 +3065,8 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
StringMatcher("Name", GNU, OS).Emit();
OS << " } else if (AttributeList::AS_Declspec == Syntax) {\n";
StringMatcher("Name", Declspec, OS).Emit();
+ OS << " } else if (AttributeList::AS_Microsoft == Syntax) {\n";
+ StringMatcher("Name", Microsoft, OS).Emit();
OS << " } else if (AttributeList::AS_CXX11 == Syntax) {\n";
StringMatcher("Name", CXX11, OS).Emit();
OS << " } else if (AttributeList::AS_Keyword == Syntax || ";
@@ -3131,8 +3150,9 @@ enum SpellingKind {
GNU = 1 << 0,
CXX11 = 1 << 1,
Declspec = 1 << 2,
- Keyword = 1 << 3,
- Pragma = 1 << 4
+ Microsoft = 1 << 3,
+ Keyword = 1 << 4,
+ Pragma = 1 << 5
};
static void WriteDocumentation(const DocumentationData &Doc,
@@ -3180,6 +3200,7 @@ static void WriteDocumentation(const DocumentationData &Doc,
.Case("GNU", GNU)
.Case("CXX11", CXX11)
.Case("Declspec", Declspec)
+ .Case("Microsoft", Microsoft)
.Case("Keyword", Keyword)
.Case("Pragma", Pragma);
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
index bbc2bdb..cad08af 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -14,14 +14,12 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/StringToOffsetTable.h"
@@ -145,6 +143,11 @@ static bool beforeThanCompare(const Record *LHS, const Record *RHS) {
LHS->getLoc().front().getPointer() < RHS->getLoc().front().getPointer();
}
+static bool diagGroupBeforeByName(const Record *LHS, const Record *RHS) {
+ return LHS->getValueAsString("GroupName") <
+ RHS->getValueAsString("GroupName");
+}
+
static bool beforeThanCompareGroups(const GroupInfo *LHS, const GroupInfo *RHS){
assert(!LHS->DiagsInGroup.empty() && !RHS->DiagsInGroup.empty());
return beforeThanCompare(LHS->DiagsInGroup.front(),
@@ -896,4 +899,444 @@ void EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS) {
OS << "DIAG_NAME_INDEX(" << R.Name << ")\n";
}
}
+
+//===----------------------------------------------------------------------===//
+// Diagnostic documentation generation
+//===----------------------------------------------------------------------===//
+
+namespace docs {
+namespace {
+
+/// Diagnostic text, parsed into pieces.
+struct DiagText {
+ struct Piece {
+ // This type and its derived classes are move-only.
+ Piece() {}
+ Piece(Piece &&O) {}
+ Piece &operator=(Piece &&O) { return *this; }
+
+ virtual void print(std::vector<std::string> &RST) = 0;
+ virtual ~Piece() {}
+ };
+ struct TextPiece : Piece {
+ StringRef Role;
+ std::string Text;
+ void print(std::vector<std::string> &RST) override;
+ };
+ struct PlaceholderPiece : Piece {
+ int Index;
+ void print(std::vector<std::string> &RST) override;
+ };
+ struct SelectPiece : Piece {
+ SelectPiece() {}
+ SelectPiece(SelectPiece &&O) noexcept : Options(std::move(O.Options)) {}
+ std::vector<DiagText> Options;
+ void print(std::vector<std::string> &RST) override;
+ };
+
+ std::vector<std::unique_ptr<Piece>> Pieces;
+
+ DiagText();
+ DiagText(DiagText &&O) noexcept : Pieces(std::move(O.Pieces)) {}
+
+ DiagText(StringRef Text);
+ DiagText(StringRef Kind, StringRef Text);
+
+ template<typename P> void add(P Piece) {
+ Pieces.push_back(llvm::make_unique<P>(std::move(Piece)));
+ }
+ void print(std::vector<std::string> &RST);
+};
+
+DiagText parseDiagText(StringRef &Text, bool Nested = false) {
+ DiagText Parsed;
+
+ while (!Text.empty()) {
+ size_t End = (size_t)-2;
+ do
+ End = Nested ? Text.find_first_of("%|}", End + 2)
+ : Text.find_first_of('%', End + 2);
+ while (End < Text.size() - 1 && Text[End] == '%' && Text[End + 1] == '%');
+
+ if (End) {
+ DiagText::TextPiece Piece;
+ Piece.Role = "diagtext";
+ Piece.Text = Text.slice(0, End);
+ Parsed.add(std::move(Piece));
+ Text = Text.slice(End, StringRef::npos);
+ if (Text.empty()) break;
+ }
+
+ if (Text[0] == '|' || Text[0] == '}')
+ break;
+
+ // Drop the '%'.
+ Text = Text.drop_front();
+
+ // Extract the (optional) modifier.
+ size_t ModLength = Text.find_first_of("0123456789{");
+ StringRef Modifier = Text.slice(0, ModLength);
+ Text = Text.slice(ModLength, StringRef::npos);
+
+ // FIXME: Handle %ordinal here.
+ if (Modifier == "select" || Modifier == "plural") {
+ DiagText::SelectPiece Select;
+ do {
+ Text = Text.drop_front();
+ if (Modifier == "plural")
+ while (Text[0] != ':')
+ Text = Text.drop_front();
+ Select.Options.push_back(parseDiagText(Text, true));
+ assert(!Text.empty() && "malformed %select");
+ } while (Text.front() == '|');
+ Parsed.add(std::move(Select));
+
+ // Drop the trailing '}n'.
+ Text = Text.drop_front(2);
+ continue;
+ }
+
+ // For %diff, just take the second alternative (tree diagnostic). It would
+ // be preferable to take the first one, and replace the $ with the suitable
+ // placeholders.
+ if (Modifier == "diff") {
+ Text = Text.drop_front(); // '{'
+ parseDiagText(Text, true);
+ Text = Text.drop_front(); // '|'
+
+ DiagText D = parseDiagText(Text, true);
+ for (auto &P : D.Pieces)
+ Parsed.Pieces.push_back(std::move(P));
+
+ Text = Text.drop_front(4); // '}n,m'
+ continue;
+ }
+
+ if (Modifier == "s") {
+ Text = Text.drop_front();
+ DiagText::SelectPiece Select;
+ Select.Options.push_back(DiagText(""));
+ Select.Options.push_back(DiagText("s"));
+ Parsed.add(std::move(Select));
+ continue;
+ }
+
+ assert(!Text.empty() && isdigit(Text[0]) && "malformed placeholder");
+ DiagText::PlaceholderPiece Placeholder;
+ Placeholder.Index = Text[0] - '0';
+ Parsed.add(std::move(Placeholder));
+ Text = Text.drop_front();
+ continue;
+ }
+ return Parsed;
+}
+
+DiagText::DiagText() {}
+
+DiagText::DiagText(StringRef Text) : DiagText(parseDiagText(Text, false)) {}
+
+DiagText::DiagText(StringRef Kind, StringRef Text) : DiagText(parseDiagText(Text, false)) {
+ TextPiece Prefix;
+ Prefix.Role = Kind;
+ Prefix.Text = Kind;
+ Prefix.Text += ": ";
+ Pieces.insert(Pieces.begin(),
+ llvm::make_unique<TextPiece>(std::move(Prefix)));
+}
+
+void escapeRST(StringRef Str, std::string &Out) {
+ for (auto K : Str) {
+ if (StringRef("`*|_[]\\").count(K))
+ Out.push_back('\\');
+ Out.push_back(K);
+ }
+}
+
+template<typename It> void padToSameLength(It Begin, It End) {
+ size_t Width = 0;
+ for (It I = Begin; I != End; ++I)
+ Width = std::max(Width, I->size());
+ for (It I = Begin; I != End; ++I)
+ (*I) += std::string(Width - I->size(), ' ');
+}
+
+template<typename It> void makeTableRows(It Begin, It End) {
+ if (Begin == End) return;
+ padToSameLength(Begin, End);
+ for (It I = Begin; I != End; ++I)
+ *I = "|" + *I + "|";
+}
+
+void makeRowSeparator(std::string &Str) {
+ for (char &K : Str)
+ K = (K == '|' ? '+' : '-');
+}
+
+void DiagText::print(std::vector<std::string> &RST) {
+ if (Pieces.empty()) {
+ RST.push_back("");
+ return;
+ }
+
+ if (Pieces.size() == 1)
+ return Pieces[0]->print(RST);
+
+ std::string EmptyLinePrefix;
+ size_t Start = RST.size();
+ bool HasMultipleLines = true;
+ for (auto &P : Pieces) {
+ std::vector<std::string> Lines;
+ P->print(Lines);
+ if (Lines.empty())
+ continue;
+
+ // We need a vertical separator if either this or the previous piece is a
+ // multi-line piece, or this is the last piece.
+ const char *Separator = (Lines.size() > 1 || HasMultipleLines) ? "|" : "";
+ HasMultipleLines = Lines.size() > 1;
+
+ if (Start + Lines.size() > RST.size())
+ RST.resize(Start + Lines.size(), EmptyLinePrefix);
+
+ padToSameLength(Lines.begin(), Lines.end());
+ for (size_t I = 0; I != Lines.size(); ++I)
+ RST[Start + I] += Separator + Lines[I];
+ std::string Empty(Lines[0].size(), ' ');
+ for (size_t I = Start + Lines.size(); I != RST.size(); ++I)
+ RST[I] += Separator + Empty;
+ EmptyLinePrefix += Separator + Empty;
+ }
+ for (size_t I = Start; I != RST.size(); ++I)
+ RST[I] += "|";
+ EmptyLinePrefix += "|";
+
+ makeRowSeparator(EmptyLinePrefix);
+ RST.insert(RST.begin() + Start, EmptyLinePrefix);
+ RST.insert(RST.end(), EmptyLinePrefix);
+}
+
+void DiagText::TextPiece::print(std::vector<std::string> &RST) {
+ RST.push_back("");
+ auto &S = RST.back();
+
+ StringRef T = Text;
+ while (!T.empty() && T.front() == ' ') {
+ RST.back() += " |nbsp| ";
+ T = T.drop_front();
+ }
+
+ std::string Suffix;
+ while (!T.empty() && T.back() == ' ') {
+ Suffix += " |nbsp| ";
+ T = T.drop_back();
+ }
+
+ if (!T.empty()) {
+ S += ':';
+ S += Role;
+ S += ":`";
+ escapeRST(T, S);
+ S += '`';
+ }
+
+ S += Suffix;
+}
+
+void DiagText::PlaceholderPiece::print(std::vector<std::string> &RST) {
+ RST.push_back(std::string(":placeholder:`") + char('A' + Index) + "`");
+}
+
+void DiagText::SelectPiece::print(std::vector<std::string> &RST) {
+ std::vector<size_t> SeparatorIndexes;
+ SeparatorIndexes.push_back(RST.size());
+ RST.emplace_back();
+ for (auto &O : Options) {
+ O.print(RST);
+ SeparatorIndexes.push_back(RST.size());
+ RST.emplace_back();
+ }
+
+ makeTableRows(RST.begin() + SeparatorIndexes.front(),
+ RST.begin() + SeparatorIndexes.back() + 1);
+ for (size_t I : SeparatorIndexes)
+ makeRowSeparator(RST[I]);
+}
+
+bool isRemarkGroup(const Record *DiagGroup,
+ const std::map<std::string, GroupInfo> &DiagsInGroup) {
+ bool AnyRemarks = false, AnyNonRemarks = false;
+
+ std::function<void(StringRef)> Visit = [&](StringRef GroupName) {
+ auto &GroupInfo = DiagsInGroup.find(GroupName)->second;
+ for (const Record *Diag : GroupInfo.DiagsInGroup)
+ (isRemark(*Diag) ? AnyRemarks : AnyNonRemarks) = true;
+ for (const auto &Name : GroupInfo.SubGroups)
+ Visit(Name);
+ };
+ Visit(DiagGroup->getValueAsString("GroupName"));
+
+ if (AnyRemarks && AnyNonRemarks)
+ PrintFatalError(
+ DiagGroup->getLoc(),
+ "Diagnostic group contains both remark and non-remark diagnostics");
+ return AnyRemarks;
+}
+
+std::string getDefaultSeverity(const Record *Diag) {
+ return Diag->getValueAsDef("DefaultSeverity")->getValueAsString("Name");
+}
+
+std::set<std::string>
+getDefaultSeverities(const Record *DiagGroup,
+ const std::map<std::string, GroupInfo> &DiagsInGroup) {
+ std::set<std::string> States;
+
+ std::function<void(StringRef)> Visit = [&](StringRef GroupName) {
+ auto &GroupInfo = DiagsInGroup.find(GroupName)->second;
+ for (const Record *Diag : GroupInfo.DiagsInGroup)
+ States.insert(getDefaultSeverity(Diag));
+ for (const auto &Name : GroupInfo.SubGroups)
+ Visit(Name);
+ };
+ Visit(DiagGroup->getValueAsString("GroupName"));
+ return States;
+}
+
+void writeHeader(StringRef Str, raw_ostream &OS, char Kind = '-') {
+ OS << Str << "\n" << std::string(Str.size(), Kind) << "\n";
+}
+
+void writeDiagnosticText(StringRef Role, StringRef Text, raw_ostream &OS) {
+ if (Text == "%0")
+ OS << "The text of this diagnostic is not controlled by Clang.\n\n";
+ else {
+ std::vector<std::string> Out;
+ DiagText(Role, Text).print(Out);
+ for (auto &Line : Out)
+ OS << Line << "\n";
+ OS << "\n";
+ }
+}
+
+} // namespace
+} // namespace docs
+
+void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS) {
+ using namespace docs;
+
+ // Get the documentation introduction paragraph.
+ const Record *Documentation = Records.getDef("GlobalDocumentation");
+ if (!Documentation) {
+ PrintFatalError("The Documentation top-level definition is missing, "
+ "no documentation will be generated.");
+ return;
+ }
+
+ OS << Documentation->getValueAsString("Intro") << "\n";
+
+ std::vector<Record*> Diags =
+ Records.getAllDerivedDefinitions("Diagnostic");
+ std::vector<Record*> DiagGroups =
+ Records.getAllDerivedDefinitions("DiagGroup");
+ std::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName);
+
+ DiagGroupParentMap DGParentMap(Records);
+
+ std::map<std::string, GroupInfo> DiagsInGroup;
+ groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
+
+ // Compute the set of diagnostics that are in -Wpedantic.
+ {
+ RecordSet DiagsInPedanticSet;
+ RecordSet GroupsInPedanticSet;
+ InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
+ inferPedantic.compute(&DiagsInPedanticSet, &GroupsInPedanticSet);
+ auto &PedDiags = DiagsInGroup["pedantic"];
+ // Put the diagnostics into a deterministic order.
+ RecordVec DiagsInPedantic(DiagsInPedanticSet.begin(),
+ DiagsInPedanticSet.end());
+ RecordVec GroupsInPedantic(GroupsInPedanticSet.begin(),
+ GroupsInPedanticSet.end());
+ std::sort(DiagsInPedantic.begin(), DiagsInPedantic.end(),
+ beforeThanCompare);
+ std::sort(GroupsInPedantic.begin(), GroupsInPedantic.end(),
+ beforeThanCompare);
+ PedDiags.DiagsInGroup.insert(PedDiags.DiagsInGroup.end(),
+ DiagsInPedantic.begin(),
+ DiagsInPedantic.end());
+ for (auto *Group : GroupsInPedantic)
+ PedDiags.SubGroups.push_back(Group->getValueAsString("GroupName"));
+ }
+
+ // FIXME: Write diagnostic categories and link to diagnostic groups in each.
+
+ // Write out the diagnostic groups.
+ for (const Record *G : DiagGroups) {
+ bool IsRemarkGroup = isRemarkGroup(G, DiagsInGroup);
+ auto &GroupInfo = DiagsInGroup[G->getValueAsString("GroupName")];
+ bool IsSynonym = GroupInfo.DiagsInGroup.empty() &&
+ GroupInfo.SubGroups.size() == 1;
+
+ writeHeader((IsRemarkGroup ? "-R" : "-W") +
+ G->getValueAsString("GroupName"),
+ OS);
+
+ if (!IsSynonym) {
+ // FIXME: Ideally, all the diagnostics in a group should have the same
+ // default state, but that is not currently the case.
+ auto DefaultSeverities = getDefaultSeverities(G, DiagsInGroup);
+ if (!DefaultSeverities.empty() && !DefaultSeverities.count("Ignored")) {
+ bool AnyNonErrors = DefaultSeverities.count("Warning") ||
+ DefaultSeverities.count("Remark");
+ if (!AnyNonErrors)
+ OS << "This diagnostic is an error by default, but the flag ``-Wno-"
+ << G->getValueAsString("GroupName") << "`` can be used to disable "
+ << "the error.\n\n";
+ else
+ OS << "This diagnostic is enabled by default.\n\n";
+ } else if (DefaultSeverities.size() > 1) {
+ OS << "Some of the diagnostics controlled by this flag are enabled "
+ << "by default.\n\n";
+ }
+ }
+
+ if (!GroupInfo.SubGroups.empty()) {
+ if (IsSynonym)
+ OS << "Synonym for ";
+ else if (GroupInfo.DiagsInGroup.empty())
+ OS << "Controls ";
+ else
+ OS << "Also controls ";
+
+ bool First = true;
+ std::sort(GroupInfo.SubGroups.begin(), GroupInfo.SubGroups.end());
+ for (const auto &Name : GroupInfo.SubGroups) {
+ if (!First) OS << ", ";
+ OS << "`" << (IsRemarkGroup ? "-R" : "-W") << Name << "`_";
+ First = false;
+ }
+ OS << ".\n\n";
+ }
+
+ if (!GroupInfo.DiagsInGroup.empty()) {
+ OS << "**Diagnostic text:**\n\n";
+ for (const Record *D : GroupInfo.DiagsInGroup) {
+ auto Severity = getDefaultSeverity(D);
+ Severity[0] = tolower(Severity[0]);
+ if (Severity == "ignored")
+ Severity = IsRemarkGroup ? "remark" : "warning";
+ writeDiagnosticText(Severity, D->getValueAsString("Text"), OS);
+ }
+ }
+
+ auto Doc = G->getValueAsString("Documentation");
+ if (!Doc.empty())
+ OS << Doc;
+ else if (GroupInfo.SubGroups.empty() && GroupInfo.DiagsInGroup.empty())
+ OS << "This diagnostic flag exists for GCC compatibility, and has no "
+ "effect in Clang.\n";
+ OS << "\n";
+ }
+}
+
} // end namespace clang
diff --git a/contrib/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp
index b5313a0..49c1edc 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/NeonEmitter.cpp
@@ -24,24 +24,32 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/SetTheory.h"
-#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cstddef>
+#include <cstdint>
#include <deque>
#include <map>
+#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
+
using namespace llvm;
namespace {
@@ -76,6 +84,7 @@ enum ClassKind {
/// builtins. These must be kept in sync with the flags in
/// include/clang/Basic/TargetBuiltins.h.
namespace NeonTypeFlags {
+
enum { EltTypeMask = 0xf, UnsignedFlag = 0x10, QuadFlag = 0x20 };
enum EltType {
@@ -91,12 +100,10 @@ enum EltType {
Float32,
Float64
};
-}
-class Intrinsic;
+} // end namespace NeonTypeFlags
+
class NeonEmitter;
-class Type;
-class Variable;
//===----------------------------------------------------------------------===//
// TypeSpec
@@ -192,6 +199,7 @@ public:
//
void makeUnsigned() { Signed = false; }
void makeSigned() { Signed = true; }
+
void makeInteger(unsigned ElemWidth, bool Sign) {
Float = false;
Poly = false;
@@ -199,6 +207,7 @@ public:
Immediate = false;
ElementBitwidth = ElemWidth;
}
+
void makeImmediate(unsigned ElemWidth) {
Float = false;
Poly = false;
@@ -206,18 +215,22 @@ public:
Immediate = true;
ElementBitwidth = ElemWidth;
}
+
void makeScalar() {
Bitwidth = ElementBitwidth;
NumVectors = 0;
}
+
void makeOneVector() {
assert(isVector());
NumVectors = 1;
}
+
void doubleLanes() {
assert_with_loc(Bitwidth != 128, "Can't get bigger than 128!");
Bitwidth = 128;
}
+
void halveLanes() {
assert_with_loc(Bitwidth != 64, "Can't get smaller than 64!");
Bitwidth = 64;
@@ -369,6 +382,7 @@ public:
bool hasImmediate() const {
return Proto.find('i') != std::string::npos;
}
+
/// Return the parameter index of the immediate operand.
unsigned getImmediateIdx() const {
assert(hasImmediate());
@@ -379,6 +393,7 @@ public:
/// Return true if the intrinsic takes an splat operand.
bool hasSplat() const { return Proto.find('a') != std::string::npos; }
+
/// Return the parameter index of the splat operand.
unsigned getSplatIdx() const {
assert(hasSplat());
@@ -414,7 +429,7 @@ public:
return Idx;
}
- bool hasBody() const { return Body && Body->getValues().size() > 0; }
+ bool hasBody() const { return Body && !Body->getValues().empty(); }
void setNeededEarly() { NeededEarly = true; }
@@ -487,7 +502,6 @@ private:
std::pair<Type, std::string> emitDagOp(DagInit *DI);
std::pair<Type, std::string> emitDag(DagInit *DI);
};
-
};
//===----------------------------------------------------------------------===//
@@ -1071,7 +1085,7 @@ std::string Intrinsic::mangleName(std::string Name, ClassKind LocalCK) const {
Name == "vcvt_f32_f64" || Name == "vcvt_f64_f32")
return Name;
- if (typeCode.size() > 0) {
+ if (!typeCode.empty()) {
// If the name ends with _xN (N = 2,3,4), insert the typeCode before _xN.
if (Name.size() >= 3 && isdigit(Name.back()) &&
Name[Name.length() - 2] == 'x' && Name[Name.length() - 3] == '_')
@@ -1246,7 +1260,6 @@ void Intrinsic::emitReturnReversal() {
emitReverseVariable(RetVar, RetVar);
}
-
void Intrinsic::emitShadowedArgs() {
// Macro arguments are not type-checked like inline function arguments,
// so assign them to local temporaries to get the right type checking.
@@ -1397,7 +1410,7 @@ void Intrinsic::emitBody(StringRef CallPrefix) {
emitNewLine();
}
- if (!Body || Body->getValues().size() == 0) {
+ if (!Body || Body->getValues().empty()) {
// Nothing specific to output - must output a builtin.
emitBodyAsBuiltinCall();
return;
@@ -1465,14 +1478,14 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagOp(DagInit *DI) {
if (DI->getNumArgs() == 2) {
// Unary op.
std::pair<Type, std::string> R =
- emitDagArg(DI->getArg(1), DI->getArgName(1));
+ emitDagArg(DI->getArg(1), DI->getArgNameStr(1));
return std::make_pair(R.first, Op + R.second);
} else {
assert(DI->getNumArgs() == 3 && "Can only handle unary and binary ops!");
std::pair<Type, std::string> R1 =
- emitDagArg(DI->getArg(1), DI->getArgName(1));
+ emitDagArg(DI->getArg(1), DI->getArgNameStr(1));
std::pair<Type, std::string> R2 =
- emitDagArg(DI->getArg(2), DI->getArgName(2));
+ emitDagArg(DI->getArg(2), DI->getArgNameStr(2));
assert_with_loc(R1.first == R2.first, "Argument type mismatch!");
return std::make_pair(R1.first, R1.second + " " + Op + " " + R2.second);
}
@@ -1483,7 +1496,7 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCall(DagInit *DI) {
std::vector<std::string> Values;
for (unsigned I = 0; I < DI->getNumArgs() - 1; ++I) {
std::pair<Type, std::string> R =
- emitDagArg(DI->getArg(I + 1), DI->getArgName(I + 1));
+ emitDagArg(DI->getArg(I + 1), DI->getArgNameStr(I + 1));
Types.push_back(R.first);
Values.push_back(R.second);
}
@@ -1516,7 +1529,8 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCast(DagInit *DI,
bool IsBitCast){
// (cast MOD* VAL) -> cast VAL to type given by MOD.
std::pair<Type, std::string> R = emitDagArg(
- DI->getArg(DI->getNumArgs() - 1), DI->getArgName(DI->getNumArgs() - 1));
+ DI->getArg(DI->getNumArgs() - 1),
+ DI->getArgNameStr(DI->getNumArgs() - 1));
Type castToType = R.first;
for (unsigned ArgIdx = 0; ArgIdx < DI->getNumArgs() - 1; ++ArgIdx) {
@@ -1527,11 +1541,11 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCast(DagInit *DI,
// 4. The value "U" or "S" to switch the signedness.
// 5. The value "H" or "D" to half or double the bitwidth.
// 6. The value "8" to convert to 8-bit (signed) integer lanes.
- if (DI->getArgName(ArgIdx).size()) {
- assert_with_loc(Intr.Variables.find(DI->getArgName(ArgIdx)) !=
+ if (!DI->getArgNameStr(ArgIdx).empty()) {
+ assert_with_loc(Intr.Variables.find(DI->getArgNameStr(ArgIdx)) !=
Intr.Variables.end(),
"Variable not found");
- castToType = Intr.Variables[DI->getArgName(ArgIdx)].getType();
+ castToType = Intr.Variables[DI->getArgNameStr(ArgIdx)].getType();
} else {
StringInit *SI = dyn_cast<StringInit>(DI->getArg(ArgIdx));
assert_with_loc(SI, "Expected string type or $Name for cast type");
@@ -1589,6 +1603,7 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){
Elts.insert(Elts2.begin(), Elts2.begin() + (Elts2.size() / 2));
}
};
+
class HighHalf : public SetTheory::Operator {
public:
void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
@@ -1598,11 +1613,13 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){
Elts.insert(Elts2.begin() + (Elts2.size() / 2), Elts2.end());
}
};
+
class Rev : public SetTheory::Operator {
unsigned ElementSize;
public:
Rev(unsigned ElementSize) : ElementSize(ElementSize) {}
+
void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
ArrayRef<SMLoc> Loc) override {
SetTheory::RecSet Elts2;
@@ -1621,11 +1638,13 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){
Elts.insert(Revved.begin(), Revved.end());
}
};
+
class MaskExpander : public SetTheory::Expander {
unsigned N;
public:
MaskExpander(unsigned N) : N(N) {}
+
void expand(SetTheory &ST, Record *R, SetTheory::RecSet &Elts) override {
unsigned Addend = 0;
if (R->getName() == "mask0")
@@ -1641,9 +1660,9 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){
// (shuffle arg1, arg2, sequence)
std::pair<Type, std::string> Arg1 =
- emitDagArg(DI->getArg(0), DI->getArgName(0));
+ emitDagArg(DI->getArg(0), DI->getArgNameStr(0));
std::pair<Type, std::string> Arg2 =
- emitDagArg(DI->getArg(1), DI->getArgName(1));
+ emitDagArg(DI->getArg(1), DI->getArgNameStr(1));
assert_with_loc(Arg1.first == Arg2.first,
"Different types in arguments to shuffle!");
@@ -1685,7 +1704,8 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){
std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDup(DagInit *DI) {
assert_with_loc(DI->getNumArgs() == 1, "dup() expects one argument");
- std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), DI->getArgName(0));
+ std::pair<Type, std::string> A = emitDagArg(DI->getArg(0),
+ DI->getArgNameStr(0));
assert_with_loc(A.first.isScalar(), "dup() expects a scalar argument");
Type T = Intr.getBaseType();
@@ -1703,8 +1723,10 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDup(DagInit *DI) {
std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSplat(DagInit *DI) {
assert_with_loc(DI->getNumArgs() == 2, "splat() expects two arguments");
- std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), DI->getArgName(0));
- std::pair<Type, std::string> B = emitDagArg(DI->getArg(1), DI->getArgName(1));
+ std::pair<Type, std::string> A = emitDagArg(DI->getArg(0),
+ DI->getArgNameStr(0));
+ std::pair<Type, std::string> B = emitDagArg(DI->getArg(1),
+ DI->getArgNameStr(1));
assert_with_loc(B.first.isScalar(),
"splat() requires a scalar int as the second argument");
@@ -1720,13 +1742,15 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSplat(DagInit *DI) {
std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSaveTemp(DagInit *DI) {
assert_with_loc(DI->getNumArgs() == 2, "save_temp() expects two arguments");
- std::pair<Type, std::string> A = emitDagArg(DI->getArg(1), DI->getArgName(1));
+ std::pair<Type, std::string> A = emitDagArg(DI->getArg(1),
+ DI->getArgNameStr(1));
assert_with_loc(!A.first.isVoid(),
"Argument to save_temp() must have non-void type!");
- std::string N = DI->getArgName(0);
- assert_with_loc(N.size(), "save_temp() expects a name as the first argument");
+ std::string N = DI->getArgNameStr(0);
+ assert_with_loc(!N.empty(),
+ "save_temp() expects a name as the first argument");
assert_with_loc(Intr.Variables.find(N) == Intr.Variables.end(),
"Variable already defined!");
@@ -1762,7 +1786,7 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagLiteral(DagInit *DI){
std::pair<Type, std::string>
Intrinsic::DagEmitter::emitDagArg(Init *Arg, std::string ArgName) {
- if (ArgName.size()) {
+ if (!ArgName.empty()) {
assert_with_loc(!Arg->isComplete(),
"Arguments must either be DAGs or names, not both!");
assert_with_loc(Intr.Variables.find(ArgName) != Intr.Variables.end(),
@@ -1900,7 +1924,7 @@ Intrinsic &NeonEmitter::getIntrinsic(StringRef Name, ArrayRef<Type> Types) {
GoodVec.push_back(&I);
}
- assert_with_loc(GoodVec.size() > 0,
+ assert_with_loc(!GoodVec.empty(),
"No compatible intrinsic found - " + ErrMsg);
assert_with_loc(GoodVec.size() == 1, "Multiple overloads found - " + ErrMsg);
@@ -2157,9 +2181,9 @@ NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
OS << "case NEON::BI__builtin_neon_" << Def->getMangledName() << ": "
<< "i = " << Idx << ";";
- if (LowerBound.size())
+ if (!LowerBound.empty())
OS << " l = " << LowerBound << ";";
- if (UpperBound.size())
+ if (!UpperBound.empty())
OS << " u = " << UpperBound << ";";
OS << " break;\n";
@@ -2350,7 +2374,7 @@ void NeonEmitter::run(raw_ostream &OS) {
// Only emit a def when its requirements have been met.
// FIXME: This loop could be made faster, but it's fast enough for now.
bool MadeProgress = true;
- std::string InGuard = "";
+ std::string InGuard;
while (!Defs.empty() && MadeProgress) {
MadeProgress = false;
@@ -2393,13 +2417,17 @@ void NeonEmitter::run(raw_ostream &OS) {
}
namespace clang {
+
void EmitNeon(RecordKeeper &Records, raw_ostream &OS) {
NeonEmitter(Records).run(OS);
}
+
void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) {
NeonEmitter(Records).runHeader(OS);
}
+
void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) {
llvm_unreachable("Neon test generation no longer implemented!");
}
-} // End namespace clang
+
+} // end namespace clang
diff --git a/contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp b/contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp
index 7ccd715..6fb5b00 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp
+++ b/contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp
@@ -13,7 +13,6 @@
#include "TableGenBackends.h" // Declares all backends.
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/TableGen/Error.h"
@@ -53,7 +52,8 @@ enum ActionType {
GenArmNeon,
GenArmNeonSema,
GenArmNeonTest,
- GenAttrDocs
+ GenAttrDocs,
+ GenDiagDocs
};
namespace {
@@ -134,7 +134,8 @@ cl::opt<ActionType> Action(
"Generate ARM NEON tests for clang"),
clEnumValN(GenAttrDocs, "gen-attr-docs",
"Generate attribute documentation"),
- clEnumValEnd));
+ clEnumValN(GenDiagDocs, "gen-diag-docs",
+ "Generate attribute documentation")));
cl::opt<std::string>
ClangComponent("clang-component",
@@ -234,6 +235,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenAttrDocs:
EmitClangAttrDocs(Records, OS);
break;
+ case GenDiagDocs:
+ EmitClangDiagDocs(Records, OS);
+ break;
}
return false;
diff --git a/contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h b/contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h
index 4adf368..0305ed1 100644
--- a/contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h
+++ b/contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h
@@ -69,6 +69,7 @@ void EmitNeonSema2(RecordKeeper &Records, raw_ostream &OS);
void EmitNeonTest2(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS);
} // end namespace clang
OpenPOWER on IntegriCloud