Consolidating several table-generated files containing parser-related string switches into a single file. This reduces build-related complexity by replacing four separate projects (and table-gen instantiations) with a single one.

No functional changes intended.

llvm-svn: 200424
This commit is contained in:
Aaron Ballman 2014-01-29 22:13:45 +00:00
parent 2c4e00ac1c
commit 35db2b3d4c
7 changed files with 148 additions and 200 deletions

View File

@ -1,19 +1,4 @@
clang_tablegen(AttrIdentifierArg.inc -gen-clang-attr-identifier-arg-list
clang_tablegen(AttrParserStringSwitches.inc -gen-clang-attr-parser-string-switches
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
TARGET ClangAttrIdentifierArg)
clang_tablegen(AttrTypeArg.inc -gen-clang-attr-type-arg-list
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
TARGET ClangAttrTypeArg)
clang_tablegen(AttrLateParsed.inc -gen-clang-attr-late-parsed-list
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
TARGET ClangAttrLateParsed)
clang_tablegen(AttrArgContext.inc -gen-clang-attr-arg-context-list
-I ${CMAKE_CURRENT_SOURCE_DIR}/../../
SOURCE ../Basic/Attr.td
TARGET ClangAttrArgContext)
TARGET ClangAttrParserStringSwitches)

View File

@ -1,31 +1,13 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
BUILT_SOURCES = AttrIdentifierArg.inc AttrLateParsed.inc AttrTypeArg.inc AttrArgContext.inc
BUILT_SOURCES = AttrParserStringSwitches.inc
TABLEGEN_INC_FILES_COMMON = 1
include $(CLANG_LEVEL)/Makefile
$(ObjDir)/AttrIdentifierArg.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
$(ObjDir)/AttrParserStringSwitches.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang attribute identifier argument table with tblgen"
$(Verb) $(ClangTableGen) -gen-clang-attr-identifier-arg-list -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
$(ObjDir)/AttrTypeArg.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang attribute type argument table with tblgen"
$(Verb) $(ClangTableGen) -gen-clang-attr-type-arg-list -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
$(ObjDir)/AttrLateParsed.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang attribute late-parsed table with tblgen"
$(Verb) $(ClangTableGen) -gen-clang-attr-late-parsed-list -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
$(ObjDir)/AttrArgContext.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang attribute argument context table with tblgen"
$(Verb) $(ClangTableGen) -gen-clang-attr-arg-context-list -o $(call SYSPATH, $@) \
$(Echo) "Building Clang parser-related attribute string switches"
$(Verb) $(ClangTableGen) -gen-clang-attr-parser-string-switches -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<

View File

