Revert r300539 - Add #pragma clang attribute

Some tests fail on the Windows buildbots. I will have to investigate more.
This commit reverts r300539, r300540 and r300542.

llvm-svn: 300543
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index 65dbccd..8aaa28b 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -12,15 +12,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TableGen/Error.h"
@@ -1524,334 +1522,6 @@
   OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
 }
 
-static bool hasGNUorCXX11Spelling(const Record &Attribute) {
-  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute);
-  for (const auto &I : Spellings) {
-    if (I.variety() == "GNU" || I.variety() == "CXX11")
-      return true;
-  }
-  return false;
-}
-
-namespace {
-
-struct AttributeSubjectMatchRule {
-  const Record *MetaSubject;
-  const Record *Constraint;
-
-  AttributeSubjectMatchRule(const Record *MetaSubject, const Record *Constraint)
-      : MetaSubject(MetaSubject), Constraint(Constraint) {
-    assert(MetaSubject && "Missing subject");
-  }
-
-  bool isSubRule() const { return Constraint != nullptr; }
-
-  std::vector<Record *> getSubjects() const {
-    return (Constraint ? Constraint : MetaSubject)
-        ->getValueAsListOfDefs("Subjects");
-  }
-
-  std::vector<Record *> getLangOpts() const {
-    if (Constraint) {
-      // Lookup the options in the sub-rule first, in case the sub-rule
-      // overrides the rules options.
-      std::vector<Record *> Opts = Constraint->getValueAsListOfDefs("LangOpts");
-      if (!Opts.empty())
-        return Opts;
-    }
-    return MetaSubject->getValueAsListOfDefs("LangOpts");
-  }
-
-  // Abstract rules are used only for sub-rules
-  bool isAbstractRule() const { return getSubjects().empty(); }
-
-  std::string getName() const {
-    return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name");
-  }
-
-  bool isNegatedSubRule() const {
-    assert(isSubRule() && "Not a sub-rule");
-    return Constraint->getValueAsBit("Negated");
-  }
-
-  std::string getSpelling() const {
-    std::string Result = MetaSubject->getValueAsString("Name");
-    if (isSubRule()) {
-      Result += '(';
-      if (isNegatedSubRule())
-        Result += "unless(";
-      Result += getName();
-      if (isNegatedSubRule())
-        Result += ')';
-      Result += ')';
-    }
-    return Result;
-  }
-
-  std::string getEnumValueName() const {
-    std::string Result =
-        "SubjectMatchRule_" + MetaSubject->getValueAsString("Name");
-    if (isSubRule()) {
-      Result += "_";
-      if (isNegatedSubRule())
-        Result += "not_";
-      Result += Constraint->getValueAsString("Name");
-    }
-    if (isAbstractRule())
-      Result += "_abstract";
-    return Result;
-  }
-
-  std::string getEnumValue() const { return "attr::" + getEnumValueName(); }
-
-  static const char *EnumName;
-};
-
-const char *AttributeSubjectMatchRule::EnumName = "attr::SubjectMatchRule";
-
-struct PragmaClangAttributeSupport {
-  std::vector<AttributeSubjectMatchRule> Rules;
-  llvm::DenseMap<const Record *, AttributeSubjectMatchRule> SubjectsToRules;
-
-  PragmaClangAttributeSupport(RecordKeeper &Records);
-
-  bool isAttributedSupported(const Record &Attribute);
-
-  void emitMatchRuleList(raw_ostream &OS);
-
-  std::string generateStrictConformsTo(const Record &Attr, raw_ostream &OS);
-
-  void generateParsingHelpers(raw_ostream &OS);
-};
-
-} // end anonymous namespace
-
-PragmaClangAttributeSupport::PragmaClangAttributeSupport(
-    RecordKeeper &Records) {
-  std::vector<Record *> MetaSubjects =
-      Records.getAllDerivedDefinitions("AttrSubjectMatcherRule");
-  auto MapFromSubjectsToRules = [this](const Record *SubjectContainer,
-                                       const Record *MetaSubject,
-                                       const Record *Constraint = nullptr) {
-    Rules.emplace_back(MetaSubject, Constraint);
-    std::vector<Record *> ApplicableSubjects =
-        SubjectContainer->getValueAsListOfDefs("Subjects");
-    for (const auto *Subject : ApplicableSubjects) {
-      bool Inserted =
-          SubjectsToRules.try_emplace(Subject, MetaSubject, Constraint).second;
-      if (!Inserted) {
-        PrintFatalError("Attribute subject match rules should not represent"
-                        "same attribute subjects.");
-      }
-    }
-  };
-  for (const auto *MetaSubject : MetaSubjects) {
-    MapFromSubjectsToRules(MetaSubject, MetaSubject);
-    std::vector<Record *> Constraints =
-        MetaSubject->getValueAsListOfDefs("Constraints");
-    for (const auto *Constraint : Constraints)
-      MapFromSubjectsToRules(Constraint, MetaSubject, Constraint);
-  }
-}
-
-static PragmaClangAttributeSupport &
-getPragmaAttributeSupport(RecordKeeper &Records) {
-  static PragmaClangAttributeSupport Instance(Records);
-  return Instance;
-}
-
-void PragmaClangAttributeSupport::emitMatchRuleList(raw_ostream &OS) {
-  OS << "#ifndef ATTR_MATCH_SUB_RULE\n";
-  OS << "#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, "
-        "IsNegated) "
-     << "ATTR_MATCH_RULE(Value, Spelling, IsAbstract)\n";
-  OS << "#endif\n";
-  for (const auto &Rule : Rules) {
-    OS << (Rule.isSubRule() ? "ATTR_MATCH_SUB_RULE" : "ATTR_MATCH_RULE") << '(';
-    OS << Rule.getEnumValueName() << ", \"" << Rule.getSpelling() << "\", "
-       << Rule.isAbstractRule();
-    if (Rule.isSubRule())
-      OS << ", "
-         << AttributeSubjectMatchRule(Rule.MetaSubject, nullptr).getEnumValue()
-         << ", " << Rule.isNegatedSubRule();
-    OS << ")\n";
-  }
-  OS << "#undef ATTR_MATCH_SUB_RULE\n";
-}
-
-bool PragmaClangAttributeSupport::isAttributedSupported(
-    const Record &Attribute) {
-  if (Attribute.getValueAsBit("ForcePragmaAttributeSupport"))
-    return true;
-  // 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;
-  // An attribute has no GNU/CXX11 spelling
-  if (!hasGNUorCXX11Spelling(Attribute))
-    return false;
-  // An attribute subject list has a subject that isn't covered by one of the
-  // subject match rules or has no subjects at all.
-  if (Attribute.isValueUnset("Subjects"))
-    return false;
-  const Record *SubjectObj = Attribute.getValueAsDef("Subjects");
-  std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
-  if (Subjects.empty())
-    return false;
-  for (const auto *Subject : Subjects) {
-    if (SubjectsToRules.find(Subject) == SubjectsToRules.end())
-      return false;
-  }
-  return true;
-}
-
-std::string
-PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr,
-                                                      raw_ostream &OS) {
-  if (!isAttributedSupported(Attr))
-    return "nullptr";
-  // Generate a function that constructs a set of matching rules that describe
-  // to which declarations the attribute should apply to.
-  std::string FnName = "matchRulesFor" + Attr.getName().str();
-  std::stringstream SS;
-  SS << "static void " << FnName << "(llvm::SmallVectorImpl<std::pair<"
-     << AttributeSubjectMatchRule::EnumName
-     << ", bool>> &MatchRules, const LangOptions &LangOpts) {\n";
-  if (Attr.isValueUnset("Subjects")) {
-    SS << "}\n\n";
-    OS << SS.str();
-    return FnName;
-  }
-  const Record *SubjectObj = Attr.getValueAsDef("Subjects");
-  std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
-  for (const auto *Subject : Subjects) {
-    auto It = SubjectsToRules.find(Subject);
-    assert(It != SubjectsToRules.end() &&
-           "This attribute is unsupported by #pragma clang attribute");
-    AttributeSubjectMatchRule Rule = It->getSecond();
-    // The rule might be language specific, so only subtract it from the given
-    // rules if the specific language options are specified.
-    std::vector<Record *> LangOpts = Rule.getLangOpts();
-    SS << "  MatchRules.push_back(std::make_pair(" << Rule.getEnumValue()
-       << ", /*IsSupported=*/";
-    if (!LangOpts.empty()) {
-      for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) {
-        std::string Part = (*I)->getValueAsString("Name");
-        if ((*I)->getValueAsBit("Negated"))
-          SS << "!";
-        SS << "LangOpts." + Part;
-        if (I + 1 != E)
-          SS << " || ";
-      }
-    } else
-      SS << "true";
-    SS << "));\n";
-  }
-  SS << "}\n\n";
-  OS << SS.str();
-  return FnName;
-}
-
-void PragmaClangAttributeSupport::generateParsingHelpers(raw_ostream &OS) {
-  // Generate routines that check the names of sub-rules.
-  OS << "Optional<attr::SubjectMatchRule> "
-        "defaultIsAttributeSubjectMatchSubRuleFor(StringRef, bool) {\n";
-  OS << "  return None;\n";
-  OS << "}\n\n";
-
-  std::map<const Record *, std::vector<AttributeSubjectMatchRule>>
-      SubMatchRules;
-  for (const auto &Rule : Rules) {
-    if (!Rule.isSubRule())
-      continue;
-    SubMatchRules[Rule.MetaSubject].push_back(Rule);
-  }
-
-  for (const auto &SubMatchRule : SubMatchRules) {
-    OS << "Optional<attr::SubjectMatchRule> isAttributeSubjectMatchSubRuleFor_"
-       << SubMatchRule.first->getValueAsString("Name")
-       << "(StringRef Name, bool IsUnless) {\n";
-    OS << "  if (IsUnless)\n";
-    OS << "    return "
-          "llvm::StringSwitch<Optional<attr::SubjectMatchRule>>(Name).\n";
-    for (const auto &Rule : SubMatchRule.second) {
-      if (Rule.isNegatedSubRule())
-        OS << "    Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
-           << ").\n";
-    }
-    OS << "    Default(None);\n";
-    OS << "  return "
-          "llvm::StringSwitch<Optional<attr::SubjectMatchRule>>(Name).\n";
-    for (const auto &Rule : SubMatchRule.second) {
-      if (!Rule.isNegatedSubRule())
-        OS << "  Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
-           << ").\n";
-    }
-    OS << "  Default(None);\n";
-    OS << "}\n\n";
-  }
-
-  // Generate the function that checks for the top-level rules.
-  OS << "std::pair<Optional<attr::SubjectMatchRule>, "
-        "llvm::function_ref<Optional<attr::SubjectMatchRule> (StringRef, "
-        "bool)>> isAttributeSubjectMatchRule(StringRef Name) {\n";
-  OS << "  return "
-        "llvm::StringSwitch<std::pair<Optional<attr::SubjectMatchRule>, "
-        "llvm::function_ref<Optional<attr::SubjectMatchRule> (StringRef, "
-        "bool)>>>(Name).\n";
-  for (const auto &Rule : Rules) {
-    if (Rule.isSubRule())
-      continue;
-    std::string SubRuleFunction;
-    if (SubMatchRules.count(Rule.MetaSubject))
-      SubRuleFunction = "isAttributeSubjectMatchSubRuleFor_" + Rule.getName();
-    else
-      SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor";
-    OS << "  Case(\"" << Rule.getName() << "\", std::make_pair("
-       << Rule.getEnumValue() << ", " << SubRuleFunction << ")).\n";
-  }
-  OS << "  Default(std::make_pair(None, "
-        "defaultIsAttributeSubjectMatchSubRuleFor));\n";
-  OS << "}\n\n";
-
-  // Generate the function that checks for the submatch rules.
-  OS << "const char *validAttributeSubjectMatchSubRules("
-     << AttributeSubjectMatchRule::EnumName << " Rule) {\n";
-  OS << "  switch (Rule) {\n";
-  for (const auto &SubMatchRule : SubMatchRules) {
-    OS << "  case "
-       << AttributeSubjectMatchRule(SubMatchRule.first, nullptr).getEnumValue()
-       << ":\n";
-    OS << "  return \"'";
-    bool IsFirst = true;
-    for (const auto &Rule : SubMatchRule.second) {
-      if (!IsFirst)
-        OS << ", '";
-      IsFirst = false;
-      if (Rule.isNegatedSubRule())
-        OS << "unless(";
-      OS << Rule.getName();
-      if (Rule.isNegatedSubRule())
-        OS << ')';
-      OS << "'";
-    }
-    OS << "\";\n";
-  }
-  OS << "  default: return nullptr;\n";
-  OS << "  }\n";
-  OS << "}\n\n";
-}
-
 template <typename Fn>
 static void forEachUniqueSpelling(const Record &Attr, Fn &&F) {
   std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
@@ -2439,17 +2109,6 @@
   OS << "#undef PRAGMA_SPELLING_ATTR\n";
 }
 
