Use property-based serialization for TemplateArgument.
authorJohn McCall <rjmccall@apple.com>
Mon, 16 Dec 2019 16:57:23 +0000 (11:57 -0500)
committerJohn McCall <rjmccall@apple.com>
Mon, 16 Dec 2019 18:34:00 +0000 (13:34 -0500)
clang/include/clang/AST/AbstractBasicReader.h
clang/include/clang/AST/AbstractBasicWriter.h
clang/include/clang/AST/PropertiesBase.td
clang/include/clang/Serialization/ASTRecordReader.h

index 30eb5cf..1e1aef2 100644 (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();
 
index 552a482..f09ac01 100644 (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.
index 5f5ad88..1cd1c79 100644 (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()));
+  }]>;
+}
index 4fad288..f6dc8b2 100644 (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();