diff options
Diffstat (limited to 'clang/utils/TableGen/ClangAttrEmitter.cpp')
| -rw-r--r-- | clang/utils/TableGen/ClangAttrEmitter.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 4d3daf605c3..7951fc467d2 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -16,6 +16,7 @@ #include "llvm/TableGen/Record.h" #include <algorithm> #include <cctype> +#include <set> using namespace llvm; @@ -65,6 +66,30 @@ static std::string WritePCHRecord(StringRef type, StringRef name) { .Default("Record.push_back(" + std::string(name) + ");\n"); } +// Normalize attribute name by removing leading and trailing +// underscores. For example, __foo, foo__, __foo__ would +// become foo. +static StringRef NormalizeAttrName(StringRef AttrName) { + if (AttrName.startswith("__")) + AttrName = AttrName.substr(2, AttrName.size()); + + if (AttrName.endswith("__")) + AttrName = AttrName.substr(0, AttrName.size() - 2); + + return AttrName; +} + +// Normalize attribute spelling only if the spelling has both leading +// and trailing underscores. For example, __ms_struct__ will be +// normalized to "ms_struct"; __cdecl will remain intact. +static StringRef NormalizeAttrSpelling(StringRef AttrSpelling) { + if (AttrSpelling.startswith("__") && AttrSpelling.endswith("__")) { + AttrSpelling = AttrSpelling.substr(2, AttrSpelling.size() - 4); + } + + return AttrSpelling; +} + namespace { class Argument { std::string lowerName, upperName; @@ -999,3 +1024,69 @@ void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) { << "} // end namespace clang\n"; } +void ClangAttrParsedAttrListEmitter::run(raw_ostream &OS) { + OS << "// This file is generated by TableGen. Do not edit.\n\n"; + + OS << "#ifndef PARSED_ATTR\n"; + OS << "#define PARSED_ATTR(NAME) NAME\n"; + OS << "#endif\n\n"; + + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); + std::set<StringRef> ProcessedAttrs; + + for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); + I != E; ++I) { + Record &Attr = **I; + + bool SemaHandler = Attr.getValueAsBit("SemaHandler"); + + if (SemaHandler) { + std::vector<StringRef> Spellings = + getValueAsListOfStrings(Attr, "Spellings"); + + for (std::vector<StringRef>::const_iterator I = Spellings.begin(), + E = Spellings.end(); I != E; ++I) { + StringRef AttrName = *I; + + AttrName = NormalizeAttrName(AttrName); + // skip if a normalized version has been processed. + if (ProcessedAttrs.find(AttrName) != ProcessedAttrs.end()) + continue; + else + ProcessedAttrs.insert(AttrName); + + OS << "PARSED_ATTR(" << AttrName << ")\n"; + } + } + } +} + +void ClangAttrParsedAttrKindsEmitter::run(raw_ostream &OS) { + OS << "// This file is generated by TableGen. Do not edit.\n\n"; + + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); + + for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); + I != E; ++I) { + Record &Attr = **I; + + bool SemaHandler = Attr.getValueAsBit("SemaHandler"); + + if (SemaHandler) { + std::vector<StringRef> Spellings = + getValueAsListOfStrings(Attr, "Spellings"); + + for (std::vector<StringRef>::const_iterator I = Spellings.begin(), + E = Spellings.end(); I != E; ++I) { + StringRef AttrName = *I, Spelling = *I; + + AttrName = NormalizeAttrName(AttrName); + Spelling = NormalizeAttrSpelling(Spelling); + + OS << ".Case(\"" << Spelling << "\", " << "AT_" << AttrName << ")\n"; + } + } + } +} + + |

