aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /utils/TableGen
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
Notes
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/ClangAttrEmitter.cpp275
-rw-r--r--utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp2
-rw-r--r--utils/TableGen/ClangDiagnosticsEmitter.cpp18
-rw-r--r--utils/TableGen/ClangOptionDocEmitter.cpp6
-rw-r--r--utils/TableGen/ClangSACheckersEmitter.cpp276
-rw-r--r--utils/TableGen/NeonEmitter.cpp43
-rw-r--r--utils/TableGen/TableGen.cpp28
-rw-r--r--utils/TableGen/TableGenBackends.h88
8 files changed, 317 insertions, 419 deletions
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 6b3df825808f..874ad2df0031 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -603,14 +603,15 @@ namespace {
OS << " OS << \"";
}
- void writeDump(raw_ostream &OS) const override {}
+ void writeDump(raw_ostream &OS) const override {
+ OS << " if (!SA->is" << getUpperName() << "Expr())\n";
+ OS << " dumpType(SA->get" << getUpperName()
+ << "Type()->getType());\n";
+ }
void writeDumpChildren(raw_ostream &OS) const override {
OS << " if (SA->is" << getUpperName() << "Expr())\n";
OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n";
- OS << " else\n";
- OS << " dumpType(SA->get" << getUpperName()
- << "Type()->getType());\n";
}
void writeHasChildren(raw_ostream &OS) const override {
@@ -1885,19 +1886,15 @@ void PragmaClangAttributeSupport::emitMatchRuleList(raw_ostream &OS) {
bool PragmaClangAttributeSupport::isAttributedSupported(
const Record &Attribute) {
- if (Attribute.getValueAsBit("ForcePragmaAttributeSupport"))
- return true;
+ // If the attribute explicitly specified whether to support #pragma clang
+ // attribute, use that setting.
+ bool Unset;
+ bool SpecifiedResult =
+ Attribute.getValueAsBitOrUnset("PragmaAttributeSupport", Unset);
+ if (!Unset)
+ return SpecifiedResult;
+
// Opt-out rules:
- // FIXME: The documentation check should be moved before
- // the ForcePragmaAttributeSupport check after annotate is documented.
- // No documentation present.
- if (Attribute.isValueUnset("Documentation"))
- return false;
- std::vector<Record *> Docs = Attribute.getValueAsListOfDefs("Documentation");
- if (Docs.empty())
- return false;
- if (Docs.size() == 1 && Docs[0]->getName() == "Undocumented")
- return false;
// An attribute requires delayed parsing (LateParsed is on)
if (Attribute.getValueAsBit("LateParsed"))
return false;
@@ -2470,8 +2467,10 @@ namespace {
static const AttrClassDescriptor AttrClassDescriptors[] = {
{ "ATTR", "Attr" },
+ { "TYPE_ATTR", "TypeAttr" },
{ "STMT_ATTR", "StmtAttr" },
{ "INHERITABLE_ATTR", "InheritableAttr" },
+ { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" },
{ "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" },
{ "PARAMETER_ABI_ATTR", "ParameterABIAttr" }
};
@@ -2937,9 +2936,9 @@ void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
if (I != List.cbegin())
OS << " else ";
if (I->first.empty())
- OS << "if (!Scope || Scope->getName() == \"\") {\n";
+ OS << "if (ScopeName == \"\") {\n";
else
- OS << "if (Scope->getName() == \"" << I->first << "\") {\n";
+ OS << "if (ScopeName == \"" << I->first << "\") {\n";
OS << " return llvm::StringSwitch<int>(Name)\n";
GenerateHasAttrSpellingStringSwitch(I->second, OS, Spelling, I->first);
OS << "}";
@@ -3335,7 +3334,7 @@ static std::string GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
SS << (Warn ? "warn_attribute_wrong_decl_type_str" :
"err_attribute_wrong_decl_type_str");
SS << ")\n";
- SS << " << Attr.getName() << ";
+ SS << " << Attr << ";
SS << CalculateDiagnostic(*SubjectObj) << ";\n";
SS << " return false;\n";
SS << " }\n";
@@ -3699,39 +3698,67 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
}
// Emits the code to dump an attribute.
-void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
- emitSourceFileHeader("Attribute dumper", OS);
+void EmitClangAttrTextNodeDump(RecordKeeper &Records, raw_ostream &OS) {
+ emitSourceFileHeader("Attribute text node dumper", OS);
- OS << " switch (A->getKind()) {\n";
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
for (const auto *Attr : Attrs) {
const Record &R = *Attr;
if (!R.getValueAsBit("ASTNode"))
continue;
- OS << " case attr::" << R.getName() << ": {\n";
// If the attribute has a semantically-meaningful name (which is determined
// by whether there is a Spelling enumeration for it), then write out the
// spelling used for the attribute.
+
+ std::string FunctionContent;
+ llvm::raw_string_ostream SS(FunctionContent);
+
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
if (Spellings.size() > 1 && !SpellingNamesAreCommon(Spellings))
- OS << " OS << \" \" << A->getSpelling();\n";
+ SS << " OS << \" \" << A->getSpelling();\n";
Args = R.getValueAsListOfDefs("Args");
- if (!Args.empty()) {
- OS << " const auto *SA = cast<" << R.getName()
- << "Attr>(A);\n";
- for (const auto *Arg : Args)
- createArgument(*Arg, R.getName())->writeDump(OS);
+ for (const auto *Arg : Args)
+ createArgument(*Arg, R.getName())->writeDump(SS);
- for (const auto *AI : Args)
- createArgument(*AI, R.getName())->writeDumpChildren(OS);
+ if (SS.tell()) {
+ OS << " void Visit" << R.getName() << "Attr(const " << R.getName()
+ << "Attr *A) {\n";
+ if (!Args.empty())
+ OS << " const auto *SA = cast<" << R.getName()
+ << "Attr>(A); (void)SA;\n";
+ OS << SS.str();
+ OS << " }\n";
+ }
+ }
+}
+
+void EmitClangAttrNodeTraverse(RecordKeeper &Records, raw_ostream &OS) {
+ emitSourceFileHeader("Attribute text node traverser", OS);
+
+ std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
+ for (const auto *Attr : Attrs) {
+ const Record &R = *Attr;
+ if (!R.getValueAsBit("ASTNode"))
+ continue;
+
+ std::string FunctionContent;
+ llvm::raw_string_ostream SS(FunctionContent);
+
+ Args = R.getValueAsListOfDefs("Args");
+ for (const auto *Arg : Args)
+ createArgument(*Arg, R.getName())->writeDumpChildren(SS);
+ if (SS.tell()) {
+ OS << " void Visit" << R.getName() << "Attr(const " << R.getName()
+ << "Attr *A) {\n";
+ if (!Args.empty())
+ OS << " const auto *SA = cast<" << R.getName()
+ << "Attr>(A); (void)SA;\n";
+ OS << SS.str();
+ OS << " }\n";
}
- OS <<
- " break;\n"
- " }\n";
}
- OS << " }\n";
}
void EmitClangAttrParserStringSwitches(RecordKeeper &Records,
@@ -3749,18 +3776,66 @@ void EmitClangAttrSubjectMatchRulesParserStringSwitches(RecordKeeper &Records,
getPragmaAttributeSupport(Records).generateParsingHelpers(OS);
}
+enum class SpellingKind {
+ GNU,
+ CXX11,
+ C2x,
+ Declspec,
+ Microsoft,
+ Keyword,
+ Pragma,
+};
+static const size_t NumSpellingKinds = (size_t)SpellingKind::Pragma + 1;
+
+class SpellingList {
+ std::vector<std::string> Spellings[NumSpellingKinds];
+
+public:
+ ArrayRef<std::string> operator[](SpellingKind K) const {
+ return Spellings[(size_t)K];
+ }
+
+ void add(const Record &Attr, FlattenedSpelling Spelling) {
+ SpellingKind Kind = StringSwitch<SpellingKind>(Spelling.variety())
+ .Case("GNU", SpellingKind::GNU)
+ .Case("CXX11", SpellingKind::CXX11)
+ .Case("C2x", SpellingKind::C2x)
+ .Case("Declspec", SpellingKind::Declspec)
+ .Case("Microsoft", SpellingKind::Microsoft)
+ .Case("Keyword", SpellingKind::Keyword)
+ .Case("Pragma", SpellingKind::Pragma);
+ std::string Name;
+ if (!Spelling.nameSpace().empty()) {
+ switch (Kind) {
+ case SpellingKind::CXX11:
+ case SpellingKind::C2x:
+ Name = Spelling.nameSpace() + "::";
+ break;
+ case SpellingKind::Pragma:
+ Name = Spelling.nameSpace() + " ";
+ break;
+ default:
+ PrintFatalError(Attr.getLoc(), "Unexpected namespace in spelling");
+ }
+ }
+ Name += Spelling.name();
+
+ Spellings[(size_t)Kind].push_back(Name);
+ }
+};
+
class DocumentationData {
public:
const Record *Documentation;
const Record *Attribute;
std::string Heading;
- unsigned SupportedSpellings;
+ SpellingList SupportedSpellings;
DocumentationData(const Record &Documentation, const Record &Attribute,
- const std::pair<std::string, unsigned> HeadingAndKinds)
+ std::pair<std::string, SpellingList> HeadingAndSpellings)
: Documentation(&Documentation), Attribute(&Attribute),
- Heading(std::move(HeadingAndKinds.first)),
- SupportedSpellings(HeadingAndKinds.second) {}
+ Heading(std::move(HeadingAndSpellings.first)),
+ SupportedSpellings(std::move(HeadingAndSpellings.second)) {}
};
static void WriteCategoryHeader(const Record *DocCategory,
@@ -3776,28 +3851,21 @@ static void WriteCategoryHeader(const Record *DocCategory,
OS << "\n\n";
}
-enum SpellingKind {
- GNU = 1 << 0,
- CXX11 = 1 << 1,
- C2x = 1 << 2,
- Declspec = 1 << 3,
- Microsoft = 1 << 4,
- Keyword = 1 << 5,
- Pragma = 1 << 6
-};
-
-static std::pair<std::string, unsigned>
-GetAttributeHeadingAndSpellingKinds(const Record &Documentation,
- const Record &Attribute) {
+static std::pair<std::string, SpellingList>
+GetAttributeHeadingAndSpellings(const Record &Documentation,
+ const Record &Attribute) {
// FIXME: there is no way to have a per-spelling category for the attribute
// documentation. This may not be a limiting factor since the spellings
// should generally be consistently applied across the category.
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute);
+ if (Spellings.empty())
+ PrintFatalError(Attribute.getLoc(),
+ "Attribute has no supported spellings; cannot be "
+ "documented");
// Determine the heading to be used for this attribute.
std::string Heading = Documentation.getValueAsString("Heading");
- bool CustomHeading = !Heading.empty();
if (Heading.empty()) {
// If there's only one spelling, we can simply use that.
if (Spellings.size() == 1)
@@ -3821,51 +3889,11 @@ GetAttributeHeadingAndSpellingKinds(const Record &Documentation,
PrintFatalError(Attribute.getLoc(),
"This attribute requires a heading to be specified");
- // Gather a list of unique spellings; this is not the same as the semantic
- // spelling for the attribute. Variations in underscores and other non-
- // semantic characters are still acceptable.
- std::vector<std::string> Names;
+ SpellingList SupportedSpellings;
+ for (const auto &I : Spellings)
+ SupportedSpellings.add(Attribute, I);
- unsigned SupportedSpellings = 0;
- for (const auto &I : Spellings) {
- SpellingKind Kind = StringSwitch<SpellingKind>(I.variety())
- .Case("GNU", GNU)
- .Case("CXX11", CXX11)
- .Case("C2x", C2x)
- .Case("Declspec", Declspec)
- .Case("Microsoft", Microsoft)
- .Case("Keyword", Keyword)
- .Case("Pragma", Pragma);
-
- // Mask in the supported spelling.
- SupportedSpellings |= Kind;
-
- std::string Name;
- if ((Kind == CXX11 || Kind == C2x) && !I.nameSpace().empty())
- Name = I.nameSpace() + "::";
- Name += I.name();
-
- // If this name is the same as the heading, do not add it.
- if (Name != Heading)
- Names.push_back(Name);
- }
-
- // Print out the heading for the attribute. If there are alternate spellings,
- // then display those after the heading.
- if (!CustomHeading && !Names.empty()) {
- Heading += " (";
- for (auto I = Names.begin(), E = Names.end(); I != E; ++I) {
- if (I != Names.begin())
- Heading += ", ";
- Heading += *I;
- }
- Heading += ")";
- }
- if (!SupportedSpellings)
- PrintFatalError(Attribute.getLoc(),
- "Attribute has no supported spellings; cannot be "
- "documented");
- return std::make_pair(std::move(Heading), SupportedSpellings);
+ return std::make_pair(std::move(Heading), std::move(SupportedSpellings));
}
static void WriteDocumentation(RecordKeeper &Records,
@@ -3874,23 +3902,30 @@ static void WriteDocumentation(RecordKeeper &Records,
// List what spelling syntaxes the attribute supports.
OS << ".. csv-table:: Supported Syntaxes\n";
- OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"__declspec\", \"Keyword\",";
- OS << " \"Pragma\", \"Pragma clang attribute\"\n\n";
+ OS << " :header: \"GNU\", \"C++11\", \"C2x\", \"``__declspec``\",";
+ OS << " \"Keyword\", \"``#pragma``\", \"``#pragma clang attribute``\"\n\n";
OS << " \"";
- if (Doc.SupportedSpellings & GNU) OS << "X";
- OS << "\",\"";
- if (Doc.SupportedSpellings & CXX11) OS << "X";
- OS << "\",\"";
- if (Doc.SupportedSpellings & C2x) OS << "X";
- OS << "\",\"";
- if (Doc.SupportedSpellings & Declspec) OS << "X";
- OS << "\",\"";
- if (Doc.SupportedSpellings & Keyword) OS << "X";
- OS << "\", \"";
- if (Doc.SupportedSpellings & Pragma) OS << "X";
- OS << "\", \"";
- if (getPragmaAttributeSupport(Records).isAttributedSupported(*Doc.Attribute))
- OS << "X";
+ for (size_t Kind = 0; Kind != NumSpellingKinds; ++Kind) {
+ SpellingKind K = (SpellingKind)Kind;
+ // TODO: List Microsoft (IDL-style attribute) spellings once we fully
+ // support them.
+ if (K == SpellingKind::Microsoft)
+ continue;
+
+ bool PrintedAny = false;
+ for (StringRef Spelling : Doc.SupportedSpellings[K]) {
+ if (PrintedAny)
+ OS << " |br| ";
+ OS << "``" << Spelling << "``";
+ PrintedAny = true;
+ }
+
+ OS << "\",\"";
+ }
+
+ if (getPragmaAttributeSupport(Records).isAttributedSupported(
+ *Doc.Attribute))
+ OS << "Yes";
OS << "\"\n\n";
// If the attribute is deprecated, print a message about it, and possibly
@@ -3946,7 +3981,7 @@ void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS) {
if (!Undocumented)
SplitDocs[Category].push_back(DocumentationData(
- Doc, Attr, GetAttributeHeadingAndSpellingKinds(Doc, Attr)));
+ Doc, Attr, GetAttributeHeadingAndSpellings(Doc, Attr)));
}
}
@@ -3955,10 +3990,10 @@ void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS) {
for (auto &I : SplitDocs) {
WriteCategoryHeader(I.first, OS);
- llvm::sort(I.second.begin(), I.second.end(),
+ llvm::sort(I.second,
[](const DocumentationData &D1, const DocumentationData &D2) {
return D1.Heading < D2.Heading;
- });
+ });
// Walk over each of the attributes in the category and write out their
// documentation.
@@ -3971,12 +4006,7 @@ void EmitTestPragmaAttributeSupportedAttributes(RecordKeeper &Records,
raw_ostream &OS) {
PragmaClangAttributeSupport Support = getPragmaAttributeSupport(Records);
ParsedAttrMap Attrs = getParsedAttrList(Records);
- unsigned NumAttrs = 0;
- for (const auto &I : Attrs) {
- if (Support.isAttributedSupported(*I.second))
- ++NumAttrs;
- }
- OS << "#pragma clang attribute supports " << NumAttrs << " attributes:\n";
+ OS << "#pragma clang attribute supports the following attributes:\n";
for (const auto &I : Attrs) {
if (!Support.isAttributedSupported(*I.second))
continue;
@@ -4008,6 +4038,7 @@ void EmitTestPragmaAttributeSupportedAttributes(RecordKeeper &Records,
}
OS << ")\n";
}
+ OS << "End of supported attributes.\n";
}
} // end namespace clang
diff --git a/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp b/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
index bea97ae13289..7c114dbe8e18 100644
--- a/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
+++ b/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This tablegen backend emits an fficient function to translate HTML named
+// This tablegen backend emits an efficient function to translate HTML named
// character references to UTF-8 sequences.
//
//===----------------------------------------------------------------------===//
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp
index 6bfb3f9f61f5..f551d9328227 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -208,9 +208,9 @@ static void groupDiagnostics(const std::vector<Record*> &Diags,
E = SortedGroups.end();
I != E; ++I) {
MutableArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup;
- llvm::sort(GroupDiags.begin(), GroupDiags.end(), beforeThanCompare);
+ llvm::sort(GroupDiags, beforeThanCompare);
}
- llvm::sort(SortedGroups.begin(), SortedGroups.end(), beforeThanCompareGroups);
+ llvm::sort(SortedGroups, beforeThanCompareGroups);
// Warn about the same group being used anonymously in multiple places.
for (SmallVectorImpl<GroupInfo *>::const_iterator I = SortedGroups.begin(),
@@ -1595,10 +1595,10 @@ void EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS) {
Index.push_back(RecordIndexElement(R));
}
- llvm::sort(Index.begin(), Index.end(),
+ llvm::sort(Index,
[](const RecordIndexElement &Lhs, const RecordIndexElement &Rhs) {
return Lhs.Name < Rhs.Name;
- });
+ });
for (unsigned i = 0, e = Index.size(); i != e; ++i) {
const RecordIndexElement &R = Index[i];
@@ -1694,7 +1694,7 @@ void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS) {
std::vector<Record*> DiagGroups =
Records.getAllDerivedDefinitions("DiagGroup");
- llvm::sort(DiagGroups.begin(), DiagGroups.end(), diagGroupBeforeByName);
+ llvm::sort(DiagGroups, diagGroupBeforeByName);
DiagGroupParentMap DGParentMap(Records);
@@ -1713,10 +1713,8 @@ void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS) {
DiagsInPedanticSet.end());
RecordVec GroupsInPedantic(GroupsInPedanticSet.begin(),
GroupsInPedanticSet.end());
- llvm::sort(DiagsInPedantic.begin(), DiagsInPedantic.end(),
- beforeThanCompare);
- llvm::sort(GroupsInPedantic.begin(), GroupsInPedantic.end(),
- beforeThanCompare);
+ llvm::sort(DiagsInPedantic, beforeThanCompare);
+ llvm::sort(GroupsInPedantic, beforeThanCompare);
PedDiags.DiagsInGroup.insert(PedDiags.DiagsInGroup.end(),
DiagsInPedantic.begin(),
DiagsInPedantic.end());
@@ -1765,7 +1763,7 @@ void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS) {
OS << "Also controls ";
bool First = true;
- llvm::sort(GroupInfo.SubGroups.begin(), GroupInfo.SubGroups.end());
+ llvm::sort(GroupInfo.SubGroups);
for (const auto &Name : GroupInfo.SubGroups) {
if (!First) OS << ", ";
OS << "`" << (IsRemarkGroup ? "-R" : "-W") << Name << "`_";
diff --git a/utils/TableGen/ClangOptionDocEmitter.cpp b/utils/TableGen/ClangOptionDocEmitter.cpp
index 7fe487e54698..cf642ec92bd8 100644
--- a/utils/TableGen/ClangOptionDocEmitter.cpp
+++ b/utils/TableGen/ClangOptionDocEmitter.cpp
@@ -111,7 +111,7 @@ Documentation extractDocumentation(RecordKeeper &Records) {
auto DocumentationForOption = [&](Record *R) -> DocumentedOption {
auto &A = Aliases[R];
- llvm::sort(A.begin(), A.end(), CompareByName);
+ llvm::sort(A, CompareByName);
return {R, std::move(A)};
};
@@ -120,7 +120,7 @@ Documentation extractDocumentation(RecordKeeper &Records) {
Documentation D;
auto &Groups = GroupsInGroup[R];
- llvm::sort(Groups.begin(), Groups.end(), CompareByLocation);
+ llvm::sort(Groups, CompareByLocation);
for (Record *G : Groups) {
D.Groups.emplace_back();
D.Groups.back().Group = G;
@@ -129,7 +129,7 @@ Documentation extractDocumentation(RecordKeeper &Records) {
}
auto &Options = OptionsInGroup[R];
- llvm::sort(Options.begin(), Options.end(), CompareByName);
+ llvm::sort(Options, CompareByName);
for (Record *O : Options)
D.Options.push_back(DocumentationForOption(O));
diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp
index 4fda8e47e4a8..57850a438720 100644
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -11,34 +11,19 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <map>
#include <string>
+
using namespace llvm;
//===----------------------------------------------------------------------===//
// Static Analyzer Checkers Tables generation
//===----------------------------------------------------------------------===//
-/// True if it is specified hidden or a parent package is specified
-/// as hidden, otherwise false.
-static bool isHidden(const Record &R) {
- if (R.getValueAsBit("Hidden"))
- return true;
- // Not declared as hidden, check the parent package if it is hidden.
- if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("ParentPackage")))
- return isHidden(*DI->getDef());
-
- return false;
-}
-
-static bool isCheckerNamed(const Record *R) {
- return !R->getValueAsString("CheckerName").empty();
-}
-
static std::string getPackageFullName(const Record *R);
static std::string getParentPackageFullName(const Record *R) {
@@ -50,17 +35,19 @@ static std::string getParentPackageFullName(const Record *R) {
static std::string getPackageFullName(const Record *R) {
std::string name = getParentPackageFullName(R);
- if (!name.empty()) name += ".";
+ if (!name.empty())
+ name += ".";
+ assert(!R->getValueAsString("PackageName").empty());
name += R->getValueAsString("PackageName");
return name;
}
static std::string getCheckerFullName(const Record *R) {
std::string name = getParentPackageFullName(R);
- if (isCheckerNamed(R)) {
- if (!name.empty()) name += ".";
- name += R->getValueAsString("CheckerName");
- }
+ if (!name.empty())
+ name += ".";
+ assert(!R->getValueAsString("CheckerName").empty());
+ name += R->getValueAsString("CheckerName");
return name;
}
@@ -70,129 +57,49 @@ static std::string getStringValue(const Record &R, StringRef field) {
return std::string();
}
-namespace {
-struct GroupInfo {
- llvm::DenseSet<const Record*> Checkers;
- llvm::DenseSet<const Record *> SubGroups;
- bool Hidden;
- unsigned Index;
+// Calculates the integer value representing the BitsInit object
+static inline uint64_t getValueFromBitsInit(const BitsInit *B, const Record &R) {
+ assert(B->getNumBits() <= sizeof(uint64_t) * 8 && "BitInits' too long!");
- GroupInfo() : Hidden(false) { }
-};
+ uint64_t Value = 0;
+ for (unsigned i = 0, e = B->getNumBits(); i != e; ++i) {
+ const auto *Bit = dyn_cast<BitInit>(B->getBit(i));
+ if (Bit)
+ Value |= uint64_t(Bit->getValue()) << i;
+ else
+ PrintFatalError(R.getLoc(),
+ "missing Documentation for " + getCheckerFullName(&R));
+ }
+ return Value;
}
-static void addPackageToCheckerGroup(const Record *package, const Record *group,
- llvm::DenseMap<const Record *, GroupInfo *> &recordGroupMap) {
- llvm::DenseSet<const Record *> &checkers = recordGroupMap[package]->Checkers;
- for (llvm::DenseSet<const Record *>::iterator
- I = checkers.begin(), E = checkers.end(); I != E; ++I)
- recordGroupMap[group]->Checkers.insert(*I);
+static std::string getCheckerDocs(const Record &R) {
+ StringRef LandingPage;
+ if (BitsInit *BI = R.getValueAsBitsInit("Documentation")) {
+ uint64_t V = getValueFromBitsInit(BI, R);
+ if (V == 1)
+ LandingPage = "available_checks.html";
+ else if (V == 2)
+ LandingPage = "alpha_checks.html";
+ }
+
+ if (LandingPage.empty())
+ return "";
- llvm::DenseSet<const Record *> &subGroups = recordGroupMap[package]->SubGroups;
- for (llvm::DenseSet<const Record *>::iterator
- I = subGroups.begin(), E = subGroups.end(); I != E; ++I)
- addPackageToCheckerGroup(*I, group, recordGroupMap);
+ return (llvm::Twine("https://clang-analyzer.llvm.org/") + LandingPage + "#" +
+ getCheckerFullName(&R))
+ .str();
}
namespace clang {
void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker");
- llvm::DenseMap<const Record *, unsigned> checkerRecIndexMap;
- for (unsigned i = 0, e = checkers.size(); i != e; ++i)
- checkerRecIndexMap[checkers[i]] = i;
-
- // Invert the mapping of checkers to package/group into a one to many
- // mapping of packages/groups to checkers.
- std::map<std::string, GroupInfo> groupInfoByName;
- llvm::DenseMap<const Record *, GroupInfo *> recordGroupMap;
-
std::vector<Record*> packages = Records.getAllDerivedDefinitions("Package");
- for (unsigned i = 0, e = packages.size(); i != e; ++i) {
- Record *R = packages[i];
- std::string fullName = getPackageFullName(R);
- if (!fullName.empty()) {
- GroupInfo &info = groupInfoByName[fullName];
- info.Hidden = isHidden(*R);
- recordGroupMap[R] = &info;
- }
- }
-
- std::vector<Record*>
- checkerGroups = Records.getAllDerivedDefinitions("CheckerGroup");
- for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) {
- Record *R = checkerGroups[i];
- std::string name = R->getValueAsString("GroupName");
- if (!name.empty()) {
- GroupInfo &info = groupInfoByName[name];
- recordGroupMap[R] = &info;
- }
- }
- for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
- Record *R = checkers[i];
- Record *package = nullptr;
- if (DefInit *
- DI = dyn_cast<DefInit>(R->getValueInit("ParentPackage")))
- package = DI->getDef();
- if (!isCheckerNamed(R) && !package)
- PrintFatalError(R->getLoc(), "Checker '" + R->getName() +
- "' is neither named, nor in a package!");
-
- if (isCheckerNamed(R)) {
- // Create a pseudo-group to hold this checker.
- std::string fullName = getCheckerFullName(R);
- GroupInfo &info = groupInfoByName[fullName];
- info.Hidden = R->getValueAsBit("Hidden");
- recordGroupMap[R] = &info;
- info.Checkers.insert(R);
- } else {
- recordGroupMap[package]->Checkers.insert(R);
- }
+ using SortedRecords = llvm::StringMap<const Record *>;
- Record *currR = isCheckerNamed(R) ? R : package;
- // Insert the checker and its parent packages into the subgroups set of
- // the corresponding parent package.
- while (DefInit *DI
- = dyn_cast<DefInit>(currR->getValueInit("ParentPackage"))) {
- Record *parentPackage = DI->getDef();
- recordGroupMap[parentPackage]->SubGroups.insert(currR);
- currR = parentPackage;
- }
- // Insert the checker into the set of its group.
- if (DefInit *DI = dyn_cast<DefInit>(R->getValueInit("Group")))
- recordGroupMap[DI->getDef()]->Checkers.insert(R);
- }
-
- // If a package is in group, add all its checkers and its sub-packages
- // checkers into the group.
- for (unsigned i = 0, e = packages.size(); i != e; ++i)
- if (DefInit *DI = dyn_cast<DefInit>(packages[i]->getValueInit("Group")))
- addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap);
-
- typedef std::map<std::string, const Record *> SortedRecords;
- typedef llvm::DenseMap<const Record *, unsigned> RecToSortIndex;
-
- SortedRecords sortedGroups;
- RecToSortIndex groupToSortIndex;
- OS << "\n#ifdef GET_GROUPS\n";
- {
- for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i)
- sortedGroups[checkerGroups[i]->getValueAsString("GroupName")]
- = checkerGroups[i];
-
- unsigned sortIndex = 0;
- for (SortedRecords::iterator
- I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) {
- const Record *R = I->second;
-
- OS << "GROUP(" << "\"";
- OS.write_escaped(R->getValueAsString("GroupName")) << "\"";
- OS << ")\n";
-
- groupToSortIndex[R] = sortIndex++;
- }
- }
- OS << "#endif // GET_GROUPS\n\n";
+ OS << "// This file is automatically generated. Do not edit this file by "
+ "hand.\n";
OS << "\n#ifdef GET_PACKAGES\n";
{
@@ -205,17 +112,7 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
const Record &R = *I->second;
OS << "PACKAGE(" << "\"";
- OS.write_escaped(getPackageFullName(&R)) << "\", ";
- // Group index
- if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
- OS << groupToSortIndex[DI->getDef()] << ", ";
- else
- OS << "-1, ";
- // Hidden bit
- if (isHidden(R))
- OS << "true";
- else
- OS << "false";
+ OS.write_escaped(getPackageFullName(&R)) << '\"';
OS << ")\n";
}
}
@@ -226,98 +123,15 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {
const Record &R = *checkers[i];
OS << "CHECKER(" << "\"";
- std::string name;
- if (isCheckerNamed(&R))
- name = getCheckerFullName(&R);
- OS.write_escaped(name) << "\", ";
+ OS.write_escaped(getCheckerFullName(&R)) << "\", ";
OS << R.getName() << ", ";
- OS << getStringValue(R, "DescFile") << ", ";
OS << "\"";
OS.write_escaped(getStringValue(R, "HelpText")) << "\", ";
- // Group index
- if (DefInit *DI = dyn_cast<DefInit>(R.getValueInit("Group")))
- OS << groupToSortIndex[DI->getDef()] << ", ";
- else
- OS << "-1, ";
- // Hidden bit
- if (isHidden(R))
- OS << "true";
- else
- OS << "false";
+ OS << "\"";
+ OS.write_escaped(getCheckerDocs(R));
+ OS << "\"";
OS << ")\n";
}
OS << "#endif // GET_CHECKERS\n\n";
-
- unsigned index = 0;
- for (std::map<std::string, GroupInfo>::iterator
- I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I)
- I->second.Index = index++;
-
- // Walk through the packages/groups/checkers emitting an array for each
- // set of checkers and an array for each set of subpackages.
-
- OS << "\n#ifdef GET_MEMBER_ARRAYS\n";
- unsigned maxLen = 0;
- for (std::map<std::string, GroupInfo>::iterator
- I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) {
- maxLen = std::max(maxLen, (unsigned)I->first.size());
-
- llvm::DenseSet<const Record *> &checkers = I->second.Checkers;
- if (!checkers.empty()) {
- OS << "static const short CheckerArray" << I->second.Index << "[] = { ";
- // Make the output order deterministic.
- std::map<int, const Record *> sorted;
- for (llvm::DenseSet<const Record *>::iterator
- I = checkers.begin(), E = checkers.end(); I != E; ++I)
- sorted[(*I)->getID()] = *I;
-
- for (std::map<int, const Record *>::iterator
- I = sorted.begin(), E = sorted.end(); I != E; ++I)
- OS << checkerRecIndexMap[I->second] << ", ";
- OS << "-1 };\n";
- }
-
- llvm::DenseSet<const Record *> &subGroups = I->second.SubGroups;
- if (!subGroups.empty()) {
- OS << "static const short SubPackageArray" << I->second.Index << "[] = { ";
- // Make the output order deterministic.
- std::map<int, const Record *> sorted;
- for (llvm::DenseSet<const Record *>::iterator
- I = subGroups.begin(), E = subGroups.end(); I != E; ++I)
- sorted[(*I)->getID()] = *I;
-
- for (std::map<int, const Record *>::iterator
- I = sorted.begin(), E = sorted.end(); I != E; ++I) {
- OS << recordGroupMap[I->second]->Index << ", ";
- }
- OS << "-1 };\n";
- }
- }
- OS << "#endif // GET_MEMBER_ARRAYS\n\n";
-
- OS << "\n#ifdef GET_CHECKNAME_TABLE\n";
- for (std::map<std::string, GroupInfo>::iterator
- I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) {
- // Group option string.
- OS << " { \"";
- OS.write_escaped(I->first) << "\","
- << std::string(maxLen-I->first.size()+1, ' ');
-
- if (I->second.Checkers.empty())
- OS << "0, ";
- else
- OS << "CheckerArray" << I->second.Index << ", ";
-
- // Subgroups.
- if (I->second.SubGroups.empty())
- OS << "0, ";
- else
- OS << "SubPackageArray" << I->second.Index << ", ";
-
- OS << (I->second.Hidden ? "true" : "false");
-
- OS << " },\n";
- }
- OS << "#endif // GET_CHECKNAME_TABLE\n\n";
}
} // end namespace clang
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index eca03a5892e2..f92110d5d7ac 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -494,6 +494,7 @@ private:
std::pair<Type, std::string> emitDagSaveTemp(DagInit *DI);
std::pair<Type, std::string> emitDagSplat(DagInit *DI);
std::pair<Type, std::string> emitDagDup(DagInit *DI);
+ std::pair<Type, std::string> emitDagDupTyped(DagInit *DI);
std::pair<Type, std::string> emitDagShuffle(DagInit *DI);
std::pair<Type, std::string> emitDagCast(DagInit *DI, bool IsBitCast);
std::pair<Type, std::string> emitDagCall(DagInit *DI);
@@ -897,6 +898,18 @@ void Type::applyModifier(char Mod) {
Float = true;
ElementBitwidth = 16;
break;
+ case '0':
+ Float = true;
+ if (AppliedQuad)
+ Bitwidth /= 2;
+ ElementBitwidth = 16;
+ break;
+ case '1':
+ Float = true;
+ if (!AppliedQuad)
+ Bitwidth *= 2;
+ ElementBitwidth = 16;
+ break;
case 'g':
if (AppliedQuad)
Bitwidth /= 2;
@@ -1507,6 +1520,8 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDag(DagInit *DI) {
return emitDagShuffle(DI);
if (Op == "dup")
return emitDagDup(DI);
+ if (Op == "dup_typed")
+ return emitDagDupTyped(DI);
if (Op == "splat")
return emitDagSplat(DI);
if (Op == "save_temp")
@@ -1771,6 +1786,28 @@ std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDup(DagInit *DI) {
return std::make_pair(T, S);
}
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDupTyped(DagInit *DI) {
+ assert_with_loc(DI->getNumArgs() == 2, "dup_typed() expects two arguments");
+ 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(),
+ "dup_typed() requires a scalar as the second argument");
+
+ Type T = A.first;
+ assert_with_loc(T.isVector(), "dup_typed() used but target type is scalar!");
+ std::string S = "(" + T.str() + ") {";
+ for (unsigned I = 0; I < T.getNumElements(); ++I) {
+ if (I != 0)
+ S += ", ";
+ S += B.second;
+ }
+ S += "}";
+
+ return std::make_pair(T, S);
+}
+
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),
@@ -2020,7 +2057,7 @@ void NeonEmitter::createIntrinsic(Record *R,
}
}
- llvm::sort(NewTypeSpecs.begin(), NewTypeSpecs.end());
+ llvm::sort(NewTypeSpecs);
NewTypeSpecs.erase(std::unique(NewTypeSpecs.begin(), NewTypeSpecs.end()),
NewTypeSpecs.end());
auto &Entry = IntrinsicMap[Name];
@@ -2409,7 +2446,7 @@ void NeonEmitter::run(raw_ostream &OS) {
OS << "#endif\n";
OS << "\n";
- OS << "#define __ai static inline __attribute__((__always_inline__, "
+ OS << "#define __ai static __inline__ __attribute__((__always_inline__, "
"__nodebug__))\n\n";
SmallVector<Intrinsic *, 128> Defs;
@@ -2518,7 +2555,7 @@ void NeonEmitter::runFP16(raw_ostream &OS) {
OS << "typedef __fp16 float16_t;\n";
- OS << "#define __ai static inline __attribute__((__always_inline__, "
+ OS << "#define __ai static __inline__ __attribute__((__always_inline__, "
"__nodebug__))\n\n";
SmallVector<Intrinsic *, 128> Defs;
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index a2ba131628f1..f40d7f123353 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -23,6 +23,8 @@ using namespace llvm;
using namespace clang;
enum ActionType {
+ PrintRecords,
+ DumpJSON,
GenClangAttrClasses,
GenClangAttrParserStringSwitches,
GenClangAttrSubjectMatchRulesParserStringSwitches,
@@ -38,7 +40,8 @@ enum ActionType {
GenClangAttrParsedAttrList,
GenClangAttrParsedAttrImpl,
GenClangAttrParsedAttrKinds,
- GenClangAttrDump,
+ GenClangAttrTextNodeDump,
+ GenClangAttrNodeTraverse,
GenClangDiagsDefs,
GenClangDiagGroups,
GenClangDiagsIndexName,
@@ -66,6 +69,10 @@ namespace {
cl::opt<ActionType> Action(
cl::desc("Action to perform:"),
cl::values(
+ clEnumValN(PrintRecords, "print-records",
+ "Print all records to stdout (default)"),
+ clEnumValN(DumpJSON, "dump-json",
+ "Dump all records as machine-readable JSON"),
clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
"Generate clang attribute clases"),
clEnumValN(GenClangAttrParserStringSwitches,
@@ -106,8 +113,10 @@ cl::opt<ActionType> Action(
clEnumValN(GenClangAttrParsedAttrKinds,
"gen-clang-attr-parsed-attr-kinds",
"Generate a clang parsed attribute kinds"),
- clEnumValN(GenClangAttrDump, "gen-clang-attr-dump",
- "Generate clang attribute dumper"),
+ clEnumValN(GenClangAttrTextNodeDump, "gen-clang-attr-text-node-dump",
+ "Generate clang attribute text node dumper"),
+ clEnumValN(GenClangAttrNodeTraverse, "gen-clang-attr-node-traverse",
+ "Generate clang attribute traverser"),
clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
"Generate Clang diagnostics definitions"),
clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups",
@@ -164,6 +173,12 @@ ClangComponent("clang-component",
bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
switch (Action) {
+ case PrintRecords:
+ OS << Records; // No argument, dump all contents
+ break;
+ case DumpJSON:
+ EmitJSON(Records, OS);
+ break;
case GenClangAttrClasses:
EmitClangAttrClass(Records, OS);
break;
@@ -209,8 +224,11 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenClangAttrParsedAttrKinds:
EmitClangAttrParsedAttrKinds(Records, OS);
break;
- case GenClangAttrDump:
- EmitClangAttrDump(Records, OS);
+ case GenClangAttrTextNodeDump:
+ EmitClangAttrTextNodeDump(Records, OS);
+ break;
+ case GenClangAttrNodeTraverse:
+ EmitClangAttrNodeTraverse(Records, OS);
break;
case GenClangDiagsDefs:
EmitClangDiagsDefs(Records, OS, ClangComponent);
diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h
index 706e812ae874..410d0100be19 100644
--- a/utils/TableGen/TableGenBackends.h
+++ b/utils/TableGen/TableGenBackends.h
@@ -23,63 +23,63 @@ namespace llvm {
class RecordKeeper;
}
-using llvm::raw_ostream;
-using llvm::RecordKeeper;
-
namespace clang {
-void EmitClangDeclContext(RecordKeeper &RK, raw_ostream &OS);
-void EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS,
+void EmitClangDeclContext(llvm::RecordKeeper &RK, llvm::raw_ostream &OS);
+void EmitClangASTNodes(llvm::RecordKeeper &RK, llvm::raw_ostream &OS,
const std::string &N, const std::string &S);
-void EmitClangAttrParserStringSwitches(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrSubjectMatchRulesParserStringSwitches(RecordKeeper &Records,
- raw_ostream &OS);
-void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrParserStringSwitches(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrSubjectMatchRulesParserStringSwitches(llvm::RecordKeeper &Records,
+ llvm::raw_ostream &OS);
+void EmitClangAttrClass(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrImpl(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrSubjectMatchRuleList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrPCHRead(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrPCHWrite(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrHasAttrImpl(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrSpellingListIndex(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrASTVisitor(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrTemplateInstantiate(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrParsedAttrList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrParsedAttrImpl(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrParsedAttrKinds(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrTextNodeDump(llvm::RecordKeeper &Records,
+ llvm::raw_ostream &OS);
+void EmitClangAttrNodeTraverse(llvm::RecordKeeper &Records,
+ llvm::raw_ostream &OS);
-void EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS,
+void EmitClangDiagsDefs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS,
const std::string &Component);
-void EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangDiagGroups(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangDiagsIndexName(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
-void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangSACheckers(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
-void EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangCommentHTMLTagsProperties(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangCommentHTMLNamedCharacterReferences(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangCommentHTMLTags(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangCommentHTMLTagsProperties(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangCommentHTMLNamedCharacterReferences(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
-void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangCommentCommandInfo(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangCommentCommandList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
-void EmitNeon(RecordKeeper &Records, raw_ostream &OS);
-void EmitFP16(RecordKeeper &Records, raw_ostream &OS);
-void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS);
-void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS);
-void EmitNeon2(RecordKeeper &Records, raw_ostream &OS);
-void EmitNeonSema2(RecordKeeper &Records, raw_ostream &OS);
-void EmitNeonTest2(RecordKeeper &Records, raw_ostream &OS);
+void EmitNeon(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitFP16(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitNeonSema(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitNeonTest(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitNeon2(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitNeonSema2(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitNeonTest2(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
-void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangOptDocs(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrDocs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangDiagDocs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangOptDocs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
-void EmitClangDataCollectors(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangDataCollectors(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
-void EmitTestPragmaAttributeSupportedAttributes(RecordKeeper &Records,
- raw_ostream &OS);
+void EmitTestPragmaAttributeSupportedAttributes(llvm::RecordKeeper &Records,
+ llvm::raw_ostream &OS);
} // end namespace clang