[clang] [clang][HeuristicResolver] Track the expression whose type is being simplified after each step in simplifyType() (PR #126689)

kadir çetinkaya via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 11 00:34:12 PST 2025


================
@@ -210,52 +210,63 @@ QualType HeuristicResolverImpl::getPointeeType(QualType T) {
 QualType HeuristicResolverImpl::simplifyType(QualType Type, const Expr *E,
                                              bool UnwrapPointer) {
   bool DidUnwrapPointer = false;
-  auto SimplifyOneStep = [&](QualType T) {
+  // A type, together with an optional expression whose type it represents
+  // which may have additional information about the expression's type
+  // not stored in the QualType itself.
+  struct TypeExprPair {
+    QualType Type;
+    const Expr *E = nullptr;
+  };
+  TypeExprPair Current{Type, E};
+  auto SimplifyOneStep = [UnwrapPointer, &DidUnwrapPointer,
+                          this](TypeExprPair T) -> TypeExprPair {
     if (UnwrapPointer) {
-      if (QualType Pointee = getPointeeType(T); !Pointee.isNull()) {
+      if (QualType Pointee = getPointeeType(T.Type); !Pointee.isNull()) {
         DidUnwrapPointer = true;
-        return Pointee;
+        return {Pointee};
       }
     }
-    if (const auto *RT = T->getAs<ReferenceType>()) {
+    if (const auto *RT = T.Type->getAs<ReferenceType>()) {
       // Does not count as "unwrap pointer".
-      return RT->getPointeeType();
+      return {RT->getPointeeType()};
     }
-    if (const auto *BT = T->getAs<BuiltinType>()) {
+    if (const auto *BT = T.Type->getAs<BuiltinType>()) {
       // If BaseType is the type of a dependent expression, it's just
       // represented as BuiltinType::Dependent which gives us no information. We
       // can get further by analyzing the dependent expression.
-      if (E && BT->getKind() == BuiltinType::Dependent) {
-        return resolveExprToType(E);
+      if (T.E && BT->getKind() == BuiltinType::Dependent) {
+        return {resolveExprToType(T.E), T.E};
       }
     }
-    if (const auto *AT = T->getContainedAutoType()) {
+    if (const auto *AT = T.Type->getContainedAutoType()) {
       // If T contains a dependent `auto` type, deduction will not have
       // been performed on it yet. In simple cases (e.g. `auto` variable with
       // initializer), get the approximate type that would result from
       // deduction.
       // FIXME: A more accurate implementation would propagate things like the
       // `const` in `const auto`.
-      if (E && AT->isUndeducedAutoType()) {
-        if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
+      if (T.E && AT->isUndeducedAutoType()) {
+        if (const auto *DRE = dyn_cast<DeclRefExpr>(T.E)) {
           if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
-            if (VD->hasInit())
-              return resolveExprToType(VD->getInit());
+            if (VD->hasInit()) {
+              auto *Init = VD->getInit();
----------------
kadircet wrote:

nit: `if (auto *Init = VD->getInit(); Init != nullptr)`

https://github.com/llvm/llvm-project/pull/126689


More information about the cfe-commits mailing list