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