-// Emits the enumeration list for attributes.
-void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS) {
-  emitSourceFileHeader(
-      "List of all attribute subject matching rules that Clang recognizes", OS);
-  PragmaClangAttributeSupport &PragmaAttributeSupport =
-      getPragmaAttributeSupport(Records);
-  emitDefaultDefine(OS, "ATTR_MATCH_RULE", nullptr);
-  PragmaAttributeSupport.emitMatchRuleList(OS);
-  OS << "#undef ATTR_MATCH_RULE\n";
-}
-
 // Emits the code to read an attribute from a precompiled header.
 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute deserialization code", OS);
@@ -3045,13 +2704,9 @@
   return B + "Decl";
 }
 
-static std::string functionNameForCustomAppertainsTo(const Record &Subject) {
-  return "is" + Subject.getName().str();
-}
-
 static std::string GenerateCustomAppertainsTo(const Record &Subject,
                                               raw_ostream &OS) {
-  std::string FnName = functionNameForCustomAppertainsTo(Subject);
+  std::string FnName = "is" + Subject.getName().str();
 
   // If this code has already been generated, simply return the previous
   // instance of it.
@@ -3136,42 +2791,6 @@
   return FnName;
 }
 
-static void
-emitAttributeMatchRules(PragmaClangAttributeSupport &PragmaAttributeSupport,
-                        raw_ostream &OS) {
-  OS << "static bool checkAttributeMatchRuleAppliesTo(const Decl *D, "
-     << AttributeSubjectMatchRule::EnumName << " rule) {\n";
-  OS << "  switch (rule) {\n";
-  for (const auto &Rule : PragmaAttributeSupport.Rules) {
-    if (Rule.isAbstractRule()) {
-      OS << "  case " << Rule.getEnumValue() << ":\n";
-      OS << "    assert(false && \"Abstract matcher rule isn't allowed\");\n";
-      OS << "    return false;\n";
-      continue;
-    }
-    std::vector<Record *> Subjects = Rule.getSubjects();
-    assert(!Subjects.empty() && "Missing subjects");
-    OS << "  case " << Rule.getEnumValue() << ":\n";
-    OS << "    return ";
-    for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
-      // If the subject has custom code associated with it, use the function
-      // that was generated for GenerateAppertainsTo to check if the declaration
-      // is valid.
-      if ((*I)->isSubClassOf("SubsetSubject"))
-        OS << functionNameForCustomAppertainsTo(**I) << "(D)";
-      else
-        OS << "isa<" << GetSubjectWithSuffix(*I) << ">(D)";
-
-      if (I + 1 != E)
-        OS << " || ";
-    }
-    OS << ";\n";
-  }
-  OS << "  }\n";
-  OS << "  llvm_unreachable(\"Invalid match rule\");\nreturn false;\n";
-  OS << "}\n\n";
-}
-
 static void GenerateDefaultLangOptRequirements(raw_ostream &OS) {
   OS << "static bool defaultDiagnoseLangOpts(Sema &, ";
   OS << "const AttributeList &) {\n";
@@ -3330,9 +2949,6 @@
 void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Parsed attribute helpers", OS);
 
-  PragmaClangAttributeSupport &PragmaAttributeSupport =
-      getPragmaAttributeSupport(Records);
-
   // Get the list of parsed attributes, and accept the optional list of
   // duplicates due to the ParseKind.
   ParsedAttrMap Dupes;
@@ -3366,13 +2982,10 @@
     SS << ", " << I->second->isSubClassOf("TypeAttr");
     SS << ", " << I->second->isSubClassOf("StmtAttr");
     SS << ", " << IsKnownToGCC(*I->second);
-    SS << ", " << PragmaAttributeSupport.isAttributedSupported(*I->second);
     SS << ", " << GenerateAppertainsTo(*I->second, OS);
     SS << ", " << GenerateLangOptRequirements(*I->second, OS);
     SS << ", " << GenerateTargetRequirements(*I->second, Dupes, OS);
     SS << ", " << GenerateSpellingIndexToSemanticSpelling(*I->second, OS);
-    SS << ", "
-       << PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS);
     SS << " }";
 
     if (I + 1 != E)
