[PATCH] D112374: [clang] Implement ElaboratedType sugaring for types written bare
Richard Smith - zygoloid via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue May 24 17:45:35 PDT 2022
rsmith added a comment.
Herald added a project: All.
I've not looked at the test changes in any detail; please let me know if there's anything in there that deserves special attention.
================
Comment at: clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp:567-577
- if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
- NestedNameSpecifierLoc NestedNameSpecifier =
- Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
- // This happens for friend declaration of a base class with injected class
- // name.
- if (!NestedNameSpecifier.getNestedNameSpecifier())
- return;
----------------
Can we keep at least the second check here?
================
Comment at: clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h:28
NameSpecifierNestingThreshold(
- Options.get("NameSpecifierNestingThreshold", 3U)) {}
+ Options.get("NameSpecifierNestingThreshold", 2U)) {}
----------------
If this is an externally-visible option that might be in someone's config file, can we keep it meaning the same thing? Eg, start with a `NestingLevel` of `1`, not `0`, so it counts the number of name components rather than the number of `::`s.
================
Comment at: clang/include/clang/AST/TypeLoc.h:2255-2257
+ unsigned getExtraLocalDataSize() const {
+ return !isEmpty() ? sizeof(ElaboratedLocInfo) : 0;
+ }
----------------
Instead of using a `LocalData` type of `void` and adding `llvm::SizeOf` etc, how about using a local data type of `ElaboratedLocInfo` and overriding `getLocalDataSize` to sometimes return 0 if you don't actually want to store local data? `AdjustedTypeLoc` does something similar already.
================
Comment at: clang/lib/AST/FormatString.cpp:979-983
+ for (const TypedefNameDecl *Typedef;; QT = Typedef->getUnderlyingType()) {
+ const auto *TT = QT->getAs<TypedefType>();
+ if (!TT)
+ return false;
+ Typedef = TT->getDecl();
----------------
Optional, but I think this is a bit clearer. (You'd need to re-add the `return false;` after the loop too.)
================
Comment at: clang/lib/CodeGen/CGCall.cpp:2790
if (!AVAttr)
- if (const auto *TOTy = dyn_cast<TypedefType>(OTy))
+ if (const auto *TOTy = OTy->getAs<TypedefType>())
AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
----------------
Hm, this and the checks for this attribute in CGExprScalar.cpp aren't fully fixed: if we don't find the attribute on a typedef we should look inside that typedef to see if its target is another typedef. See `TypeHasMayAlias` for an example of code doing it correctly. Might make sense to land that as a separate change since it's a pre-existing bug?
================
Comment at: clang/lib/CodeGen/CodeGenFunction.cpp:2210
case Type::ExtInt:
llvm_unreachable("type class is never variably-modified!");
----------------
Hm, this seems to already be reachable for an `ElaboratedType`, even without this change:
```
void f(int n) {
using T = int[n];
struct A {
using U = T;
};
A::U au;
}
```
... but I think that's actually a bug. Bad things are going to happen if the members of `A` mention `U`.
Filed that as https://github.com/llvm/llvm-project/issues/55686.
================
Comment at: clang/lib/Sema/SemaTemplate.cpp:3982
+ // Create an elaborated-type-specifier containing the nested-name-specifier.
+ QualType ElTy = getElaboratedType(ETK_None, SS, SpecTy);
+ ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(ElTy);
----------------
I think in the case we have a constructor or destructor name, we should pass in an empty scope specifier here, so that pretty-printing `Namespace::Class::Class() {}` produces just that instead of `Namespace::Class::Namespace::Class) {}`. (The first name specifier comes from printing the declaration's qualified name, and the second one would come from printing the constructor type.)
================
Comment at: llvm/include/llvm/Support/SizeOf.h:20-23
+/// A sizeof operator stand-in which supports `sizeof(void) == 0`.
+///
+template <class T> struct SizeOf { static constexpr size_t value = sizeof(T); };
+template <> struct SizeOf<void> { static constexpr size_t value = 0; };
----------------
I think it's too surprising to call this simply `SizeOf`, especially given that under https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0146r1.html we might eventually see C++ defining `sizeof(void)` as some non-zero value.
================
Comment at: llvm/include/llvm/Support/SizeOf.h:25-32
+/// An alignof operator stand-in which supports `alignof(void) == 1`.
+///
+template <class T> struct AlignOf {
+ static constexpr size_t value = alignof(T);
+};
+template <> struct AlignOf<void> { static constexpr size_t value = 1; };
+
----------------
There's already a (different!) `llvm::AlignOf` in `llvm/Support/AlignOf.h`.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112374/new/
https://reviews.llvm.org/D112374
More information about the cfe-commits
mailing list