Add the ability for properties to be conditional on other properties.
This will be required by TemplateName.
diff --git a/clang/utils/TableGen/ClangASTPropertiesEmitter.cpp b/clang/utils/TableGen/ClangASTPropertiesEmitter.cpp
index db756ce..8dc0e88 100644
--- a/clang/utils/TableGen/ClangASTPropertiesEmitter.cpp
+++ b/clang/utils/TableGen/ClangASTPropertiesEmitter.cpp
@@ -188,6 +188,10 @@
ignoredProperties.insert(list.begin(), list.end());
}
+ // TODO: we should sort the properties in various ways
+ // - put arrays at the end to enable abbreviations
+ // - put conditional properties after properties used in the condition
+
visitAllNodesWithInfo(derived, derivedInfo,
[&](HasProperties node, const NodeInfo &info) {
for (Property prop : info.Properties) {
@@ -244,11 +248,12 @@
void emitReadOfProperty(StringRef readerName, Property property);
void emitReadOfProperty(StringRef readerName, StringRef name,
- PropertyType type);
+ PropertyType type, StringRef condition = "");
void emitWriteOfProperty(StringRef writerName, Property property);
void emitWriteOfProperty(StringRef writerName, StringRef name,
- PropertyType type, StringRef readCode);
+ PropertyType type, StringRef readCode,
+ StringRef condition = "");
void emitBasicReaderWriterFile(const ReaderWriterInfo &info);
void emitDispatcherTemplate(const ReaderWriterInfo &info);
@@ -499,12 +504,14 @@
/// Emit code to read the given property in a node-reader method.
void ASTPropsEmitter::emitReadOfProperty(StringRef readerName,
Property property) {
- emitReadOfProperty(readerName, property.getName(), property.getType());
+ emitReadOfProperty(readerName, property.getName(), property.getType(),
+ property.getCondition());
}
void ASTPropsEmitter::emitReadOfProperty(StringRef readerName,
StringRef name,
- PropertyType type) {
+ PropertyType type,
+ StringRef condition) {
// Declare all the necessary buffers.
auto bufferTypes = type.getBufferElementTypes();
for (size_t i = 0, e = bufferTypes.size(); i != e; ++i) {
@@ -518,33 +525,65 @@
// get a pr-value back from read(), and we should be able to forward
// that in the creation rule.
Out << " ";
+ if (!condition.empty()) Out << "llvm::Optional<";
type.emitCXXValueTypeName(true, Out);
- Out << " " << name << " = " << readerName << ".find(\"" << name << "\")."
+ if (!condition.empty()) Out << ">";
+ Out << " " << name;
+
+ if (condition.empty()) {
+ Out << " = ";
+ } else {
+ Out << ";\n"
+ " if (" << condition << ") {\n"
+ " " << name << ".emplace(";
+ }
+
+ Out << readerName << ".find(\"" << name << "\")."
<< (type.isGenericSpecialization() ? "template " : "") << "read";
emitBasicReaderWriterMethodSuffix(Out, type, /*for read*/ true);
Out << "(";
for (size_t i = 0, e = bufferTypes.size(); i != e; ++i) {
Out << (i > 0 ? ", " : "") << name << "_buffer_" << i;
}
- Out << ");\n";
+ Out << ")";
+
+ if (condition.empty()) {
+ Out << ";\n";
+ } else {
+ Out << ");\n"
+ " }\n";
+ }
}
/// Emit code to write the given property in a node-writer method.
void ASTPropsEmitter::emitWriteOfProperty(StringRef writerName,
Property property) {
emitWriteOfProperty(writerName, property.getName(), property.getType(),
- property.getReadCode());
+ property.getReadCode(), property.getCondition());
}
void ASTPropsEmitter::emitWriteOfProperty(StringRef writerName,
StringRef name,
PropertyType type,
- StringRef readCode) {
+ StringRef readCode,
+ StringRef condition) {
+ if (!condition.empty()) {
+ Out << " if (" << condition << ") {\n";
+ }
+
// Focus down to the property:
- // W.find("prop").write##ValueType(value);
- Out << " " << writerName << ".find(\"" << name << "\").write";
+ // T prop = <READ>;
+ // W.find("prop").write##ValueType(prop);
+ Out << " ";
+ type.emitCXXValueTypeName(false, Out);
+ Out << " " << name << " = (" << readCode << ");\n"
+ " " << writerName << ".find(\"" << name << "\").write";
emitBasicReaderWriterMethodSuffix(Out, type, /*for read*/ false);
- Out << "(" << readCode << ");\n";
+ Out << "(" << name << ");\n";
+
+ if (!condition.empty()) {
+ Out << " }\n";
+ }
}
/// Emit an .inc file that defines the AbstractFooReader class
@@ -775,11 +814,10 @@
if (info.IsReader) {
emitReadOfProperty(subvar, kindProperty, kindType);
} else {
- // Read the kind into a local variable.
- Out << " ";
- kindType.emitCXXValueTypeName(/*for read*/ false, Out);
- Out << " " << kindProperty << " = " << kindRule.getReadCode() << ";\n";
- emitWriteOfProperty(subvar, kindProperty, kindType, kindProperty);
+ // Write the property. Note that this will implicitly read the
+ // kind into a local variable with the right name.
+ emitWriteOfProperty(subvar, kindProperty, kindType,
+ kindRule.getReadCode());
}
// Prepare a ReaderWriterInfo with a helper variable that will use