@@ -3384,9 +2997,6 @@
   OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n";
   OS << SS.str();
   OS << "};\n\n";
-
-  // Generate the attribute match rules.
-  emitAttributeMatchRules(PragmaAttributeSupport, OS);
 }
 
 // Emits the kind list of parsed attributes
@@ -3526,11 +3136,6 @@
   emitClangAttrLateParsedList(Records, OS);
 }
 
-void EmitClangAttrSubjectMatchRulesParserStringSwitches(RecordKeeper &Records,
-                                                        raw_ostream &OS) {
-  getPragmaAttributeSupport(Records).generateParsingHelpers(OS);
-}
-
 class DocumentationData {
 public:
   const Record *Documentation;
@@ -3562,8 +3167,8 @@
   Pragma = 1 << 5
 };
 
-static void WriteDocumentation(RecordKeeper &Records,
-                               const DocumentationData &Doc, raw_ostream &OS) {
+static void WriteDocumentation(const DocumentationData &Doc,
+                               raw_ostream &OS) {
   // 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.
@@ -3645,7 +3250,7 @@
   // List what spelling syntaxes the attribute supports.
   OS << ".. csv-table:: Supported Syntaxes\n";
   OS << "   :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\",";
-  OS << " \"Pragma\", \"Pragma clang attribute\"\n\n";
+  OS << " \"Pragma\"\n\n";
   OS << "   \"";
   if (SupportedSpellings & GNU) OS << "X";
   OS << "\",\"";
@@ -3656,9 +3261,6 @@
   if (SupportedSpellings & Keyword) OS << "X";
   OS << "\", \"";
   if (SupportedSpellings & Pragma) OS << "X";
-  OS << "\", \"";
-  if (getPragmaAttributeSupport(Records).isAttributedSupported(*Doc.Attribute))
-    OS << "X";
   OS << "\"\n\n";
 
   // If the attribute is deprecated, print a message about it, and possibly
@@ -3725,40 +3327,7 @@
     // Walk over each of the attributes in the category and write out their
     // documentation.
     for (const auto &Doc : I.second)
-      WriteDocumentation(Records, Doc, OS);
-  }
-}
-
-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";
-  for (const auto &I : Attrs) {
-    if (!Support.isAttributedSupported(*I.second))
-      continue;
-    OS << I.first;
-    if (I.second->isValueUnset("Subjects")) {
-      OS << " ()\n";
-      continue;
-    }
-    const Record *SubjectObj = I.second->getValueAsDef("Subjects");
-    std::vector<Record *> Subjects =
-        SubjectObj->getValueAsListOfDefs("Subjects");
-    OS << " (";
-    for (const auto &Subject : llvm::enumerate(Subjects)) {
-      if (Subject.index())
-        OS << ", ";
-      OS << Support.SubjectsToRules.find(Subject.value())
-                ->getSecond()
-                .getEnumValueName();
-    }
-    OS << ")\n";
+      WriteDocumentation(Doc, OS);
   }
 }