Michael137 created this revision.
Michael137 added reviewers: erichkeane, aaron.ballman, dblaikie.
Herald added a project: All.
Michael137 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

**Summary**

This patch adds a `IsDefaulted` field to `clang::TemplateArgument`.

To prevent memory footprint increase we still 1 bit from `ArgKind`.

**Background**

In LLDB we construct ASTs from debug-info and hand it to clang
to perform actions such as printing/formatting a typenames.
Some debug formats, specifically DWARF, may only encode information
about class template instantiations, losing the structure of the generic
class definition. However, the `clang::TypePrinter` needs a properly
constructed `ClassTemplateDecl` with generic default argument decls
to be able to deduce whether a `ClassTemplateSpecializationDecl` was
instantiatiated with `TemplateArgument`s that correspond to the
defaults. LLDB does know whether a particular template argument was
defaulted, but can't currently tell clang about it.

This patch allows LLDB to set the defaulted-ness of a `TemplateArgument`
and thus benefit more from `clang::TypePrinter`.

See discussion in https://reviews.llvm.org/D140423

**Testing**

- TODO


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141826

Files:
  clang/include/clang/AST/TemplateBase.h
  clang/lib/AST/TemplateBase.cpp

Index: clang/lib/AST/TemplateBase.cpp
===================================================================
--- clang/lib/AST/TemplateBase.cpp
+++ clang/lib/AST/TemplateBase.cpp
@@ -162,6 +162,7 @@
 TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
                                    QualType Type) {
   Integer.Kind = Integral;
+  Integer.IsDefaulted = false;
   // Copy the APSInt value into our decomposed form.
   Integer.BitWidth = Value.getBitWidth();
   Integer.IsUnsigned = Value.isUnsigned();
Index: clang/include/clang/AST/TemplateBase.h
===================================================================
--- clang/include/clang/AST/TemplateBase.h
+++ clang/include/clang/AST/TemplateBase.h
@@ -103,12 +103,14 @@
   /// The kind of template argument we're storing.
 
   struct DA {
-    unsigned Kind;
+    unsigned Kind : 31;
+    unsigned IsDefaulted : 1;
     void *QT;
     ValueDecl *D;
   };
   struct I {
-    unsigned Kind;
+    unsigned Kind : 31;
+    unsigned IsDefaulted : 1;
     // We store a decomposed APSInt with the data allocated by ASTContext if
     // BitWidth > 64. The memory may be shared between multiple
     // TemplateArgument instances.
@@ -124,17 +126,20 @@
     void *Type;
   };
   struct A {
-    unsigned Kind;
+    unsigned Kind : 31;
+    unsigned IsDefaulted : 1;
     unsigned NumArgs;
     const TemplateArgument *Args;
   };
   struct TA {
-    unsigned Kind;
+    unsigned Kind : 31;
+    unsigned IsDefaulted : 1;
     unsigned NumExpansions;
     void *Name;
   };
   struct TV {
-    unsigned Kind;
+    unsigned Kind : 31;
+    unsigned IsDefaulted : 1;
     uintptr_t V;
   };
   union {
@@ -147,11 +152,12 @@
 
 public:
   /// Construct an empty, invalid template argument.
-  constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
+  constexpr TemplateArgument() : TypeOrValue({Null, /* IsDefaulted */ 0, 0}) {}
 
   /// Construct a template type argument.
   TemplateArgument(QualType T, bool isNullPtr = false) {
     TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
+    TypeOrValue.IsDefaulted = false;
     TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
   }
 
@@ -161,6 +167,7 @@
   TemplateArgument(ValueDecl *D, QualType QT) {
     assert(D && "Expected decl");
     DeclArg.Kind = Declaration;
+    DeclArg.IsDefaulted = false;
     DeclArg.QT = QT.getAsOpaquePtr();
     DeclArg.D = D;
   }
@@ -186,6 +193,7 @@
   /// \param Name The template name.
   TemplateArgument(TemplateName Name) {
     TemplateArg.Kind = Template;
+    TemplateArg.IsDefaulted = false;
     TemplateArg.Name = Name.getAsVoidPointer();
     TemplateArg.NumExpansions = 0;
   }
@@ -203,6 +211,7 @@
   /// instantiating
   TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
     TemplateArg.Kind = TemplateExpansion;
+    TemplateArg.IsDefaulted = false;
     TemplateArg.Name = Name.getAsVoidPointer();
     if (NumExpansions)
       TemplateArg.NumExpansions = *NumExpansions + 1;
@@ -217,6 +226,7 @@
   /// occur in a non-dependent, canonical template argument list.
   TemplateArgument(Expr *E) {
     TypeOrValue.Kind = Expression;
+    TypeOrValue.IsDefaulted = false;
     TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
   }
 
@@ -226,6 +236,7 @@
   /// outlives the TemplateArgument itself.
   explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
     this->Args.Kind = Pack;
+    this->Args.IsDefaulted = false;
     this->Args.Args = Args.data();
     this->Args.NumArgs = Args.size();
   }
@@ -334,6 +345,10 @@
     Integer.Type = T.getAsOpaquePtr();
   }
 
+  void setIsDefaulted(bool v) { TypeOrValue.IsDefaulted = v; }
+
+  bool getIsDefaulted() const { return (bool)TypeOrValue.IsDefaulted; }
+
   /// If this is a non-type template argument, get its type. Otherwise,
   /// returns a null QualType.
   QualType getNonTypeTemplateArgumentType() const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to