diff options
Diffstat (limited to 'utils/TableGen')
| -rw-r--r-- | utils/TableGen/ClangASTNodesEmitter.cpp | 61 | ||||
| -rw-r--r-- | utils/TableGen/ClangASTNodesEmitter.h | 84 | ||||
| -rw-r--r-- | utils/TableGen/ClangAttrEmitter.cpp | 175 | ||||
| -rw-r--r-- | utils/TableGen/ClangAttrEmitter.h | 153 | ||||
| -rw-r--r-- | utils/TableGen/ClangDiagnosticsEmitter.cpp | 294 | ||||
| -rw-r--r-- | utils/TableGen/ClangDiagnosticsEmitter.h | 54 | ||||
| -rw-r--r-- | utils/TableGen/ClangSACheckersEmitter.cpp | 8 | ||||
| -rw-r--r-- | utils/TableGen/ClangSACheckersEmitter.h | 31 | ||||
| -rw-r--r-- | utils/TableGen/NeonEmitter.cpp | 233 | ||||
| -rw-r--r-- | utils/TableGen/NeonEmitter.h | 210 | ||||
| -rw-r--r-- | utils/TableGen/OptParserEmitter.cpp | 13 | ||||
| -rw-r--r-- | utils/TableGen/OptParserEmitter.h | 34 | ||||
| -rw-r--r-- | utils/TableGen/TableGen.cpp | 58 | ||||
| -rw-r--r-- | utils/TableGen/TableGenBackends.h | 56 | 
14 files changed, 777 insertions, 687 deletions
diff --git a/utils/TableGen/ClangASTNodesEmitter.cpp b/utils/TableGen/ClangASTNodesEmitter.cpp index d9d5a3ccd907..c51ca9645db0 100644 --- a/utils/TableGen/ClangASTNodesEmitter.cpp +++ b/utils/TableGen/ClangASTNodesEmitter.cpp @@ -11,10 +11,58 @@  //  //===----------------------------------------------------------------------===// -#include "ClangASTNodesEmitter.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" +#include <cctype> +#include <map>  #include <set> +#include <string>  using namespace llvm; +/// ClangASTNodesEmitter - The top-level class emits .inc files containing +///  declarations of Clang statements. +/// +namespace { +class ClangASTNodesEmitter { +  // A map from a node to each of its derived nodes. +  typedef std::multimap<Record*, Record*> ChildMap; +  typedef ChildMap::const_iterator ChildIterator; + +  RecordKeeper &Records; +  Record Root; +  const std::string &BaseSuffix; + +  // Create a macro-ized version of a name +  static std::string macroName(std::string S) { +    for (unsigned i = 0; i < S.size(); ++i) +      S[i] = std::toupper(S[i]); + +    return S; +  } + +  // Return the name to be printed in the base field. Normally this is +  // the record's name plus the base suffix, but if it is the root node and +  // the suffix is non-empty, it's just the suffix. +  std::string baseName(Record &R) { +    if (&R == &Root && !BaseSuffix.empty()) +      return BaseSuffix; + +    return R.getName() + BaseSuffix; +  } + +  std::pair<Record *, Record *> EmitNode (const ChildMap &Tree, raw_ostream& OS, +                                          Record *Base); +public: +  explicit ClangASTNodesEmitter(RecordKeeper &R, const std::string &N, +                                const std::string &S) +    : Records(R), Root(N, SMLoc(), R), BaseSuffix(S) +    {} + +  // run - Output the .inc file contents +  void run(raw_ostream &OS); +}; +} // end anonymous namespace +  //===----------------------------------------------------------------------===//  // Statement Node Tables (.inc file) generation.  //===----------------------------------------------------------------------===// @@ -124,7 +172,15 @@ void ClangASTNodesEmitter::run(raw_ostream &OS) {    OS << "#undef ABSTRACT_" << macroName(Root.getName()) << "\n";  } -void ClangDeclContextEmitter::run(raw_ostream &OS) { +namespace clang { +void EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS, +                       const std::string &N, const std::string &S) { +  ClangASTNodesEmitter(RK, N, S).run(OS); +} + +// Emits and addendum to a .inc file to enumerate the clang declaration +// contexts. +void EmitClangDeclContext(RecordKeeper &Records, raw_ostream &OS) {    // FIXME: Find a .td file format to allow for this to be represented better.    OS << "#ifndef DECL_CONTEXT\n"; @@ -166,3 +222,4 @@ void ClangDeclContextEmitter::run(raw_ostream &OS) {    OS << "#undef DECL_CONTEXT\n";    OS << "#undef DECL_CONTEXT_BASE\n";  } +} // end namespace clang diff --git a/utils/TableGen/ClangASTNodesEmitter.h b/utils/TableGen/ClangASTNodesEmitter.h deleted file mode 100644 index edd9316544ea..000000000000 --- a/utils/TableGen/ClangASTNodesEmitter.h +++ /dev/null @@ -1,84 +0,0 @@ -//===- ClangASTNodesEmitter.h - Generate Clang AST node tables -*- C++ -*--===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang AST node tables -// -//===----------------------------------------------------------------------===// - -#ifndef CLANGAST_EMITTER_H -#define CLANGAST_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" -#include "llvm/TableGen/Record.h" -#include <string> -#include <cctype> -#include <map> - -namespace llvm { - -/// ClangASTNodesEmitter - The top-level class emits .inc files containing -///  declarations of Clang statements. -/// -class ClangASTNodesEmitter : public TableGenBackend { -  // A map from a node to each of its derived nodes. -  typedef std::multimap<Record*, Record*> ChildMap; -  typedef ChildMap::const_iterator ChildIterator; - -  RecordKeeper &Records; -  Record Root; -  const std::string &BaseSuffix; - -  // Create a macro-ized version of a name -  static std::string macroName(std::string S) { -    for (unsigned i = 0; i < S.size(); ++i) -      S[i] = std::toupper(S[i]); - -    return S; -  } - -  // Return the name to be printed in the base field. Normally this is -  // the record's name plus the base suffix, but if it is the root node and -  // the suffix is non-empty, it's just the suffix. -  std::string baseName(Record &R) { -    if (&R == &Root && !BaseSuffix.empty()) -      return BaseSuffix; -     -    return R.getName() + BaseSuffix; -  } - -  std::pair<Record *, Record *> EmitNode (const ChildMap &Tree, raw_ostream& OS, -                                          Record *Base); -public: -  explicit ClangASTNodesEmitter(RecordKeeper &R, const std::string &N, -                                const std::string &S) -    : Records(R), Root(N, SMLoc(), R), BaseSuffix(S) -    {} - -  // run - Output the .inc file contents -  void run(raw_ostream &OS); -}; - -/// ClangDeclContextEmitter - Emits an addendum to a .inc file to enumerate the -/// clang declaration contexts. -/// -class ClangDeclContextEmitter : public TableGenBackend { -  RecordKeeper &Records; - -public: -  explicit ClangDeclContextEmitter(RecordKeeper &R) -    : Records(R) -  {} - -  // run - Output the .inc file contents -  void run(raw_ostream &OS); -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 7951fc467d20..1b1a478ceb13 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -11,12 +11,13 @@  //  //===----------------------------------------------------------------------===// -#include "ClangAttrEmitter.h" +#include "llvm/ADT/SmallString.h"  #include "llvm/ADT/StringSwitch.h"  #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringMatcher.h" +#include "llvm/TableGen/TableGenBackend.h"  #include <algorithm>  #include <cctype> -#include <set>  using namespace llvm; @@ -660,7 +661,10 @@ static void writeAvailabilityValue(raw_ostream &OS) {       << "  OS << \"";  } -void ClangAttrClassEmitter::run(raw_ostream &OS) { +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";    OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";    OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; @@ -670,6 +674,10 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) {    for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();         i != e; ++i) {      Record &R = **i; +     +    if (!R.getValueAsBit("ASTNode")) +      continue; +          const std::string &SuperName = R.getSuperClasses().back()->getName();      OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; @@ -745,7 +753,8 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) {    OS << "#endif\n";  } -void ClangAttrImplEmitter::run(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";    std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -754,8 +763,12 @@ void ClangAttrImplEmitter::run(raw_ostream &OS) {    for (; i != e; ++i) {      Record &R = **i; +     +    if (!R.getValueAsBit("ASTNode")) +      continue; +          std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); -    std::vector<StringRef> Spellings = getValueAsListOfStrings(R, "Spellings"); +    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())); @@ -775,9 +788,10 @@ void ClangAttrImplEmitter::run(raw_ostream &OS) {      OS << "void " << R.getName() << "Attr::printPretty("         << "llvm::raw_ostream &OS, ASTContext &Ctx) const {\n";      if (Spellings.begin() != Spellings.end()) { -      OS << "  OS << \" __attribute__((" << *Spellings.begin(); +      std::string Spelling = (*Spellings.begin())->getValueAsString("Name"); +      OS << "  OS << \" __attribute__((" << Spelling;        if (Args.size()) OS << "("; -      if (*Spellings.begin()=="availability") { +      if (Spelling == "availability") {          writeAvailabilityValue(OS);        } else {          for (ai = Args.begin(); ai != ae; ++ai) { @@ -792,20 +806,29 @@ void ClangAttrImplEmitter::run(raw_ostream &OS) {    }  } +} // end namespace clang +  static void EmitAttrList(raw_ostream &OS, StringRef Class,                           const std::vector<Record*> &AttrList) {    std::vector<Record*>::const_iterator i = AttrList.begin(), e = AttrList.end();    if (i != e) {      // Move the end iterator back to emit the last attribute. -    for(--e; i != e; ++i) +    for(--e; i != e; ++i) { +      if (!(*i)->getValueAsBit("ASTNode")) +        continue; +              OS << Class << "(" << (*i)->getName() << ")\n"; +    }      OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n";    }  } -void ClangAttrListEmitter::run(raw_ostream &OS) { +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";    OS << "#ifndef LAST_ATTR\n"; @@ -835,6 +858,9 @@ void ClangAttrListEmitter::run(raw_ostream &OS) {                         NonInhAttrs, InhAttrs, InhParamAttrs;    for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();         i != e; ++i) { +    if (!(*i)->getValueAsBit("ASTNode")) +      continue; +          if ((*i)->isSubClassOf(InhParamClass))        InhParamAttrs.push_back(*i);      else if ((*i)->isSubClassOf(InhClass)) @@ -854,7 +880,8 @@ void ClangAttrListEmitter::run(raw_ostream &OS) {    OS << "#undef ATTR\n";  } -void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { +// 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";    Record *InhClass = Records.getClass("InheritableAttr"); @@ -870,6 +897,9 @@ void ClangAttrPCHReadEmitter::run(raw_ostream &OS) {    OS << "    break;\n";    for (; i != e; ++i) {      Record &R = **i; +    if (!R.getValueAsBit("ASTNode")) +      continue; +          OS << "  case attr::" << R.getName() << ": {\n";      if (R.isSubClassOf(InhClass))        OS << "    bool isInherited = Record[Idx++];\n"; @@ -894,7 +924,8 @@ void ClangAttrPCHReadEmitter::run(raw_ostream &OS) {    OS << "  }\n";  } -void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { +// Emits the code to write an attribute to a precompiled header. +void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &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; @@ -905,6 +936,8 @@ void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) {    OS << "    break;\n";    for (; i != e; ++i) {      Record &R = **i; +    if (!R.getValueAsBit("ASTNode")) +      continue;      OS << "  case attr::" << R.getName() << ": {\n";      Args = R.getValueAsListOfDefs("Args");      if (R.isSubClassOf(InhClass) || !Args.empty()) @@ -920,7 +953,8 @@ void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) {    OS << "  }\n";  } -void ClangAttrSpellingListEmitter::run(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";    std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -928,17 +962,17 @@ void ClangAttrSpellingListEmitter::run(raw_ostream &OS) {    for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {      Record &Attr = **I; -    std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings"); +    std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); -    for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { -      StringRef Spelling = *I; -      OS << ".Case(\"" << Spelling << "\", true)\n"; +    for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { +      OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n";      }    }  } -void ClangAttrLateParsedListEmitter::run(raw_ostream &OS) { +// 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";    std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -950,19 +984,23 @@ void ClangAttrLateParsedListEmitter::run(raw_ostream &OS) {      bool LateParsed = Attr.getValueAsBit("LateParsed");      if (LateParsed) { -      std::vector<StringRef> Spellings = -        getValueAsListOfStrings(Attr, "Spellings"); +      std::vector<Record*> Spellings = +        Attr.getValueAsListOfDefs("Spellings"); -      for (std::vector<StringRef>::const_iterator I = Spellings.begin(), +      // FIXME: Handle non-GNU attributes +      for (std::vector<Record*>::const_iterator I = Spellings.begin(),             E = Spellings.end(); I != E; ++I) { -        OS << ".Case(\"" << (*I) << "\", " << LateParsed << ")\n"; +        if ((*I)->getValueAsString("Variety") != "GNU") +          continue; +        OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", " +           << LateParsed << ")\n";        }      }    }  } - -void ClangAttrTemplateInstantiateEmitter::run(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";    std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); @@ -979,8 +1017,18 @@ void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) {    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"; +    bool ShouldClone = R.getValueAsBit("Clone"); + +    if (!ShouldClone) { +      OS << "      return NULL;\n"; +      OS << "    }\n"; +      continue; +    } +      OS << "      const " << R.getName() << "Attr *A = cast<"         << R.getName() << "Attr>(At);\n";      bool TDependent = R.getValueAsBit("TemplateDependent"); @@ -1024,7 +1072,8 @@ void ClangAttrTemplateInstantiateEmitter::run(raw_ostream &OS) {       << "} // end namespace clang\n";  } -void ClangAttrParsedAttrListEmitter::run(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";    OS << "#ifndef PARSED_ATTR\n"; @@ -1032,61 +1081,85 @@ void ClangAttrParsedAttrListEmitter::run(raw_ostream &OS) {    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"); -     +    bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings"); +      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; +      if (DistinctSpellings) { +        std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); +         +        for (std::vector<Record*>::const_iterator I = Spellings.begin(), +             E = Spellings.end(); I != E; ++I) { +          std::string AttrName = (*I)->getValueAsString("Name"); -        AttrName = NormalizeAttrName(AttrName); -        // skip if a normalized version has been processed. -        if (ProcessedAttrs.find(AttrName) != ProcessedAttrs.end()) -          continue; -        else -          ProcessedAttrs.insert(AttrName); +          StringRef Spelling = NormalizeAttrName(AttrName); +          OS << "PARSED_ATTR(" << Spelling << ")\n"; +        } +      } else { +        StringRef AttrName = Attr.getName(); +        AttrName = NormalizeAttrName(AttrName);          OS << "PARSED_ATTR(" << AttrName << ")\n";        }      }    }  } -void ClangAttrParsedAttrKindsEmitter::run(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"; +      std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); +  std::vector<StringMatcher::StringPair> Matches;    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"); +    bool Ignored = Attr.getValueAsBit("Ignored"); +    bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings"); +    if (SemaHandler || Ignored) { +      std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings"); -      for (std::vector<StringRef>::const_iterator I = Spellings.begin(), +      for (std::vector<Record*>::const_iterator I = Spellings.begin(),             E = Spellings.end(); I != E; ++I) { -       StringRef AttrName = *I, Spelling = *I; -        -       AttrName = NormalizeAttrName(AttrName); -       Spelling = NormalizeAttrSpelling(Spelling); +        std::string RawSpelling = (*I)->getValueAsString("Name"); +        StringRef AttrName = NormalizeAttrName(DistinctSpellings +                                                 ? StringRef(RawSpelling) +                                                 : StringRef(Attr.getName())); + +        SmallString<64> Spelling; +        if ((*I)->getValueAsString("Variety") == "CXX11") { +          Spelling += (*I)->getValueAsString("Namespace"); +          Spelling += "::"; +        } +        Spelling += NormalizeAttrSpelling(RawSpelling); -       OS << ".Case(\"" << Spelling << "\", " << "AT_" << AttrName << ")\n"; +        if (SemaHandler) +          Matches.push_back( +            StringMatcher::StringPair( +              StringRef(Spelling), +              "return AttributeList::AT_" + AttrName.str() + ";")); +        else +          Matches.push_back( +            StringMatcher::StringPair( +              StringRef(Spelling), +              "return AttributeList::IgnoredAttribute;"));        }      }    } +   +  OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n"; +  StringMatcher("Name", Matches, OS).Emit(); +  OS << "return AttributeList::UnknownAttribute;\n" +     << "}\n";  } - +} // end namespace clang diff --git a/utils/TableGen/ClangAttrEmitter.h b/utils/TableGen/ClangAttrEmitter.h deleted file mode 100644 index d119a094c177..000000000000 --- a/utils/TableGen/ClangAttrEmitter.h +++ /dev/null @@ -1,153 +0,0 @@ -//===- ClangAttrEmitter.h - Generate Clang attribute handling =-*- C++ -*--===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang attribute processing code -// -//===----------------------------------------------------------------------===// - -#ifndef CLANGATTR_EMITTER_H -#define CLANGATTR_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" - -namespace llvm { - -/// ClangAttrClassEmitter - class emits the class defintions for attributes for -///   clang. -class ClangAttrClassEmitter : public TableGenBackend { -  RecordKeeper &Records; -  - public: -  explicit ClangAttrClassEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrImplEmitter - class emits the class method defintions for -///   attributes for clang. -class ClangAttrImplEmitter : public TableGenBackend { -  RecordKeeper &Records; -  - public: -  explicit ClangAttrImplEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrListEmitter - class emits the enumeration list for attributes for -///   clang. -class ClangAttrListEmitter : public TableGenBackend { -  RecordKeeper &Records; - - public: -  explicit ClangAttrListEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrPCHReadEmitter - class emits the code to read an attribute from -///   a clang precompiled header. -class ClangAttrPCHReadEmitter : public TableGenBackend { -  RecordKeeper &Records; - -public: -  explicit ClangAttrPCHReadEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrPCHWriteEmitter - class emits the code to read an attribute from -///   a clang precompiled header. -class ClangAttrPCHWriteEmitter : public TableGenBackend { -  RecordKeeper &Records; - -public: -  explicit ClangAttrPCHWriteEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrSpellingListEmitter - class emits the list of spellings for attributes for -///   clang. -class ClangAttrSpellingListEmitter : public TableGenBackend { -  RecordKeeper &Records; - - public: -  explicit ClangAttrSpellingListEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrLateParsedListEmitter emits the LateParsed property for attributes -/// for clang. -class ClangAttrLateParsedListEmitter : public TableGenBackend { -  RecordKeeper &Records; - - public: -  explicit ClangAttrLateParsedListEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrTemplateInstantiateEmitter emits code to instantiate dependent -/// attributes on templates. -class ClangAttrTemplateInstantiateEmitter : public TableGenBackend { -  RecordKeeper &Records; - - public: -  explicit ClangAttrTemplateInstantiateEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrParsedAttrListEmitter emits the list of parsed attributes -/// for clang. -class ClangAttrParsedAttrListEmitter : public TableGenBackend { -  RecordKeeper &Records; - -public: -  explicit ClangAttrParsedAttrListEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -/// ClangAttrParsedAttrKindsEmitter emits the kind list of parsed attributes -/// for clang. -class ClangAttrParsedAttrKindsEmitter : public TableGenBackend { -  RecordKeeper &Records; - -public: -  explicit ClangAttrParsedAttrKindsEmitter(RecordKeeper &R) -    : Records(R) -    {} - -  void run(raw_ostream &OS); -}; - -} - -#endif diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp index 8a49619c725e..8615d2db8cda 100644 --- a/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -11,16 +11,19 @@  //  //===----------------------------------------------------------------------===// -#include "ClangDiagnosticsEmitter.h" -#include "llvm/TableGen/Record.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" +#include "llvm/ADT/PointerUnion.h"  #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/StringMap.h"  #include "llvm/ADT/SmallString.h" -#include <map> +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h"  #include <algorithm> +#include <cctype>  #include <functional> +#include <map>  #include <set>  using namespace llvm; @@ -78,7 +81,7 @@ static std::string getDiagnosticCategory(const Record *R,                                                     DiagGroupParents);      if (!CatName.empty()) return CatName;    } -   +    // If the diagnostic itself has a category, get it.    return R->getValueAsString("CategoryName");  } @@ -135,6 +138,8 @@ static void groupDiagnostics(const std::vector<Record*> &Diags,      const Record *R = Diags[i];      DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group"));      if (DI == 0) continue; +    assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" && +           "Note can't be in a DiagGroup");      std::string GroupName = DI->getDef()->getValueAsString("GroupName");      DiagsInGroup[GroupName].DiagsInGroup.push_back(R);    } @@ -158,10 +163,201 @@ static void groupDiagnostics(const std::vector<Record*> &Diags,  }  //===----------------------------------------------------------------------===// +// Infer members of -Wpedantic. +//===----------------------------------------------------------------------===// + +typedef std::vector<const Record *> RecordVec; +typedef llvm::DenseSet<const Record *> RecordSet; +typedef llvm::PointerUnion<RecordVec*, RecordSet*> VecOrSet; + +namespace { +class InferPedantic { +  typedef llvm::DenseMap<const Record*, +                         std::pair<unsigned, llvm::Optional<unsigned> > > GMap; + +  DiagGroupParentMap &DiagGroupParents; +  const std::vector<Record*> &Diags; +  const std::vector<Record*> DiagGroups; +  std::map<std::string, GroupInfo> &DiagsInGroup; +  llvm::DenseSet<const Record*> DiagsSet; +  GMap GroupCount; +public: +  InferPedantic(DiagGroupParentMap &DiagGroupParents, +                const std::vector<Record*> &Diags, +                const std::vector<Record*> &DiagGroups, +                std::map<std::string, GroupInfo> &DiagsInGroup) +  : DiagGroupParents(DiagGroupParents), +  Diags(Diags), +  DiagGroups(DiagGroups), +  DiagsInGroup(DiagsInGroup) {} + +  /// Compute the set of diagnostics and groups that are immediately +  /// in -Wpedantic. +  void compute(VecOrSet DiagsInPedantic, +               VecOrSet GroupsInPedantic); + +private: +  /// Determine whether a group is a subgroup of another group. +  bool isSubGroupOfGroup(const Record *Group, +                         llvm::StringRef RootGroupName); + +  /// Determine if the diagnostic is an extension. +  bool isExtension(const Record *Diag); + +  /// Determine if the diagnostic is off by default. +  bool isOffByDefault(const Record *Diag); + +  /// Increment the count for a group, and transitively marked +  /// parent groups when appropriate. +  void markGroup(const Record *Group); + +  /// Return true if the diagnostic is in a pedantic group. +  bool groupInPedantic(const Record *Group, bool increment = false); +}; +} // end anonymous namespace + +bool InferPedantic::isSubGroupOfGroup(const Record *Group, +                                      llvm::StringRef GName) { + +  const std::string &GroupName = Group->getValueAsString("GroupName"); +  if (GName == GroupName) +    return true; + +  const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); +  for (unsigned i = 0, e = Parents.size(); i != e; ++i) +    if (isSubGroupOfGroup(Parents[i], GName)) +      return true; + +  return false; +} + +/// Determine if the diagnostic is an extension. +bool InferPedantic::isExtension(const Record *Diag) { +  const std::string &ClsName = Diag->getValueAsDef("Class")->getName(); +  return ClsName == "CLASS_EXTENSION"; +} + +bool InferPedantic::isOffByDefault(const Record *Diag) { +  const std::string &DefMap = Diag->getValueAsDef("DefaultMapping")->getName(); +  return DefMap == "MAP_IGNORE"; +} + +bool InferPedantic::groupInPedantic(const Record *Group, bool increment) { +  GMap::mapped_type &V = GroupCount[Group]; +  // Lazily compute the threshold value for the group count. +  if (!V.second.hasValue()) { +    const GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; +    V.second = GI.SubGroups.size() + GI.DiagsInGroup.size(); +  } + +  if (increment) +    ++V.first; + +  // Consider a group in -Wpendatic IFF if has at least one diagnostic +  // or subgroup AND all of those diagnostics and subgroups are covered +  // by -Wpedantic via our computation. +  return V.first != 0 && V.first == V.second.getValue(); +} + +void InferPedantic::markGroup(const Record *Group) { +  // If all the diagnostics and subgroups have been marked as being +  // covered by -Wpedantic, increment the count of parent groups.  Once the +  // group's count is equal to the number of subgroups and diagnostics in +  // that group, we can safely add this group to -Wpedantic. +  if (groupInPedantic(Group, /* increment */ true)) { +    const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); +    for (unsigned i = 0, e = Parents.size(); i != e; ++i) +      markGroup(Parents[i]); +  } +} + +void InferPedantic::compute(VecOrSet DiagsInPedantic, +                            VecOrSet GroupsInPedantic) { +  // All extensions that are not on by default are implicitly in the +  // "pedantic" group.  For those that aren't explicitly included in -Wpedantic, +  // mark them for consideration to be included in -Wpedantic directly. +  for (unsigned i = 0, e = Diags.size(); i != e; ++i) { +    Record *R = Diags[i]; +    if (isExtension(R) && isOffByDefault(R)) { +      DiagsSet.insert(R); +      if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) { +        const Record *GroupRec = Group->getDef(); +        if (!isSubGroupOfGroup(GroupRec, "pedantic")) { +          markGroup(GroupRec); +        } +      } +    } +  } + +  // Compute the set of diagnostics that are directly in -Wpedantic.  We +  // march through Diags a second time to ensure the results are emitted +  // in deterministic order. +  for (unsigned i = 0, e = Diags.size(); i != e; ++i) { +    Record *R = Diags[i]; +    if (!DiagsSet.count(R)) +      continue; +    // Check if the group is implicitly in -Wpedantic.  If so, +    // the diagnostic should not be directly included in the -Wpedantic +    // diagnostic group. +    if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) +      if (groupInPedantic(Group->getDef())) +        continue; + +    // The diagnostic is not included in a group that is (transitively) in +    // -Wpedantic.  Include it in -Wpedantic directly. +    if (RecordVec *V = DiagsInPedantic.dyn_cast<RecordVec*>()) +      V->push_back(R); +    else { +      DiagsInPedantic.get<RecordSet*>()->insert(R); +    } +  } + +  if (!GroupsInPedantic) +    return; + +  // Compute the set of groups that are directly in -Wpedantic.  We +  // march through the groups to ensure the results are emitted +  /// in a deterministc order. +  for (unsigned i = 0, ei = DiagGroups.size(); i != ei; ++i) { +    Record *Group = DiagGroups[i]; +    if (!groupInPedantic(Group)) +      continue; + +    unsigned ParentsInPedantic = 0; +    const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); +    for (unsigned j = 0, ej = Parents.size(); j != ej; ++j) { +      if (groupInPedantic(Parents[j])) +        ++ParentsInPedantic; +    } +    // If all the parents are in -Wpedantic, this means that this diagnostic +    // group will be indirectly included by -Wpedantic already.  In that +    // case, do not add it directly to -Wpedantic.  If the group has no +    // parents, obviously it should go into -Wpedantic. +    if (Parents.size() > 0 && ParentsInPedantic == Parents.size()) +      continue; + +    if (RecordVec *V = GroupsInPedantic.dyn_cast<RecordVec*>()) +      V->push_back(Group); +    else { +      GroupsInPedantic.get<RecordSet*>()->insert(Group); +    } +  } +} + +//===----------------------------------------------------------------------===//  // Warning Tables (.inc file) generation.  //===----------------------------------------------------------------------===// -void ClangDiagsDefsEmitter::run(raw_ostream &OS) { +static bool isError(const Record &Diag) { +  const std::string &ClsName = Diag.getValueAsDef("Class")->getName(); +  return ClsName == "CLASS_ERROR"; +} + +/// ClangDiagsDefsEmitter - The top-level class emits .def files containing +/// declarations of Clang diagnostics. +namespace clang { +void EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS, +                        const std::string &Component) {    // Write the #if guard    if (!Component.empty()) {      std::string ComponentName = StringRef(Component).upper(); @@ -184,8 +380,25 @@ void ClangDiagsDefsEmitter::run(raw_ostream &OS) {    DiagCategoryIDMap CategoryIDs(Records);    DiagGroupParentMap DGParentMap(Records); +  // Compute the set of diagnostics that are in -Wpedantic. +  RecordSet DiagsInPedantic; +  InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup); +  inferPedantic.compute(&DiagsInPedantic, (RecordVec*)0); +    for (unsigned i = 0, e = Diags.size(); i != e; ++i) {      const Record &R = *Diags[i]; +     +    // Check if this is an error that is accidentally in a warning +    // group. +    if (isError(R)) { +      if (DefInit *Group = dynamic_cast<DefInit*>(R.getValueInit("Group"))) { +        const Record *GroupRec = Group->getDef(); +        const std::string &GroupName = GroupRec->getValueAsString("GroupName"); +        throw "Error " + R.getName() + " cannot be in a warning group [" + +              GroupName + "]"; +      } +    } +      // Filter by component.      if (!Component.empty() && Component != R.getValueAsString("Component"))        continue; @@ -205,6 +418,11 @@ void ClangDiagsDefsEmitter::run(raw_ostream &OS) {            DiagsInGroup.find(DI->getDef()->getValueAsString("GroupName"));        assert(I != DiagsInGroup.end());        OS << ", " << I->second.IDNo; +    } else if (DiagsInPedantic.count(&R)) { +      std::map<std::string, GroupInfo>::iterator I = +        DiagsInGroup.find("pedantic"); +      assert(I != DiagsInGroup.end() && "pedantic group not defined"); +      OS << ", " << I->second.IDNo;      } else {        OS << ", 0";      } @@ -242,6 +460,7 @@ void ClangDiagsDefsEmitter::run(raw_ostream &OS) {      OS << ")\n";    }  } +} // end namespace clang  //===----------------------------------------------------------------------===//  // Warning Group Tables generation @@ -255,11 +474,12 @@ static std::string getDiagCategoryEnum(llvm::StringRef name) {      enumName += isalnum(*I) ? *I : '_';    return enumName.str();  } - -void ClangDiagGroupsEmitter::run(raw_ostream &OS) { +   +namespace clang { +void EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS) {    // Compute a mapping from a DiagGroup to all of its parents.    DiagGroupParentMap DGParentMap(Records); -   +    std::vector<Record*> Diags =      Records.getAllDerivedDefinitions("Diagnostic"); @@ -268,7 +488,15 @@ void ClangDiagGroupsEmitter::run(raw_ostream &OS) {    std::map<std::string, GroupInfo> DiagsInGroup;    groupDiagnostics(Diags, DiagGroups, DiagsInGroup); -   + +  // All extensions are implicitly in the "pedantic" group.  Record the +  // implicit set of groups in the "pedantic" group, and use this information +  // later when emitting the group information for Pedantic. +  RecordVec DiagsInPedantic; +  RecordVec GroupsInPedantic; +  InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup); +  inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic); +    // Walk through the groups emitting an array for each diagnostic of the diags    // that are mapped to.    OS << "\n#ifdef GET_DIAG_ARRAYS\n"; @@ -276,17 +504,23 @@ void ClangDiagGroupsEmitter::run(raw_ostream &OS) {    for (std::map<std::string, GroupInfo>::iterator         I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {      MaxLen = std::max(MaxLen, (unsigned)I->first.size()); -     +    const bool IsPedantic = I->first == "pedantic"; +      std::vector<const Record*> &V = I->second.DiagsInGroup; -    if (!V.empty()) { +    if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {        OS << "static const short DiagArray" << I->second.IDNo << "[] = { ";        for (unsigned i = 0, e = V.size(); i != e; ++i)          OS << "diag::" << V[i]->getName() << ", "; +      // Emit the diagnostics implicitly in "pedantic". +      if (IsPedantic) { +        for (unsigned i = 0, e = DiagsInPedantic.size(); i != e; ++i) +          OS << "diag::" << DiagsInPedantic[i]->getName() << ", "; +      }        OS << "-1 };\n";      }      const std::vector<std::string> &SubGroups = I->second.SubGroups; -    if (!SubGroups.empty()) { +    if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {        OS << "static const short DiagSubGroup" << I->second.IDNo << "[] = { ";        for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) {          std::map<std::string, GroupInfo>::iterator RI = @@ -294,6 +528,18 @@ void ClangDiagGroupsEmitter::run(raw_ostream &OS) {          assert(RI != DiagsInGroup.end() && "Referenced without existing?");          OS << RI->second.IDNo << ", ";        } +      // Emit the groups implicitly in "pedantic". +      if (IsPedantic) { +        for (unsigned i = 0, e = GroupsInPedantic.size(); i != e; ++i) { +          const std::string &GroupName = +            GroupsInPedantic[i]->getValueAsString("GroupName"); +          std::map<std::string, GroupInfo>::iterator RI = +            DiagsInGroup.find(GroupName); +          assert(RI != DiagsInGroup.end() && "Referenced without existing?"); +          OS << RI->second.IDNo << ", "; +        } +      } +        OS << "-1 };\n";      }    } @@ -313,15 +559,22 @@ void ClangDiagGroupsEmitter::run(raw_ostream &OS) {        throw "Invalid character in diagnostic group '" + I->first + "'";      OS.write_escaped(I->first) << "\","                                 << std::string(MaxLen-I->first.size()+1, ' '); -     + +    // Special handling for 'pedantic'. +    const bool IsPedantic = I->first == "pedantic"; +      // Diagnostics in the group. -    if (I->second.DiagsInGroup.empty()) +    const bool hasDiags = !I->second.DiagsInGroup.empty() || +                          (IsPedantic && !DiagsInPedantic.empty()); +    if (!hasDiags)        OS << "0, ";      else        OS << "DiagArray" << I->second.IDNo << ", ";      // Subgroups. -    if (I->second.SubGroups.empty()) +    const bool hasSubGroups = !I->second.SubGroups.empty() || +                              (IsPedantic && !GroupsInPedantic.empty()); +    if (!hasSubGroups)        OS << 0;      else        OS << "DiagSubGroup" << I->second.IDNo; @@ -337,6 +590,7 @@ void ClangDiagGroupsEmitter::run(raw_ostream &OS) {      OS << "CATEGORY(\"" << *I << "\", " << getDiagCategoryEnum(*I) << ")\n";    OS << "#endif // GET_CATEGORY_TABLE\n\n";  } +} // end namespace clang  //===----------------------------------------------------------------------===//  // Diagnostic name index generation @@ -364,7 +618,8 @@ struct RecordIndexElementSorter :  } // end anonymous namespace. -void ClangDiagsIndexNameEmitter::run(raw_ostream &OS) { +namespace clang { +void EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS) {    const std::vector<Record*> &Diags =      Records.getAllDerivedDefinitions("Diagnostic"); @@ -383,3 +638,4 @@ void ClangDiagsIndexNameEmitter::run(raw_ostream &OS) {      OS << "DIAG_NAME_INDEX(" << R.Name << ")\n";    }  } +} // end namespace clang diff --git a/utils/TableGen/ClangDiagnosticsEmitter.h b/utils/TableGen/ClangDiagnosticsEmitter.h deleted file mode 100644 index 73d3c4dc0e97..000000000000 --- a/utils/TableGen/ClangDiagnosticsEmitter.h +++ /dev/null @@ -1,54 +0,0 @@ -//===- ClangDiagnosticsEmitter.h - Generate Clang diagnostics tables -*- C++ -*- -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang diagnostics tables. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANGDIAGS_EMITTER_H -#define CLANGDIAGS_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" - -namespace llvm { - -/// ClangDiagsDefsEmitter - The top-level class emits .def files containing -///  declarations of Clang diagnostics. -/// -class ClangDiagsDefsEmitter : public TableGenBackend { -  RecordKeeper &Records; -  const std::string& Component; -public: -  explicit ClangDiagsDefsEmitter(RecordKeeper &R, const std::string& component) -    : Records(R), Component(component) {} - -  // run - Output the .def file contents -  void run(raw_ostream &OS); -}; - -class ClangDiagGroupsEmitter : public TableGenBackend { -  RecordKeeper &Records; -public: -  explicit ClangDiagGroupsEmitter(RecordKeeper &R) : Records(R) {} -     -  void run(raw_ostream &OS); -}; - -class ClangDiagsIndexNameEmitter : public TableGenBackend { -  RecordKeeper &Records; -public: -  explicit ClangDiagsIndexNameEmitter(RecordKeeper &R) : Records(R) {} -   -  void run(raw_ostream &OS); -}; - -   -} // End llvm namespace - -#endif diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp index 423b68a64842..5a0db501dff9 100644 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ b/utils/TableGen/ClangSACheckersEmitter.cpp @@ -11,9 +11,9 @@  //  //===----------------------------------------------------------------------===// -#include "ClangSACheckersEmitter.h" -#include "llvm/TableGen/Record.h"  #include "llvm/ADT/DenseSet.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h"  #include <map>  #include <string>  using namespace llvm; @@ -93,7 +93,8 @@ static void addPackageToCheckerGroup(const Record *package, const Record *group,      addPackageToCheckerGroup(*I, group, recordGroupMap);  } -void ClangSACheckersEmitter::run(raw_ostream &OS) { +namespace clang { +void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) {    std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker");    llvm::DenseMap<const Record *, unsigned> checkerRecIndexMap;    for (unsigned i = 0, e = checkers.size(); i != e; ++i) @@ -317,3 +318,4 @@ void ClangSACheckersEmitter::run(raw_ostream &OS) {    }    OS << "#endif // GET_CHECKNAME_TABLE\n\n";  } +} // end namespace clang diff --git a/utils/TableGen/ClangSACheckersEmitter.h b/utils/TableGen/ClangSACheckersEmitter.h deleted file mode 100644 index 5a0e14811124..000000000000 --- a/utils/TableGen/ClangSACheckersEmitter.h +++ /dev/null @@ -1,31 +0,0 @@ -//===- ClangSACheckersEmitter.h - Generate Clang SA checkers tables -*- C++ -*- -// -//                     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 Clang Static Analyzer checkers tables. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANGSACHECKERS_EMITTER_H -#define CLANGSACHECKERS_EMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" - -namespace llvm { - -class ClangSACheckersEmitter : public TableGenBackend { -    RecordKeeper &Records; -public: -  explicit ClangSACheckersEmitter(RecordKeeper &R) : Records(R) {} - -  void run(raw_ostream &OS); -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp index e6f2e53aa706..68373063baae 100644 --- a/utils/TableGen/NeonEmitter.cpp +++ b/utils/TableGen/NeonEmitter.cpp @@ -23,16 +23,206 @@  //  //===----------------------------------------------------------------------===// -#include "NeonEmitter.h" -#include "llvm/TableGen/Error.h" +#include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/SmallString.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h"  #include "llvm/Support/ErrorHandling.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h"  #include <string> -  using namespace llvm; +enum OpKind { +  OpNone, +  OpUnavailable, +  OpAdd, +  OpAddl, +  OpAddw, +  OpSub, +  OpSubl, +  OpSubw, +  OpMul, +  OpMla, +  OpMlal, +  OpMls, +  OpMlsl, +  OpMulN, +  OpMlaN, +  OpMlsN, +  OpMlalN, +  OpMlslN, +  OpMulLane, +  OpMullLane, +  OpMlaLane, +  OpMlsLane, +  OpMlalLane, +  OpMlslLane, +  OpQDMullLane, +  OpQDMlalLane, +  OpQDMlslLane, +  OpQDMulhLane, +  OpQRDMulhLane, +  OpEq, +  OpGe, +  OpLe, +  OpGt, +  OpLt, +  OpNeg, +  OpNot, +  OpAnd, +  OpOr, +  OpXor, +  OpAndNot, +  OpOrNot, +  OpCast, +  OpConcat, +  OpDup, +  OpDupLane, +  OpHi, +  OpLo, +  OpSelect, +  OpRev16, +  OpRev32, +  OpRev64, +  OpReinterpret, +  OpAbdl, +  OpAba, +  OpAbal +}; + +enum ClassKind { +  ClassNone, +  ClassI,           // generic integer instruction, e.g., "i8" suffix +  ClassS,           // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix +  ClassW,           // width-specific instruction, e.g., "8" suffix +  ClassB            // bitcast arguments with enum argument to specify type +}; + +/// NeonTypeFlags - Flags to identify the types for overloaded Neon +/// builtins.  These must be kept in sync with the flags in +/// include/clang/Basic/TargetBuiltins.h. +namespace { +class NeonTypeFlags { +  enum { +    EltTypeMask = 0xf, +    UnsignedFlag = 0x10, +    QuadFlag = 0x20 +  }; +  uint32_t Flags; + +public: +  enum EltType { +    Int8, +    Int16, +    Int32, +    Int64, +    Poly8, +    Poly16, +    Float16, +    Float32 +  }; + +  NeonTypeFlags(unsigned F) : Flags(F) {} +  NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) { +    if (IsUnsigned) +      Flags |= UnsignedFlag; +    if (IsQuad) +      Flags |= QuadFlag; +  } + +  uint32_t getFlags() const { return Flags; } +}; +} // end anonymous namespace + +namespace { +class NeonEmitter { +  RecordKeeper &Records; +  StringMap<OpKind> OpMap; +  DenseMap<Record*, ClassKind> ClassMap; + +public: +  NeonEmitter(RecordKeeper &R) : Records(R) { +    OpMap["OP_NONE"]  = OpNone; +    OpMap["OP_UNAVAILABLE"] = OpUnavailable; +    OpMap["OP_ADD"]   = OpAdd; +    OpMap["OP_ADDL"]  = OpAddl; +    OpMap["OP_ADDW"]  = OpAddw; +    OpMap["OP_SUB"]   = OpSub; +    OpMap["OP_SUBL"]  = OpSubl; +    OpMap["OP_SUBW"]  = OpSubw; +    OpMap["OP_MUL"]   = OpMul; +    OpMap["OP_MLA"]   = OpMla; +    OpMap["OP_MLAL"]  = OpMlal; +    OpMap["OP_MLS"]   = OpMls; +    OpMap["OP_MLSL"]  = OpMlsl; +    OpMap["OP_MUL_N"] = OpMulN; +    OpMap["OP_MLA_N"] = OpMlaN; +    OpMap["OP_MLS_N"] = OpMlsN; +    OpMap["OP_MLAL_N"] = OpMlalN; +    OpMap["OP_MLSL_N"] = OpMlslN; +    OpMap["OP_MUL_LN"]= OpMulLane; +    OpMap["OP_MULL_LN"] = OpMullLane; +    OpMap["OP_MLA_LN"]= OpMlaLane; +    OpMap["OP_MLS_LN"]= OpMlsLane; +    OpMap["OP_MLAL_LN"] = OpMlalLane; +    OpMap["OP_MLSL_LN"] = OpMlslLane; +    OpMap["OP_QDMULL_LN"] = OpQDMullLane; +    OpMap["OP_QDMLAL_LN"] = OpQDMlalLane; +    OpMap["OP_QDMLSL_LN"] = OpQDMlslLane; +    OpMap["OP_QDMULH_LN"] = OpQDMulhLane; +    OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane; +    OpMap["OP_EQ"]    = OpEq; +    OpMap["OP_GE"]    = OpGe; +    OpMap["OP_LE"]    = OpLe; +    OpMap["OP_GT"]    = OpGt; +    OpMap["OP_LT"]    = OpLt; +    OpMap["OP_NEG"]   = OpNeg; +    OpMap["OP_NOT"]   = OpNot; +    OpMap["OP_AND"]   = OpAnd; +    OpMap["OP_OR"]    = OpOr; +    OpMap["OP_XOR"]   = OpXor; +    OpMap["OP_ANDN"]  = OpAndNot; +    OpMap["OP_ORN"]   = OpOrNot; +    OpMap["OP_CAST"]  = OpCast; +    OpMap["OP_CONC"]  = OpConcat; +    OpMap["OP_HI"]    = OpHi; +    OpMap["OP_LO"]    = OpLo; +    OpMap["OP_DUP"]   = OpDup; +    OpMap["OP_DUP_LN"] = OpDupLane; +    OpMap["OP_SEL"]   = OpSelect; +    OpMap["OP_REV16"] = OpRev16; +    OpMap["OP_REV32"] = OpRev32; +    OpMap["OP_REV64"] = OpRev64; +    OpMap["OP_REINT"] = OpReinterpret; +    OpMap["OP_ABDL"]  = OpAbdl; +    OpMap["OP_ABA"]   = OpAba; +    OpMap["OP_ABAL"]  = OpAbal; + +    Record *SI = R.getClass("SInst"); +    Record *II = R.getClass("IInst"); +    Record *WI = R.getClass("WInst"); +    ClassMap[SI] = ClassS; +    ClassMap[II] = ClassI; +    ClassMap[WI] = ClassW; +  } + +  // run - Emit arm_neon.h.inc +  void run(raw_ostream &o); + +  // runHeader - Emit all the __builtin prototypes used in arm_neon.h +  void runHeader(raw_ostream &o); + +  // runTests - Emit tests for all the Neon intrinsics. +  void runTests(raw_ostream &o); + +private: +  void emitIntrinsic(raw_ostream &OS, Record *R); +}; +} // end anonymous namespace +  /// ParseTypes - break down a string such as "fQf" into a vector of StringRefs,  /// which each StringRef representing a single type declared in the string.  /// for "fQf" we would end up with 2 StringRefs, "f", and "Qf", representing @@ -1012,7 +1202,7 @@ static std::string GenIntrinsic(const std::string &name,                                  StringRef outTypeStr, StringRef inTypeStr,                                  OpKind kind, ClassKind classKind) {    assert(!proto.empty() && ""); -  bool define = UseMacro(proto); +  bool define = UseMacro(proto) && kind != OpUnavailable;    std::string s;    // static always inline + return type @@ -1040,9 +1230,11 @@ static std::string GenIntrinsic(const std::string &name,    if (define) {      s += " __extension__ ({ \\\n  ";      s += GenMacroLocals(proto, inTypeStr); -  } else { -    s += " { \\\n  "; -  } +  } else if (kind == OpUnavailable) { +    s += " __attribute__((unavailable));\n"; +    return s; +  } else +    s += " {\n  ";    if (kind != OpNone)      s += GenOpString(kind, proto, outTypeStr); @@ -1238,7 +1430,7 @@ static unsigned RangeFromType(const char mod, StringRef typestr) {  /// runHeader - Emit a file with sections defining:  /// 1. the NEON section of BuiltinsARM.def.  /// 2. the SemaChecking code for the type overload checking. -/// 3. the SemaChecking code for validation of intrinsic immedate arguments. +/// 3. the SemaChecking code for validation of intrinsic immediate arguments.  void NeonEmitter::runHeader(raw_ostream &OS) {    std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst"); @@ -1312,7 +1504,7 @@ void NeonEmitter::runHeader(raw_ostream &OS) {        throw TGError(R->getLoc(), "Builtin has no class kind");      int si = -1, qi = -1; -    unsigned mask = 0, qmask = 0; +    uint64_t mask = 0, qmask = 0;      for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {        // Generate the switch case(s) for this builtin for the type validation.        bool quad = false, poly = false, usgn = false; @@ -1320,10 +1512,10 @@ void NeonEmitter::runHeader(raw_ostream &OS) {        if (quad) {          qi = ti; -        qmask |= 1 << GetNeonEnum(Proto, TypeVec[ti]); +        qmask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);        } else {          si = ti; -        mask |= 1 << GetNeonEnum(Proto, TypeVec[ti]); +        mask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);        }      } @@ -1360,7 +1552,7 @@ void NeonEmitter::runHeader(raw_ostream &OS) {      if (mask) {        OS << "case ARM::BI__builtin_neon_"           << MangleName(name, TypeVec[si], ClassB) -         << ": mask = " << "0x" << utohexstr(mask); +         << ": mask = " << "0x" << utohexstr(mask) << "ULL";        if (PtrArgNum >= 0)          OS << "; PtrArgNum = " << PtrArgNum;        if (HasConstPtr) @@ -1370,7 +1562,7 @@ void NeonEmitter::runHeader(raw_ostream &OS) {      if (qmask) {        OS << "case ARM::BI__builtin_neon_"           << MangleName(name, TypeVec[qi], ClassB) -         << ": mask = " << "0x" << utohexstr(qmask); +         << ": mask = " << "0x" << utohexstr(qmask) << "ULL";        if (PtrArgNum >= 0)          OS << "; PtrArgNum = " << PtrArgNum;        if (HasConstPtr) @@ -1505,7 +1697,7 @@ static std::string GenTest(const std::string &name,      s.push_back(arg);      comma = ", ";    } -  s += ") { \\\n  "; +  s += ") {\n  ";    if (proto[0] != 'v')      s += "return "; @@ -1551,6 +1743,8 @@ void NeonEmitter::runTests(raw_ostream &OS) {      ParseTypes(R, Types, TypeVec);      OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()]; +    if (kind == OpUnavailable) +      continue;      for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {        if (kind == OpReinterpret) {          bool outQuad = false; @@ -1572,3 +1766,14 @@ void NeonEmitter::runTests(raw_ostream &OS) {    }  } +namespace clang { +void EmitNeon(RecordKeeper &Records, raw_ostream &OS) { +  NeonEmitter(Records).run(OS); +} +void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) { +  NeonEmitter(Records).runHeader(OS); +} +void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) { +  NeonEmitter(Records).runTests(OS); +} +} // End namespace clang diff --git a/utils/TableGen/NeonEmitter.h b/utils/TableGen/NeonEmitter.h deleted file mode 100644 index dec745111164..000000000000 --- a/utils/TableGen/NeonEmitter.h +++ /dev/null @@ -1,210 +0,0 @@ -//===- NeonEmitter.h - Generate arm_neon.h for use with clang ---*- C++ -*-===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tablegen backend is responsible for emitting arm_neon.h, which includes -// a declaration and definition of each function specified by the ARM NEON -// compiler interface.  See ARM document DUI0348B. -// -//===----------------------------------------------------------------------===// - -#ifndef NEON_EMITTER_H -#define NEON_EMITTER_H - -#include "llvm/TableGen/Record.h" -#include "llvm/TableGen/TableGenBackend.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringMap.h" - -enum OpKind { -  OpNone, -  OpAdd, -  OpAddl, -  OpAddw, -  OpSub, -  OpSubl, -  OpSubw, -  OpMul, -  OpMla, -  OpMlal, -  OpMls, -  OpMlsl, -  OpMulN, -  OpMlaN, -  OpMlsN, -  OpMlalN, -  OpMlslN, -  OpMulLane, -  OpMullLane, -  OpMlaLane, -  OpMlsLane, -  OpMlalLane, -  OpMlslLane, -  OpQDMullLane, -  OpQDMlalLane, -  OpQDMlslLane, -  OpQDMulhLane, -  OpQRDMulhLane, -  OpEq, -  OpGe, -  OpLe, -  OpGt, -  OpLt, -  OpNeg, -  OpNot, -  OpAnd, -  OpOr, -  OpXor, -  OpAndNot, -  OpOrNot, -  OpCast, -  OpConcat, -  OpDup, -  OpDupLane, -  OpHi, -  OpLo, -  OpSelect, -  OpRev16, -  OpRev32, -  OpRev64, -  OpReinterpret, -  OpAbdl, -  OpAba, -  OpAbal -}; - -enum ClassKind { -  ClassNone, -  ClassI,           // generic integer instruction, e.g., "i8" suffix -  ClassS,           // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix -  ClassW,           // width-specific instruction, e.g., "8" suffix -  ClassB            // bitcast arguments with enum argument to specify type -}; - -/// NeonTypeFlags - Flags to identify the types for overloaded Neon -/// builtins.  These must be kept in sync with the flags in -/// include/clang/Basic/TargetBuiltins.h. -class NeonTypeFlags { -  enum { -    EltTypeMask = 0xf, -    UnsignedFlag = 0x10, -    QuadFlag = 0x20 -  }; -  uint32_t Flags; - -public: -  enum EltType { -    Int8, -    Int16, -    Int32, -    Int64, -    Poly8, -    Poly16, -    Float16, -    Float32 -  }; - -  NeonTypeFlags(unsigned F) : Flags(F) {} -  NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) { -    if (IsUnsigned) -      Flags |= UnsignedFlag; -    if (IsQuad) -      Flags |= QuadFlag; -  } - -  uint32_t getFlags() const { return Flags; } -}; - -namespace llvm { - -  class NeonEmitter : public TableGenBackend { -    RecordKeeper &Records; -    StringMap<OpKind> OpMap; -    DenseMap<Record*, ClassKind> ClassMap; - -  public: -    NeonEmitter(RecordKeeper &R) : Records(R) { -      OpMap["OP_NONE"]  = OpNone; -      OpMap["OP_ADD"]   = OpAdd; -      OpMap["OP_ADDL"]  = OpAddl; -      OpMap["OP_ADDW"]  = OpAddw; -      OpMap["OP_SUB"]   = OpSub; -      OpMap["OP_SUBL"]  = OpSubl; -      OpMap["OP_SUBW"]  = OpSubw; -      OpMap["OP_MUL"]   = OpMul; -      OpMap["OP_MLA"]   = OpMla; -      OpMap["OP_MLAL"]  = OpMlal; -      OpMap["OP_MLS"]   = OpMls; -      OpMap["OP_MLSL"]  = OpMlsl; -      OpMap["OP_MUL_N"] = OpMulN; -      OpMap["OP_MLA_N"] = OpMlaN; -      OpMap["OP_MLS_N"] = OpMlsN; -      OpMap["OP_MLAL_N"] = OpMlalN; -      OpMap["OP_MLSL_N"] = OpMlslN; -      OpMap["OP_MUL_LN"]= OpMulLane; -      OpMap["OP_MULL_LN"] = OpMullLane; -      OpMap["OP_MLA_LN"]= OpMlaLane; -      OpMap["OP_MLS_LN"]= OpMlsLane; -      OpMap["OP_MLAL_LN"] = OpMlalLane; -      OpMap["OP_MLSL_LN"] = OpMlslLane; -      OpMap["OP_QDMULL_LN"] = OpQDMullLane; -      OpMap["OP_QDMLAL_LN"] = OpQDMlalLane; -      OpMap["OP_QDMLSL_LN"] = OpQDMlslLane; -      OpMap["OP_QDMULH_LN"] = OpQDMulhLane; -      OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane; -      OpMap["OP_EQ"]    = OpEq; -      OpMap["OP_GE"]    = OpGe; -      OpMap["OP_LE"]    = OpLe; -      OpMap["OP_GT"]    = OpGt; -      OpMap["OP_LT"]    = OpLt; -      OpMap["OP_NEG"]   = OpNeg; -      OpMap["OP_NOT"]   = OpNot; -      OpMap["OP_AND"]   = OpAnd; -      OpMap["OP_OR"]    = OpOr; -      OpMap["OP_XOR"]   = OpXor; -      OpMap["OP_ANDN"]  = OpAndNot; -      OpMap["OP_ORN"]   = OpOrNot; -      OpMap["OP_CAST"]  = OpCast; -      OpMap["OP_CONC"]  = OpConcat; -      OpMap["OP_HI"]    = OpHi; -      OpMap["OP_LO"]    = OpLo; -      OpMap["OP_DUP"]   = OpDup; -      OpMap["OP_DUP_LN"] = OpDupLane; -      OpMap["OP_SEL"]   = OpSelect; -      OpMap["OP_REV16"] = OpRev16; -      OpMap["OP_REV32"] = OpRev32; -      OpMap["OP_REV64"] = OpRev64; -      OpMap["OP_REINT"] = OpReinterpret; -      OpMap["OP_ABDL"]  = OpAbdl; -      OpMap["OP_ABA"]   = OpAba; -      OpMap["OP_ABAL"]  = OpAbal; - -      Record *SI = R.getClass("SInst"); -      Record *II = R.getClass("IInst"); -      Record *WI = R.getClass("WInst"); -      ClassMap[SI] = ClassS; -      ClassMap[II] = ClassI; -      ClassMap[WI] = ClassW; -    } - -    // run - Emit arm_neon.h.inc -    void run(raw_ostream &o); - -    // runHeader - Emit all the __builtin prototypes used in arm_neon.h -    void runHeader(raw_ostream &o); - -    // runTests - Emit tests for all the Neon intrinsics. -    void runTests(raw_ostream &o); - -  private: -    void emitIntrinsic(raw_ostream &OS, Record *R); -  }; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp index dea22d388612..b0431a9be16b 100644 --- a/utils/TableGen/OptParserEmitter.cpp +++ b/utils/TableGen/OptParserEmitter.cpp @@ -7,8 +7,8 @@  //  //===----------------------------------------------------------------------===// -#include "OptParserEmitter.h"  #include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h"  #include "llvm/ADT/STLExtras.h"  using namespace llvm; @@ -69,16 +69,20 @@ static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) {    return OS;  } -void OptParserEmitter::run(raw_ostream &OS) { +/// OptParserEmitter - This tablegen backend takes an input .td file +/// describing a list of options and emits a data structure for parsing and +/// working with those options when given an input command line. +namespace clang { +void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs) {    // Get the option groups and options.    const std::vector<Record*> &Groups =      Records.getAllDerivedDefinitions("OptionGroup");    std::vector<Record*> Opts = Records.getAllDerivedDefinitions("Option");    if (GenDefs) -    EmitSourceFileHeader("Option Parsing Definitions", OS); +    emitSourceFileHeader("Option Parsing Definitions", OS);    else -    EmitSourceFileHeader("Option Parsing Table", OS); +    emitSourceFileHeader("Option Parsing Table", OS);    array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords);    if (GenDefs) { @@ -192,3 +196,4 @@ void OptParserEmitter::run(raw_ostream &OS) {      }    }  } +} // end namespace clang diff --git a/utils/TableGen/OptParserEmitter.h b/utils/TableGen/OptParserEmitter.h deleted file mode 100644 index ca667caf439c..000000000000 --- a/utils/TableGen/OptParserEmitter.h +++ /dev/null @@ -1,34 +0,0 @@ -//===- OptParserEmitter.h - Table Driven Command Line Parsing ---*- C++ -*-===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef UTILS_TABLEGEN_OPTPARSEREMITTER_H -#define UTILS_TABLEGEN_OPTPARSEREMITTER_H - -#include "llvm/TableGen/TableGenBackend.h" - -namespace llvm { -  /// OptParserEmitter - This tablegen backend takes an input .td file -  /// describing a list of options and emits a data structure for parsing and -  /// working with those options when given an input command line. -  class OptParserEmitter : public TableGenBackend { -    RecordKeeper &Records; -    bool GenDefs; - -  public: -    OptParserEmitter(RecordKeeper &R, bool _GenDefs) -      : Records(R), GenDefs(_GenDefs) {} - -    /// run - Output the option parsing information. -    /// -    /// \param GenHeader - Generate the header describing the option IDs.x -    void run(raw_ostream &OS); -  }; -} - -#endif diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index 5ff88db30156..d3408ed20f4d 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -11,12 +11,7 @@  //  //===----------------------------------------------------------------------===// -#include "ClangASTNodesEmitter.h" -#include "ClangAttrEmitter.h" -#include "ClangDiagnosticsEmitter.h" -#include "ClangSACheckersEmitter.h" -#include "NeonEmitter.h" -#include "OptParserEmitter.h" +#include "TableGenBackends.h" // Declares all backends.  #include "llvm/Support/CommandLine.h"  #include "llvm/Support/PrettyStackTrace.h" @@ -27,6 +22,7 @@  #include "llvm/TableGen/TableGenAction.h"  using namespace llvm; +using namespace clang;  enum ActionType {    GenClangAttrClasses, @@ -42,6 +38,7 @@ enum ActionType {    GenClangDiagsDefs,    GenClangDiagGroups,    GenClangDiagsIndexName, +  GenClangCommentNodes,    GenClangDeclNodes,    GenClangStmtNodes,    GenClangSACheckers, @@ -90,6 +87,8 @@ namespace {                      clEnumValN(GenClangDiagsIndexName,                                 "gen-clang-diags-index-name",                                 "Generate Clang diagnostic name index"), +                    clEnumValN(GenClangCommentNodes, "gen-clang-comment-nodes", +                               "Generate Clang AST comment nodes"),                      clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes",                                 "Generate Clang AST declaration nodes"),                      clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes", @@ -114,68 +113,71 @@ public:    bool operator()(raw_ostream &OS, RecordKeeper &Records) {      switch (Action) {      case GenClangAttrClasses: -      ClangAttrClassEmitter(Records).run(OS); +      EmitClangAttrClass(Records, OS);        break;      case GenClangAttrImpl: -      ClangAttrImplEmitter(Records).run(OS); +      EmitClangAttrImpl(Records, OS);        break;      case GenClangAttrList: -      ClangAttrListEmitter(Records).run(OS); +      EmitClangAttrList(Records, OS);        break;      case GenClangAttrPCHRead: -      ClangAttrPCHReadEmitter(Records).run(OS); +      EmitClangAttrPCHRead(Records, OS);        break;      case GenClangAttrPCHWrite: -      ClangAttrPCHWriteEmitter(Records).run(OS); +      EmitClangAttrPCHWrite(Records, OS);        break;      case GenClangAttrSpellingList: -      ClangAttrSpellingListEmitter(Records).run(OS); +      EmitClangAttrSpellingList(Records, OS);        break;      case GenClangAttrLateParsedList: -      ClangAttrLateParsedListEmitter(Records).run(OS); +      EmitClangAttrLateParsedList(Records, OS);        break;      case GenClangAttrTemplateInstantiate: -      ClangAttrTemplateInstantiateEmitter(Records).run(OS); +      EmitClangAttrTemplateInstantiate(Records, OS);        break;      case GenClangAttrParsedAttrList: -      ClangAttrParsedAttrListEmitter(Records).run(OS); +      EmitClangAttrParsedAttrList(Records, OS);        break;      case GenClangAttrParsedAttrKinds: -      ClangAttrParsedAttrKindsEmitter(Records).run(OS); +      EmitClangAttrParsedAttrKinds(Records, OS);        break;      case GenClangDiagsDefs: -      ClangDiagsDefsEmitter(Records, ClangComponent).run(OS); +      EmitClangDiagsDefs(Records, OS, ClangComponent);        break;      case GenClangDiagGroups: -      ClangDiagGroupsEmitter(Records).run(OS); +      EmitClangDiagGroups(Records, OS);        break;      case GenClangDiagsIndexName: -      ClangDiagsIndexNameEmitter(Records).run(OS); +      EmitClangDiagsIndexName(Records, OS); +      break; +    case GenClangCommentNodes: +      EmitClangASTNodes(Records, OS, "Comment", "");        break;      case GenClangDeclNodes: -      ClangASTNodesEmitter(Records, "Decl", "Decl").run(OS); -      ClangDeclContextEmitter(Records).run(OS); +      EmitClangASTNodes(Records, OS, "Decl", "Decl"); +      EmitClangDeclContext(Records, OS);        break;      case GenClangStmtNodes: -      ClangASTNodesEmitter(Records, "Stmt", "").run(OS); +      EmitClangASTNodes(Records, OS, "Stmt", "");        break;      case GenClangSACheckers: -      ClangSACheckersEmitter(Records).run(OS); +      EmitClangSACheckers(Records, OS);        break;      case GenOptParserDefs: -      OptParserEmitter(Records, true).run(OS); +      EmitOptParser(Records, OS, true);        break;      case GenOptParserImpl: -      OptParserEmitter(Records, false).run(OS); +      EmitOptParser(Records, OS, false);        break;      case GenArmNeon: -      NeonEmitter(Records).run(OS); +      EmitNeon(Records, OS);        break;      case GenArmNeonSema: -      NeonEmitter(Records).runHeader(OS); +      EmitNeonSema(Records, OS);        break;      case GenArmNeonTest: -      NeonEmitter(Records).runTests(OS); +      EmitNeonTest(Records, OS);        break;      } diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h new file mode 100644 index 000000000000..779de7c734b0 --- /dev/null +++ b/utils/TableGen/TableGenBackends.h @@ -0,0 +1,56 @@ +//===- TableGenBackends.h - Declarations for Clang TableGen Backends ------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations for all of the Clang TableGen +// backends. A "TableGen backend" is just a function. See +// "$LLVM_ROOT/utils/TableGen/TableGenBackends.h" for more info. +// +//===----------------------------------------------------------------------===// + +#include <string> + +namespace llvm { +  class raw_ostream; +  class RecordKeeper; +} + +using llvm::raw_ostream; +using llvm::RecordKeeper; + +namespace clang { + +void EmitClangDeclContext(RecordKeeper &RK, raw_ostream &OS); +void EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS, +                       const std::string &N, const std::string &S); + +void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS); +void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS); +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 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 EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS, +                        const std::string &Component); +void EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS); +void EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS); + +void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS); + +void EmitNeon(RecordKeeper &Records, raw_ostream &OS); +void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS); +void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS); + +void EmitOptParser(RecordKeeper &Records, raw_ostream &OS, bool GenDefs); + +} // end namespace clang  | 
