Use property-based serialization for TemplateArgument.

This commit is contained in:
John McCall 2019-12-16 11:57:23 -05:00
parent 2e2d142efe
commit da74c4d2d8
4 changed files with 101 additions and 90 deletions

View File

@ -197,54 +197,6 @@ public:
return FunctionProtoType::ExtParameterInfo::getFromOpaqueValue(value);
}
TemplateArgument readTemplateArgument(bool canonicalize = false) {
if (canonicalize) {
return getASTContext().getCanonicalTemplateArgument(
readTemplateArgument(false));
}
auto kind = asImpl().readTemplateArgumentKind();
switch (kind) {
case TemplateArgument::Null:
return TemplateArgument();
case TemplateArgument::Type:
return TemplateArgument(asImpl().readQualType());
case TemplateArgument::Declaration: {
auto decl = asImpl().readValueDeclRef();
auto type = asImpl().readQualType();
return TemplateArgument(decl, type);
}
case TemplateArgument::NullPtr:
return TemplateArgument(asImpl().readQualType(), /*nullptr*/ true);
case TemplateArgument::Integral: {
auto value = asImpl().readAPSInt();
auto type = asImpl().readQualType();
return TemplateArgument(getASTContext(), value, type);
}
case TemplateArgument::Template:
return TemplateArgument(asImpl().readTemplateName());
case TemplateArgument::TemplateExpansion: {
auto name = asImpl().readTemplateName();
auto numExpansions = asImpl().template readOptional<uint32_t>();
return TemplateArgument(name, numExpansions);
}
case TemplateArgument::Expression:
return TemplateArgument(asImpl().readExprRef());
case TemplateArgument::Pack: {
llvm::SmallVector<TemplateArgument, 8> packBuffer;
auto pack = asImpl().template readArray<TemplateArgument>(packBuffer);
// Copy the pack into the ASTContext.
TemplateArgument *contextPack =
new (getASTContext()) TemplateArgument[pack.size()];
for (size_t i = 0, e = pack.size(); i != e; ++i)
contextPack[i] = pack[i];
return TemplateArgument(llvm::makeArrayRef(contextPack, pack.size()));
}
}
llvm_unreachable("bad template argument kind");
}
NestedNameSpecifier *readNestedNameSpecifier() {
auto &ctx = getASTContext();

View File

@ -178,47 +178,6 @@ public:
asImpl().writeUInt32(epi.getOpaqueValue());
}
void writeTemplateArgument(const TemplateArgument &arg) {
asImpl().writeTemplateArgumentKind(arg.getKind());
switch (arg.getKind()) {
case TemplateArgument::Null:
return;
case TemplateArgument::Type:
asImpl().writeQualType(arg.getAsType());
return;
case TemplateArgument::Declaration:
asImpl().writeValueDeclRef(arg.getAsDecl());
asImpl().writeQualType(arg.getParamTypeForDecl());
return;
case TemplateArgument::NullPtr:
asImpl().writeQualType(arg.getNullPtrType());
return;
case TemplateArgument::Integral:
asImpl().writeAPSInt(arg.getAsIntegral());
asImpl().writeQualType(arg.getIntegralType());
return;
case TemplateArgument::Template:
asImpl().writeTemplateName(arg.getAsTemplateOrTemplatePattern());
return;
case TemplateArgument::TemplateExpansion: {
asImpl().writeTemplateName(arg.getAsTemplateOrTemplatePattern());
// Convert Optional<unsigned> to Optional<uint32>, just in case.
Optional<unsigned> numExpansions = arg.getNumTemplateExpansions();
Optional<uint32_t> numExpansions32;
if (numExpansions) numExpansions32 = *numExpansions;
asImpl().template writeOptional<uint32_t>(numExpansions32);
return;
}
case TemplateArgument::Expression:
asImpl().writeExprRef(arg.getAsExpr());
return;
case TemplateArgument::Pack:
asImpl().template writeArray<TemplateArgument>(arg.pack_elements());
return;
}
llvm_unreachable("bad template argument kind");
}
void writeNestedNameSpecifier(NestedNameSpecifier *NNS) {
// Nested name specifiers usually aren't too long. I think that 8 would
// typically accommodate the vast majority.

View File

@ -401,3 +401,95 @@ let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in {
return ctx.getSubstTemplateTemplateParmPack(parameterPack, argumentPack);
}]>;
}
// Type cases for TemplateArgument.
def : PropertyTypeKind<TemplateArgument, TemplateArgumentKind,
"node.getKind()">;
let Class = PropertyTypeCase<TemplateArgument, "Null"> in {
def : Creator<[{
return TemplateArgument();
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Type"> in {
def : Property<"type", QualType> {
let Read = [{ node.getAsType() }];
}
def : Creator<[{
return TemplateArgument(type);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
def : Property<"declaration", ValueDeclRef> {
let Read = [{ node.getAsDecl() }];
}
def : Property<"parameterType", QualType> {
let Read = [{ node.getParamTypeForDecl() }];
}
def : Creator<[{
return TemplateArgument(declaration, parameterType);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in {
def : Property<"type", QualType> {
let Read = [{ node.getNullPtrType() }];
}
def : Creator<[{
return TemplateArgument(type, /*nullptr*/ true);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
def : Property<"value", APSInt> {
let Read = [{ node.getAsIntegral() }];
}
def : Property<"type", QualType> {
let Read = [{ node.getIntegralType() }];
}
def : Creator<[{
return TemplateArgument(ctx, value, type);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
def : Property<"name", TemplateName> {
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
}
def : Creator<[{
return TemplateArgument(name);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
def : Property<"name", TemplateName> {
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
}
def : Property<"numExpansions", Optional<UInt32>> {
let Read = [{
// Translate unsigned -> uint32_t just in case.
node.getNumTemplateExpansions().map(
[](unsigned i) { return uint32_t(i); })
}];
}
def : Creator<[{
auto numExpansionsUnsigned =
numExpansions.map([](uint32_t i) { return unsigned(i); });
return TemplateArgument(name, numExpansionsUnsigned);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
def : Property<"expression", ExprRef> {
let Read = [{ node.getAsExpr() }];
}
def : Creator<[{
return TemplateArgument(expression);
}]>;
}
let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {
def : Property<"elements", Array<TemplateArgument>> {
let Read = [{ node.pack_elements() }];
}
def : Creator<[{
// Copy the pack into the ASTContext.
TemplateArgument *ctxElements = new (ctx) TemplateArgument[elements.size()];
for (size_t i = 0, e = elements.size(); i != e; ++i)
ctxElements[i] = elements[i];
return TemplateArgument(llvm::makeArrayRef(ctxElements, elements.size()));
}]>;
}

View File

@ -228,7 +228,15 @@ public:
// TemplateName readTemplateName(); (inherited)
/// Read a template argument, advancing Idx. (inherited)
// TemplateArgument readTemplateArgument(bool Canonicalize = false);
// TemplateArgument readTemplateArgument();
using DataStreamBasicReader::readTemplateArgument;
TemplateArgument readTemplateArgument(bool Canonicalize) {
TemplateArgument Arg = readTemplateArgument();
if (Canonicalize) {
Arg = getContext().getCanonicalTemplateArgument(Arg);
}
return Arg;
}
/// Read a template parameter list, advancing Idx.
TemplateParameterList *readTemplateParameterList();