<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Sep 15, 2014 at 8:14 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: aaronballman<br>
Date: Mon Sep 15 10:14:13 2014<br>
New Revision: 217771<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=217771&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=217771&view=rev</a><br>
Log:<br>
When pretty printing attributes that have enumeration arguments, print the enumerator identifier (as a string literal) instead of the internal enumerator integral value.<br></blockquote><div><br></div><div>I don't think this is a complete solution to the problem: EnumArgument is used both for string literal enumerations and for identifier enumerations, and the .td file doesn't distinguish the two cases. This will incorrectly print "" around values for attributes that take an identifier.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Modified:<br>
    cfe/trunk/test/SemaCXX/attr-print.cpp<br>
    cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp<br>
<br>
Modified: cfe/trunk/test/SemaCXX/attr-print.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-print.cpp?rev=217771&r1=217770&r2=217771&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-print.cpp?rev=217771&r1=217770&r2=217771&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/attr-print.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/attr-print.cpp Mon Sep 15 10:14:13 2014<br>
@@ -22,3 +22,12 @@ typedef int Small1 __attribute__((mode(b<br>
<br>
 // CHECK: int small __attribute__((mode(byte)));<br>
 int small __attribute__((mode(byte)));<br>
+<br>
+// CHECK: int v __attribute__((visibility("hidden")));<br>
+int v __attribute__((visibility("hidden")));<br>
+<br>
+// FIXME: The attribute should be printed with the tag declaration.<br>
+class __attribute__((consumable(unknown))) AttrTester1 {<br>
+  // CHECK: void callableWhen() __attribute__((callable_when("unconsumed", "consumed")));<br>
+  void callableWhen()  __attribute__((callable_when("unconsumed", "consumed")));<br>
+};<br>
<br>
Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=217771&r1=217770&r2=217771&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=217771&r1=217770&r2=217771&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)<br>
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Sep 15 10:14:13 2014<br>
@@ -510,6 +510,12 @@ namespace {<br>
   class VariadicArgument : public Argument {<br>
     std::string Type, ArgName, ArgSizeName, RangeName;<br>
<br>
+  protected:<br>
+    // Assumed to receive a parameter: raw_ostream OS.<br>
+    virtual void writeValueImpl(raw_ostream &OS) const {<br>
+      OS << "    OS << Val;\n";<br>
+    }<br>
+<br>
   public:<br>
     VariadicArgument(const Record &Arg, StringRef Attr, std::string T)<br>
         : Argument(Arg, Attr), Type(T), ArgName(getLowerName().str() + "_"),<br>
@@ -589,9 +595,9 @@ namespace {<br>
       OS << "  bool isFirst = true;\n"<br>
          << "  for (const auto &Val : " << RangeName << "()) {\n"<br>
          << "    if (isFirst) isFirst = false;\n"<br>
-         << "    else OS << \", \";\n"<br>
-         << "    OS << Val;\n"<br>
-         << "  }\n";<br>
+         << "    else OS << \", \";\n";<br>
+      writeValueImpl(OS);<br>
+      OS << "  }\n";<br>
       OS << "  OS << \"";<br>
     }<br>
     void writeDump(raw_ostream &OS) const override {<br>
@@ -678,7 +684,8 @@ namespace {<br>
       OS << "Record.push_back(SA->get" << getUpperName() << "());\n";<br>
     }<br>
     void writeValue(raw_ostream &OS) const override {<br>
-      OS << "\" << get" << getUpperName() << "() << \"";<br>
+      OS << "\\\"\" << " << getAttrName() << "Attr::Convert" << type << "ToStr(get"<br>
+         << getUpperName() << "()) << \"\\\"";<br>
     }<br>
     void writeDump(raw_ostream &OS) const override {<br>
       OS << "    switch(SA->get" << getUpperName() << "()) {\n";<br>
@@ -703,13 +710,37 @@ namespace {<br>
       OS << "    if (R) {\n";<br>
       OS << "      Out = *R;\n      return true;\n    }\n";<br>
       OS << "    return false;\n";<br>
-      OS << "  }\n";<br>
+      OS << "  }\n\n";<br>
+<br>
+      // Mapping from enumeration values back to enumeration strings isn't<br>
+      // trivial because some enumeration values have multiple named<br>
+      // enumerators, such as type_visibility(internal) and<br>
+      // type_visibility(hidden) both mapping to TypeVisibilityAttr::Hidden.<br>
+      OS << "  static const char *Convert" << type << "ToStr("<br>
+         << type << " Val) {\n"<br>
+         << "    switch(Val) {\n";<br>
+      std::set<std::string> Uniques;<br>
+      for (size_t I = 0; I < enums.size(); ++I) {<br>
+        if (Uniques.insert(enums[I]).second)<br>
+          OS << "    case " << getAttrName() << "Attr::" << enums[I]<br>
+             << ": return \"" << values[I] << "\";\n";<br>
+      }<br>
+      OS << "    }\n"<br>
+         << "    llvm_unreachable(\"No enumerator with that value\");\n"<br>
+         << "  }\n";<br>
     }<br>
   };<br>
<br>
   class VariadicEnumArgument: public VariadicArgument {<br>
     std::string type, QualifiedTypeName;<br>
     std::vector<std::string> values, enums, uniques;<br>
+<br>
+  protected:<br>
+    void writeValueImpl(raw_ostream &OS) const override {<br>
+      OS << "    OS << \"\\\"\" << " << getAttrName() << "Attr::Convert" << type<br>
+         << "ToStr(Val)" << "<< \"\\\"\";\n";<br>
+    }<br>
+<br>
   public:<br>
     VariadicEnumArgument(const Record &Arg, StringRef Attr)<br>
       : VariadicArgument(Arg, Attr, Arg.getValueAsString("Type")),<br>
@@ -785,7 +816,20 @@ namespace {<br>
       OS << "    if (R) {\n";<br>
       OS << "      Out = *R;\n      return true;\n    }\n";<br>
       OS << "    return false;\n";<br>
-      OS << "  }\n";<br>
+      OS << "  }\n\n";<br>
+<br>
+      OS << "  static const char *Convert" << type << "ToStr("<br>
+        << type << " Val) {\n"<br>
+        << "    switch(Val) {\n";<br>
+      std::set<std::string> Uniques;<br>
+      for (size_t I = 0; I < enums.size(); ++I) {<br>
+        if (Uniques.insert(enums[I]).second)<br>
+          OS << "    case " << getAttrName() << "Attr::" << enums[I]<br>
+          << ": return \"" << values[I] << "\";\n";<br>
+      }<br>
+      OS << "    }\n"<br>
+        << "    llvm_unreachable(\"No enumerator with that value\");\n"<br>
+        << "  }\n";<br>
     }<br>
   };<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>