@ -23,17 +23,14 @@ add_clang_library(clangParse
add_dependencies(clangParse
ClangAttrClasses
ClangAttrIdentifierArg
ClangAttrLateParsed
ClangAttrParserStringSwitches
ClangAttrList
ClangAttrParsedAttrList
ClangAttrTypeArg
ClangCommentNodes
ClangDeclNodes
ClangDiagnosticCommon
ClangDiagnosticParse
ClangStmtNodes
ClangAttrArgContext
)
target_link_libraries(clangParse

View File

@ -69,9 +69,11 @@ TypeResult Parser::ParseTypeName(SourceRange *Range,
/// isAttributeLateParsed - Return true if the attribute has arguments that
/// require late parsing.
static bool isAttributeLateParsed(const IdentifierInfo &II) {
#define CLANG_ATTR_LATE_PARSED_LIST
return llvm::StringSwitch<bool>(II.getName())
#include "clang/Parse/AttrLateParsed.inc"
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_LATE_PARSED_LIST
}
/// ParseGNUAttributes - Parse a non-empty attributes list.
@ -196,24 +198,30 @@ static StringRef normalizeAttrName(StringRef Name) {
/// \brief Determine whether the given attribute has an identifier argument.
static bool attributeHasIdentifierArg(const IdentifierInfo &II) {
#define CLANG_ATTR_IDENTIFIER_ARG_LIST
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrIdentifierArg.inc"
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
}
/// \brief Determine whether the given attribute parses a type argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
#define CLANG_ATTR_TYPE_ARG_LIST
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrTypeArg.inc"
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_TYPE_ARG_LIST
}
/// \brief Determine whether the given attribute requires parsing its arguments
/// in an unevaluated context or not.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II) {
#define CLANG_ATTR_ARG_CONTEXT_LIST
return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrArgContext.inc"
#include "clang/Parse/AttrParserStringSwitches.inc"
.Default(false);
#undef CLANG_ATTR_ARG_CONTEXT_LIST
}
IdentifierLoc *Parser::ParseIdentifierLoc() {

View File

@ -1243,6 +1243,119 @@ void WriteSemanticSpellingSwitch(const std::string &VarName,
OS << " }\n";
}
// Emits the LateParsed property for attributes.
static void emitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
OS << "#if defined(CLANG_ATTR_LATE_PARSED_LIST)\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<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
// FIXME: Handle non-GNU attributes
for (std::vector<FlattenedSpelling>::const_iterator
I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
if (I->variety() != "GNU")
continue;
OS << ".Case(\"" << I->name() << "\", " << LateParsed << ")\n";
}
}
}
OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
}
/// \brief Emits the first-argument-is-type property for attributes.
static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\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;
// Determine whether the first argument is a type.
std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
if (Args.empty())
continue;
if (Args[0]->getSuperClasses().back()->getName() != "TypeArgument")
continue;
// All these spellings take a single type argument.
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
std::set<std::string> Emitted;
for (std::vector<FlattenedSpelling>::const_iterator I = Spellings.begin(),
E = Spellings.end(); I != E; ++I) {
if (Emitted.insert(I->name()).second)
OS << ".Case(\"" << I->name() << "\", " << "true" << ")\n";
}
}
OS << "#endif // CLANG_ATTR_TYPE_ARG_LIST\n\n";
}
/// \brief Emits the parse-arguments-in-unevaluated-context property for
/// attributes.
static void emitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS) {
OS << "#if defined(CLANG_ATTR_ARG_CONTEXT_LIST)\n";
ParsedAttrMap Attrs = getParsedAttrList(Records);
for (ParsedAttrMap::const_iterator I = Attrs.begin(), E = Attrs.end();
I != E; ++I) {
const Record &Attr = *I->second;
if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated"))
continue;
// All these spellings take are parsed unevaluated.
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
std::set<std::string> Emitted;
for (std::vector<FlattenedSpelling>::const_iterator I = Spellings.begin(),
E = Spellings.end(); I != E; ++I) {
if (Emitted.insert(I->name()).second)
OS << ".Case(\"" << I->name() << "\", " << "true" << ")\n";
}
}
OS << "#endif // CLANG_ATTR_ARG_CONTEXT_LIST\n\n";
}
static bool isIdentifierArgument(Record *Arg) {
return !Arg->getSuperClasses().empty() &&
llvm::StringSwitch<bool>(Arg->getSuperClasses().back()->getName())
.Case("IdentifierArgument", true)
.Case("EnumArgument", true)
.Default(false);
}
// Emits the first-argument-is-identifier property for attributes.
static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
OS << "#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)\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;
// Determine whether the first argument is an identifier.
std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
if (Args.empty() || !isIdentifierArgument(Args[0]))
continue;
// All these spellings take an identifier argument.
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
std::set<std::string> Emitted;
for (std::vector<FlattenedSpelling>::const_iterator I = Spellings.begin(),
E = Spellings.end(); I != E; ++I) {
if (Emitted.insert(I->name()).second)
OS << ".Case(\"" << I->name() << "\", " << "true" << ")\n";
}
}
OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n";
}
namespace clang {
// Emits the class definitions for attributes.
@ -1441,97 +1554,6 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
OS << "#endif\n";
}
static bool isIdentifierArgument(Record *Arg) {
return !Arg->getSuperClasses().empty() &&
llvm::StringSwitch<bool>(Arg->getSuperClasses().back()->getName())
.Case("IdentifierArgument", true)
.Case("EnumArgument", true)
.Default(false);
}
/// \brief Emits the first-argument-is-type property for attributes.
void EmitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("llvm::StringSwitch code to match attributes with a "
"type argument", OS);
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
for (std::vector<Record *>::iterator I = Attrs.begin(), E = Attrs.end();
I != E; ++I) {
Record &Attr = **I;
// Determine whether the first argument is a type.
std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
if (Args.empty())
continue;
if (Args[0]->getSuperClasses().back()->getName() != "TypeArgument")
continue;
// All these spellings take a single type argument.
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
std::set<std::string> Emitted;
for (std::vector<FlattenedSpelling>::const_iterator I = Spellings.begin(),
E = Spellings.end(); I != E; ++I) {
if (Emitted.insert(I->name()).second)
OS << ".Case(\"" << I->name() << "\", " << "true" << ")\n";
}
}
}
/// \brief Emits the parse-arguments-in-unevaluated-context property for
/// attributes.
void EmitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("StringSwitch code to match attributes which require "
"an unevaluated context", OS);
ParsedAttrMap Attrs = getParsedAttrList(Records);
for (ParsedAttrMap::const_iterator I = Attrs.begin(), E = Attrs.end();
I != E; ++I) {
const Record &Attr = *I->second;
if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated"))
continue;
// All these spellings take are parsed unevaluated.
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
std::set<std::string> Emitted;
for (std::vector<FlattenedSpelling>::const_iterator I = Spellings.begin(),
E = Spellings.end(); I != E; ++I) {
if (Emitted.insert(I->name()).second)
OS << ".Case(\"" << I->name() << "\", " << "true" << ")\n";
}
}
}
// Emits the first-argument-is-identifier property for attributes.
void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("llvm::StringSwitch code to match attributes with "
"an identifier argument", OS);
std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
I != E; ++I) {
Record &Attr = **I;
// Determine whether the first argument is an identifier.
std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
if (Args.empty() || !isIdentifierArgument(Args[0]))
continue;
// All these spellings take an identifier argument.
std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
std::set<std::string> Emitted;
for (std::vector<FlattenedSpelling>::const_iterator I = Spellings.begin(),
E = Spellings.end(); I != E; ++I) {
if (Emitted.insert(I->name()).second)
OS << ".Case(\"" << I->name() << "\", " << "true" << ")\n";
}
}
}
// Emits the class method definitions for attributes.
void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Attribute classes' member function definitions", OS);
@ -1893,34 +1915,6 @@ void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
OS << "#endif // ATTR_VISITOR_DECLS_ONLY\n";
}
// Emits the LateParsed property for attributes.
void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("llvm::StringSwitch code to match late parsed "
"attributes", OS);
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<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
// FIXME: Handle non-GNU attributes
for (std::vector<FlattenedSpelling>::const_iterator
I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
if (I->variety() != "GNU")
continue;
OS << ".Case(\"" << I->name() << "\", " << LateParsed << ")\n";
}
}
}
}
// Emits code to instantiate dependent attributes on templates.
void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader("Template instantiation code for attributes", OS);
@ -2619,4 +2613,13 @@ void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
OS << " }\n";
}
void EmitClangAttrParserStringSwitches(RecordKeeper &Records,
raw_ostream &OS) {
emitSourceFileHeader("Parser-related llvm::StringSwitch cases", OS);
emitClangAttrArgContextList(Records, OS);
emitClangAttrIdentifierArgList(Records, OS);
emitClangAttrTypeArgList(Records, OS);
emitClangAttrLateParsedList(Records, OS);
}
} // end namespace clang

