[PATCH] D133468: [clang] Implement divergence for TypedefType and UsingType

David Rector via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 19 20:56:39 PDT 2022


davrec added a comment.

If I understand this correctly: whenever isDivergent() is true, `getDecl()` or `getFoundDecl()` is an arbitrary choice between multiple candidate (re)declarations of a typedef or using decl.  In particular it will be the first redeclaration, //even though each different redeclaration can contain different sugar information//.

E.g. considering your examples:

  using X1 = int;
  using Y1 = int;
  
  using RPB1 = X1*;
  using RPX1 = RPB1;
  using RPB1 = Y1*; // redeclared
  using RPY1 = RPB1;
  
  namespace A { using type1 = X1*; };
  namespace C { using A::type1; };
  using UPX1 = C::type1;
  namespace A { using type1 = Y1*; };  // redeclared
  namespace C { using A::type1; };     // redeclared
  using UPY1 = C::type1;

So far so good: isDivergent() would be false for all the above TypedefTypes and UsingTypes, since the UnderlyingTypes and Decls/FoundDecls are consistent.  But these types are a different matter:

  auto t29 = 0 ? (RPX1){} : (RPY1){};
  auto t32 = 0 ? (UPX1){} : (UPY1){};

In the process of unifying the sugar to get the deduced type of t29/t32, we will compare their sugar, which has the same basic structure for each, but different decls/found decls; so unifying these types will simply involve unifying their decls; and getCommonDecl(X,Y) has been defined to will simply get the older declaration between them.  So, the TypedefType/UsingType sugar in t29/t32 will reference the X1 decls and friends, *not* the Y1s, as its Decls/FoundDecls.  (Right?)

The UnderlyingType however will not be as arbitrary, as it will use getCommonType to skip over everything the two don't have in common.

If I have this right, my question is: since the Decl/FoundDecl is an arbitrary choice, should we solve this by either

1. constructing these with a null Decl/FoundDecl for such types, or if that is problematic,
2. renaming `isDivergent` to `declIsArbitrary()` or something like that, to suggest that not only do the underlying type and decl diverge, it is the underlying type which is more meaningful, not the decl.





================
Comment at: clang/include/clang/AST/Type.h:4490
   UsingShadowDecl *getFoundDecl() const { return Found; }
+  bool isDivergent() const { return UsingBits.isDivergent; }
   QualType getUnderlyingType() const;
----------------
The name of this might be less important than just documenting it extremely well here, with an example.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133468



More information about the cfe-commits mailing list