[PATCH] D107275: [Sema] a[x] has type T when a has type T* or T[], even when T is dependent
Sam McCall via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 2 06:56:15 PDT 2021
sammccall created this revision.
sammccall added reviewers: kadircet, rsmith.
Herald added a subscriber: usaxena95.
sammccall requested review of this revision.
Herald added subscribers: cfe-commits, ilya-biryukov.
Herald added a project: clang.
This more precise type is useful for tools, e.g.
fixes https://github.com/clangd/clangd/issues/831
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D107275
Files:
clang/lib/Sema/SemaExpr.cpp
clang/test/AST/ast-dump-array.cpp
Index: clang/test/AST/ast-dump-array.cpp
===================================================================
--- clang/test/AST/ast-dump-array.cpp
+++ clang/test/AST/ast-dump-array.cpp
@@ -25,3 +25,32 @@
// CHECK: `-DependentSizedArrayType 0x{{[^ ]*}} 'T [Size]' dependent <col:25, col:30>
};
+template <typename U, typename Idx>
+void testDependentSubscript() {
+ U* a;
+ U b[5];
+ Idx i{};
+
+ // Can types of subscript expressions can be determined?
+ // LHS is a type-dependent array
+ a[1];
+ // CHECK: ArraySubscriptExpr {{.*}} 'U' lvalue
+ b[1];
+ // CHECK: ArraySubscriptExpr {{.*}} 'U' lvalue
+
+ // LHS is a type-dependent array, RHS is type-dependent.
+ a[i];
+ // CHECK: ArraySubscriptExpr {{.*}} 'U' lvalue
+ b[i];
+ // CHECK: ArraySubscriptExpr {{.*}} 'U' lvalue
+
+ struct V;
+ V *a2;
+ V b2[5];
+
+ // LHS is a known array, RHS is type-dependent.
+ a2[i];
+ // CHECK: ArraySubscriptExpr {{.*}} 'V' lvalue
+ b2[i];
+ // CHECK: ArraySubscriptExpr {{.*}} 'V' lvalue
+};
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -4785,8 +4785,17 @@
// Build an unanalyzed expression if either operand is type-dependent.
if (getLangOpts().CPlusPlus &&
(base->isTypeDependent() || idx->isTypeDependent())) {
- return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy,
- VK_LValue, OK_Ordinary, rbLoc);
+ QualType Type = Context.DependentTy;
+ // Refine type if LHS is an array or pointer.
+ // This is safe because overloading is not possible in this case, and
+ // arrays/pointers can't be the index of of a builtin subscript.
+ // Don't bother for RHS, that case is very rare.
+ if (const PointerType *PT = base->getType()->getAs<PointerType>())
+ Type = PT->getPointeeType();
+ else if (const ArrayType *AT = base->getType()->getAsArrayTypeUnsafe())
+ Type = AT->getElementType();
+ return new (Context)
+ ArraySubscriptExpr(base, idx, Type, VK_LValue, OK_Ordinary, rbLoc);
}
// MSDN, property (C++)
@@ -5541,6 +5550,13 @@
BaseExpr = LHSExp;
IndexExpr = RHSExp;
ResultType = Context.DependentTy;
+ // One of LHS and RHS must be pointer, the other must be array.
+ // We don't know in general, but determine a more specific type if we can.
+ // Don't bother for the uncommon case where the index is on the left.
+ if (const PointerType *PT = LHSTy->getAs<PointerType>())
+ ResultType = PT->getPointeeType();
+ else if (const ArrayType *AT = LHSTy->getAsArrayTypeUnsafe())
+ ResultType = AT->getElementType();
} else if (const PointerType *PTy = LHSTy->getAs<PointerType>()) {
BaseExpr = LHSExp;
IndexExpr = RHSExp;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107275.363469.patch
Type: text/x-patch
Size: 2844 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210802/dfb45fe9/attachment-0001.bin>
More information about the cfe-commits
mailing list