View File

@ -24,9 +24,7 @@ using namespace clang;
enum ActionType {
GenClangAttrClasses,
GenClangAttrIdentifierArgList,
GenClangAttrArgContextList,
GenClangAttrTypeArgList,
GenClangAttrParserStringSwitches,
GenClangAttrImpl,
GenClangAttrList,
GenClangAttrPCHRead,
@ -34,7 +32,6 @@ enum ActionType {
GenClangAttrSpellingList,
GenClangAttrSpellingListIndex,
GenClangAttrASTVisitor,
GenClangAttrLateParsedList,
GenClangAttrTemplateInstantiate,
GenClangAttrParsedAttrList,
GenClangAttrParsedAttrImpl,
@ -63,18 +60,9 @@ cl::opt<ActionType> Action(
cl::values(
clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
"Generate clang attribute clases"),
clEnumValN(GenClangAttrIdentifierArgList,
"gen-clang-attr-identifier-arg-list",
"Generate a list of attributes that take an "
"identifier as their first argument"),
clEnumValN(GenClangAttrArgContextList,
"gen-clang-attr-arg-context-list",
"Generate a list of attributes that parse their arguments "
"in an unevaluated context"),
clEnumValN(GenClangAttrTypeArgList,
"gen-clang-attr-type-arg-list",
"Generate a list of attributes that take a type as their "
"first argument"),
clEnumValN(GenClangAttrParserStringSwitches,
"gen-clang-attr-parser-string-switches",
"Generate all parser-related attribute string switches"),
clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl",
"Generate clang attribute implementations"),
clEnumValN(GenClangAttrList, "gen-clang-attr-list",
@ -91,9 +79,6 @@ cl::opt<ActionType> Action(
clEnumValN(GenClangAttrASTVisitor,
"gen-clang-attr-ast-visitor",
"Generate a recursive AST visitor for clang attributes"),
clEnumValN(GenClangAttrLateParsedList,
"gen-clang-attr-late-parsed-list",
"Generate a clang attribute LateParsed list"),
clEnumValN(GenClangAttrTemplateInstantiate,
"gen-clang-attr-template-instantiate",
"Generate a clang template instantiate code"),
@ -156,14 +141,8 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenClangAttrClasses:
EmitClangAttrClass(Records, OS);
break;
case GenClangAttrIdentifierArgList:
EmitClangAttrIdentifierArgList(Records, OS);
break;
case GenClangAttrArgContextList:
EmitClangAttrArgContextList(Records, OS);
break;
case GenClangAttrTypeArgList:
EmitClangAttrTypeArgList(Records, OS);
case GenClangAttrParserStringSwitches:
EmitClangAttrParserStringSwitches(Records, OS);
break;
case GenClangAttrImpl:
EmitClangAttrImpl(Records, OS);
@ -186,9 +165,6 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenClangAttrASTVisitor:
EmitClangAttrASTVisitor(Records, OS);
break;
case GenClangAttrLateParsedList:
EmitClangAttrLateParsedList(Records, OS);
break;
case GenClangAttrTemplateInstantiate:
EmitClangAttrTemplateInstantiate(Records, OS);
break;

View File

@ -29,10 +29,8 @@ void EmitClangDeclContext(RecordKeeper &RK, raw_ostream &OS);
void EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS,
const std::string &N, const std::string &S);
void EmitClangAttrParserStringSwitches(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS);
@ -40,7 +38,6 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS);
void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS);