diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2011-10-06 13:21:42 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2011-10-06 13:21:42 +0000 |
commit | 6d1409dcc517185dca5fe6aef8d0417615951cd3 (patch) | |
tree | e04461a3c034aca20b70bd6238def22d3313077c | |
parent | 4df1557f4073cd91893a186acfee96bee64b28cc (diff) | |
download | external_llvm-6d1409dcc517185dca5fe6aef8d0417615951cd3.zip external_llvm-6d1409dcc517185dca5fe6aef8d0417615951cd3.tar.gz external_llvm-6d1409dcc517185dca5fe6aef8d0417615951cd3.tar.bz2 |
Remove the Clang tblgen backends from LLVM.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141293 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | utils/TableGen/CMakeLists.txt | 6 | ||||
-rw-r--r-- | utils/TableGen/ClangASTNodesEmitter.cpp | 168 | ||||
-rw-r--r-- | utils/TableGen/ClangASTNodesEmitter.h | 84 | ||||
-rw-r--r-- | utils/TableGen/ClangAttrEmitter.cpp | 788 | ||||
-rw-r--r-- | utils/TableGen/ClangAttrEmitter.h | 114 | ||||
-rw-r--r-- | utils/TableGen/ClangDiagnosticsEmitter.cpp | 378 | ||||
-rw-r--r-- | utils/TableGen/ClangDiagnosticsEmitter.h | 54 | ||||
-rw-r--r-- | utils/TableGen/ClangSACheckersEmitter.cpp | 319 | ||||
-rw-r--r-- | utils/TableGen/ClangSACheckersEmitter.h | 31 | ||||
-rw-r--r-- | utils/TableGen/NeonEmitter.cpp | 1551 | ||||
-rw-r--r-- | utils/TableGen/NeonEmitter.h | 176 | ||||
-rw-r--r-- | utils/TableGen/OptParserEmitter.cpp | 194 | ||||
-rw-r--r-- | utils/TableGen/OptParserEmitter.h | 34 | ||||
-rw-r--r-- | utils/TableGen/TableGen.cpp | 122 |
14 files changed, 0 insertions, 4019 deletions
diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index a845ed2..02ebd67 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -7,10 +7,6 @@ add_tablegen(llvm-tblgen LLVM AsmWriterEmitter.cpp AsmWriterInst.cpp CallingConvEmitter.cpp - ClangASTNodesEmitter.cpp - ClangAttrEmitter.cpp - ClangDiagnosticsEmitter.cpp - ClangSACheckersEmitter.cpp CodeEmitterGen.cpp CodeGenDAGPatterns.cpp CodeGenInstruction.cpp @@ -28,8 +24,6 @@ add_tablegen(llvm-tblgen LLVM InstrEnumEmitter.cpp InstrInfoEmitter.cpp IntrinsicEmitter.cpp - NeonEmitter.cpp - OptParserEmitter.cpp PseudoLoweringEmitter.cpp RegisterInfoEmitter.cpp SetTheory.cpp diff --git a/utils/TableGen/ClangASTNodesEmitter.cpp b/utils/TableGen/ClangASTNodesEmitter.cpp deleted file mode 100644 index d9d5a3c..0000000 --- a/utils/TableGen/ClangASTNodesEmitter.cpp +++ /dev/null @@ -1,168 +0,0 @@ -//=== ClangASTNodesEmitter.cpp - 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 -// -//===----------------------------------------------------------------------===// - -#include "ClangASTNodesEmitter.h" -#include <set> -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Statement Node Tables (.inc file) generation. -//===----------------------------------------------------------------------===// - -// Returns the first and last non-abstract subrecords -// Called recursively to ensure that nodes remain contiguous -std::pair<Record *, Record *> ClangASTNodesEmitter::EmitNode( - const ChildMap &Tree, - raw_ostream &OS, - Record *Base) { - std::string BaseName = macroName(Base->getName()); - - ChildIterator i = Tree.lower_bound(Base), e = Tree.upper_bound(Base); - - Record *First = 0, *Last = 0; - // This might be the pseudo-node for Stmt; don't assume it has an Abstract - // bit - if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract")) - First = Last = Base; - - for (; i != e; ++i) { - Record *R = i->second; - bool Abstract = R->getValueAsBit("Abstract"); - std::string NodeName = macroName(R->getName()); - - OS << "#ifndef " << NodeName << "\n"; - OS << "# define " << NodeName << "(Type, Base) " - << BaseName << "(Type, Base)\n"; - OS << "#endif\n"; - - if (Abstract) - OS << "ABSTRACT_" << macroName(Root.getName()) << "(" << NodeName << "(" - << R->getName() << ", " << baseName(*Base) << "))\n"; - else - OS << NodeName << "(" << R->getName() << ", " - << baseName(*Base) << ")\n"; - - if (Tree.find(R) != Tree.end()) { - const std::pair<Record *, Record *> &Result - = EmitNode(Tree, OS, R); - if (!First && Result.first) - First = Result.first; - if (Result.second) - Last = Result.second; - } else { - if (!Abstract) { - Last = R; - - if (!First) - First = R; - } - } - - OS << "#undef " << NodeName << "\n\n"; - } - - if (First) { - assert (Last && "Got a first node but not a last node for a range!"); - if (Base == &Root) - OS << "LAST_" << macroName(Root.getName()) << "_RANGE("; - else - OS << macroName(Root.getName()) << "_RANGE("; - OS << Base->getName() << ", " << First->getName() << ", " - << Last->getName() << ")\n\n"; - } - - return std::make_pair(First, Last); -} - -void ClangASTNodesEmitter::run(raw_ostream &OS) { - // Write the preamble - OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n"; - OS << "# define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n"; - OS << "#endif\n"; - - OS << "#ifndef " << macroName(Root.getName()) << "_RANGE\n"; - OS << "# define " - << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef LAST_" << macroName(Root.getName()) << "_RANGE\n"; - OS << "# define LAST_" - << macroName(Root.getName()) << "_RANGE(Base, First, Last) " - << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n"; - OS << "#endif\n\n"; - - // Emit statements - const std::vector<Record*> Stmts - = Records.getAllDerivedDefinitions(Root.getName()); - - ChildMap Tree; - - for (unsigned i = 0, e = Stmts.size(); i != e; ++i) { - Record *R = Stmts[i]; - - if (R->getValue("Base")) - Tree.insert(std::make_pair(R->getValueAsDef("Base"), R)); - else - Tree.insert(std::make_pair(&Root, R)); - } - - EmitNode(Tree, OS, &Root); - - OS << "#undef " << macroName(Root.getName()) << "\n"; - OS << "#undef " << macroName(Root.getName()) << "_RANGE\n"; - OS << "#undef LAST_" << macroName(Root.getName()) << "_RANGE\n"; - OS << "#undef ABSTRACT_" << macroName(Root.getName()) << "\n"; -} - -void ClangDeclContextEmitter::run(raw_ostream &OS) { - // FIXME: Find a .td file format to allow for this to be represented better. - - OS << "#ifndef DECL_CONTEXT\n"; - OS << "# define DECL_CONTEXT(DECL)\n"; - OS << "#endif\n"; - - OS << "#ifndef DECL_CONTEXT_BASE\n"; - OS << "# define DECL_CONTEXT_BASE(DECL) DECL_CONTEXT(DECL)\n"; - OS << "#endif\n"; - - typedef std::set<Record*> RecordSet; - typedef std::vector<Record*> RecordVector; - - RecordVector DeclContextsVector - = Records.getAllDerivedDefinitions("DeclContext"); - RecordVector Decls = Records.getAllDerivedDefinitions("Decl"); - RecordSet DeclContexts (DeclContextsVector.begin(), DeclContextsVector.end()); - - for (RecordVector::iterator i = Decls.begin(), e = Decls.end(); i != e; ++i) { - Record *R = *i; - - if (R->getValue("Base")) { - Record *B = R->getValueAsDef("Base"); - if (DeclContexts.find(B) != DeclContexts.end()) { - OS << "DECL_CONTEXT_BASE(" << B->getName() << ")\n"; - DeclContexts.erase(B); - } - } - } - - // To keep identical order, RecordVector may be used - // instead of RecordSet. - for (RecordVector::iterator - i = DeclContextsVector.begin(), e = DeclContextsVector.end(); - i != e; ++i) - if (DeclContexts.find(*i) != DeclContexts.end()) - OS << "DECL_CONTEXT(" << (*i)->getName() << ")\n"; - - OS << "#undef DECL_CONTEXT\n"; - OS << "#undef DECL_CONTEXT_BASE\n"; -} diff --git a/utils/TableGen/ClangASTNodesEmitter.h b/utils/TableGen/ClangASTNodesEmitter.h deleted file mode 100644 index edd9316..0000000 --- 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 deleted file mode 100644 index 5f25b8f..0000000 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ /dev/null @@ -1,788 +0,0 @@ -//===- ClangAttrEmitter.cpp - 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 -// -//===----------------------------------------------------------------------===// - -#include "ClangAttrEmitter.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/TableGen/Record.h" -#include <algorithm> -#include <cctype> - -using namespace llvm; - -static const std::vector<StringRef> -getValueAsListOfStrings(Record &R, StringRef FieldName) { - ListInit *List = R.getValueAsListInit(FieldName); - assert (List && "Got a null ListInit"); - - std::vector<StringRef> Strings; - Strings.reserve(List->getSize()); - - for (ListInit::const_iterator i = List->begin(), e = List->end(); - i != e; - ++i) { - assert(*i && "Got a null element in a ListInit"); - if (StringInit *S = dynamic_cast<StringInit *>(*i)) - Strings.push_back(S->getValue()); - else if (CodeInit *C = dynamic_cast<CodeInit *>(*i)) - Strings.push_back(C->getValue()); - else - assert(false && "Got a non-string, non-code element in a ListInit"); - } - - return Strings; -} - -static std::string ReadPCHRecord(StringRef type) { - return StringSwitch<std::string>(type) - .EndsWith("Decl *", "GetLocalDeclAs<" - + std::string(type, 0, type.size()-1) + ">(F, Record[Idx++])") - .Case("QualType", "getLocalType(F, Record[Idx++])") - .Case("Expr *", "ReadSubExpr()") - .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)") - .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)") - .Default("Record[Idx++]"); -} - -// Assumes that the way to get the value is SA->getname() -static std::string WritePCHRecord(StringRef type, StringRef name) { - return StringSwitch<std::string>(type) - .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + - ", Record);\n") - .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n") - .Case("Expr *", "AddStmt(" + std::string(name) + ");\n") - .Case("IdentifierInfo *", - "AddIdentifierRef(" + std::string(name) + ", Record);\n") - .Case("SourceLocation", - "AddSourceLocation(" + std::string(name) + ", Record);\n") - .Default("Record.push_back(" + std::string(name) + ");\n"); -} - -namespace { - class Argument { - std::string lowerName, upperName; - StringRef attrName; - - public: - Argument(Record &Arg, StringRef Attr) - : lowerName(Arg.getValueAsString("Name")), upperName(lowerName), - attrName(Attr) { - if (!lowerName.empty()) { - lowerName[0] = std::tolower(lowerName[0]); - upperName[0] = std::toupper(upperName[0]); - } - } - virtual ~Argument() {} - - StringRef getLowerName() const { return lowerName; } - StringRef getUpperName() const { return upperName; } - StringRef getAttrName() const { return attrName; } - - // 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 {} - virtual void writeCloneArgs(raw_ostream &OS) const = 0; - virtual void writeCtorBody(raw_ostream &OS) const {} - virtual void writeCtorInitializers(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; - virtual void writePCHReadDecls(raw_ostream &OS) const = 0; - virtual void writePCHWrite(raw_ostream &OS) const = 0; - }; - - class SimpleArgument : public Argument { - std::string type; - - public: - SimpleArgument(Record &Arg, StringRef Attr, std::string T) - : Argument(Arg, Attr), type(T) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " " << type << " get" << getUpperName() << "() const {\n"; - OS << " return " << getLowerName() << ";\n"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "(" << getUpperName() << ")"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << type << " " << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - OS << type << " " << getLowerName() << ";"; - } - void writePCHReadDecls(raw_ostream &OS) const { - std::string read = ReadPCHRecord(type); - OS << " " << type << " " << getLowerName() << " = " << read << ";\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writePCHWrite(raw_ostream &OS) const { - OS << " " << WritePCHRecord(type, "SA->get" + - std::string(getUpperName()) + "()"); - } - }; - - class StringArgument : public Argument { - public: - StringArgument(Record &Arg, StringRef Attr) - : Argument(Arg, Attr) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " llvm::StringRef get" << getUpperName() << "() const {\n"; - OS << " return llvm::StringRef(" << getLowerName() << ", " - << getLowerName() << "Length);\n"; - OS << " }\n"; - OS << " unsigned get" << getUpperName() << "Length() const {\n"; - OS << " return " << getLowerName() << "Length;\n"; - OS << " }\n"; - OS << " void set" << getUpperName() - << "(ASTContext &C, llvm::StringRef S) {\n"; - OS << " " << getLowerName() << "Length = S.size();\n"; - OS << " this->" << getLowerName() << " = new (C, 1) char [" - << getLowerName() << "Length];\n"; - OS << " std::memcpy(this->" << getLowerName() << ", S.data(), " - << getLowerName() << "Length);\n"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << "get" << getUpperName() << "()"; - } - void writeCtorBody(raw_ostream &OS) const { - OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() - << ".data(), " << getLowerName() << "Length);"; - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "Length(" << getUpperName() << ".size())," - << getLowerName() << "(new (Ctx, 1) char[" << getLowerName() - << "Length])"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << "llvm::StringRef " << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - OS << "unsigned " << getLowerName() << "Length;\n"; - OS << "char *" << getLowerName() << ";"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " std::string " << getLowerName() - << "= ReadString(Record, Idx);\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writePCHWrite(raw_ostream &OS) const { - OS << " AddString(SA->get" << getUpperName() << "(), Record);\n"; - } - }; - - class AlignedArgument : public Argument { - public: - AlignedArgument(Record &Arg, StringRef Attr) - : Argument(Arg, Attr) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " bool is" << getUpperName() << "Dependent() const;\n"; - - OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n"; - - OS << " bool is" << getUpperName() << "Expr() const {\n"; - OS << " return is" << getLowerName() << "Expr;\n"; - OS << " }\n"; - - OS << " Expr *get" << getUpperName() << "Expr() const {\n"; - OS << " assert(is" << getLowerName() << "Expr);\n"; - OS << " return " << getLowerName() << "Expr;\n"; - OS << " }\n"; - - OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n"; - OS << " assert(!is" << getLowerName() << "Expr);\n"; - OS << " return " << getLowerName() << "Type;\n"; - OS << " }"; - } - void writeAccessorDefinitions(raw_ostream &OS) const { - OS << "bool " << getAttrName() << "Attr::is" << getUpperName() - << "Dependent() const {\n"; - OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " return " << getLowerName() << "Expr && (" << getLowerName() - << "Expr->isValueDependent() || " << getLowerName() - << "Expr->isTypeDependent());\n"; - OS << " else\n"; - OS << " return " << getLowerName() - << "Type->getType()->isDependentType();\n"; - OS << "}\n"; - - // FIXME: Do not do the calculation here - // FIXME: Handle types correctly - // A null pointer means maximum alignment - // FIXME: Load the platform-specific maximum alignment, rather than - // 16, the x86 max. - OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName() - << "(ASTContext &Ctx) const {\n"; - OS << " assert(!is" << getUpperName() << "Dependent());\n"; - OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " return (" << getLowerName() << "Expr ? " << getLowerName() - << "Expr->EvaluateAsInt(Ctx).getZExtValue() : 16)" - << "* Ctx.getCharWidth();\n"; - OS << " else\n"; - OS << " return 0; // FIXME\n"; - OS << "}\n"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << "is" << getLowerName() << "Expr, is" << getLowerName() - << "Expr ? static_cast<void*>(" << getLowerName() - << "Expr) : " << getLowerName() - << "Type"; - } - void writeCtorBody(raw_ostream &OS) const { - OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>(" - << getUpperName() << ");\n"; - OS << " else\n"; - OS << " " << getLowerName() - << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName() - << ");"; - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - OS << "bool is" << getLowerName() << "Expr;\n"; - OS << "union {\n"; - OS << "Expr *" << getLowerName() << "Expr;\n"; - OS << "TypeSourceInfo *" << getLowerName() << "Type;\n"; - OS << "};"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n"; - OS << " void *" << getLowerName() << "Ptr;\n"; - OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n"; - OS << " else\n"; - OS << " " << getLowerName() - << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n"; - } - void writePCHWrite(raw_ostream &OS) const { - OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n"; - OS << " if (SA->is" << getUpperName() << "Expr())\n"; - OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n"; - OS << " else\n"; - OS << " AddTypeSourceInfo(SA->get" << getUpperName() - << "Type(), Record);\n"; - } - }; - - class VariadicArgument : public Argument { - std::string type; - - public: - VariadicArgument(Record &Arg, StringRef Attr, std::string T) - : Argument(Arg, Attr), type(T) - {} - - std::string getType() const { return type; } - - void writeAccessors(raw_ostream &OS) const { - OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n"; - OS << " " << getLowerName() << "_iterator " << getLowerName() - << "_begin() const {\n"; - OS << " return " << getLowerName() << ";\n"; - OS << " }\n"; - OS << " " << getLowerName() << "_iterator " << getLowerName() - << "_end() const {\n"; - OS << " return " << getLowerName() << " + " << getLowerName() - << "Size;\n"; - OS << " }\n"; - OS << " unsigned " << getLowerName() << "_size() const {\n" - << " return " << getLowerName() << "Size;\n;"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << getLowerName() << ", " << getLowerName() << "Size"; - } - void writeCtorBody(raw_ostream &OS) const { - // FIXME: memcpy is not safe on non-trivial types. - OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() - << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n"; - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "Size(" << getUpperName() << "Size), " - << getLowerName() << "(new (Ctx, 16) " << getType() << "[" - << getLowerName() << "Size])"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << getType() << " *" << getUpperName() << ", unsigned " - << getUpperName() << "Size"; - } - void writeDeclarations(raw_ostream &OS) const { - OS << " unsigned " << getLowerName() << "Size;\n"; - OS << " " << getType() << " *" << getLowerName() << ";"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; - OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName() - << ";\n"; - OS << " " << getLowerName() << ".reserve(" << getLowerName() - << "Size);\n"; - OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; - - std::string read = ReadPCHRecord(type); - OS << " " << getLowerName() << ".push_back(" << read << ");\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName() << ".data(), " << getLowerName() << "Size"; - } - void writePCHWrite(raw_ostream &OS) const{ - OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; - OS << " for (" << getAttrName() << "Attr::" << getLowerName() - << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" - << getLowerName() << "_end(); i != e; ++i)\n"; - OS << " " << WritePCHRecord(type, "(*i)"); - } - }; - - class EnumArgument : public Argument { - std::string type; - std::vector<StringRef> values, enums; - public: - EnumArgument(Record &Arg, StringRef Attr) - : Argument(Arg, Attr), type(Arg.getValueAsString("Type")), - values(getValueAsListOfStrings(Arg, "Values")), - enums(getValueAsListOfStrings(Arg, "Enums")) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " " << type << " get" << getUpperName() << "() const {\n"; - OS << " return " << getLowerName() << ";\n"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "(" << getUpperName() << ")"; - } - void writeCtorParameters(raw_ostream &OS) const { - 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(); - // The last one needs to not have a comma. - --e; - - OS << "public:\n"; - OS << " enum " << type << " {\n"; - for (; i != e; ++i) - OS << " " << *i << ",\n"; - OS << " " << *e << "\n"; - OS << " };\n"; - OS << "private:\n"; - OS << " " << type << " " << getLowerName() << ";"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName() - << "(static_cast<" << getAttrName() << "Attr::" << type - << ">(Record[Idx++]));\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writePCHWrite(raw_ostream &OS) const { - OS << "Record.push_back(SA->get" << getUpperName() << "());\n"; - } - }; - - class VersionArgument : public Argument { - public: - VersionArgument(Record &Arg, StringRef Attr) - : Argument(Arg, Attr) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " VersionTuple get" << getUpperName() << "() const {\n"; - OS << " return " << getLowerName() << ";\n"; - OS << " }\n"; - OS << " void set" << getUpperName() - << "(ASTContext &C, VersionTuple V) {\n"; - OS << " " << getLowerName() << " = V;\n"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << "get" << getUpperName() << "()"; - } - void writeCtorBody(raw_ostream &OS) const { - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "(" << getUpperName() << ")"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << "VersionTuple " << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - OS << "VersionTuple " << getLowerName() << ";\n"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " VersionTuple " << getLowerName() - << "= ReadVersionTuple(Record, Idx);\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writePCHWrite(raw_ostream &OS) const { - OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n"; - } - }; -} - -static Argument *createArgument(Record &Arg, StringRef Attr, - Record *Search = 0) { - if (!Search) - Search = &Arg; - - Argument *Ptr = 0; - llvm::StringRef ArgName = Search->getName(); - - if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr); - else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr); - else if (ArgName == "ExprArgument") Ptr = new SimpleArgument(Arg, Attr, - "Expr *"); - else if (ArgName == "FunctionArgument") - Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *"); - else if (ArgName == "IdentifierArgument") - Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *"); - else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, - "bool"); - else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int"); - else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr); - else if (ArgName == "TypeArgument") - Ptr = new SimpleArgument(Arg, Attr, "QualType"); - else if (ArgName == "UnsignedArgument") - Ptr = new SimpleArgument(Arg, Attr, "unsigned"); - else if (ArgName == "SourceLocArgument") - Ptr = new SimpleArgument(Arg, Attr, "SourceLocation"); - else if (ArgName == "VariadicUnsignedArgument") - Ptr = new VariadicArgument(Arg, Attr, "unsigned"); - else if (ArgName == "VariadicExprArgument") - Ptr = new VariadicArgument(Arg, Attr, "Expr *"); - else if (ArgName == "VersionArgument") - Ptr = new VersionArgument(Arg, Attr); - - if (!Ptr) { - std::vector<Record*> Bases = Search->getSuperClasses(); - for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end(); - i != e; ++i) { - Ptr = createArgument(Arg, Attr, *i); - if (Ptr) - break; - } - } - return Ptr; -} - -void ClangAttrClassEmitter::run(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"; - - std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); - - for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); - i != e; ++i) { - Record &R = **i; - const std::string &SuperName = R.getSuperClasses().back()->getName(); - - OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; - - std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); - std::vector<Argument*> Args; - std::vector<Argument*>::iterator ai, ae; - Args.reserve(ArgRecords.size()); - - for (std::vector<Record*>::iterator ri = ArgRecords.begin(), - re = ArgRecords.end(); - ri != re; ++ri) { - Record &ArgRecord = **ri; - Argument *Arg = createArgument(ArgRecord, R.getName()); - assert(Arg); - Args.push_back(Arg); - - Arg->writeDeclarations(OS); - OS << "\n\n"; - } - - ae = Args.end(); - - OS << "\n public:\n"; - OS << " " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n"; - - for (ai = Args.begin(); ai != ae; ++ai) { - OS << " , "; - (*ai)->writeCtorParameters(OS); - OS << "\n"; - } - - OS << " )\n"; - OS << " : " << SuperName << "(attr::" << R.getName() << ", R)\n"; - - for (ai = Args.begin(); ai != ae; ++ai) { - OS << " , "; - (*ai)->writeCtorInitializers(OS); - OS << "\n"; - } - - OS << " {\n"; - - for (ai = Args.begin(); ai != ae; ++ai) { - (*ai)->writeCtorBody(OS); - OS << "\n"; - } - OS << " }\n\n"; - - OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; - - for (ai = Args.begin(); ai != ae; ++ai) { - (*ai)->writeAccessors(OS); - OS << "\n\n"; - } - - OS << R.getValueAsCode("AdditionalMembers"); - OS << "\n\n"; - - OS << " static bool classof(const Attr *A) { return A->getKind() == " - << "attr::" << R.getName() << "; }\n"; - OS << " static bool classof(const " << R.getName() - << "Attr *) { return true; }\n"; - OS << "};\n\n"; - } - - OS << "#endif\n"; -} - -void ClangAttrImplEmitter::run(raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - - std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; - std::vector<Argument*>::iterator ai, ae; - - for (; i != e; ++i) { - Record &R = **i; - std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args"); - std::vector<Argument*> Args; - for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) - Args.push_back(createArgument(**ri, R.getName())); - - for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) - (*ai)->writeAccessorDefinitions(OS); - - OS << R.getName() << "Attr *" << R.getName() - << "Attr::clone(ASTContext &C) const {\n"; - OS << " return new (C) " << R.getName() << "Attr(getLocation(), C"; - for (ai = Args.begin(); ai != ae; ++ai) { - OS << ", "; - (*ai)->writeCloneArgs(OS); - } - OS << ");\n}\n\n"; - } -} - -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) - OS << Class << "(" << (*i)->getName() << ")\n"; - - OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; - } -} - -void ClangAttrListEmitter::run(raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - - OS << "#ifndef LAST_ATTR\n"; - OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef INHERITABLE_ATTR\n"; - OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef LAST_INHERITABLE_ATTR\n"; - OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef INHERITABLE_PARAM_ATTR\n"; - OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n"; - OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)" - " INHERITABLE_PARAM_ATTR(NAME)\n"; - OS << "#endif\n\n"; - - Record *InhClass = Records.getClass("InheritableAttr"); - Record *InhParamClass = Records.getClass("InheritableParamAttr"); - std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), - NonInhAttrs, InhAttrs, InhParamAttrs; - for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(); - i != e; ++i) { - if ((*i)->isSubClassOf(InhParamClass)) - InhParamAttrs.push_back(*i); - else if ((*i)->isSubClassOf(InhClass)) - InhAttrs.push_back(*i); - else - NonInhAttrs.push_back(*i); - } - - EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); - EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); - EmitAttrList(OS, "ATTR", NonInhAttrs); - - OS << "#undef LAST_ATTR\n"; - OS << "#undef INHERITABLE_ATTR\n"; - OS << "#undef LAST_INHERITABLE_ATTR\n"; - OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; - OS << "#undef ATTR\n"; -} - -void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - - Record *InhClass = Records.getClass("InheritableAttr"); - std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), - ArgRecords; - std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; - std::vector<Argument*> Args; - std::vector<Argument*>::iterator ri, re; - - OS << " switch (Kind) {\n"; - OS << " default:\n"; - OS << " assert(0 && \"Unknown attribute!\");\n"; - OS << " break;\n"; - for (; i != e; ++i) { - Record &R = **i; - OS << " case attr::" << R.getName() << ": {\n"; - if (R.isSubClassOf(InhClass)) - OS << " bool isInherited = Record[Idx++];\n"; - ArgRecords = R.getValueAsListOfDefs("Args"); - Args.clear(); - for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { - Argument *A = createArgument(**ai, R.getName()); - Args.push_back(A); - A->writePCHReadDecls(OS); - } - OS << " New = new (Context) " << R.getName() << "Attr(Range, Context"; - for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) { - OS << ", "; - (*ri)->writePCHReadArgs(OS); - } - OS << ");\n"; - if (R.isSubClassOf(InhClass)) - OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n"; - OS << " break;\n"; - OS << " }\n"; - } - OS << " }\n"; -} - -void ClangAttrPCHWriteEmitter::run(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; - - OS << " switch (A->getKind()) {\n"; - OS << " default:\n"; - OS << " llvm_unreachable(\"Unknown attribute kind!\");\n"; - OS << " break;\n"; - for (; i != e; ++i) { - Record &R = **i; - OS << " case attr::" << R.getName() << ": {\n"; - Args = R.getValueAsListOfDefs("Args"); - if (R.isSubClassOf(InhClass) || !Args.empty()) - OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() - << "Attr>(A);\n"; - if (R.isSubClassOf(InhClass)) - OS << " Record.push_back(SA->isInherited());\n"; - for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) - createArgument(**ai, R.getName())->writePCHWrite(OS); - OS << " break;\n"; - OS << " }\n"; - } - OS << " }\n"; -} - -void ClangAttrSpellingListEmitter::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; - - std::vector<StringRef> Spellings = getValueAsListOfStrings(Attr, "Spellings"); - - for (std::vector<StringRef>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { - StringRef Spelling = *I; - OS << ".Case(\"" << Spelling << "\", true)\n"; - } - } - -} - -void ClangAttrLateParsedListEmitter::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 LateParsed = Attr.getValueAsBit("LateParsed"); - - if (LateParsed) { - std::vector<StringRef> Spellings = - getValueAsListOfStrings(Attr, "Spellings"); - - for (std::vector<StringRef>::const_iterator I = Spellings.begin(), - E = Spellings.end(); I != E; ++I) { - OS << ".Case(\"" << (*I) << "\", " << LateParsed << ")\n"; - } - } - } -} diff --git a/utils/TableGen/ClangAttrEmitter.h b/utils/TableGen/ClangAttrEmitter.h deleted file mode 100644 index 5acca56..0000000 --- a/utils/TableGen/ClangAttrEmitter.h +++ /dev/null @@ -1,114 +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); -}; - -} - -#endif diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp deleted file mode 100644 index da2fb70..0000000 --- a/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ /dev/null @@ -1,378 +0,0 @@ -//=- ClangDiagnosticsEmitter.cpp - 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. -// -//===----------------------------------------------------------------------===// - -#include "ClangDiagnosticsEmitter.h" -#include "llvm/TableGen/Record.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/VectorExtras.h" -#include <map> -#include <algorithm> -#include <functional> -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Diagnostic category computation code. -//===----------------------------------------------------------------------===// - -namespace { -class DiagGroupParentMap { - RecordKeeper &Records; - std::map<const Record*, std::vector<Record*> > Mapping; -public: - DiagGroupParentMap(RecordKeeper &records) : Records(records) { - std::vector<Record*> DiagGroups - = Records.getAllDerivedDefinitions("DiagGroup"); - for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { - std::vector<Record*> SubGroups = - DiagGroups[i]->getValueAsListOfDefs("SubGroups"); - for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) - Mapping[SubGroups[j]].push_back(DiagGroups[i]); - } - } - - const std::vector<Record*> &getParents(const Record *Group) { - return Mapping[Group]; - } -}; -} // end anonymous namespace. - - -static std::string -getCategoryFromDiagGroup(const Record *Group, - DiagGroupParentMap &DiagGroupParents) { - // If the DiagGroup has a category, return it. - std::string CatName = Group->getValueAsString("CategoryName"); - if (!CatName.empty()) return CatName; - - // The diag group may the subgroup of one or more other diagnostic groups, - // check these for a category as well. - const std::vector<Record*> &Parents = DiagGroupParents.getParents(Group); - for (unsigned i = 0, e = Parents.size(); i != e; ++i) { - CatName = getCategoryFromDiagGroup(Parents[i], DiagGroupParents); - if (!CatName.empty()) return CatName; - } - return ""; -} - -/// getDiagnosticCategory - Return the category that the specified diagnostic -/// lives in. -static std::string getDiagnosticCategory(const Record *R, - DiagGroupParentMap &DiagGroupParents) { - // If the diagnostic is in a group, and that group has a category, use it. - if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) { - // Check the diagnostic's diag group for a category. - std::string CatName = getCategoryFromDiagGroup(Group->getDef(), - DiagGroupParents); - if (!CatName.empty()) return CatName; - } - - // If the diagnostic itself has a category, get it. - return R->getValueAsString("CategoryName"); -} - -namespace { - class DiagCategoryIDMap { - RecordKeeper &Records; - StringMap<unsigned> CategoryIDs; - std::vector<std::string> CategoryStrings; - public: - DiagCategoryIDMap(RecordKeeper &records) : Records(records) { - DiagGroupParentMap ParentInfo(Records); - - // The zero'th category is "". - CategoryStrings.push_back(""); - CategoryIDs[""] = 0; - - std::vector<Record*> Diags = - Records.getAllDerivedDefinitions("Diagnostic"); - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - std::string Category = getDiagnosticCategory(Diags[i], ParentInfo); - if (Category.empty()) continue; // Skip diags with no category. - - unsigned &ID = CategoryIDs[Category]; - if (ID != 0) continue; // Already seen. - - ID = CategoryStrings.size(); - CategoryStrings.push_back(Category); - } - } - - unsigned getID(StringRef CategoryString) { - return CategoryIDs[CategoryString]; - } - - typedef std::vector<std::string>::iterator iterator; - iterator begin() { return CategoryStrings.begin(); } - iterator end() { return CategoryStrings.end(); } - }; -} // end anonymous namespace. - - -//===----------------------------------------------------------------------===// -// Warning Tables (.inc file) generation. -//===----------------------------------------------------------------------===// - -void ClangDiagsDefsEmitter::run(raw_ostream &OS) { - // Write the #if guard - if (!Component.empty()) { - std::string ComponentName = UppercaseString(Component); - OS << "#ifdef " << ComponentName << "START\n"; - OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName - << ",\n"; - OS << "#undef " << ComponentName << "START\n"; - OS << "#endif\n\n"; - } - - const std::vector<Record*> &Diags = - Records.getAllDerivedDefinitions("Diagnostic"); - - DiagCategoryIDMap CategoryIDs(Records); - DiagGroupParentMap DGParentMap(Records); - - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - const Record &R = *Diags[i]; - // Filter by component. - if (!Component.empty() && Component != R.getValueAsString("Component")) - continue; - - OS << "DIAG(" << R.getName() << ", "; - OS << R.getValueAsDef("Class")->getName(); - OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); - - // Description string. - OS << ", \""; - OS.write_escaped(R.getValueAsString("Text")) << '"'; - - // Warning associated with the diagnostic. - if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) { - OS << ", \""; - OS.write_escaped(DI->getDef()->getValueAsString("GroupName")) << '"'; - } else { - OS << ", \"\""; - } - - // SFINAE bit - if (R.getValueAsBit("SFINAE")) - OS << ", true"; - else - OS << ", false"; - - // Access control bit - if (R.getValueAsBit("AccessControl")) - OS << ", true"; - else - OS << ", false"; - - // FIXME: This condition is just to avoid temporary revlock, it can be - // removed. - if (R.getValue("WarningNoWerror")) { - // Default warning has no Werror bit. - if (R.getValueAsBit("WarningNoWerror")) - OS << ", true"; - else - OS << ", false"; - - // Default warning show in system header bit. - if (R.getValueAsBit("WarningShowInSystemHeader")) - OS << ", true"; - else - OS << ", false"; - } - - // Category number. - OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap)); - - // Brief - OS << ", \""; - OS.write_escaped(R.getValueAsString("Brief")) << '"'; - - // Explanation - OS << ", \""; - OS.write_escaped(R.getValueAsString("Explanation")) << '"'; - OS << ")\n"; - } -} - -//===----------------------------------------------------------------------===// -// Warning Group Tables generation -//===----------------------------------------------------------------------===// - -static std::string getDiagCategoryEnum(llvm::StringRef name) { - if (name.empty()) - return "DiagCat_None"; - llvm::SmallString<256> enumName = llvm::StringRef("DiagCat_"); - for (llvm::StringRef::iterator I = name.begin(), E = name.end(); I != E; ++I) - enumName += isalnum(*I) ? *I : '_'; - return enumName.str(); -} - -namespace { -struct GroupInfo { - std::vector<const Record*> DiagsInGroup; - std::vector<std::string> SubGroups; - unsigned IDNo; -}; -} // end anonymous namespace. - -void ClangDiagGroupsEmitter::run(raw_ostream &OS) { - // Compute a mapping from a DiagGroup to all of its parents. - DiagGroupParentMap DGParentMap(Records); - - // Invert the 1-[0/1] mapping of diags to group into a one to many mapping of - // groups to diags in the group. - std::map<std::string, GroupInfo> DiagsInGroup; - - std::vector<Record*> Diags = - Records.getAllDerivedDefinitions("Diagnostic"); - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - const Record *R = Diags[i]; - DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group")); - if (DI == 0) continue; - std::string GroupName = DI->getDef()->getValueAsString("GroupName"); - DiagsInGroup[GroupName].DiagsInGroup.push_back(R); - } - - // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty - // groups (these are warnings that GCC supports that clang never produces). - std::vector<Record*> DiagGroups - = Records.getAllDerivedDefinitions("DiagGroup"); - for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { - Record *Group = DiagGroups[i]; - GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; - - std::vector<Record*> SubGroups = Group->getValueAsListOfDefs("SubGroups"); - for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) - GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName")); - } - - // Assign unique ID numbers to the groups. - unsigned IDNo = 0; - for (std::map<std::string, GroupInfo>::iterator - I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo) - I->second.IDNo = IDNo; - - // Walk through the groups emitting an array for each diagnostic of the diags - // that are mapped to. - OS << "\n#ifdef GET_DIAG_ARRAYS\n"; - unsigned MaxLen = 0; - for (std::map<std::string, GroupInfo>::iterator - I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { - MaxLen = std::max(MaxLen, (unsigned)I->first.size()); - - std::vector<const Record*> &V = I->second.DiagsInGroup; - if (!V.empty()) { - OS << "static const short DiagArray" << I->second.IDNo << "[] = { "; - for (unsigned i = 0, e = V.size(); i != e; ++i) - OS << "diag::" << V[i]->getName() << ", "; - OS << "-1 };\n"; - } - - const std::vector<std::string> &SubGroups = I->second.SubGroups; - if (!SubGroups.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 = - DiagsInGroup.find(SubGroups[i]); - assert(RI != DiagsInGroup.end() && "Referenced without existing?"); - OS << RI->second.IDNo << ", "; - } - OS << "-1 };\n"; - } - } - OS << "#endif // GET_DIAG_ARRAYS\n\n"; - - // Emit the table now. - OS << "\n#ifdef GET_DIAG_TABLE\n"; - for (std::map<std::string, GroupInfo>::iterator - I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { - // Group option string. - OS << " { "; - OS << I->first.size() << ", "; - OS << "\""; - OS.write_escaped(I->first) << "\"," - << std::string(MaxLen-I->first.size()+1, ' '); - - // Diagnostics in the group. - if (I->second.DiagsInGroup.empty()) - OS << "0, "; - else - OS << "DiagArray" << I->second.IDNo << ", "; - - // Subgroups. - if (I->second.SubGroups.empty()) - OS << 0; - else - OS << "DiagSubGroup" << I->second.IDNo; - OS << " },\n"; - } - OS << "#endif // GET_DIAG_TABLE\n\n"; - - // Emit the category table next. - DiagCategoryIDMap CategoriesByID(Records); - OS << "\n#ifdef GET_CATEGORY_TABLE\n"; - for (DiagCategoryIDMap::iterator I = CategoriesByID.begin(), - E = CategoriesByID.end(); I != E; ++I) - OS << "CATEGORY(\"" << *I << "\", " << getDiagCategoryEnum(*I) << ")\n"; - OS << "#endif // GET_CATEGORY_TABLE\n\n"; -} - -//===----------------------------------------------------------------------===// -// Diagnostic name index generation -//===----------------------------------------------------------------------===// - -namespace { -struct RecordIndexElement -{ - RecordIndexElement() {} - explicit RecordIndexElement(Record const &R): - Name(R.getName()) {} - - std::string Name; -}; - -struct RecordIndexElementSorter : - public std::binary_function<RecordIndexElement, RecordIndexElement, bool> { - - bool operator()(RecordIndexElement const &Lhs, - RecordIndexElement const &Rhs) const { - return Lhs.Name < Rhs.Name; - } - -}; - -} // end anonymous namespace. - -void ClangDiagsIndexNameEmitter::run(raw_ostream &OS) { - const std::vector<Record*> &Diags = - Records.getAllDerivedDefinitions("Diagnostic"); - - std::vector<RecordIndexElement> Index; - Index.reserve(Diags.size()); - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - const Record &R = *(Diags[i]); - Index.push_back(RecordIndexElement(R)); - } - - std::sort(Index.begin(), Index.end(), RecordIndexElementSorter()); - - for (unsigned i = 0, e = Index.size(); i != e; ++i) { - const RecordIndexElement &R = Index[i]; - - OS << "DIAG_NAME_INDEX(" << R.Name << ")\n"; - } -} diff --git a/utils/TableGen/ClangDiagnosticsEmitter.h b/utils/TableGen/ClangDiagnosticsEmitter.h deleted file mode 100644 index 73d3c4d..0000000 --- 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 deleted file mode 100644 index 423b68a..0000000 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ /dev/null @@ -1,319 +0,0 @@ -//=- ClangSACheckersEmitter.cpp - 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. -// -//===----------------------------------------------------------------------===// - -#include "ClangSACheckersEmitter.h" -#include "llvm/TableGen/Record.h" -#include "llvm/ADT/DenseSet.h" -#include <map> -#include <string> -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Static Analyzer Checkers Tables generation -//===----------------------------------------------------------------------===// - -/// \brief True if it is specified hidden or a parent package is specified -/// as hidden, otherwise false. -static bool isHidden(const Record &R) { - if (R.getValueAsBit("Hidden")) - return true; - // Not declared as hidden, check the parent package if it is hidden. - if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("ParentPackage"))) - return isHidden(*DI->getDef()); - - return false; -} - -static bool isCheckerNamed(const Record *R) { - return !R->getValueAsString("CheckerName").empty(); -} - -static std::string getPackageFullName(const Record *R); - -static std::string getParentPackageFullName(const Record *R) { - std::string name; - if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("ParentPackage"))) - name = getPackageFullName(DI->getDef()); - return name; -} - -static std::string getPackageFullName(const Record *R) { - std::string name = getParentPackageFullName(R); - if (!name.empty()) name += "."; - return name + R->getValueAsString("PackageName"); -} - -static std::string getCheckerFullName(const Record *R) { - std::string name = getParentPackageFullName(R); - if (isCheckerNamed(R)) { - if (!name.empty()) name += "."; - name += R->getValueAsString("CheckerName"); - } - return name; -} - -static std::string getStringValue(const Record &R, StringRef field) { - if (StringInit * - SI = dynamic_cast<StringInit*>(R.getValueInit(field))) - return SI->getValue(); - return std::string(); -} - -namespace { -struct GroupInfo { - llvm::DenseSet<const Record*> Checkers; - llvm::DenseSet<const Record *> SubGroups; - bool Hidden; - unsigned Index; - - GroupInfo() : Hidden(false) { } -}; -} - -static void addPackageToCheckerGroup(const Record *package, const Record *group, - llvm::DenseMap<const Record *, GroupInfo *> &recordGroupMap) { - llvm::DenseSet<const Record *> &checkers = recordGroupMap[package]->Checkers; - for (llvm::DenseSet<const Record *>::iterator - I = checkers.begin(), E = checkers.end(); I != E; ++I) - recordGroupMap[group]->Checkers.insert(*I); - - llvm::DenseSet<const Record *> &subGroups = recordGroupMap[package]->SubGroups; - for (llvm::DenseSet<const Record *>::iterator - I = subGroups.begin(), E = subGroups.end(); I != E; ++I) - addPackageToCheckerGroup(*I, group, recordGroupMap); -} - -void ClangSACheckersEmitter::run(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) - checkerRecIndexMap[checkers[i]] = i; - - // Invert the mapping of checkers to package/group into a one to many - // mapping of packages/groups to checkers. - std::map<std::string, GroupInfo> groupInfoByName; - llvm::DenseMap<const Record *, GroupInfo *> recordGroupMap; - - std::vector<Record*> packages = Records.getAllDerivedDefinitions("Package"); - for (unsigned i = 0, e = packages.size(); i != e; ++i) { - Record *R = packages[i]; - std::string fullName = getPackageFullName(R); - if (!fullName.empty()) { - GroupInfo &info = groupInfoByName[fullName]; - info.Hidden = isHidden(*R); - recordGroupMap[R] = &info; - } - } - - std::vector<Record*> - checkerGroups = Records.getAllDerivedDefinitions("CheckerGroup"); - for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) { - Record *R = checkerGroups[i]; - std::string name = R->getValueAsString("GroupName"); - if (!name.empty()) { - GroupInfo &info = groupInfoByName[name]; - recordGroupMap[R] = &info; - } - } - - for (unsigned i = 0, e = checkers.size(); i != e; ++i) { - Record *R = checkers[i]; - Record *package = 0; - if (DefInit * - DI = dynamic_cast<DefInit*>(R->getValueInit("ParentPackage"))) - package = DI->getDef(); - if (!isCheckerNamed(R) && !package) - throw "Checker '" + R->getName() + "' is neither named, nor in a package!"; - - if (isCheckerNamed(R)) { - // Create a pseudo-group to hold this checker. - std::string fullName = getCheckerFullName(R); - GroupInfo &info = groupInfoByName[fullName]; - info.Hidden = R->getValueAsBit("Hidden"); - recordGroupMap[R] = &info; - info.Checkers.insert(R); - } else { - recordGroupMap[package]->Checkers.insert(R); - } - - Record *currR = isCheckerNamed(R) ? R : package; - // Insert the checker and its parent packages into the subgroups set of - // the corresponding parent package. - while (DefInit *DI - = dynamic_cast<DefInit*>(currR->getValueInit("ParentPackage"))) { - Record *parentPackage = DI->getDef(); - recordGroupMap[parentPackage]->SubGroups.insert(currR); - currR = parentPackage; - } - // Insert the checker into the set of its group. - if (DefInit *DI = dynamic_cast<DefInit*>(R->getValueInit("Group"))) - recordGroupMap[DI->getDef()]->Checkers.insert(R); - } - - // If a package is in group, add all its checkers and its sub-packages - // checkers into the group. - for (unsigned i = 0, e = packages.size(); i != e; ++i) - if (DefInit *DI = dynamic_cast<DefInit*>(packages[i]->getValueInit("Group"))) - addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap); - - typedef std::map<std::string, const Record *> SortedRecords; - typedef llvm::DenseMap<const Record *, unsigned> RecToSortIndex; - - SortedRecords sortedGroups; - RecToSortIndex groupToSortIndex; - OS << "\n#ifdef GET_GROUPS\n"; - { - for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) - sortedGroups[checkerGroups[i]->getValueAsString("GroupName")] - = checkerGroups[i]; - - unsigned sortIndex = 0; - for (SortedRecords::iterator - I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) { - const Record *R = I->second; - - OS << "GROUP(" << "\""; - OS.write_escaped(R->getValueAsString("GroupName")) << "\""; - OS << ")\n"; - - groupToSortIndex[R] = sortIndex++; - } - } - OS << "#endif // GET_GROUPS\n\n"; - - OS << "\n#ifdef GET_PACKAGES\n"; - { - SortedRecords sortedPackages; - for (unsigned i = 0, e = packages.size(); i != e; ++i) - sortedPackages[getPackageFullName(packages[i])] = packages[i]; - - for (SortedRecords::iterator - I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) { - const Record &R = *I->second; - - OS << "PACKAGE(" << "\""; - OS.write_escaped(getPackageFullName(&R)) << "\", "; - // Group index - if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) - OS << groupToSortIndex[DI->getDef()] << ", "; - else - OS << "-1, "; - // Hidden bit - if (isHidden(R)) - OS << "true"; - else - OS << "false"; - OS << ")\n"; - } - } - OS << "#endif // GET_PACKAGES\n\n"; - - OS << "\n#ifdef GET_CHECKERS\n"; - for (unsigned i = 0, e = checkers.size(); i != e; ++i) { - const Record &R = *checkers[i]; - - OS << "CHECKER(" << "\""; - std::string name; - if (isCheckerNamed(&R)) - name = getCheckerFullName(&R); - OS.write_escaped(name) << "\", "; - OS << R.getName() << ", "; - OS << getStringValue(R, "DescFile") << ", "; - OS << "\""; - OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; - // Group index - if (DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) - OS << groupToSortIndex[DI->getDef()] << ", "; - else - OS << "-1, "; - // Hidden bit - if (isHidden(R)) - OS << "true"; - else - OS << "false"; - OS << ")\n"; - } - OS << "#endif // GET_CHECKERS\n\n"; - - unsigned index = 0; - for (std::map<std::string, GroupInfo>::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) - I->second.Index = index++; - - // Walk through the packages/groups/checkers emitting an array for each - // set of checkers and an array for each set of subpackages. - - OS << "\n#ifdef GET_MEMBER_ARRAYS\n"; - unsigned maxLen = 0; - for (std::map<std::string, GroupInfo>::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { - maxLen = std::max(maxLen, (unsigned)I->first.size()); - - llvm::DenseSet<const Record *> &checkers = I->second.Checkers; - if (!checkers.empty()) { - OS << "static const short CheckerArray" << I->second.Index << "[] = { "; - // Make the output order deterministic. - std::map<int, const Record *> sorted; - for (llvm::DenseSet<const Record *>::iterator - I = checkers.begin(), E = checkers.end(); I != E; ++I) - sorted[(*I)->getID()] = *I; - - for (std::map<int, const Record *>::iterator - I = sorted.begin(), E = sorted.end(); I != E; ++I) - OS << checkerRecIndexMap[I->second] << ", "; - OS << "-1 };\n"; - } - - llvm::DenseSet<const Record *> &subGroups = I->second.SubGroups; - if (!subGroups.empty()) { - OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; - // Make the output order deterministic. - std::map<int, const Record *> sorted; - for (llvm::DenseSet<const Record *>::iterator - I = subGroups.begin(), E = subGroups.end(); I != E; ++I) - sorted[(*I)->getID()] = *I; - - for (std::map<int, const Record *>::iterator - I = sorted.begin(), E = sorted.end(); I != E; ++I) { - OS << recordGroupMap[I->second]->Index << ", "; - } - OS << "-1 };\n"; - } - } - OS << "#endif // GET_MEMBER_ARRAYS\n\n"; - - OS << "\n#ifdef GET_CHECKNAME_TABLE\n"; - for (std::map<std::string, GroupInfo>::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { - // Group option string. - OS << " { \""; - OS.write_escaped(I->first) << "\"," - << std::string(maxLen-I->first.size()+1, ' '); - - if (I->second.Checkers.empty()) - OS << "0, "; - else - OS << "CheckerArray" << I->second.Index << ", "; - - // Subgroups. - if (I->second.SubGroups.empty()) - OS << "0, "; - else - OS << "SubPackageArray" << I->second.Index << ", "; - - OS << (I->second.Hidden ? "true" : "false"); - - OS << " },\n"; - } - OS << "#endif // GET_CHECKNAME_TABLE\n\n"; -} diff --git a/utils/TableGen/ClangSACheckersEmitter.h b/utils/TableGen/ClangSACheckersEmitter.h deleted file mode 100644 index 5a0e148..0000000 --- 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 deleted file mode 100644 index 0b5665f..0000000 --- a/utils/TableGen/NeonEmitter.cpp +++ /dev/null @@ -1,1551 +0,0 @@ -//===- NeonEmitter.cpp - 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. -// -// Each NEON instruction is implemented in terms of 1 or more functions which -// are suffixed with the element type of the input vectors. Functions may be -// implemented in terms of generic vector operations such as +, *, -, etc. or -// by calling a __builtin_-prefixed function which will be handled by clang's -// CodeGen library. -// -// Additional validation code can be generated by this file when runHeader() is -// called, rather than the normal run() entry point. A complete set of tests -// for Neon intrinsics can be generated by calling the runTests() entry point. -// -//===----------------------------------------------------------------------===// - -#include "NeonEmitter.h" -#include "llvm/TableGen/Error.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringExtras.h" -#include <string> - -using namespace llvm; - -/// 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 -/// 2xfloat and 4xfloat respectively. -static void ParseTypes(Record *r, std::string &s, - SmallVectorImpl<StringRef> &TV) { - const char *data = s.data(); - int len = 0; - - for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) { - if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U') - continue; - - switch (data[len]) { - case 'c': - case 's': - case 'i': - case 'l': - case 'h': - case 'f': - break; - default: - throw TGError(r->getLoc(), - "Unexpected letter: " + std::string(data + len, 1)); - break; - } - TV.push_back(StringRef(data, len + 1)); - data += len + 1; - len = -1; - } -} - -/// Widen - Convert a type code into the next wider type. char -> short, -/// short -> int, etc. -static char Widen(const char t) { - switch (t) { - case 'c': - return 's'; - case 's': - return 'i'; - case 'i': - return 'l'; - case 'h': - return 'f'; - default: throw "unhandled type in widen!"; - } - return '\0'; -} - -/// Narrow - Convert a type code into the next smaller type. short -> char, -/// float -> half float, etc. -static char Narrow(const char t) { - switch (t) { - case 's': - return 'c'; - case 'i': - return 's'; - case 'l': - return 'i'; - case 'f': - return 'h'; - default: throw "unhandled type in narrow!"; - } - return '\0'; -} - -/// For a particular StringRef, return the base type code, and whether it has -/// the quad-vector, polynomial, or unsigned modifiers set. -static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) { - unsigned off = 0; - - // remember quad. - if (ty[off] == 'Q') { - quad = true; - ++off; - } - - // remember poly. - if (ty[off] == 'P') { - poly = true; - ++off; - } - - // remember unsigned. - if (ty[off] == 'U') { - usgn = true; - ++off; - } - - // base type to get the type string for. - return ty[off]; -} - -/// ModType - Transform a type code and its modifiers based on a mod code. The -/// mod code definitions may be found at the top of arm_neon.td. -static char ModType(const char mod, char type, bool &quad, bool &poly, - bool &usgn, bool &scal, bool &cnst, bool &pntr) { - switch (mod) { - case 't': - if (poly) { - poly = false; - usgn = true; - } - break; - case 'u': - usgn = true; - poly = false; - if (type == 'f') - type = 'i'; - break; - case 'x': - usgn = false; - poly = false; - if (type == 'f') - type = 'i'; - break; - case 'f': - if (type == 'h') - quad = true; - type = 'f'; - usgn = false; - break; - case 'g': - quad = false; - break; - case 'w': - type = Widen(type); - quad = true; - break; - case 'n': - type = Widen(type); - break; - case 'i': - type = 'i'; - scal = true; - break; - case 'l': - type = 'l'; - scal = true; - usgn = true; - break; - case 's': - case 'a': - scal = true; - break; - case 'k': - quad = true; - break; - case 'c': - cnst = true; - case 'p': - pntr = true; - scal = true; - break; - case 'h': - type = Narrow(type); - if (type == 'h') - quad = false; - break; - case 'e': - type = Narrow(type); - usgn = true; - break; - default: - break; - } - return type; -} - -/// TypeString - for a modifier and type, generate the name of the typedef for -/// that type. QUc -> uint8x8_t. -static std::string TypeString(const char mod, StringRef typestr) { - bool quad = false; - bool poly = false; - bool usgn = false; - bool scal = false; - bool cnst = false; - bool pntr = false; - - if (mod == 'v') - return "void"; - if (mod == 'i') - return "int"; - - // base type to get the type string for. - char type = ClassifyType(typestr, quad, poly, usgn); - - // Based on the modifying character, change the type and width if necessary. - type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); - - SmallString<128> s; - - if (usgn) - s.push_back('u'); - - switch (type) { - case 'c': - s += poly ? "poly8" : "int8"; - if (scal) - break; - s += quad ? "x16" : "x8"; - break; - case 's': - s += poly ? "poly16" : "int16"; - if (scal) - break; - s += quad ? "x8" : "x4"; - break; - case 'i': - s += "int32"; - if (scal) - break; - s += quad ? "x4" : "x2"; - break; - case 'l': - s += "int64"; - if (scal) - break; - s += quad ? "x2" : "x1"; - break; - case 'h': - s += "float16"; - if (scal) - break; - s += quad ? "x8" : "x4"; - break; - case 'f': - s += "float32"; - if (scal) - break; - s += quad ? "x4" : "x2"; - break; - default: - throw "unhandled type!"; - break; - } - - if (mod == '2') - s += "x2"; - if (mod == '3') - s += "x3"; - if (mod == '4') - s += "x4"; - - // Append _t, finishing the type string typedef type. - s += "_t"; - - if (cnst) - s += " const"; - - if (pntr) - s += " *"; - - return s.str(); -} - -/// BuiltinTypeString - for a modifier and type, generate the clang -/// BuiltinsARM.def prototype code for the function. See the top of clang's -/// Builtins.def for a description of the type strings. -static std::string BuiltinTypeString(const char mod, StringRef typestr, - ClassKind ck, bool ret) { - bool quad = false; - bool poly = false; - bool usgn = false; - bool scal = false; - bool cnst = false; - bool pntr = false; - - if (mod == 'v') - return "v"; // void - if (mod == 'i') - return "i"; // int - - // base type to get the type string for. - char type = ClassifyType(typestr, quad, poly, usgn); - - // Based on the modifying character, change the type and width if necessary. - type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); - - // All pointers are void* pointers. Change type to 'v' now. - if (pntr) { - usgn = false; - poly = false; - type = 'v'; - } - // Treat half-float ('h') types as unsigned short ('s') types. - if (type == 'h') { - type = 's'; - usgn = true; - } - usgn = usgn | poly | ((ck == ClassI || ck == ClassW) && scal && type != 'f'); - - if (scal) { - SmallString<128> s; - - if (usgn) - s.push_back('U'); - else if (type == 'c') - s.push_back('S'); // make chars explicitly signed - - if (type == 'l') // 64-bit long - s += "LLi"; - else - s.push_back(type); - - if (cnst) - s.push_back('C'); - if (pntr) - s.push_back('*'); - return s.str(); - } - - // Since the return value must be one type, return a vector type of the - // appropriate width which we will bitcast. An exception is made for - // returning structs of 2, 3, or 4 vectors which are returned in a sret-like - // fashion, storing them to a pointer arg. - if (ret) { - if (mod >= '2' && mod <= '4') - return "vv*"; // void result with void* first argument - if (mod == 'f' || (ck != ClassB && type == 'f')) - return quad ? "V4f" : "V2f"; - if (ck != ClassB && type == 's') - return quad ? "V8s" : "V4s"; - if (ck != ClassB && type == 'i') - return quad ? "V4i" : "V2i"; - if (ck != ClassB && type == 'l') - return quad ? "V2LLi" : "V1LLi"; - - return quad ? "V16Sc" : "V8Sc"; - } - - // Non-return array types are passed as individual vectors. - if (mod == '2') - return quad ? "V16ScV16Sc" : "V8ScV8Sc"; - if (mod == '3') - return quad ? "V16ScV16ScV16Sc" : "V8ScV8ScV8Sc"; - if (mod == '4') - return quad ? "V16ScV16ScV16ScV16Sc" : "V8ScV8ScV8ScV8Sc"; - - if (mod == 'f' || (ck != ClassB && type == 'f')) - return quad ? "V4f" : "V2f"; - if (ck != ClassB && type == 's') - return quad ? "V8s" : "V4s"; - if (ck != ClassB && type == 'i') - return quad ? "V4i" : "V2i"; - if (ck != ClassB && type == 'l') - return quad ? "V2LLi" : "V1LLi"; - - return quad ? "V16Sc" : "V8Sc"; -} - -/// MangleName - Append a type or width suffix to a base neon function name, -/// and insert a 'q' in the appropriate location if the operation works on -/// 128b rather than 64b. E.g. turn "vst2_lane" into "vst2q_lane_f32", etc. -static std::string MangleName(const std::string &name, StringRef typestr, - ClassKind ck) { - if (name == "vcvt_f32_f16") - return name; - - bool quad = false; - bool poly = false; - bool usgn = false; - char type = ClassifyType(typestr, quad, poly, usgn); - - std::string s = name; - - switch (type) { - case 'c': - switch (ck) { - case ClassS: s += poly ? "_p8" : usgn ? "_u8" : "_s8"; break; - case ClassI: s += "_i8"; break; - case ClassW: s += "_8"; break; - default: break; - } - break; - case 's': - switch (ck) { - case ClassS: s += poly ? "_p16" : usgn ? "_u16" : "_s16"; break; - case ClassI: s += "_i16"; break; - case ClassW: s += "_16"; break; - default: break; - } - break; - case 'i': - switch (ck) { - case ClassS: s += usgn ? "_u32" : "_s32"; break; - case ClassI: s += "_i32"; break; - case ClassW: s += "_32"; break; - default: break; - } - break; - case 'l': - switch (ck) { - case ClassS: s += usgn ? "_u64" : "_s64"; break; - case ClassI: s += "_i64"; break; - case ClassW: s += "_64"; break; - default: break; - } - break; - case 'h': - switch (ck) { - case ClassS: - case ClassI: s += "_f16"; break; - case ClassW: s += "_16"; break; - default: break; - } - break; - case 'f': - switch (ck) { - case ClassS: - case ClassI: s += "_f32"; break; - case ClassW: s += "_32"; break; - default: break; - } - break; - default: - throw "unhandled type!"; - break; - } - if (ck == ClassB) - s += "_v"; - - // Insert a 'q' before the first '_' character so that it ends up before - // _lane or _n on vector-scalar operations. - if (quad) { - size_t pos = s.find('_'); - s = s.insert(pos, "q"); - } - return s; -} - -/// UseMacro - Examine the prototype string to determine if the intrinsic -/// should be defined as a preprocessor macro instead of an inline function. -static bool UseMacro(const std::string &proto) { - // If this builtin takes an immediate argument, we need to #define it rather - // than use a standard declaration, so that SemaChecking can range check - // the immediate passed by the user. - if (proto.find('i') != std::string::npos) - return true; - - // Pointer arguments need to use macros to avoid hiding aligned attributes - // from the pointer type. - if (proto.find('p') != std::string::npos || - proto.find('c') != std::string::npos) - return true; - - return false; -} - -/// MacroArgUsedDirectly - Return true if argument i for an intrinsic that is -/// defined as a macro should be accessed directly instead of being first -/// assigned to a local temporary. -static bool MacroArgUsedDirectly(const std::string &proto, unsigned i) { - // True for constant ints (i), pointers (p) and const pointers (c). - return (proto[i] == 'i' || proto[i] == 'p' || proto[i] == 'c'); -} - -// Generate the string "(argtype a, argtype b, ...)" -static std::string GenArgs(const std::string &proto, StringRef typestr) { - bool define = UseMacro(proto); - char arg = 'a'; - - std::string s; - s += "("; - - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - if (define) { - // Some macro arguments are used directly instead of being assigned - // to local temporaries; prepend an underscore prefix to make their - // names consistent with the local temporaries. - if (MacroArgUsedDirectly(proto, i)) - s += "__"; - } else { - s += TypeString(proto[i], typestr) + " __"; - } - s.push_back(arg); - if ((i + 1) < e) - s += ", "; - } - - s += ")"; - return s; -} - -// Macro arguments are not type-checked like inline function arguments, so -// assign them to local temporaries to get the right type checking. -static std::string GenMacroLocals(const std::string &proto, StringRef typestr) { - char arg = 'a'; - std::string s; - bool generatedLocal = false; - - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - // Do not create a temporary for an immediate argument. - // That would defeat the whole point of using a macro! - // FIXME: For other (non-immediate) arguments that are used directly, a - // local temporary (or some other method) is still needed to get the - // correct type checking, even if that temporary is not used for anything. - // This is omitted for now because it turns out the the use of - // "__extension__" in the macro disables any warnings from the pointer - // assignment. - if (MacroArgUsedDirectly(proto, i)) - continue; - generatedLocal = true; - - s += TypeString(proto[i], typestr) + " __"; - s.push_back(arg); - s += " = ("; - s.push_back(arg); - s += "); "; - } - - if (generatedLocal) - s += "\\\n "; - return s; -} - -// Use the vmovl builtin to sign-extend or zero-extend a vector. -static std::string Extend(StringRef typestr, const std::string &a) { - std::string s; - s = MangleName("vmovl", typestr, ClassS); - s += "(" + a + ")"; - return s; -} - -static std::string Duplicate(unsigned nElts, StringRef typestr, - const std::string &a) { - std::string s; - - s = "(" + TypeString('d', typestr) + "){ "; - for (unsigned i = 0; i != nElts; ++i) { - s += a; - if ((i + 1) < nElts) - s += ", "; - } - s += " }"; - - return s; -} - -static std::string SplatLane(unsigned nElts, const std::string &vec, - const std::string &lane) { - std::string s = "__builtin_shufflevector(" + vec + ", " + vec; - for (unsigned i = 0; i < nElts; ++i) - s += ", " + lane; - s += ")"; - return s; -} - -static unsigned GetNumElements(StringRef typestr, bool &quad) { - quad = false; - bool dummy = false; - char type = ClassifyType(typestr, quad, dummy, dummy); - unsigned nElts = 0; - switch (type) { - case 'c': nElts = 8; break; - case 's': nElts = 4; break; - case 'i': nElts = 2; break; - case 'l': nElts = 1; break; - case 'h': nElts = 4; break; - case 'f': nElts = 2; break; - default: - throw "unhandled type!"; - break; - } - if (quad) nElts <<= 1; - return nElts; -} - -// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd. -static std::string GenOpString(OpKind op, const std::string &proto, - StringRef typestr) { - bool quad; - unsigned nElts = GetNumElements(typestr, quad); - bool define = UseMacro(proto); - - std::string ts = TypeString(proto[0], typestr); - std::string s; - if (!define) { - s = "return "; - } - - switch(op) { - case OpAdd: - s += "__a + __b;"; - break; - case OpAddl: - s += Extend(typestr, "__a") + " + " + Extend(typestr, "__b") + ";"; - break; - case OpAddw: - s += "__a + " + Extend(typestr, "__b") + ";"; - break; - case OpSub: - s += "__a - __b;"; - break; - case OpSubl: - s += Extend(typestr, "__a") + " - " + Extend(typestr, "__b") + ";"; - break; - case OpSubw: - s += "__a - " + Extend(typestr, "__b") + ";"; - break; - case OpMulN: - s += "__a * " + Duplicate(nElts, typestr, "__b") + ";"; - break; - case OpMulLane: - s += "__a * " + SplatLane(nElts, "__b", "__c") + ";"; - break; - case OpMul: - s += "__a * __b;"; - break; - case OpMullLane: - s += MangleName("vmull", typestr, ClassS) + "(__a, " + - SplatLane(nElts, "__b", "__c") + ");"; - break; - case OpMlaN: - s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");"; - break; - case OpMlaLane: - s += "__a + (__b * " + SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpMla: - s += "__a + (__b * __c);"; - break; - case OpMlalN: - s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " + - Duplicate(nElts, typestr, "__c") + ");"; - break; - case OpMlalLane: - s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " + - SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpMlal: - s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, __c);"; - break; - case OpMlsN: - s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");"; - break; - case OpMlsLane: - s += "__a - (__b * " + SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpMls: - s += "__a - (__b * __c);"; - break; - case OpMlslN: - s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " + - Duplicate(nElts, typestr, "__c") + ");"; - break; - case OpMlslLane: - s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " + - SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpMlsl: - s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, __c);"; - break; - case OpQDMullLane: - s += MangleName("vqdmull", typestr, ClassS) + "(__a, " + - SplatLane(nElts, "__b", "__c") + ");"; - break; - case OpQDMlalLane: - s += MangleName("vqdmlal", typestr, ClassS) + "(__a, __b, " + - SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpQDMlslLane: - s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, __b, " + - SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpQDMulhLane: - s += MangleName("vqdmulh", typestr, ClassS) + "(__a, " + - SplatLane(nElts, "__b", "__c") + ");"; - break; - case OpQRDMulhLane: - s += MangleName("vqrdmulh", typestr, ClassS) + "(__a, " + - SplatLane(nElts, "__b", "__c") + ");"; - break; - case OpEq: - s += "(" + ts + ")(__a == __b);"; - break; - case OpGe: - s += "(" + ts + ")(__a >= __b);"; - break; - case OpLe: - s += "(" + ts + ")(__a <= __b);"; - break; - case OpGt: - s += "(" + ts + ")(__a > __b);"; - break; - case OpLt: - s += "(" + ts + ")(__a < __b);"; - break; - case OpNeg: - s += " -__a;"; - break; - case OpNot: - s += " ~__a;"; - break; - case OpAnd: - s += "__a & __b;"; - break; - case OpOr: - s += "__a | __b;"; - break; - case OpXor: - s += "__a ^ __b;"; - break; - case OpAndNot: - s += "__a & ~__b;"; - break; - case OpOrNot: - s += "__a | ~__b;"; - break; - case OpCast: - s += "(" + ts + ")__a;"; - break; - case OpConcat: - s += "(" + ts + ")__builtin_shufflevector((int64x1_t)__a"; - s += ", (int64x1_t)__b, 0, 1);"; - break; - case OpHi: - s += "(" + ts + - ")__builtin_shufflevector((int64x2_t)__a, (int64x2_t)__a, 1);"; - break; - case OpLo: - s += "(" + ts + - ")__builtin_shufflevector((int64x2_t)__a, (int64x2_t)__a, 0);"; - break; - case OpDup: - s += Duplicate(nElts, typestr, "__a") + ";"; - break; - case OpDupLane: - s += SplatLane(nElts, "__a", "__b") + ";"; - break; - case OpSelect: - // ((0 & 1) | (~0 & 2)) - s += "(" + ts + ")"; - ts = TypeString(proto[1], typestr); - s += "((__a & (" + ts + ")__b) | "; - s += "(~__a & (" + ts + ")__c));"; - break; - case OpRev16: - s += "__builtin_shufflevector(__a, __a"; - for (unsigned i = 2; i <= nElts; i += 2) - for (unsigned j = 0; j != 2; ++j) - s += ", " + utostr(i - j - 1); - s += ");"; - break; - case OpRev32: { - unsigned WordElts = nElts >> (1 + (int)quad); - s += "__builtin_shufflevector(__a, __a"; - for (unsigned i = WordElts; i <= nElts; i += WordElts) - for (unsigned j = 0; j != WordElts; ++j) - s += ", " + utostr(i - j - 1); - s += ");"; - break; - } - case OpRev64: { - unsigned DblWordElts = nElts >> (int)quad; - s += "__builtin_shufflevector(__a, __a"; - for (unsigned i = DblWordElts; i <= nElts; i += DblWordElts) - for (unsigned j = 0; j != DblWordElts; ++j) - s += ", " + utostr(i - j - 1); - s += ");"; - break; - } - case OpAbdl: { - std::string abd = MangleName("vabd", typestr, ClassS) + "(__a, __b)"; - if (typestr[0] != 'U') { - // vabd results are always unsigned and must be zero-extended. - std::string utype = "U" + typestr.str(); - s += "(" + TypeString(proto[0], typestr) + ")"; - abd = "(" + TypeString('d', utype) + ")" + abd; - s += Extend(utype, abd) + ";"; - } else { - s += Extend(typestr, abd) + ";"; - } - break; - } - case OpAba: - s += "__a + " + MangleName("vabd", typestr, ClassS) + "(__b, __c);"; - break; - case OpAbal: { - s += "__a + "; - std::string abd = MangleName("vabd", typestr, ClassS) + "(__b, __c)"; - if (typestr[0] != 'U') { - // vabd results are always unsigned and must be zero-extended. - std::string utype = "U" + typestr.str(); - s += "(" + TypeString(proto[0], typestr) + ")"; - abd = "(" + TypeString('d', utype) + ")" + abd; - s += Extend(utype, abd) + ";"; - } else { - s += Extend(typestr, abd) + ";"; - } - break; - } - default: - throw "unknown OpKind!"; - break; - } - return s; -} - -static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) { - unsigned mod = proto[0]; - unsigned ret = 0; - - if (mod == 'v' || mod == 'f') - mod = proto[1]; - - bool quad = false; - bool poly = false; - bool usgn = false; - bool scal = false; - bool cnst = false; - bool pntr = false; - - // Base type to get the type string for. - char type = ClassifyType(typestr, quad, poly, usgn); - - // Based on the modifying character, change the type and width if necessary. - type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); - - if (usgn) - ret |= 0x08; - if (quad && proto[1] != 'g') - ret |= 0x10; - - switch (type) { - case 'c': - ret |= poly ? 5 : 0; - break; - case 's': - ret |= poly ? 6 : 1; - break; - case 'i': - ret |= 2; - break; - case 'l': - ret |= 3; - break; - case 'h': - ret |= 7; - break; - case 'f': - ret |= 4; - break; - default: - throw "unhandled type!"; - break; - } - return ret; -} - -// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a) -static std::string GenBuiltin(const std::string &name, const std::string &proto, - StringRef typestr, ClassKind ck) { - std::string s; - - // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit - // sret-like argument. - bool sret = (proto[0] >= '2' && proto[0] <= '4'); - - bool define = UseMacro(proto); - - // Check if the prototype has a scalar operand with the type of the vector - // elements. If not, bitcasting the args will take care of arg checking. - // The actual signedness etc. will be taken care of with special enums. - if (proto.find('s') == std::string::npos) - ck = ClassB; - - if (proto[0] != 'v') { - std::string ts = TypeString(proto[0], typestr); - - if (define) { - if (sret) - s += ts + " r; "; - else - s += "(" + ts + ")"; - } else if (sret) { - s += ts + " r; "; - } else { - s += "return (" + ts + ")"; - } - } - - bool splat = proto.find('a') != std::string::npos; - - s += "__builtin_neon_"; - if (splat) { - // Call the non-splat builtin: chop off the "_n" suffix from the name. - std::string vname(name, 0, name.size()-2); - s += MangleName(vname, typestr, ck); - } else { - s += MangleName(name, typestr, ck); - } - s += "("; - - // Pass the address of the return variable as the first argument to sret-like - // builtins. - if (sret) - s += "&r, "; - - char arg = 'a'; - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - std::string args = std::string(&arg, 1); - - // Use the local temporaries instead of the macro arguments. - args = "__" + args; - - bool argQuad = false; - bool argPoly = false; - bool argUsgn = false; - bool argScalar = false; - bool dummy = false; - char argType = ClassifyType(typestr, argQuad, argPoly, argUsgn); - argType = ModType(proto[i], argType, argQuad, argPoly, argUsgn, argScalar, - dummy, dummy); - - // Handle multiple-vector values specially, emitting each subvector as an - // argument to the __builtin. - if (proto[i] >= '2' && proto[i] <= '4') { - // Check if an explicit cast is needed. - if (argType != 'c' || argPoly || argUsgn) - args = (argQuad ? "(int8x16_t)" : "(int8x8_t)") + args; - - for (unsigned vi = 0, ve = proto[i] - '0'; vi != ve; ++vi) { - s += args + ".val[" + utostr(vi) + "]"; - if ((vi + 1) < ve) - s += ", "; - } - if ((i + 1) < e) - s += ", "; - - continue; - } - - if (splat && (i + 1) == e) - args = Duplicate(GetNumElements(typestr, argQuad), typestr, args); - - // Check if an explicit cast is needed. - if ((splat || !argScalar) && - ((ck == ClassB && argType != 'c') || argPoly || argUsgn)) { - std::string argTypeStr = "c"; - if (ck != ClassB) - argTypeStr = argType; - if (argQuad) - argTypeStr = "Q" + argTypeStr; - args = "(" + TypeString('d', argTypeStr) + ")" + args; - } - - s += args; - if ((i + 1) < e) - s += ", "; - } - - // Extra constant integer to hold type class enum for this function, e.g. s8 - if (ck == ClassB) - s += ", " + utostr(GetNeonEnum(proto, typestr)); - - s += ");"; - - if (proto[0] != 'v' && sret) { - if (define) - s += " r;"; - else - s += " return r;"; - } - return s; -} - -static std::string GenBuiltinDef(const std::string &name, - const std::string &proto, - StringRef typestr, ClassKind ck) { - std::string s("BUILTIN(__builtin_neon_"); - - // If all types are the same size, bitcasting the args will take care - // of arg checking. The actual signedness etc. will be taken care of with - // special enums. - if (proto.find('s') == std::string::npos) - ck = ClassB; - - s += MangleName(name, typestr, ck); - s += ", \""; - - for (unsigned i = 0, e = proto.size(); i != e; ++i) - s += BuiltinTypeString(proto[i], typestr, ck, i == 0); - - // Extra constant integer to hold type class enum for this function, e.g. s8 - if (ck == ClassB) - s += "i"; - - s += "\", \"n\")"; - return s; -} - -static std::string GenIntrinsic(const std::string &name, - const std::string &proto, - StringRef outTypeStr, StringRef inTypeStr, - OpKind kind, ClassKind classKind) { - assert(!proto.empty() && ""); - bool define = UseMacro(proto); - std::string s; - - // static always inline + return type - if (define) - s += "#define "; - else - s += "__ai " + TypeString(proto[0], outTypeStr) + " "; - - // Function name with type suffix - std::string mangledName = MangleName(name, outTypeStr, ClassS); - if (outTypeStr != inTypeStr) { - // If the input type is different (e.g., for vreinterpret), append a suffix - // for the input type. String off a "Q" (quad) prefix so that MangleName - // does not insert another "q" in the name. - unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0); - StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff); - mangledName = MangleName(mangledName, inTypeNoQuad, ClassS); - } - s += mangledName; - - // Function arguments - s += GenArgs(proto, inTypeStr); - - // Definition. - if (define) { - s += " __extension__ ({ \\\n "; - s += GenMacroLocals(proto, inTypeStr); - } else { - s += " { \\\n "; - } - - if (kind != OpNone) - s += GenOpString(kind, proto, outTypeStr); - else - s += GenBuiltin(name, proto, outTypeStr, classKind); - if (define) - s += " })"; - else - s += " }"; - s += "\n"; - return s; -} - -/// run - Read the records in arm_neon.td and output arm_neon.h. arm_neon.h -/// is comprised of type definitions and function declarations. -void NeonEmitter::run(raw_ostream &OS) { - OS << - "/*===---- arm_neon.h - ARM Neon intrinsics ------------------------------" - "---===\n" - " *\n" - " * Permission is hereby granted, free of charge, to any person obtaining " - "a copy\n" - " * of this software and associated documentation files (the \"Software\")," - " to deal\n" - " * in the Software without restriction, including without limitation the " - "rights\n" - " * to use, copy, modify, merge, publish, distribute, sublicense, " - "and/or sell\n" - " * copies of the Software, and to permit persons to whom the Software is\n" - " * furnished to do so, subject to the following conditions:\n" - " *\n" - " * The above copyright notice and this permission notice shall be " - "included in\n" - " * all copies or substantial portions of the Software.\n" - " *\n" - " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, " - "EXPRESS OR\n" - " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF " - "MERCHANTABILITY,\n" - " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT " - "SHALL THE\n" - " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR " - "OTHER\n" - " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, " - "ARISING FROM,\n" - " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER " - "DEALINGS IN\n" - " * THE SOFTWARE.\n" - " *\n" - " *===--------------------------------------------------------------------" - "---===\n" - " */\n\n"; - - OS << "#ifndef __ARM_NEON_H\n"; - OS << "#define __ARM_NEON_H\n\n"; - - OS << "#ifndef __ARM_NEON__\n"; - OS << "#error \"NEON support not enabled\"\n"; - OS << "#endif\n\n"; - - OS << "#include <stdint.h>\n\n"; - - // Emit NEON-specific scalar typedefs. - OS << "typedef float float32_t;\n"; - OS << "typedef int8_t poly8_t;\n"; - OS << "typedef int16_t poly16_t;\n"; - OS << "typedef uint16_t float16_t;\n"; - - // Emit Neon vector typedefs. - std::string TypedefTypes("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfPcQPcPsQPs"); - SmallVector<StringRef, 24> TDTypeVec; - ParseTypes(0, TypedefTypes, TDTypeVec); - - // Emit vector typedefs. - for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) { - bool dummy, quad = false, poly = false; - (void) ClassifyType(TDTypeVec[i], quad, poly, dummy); - if (poly) - OS << "typedef __attribute__((neon_polyvector_type("; - else - OS << "typedef __attribute__((neon_vector_type("; - - unsigned nElts = GetNumElements(TDTypeVec[i], quad); - OS << utostr(nElts) << "))) "; - if (nElts < 10) - OS << " "; - - OS << TypeString('s', TDTypeVec[i]); - OS << " " << TypeString('d', TDTypeVec[i]) << ";\n"; - } - OS << "\n"; - - // Emit struct typedefs. - for (unsigned vi = 2; vi != 5; ++vi) { - for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) { - std::string ts = TypeString('d', TDTypeVec[i]); - std::string vs = TypeString('0' + vi, TDTypeVec[i]); - OS << "typedef struct " << vs << " {\n"; - OS << " " << ts << " val"; - OS << "[" << utostr(vi) << "]"; - OS << ";\n} "; - OS << vs << ";\n\n"; - } - } - - OS << "#define __ai static __attribute__((__always_inline__))\n\n"; - - std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst"); - - // Emit vmovl, vmull and vabd intrinsics first so they can be used by other - // intrinsics. (Some of the saturating multiply instructions are also - // used to implement the corresponding "_lane" variants, but tablegen - // sorts the records into alphabetical order so that the "_lane" variants - // come after the intrinsics they use.) - emitIntrinsic(OS, Records.getDef("VMOVL")); - emitIntrinsic(OS, Records.getDef("VMULL")); - emitIntrinsic(OS, Records.getDef("VABD")); - - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - if (R->getName() != "VMOVL" && - R->getName() != "VMULL" && - R->getName() != "VABD") - emitIntrinsic(OS, R); - } - - OS << "#undef __ai\n\n"; - OS << "#endif /* __ARM_NEON_H */\n"; -} - -/// emitIntrinsic - Write out the arm_neon.h header file definitions for the -/// intrinsics specified by record R. -void NeonEmitter::emitIntrinsic(raw_ostream &OS, Record *R) { - std::string name = R->getValueAsString("Name"); - std::string Proto = R->getValueAsString("Prototype"); - std::string Types = R->getValueAsString("Types"); - - SmallVector<StringRef, 16> TypeVec; - ParseTypes(R, Types, TypeVec); - - OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()]; - - ClassKind classKind = ClassNone; - if (R->getSuperClasses().size() >= 2) - classKind = ClassMap[R->getSuperClasses()[1]]; - if (classKind == ClassNone && kind == OpNone) - throw TGError(R->getLoc(), "Builtin has no class kind"); - - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - if (kind == OpReinterpret) { - bool outQuad = false; - bool dummy = false; - (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy); - for (unsigned srcti = 0, srcte = TypeVec.size(); - srcti != srcte; ++srcti) { - bool inQuad = false; - (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy); - if (srcti == ti || inQuad != outQuad) - continue; - OS << GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[srcti], - OpCast, ClassS); - } - } else { - OS << GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[ti], - kind, classKind); - } - } - OS << "\n"; -} - -static unsigned RangeFromType(const char mod, StringRef typestr) { - // base type to get the type string for. - bool quad = false, dummy = false; - char type = ClassifyType(typestr, quad, dummy, dummy); - type = ModType(mod, type, quad, dummy, dummy, dummy, dummy, dummy); - - switch (type) { - case 'c': - return (8 << (int)quad) - 1; - case 'h': - case 's': - return (4 << (int)quad) - 1; - case 'f': - case 'i': - return (2 << (int)quad) - 1; - case 'l': - return (1 << (int)quad) - 1; - default: - throw "unhandled type!"; - break; - } - assert(0 && "unreachable"); - return 0; -} - -/// 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. -void NeonEmitter::runHeader(raw_ostream &OS) { - std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst"); - - StringMap<OpKind> EmittedMap; - - // Generate BuiltinsARM.def for NEON - OS << "#ifdef GET_NEON_BUILTINS\n"; - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; - if (k != OpNone) - continue; - - std::string Proto = R->getValueAsString("Prototype"); - - // Functions with 'a' (the splat code) in the type prototype should not get - // their own builtin as they use the non-splat variant. - if (Proto.find('a') != std::string::npos) - continue; - - std::string Types = R->getValueAsString("Types"); - SmallVector<StringRef, 16> TypeVec; - ParseTypes(R, Types, TypeVec); - - if (R->getSuperClasses().size() < 2) - throw TGError(R->getLoc(), "Builtin has no class kind"); - - std::string name = R->getValueAsString("Name"); - ClassKind ck = ClassMap[R->getSuperClasses()[1]]; - - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - // Generate the BuiltinsARM.def declaration for this builtin, ensuring - // that each unique BUILTIN() macro appears only once in the output - // stream. - std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck); - if (EmittedMap.count(bd)) - continue; - - EmittedMap[bd] = OpNone; - OS << bd << "\n"; - } - } - OS << "#endif\n\n"; - - // Generate the overloaded type checking code for SemaChecking.cpp - OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n"; - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; - if (k != OpNone) - continue; - - std::string Proto = R->getValueAsString("Prototype"); - std::string Types = R->getValueAsString("Types"); - std::string name = R->getValueAsString("Name"); - - // Functions with 'a' (the splat code) in the type prototype should not get - // their own builtin as they use the non-splat variant. - if (Proto.find('a') != std::string::npos) - continue; - - // Functions which have a scalar argument cannot be overloaded, no need to - // check them if we are emitting the type checking code. - if (Proto.find('s') != std::string::npos) - continue; - - SmallVector<StringRef, 16> TypeVec; - ParseTypes(R, Types, TypeVec); - - if (R->getSuperClasses().size() < 2) - throw TGError(R->getLoc(), "Builtin has no class kind"); - - int si = -1, qi = -1; - unsigned 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; - (void) ClassifyType(TypeVec[ti], quad, poly, usgn); - - if (quad) { - qi = ti; - qmask |= 1 << GetNeonEnum(Proto, TypeVec[ti]); - } else { - si = ti; - mask |= 1 << GetNeonEnum(Proto, TypeVec[ti]); - } - } - if (mask) - OS << "case ARM::BI__builtin_neon_" - << MangleName(name, TypeVec[si], ClassB) - << ": mask = " << "0x" << utohexstr(mask) << "; break;\n"; - if (qmask) - OS << "case ARM::BI__builtin_neon_" - << MangleName(name, TypeVec[qi], ClassB) - << ": mask = " << "0x" << utohexstr(qmask) << "; break;\n"; - } - OS << "#endif\n\n"; - - // Generate the intrinsic range checking code for shift/lane immediates. - OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n"; - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - - OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; - if (k != OpNone) - continue; - - std::string name = R->getValueAsString("Name"); - std::string Proto = R->getValueAsString("Prototype"); - std::string Types = R->getValueAsString("Types"); - - // Functions with 'a' (the splat code) in the type prototype should not get - // their own builtin as they use the non-splat variant. - if (Proto.find('a') != std::string::npos) - continue; - - // Functions which do not have an immediate do not need to have range - // checking code emitted. - size_t immPos = Proto.find('i'); - if (immPos == std::string::npos) - continue; - - SmallVector<StringRef, 16> TypeVec; - ParseTypes(R, Types, TypeVec); - - if (R->getSuperClasses().size() < 2) - throw TGError(R->getLoc(), "Builtin has no class kind"); - - ClassKind ck = ClassMap[R->getSuperClasses()[1]]; - - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - std::string namestr, shiftstr, rangestr; - - if (R->getValueAsBit("isVCVT_N")) { - // VCVT between floating- and fixed-point values takes an immediate - // in the range 1 to 32. - ck = ClassB; - rangestr = "l = 1; u = 31"; // upper bound = l + u - } else if (Proto.find('s') == std::string::npos) { - // Builtins which are overloaded by type will need to have their upper - // bound computed at Sema time based on the type constant. - ck = ClassB; - if (R->getValueAsBit("isShift")) { - shiftstr = ", true"; - - // Right shifts have an 'r' in the name, left shifts do not. - if (name.find('r') != std::string::npos) - rangestr = "l = 1; "; - } - rangestr += "u = RFT(TV" + shiftstr + ")"; - } else { - // The immediate generally refers to a lane in the preceding argument. - assert(immPos > 0 && "unexpected immediate operand"); - rangestr = "u = " + utostr(RangeFromType(Proto[immPos-1], TypeVec[ti])); - } - // Make sure cases appear only once by uniquing them in a string map. - namestr = MangleName(name, TypeVec[ti], ck); - if (EmittedMap.count(namestr)) - continue; - EmittedMap[namestr] = OpNone; - - // Calculate the index of the immediate that should be range checked. - unsigned immidx = 0; - - // Builtins that return a struct of multiple vectors have an extra - // leading arg for the struct return. - if (Proto[0] >= '2' && Proto[0] <= '4') - ++immidx; - - // Add one to the index for each argument until we reach the immediate - // to be checked. Structs of vectors are passed as multiple arguments. - for (unsigned ii = 1, ie = Proto.size(); ii != ie; ++ii) { - switch (Proto[ii]) { - default: immidx += 1; break; - case '2': immidx += 2; break; - case '3': immidx += 3; break; - case '4': immidx += 4; break; - case 'i': ie = ii + 1; break; - } - } - OS << "case ARM::BI__builtin_neon_" << MangleName(name, TypeVec[ti], ck) - << ": i = " << immidx << "; " << rangestr << "; break;\n"; - } - } - OS << "#endif\n\n"; -} - -/// GenTest - Write out a test for the intrinsic specified by the name and -/// type strings, including the embedded patterns for FileCheck to match. -static std::string GenTest(const std::string &name, - const std::string &proto, - StringRef outTypeStr, StringRef inTypeStr, - bool isShift) { - assert(!proto.empty() && ""); - std::string s; - - // Function name with type suffix - std::string mangledName = MangleName(name, outTypeStr, ClassS); - if (outTypeStr != inTypeStr) { - // If the input type is different (e.g., for vreinterpret), append a suffix - // for the input type. String off a "Q" (quad) prefix so that MangleName - // does not insert another "q" in the name. - unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0); - StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff); - mangledName = MangleName(mangledName, inTypeNoQuad, ClassS); - } - - // Emit the FileCheck patterns. - s += "// CHECK: test_" + mangledName + "\n"; - // s += "// CHECK: \n"; // FIXME: + expected instruction opcode. - - // Emit the start of the test function. - s += TypeString(proto[0], outTypeStr) + " test_" + mangledName + "("; - char arg = 'a'; - std::string comma; - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - // Do not create arguments for values that must be immediate constants. - if (proto[i] == 'i') - continue; - s += comma + TypeString(proto[i], inTypeStr) + " "; - s.push_back(arg); - comma = ", "; - } - s += ") { \\\n "; - - if (proto[0] != 'v') - s += "return "; - s += mangledName + "("; - arg = 'a'; - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - if (proto[i] == 'i') { - // For immediate operands, test the maximum value. - if (isShift) - s += "1"; // FIXME - else - // The immediate generally refers to a lane in the preceding argument. - s += utostr(RangeFromType(proto[i-1], inTypeStr)); - } else { - s.push_back(arg); - } - if ((i + 1) < e) - s += ", "; - } - s += ");\n}\n\n"; - return s; -} - -/// runTests - Write out a complete set of tests for all of the Neon -/// intrinsics. -void NeonEmitter::runTests(raw_ostream &OS) { - OS << - "// RUN: %clang_cc1 -triple thumbv7-apple-darwin \\\n" - "// RUN: -target-cpu cortex-a9 -ffreestanding -S -o - %s | FileCheck %s\n" - "\n" - "#include <arm_neon.h>\n" - "\n"; - - std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst"); - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - std::string name = R->getValueAsString("Name"); - std::string Proto = R->getValueAsString("Prototype"); - std::string Types = R->getValueAsString("Types"); - bool isShift = R->getValueAsBit("isShift"); - - SmallVector<StringRef, 16> TypeVec; - ParseTypes(R, Types, TypeVec); - - OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()]; - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - if (kind == OpReinterpret) { - bool outQuad = false; - bool dummy = false; - (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy); - for (unsigned srcti = 0, srcte = TypeVec.size(); - srcti != srcte; ++srcti) { - bool inQuad = false; - (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy); - if (srcti == ti || inQuad != outQuad) - continue; - OS << GenTest(name, Proto, TypeVec[ti], TypeVec[srcti], isShift); - } - } else { - OS << GenTest(name, Proto, TypeVec[ti], TypeVec[ti], isShift); - } - } - OS << "\n"; - } -} - diff --git a/utils/TableGen/NeonEmitter.h b/utils/TableGen/NeonEmitter.h deleted file mode 100644 index 708ad3c..0000000 --- a/utils/TableGen/NeonEmitter.h +++ /dev/null @@ -1,176 +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 -}; - -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 deleted file mode 100644 index dea22d3..0000000 --- a/utils/TableGen/OptParserEmitter.cpp +++ /dev/null @@ -1,194 +0,0 @@ -//===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "OptParserEmitter.h" -#include "llvm/TableGen/Record.h" -#include "llvm/ADT/STLExtras.h" -using namespace llvm; - -static int StrCmpOptionName(const char *A, const char *B) { - char a = *A, b = *B; - while (a == b) { - if (a == '\0') - return 0; - - a = *++A; - b = *++B; - } - - if (a == '\0') // A is a prefix of B. - return 1; - if (b == '\0') // B is a prefix of A. - return -1; - - // Otherwise lexicographic. - return (a < b) ? -1 : 1; -} - -static int CompareOptionRecords(const void *Av, const void *Bv) { - const Record *A = *(Record**) Av; - const Record *B = *(Record**) Bv; - - // Sentinel options precede all others and are only ordered by precedence. - bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel"); - bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel"); - if (ASent != BSent) - return ASent ? -1 : 1; - - // Compare options by name, unless they are sentinels. - if (!ASent) - if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(), - B->getValueAsString("Name").c_str())) - return Cmp; - - // Then by the kind precedence; - int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence"); - int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence"); - assert(APrec != BPrec && "Options are equivalent!"); - return APrec < BPrec ? -1 : 1; -} - -static const std::string getOptionName(const Record &R) { - // Use the record name unless EnumName is defined. - if (dynamic_cast<UnsetInit*>(R.getValueInit("EnumName"))) - return R.getName(); - - return R.getValueAsString("EnumName"); -} - -static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) { - OS << '"'; - OS.write_escaped(Str); - OS << '"'; - return OS; -} - -void OptParserEmitter::run(raw_ostream &OS) { - // 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); - else - EmitSourceFileHeader("Option Parsing Table", OS); - - array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords); - if (GenDefs) { - OS << "#ifndef OPTION\n"; - OS << "#error \"Define OPTION prior to including this file!\"\n"; - OS << "#endif\n\n"; - - OS << "/////////\n"; - OS << "// Groups\n\n"; - for (unsigned i = 0, e = Groups.size(); i != e; ++i) { - const Record &R = *Groups[i]; - - // Start a single option entry. - OS << "OPTION("; - - // The option string. - OS << '"' << R.getValueAsString("Name") << '"'; - - // The option identifier name. - OS << ", "<< getOptionName(R); - - // The option kind. - OS << ", Group"; - - // The containing option group (if any). - OS << ", "; - if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) - OS << getOptionName(*DI->getDef()); - else - OS << "INVALID"; - - // The other option arguments (unused for groups). - OS << ", INVALID, 0, 0"; - - // The option help text. - if (!dynamic_cast<UnsetInit*>(R.getValueInit("HelpText"))) { - OS << ",\n"; - OS << " "; - write_cstring(OS, R.getValueAsString("HelpText")); - } else - OS << ", 0"; - - // The option meta-variable name (unused). - OS << ", 0)\n"; - } - OS << "\n"; - - OS << "//////////\n"; - OS << "// Options\n\n"; - for (unsigned i = 0, e = Opts.size(); i != e; ++i) { - const Record &R = *Opts[i]; - - // Start a single option entry. - OS << "OPTION("; - - // The option string. - write_cstring(OS, R.getValueAsString("Name")); - - // The option identifier name. - OS << ", "<< getOptionName(R); - - // The option kind. - OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name"); - - // The containing option group (if any). - OS << ", "; - if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Group"))) - OS << getOptionName(*DI->getDef()); - else - OS << "INVALID"; - - // The option alias (if any). - OS << ", "; - if (const DefInit *DI = dynamic_cast<DefInit*>(R.getValueInit("Alias"))) - OS << getOptionName(*DI->getDef()); - else - OS << "INVALID"; - - // The option flags. - const ListInit *LI = R.getValueAsListInit("Flags"); - if (LI->empty()) { - OS << ", 0"; - } else { - OS << ", "; - for (unsigned i = 0, e = LI->size(); i != e; ++i) { - if (i) - OS << " | "; - OS << dynamic_cast<DefInit*>(LI->getElement(i))->getDef()->getName(); - } - } - - // The option parameter field. - OS << ", " << R.getValueAsInt("NumArgs"); - - // The option help text. - if (!dynamic_cast<UnsetInit*>(R.getValueInit("HelpText"))) { - OS << ",\n"; - OS << " "; - write_cstring(OS, R.getValueAsString("HelpText")); - } else - OS << ", 0"; - - // The option meta-variable name. - OS << ", "; - if (!dynamic_cast<UnsetInit*>(R.getValueInit("MetaVarName"))) - write_cstring(OS, R.getValueAsString("MetaVarName")); - else - OS << "0"; - - OS << ")\n"; - } - } -} diff --git a/utils/TableGen/OptParserEmitter.h b/utils/TableGen/OptParserEmitter.h deleted file mode 100644 index ca667ca..0000000 --- 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 a1cb427..eacfdf6 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -14,10 +14,6 @@ #include "AsmMatcherEmitter.h" #include "AsmWriterEmitter.h" #include "CallingConvEmitter.h" -#include "ClangASTNodesEmitter.h" -#include "ClangAttrEmitter.h" -#include "ClangDiagnosticsEmitter.h" -#include "ClangSACheckersEmitter.h" #include "CodeEmitterGen.h" #include "DAGISelEmitter.h" #include "DisassemblerEmitter.h" @@ -25,8 +21,6 @@ #include "FastISelEmitter.h" #include "InstrInfoEmitter.h" #include "IntrinsicEmitter.h" -#include "NeonEmitter.h" -#include "OptParserEmitter.h" #include "PseudoLoweringEmitter.h" #include "RegisterInfoEmitter.h" #include "ARMDecoderEmitter.h" @@ -54,29 +48,12 @@ enum ActionType { GenDisassembler, GenPseudoLowering, GenCallingConv, - GenClangAttrClasses, - GenClangAttrImpl, - GenClangAttrList, - GenClangAttrPCHRead, - GenClangAttrPCHWrite, - GenClangAttrSpellingList, - GenClangAttrLateParsedList, - GenClangDiagsDefs, - GenClangDiagGroups, - GenClangDiagsIndexName, - GenClangDeclNodes, - GenClangStmtNodes, - GenClangSACheckers, GenDAGISel, GenFastISel, - GenOptParserDefs, GenOptParserImpl, GenSubtarget, GenIntrinsic, GenTgtIntrinsic, GenEDInfo, - GenArmNeon, - GenArmNeonSema, - GenArmNeonTest, PrintEnums, PrintSets }; @@ -108,53 +85,14 @@ namespace { "Generate a DAG instruction selector"), clEnumValN(GenFastISel, "gen-fast-isel", "Generate a \"fast\" instruction selector"), - clEnumValN(GenOptParserDefs, "gen-opt-parser-defs", - "Generate option definitions"), - clEnumValN(GenOptParserImpl, "gen-opt-parser-impl", - "Generate option parser implementation"), clEnumValN(GenSubtarget, "gen-subtarget", "Generate subtarget enumerations"), clEnumValN(GenIntrinsic, "gen-intrinsic", "Generate intrinsic information"), clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic", "Generate target intrinsic information"), - clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes", - "Generate clang attribute clases"), - clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl", - "Generate clang attribute implementations"), - clEnumValN(GenClangAttrList, "gen-clang-attr-list", - "Generate a clang attribute list"), - clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read", - "Generate clang PCH attribute reader"), - clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write", - "Generate clang PCH attribute writer"), - clEnumValN(GenClangAttrSpellingList, - "gen-clang-attr-spelling-list", - "Generate a clang attribute spelling list"), - clEnumValN(GenClangAttrLateParsedList, - "gen-clang-attr-late-parsed-list", - "Generate a clang attribute LateParsed list"), - clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", - "Generate Clang diagnostics definitions"), - clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", - "Generate Clang diagnostic groups"), - clEnumValN(GenClangDiagsIndexName, - "gen-clang-diags-index-name", - "Generate Clang diagnostic name index"), - clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes", - "Generate Clang AST declaration nodes"), - clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes", - "Generate Clang AST statement nodes"), - clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers", - "Generate Clang Static Analyzer checkers"), clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info", "Generate enhanced disassembly info"), - clEnumValN(GenArmNeon, "gen-arm-neon", - "Generate arm_neon.h for clang"), - clEnumValN(GenArmNeonSema, "gen-arm-neon-sema", - "Generate ARM NEON sema support for clang"), - clEnumValN(GenArmNeonTest, "gen-arm-neon-test", - "Generate ARM NEON tests for clang"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValN(PrintSets, "print-sets", @@ -164,11 +102,6 @@ namespace { cl::opt<std::string> Class("class", cl::desc("Print Enum list for this class"), cl::value_desc("class name")); - - cl::opt<std::string> - ClangComponent("clang-component", - cl::desc("Only use warnings from specified component"), - cl::value_desc("component"), cl::Hidden); } class LLVMTableGenAction : public TableGenAction { @@ -199,58 +132,12 @@ public: case GenAsmMatcher: AsmMatcherEmitter(Records).run(OS); break; - case GenClangAttrClasses: - ClangAttrClassEmitter(Records).run(OS); - break; - case GenClangAttrImpl: - ClangAttrImplEmitter(Records).run(OS); - break; - case GenClangAttrList: - ClangAttrListEmitter(Records).run(OS); - break; - case GenClangAttrPCHRead: - ClangAttrPCHReadEmitter(Records).run(OS); - break; - case GenClangAttrPCHWrite: - ClangAttrPCHWriteEmitter(Records).run(OS); - break; - case GenClangAttrSpellingList: - ClangAttrSpellingListEmitter(Records).run(OS); - break; - case GenClangAttrLateParsedList: - ClangAttrLateParsedListEmitter(Records).run(OS); - break; - case GenClangDiagsDefs: - ClangDiagsDefsEmitter(Records, ClangComponent).run(OS); - break; - case GenClangDiagGroups: - ClangDiagGroupsEmitter(Records).run(OS); - break; - case GenClangDiagsIndexName: - ClangDiagsIndexNameEmitter(Records).run(OS); - break; - case GenClangDeclNodes: - ClangASTNodesEmitter(Records, "Decl", "Decl").run(OS); - ClangDeclContextEmitter(Records).run(OS); - break; - case GenClangStmtNodes: - ClangASTNodesEmitter(Records, "Stmt", "").run(OS); - break; - case GenClangSACheckers: - ClangSACheckersEmitter(Records).run(OS); - break; case GenDisassembler: DisassemblerEmitter(Records).run(OS); break; case GenPseudoLowering: PseudoLoweringEmitter(Records).run(OS); break; - case GenOptParserDefs: - OptParserEmitter(Records, true).run(OS); - break; - case GenOptParserImpl: - OptParserEmitter(Records, false).run(OS); - break; case GenDAGISel: DAGISelEmitter(Records).run(OS); break; @@ -269,15 +156,6 @@ public: case GenEDInfo: EDEmitter(Records).run(OS); break; - case GenArmNeon: - NeonEmitter(Records).run(OS); - break; - case GenArmNeonSema: - NeonEmitter(Records).runHeader(OS); - break; - case GenArmNeonTest: - NeonEmitter(Records).runTests(OS); - break; case PrintEnums: { std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class); |