#define TypeClassName "Type"
static StringRef getIdForType(Record *type) {
- // The record name is expected to be the full C++ class name,
- // including "Type". Check for that and strip it off.
- auto fullName = type->getName();
- if (!fullName.endswith("Type"))
- PrintFatalError(type->getLoc(), "name of Type node doesn't end in Type");
- return fullName.drop_back(4);
+ // The record name is expected to be the full C++ class name,
+ // including "Type". Check for that and strip it off.
+ auto fullName = type->getName();
+ if (!fullName.endswith("Type"))
+ PrintFatalError(type->getLoc(), "name of Type node doesn't end in Type");
+ return fullName.drop_back(4);
}
namespace {
class TypeNodeEmitter {
- RecordKeeper &Records;
- raw_ostream &Out;
- const std::vector<Record*> Types;
- std::vector<StringRef> MacrosToUndef;
+ RecordKeeper &Records;
+ raw_ostream &Out;
+ const std::vector<Record*> Types;
+ std::vector<StringRef> MacrosToUndef;
public:
- TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)
- : Records(records), Out(out),
- Types(Records.getAllDerivedDefinitions(TypeNodeClassName)) {
- }
+ TypeNodeEmitter(RecordKeeper &records, raw_ostream &out)
+ : Records(records), Out(out),
+ Types(Records.getAllDerivedDefinitions(TypeNodeClassName)) {
+ }
- void emit();
+ void emit();
private:
- void emitFallbackDefine(StringRef macroName, StringRef fallbackMacroName,
- StringRef args);
+ void emitFallbackDefine(StringRef macroName, StringRef fallbackMacroName,
+ StringRef args);
- void emitNodeInvocations();
- void emitLastNodeInvocation();
- void emitLeafNodeInvocations();
+ void emitNodeInvocations();
+ void emitLastNodeInvocation();
+ void emitLeafNodeInvocations();
- void addMacroToUndef(StringRef macroName);
- void emitUndefs();
+ void addMacroToUndef(StringRef macroName);
+ void emitUndefs();
};
}
void TypeNodeEmitter::emit() {
- if (Types.empty())
- PrintFatalError("no Type records in input!");
-
- emitSourceFileHeader("An x-macro database of Clang type nodes", Out);
-
- // Preamble
- addMacroToUndef(TypeMacroName);
- addMacroToUndef(AbstractTypeMacroName);
- emitFallbackDefine(AbstractTypeMacroName, TypeMacroName, TypeMacroArgs);
- emitFallbackDefine(NonCanonicalTypeMacroName, TypeMacroName, TypeMacroArgs);
- emitFallbackDefine(DependentTypeMacroName, TypeMacroName, TypeMacroArgs);
- emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName,
- TypeMacroArgs);
-
- // Invocations.
- emitNodeInvocations();
- emitLastNodeInvocation();
- emitLeafNodeInvocations();
-
- // Postmatter
- emitUndefs();
+ if (Types.empty())
+ PrintFatalError("no Type records in input!");
+
+ emitSourceFileHeader("An x-macro database of Clang type nodes", Out);
+
+ // Preamble
+ addMacroToUndef(TypeMacroName);
+ addMacroToUndef(AbstractTypeMacroName);
+ emitFallbackDefine(AbstractTypeMacroName, TypeMacroName, TypeMacroArgs);
+ emitFallbackDefine(NonCanonicalTypeMacroName, TypeMacroName, TypeMacroArgs);
+ emitFallbackDefine(DependentTypeMacroName, TypeMacroName, TypeMacroArgs);
+ emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName,
+ TypeMacroArgs);
+
+ // Invocations.
+ emitNodeInvocations();
+ emitLastNodeInvocation();
+ emitLeafNodeInvocations();
+
+ // Postmatter
+ emitUndefs();
}
void TypeNodeEmitter::emitFallbackDefine(StringRef macroName,
- StringRef fallbackMacroName,
- StringRef args) {
+ StringRef fallbackMacroName,
+ StringRef args) {
Out << "#ifndef " << macroName << "\n";
Out << "# define " << macroName << args
- << " " << fallbackMacroName << args << "\n";
+ << " " << fallbackMacroName << args << "\n";
Out << "#endif\n";
addMacroToUndef(macroName);
}
void TypeNodeEmitter::emitNodeInvocations() {
- for (auto type : Types) {
- // The name without the Type suffix.
- StringRef id = getIdForType(type);
-
- // If this is the Type node itself, skip it.
- if (id.empty()) continue;
-
- // Figure out which macro to use.
- StringRef macroName;
- auto setMacroName = [&](StringRef newName) {
- if (!macroName.empty())
- PrintFatalError(type->getLoc(),
- Twine("conflict when computing macro name for "
- "Type node: trying to use both \"")
- + macroName + "\" and \"" + newName + "\"");
- macroName = newName;
- };
- if (type->isSubClassOf(AlwaysDependentClassName))
- setMacroName(DependentTypeMacroName);
- if (type->isSubClassOf(NeverCanonicalClassName))
- setMacroName(NonCanonicalTypeMacroName);
- if (type->isSubClassOf(NeverCanonicalUnlessDependentClassName))
- setMacroName(NonCanonicalUnlessDependentTypeMacroName);
- if (type->getValueAsBit(AbstractFieldName))
- setMacroName(AbstractTypeMacroName);
- if (macroName.empty())
- macroName = TypeMacroName;
-
- // Compute the base class.
- StringRef baseName = TypeClassName;
- if (auto base = type->getValueAsOptionalDef(BaseFieldName))
- baseName = base->getName();
-
- // Generate the invocation line.
- Out << macroName << "(" << id << ", " << baseName << ")\n";
- }
+ for (auto type : Types) {
+ // The name without the Type suffix.
+ StringRef id = getIdForType(type);
+
+ // If this is the Type node itself, skip it.
+ if (id.empty()) continue;
+
+ // Figure out which macro to use.
+ StringRef macroName;
+ auto setMacroName = [&](StringRef newName) {
+ if (!macroName.empty())
+ PrintFatalError(type->getLoc(),
+ Twine("conflict when computing macro name for "
+ "Type node: trying to use both \"")
+ + macroName + "\" and \"" + newName + "\"");
+ macroName = newName;
+ };
+ if (type->isSubClassOf(AlwaysDependentClassName))
+ setMacroName(DependentTypeMacroName);
+ if (type->isSubClassOf(NeverCanonicalClassName))
+ setMacroName(NonCanonicalTypeMacroName);
+ if (type->isSubClassOf(NeverCanonicalUnlessDependentClassName))
+ setMacroName(NonCanonicalUnlessDependentTypeMacroName);
+ if (type->getValueAsBit(AbstractFieldName))
+ setMacroName(AbstractTypeMacroName);
+ if (macroName.empty())
+ macroName = TypeMacroName;
+
+ // Compute the base class.
+ StringRef baseName = TypeClassName;
+ if (auto base = type->getValueAsOptionalDef(BaseFieldName))
+ baseName = base->getName();
+
+ // Generate the invocation line.
+ Out << macroName << "(" << id << ", " << baseName << ")\n";
+ }
}
void TypeNodeEmitter::emitLastNodeInvocation() {
- // We check that this is non-empty earlier.
- Out << "#ifdef " LastTypeMacroName "\n"
- LastTypeMacroName "(" << getIdForType(Types.back()) << ")\n"
- "#undef " LastTypeMacroName "\n"
- "#endif\n";
+ // We check that this is non-empty earlier.
+ Out << "#ifdef " LastTypeMacroName "\n"
+ LastTypeMacroName "(" << getIdForType(Types.back()) << ")\n"
+ "#undef " LastTypeMacroName "\n"
+ "#endif\n";
}
void TypeNodeEmitter::emitLeafNodeInvocations() {
- Out << "#ifdef " LeafTypeMacroName "\n";
+ Out << "#ifdef " LeafTypeMacroName "\n";
- for (auto type : Types) {
- if (!type->isSubClassOf(LeafTypeClassName)) continue;
- Out << LeafTypeMacroName "(" << getIdForType(type) << ")\n";
- }
+ for (auto type : Types) {
+ if (!type->isSubClassOf(LeafTypeClassName)) continue;
+ Out << LeafTypeMacroName "(" << getIdForType(type) << ")\n";
+ }
- Out << "#undef " LeafTypeMacroName "\n"
- "#endif\n";
+ Out << "#undef " LeafTypeMacroName "\n"
+ "#endif\n";
}
void TypeNodeEmitter::addMacroToUndef(StringRef macroName) {
- MacrosToUndef.push_back(macroName);
+ MacrosToUndef.push_back(macroName);
}
void TypeNodeEmitter::emitUndefs() {
- for (auto ¯oName : MacrosToUndef) {
- Out << "#undef " << macroName << "\n";
- }
+ for (auto ¯oName : MacrosToUndef) {
+ Out << "#undef " << macroName << "\n";
+ }
}
void clang::EmitClangTypeNodes(RecordKeeper &records, raw_ostream &out) {
- TypeNodeEmitter(records, out).emit();
+ TypeNodeEmitter(records, out).emit();
}