diff options
Diffstat (limited to 'clang/utils/TableGen/ClangAttrEmitter.cpp')
| -rw-r--r-- | clang/utils/TableGen/ClangAttrEmitter.cpp | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 4bf18089b5a..c2f9dec0c0f 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -1520,7 +1520,9 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { OS << "unsigned SI\n"; OS << " )\n"; - OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; + OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI, " + << R.getValueAsBit("LateParsed") << ", " + << R.getValueAsBit("DuplicatesAllowedWhileMerging") << ")\n"; for (auto const &ai : Args) { OS << " , "; @@ -1552,7 +1554,9 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { OS << "unsigned SI\n"; OS << " )\n"; - OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; + OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI, " + << R.getValueAsBit("LateParsed") << ", " + << R.getValueAsBit("DuplicatesAllowedWhileMerging") << ")\n"; for (auto const &ai : Args) { OS << " , "; @@ -1571,10 +1575,10 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { OS << " }\n\n"; } - OS << " " << R.getName() << "Attr *clone(ASTContext &C) const override;\n"; + OS << " " << R.getName() << "Attr *clone(ASTContext &C) const;\n"; OS << " void printPretty(raw_ostream &OS,\n" - << " const PrintingPolicy &Policy) const override;\n"; - OS << " const char *getSpelling() const override;\n"; + << " const PrintingPolicy &Policy) const;\n"; + OS << " const char *getSpelling() const;\n"; if (!ElideSpelling) { assert(!SemanticToSyntacticMap.empty() && "Empty semantic mapping list"); @@ -1603,13 +1607,6 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { OS << " static bool classof(const Attr *A) { return A->getKind() == " << "attr::" << R.getName() << "; }\n"; - bool LateParsed = R.getValueAsBit("LateParsed"); - OS << " bool isLateParsed() const override { return " - << LateParsed << "; }\n"; - - if (R.getValueAsBit("DuplicatesAllowedWhileMerging")) - OS << " bool duplicatesAllowed() const override { return true; }\n\n"; - OS << "};\n\n"; } @@ -1652,6 +1649,36 @@ void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) { writePrettyPrintFunction(R, Args, OS); writeGetSpellingFunction(R, OS); } + + // Instead of relying on virtual dispatch we just create a huge dispatch + // switch. This is both smaller and faster than virtual functions. + auto EmitFunc = [&](const char *Method) { + OS << " switch (getKind()) {\n"; + for (const auto *Attr : Attrs) { + const Record &R = *Attr; + if (!R.getValueAsBit("ASTNode")) + continue; + + OS << " case attr::" << R.getName() << ":\n"; + OS << " return cast<" << R.getName() << "Attr>(this)->" << Method + << ";\n"; + } + OS << " case attr::NUM_ATTRS:\n"; + OS << " break;\n"; + OS << " }\n"; + OS << " llvm_unreachable(\"Unexpected attribute kind!\");\n"; + OS << "}\n\n"; + }; + + OS << "const char *Attr::getSpelling() const {\n"; + EmitFunc("getSpelling()"); + + OS << "Attr *Attr::clone(ASTContext &C) const {\n"; + EmitFunc("clone(C)"); + + OS << "void Attr::printPretty(raw_ostream &OS, " + "const PrintingPolicy &Policy) const {\n"; + EmitFunc("printPretty(OS, Policy)"); } } // end namespace clang |

