diff options
Diffstat (limited to 'clang/utils/TableGen')
| -rw-r--r-- | clang/utils/TableGen/ClangAttrEmitter.cpp | 138 | ||||
| -rw-r--r-- | clang/utils/TableGen/TableGen.cpp | 19 | ||||
| -rw-r--r-- | clang/utils/TableGen/TableGenBackends.h | 1 |
3 files changed, 140 insertions, 18 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index fdc4904f3c2..e217d69c132 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" #include "llvm/TableGen/TableGenBackend.h" @@ -95,11 +96,12 @@ namespace { class Argument { std::string lowerName, upperName; StringRef attrName; + bool isOpt; public: Argument(Record &Arg, StringRef Attr) : lowerName(Arg.getValueAsString("Name")), upperName(lowerName), - attrName(Attr) { + attrName(Attr), isOpt(false) { if (!lowerName.empty()) { lowerName[0] = std::tolower(lowerName[0]); upperName[0] = std::toupper(upperName[0]); @@ -111,6 +113,9 @@ namespace { StringRef getUpperName() const { return upperName; } StringRef getAttrName() const { return attrName; } + bool isOptional() const { return isOpt; } + void setOptional(bool set) { isOpt = set; } + // These functions print the argument contents formatted in different ways. virtual void writeAccessors(raw_ostream &OS) const = 0; virtual void writeAccessorDefinitions(raw_ostream &OS) const {} @@ -119,6 +124,7 @@ namespace { virtual void writeTemplateInstantiation(raw_ostream &OS) const {} virtual void writeCtorBody(raw_ostream &OS) const {} virtual void writeCtorInitializers(raw_ostream &OS) const = 0; + virtual void writeCtorDefaultInitializers(raw_ostream &OS) const = 0; virtual void writeCtorParameters(raw_ostream &OS) const = 0; virtual void writeDeclarations(raw_ostream &OS) const = 0; virtual void writePCHReadArgs(raw_ostream &OS) const = 0; @@ -154,6 +160,9 @@ namespace { void writeCtorInitializers(raw_ostream &OS) const { OS << getLowerName() << "(" << getUpperName() << ")"; } + void writeCtorDefaultInitializers(raw_ostream &OS) const { + OS << getLowerName() << "()"; + } void writeCtorParameters(raw_ostream &OS) const { OS << type << " " << getUpperName(); } @@ -246,6 +255,9 @@ namespace { << getLowerName() << "(new (Ctx, 1) char[" << getLowerName() << "Length])"; } + void writeCtorDefaultInitializers(raw_ostream &OS) const { + OS << getLowerName() << "Length(0)," << getLowerName() << "(0)"; + } void writeCtorParameters(raw_ostream &OS) const { OS << "llvm::StringRef " << getUpperName(); } @@ -347,6 +359,9 @@ namespace { void writeCtorInitializers(raw_ostream &OS) const { OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)"; } + void writeCtorDefaultInitializers(raw_ostream &OS) const { + OS << "is" << getLowerName() << "Expr(false)"; + } void writeCtorParameters(raw_ostream &OS) const { OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName(); } @@ -440,6 +455,9 @@ namespace { << getLowerName() << "(new (Ctx, 16) " << getType() << "[" << getLowerName() << "Size])"; } + void writeCtorDefaultInitializers(raw_ostream &OS) const { + OS << getLowerName() << "Size(0), " << getLowerName() << "(0)"; + } void writeCtorParameters(raw_ostream &OS) const { OS << getType() << " *" << getUpperName() << ", unsigned " << getUpperName() << "Size"; @@ -520,6 +538,9 @@ namespace { void writeCtorInitializers(raw_ostream &OS) const { OS << getLowerName() << "(" << getUpperName() << ")"; } + void writeCtorDefaultInitializers(raw_ostream &OS) const { + OS << getLowerName() << "(" << type << "(0))"; + } void writeCtorParameters(raw_ostream &OS) const { OS << type << " " << getUpperName(); } @@ -590,6 +611,9 @@ namespace { void writeCtorInitializers(raw_ostream &OS) const { OS << getLowerName() << "(" << getUpperName() << ")"; } + void writeCtorDefaultInitializers(raw_ostream &OS) const { + OS << getLowerName() << "()"; + } void writeCtorParameters(raw_ostream &OS) const { OS << "VersionTuple " << getUpperName(); } @@ -738,6 +762,10 @@ static Argument *createArgument(Record &Arg, StringRef Attr, break; } } + + if (Ptr && Arg.getValueAsBit("Optional")) + Ptr->setOptional(true); + return Ptr; } @@ -926,10 +954,13 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { OS << "\n public:\n"; OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; + bool HasOpt = false; for (ai = Args.begin(); ai != ae; ++ai) { OS << " , "; (*ai)->writeCtorParameters(OS); OS << "\n"; + if ((*ai)->isOptional()) + HasOpt = true; } OS << " , "; @@ -952,6 +983,41 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) { } OS << " }\n\n"; + // If there are optional arguments, write out a constructor that elides the + // optional arguments as well. + if (HasOpt) { + OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; + for (ai = Args.begin(); ai != ae; ++ai) { + if (!(*ai)->isOptional()) { + OS << " , "; + (*ai)->writeCtorParameters(OS); + OS << "\n"; + } + } + + OS << " , "; + OS << "unsigned SI = 0\n"; + + OS << " )\n"; + OS << " : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n"; + + for (ai = Args.begin(); ai != ae; ++ai) { + OS << " , "; + (*ai)->writeCtorDefaultInitializers(OS); + OS << "\n"; + } + + OS << " {\n"; + + for (ai = Args.begin(); ai != ae; ++ai) { + if (!(*ai)->isOptional()) { + (*ai)->writeCtorBody(OS); + OS << "\n"; + } + } + OS << " }\n\n"; + } + OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; OS << " virtual void printPretty(raw_ostream &OS,\n" << " const PrintingPolicy &Policy) const;\n"; @@ -1402,16 +1468,11 @@ void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) { << "} // end namespace clang\n"; } -// Emits the list of parsed attributes. -void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { - emitSourceFileHeader("List of all attributes that Clang recognizes", OS); +typedef std::vector<std::pair<std::string, Record *> > ParsedAttrMap; - OS << "#ifndef PARSED_ATTR\n"; - OS << "#define PARSED_ATTR(NAME) NAME\n"; - OS << "#endif\n\n"; - +static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records) { std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); - + ParsedAttrMap R; for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { Record &Attr = **I; @@ -1428,16 +1489,69 @@ void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { std::string AttrName = (*I)->getValueAsString("Name"); StringRef Spelling = NormalizeAttrName(AttrName); - - OS << "PARSED_ATTR(" << Spelling << ")\n"; + R.push_back(std::make_pair(Spelling.str(), &Attr)); } } else { StringRef AttrName = Attr.getName(); AttrName = NormalizeAttrName(AttrName); - OS << "PARSED_ATTR(" << AttrName << ")\n"; + R.push_back(std::make_pair(AttrName.str(), *I)); } } } + return R; +} + +// Emits the list of parsed attributes. +void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) { + 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"; + + ParsedAttrMap Names = getParsedAttrList(Records); + for (ParsedAttrMap::iterator I = Names.begin(), E = Names.end(); I != E; + ++I) { + OS << "PARSED_ATTR(" << I->first << ")\n"; + } +} + +static void emitArgInfo(const Record &R, raw_ostream &OS) { + // This function will count the number of arguments specified for the + // attribute and emit the number of required arguments followed by the + // number of optional arguments. + std::vector<Record *> Args = R.getValueAsListOfDefs("Args"); + unsigned ArgCount = 0, OptCount = 0; + for (std::vector<Record *>::const_iterator I = Args.begin(), E = Args.end(); + I != E; ++I) { + const Record &Arg = **I; + Arg.getValueAsBit("Optional") ? ++OptCount : ++ArgCount; + } + OS << ArgCount << ", " << OptCount; +} + +/// Emits the parsed attribute helpers +void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Parsed attribute helpers", OS); + + ParsedAttrMap Attrs = getParsedAttrList(Records); + + OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n"; + for (ParsedAttrMap::iterator I = Attrs.begin(), E = Attrs.end(); I != E; + ++I) { + // We need to generate struct instances based off ParsedAttrInfo from + // AttributeList.cpp. + OS << " { "; + emitArgInfo(*I->second, OS); + OS << ", " << I->second->getValueAsBit("HasCustomParsing"); + OS << " }"; + + if (I + 1 != E) + OS << ","; + + OS << " // AT_" << I->first << "\n"; + } + OS << "};\n\n"; } // Emits the kind list of parsed attributes diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp index 429b6fb311c..e6c703fc665 100644 --- a/clang/utils/TableGen/TableGen.cpp +++ b/clang/utils/TableGen/TableGen.cpp @@ -34,6 +34,7 @@ enum ActionType { GenClangAttrLateParsedList, GenClangAttrTemplateInstantiate, GenClangAttrParsedAttrList, + GenClangAttrParsedAttrImpl, GenClangAttrParsedAttrKinds, GenClangAttrDump, GenClangDiagsDefs, @@ -81,12 +82,15 @@ cl::opt<ActionType> Action( clEnumValN(GenClangAttrTemplateInstantiate, "gen-clang-attr-template-instantiate", "Generate a clang template instantiate code"), - clEnumValN(GenClangAttrParsedAttrList, - "gen-clang-attr-parsed-attr-list", - "Generate a clang parsed attribute list"), - clEnumValN(GenClangAttrParsedAttrKinds, - "gen-clang-attr-parsed-attr-kinds", - "Generate a clang parsed attribute kinds"), + clEnumValN(GenClangAttrParsedAttrList, + "gen-clang-attr-parsed-attr-list", + "Generate a clang parsed attribute list"), + clEnumValN(GenClangAttrParsedAttrImpl, + "gen-clang-attr-parsed-attr-impl", + "Generate the clang parsed attribute helpers"), + 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", @@ -167,6 +171,9 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenClangAttrParsedAttrList: EmitClangAttrParsedAttrList(Records, OS); break; + case GenClangAttrParsedAttrImpl: + EmitClangAttrParsedAttrImpl(Records, OS); + break; case GenClangAttrParsedAttrKinds: EmitClangAttrParsedAttrKinds(Records, OS); break; diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h index b641732b810..d95d0afff11 100644 --- a/clang/utils/TableGen/TableGenBackends.h +++ b/clang/utils/TableGen/TableGenBackends.h @@ -40,6 +40,7 @@ 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 EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS); void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS); |

