diff options
author | DeLesley Hutchins <delesley@google.com> | 2013-10-04 21:28:06 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2013-10-04 21:28:06 +0000 |
commit | 66540857c08de7f1be9bea48381548d3942cf9d1 (patch) | |
tree | f7b37bfb773f09b0a81afe3745ae7702fb012b59 /utils | |
parent | 1cd6fab3930d5c058c201895654c6b0bd6ecb8c1 (diff) | |
download | clang-66540857c08de7f1be9bea48381548d3942cf9d1.tar.gz clang-66540857c08de7f1be9bea48381548d3942cf9d1.tar.bz2 clang-66540857c08de7f1be9bea48381548d3942cf9d1.tar.xz |
Consumed Analysis: Change callable_when so that it can take a list of states
that a function can be called in. This reduced the total number of annotations
needed and makes writing more complicated behaviour less burdensome.
Patch by chriswails@gmail.com.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191983 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/ClangAttrEmitter.cpp | 95 |
1 files changed, 94 insertions, 1 deletions
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 7f42e455bd..6e44ac4146 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -136,6 +136,7 @@ namespace { virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; } virtual bool isEnumArg() const { return false; } + virtual bool isVariadicEnumArg() const { return false; } }; class SimpleArgument : public Argument { @@ -474,7 +475,7 @@ namespace { << ";\n"; OS << " " << getLowerName() << ".reserve(" << getLowerName() << "Size);\n"; - OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; + OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; std::string read = ReadPCHRecord(type); OS << " " << getLowerName() << ".push_back(" << read << ");\n"; @@ -604,6 +605,93 @@ namespace { OS << " }\n"; } }; + + class VariadicEnumArgument: public VariadicArgument { + std::string type, QualifiedTypeName; + std::vector<StringRef> values, enums, uniques; + public: + VariadicEnumArgument(Record &Arg, StringRef Attr) + : VariadicArgument(Arg, Attr, Arg.getValueAsString("Type")), + type(Arg.getValueAsString("Type")), + values(getValueAsListOfStrings(Arg, "Values")), + enums(getValueAsListOfStrings(Arg, "Enums")), + uniques(enums) + { + // Calculate the various enum values + std::sort(uniques.begin(), uniques.end()); + uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end()); + + QualifiedTypeName = getAttrName().str() + "Attr::" + type; + + // FIXME: Emit a proper error + assert(!uniques.empty()); + } + + bool isVariadicEnumArg() const { return true; } + + void writeDeclarations(raw_ostream &OS) const { + std::vector<StringRef>::const_iterator i = uniques.begin(), + e = uniques.end(); + // The last one needs to not have a comma. + --e; + + OS << "public:\n"; + OS << " enum " << type << " {\n"; + for (; i != e; ++i) + OS << " " << *i << ",\n"; + OS << " " << *e << "\n"; + OS << " };\n"; + OS << "private:\n"; + + VariadicArgument::writeDeclarations(OS); + } + void writeDump(raw_ostream &OS) const { + OS << " for (" << getAttrName() << "Attr::" << getLowerName() + << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" + << getLowerName() << "_end(); I != E; ++I) {\n"; + OS << " switch(*I) {\n"; + for (std::vector<StringRef>::const_iterator UI = uniques.begin(), + UE = uniques.end(); UI != UE; ++UI) { + OS << " case " << getAttrName() << "Attr::" << *UI << ":\n"; + OS << " OS << \" " << *UI << "\";\n"; + OS << " break;\n"; + } + OS << " }\n"; + OS << " }\n"; + } + void writePCHReadDecls(raw_ostream &OS) const { + OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; + OS << " SmallVector<" << QualifiedTypeName << ", 4> " << getLowerName() + << ";\n"; + OS << " " << getLowerName() << ".reserve(" << getLowerName() + << "Size);\n"; + OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; + OS << " " << getLowerName() << ".push_back(" << "static_cast<" + << QualifiedTypeName << ">(Record[Idx++]));\n"; + } + void writePCHWrite(raw_ostream &OS) const{ + OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; + OS << " for (" << getAttrName() << "Attr::" << getLowerName() + << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" + << getLowerName() << "_end(); i != e; ++i)\n"; + OS << " " << WritePCHRecord(QualifiedTypeName, "(*i)"); + } + void writeConversion(raw_ostream &OS) const { + OS << " static bool ConvertStrTo" << type << "(StringRef Val, "; + OS << type << " &Out) {\n"; + OS << " Optional<" << type << "> R = llvm::StringSwitch<Optional<"; + OS << type << "> >(Val)\n"; + for (size_t I = 0; I < enums.size(); ++I) { + OS << " .Case(\"" << values[I] << "\", "; + OS << getAttrName() << "Attr::" << enums[I] << ")\n"; + } + OS << " .Default(Optional<" << type << ">());\n"; + OS << " if (R) {\n"; + OS << " Out = *R;\n return true;\n }\n"; + OS << " return false;\n"; + OS << " }\n"; + } + }; class VersionArgument : public Argument { public: @@ -768,6 +856,8 @@ static Argument *createArgument(Record &Arg, StringRef Attr, Ptr = new SimpleArgument(Arg, Attr, "SourceLocation"); else if (ArgName == "VariadicUnsignedArgument") Ptr = new VariadicArgument(Arg, Attr, "unsigned"); + else if (ArgName == "VariadicEnumArgument") + Ptr = new VariadicEnumArgument(Arg, Attr); else if (ArgName == "VariadicExprArgument") Ptr = new VariadicExprArgument(Arg, Attr); else if (ArgName == "VersionArgument") @@ -1051,6 +1141,9 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { if ((*ai)->isEnumArg()) { EnumArgument *EA = (EnumArgument *)*ai; EA->writeConversion(OS); + } else if ((*ai)->isVariadicEnumArg()) { + VariadicEnumArgument *VEA = (VariadicEnumArgument *)*ai; + VEA->writeConversion(OS); } } |