diff options
author | Alexander Kornienko <alexfh@google.com> | 2013-01-07 17:53:08 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2013-01-07 17:53:08 +0000 |
commit | c3cd2b0d538e4db78f1bcbedd0085e2005ce5c51 (patch) | |
tree | 0529c5ef39bb2b560eefbda8a2b45a340eee87b1 /utils | |
parent | 07fc1ba7553f2f5bf26984091197311decd9028e (diff) |
Implement Attr dumping for -ast-dump.
http://llvm-reviews.chandlerc.com/D234
Patch by Philip Craig!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@171760 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/ClangAttrEmitter.cpp | 135 | ||||
-rw-r--r-- | utils/TableGen/TableGen.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/TableGenBackends.h | 1 |
3 files changed, 129 insertions, 13 deletions
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 08f4499aeb..3651636e95 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -125,6 +125,8 @@ 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 {} }; class SimpleArgument : public Argument { @@ -181,6 +183,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 +265,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 +381,15 @@ 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 << " dumpStmt(SA->get" << getUpperName() << "Expr());\n"; + OS << " else\n"; + OS << " dumpType(SA->get" << getUpperName() + << "Type()->getType());\n"; + } }; class VariadicArgument : public Argument { @@ -439,17 +476,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 +519,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 +547,21 @@ namespace { void writeValue(raw_ostream &OS) const { OS << "\" << get" << getUpperName() << "() << \""; } + void writeDump(raw_ostream &OS) const { + OS << " switch(SA->get" << getUpperName() << "()) {\n"; + OS << " default:\n"; + OS << " llvm_unreachable(\"Unknown " << getAttrName() << "Attr::" + << type << "!\");\n"; + OS << " break;\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,13 @@ namespace { << "Result.takeAs<Expr>();\n"; OS << " }\n"; } + + void writeDump(raw_ostream &OS) const { + } + + void writeDumpChildren(raw_ostream &OS) const { + OS << " dumpStmt(SA->get" << getUpperName() << "());\n"; + } }; class VariadicExprArgument : public VariadicArgument { @@ -607,6 +674,16 @@ 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 << " dumpStmt(*I);\n"; + } }; } @@ -1163,4 +1240,36 @@ void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) { << "}\n"; } +// Emits the code to dump an attribute. +void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &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); + for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end(); + I != E; ++I) + createArgument(**I, R.getName())->writeDumpChildren(OS); + } + OS << + " break;\n" + " }\n"; + } + OS << " }\n"; +} + } // end namespace clang diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index 32aaf71015..7e9076f7b3 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -33,6 +33,7 @@ enum ActionType { GenClangAttrTemplateInstantiate, GenClangAttrParsedAttrList, GenClangAttrParsedAttrKinds, + GenClangAttrDump, GenClangDiagsDefs, GenClangDiagGroups, GenClangDiagsIndexName, @@ -81,6 +82,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", @@ -153,6 +156,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; diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h index 838fc84dca..54e76fdd5e 100644 --- a/utils/TableGen/TableGenBackends.h +++ b/utils/TableGen/TableGenBackends.h @@ -39,6 +39,7 @@ 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); |