[PATCH] D134286: [C2x] implement typeof and typeof_unqual

Erich Keane via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 20 09:54:33 PDT 2022


erichkeane added a comment.

I'm on the fence about re-using the same nodes for `typeof` and `typeof_unqual`.  However, I have a preference to stop shuffling a bool around everywhere as parameters, and would like an enum (even if we store it as a bitfield : 1).  Something like:

  enum class TypeofKind {
         Typeof, TypeofUnqual };

I think improves readability in a bunch of places, AND gives us less work to do if we need to extend this node in the future.



================
Comment at: clang/include/clang/AST/ASTContext.h:1718
   /// GCC extension.
-  QualType getTypeOfExprType(Expr *e) const;
-  QualType getTypeOfType(QualType t) const;
+  QualType getTypeOfExprType(Expr *E, bool IsUnqual) const;
+  QualType getTypeOfType(QualType QT, bool IsUnqual) const;
----------------
Mild preference for an enum, instead of a bool here.

Alternatively, depending on your design below that I haven't seen yet, perhaps unqual versions of these functions?


================
Comment at: clang/include/clang/AST/Type.h:4542
 
-  TypeOfExprType(Expr *E, QualType can = QualType());
+  TypeOfExprType(Expr *E, bool IsUnqual, QualType Can = QualType());
 
----------------
This constructor is smelly.... Am I to guess this does something like, "if E, type is the type of this, else it is the type passed in Can?"


================
Comment at: clang/include/clang/AST/Type.h:4592
+          T->getDependence()), TOType(T), IsUnqual(IsUnqual) {
+    assert(!isa<TypedefType>(Can) && "Invalid canonical type");
   }
----------------
Are `TypedefType`'s EVER canonical?  Should you just be asserting 'Can' is canonical?


================
Comment at: clang/lib/AST/ASTContext.cpp:12910
   case Type::TypeOf:
-    return Ctx.getTypeOfType(Ctx.getQualifiedType(Underlying));
+    // FIXME:: is this assumption correct or do we need to do work here to find
+    // the common type sugar regarding the stripped qualifiers if only one side
----------------
I'm unfamiliar with this function, but I would expect you MIGHT need to?  If only because they are the same AST node.  Should 'unqual' version be its own node?  I'm on the fence, as it is a LOT of code to do so, but also ends up being simpler in many places.


================
Comment at: clang/lib/AST/Type.cpp:3502
+  // We strip all qualifier-like attributes as well.
+  if (const auto *AT =
+          dyn_cast_if_present<AttributedType>(Ret.getTypePtrOrNull());
----------------
In what situation is getTypePtrOrNull required here?  I would imagine that the 'isNull' check above should make sure we aren't in a situation where 'Ret' could be 'null' here?  Same with the 'if_present'.


================
Comment at: clang/lib/Lex/Preprocessor.cpp:61
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/Capacity.h"
----------------
Oh?


================
Comment at: clang/lib/Parse/ParseDecl.cpp:7463
   SourceLocation StartLoc = ConsumeToken();
-
-  const bool hasParens = Tok.is(tok::l_paren);
+  bool HasParens = Tok.is(tok::l_paren);
 
----------------
Should it be an error to `!HasParens` if `IsUnqual`.


================
Comment at: clang/lib/Sema/SemaType.cpp:9137
+    Diag(E->getExprLoc(), diag::err_sizeof_alignof_typeof_bitfield)
+        << (IsUnqual ? 3 : 2);
 
----------------
`(IsUnqual + 2)` maybe?  Or perhaps too cute.


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

https://reviews.llvm.org/D134286



More information about the cfe-commits mailing list