diff options
Diffstat (limited to 'contrib/llvm/tools/clang/utils/TableGen')
9 files changed, 682 insertions, 65 deletions
diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp index c51ca96..682f9c7 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp +++ b/contrib/llvm/tools/clang/utils/TableGen/ClangASTNodesEmitter.cpp @@ -133,6 +133,8 @@ std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode( } void ClangASTNodesEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("List of AST nodes of a particular kind", OS); + // Write the preamble OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n"; OS << "# define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n"; @@ -183,6 +185,8 @@ void EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS, void EmitClangDeclContext(RecordKeeper &Records, raw_ostream &OS) { // FIXME: Find a .td file format to allow for this to be represented better. + emitSourceFileHeader("List of AST Decl nodes", OS); + OS << "#ifndef DECL_CONTEXT\n"; OS << "# define DECL_CONTEXT(DECL)\n"; OS << "#endif\n"; diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp index 521f604..7c8603f 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/contrib/llvm/tools/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -47,7 +47,7 @@ static std::string ReadPCHRecord(StringRef type) { .EndsWith("Decl *", "GetLocalDeclAs<" + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])") .Case("QualType", "getLocalType(F, Record[Idx++])") - .Case("Expr *", "ReadSubExpr()") + .Case("Expr *", "ReadExpr(F)") .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)") .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)") .Default("Record[Idx++]"); @@ -125,6 +125,9 @@ namespace { virtual void writePCHReadDecls(raw_ostream &OS) const = 0; virtual void writePCHWrite(raw_ostream &OS) const = 0; virtual void writeValue(raw_ostream &OS) const = 0; + virtual void writeDump(raw_ostream &OS) const = 0; + virtual void writeDumpChildren(raw_ostream &OS) const {} + virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; } }; class SimpleArgument : public Argument { @@ -181,6 +184,28 @@ namespace { OS << "\" << get" << getUpperName() << "() << \""; } } + void writeDump(raw_ostream &OS) const { + if (type == "FunctionDecl *") { + OS << " OS << \" \";\n"; + OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n"; + } else if (type == "IdentifierInfo *") { + OS << " OS << \" \" << SA->get" << getUpperName() + << "()->getName();\n"; + } else if (type == "QualType") { + OS << " OS << \" \" << SA->get" << getUpperName() + << "().getAsString();\n"; + } else if (type == "SourceLocation") { + OS << " OS << \" \";\n"; + OS << " SA->get" << getUpperName() << "().print(OS, *SM);\n"; + } else if (type == "bool") { + OS << " if (SA->get" << getUpperName() << "()) OS << \" " + << getUpperName() << "\";\n"; + } else if (type == "int" || type == "unsigned") { + OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; + } else { + llvm_unreachable("Unknown SimpleArgument type!"); + } + } }; class StringArgument : public Argument { @@ -241,6 +266,10 @@ namespace { void writeValue(raw_ostream &OS) const { OS << "\\\"\" << get" << getUpperName() << "() << \"\\\""; } + void writeDump(raw_ostream &OS) const { + OS << " OS << \" \\\"\" << SA->get" << getUpperName() + << "() << \"\\\"\";\n"; + } }; class AlignedArgument : public Argument { @@ -353,6 +382,19 @@ namespace { << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n" << " OS << \""; } + void writeDump(raw_ostream &OS) const { + } + void writeDumpChildren(raw_ostream &OS) const { + OS << " if (SA->is" << getUpperName() << "Expr()) {\n"; + OS << " lastChild();\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 { + OS << "SA->is" << getUpperName() << "Expr()"; + } }; class VariadicArgument : public Argument { @@ -408,7 +450,7 @@ namespace { } void writePCHReadDecls(raw_ostream &OS) const { OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; - OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName() + OS << " SmallVector<" << type << ", 4> " << getLowerName() << ";\n"; OS << " " << getLowerName() << ".reserve(" << getLowerName() << "Size);\n"; @@ -439,17 +481,30 @@ namespace { << " }\n"; OS << " 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 << " OS << \" \" << *I;\n"; + } }; class EnumArgument : public Argument { std::string type; - std::vector<StringRef> values, enums; + std::vector<StringRef> values, enums, uniques; public: EnumArgument(Record &Arg, StringRef Attr) : Argument(Arg, Attr), type(Arg.getValueAsString("Type")), values(getValueAsListOfStrings(Arg, "Values")), - enums(getValueAsListOfStrings(Arg, "Enums")) - {} + 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()); + // FIXME: Emit a proper error + assert(!uniques.empty()); + } void writeAccessors(raw_ostream &OS) const { OS << " " << type << " get" << getUpperName() << "() const {\n"; @@ -469,16 +524,8 @@ namespace { OS << type << " " << getUpperName(); } void writeDeclarations(raw_ostream &OS) const { - // Calculate the various enum values - std::vector<StringRef> uniques(enums); - std::sort(uniques.begin(), uniques.end()); - uniques.erase(std::unique(uniques.begin(), uniques.end()), - uniques.end()); - // FIXME: Emit a proper error - assert(!uniques.empty()); - - std::vector<StringRef>::iterator i = uniques.begin(), - e = uniques.end(); + std::vector<StringRef>::const_iterator i = uniques.begin(), + e = uniques.end(); // The last one needs to not have a comma. --e; @@ -505,6 +552,16 @@ namespace { void writeValue(raw_ostream &OS) const { OS << "\" << get" << getUpperName() << "() << \""; } + void writeDump(raw_ostream &OS) const { + OS << " switch(SA->get" << getUpperName() << "()) {\n"; + for (std::vector<StringRef>::const_iterator I = uniques.begin(), + E = uniques.end(); I != E; ++I) { + OS << " case " << getAttrName() << "Attr::" << *I << ":\n"; + OS << " OS << \" " << *I << "\";\n"; + OS << " break;\n"; + } + OS << " }\n"; + } }; class VersionArgument : public Argument { @@ -552,6 +609,9 @@ namespace { void writeValue(raw_ostream &OS) const { OS << getLowerName() << "=\" << get" << getUpperName() << "() << \""; } + void writeDump(raw_ostream &OS) const { + OS << " OS << \" \" << SA->get" << getUpperName() << "();\n"; + } }; class ExprArgument : public SimpleArgument { @@ -575,6 +635,15 @@ namespace { << "Result.takeAs<Expr>();\n"; OS << " }\n"; } + + void writeDump(raw_ostream &OS) const { + } + + void writeDumpChildren(raw_ostream &OS) const { + OS << " lastChild();\n"; + OS << " dumpStmt(SA->get" << getUpperName() << "());\n"; + } + void writeHasChildren(raw_ostream &OS) const { OS << "true"; } }; class VariadicExprArgument : public VariadicArgument { @@ -607,6 +676,24 @@ namespace { OS << " }\n"; OS << " }\n"; } + + void writeDump(raw_ostream &OS) const { + } + + void writeDumpChildren(raw_ostream &OS) const { + OS << " for (" << getAttrName() << "Attr::" << getLowerName() + << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" + << getLowerName() << "_end(); I != E; ++I) {\n"; + OS << " if (I + 1 == E)\n"; + OS << " lastChild();\n"; + OS << " dumpStmt(*I);\n"; + OS << " }\n"; + } + + void writeHasChildren(raw_ostream &OS) const { + OS << "SA->" << getLowerName() << "_begin() != " + << "SA->" << getLowerName() << "_end()"; + } }; } @@ -663,11 +750,136 @@ static void writeAvailabilityValue(raw_ostream &OS) { << " OS << \""; } +static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args, + raw_ostream &OS) { + std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); + + OS << "void " << R.getName() << "Attr::printPretty(" + << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n"; + + if (Spellings.size() == 0) { + OS << "}\n\n"; + return; + } + + OS << + " switch (SpellingListIndex) {\n" + " default:\n" + " llvm_unreachable(\"Unknown attribute spelling!\");\n" + " break;\n"; + + for (unsigned I = 0; I < Spellings.size(); ++ I) { + llvm::SmallString<16> Prefix; + llvm::SmallString<8> Suffix; + // The actual spelling of the name and namespace (if applicable) + // of an attribute without considering prefix and suffix. + llvm::SmallString<64> Spelling; + std::string Name = Spellings[I]->getValueAsString("Name"); + std::string Variety = Spellings[I]->getValueAsString("Variety"); + + if (Variety == "GNU") { + Prefix = " __attribute__(("; + Suffix = "))"; + } else if (Variety == "CXX11") { + Prefix = " [["; + Suffix = "]]"; + std::string Namespace = Spellings[I]->getValueAsString("Namespace"); + if (Namespace != "") { + Spelling += Namespace; + Spelling += "::"; + } + } else if (Variety == "Declspec") { + Prefix = " __declspec("; + Suffix = ")"; + } else if (Variety == "Keyword") { + Prefix = " "; + Suffix = ""; + } else { + llvm_unreachable("Unknown attribute syntax variety!"); + } + + Spelling += Name; + + OS << + " case " << I << " : {\n" + " OS << \"" + Prefix.str() + Spelling.str(); + + if (Args.size()) OS << "("; + if (Spelling == "availability") { + writeAvailabilityValue(OS); + } else { + for (std::vector<Argument*>::const_iterator I = Args.begin(), + E = Args.end(); I != E; ++ I) { + if (I != Args.begin()) OS << ", "; + (*I)->writeValue(OS); + } + } + + if (Args.size()) OS << ")"; + OS << Suffix.str() + "\";\n"; + + OS << + " break;\n" + " }\n"; + } + + // End of the switch statement. + OS << "}\n"; + // End of the print function. + OS << "}\n\n"; +} + +/// \brief Return the index of a spelling in a spelling list. +static unsigned getSpellingListIndex(const std::vector<Record*> &SpellingList, + const Record &Spelling) { + assert(SpellingList.size() && "Spelling list is empty!"); + + for (unsigned Index = 0; Index < SpellingList.size(); ++Index) { + Record *S = SpellingList[Index]; + if (S->getValueAsString("Variety") != Spelling.getValueAsString("Variety")) + continue; + if (S->getValueAsString("Variety") == "CXX11" && + S->getValueAsString("Namespace") != + Spelling.getValueAsString("Namespace")) + continue; + if (S->getValueAsString("Name") != Spelling.getValueAsString("Name")) + continue; + + return Index; + } + + llvm_unreachable("Unknown spelling!"); +} + +static void writeAttrAccessorDefinition(Record &R, raw_ostream &OS) { + std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors"); + for (std::vector<Record*>::const_iterator I = Accessors.begin(), + E = Accessors.end(); I != E; ++I) { + Record *Accessor = *I; + std::string Name = Accessor->getValueAsString("Name"); + std::vector<Record*> Spellings = Accessor->getValueAsListOfDefs( + "Spellings"); + std::vector<Record*> SpellingList = R.getValueAsListOfDefs("Spellings"); + assert(SpellingList.size() && + "Attribute with empty spelling list can't have accessors!"); + + OS << " bool " << Name << "() const { return SpellingListIndex == "; + for (unsigned Index = 0; Index < Spellings.size(); ++Index) { + OS << getSpellingListIndex(SpellingList, *Spellings[Index]); + if (Index != Spellings.size() -1) + OS << " ||\n SpellingListIndex == "; + else + OS << "; }\n"; + } + } +} + namespace clang { // Emits the class definitions for attributes. void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("Attribute classes' definitions", OS); + OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; @@ -711,9 +923,12 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { (*ai)->writeCtorParameters(OS); OS << "\n"; } - + + OS << " , "; + OS << "unsigned SI = 0\n"; + OS << " )\n"; - OS << " : " << SuperName << "(attr::" << R.getName() << ", R)\n"; + OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; for (ai = Args.begin(); ai != ae; ++ai) { OS << " , "; @@ -730,9 +945,11 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { OS << " }\n\n"; OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; - OS << " virtual void printPretty(llvm::raw_ostream &OS," + OS << " virtual void printPretty(raw_ostream &OS,\n" << " const PrintingPolicy &Policy) const;\n"; + writeAttrAccessorDefinition(R, OS); + for (ai = Args.begin(); ai != ae; ++ai) { (*ai)->writeAccessors(OS); OS << "\n\n"; @@ -756,7 +973,7 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { // Emits the class method definitions for attributes. void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("Attribute classes' member function definitions", OS); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; @@ -769,7 +986,6 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { continue; std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); - std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); std::vector<Argument*> Args; for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) Args.push_back(createArgument(**ri, R.getName())); @@ -784,26 +1000,9 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { OS << ", "; (*ai)->writeCloneArgs(OS); } - OS << ");\n}\n\n"; + OS << ", getSpellingListIndex());\n}\n\n"; - OS << "void " << R.getName() << "Attr::printPretty(" - << "llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {\n"; - if (Spellings.begin() != Spellings.end()) { - std::string Spelling = (*Spellings.begin())->getValueAsString("Name"); - OS << " OS << \" __attribute__((" << Spelling; - if (Args.size()) OS << "("; - if (Spelling == "availability") { - writeAvailabilityValue(OS); - } else { - for (ai = Args.begin(); ai != ae; ++ai) { - if (ai!=Args.begin()) OS <<", "; - (*ai)->writeValue(OS); - } - } - if (Args.size()) OS << ")"; - OS << "))\";\n"; - } - OS << "}\n\n"; + writePrettyPrintFunction(R, Args, OS); } } @@ -830,7 +1029,7 @@ namespace clang { // Emits the enumeration list for attributes. void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("List of all attributes that Clang recognizes", OS); OS << "#ifndef LAST_ATTR\n"; OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; @@ -853,10 +1052,20 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { " INHERITABLE_PARAM_ATTR(NAME)\n"; OS << "#endif\n\n"; + OS << "#ifndef MS_INHERITABLE_ATTR\n"; + OS << "#define MS_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; + OS << "#endif\n\n"; + + OS << "#ifndef LAST_MS_INHERITABLE_ATTR\n"; + OS << "#define LAST_MS_INHERITABLE_ATTR(NAME)" + " MS_INHERITABLE_ATTR(NAME)\n"; + OS << "#endif\n\n"; + Record *InhClass = Records.getClass("InheritableAttr"); Record *InhParamClass = Records.getClass("InheritableParamAttr"); + Record *MSInheritanceClass = Records.getClass("MSInheritanceAttr"); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), - NonInhAttrs, InhAttrs, InhParamAttrs; + NonInhAttrs, InhAttrs, InhParamAttrs, MSInhAttrs; for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i) { if (!(*i)->getValueAsBit("ASTNode")) @@ -864,6 +1073,8 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { if ((*i)->isSubClassOf(InhParamClass)) InhParamAttrs.push_back(*i); + else if ((*i)->isSubClassOf(MSInheritanceClass)) + MSInhAttrs.push_back(*i); else if ((*i)->isSubClassOf(InhClass)) InhAttrs.push_back(*i); else @@ -871,19 +1082,22 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { } EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); + EmitAttrList(OS, "MS_INHERITABLE_ATTR", MSInhAttrs); EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); EmitAttrList(OS, "ATTR", NonInhAttrs); OS << "#undef LAST_ATTR\n"; OS << "#undef INHERITABLE_ATTR\n"; + OS << "#undef MS_INHERITABLE_ATTR\n"; OS << "#undef LAST_INHERITABLE_ATTR\n"; OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; + OS << "#undef LAST_MS_INHERITABLE_ATTR\n"; OS << "#undef ATTR\n"; } // Emits the code to read an attribute from a precompiled header. void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("Attribute deserialization code", OS); Record *InhClass = Records.getClass("InheritableAttr"); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), @@ -927,6 +1141,8 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { // Emits the code to write an attribute to a precompiled header. void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Attribute serialization code", OS); + Record *InhClass = Records.getClass("InheritableAttr"); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; @@ -956,7 +1172,8 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) { // Emits the list of spellings for attributes. void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("llvm::StringSwitch code to match all known attributes", + OS); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -972,9 +1189,70 @@ void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) { } +void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Code to translate different attribute spellings " + "into internal identifiers", OS); + + OS << + " unsigned Index = 0;\n" + " switch (AttrKind) {\n" + " default:\n" + " llvm_unreachable(\"Unknown attribute kind!\");\n" + " break;\n"; + + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); + for (std::vector<Record*>::const_iterator I = Attrs.begin(), E = Attrs.end(); + I != E; ++I) { + Record &R = **I; + // We only care about attributes that participate in Sema checking, so + // skip those attributes that are not able to make their way to Sema. + if (!R.getValueAsBit("SemaHandler")) + continue; + + std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings"); + // Each distinct spelling yields an attribute kind. + if (R.getValueAsBit("DistinctSpellings")) { + for (unsigned I = 0; I < Spellings.size(); ++ I) { + OS << + " case AT_" << Spellings[I]->getValueAsString("Name") << ": \n" + " Index = " << I << ";\n" + " break;\n"; + } + } else { + OS << " case AT_" << R.getName() << " : {\n"; + for (unsigned I = 0; I < Spellings.size(); ++ I) { + SmallString<16> Namespace; + if (Spellings[I]->getValueAsString("Variety") == "CXX11") + Namespace = Spellings[I]->getValueAsString("Namespace"); + else + Namespace = ""; + + OS << " if (Name == \"" + << Spellings[I]->getValueAsString("Name") << "\" && " + << "SyntaxUsed == " + << StringSwitch<unsigned>(Spellings[I]->getValueAsString("Variety")) + .Case("GNU", 0) + .Case("CXX11", 1) + .Case("Declspec", 2) + .Case("Keyword", 3) + .Default(0) + << " && Scope == \"" << Namespace << "\")\n" + << " return " << I << ";\n"; + } + + OS << " break;\n"; + OS << " }\n"; + } + } + + OS << " }\n"; + OS << " return Index;\n"; +} + // Emits the LateParsed property for attributes. void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("llvm::StringSwitch code to match late parsed " + "attributes", OS); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -1002,7 +1280,7 @@ void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) { // Emits code to instantiate dependent attributes on templates. void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("Template instantiation code for attributes", OS); std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -1075,8 +1353,8 @@ void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { // Emits the list of parsed attributes. void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - + emitSourceFileHeader("List of all attributes that Clang recognizes", OS); + OS << "#ifndef PARSED_ATTR\n"; OS << "#define PARSED_ATTR(NAME) NAME\n"; OS << "#endif\n\n"; @@ -1113,9 +1391,8 @@ void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { // Emits the kind list of parsed attributes void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - OS << "\n"; - + emitSourceFileHeader("Attribute name matcher", OS); + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); std::vector<StringMatcher::StringPair> Matches; @@ -1163,4 +1440,56 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { << "}\n"; } +// Emits the code to dump an attribute. +void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Attribute dumper", OS); + + OS << + " switch (A->getKind()) {\n" + " default:\n" + " llvm_unreachable(\"Unknown attribute kind!\");\n" + " break;\n"; + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; + for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); + I != E; ++I) { + Record &R = **I; + if (!R.getValueAsBit("ASTNode")) + continue; + OS << " case attr::" << R.getName() << ": {\n"; + Args = R.getValueAsListOfDefs("Args"); + if (!Args.empty()) { + OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() + << "Attr>(A);\n"; + for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end(); + I != E; ++I) + createArgument(**I, R.getName())->writeDump(OS); + + // Code for detecting the last child. + OS << " bool OldMoreChildren = hasMoreChildren();\n"; + OS << " bool MoreChildren = OldMoreChildren;\n"; + + for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end(); + I != E; ++I) { + // More code for detecting the last child. + OS << " MoreChildren = OldMoreChildren"; + for (std::vector<Record*>::iterator Next = I + 1; Next != E; ++Next) { + OS << " || "; + createArgument(**Next, R.getName())->writeHasChildren(OS); + } + OS << ";\n"; + OS << " setMoreChildren(MoreChildren);\n"; + + createArgument(**I, R.getName())->writeDumpChildren(OS); + } + + // Reset the last child. + OS << " setMoreChildren(OldMoreChildren);\n"; + } + OS << + " break;\n" + " }\n"; + } + OS << " }\n"; +} + } // end namespace clang diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp index 36fbcd4..ebb0427 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp +++ b/contrib/llvm/tools/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp @@ -7,20 +7,22 @@ // //===----------------------------------------------------------------------===// // -// This tablegen backend emits command lists and efficient matchers command +// This tablegen backend emits command lists and efficient matchers for command // names that are used in documentation comments. // //===----------------------------------------------------------------------===// #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" #include <vector> using namespace llvm; namespace clang { void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("A list of commands useable in documentation " + "comments", OS); OS << "namespace {\n" "const CommandInfo Commands[] = {\n"; @@ -39,11 +41,15 @@ void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { << Tag.getValueAsBit("IsParamCommand") << ", " << Tag.getValueAsBit("IsTParamCommand") << ", " << Tag.getValueAsBit("IsDeprecatedCommand") << ", " + << Tag.getValueAsBit("IsHeaderfileCommand") << ", " << Tag.getValueAsBit("IsEmptyParagraphAllowed") << ", " << Tag.getValueAsBit("IsVerbatimBlockCommand") << ", " << Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", " << Tag.getValueAsBit("IsVerbatimLineCommand") << ", " << Tag.getValueAsBit("IsDeclarationCommand") << ", " + << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", " + << Tag.getValueAsBit("IsRecordLikeDetailCommand") << ", " + << Tag.getValueAsBit("IsRecordLikeDeclarationCommand") << ", " << /* IsUnknownCommand = */ "0" << " }"; if (i + 1 != e) @@ -68,5 +74,49 @@ void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { OS << " return NULL;\n" << "}\n\n"; } + +static std::string MangleName(StringRef Str) { + std::string Mangled; + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + switch (Str[i]) { + default: + Mangled += Str[i]; + break; + case '[': + Mangled += "lsquare"; + break; + case ']': + Mangled += "rsquare"; + break; + case '{': + Mangled += "lbrace"; + break; + case '}': + Mangled += "rbrace"; + break; + case '$': + Mangled += "dollar"; + break; + } + } + return Mangled; +} + +void EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("A list of commands useable in documentation " + "comments", OS); + + OS << "#ifndef COMMENT_COMMAND\n" + << "# define COMMENT_COMMAND(NAME)\n" + << "#endif\n"; + + std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command"); + for (size_t i = 0, e = Tags.size(); i != e; ++i) { + Record &Tag = *Tags[i]; + std::string MangledName = MangleName(Tag.getValueAsString("Name")); + + OS << "COMMENT_COMMAND(" << MangledName << ")\n"; + } +} } // end namespace clang diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp new file mode 100644 index 0000000..bfdb268 --- /dev/null +++ b/contrib/llvm/tools/clang/utils/TableGen/ClangCommentHTMLNamedCharacterReferenceEmitter.cpp @@ -0,0 +1,85 @@ +//===--- ClangCommentHTMLNamedCharacterReferenceEmitter.cpp -----------------=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend emits an fficient function to translate HTML named +// character references to UTF-8 sequences. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" +#include <vector> + +using namespace llvm; + +/// \brief Convert a code point to the corresponding UTF-8 sequence represented +/// as a C string literal. +/// +/// \returns true on success. +static bool translateCodePointToUTF8(unsigned CodePoint, + SmallVectorImpl<char> &CLiteral) { + char Translated[UNI_MAX_UTF8_BYTES_PER_CODE_POINT]; + char *TranslatedPtr = Translated; + if (!ConvertCodePointToUTF8(CodePoint, TranslatedPtr)) + return false; + + StringRef UTF8(Translated, TranslatedPtr - Translated); + + raw_svector_ostream OS(CLiteral); + OS << "\""; + for (size_t i = 0, e = UTF8.size(); i != e; ++i) { + OS << "\\x"; + OS.write_hex(static_cast<unsigned char>(UTF8[i])); + } + OS << "\""; + + return true; +} + +namespace clang { +void EmitClangCommentHTMLNamedCharacterReferences(RecordKeeper &Records, + raw_ostream &OS) { + std::vector<Record *> Tags = Records.getAllDerivedDefinitions("NCR"); + std::vector<StringMatcher::StringPair> NameToUTF8; + SmallString<32> CLiteral; + for (std::vector<Record *>::iterator I = Tags.begin(), E = Tags.end(); + I != E; ++I) { + Record &Tag = **I; + std::string Spelling = Tag.getValueAsString("Spelling"); + uint64_t CodePoint = Tag.getValueAsInt("CodePoint"); + CLiteral.clear(); + CLiteral.append("return "); + if (!translateCodePointToUTF8(CodePoint, CLiteral)) { + SrcMgr.PrintMessage(Tag.getLoc().front(), + SourceMgr::DK_Error, + Twine("invalid code point")); + continue; + } + CLiteral.append(";"); + + StringMatcher::StringPair Match(Spelling, CLiteral.str()); + NameToUTF8.push_back(Match); + } + + emitSourceFileHeader("HTML named character reference to UTF-8 " + "translation", OS); + + OS << "StringRef translateHTMLNamedCharacterReferenceToUTF8(\n" + " StringRef Name) {\n"; + StringMatcher("Name", NameToUTF8, OS).Emit(); + OS << " return StringRef();\n" + << "}\n\n"; +} + +} // end namespace clang + diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp index 0ae23b2..bfcd2cf 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp +++ b/contrib/llvm/tools/clang/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp @@ -14,6 +14,7 @@ #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h" #include <vector> using namespace llvm; @@ -29,7 +30,7 @@ void EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS) { Matches.push_back(StringMatcher::StringPair(Spelling, "return true;")); } - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("HTML tag name matcher", OS); OS << "bool isHTMLTagName(StringRef Name) {\n"; StringMatcher("Name", Matches, OS).Emit(); @@ -53,7 +54,7 @@ void EmitClangCommentHTMLTagsProperties(RecordKeeper &Records, MatchesEndTagForbidden.push_back(Match); } - OS << "// This file is generated by TableGen. Do not edit.\n\n"; + emitSourceFileHeader("HTML tag properties", OS); OS << "bool isHTMLEndTagOptional(StringRef Name) {\n"; StringMatcher("Name", MatchesEndTagOptional, OS).Emit(); diff --git a/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index b1472a8..291eb75 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/contrib/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -11,11 +11,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/Optional.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/TableGen/Error.h" @@ -127,14 +131,41 @@ namespace { std::vector<const Record*> DiagsInGroup; std::vector<std::string> SubGroups; unsigned IDNo; + + const Record *ExplicitDef; + + GroupInfo() : ExplicitDef(0) {} }; } // end anonymous namespace. +static bool beforeThanCompare(const Record *LHS, const Record *RHS) { + assert(!LHS->getLoc().empty() && !RHS->getLoc().empty()); + return + LHS->getLoc().front().getPointer() < RHS->getLoc().front().getPointer(); +} + +static bool beforeThanCompareGroups(const GroupInfo *LHS, const GroupInfo *RHS){ + assert(!LHS->DiagsInGroup.empty() && !RHS->DiagsInGroup.empty()); + return beforeThanCompare(LHS->DiagsInGroup.front(), + RHS->DiagsInGroup.front()); +} + +static SMRange findSuperClassRange(const Record *R, StringRef SuperName) { + ArrayRef<Record *> Supers = R->getSuperClasses(); + + for (size_t i = 0, e = Supers.size(); i < e; ++i) + if (Supers[i]->getName() == SuperName) + return R->getSuperClassRanges()[i]; + + return SMRange(); +} + /// \brief Invert the 1-[0/1] mapping of diags to group into a one to many /// mapping of groups to diags in the group. static void groupDiagnostics(const std::vector<Record*> &Diags, const std::vector<Record*> &DiagGroups, std::map<std::string, GroupInfo> &DiagsInGroup) { + for (unsigned i = 0, e = Diags.size(); i != e; ++i) { const Record *R = Diags[i]; DefInit *DI = dyn_cast<DefInit>(R->getValueInit("Group")); @@ -144,13 +175,25 @@ static void groupDiagnostics(const std::vector<Record*> &Diags, std::string GroupName = DI->getDef()->getValueAsString("GroupName"); DiagsInGroup[GroupName].DiagsInGroup.push_back(R); } - + + typedef SmallPtrSet<GroupInfo *, 16> GroupSetTy; + GroupSetTy ImplicitGroups; + // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty // groups (these are warnings that GCC supports that clang never produces). for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { Record *Group = DiagGroups[i]; GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; - + if (Group->isAnonymous()) { + if (GI.DiagsInGroup.size() > 1) + ImplicitGroups.insert(&GI); + } else { + if (GI.ExplicitDef) + assert(GI.ExplicitDef == Group); + else + GI.ExplicitDef = Group; + } + std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups"); for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName")); @@ -161,6 +204,80 @@ static void groupDiagnostics(const std::vector<Record*> &Diags, for (std::map<std::string, GroupInfo>::iterator I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo) I->second.IDNo = IDNo; + + // Sort the implicit groups, so we can warn about them deterministically. + SmallVector<GroupInfo *, 16> SortedGroups(ImplicitGroups.begin(), + ImplicitGroups.end()); + for (SmallVectorImpl<GroupInfo *>::iterator I = SortedGroups.begin(), + E = SortedGroups.end(); + I != E; ++I) { + MutableArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup; + std::sort(GroupDiags.begin(), GroupDiags.end(), beforeThanCompare); + } + std::sort(SortedGroups.begin(), SortedGroups.end(), beforeThanCompareGroups); + + // Warn about the same group being used anonymously in multiple places. + for (SmallVectorImpl<GroupInfo *>::const_iterator I = SortedGroups.begin(), + E = SortedGroups.end(); + I != E; ++I) { + ArrayRef<const Record *> GroupDiags = (*I)->DiagsInGroup; + + if ((*I)->ExplicitDef) { + std::string Name = (*I)->ExplicitDef->getValueAsString("GroupName"); + for (ArrayRef<const Record *>::const_iterator DI = GroupDiags.begin(), + DE = GroupDiags.end(); + DI != DE; ++DI) { + const DefInit *GroupInit = cast<DefInit>((*DI)->getValueInit("Group")); + const Record *NextDiagGroup = GroupInit->getDef(); + if (NextDiagGroup == (*I)->ExplicitDef) + continue; + + SMRange InGroupRange = findSuperClassRange(*DI, "InGroup"); + SmallString<64> Replacement; + if (InGroupRange.isValid()) { + Replacement += "InGroup<"; + Replacement += (*I)->ExplicitDef->getName(); + Replacement += ">"; + } + SMFixIt FixIt(InGroupRange, Replacement.str()); + + SrcMgr.PrintMessage(NextDiagGroup->getLoc().front(), + SourceMgr::DK_Error, + Twine("group '") + Name + + "' is referred to anonymously", + ArrayRef<SMRange>(), + InGroupRange.isValid() ? FixIt + : ArrayRef<SMFixIt>()); + SrcMgr.PrintMessage((*I)->ExplicitDef->getLoc().front(), + SourceMgr::DK_Note, "group defined here"); + } + } else { + // If there's no existing named group, we should just warn once and use + // notes to list all the other cases. + ArrayRef<const Record *>::const_iterator DI = GroupDiags.begin(), + DE = GroupDiags.end(); + assert(DI != DE && "We only care about groups with multiple uses!"); + + const DefInit *GroupInit = cast<DefInit>((*DI)->getValueInit("Group")); + const Record *NextDiagGroup = GroupInit->getDef(); + std::string Name = NextDiagGroup->getValueAsString("GroupName"); + + SMRange InGroupRange = findSuperClassRange(*DI, "InGroup"); + SrcMgr.PrintMessage(NextDiagGroup->getLoc().front(), + SourceMgr::DK_Error, + Twine("group '") + Name + + "' is referred to anonymously", + InGroupRange); + + for (++DI; DI != DE; ++DI) { + GroupInit = cast<DefInit>((*DI)->getValueInit("Group")); + InGroupRange = findSuperClassRange(*DI, "InGroup"); + SrcMgr.PrintMessage(GroupInit->getDef()->getLoc().front(), + SourceMgr::DK_Note, "also referenced here", + InGroupRange); + } + } + } } //===----------------------------------------------------------------------===// @@ -174,7 +291,7 @@ typedef llvm::PointerUnion<RecordVec*, RecordSet*> VecOrSet; namespace { class InferPedantic { typedef llvm::DenseMap<const Record*, - std::pair<unsigned, llvm::Optional<unsigned> > > GMap; + std::pair<unsigned, Optional<unsigned> > > GMap; DiagGroupParentMap &DiagGroupParents; const std::vector<Record*> &Diags; diff --git a/contrib/llvm/tools/clang/utils/TableGen/OptParserEmitter.cpp b/contrib/llvm/tools/clang/utils/TableGen/OptParserEmitter.cpp index 674c89a..0553b1f 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/OptParserEmitter.cpp +++ b/contrib/llvm/tools/clang/utils/TableGen/OptParserEmitter.cpp @@ -7,13 +7,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/TableGen/Error.h" -#include "llvm/TableGen/Record.h" -#include "llvm/TableGen/TableGenBackend.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" - +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include <map> using namespace llvm; diff --git a/contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp b/contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp index 41471a4..3df8940 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp +++ b/contrib/llvm/tools/clang/utils/TableGen/TableGen.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "TableGenBackends.h" // Declares all backends. - #include "llvm/Support/CommandLine.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" @@ -30,10 +29,12 @@ enum ActionType { GenClangAttrPCHRead, GenClangAttrPCHWrite, GenClangAttrSpellingList, + GenClangAttrSpellingListIndex, GenClangAttrLateParsedList, GenClangAttrTemplateInstantiate, GenClangAttrParsedAttrList, GenClangAttrParsedAttrKinds, + GenClangAttrDump, GenClangDiagsDefs, GenClangDiagGroups, GenClangDiagsIndexName, @@ -43,7 +44,9 @@ enum ActionType { GenClangSACheckers, GenClangCommentHTMLTags, GenClangCommentHTMLTagsProperties, + GenClangCommentHTMLNamedCharacterReferences, GenClangCommentCommandInfo, + GenClangCommentCommandList, GenOptParserDefs, GenOptParserImpl, GenArmNeon, GenArmNeonSema, @@ -70,6 +73,9 @@ namespace { clEnumValN(GenClangAttrSpellingList, "gen-clang-attr-spelling-list", "Generate a clang attribute spelling list"), + clEnumValN(GenClangAttrSpellingListIndex, + "gen-clang-attr-spelling-index", + "Generate a clang attribute spelling index"), clEnumValN(GenClangAttrLateParsedList, "gen-clang-attr-late-parsed-list", "Generate a clang attribute LateParsed list"), @@ -82,6 +88,8 @@ namespace { 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(GenClangDiagsDefs, "gen-clang-diags-defs", "Generate Clang diagnostics definitions"), clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", @@ -105,8 +113,16 @@ namespace { "gen-clang-comment-html-tags-properties", "Generate efficient matchers for HTML tag " "properties"), + clEnumValN(GenClangCommentHTMLNamedCharacterReferences, + "gen-clang-comment-html-named-character-references", + "Generate function to translate named character " + "references to UTF-8 sequences"), clEnumValN(GenClangCommentCommandInfo, "gen-clang-comment-command-info", + "Generate command properties for commands that " + "are used in documentation comments"), + clEnumValN(GenClangCommentCommandList, + "gen-clang-comment-command-list", "Generate list of commands that are used in " "documentation comments"), clEnumValN(GenArmNeon, "gen-arm-neon", @@ -142,6 +158,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenClangAttrSpellingList: EmitClangAttrSpellingList(Records, OS); break; + case GenClangAttrSpellingListIndex: + EmitClangAttrSpellingListIndex(Records, OS); + break; case GenClangAttrLateParsedList: EmitClangAttrLateParsedList(Records, OS); break; @@ -154,6 +173,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenClangAttrParsedAttrKinds: EmitClangAttrParsedAttrKinds(Records, OS); break; + case GenClangAttrDump: + EmitClangAttrDump(Records, OS); + break; case GenClangDiagsDefs: EmitClangDiagsDefs(Records, OS, ClangComponent); break; @@ -182,9 +204,15 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenClangCommentHTMLTagsProperties: EmitClangCommentHTMLTagsProperties(Records, OS); break; + case GenClangCommentHTMLNamedCharacterReferences: + EmitClangCommentHTMLNamedCharacterReferences(Records, OS); + break; case GenClangCommentCommandInfo: EmitClangCommentCommandInfo(Records, OS); break; + case GenClangCommentCommandList: + EmitClangCommentCommandList(Records, OS); + break; case GenOptParserDefs: EmitOptParser(Records, OS, true); break; diff --git a/contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h b/contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h index 838fc84..03708b6 100644 --- a/contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h +++ b/contrib/llvm/tools/clang/utils/TableGen/TableGenBackends.h @@ -35,10 +35,12 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS); +void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS); +void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS); void EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS, const std::string &Component); @@ -49,8 +51,10 @@ void EmitClangSACheckers(RecordKeeper &Records, 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 EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS); +void EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS); void EmitNeon(RecordKeeper &Records, raw_ostream &OS); void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS); |