[PATCH] D45131: [AST] Refactor UnaryTransformType into TransformTraitType supporting non-unary transforms
Richard Smith - zygoloid via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 4 19:25:17 PDT 2018
rsmith added inline comments.
================
Comment at: include/clang/AST/Type.h:3990
/// The untransformed type.
- QualType BaseType;
+ SmallVector<QualType, 2> ArgTypes;
----------------
You can't store types with non-trivial destructors on AST nodes; the Type destructor will never run, so you'll leak. Instead, consider tail-allocating this list of QualTypes, or performing a separate allocation using the ASTContext slab allocator to hold the list if tail-allocation isn't feasible for some reason.
================
Comment at: include/clang/Basic/DiagnosticCommonKinds.td:111-114
+// Type traits
+def err_type_trait_arity : Error<
+ "type trait requires %0%select{| or more| or fewer}1 argument%select{|s}2; have "
+ "%3 argument%s3">;
----------------
Hmm, do you need to touch this diagnostic in this change?
(If so, can you fix the second select to use %plural?)
================
Comment at: include/clang/Basic/Specifiers.h:80
#include "clang/Basic/OpenCLImageTypes.def"
TST_error // erroneous type
};
----------------
Not sure what happened here, these whitespace changes look unrelated to your patch.
================
Comment at: include/clang/Serialization/ASTBitCodes.h:1088
/// \brief A DeducedTemplateSpecializationType record.
TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45,
----------------
Please commit the whitespace changes in this file separately.
================
Comment at: lib/AST/ASTDumper.cpp:2219
+ OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
+ << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
+ if (!Node->canOverflow())
----------------
I prefer this as it was before (`'`s wrapping the thing they're quoting)...
================
Comment at: lib/AST/ASTImporter.cpp:717
+QualType ASTNodeImporter::VisitTransformTraitType(const TransformTraitType *T) {
+ SmallVector<QualType, 2> ToArgTypes;
+ for (auto Ty : T->getArgs()) {
----------------
2 seems unnecessarily low here.
================
Comment at: lib/AST/ASTStructuralEquivalence.cpp:502
+ case Type::TransformTrait: {
+ const TransformTraitType *TT1 = cast<TransformTraitType>(T1);
+ const TransformTraitType *TT2 = cast<TransformTraitType>(T2);
----------------
This should presumably also check the kind...
================
Comment at: lib/AST/ItaniumMangle.cpp:3250-3251
- mangleType(T->getBaseType());
+ for (auto Ty : T->getArgs())
+ mangleType(Ty);
}
----------------
We need manglings to be self-delimiting, and we can't tell where the end of the argument list is with this mangling approach. :(
(Eg, `f(__raw_invocation_type(T1, T2, T3))` and `f(__raw_invocation_type(T1, T2), T3)` would mangle the same with this mangling.)
Maybe drop an `E` on the end? (Or maybe do that only for traits that don't require exactly one argument, but that would create pain for demanglers....)
================
Comment at: lib/AST/TypePrinter.cpp:901
+ return;
+ llvm_unreachable("transformation trait not handled");
}
----------------
This doesn't look right...
================
Comment at: lib/Parse/ParseDeclCXX.cpp:1077-1087
+ auto DiagSelect = [&]() -> Optional<DiagInfo> {
+ if (Info.MinArity && Info.MinArity == Info.MaxArity &&
+ Info.MinArity != Args.size())
+ return DiagInfo{Info.MinArity, 0};
+ if (Info.MinArity && Args.size() < Info.MinArity)
+ return DiagInfo{Info.MinArity, 1};
+ if (Info.MaxArity && Args.size() > Info.MaxArity)
----------------
This only works if none of the arguments are pack expansions.
================
Comment at: lib/Sema/SemaTemplateDeduction.cpp:5367-5368
+ }
+ MarkUsedTemplateParameters(Ctx, TT->getTransformedType(), OnlyDeduced,
+ Depth, Used);
+ }
----------------
Marking the transformed type doesn't seem necessary. It can't possibly name template parameters (except via the inputs to the trait).
================
Comment at: lib/Sema/SemaType.cpp:1508-1509
+ break;
+ default:
+ llvm_unreachable("unhandled case");
+ }
----------------
Try to avoid `default:` cases like this, as they suppress the warning notifying the user to update this switch when new traits are added.
================
Comment at: lib/Sema/SemaType.cpp:8004-8013
+ unsigned MinArity, MaxArity;
+ switch (Kind) {
+ case TransformTraitType::EnumUnderlyingType:
+ MinArity = MaxArity = 1;
+ break;
+ }
+ struct DiagInfo {
----------------
Looks like you were half-way through factoring out the commonality between this and the parser's version?
================
Comment at: lib/Sema/SemaType.cpp:8037-8038
SourceLocation Loc) {
- switch (UKind) {
- case UnaryTransformType::EnumUnderlyingType:
+ if (diagnoseTransformTraitArity(*this, TKind, Loc, ArgTypes.size()))
+ return QualType();
+ switch (TKind) {
----------------
You'll need to deal with the case that the arguments contain unexpanded packs here before assuming that `ArgTypes.size()` is meaningful.
================
Comment at: lib/Sema/TreeTransform.h:625-627
+ bool TransformTypeSourceListAndExpandPacks(
+ ArrayRef<TypeSourceInfo *> InArgs, bool &ArgChanged,
+ SmallVectorImpl<TypeSourceInfo *> &Args);
----------------
I would drop the "Source" from this. We generally don't shorten "TypeSourceInfo" to "TypeSource", and it's clear enough to just say "Type" here I think. I'd also drop the "AndExpandPacks" because that's just a part of what it means to transform a list.
https://reviews.llvm.org/D45131
More information about the cfe-commits
mailing list