[PATCH] D127695: [clang] Implement Template Specialization Resugaring

David Rector via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 1 05:57:42 PDT 2022


davrec added a subscriber: rjmccall.
davrec added a comment.

First thank you for having separated out the public AST changes into other patches, it makes these mostly-Sema changes much easier to review.

I don't see any major issues with the code, though this would benefit from a close look from more folks with deeper Sema familiarity.  Maybe @rjmccall would be willing or could @ someone?

The larger issues:

1. Performance - can we see some numbers?  and
2. There are a lot of FIXMEs introduced - understandable because of the scale, but it would be nice to hear you commit to eventually getting to those because otherwise they will probably remain indefinitely.   @aaron.ballman should probably weigh in/sign off on this one given the number of FIXMEs, which probably can't be handled before @mizvekov 's deadline (when is that again?).



================
Comment at: clang/lib/Sema/SemaCXXScopeSpec.cpp:879-882
+  TypeLocBuilder TLB;
+  DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T);
+  DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc());
+  DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd());
----------------
Move back down?


================
Comment at: clang/lib/Sema/SemaCXXScopeSpec.cpp:993-999
+  // Alias template specializations can produce types which are not valid
+  // nested name specifiers.
+  if (!T->isDependentType() && !T->getAs<TagType>()) {
+    Diag(TemplateNameLoc, diag::err_nested_name_spec_non_tag) << T;
+    NoteAllFoundTemplates(Template);
+    return true;
+  }
----------------
Move back up?


================
Comment at: clang/lib/Sema/SemaExpr.cpp:3427-3430
     if (unsigned BID = cast<FunctionDecl>(VD)->getBuiltinID()) {
       if (!Context.BuiltinInfo.isDirectlyAddressable(BID)) {
         type = Context.BuiltinFnTy;
         valueKind = VK_PRValue;
----------------
Does this need the same changes as Sema::FixOverloadedFunctionReference?  (see below)


================
Comment at: clang/lib/Sema/SemaExpr.cpp:20800
         DRE->copyTemplateArgumentsInto(TemplateArgs);
+        // FIXME: resugar
         return BuildDeclRefExpr(
----------------
Could this be done same as earlier (lines 19548-19553)?


================
Comment at: clang/lib/Sema/SemaExprMember.cpp:1862
 
     Qualifiers MemberQuals =
+        Context.getCanonicalType(FieldType).getQualifiers();
----------------
Rename to FieldQuals


================
Comment at: clang/lib/Sema/SemaOverload.cpp:15357
 
     // FIXME: Duplicated from BuildDeclarationNameExpr.
+    QualType Type;
----------------
I think this should have said "Duplicated from diagnoseUncapturableValueReferenceOrBinding" - if so do we need the below changes over there too?


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:743
+      }
+      llvm_unreachable("");
+    }
----------------
Add message


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:95
 
+TemplateDecl *getTemplateDecl(NamedDecl *D) {
+  switch (D->getKind()) {
----------------
static/move to namespace {} below.  Or make it a public method of Decl?  `Decl::getOriginalDescribedTemplate()` or something like that?  (If you go that route then best to fall back to getDescribedTemplate instead of the unreachable.)


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:130
+    // Maybe fall back to Decl::getDescribedTemplate.
+    D->dumpColor();
+    llvm_unreachable("Unhandled decl kind");
----------------
Not sure of policy, should this dump should be removed?  Several others below too.


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:161
+public:
+  struct SemanticContextRAII {
+    SemanticContextRAII(Resugarer &R, NamedDecl *ND,
----------------
Wouldn't hurt to add a brief comment above each RAII class describing its role


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:257
+      assert(!Args.empty());
+      if (Reverse)
+        R->CurTemplateToArgs.try_emplace(Template, Args);
----------------
Would be nice to have a comment explaining the effect of Reverse here or above addTypeToMap.  (Reverse iteration?)


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:265
+      struct {
+        NamedDecl *ND;
+        const TemplateSpecializationType *TS;
----------------
Could clarify to CXXRecordDecl


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:293
+          T->dump();
+          llvm_unreachable("");
+        }
----------------
Add message


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:466
+      Result = SemaRef.Context.getElaboratedType(
+          T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), NamedT);
+
----------------
Maybe include T->OwnedTagDecl arg for consistency with deduction resugaring


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:479
+    const SubstTemplateTypeParmType *T = TL.getTypePtr();
+    Decl *ReplacedDecl = T->getAssociatedDecl();
+    Optional<unsigned> PackIndex = T->getPackIndex();
----------------
AssociatedDecl


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:4783
     int64_t N = Index.getExtValue();
-    return getSubstType(Ts.getPackAsArray()[N].getAsType(), 1,
-                        Ts.pack_size() - 1 - N);
+    // FIXME: resugaring here is actually unnecessary.
+    return getResugaredTemplateSpecializationType(
----------------
Change back to original?


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:5371-5386
+  // Check the tag kind
+  if (const RecordType *RT = T->getAs<RecordType>()) {
+    RecordDecl *D = RT->getDecl();
+
+    IdentifierInfo *Id = D->getIdentifier();
+    assert(Id && "templated class must have an identifier");
+
----------------
Move back up?


================
Comment at: clang/lib/Sema/TreeTransform.h:2679-2681
+    CXXScopeSpec SS;
+    SS.Adopt(QualifierLoc);
+
----------------
Move back down?


================
Comment at: clang/test/Sema/Resugar/resugar-expr.cpp:244
+// N-error at -2 {{with an rvalue of type 'int'}}
+} // namespace t21
----------------
mizvekov wrote:
> davrec wrote:
> > Compositions of MemberExprs/CXXMemberCallExprs have an issue:
> > ```
> > template <class A1> struct A {
> >   struct Inner {
> >     A1 m;
> >     A1 f();
> >   } inner;
> >   Inner g();
> > };
> > Z x1 = A<Int>().inner.m; //No resugar
> > Z x2 = A<Int>().inner.f(); //No resugar
> > Z x3 = A<Int>().g().m; //No resugar
> > Z x4 = A<Int>().g().f(); //No resugar
> > Z x5 = A<Int>::Inner().m; //ok
> > ```
> > 
> > Composed `CallExprs` seem to work but probably warrant a test, e.g.
> > ```
> > template <class B1> B1 h(B1);
> > Z x6 = h(Int());
> > Z x7 = h(h(Int()));
> > ```
> > 
> > https://godbolt.org/z/cszrsvh8d
> > 
> Thanks for the feedback!
> 
> The problem here I think is that for a MemberExpr, we have to look at not only the BaseType of it for a resugaring context, but instead look at its BaseExpr to see if it or any bases of it, and so on recursively, can provide a resugaring context as well, effectively building one naming context from the whole composition.
> 
> I will try to address that later, I probably should work on facilitating the reviews of the other patches in this stack, and then splitting this one big patch up more :)
Inheritance is also an issue:

https://godbolt.org/z/81nPqzsrd

```
using Int = int;
enum class Z;

template<typename A1>
struct A {
    A1 m;
};

template<typename A1>
struct B : A<A1> {};

Z x2 = B<Int>().m; //doesn't resugar
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127695/new/

https://reviews.llvm.org/D127695



More information about the cfe-commits mailing list