//===----------------------------------------------------------------------===//
#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"
// 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;
}
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;
}
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]
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]
// 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
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";
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";
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";
}
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";
}
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";
}
// 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();
}
}
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";
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));
}
}
}
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