vsapsai created this revision.
vsapsai added reviewers: rnk, leonardchan, yonghong-song.
Herald added a subscriber: ributzka.
Herald added a project: All.
vsapsai requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Some `TypeLoc`s are considered "sugar" and we go past them in
`GetTypeSourceInfoForDeclarator`. The problem is that we peel off only
the same kind of `TypeLoc` at the time which makes it impossible to
handle mixed sequences like
`AttributedTypeLoc - MacroQualifiedTypeLoc - AttributedTypeLoc - PointerTypeLoc`

In this situation, as shown in the added test, we don't get to
`PointerTypeLoc` and don't set its starLoc leaving it uninitialized.

Address FIXME and peel off "sugar" `TypeLoc`s regardless of their order.

rdar://102149264


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141424

Files:
  clang/lib/Sema/SemaType.cpp
  clang/unittests/AST/SourceLocationTest.cpp

Index: clang/unittests/AST/SourceLocationTest.cpp
===================================================================
--- clang/unittests/AST/SourceLocationTest.cpp
+++ clang/unittests/AST/SourceLocationTest.cpp
@@ -438,6 +438,47 @@
       loc(unaryTransformType())));
 }
 
+TEST(PointerTypeLoc, StarLoc) {
+  llvm::Annotations Example(R"c(
+    int $star^*var;
+  )c");
+
+  auto AST = tooling::buildASTFromCode(Example.code());
+  SourceManager &SM = AST->getSourceManager();
+  auto &Ctx = AST->getASTContext();
+
+  auto *VD = selectFirst<VarDecl>("vd", match(varDecl(hasName("var")).bind("vd"), Ctx));
+  ASSERT_NE(VD, nullptr);
+
+  auto TL =
+      VD->getTypeSourceInfo()->getTypeLoc().castAs<PointerTypeLoc>();
+  ASSERT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("star"));
+}
+
+TEST(PointerTypeLoc, StarLocBehindSugar) {
+  llvm::Annotations Example(R"c(
+    #define NODEREF __attribute__((noderef))
+    char $1st^* NODEREF _Nonnull $2nd^* var;
+  )c");
+
+  auto AST = tooling::buildASTFromCode(Example.code());
+  SourceManager &SM = AST->getSourceManager();
+  auto &Ctx = AST->getASTContext();
+
+  auto *VD = selectFirst<VarDecl>("vd", match(varDecl(hasName("var")).bind("vd"), Ctx));
+  ASSERT_NE(VD, nullptr);
+
+  auto TL = VD->getTypeSourceInfo()->getTypeLoc().castAs<PointerTypeLoc>();
+  EXPECT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("2nd"));
+
+  // Cast intermediate TypeLoc to make sure the structure matches expectations.
+  auto InnerPtrTL = TL.getPointeeLoc().castAs<AttributedTypeLoc>()
+    .getNextTypeLoc().castAs<MacroQualifiedTypeLoc>()
+    .getNextTypeLoc().castAs<AttributedTypeLoc>()
+    .getNextTypeLoc().castAs<PointerTypeLoc>();
+  EXPECT_EQ(SM.getFileOffset(InnerPtrTL.getStarLoc()), Example.point("1st"));
+}
+
 TEST(CXXFunctionalCastExpr, SourceRange) {
   RangeVerifier<CXXFunctionalCastExpr> Verifier;
   Verifier.expectRange(2, 10, 2, 14);
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -6511,29 +6511,42 @@
       CurrTL = ATL.getValueLoc().getUnqualifiedLoc();
     }
 
-    while (MacroQualifiedTypeLoc TL = CurrTL.getAs<MacroQualifiedTypeLoc>()) {
-      TL.setExpansionLoc(
-          State.getExpansionLocForMacroQualifiedType(TL.getTypePtr()));
-      CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
-    }
+    bool HasDesugaredTypeLoc = true;
+    while (HasDesugaredTypeLoc) {
+      switch (CurrTL.getTypeLocClass()) {
+        case TypeLoc::MacroQualified: {
+          auto TL = CurrTL.castAs<MacroQualifiedTypeLoc>();
+          TL.setExpansionLoc(
+              State.getExpansionLocForMacroQualifiedType(TL.getTypePtr()));
+          CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+          break;
+        }
 
-    while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {
-      fillAttributedTypeLoc(TL, State);
-      CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
-    }
+        case TypeLoc::Attributed: {
+          auto TL = CurrTL.castAs<AttributedTypeLoc>();
+          fillAttributedTypeLoc(TL, State);
+          CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+          break;
+        }
 
-    while (BTFTagAttributedTypeLoc TL = CurrTL.getAs<BTFTagAttributedTypeLoc>())
-      CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+        case TypeLoc::Adjusted:
+        case TypeLoc::BTFTagAttributed: {
+          CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
+          break;
+        }
 
-    while (DependentAddressSpaceTypeLoc TL =
-               CurrTL.getAs<DependentAddressSpaceTypeLoc>()) {
-      fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs());
-      CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
-    }
+        case TypeLoc::DependentAddressSpace: {
+          auto TL = CurrTL.castAs<DependentAddressSpaceTypeLoc>();
+          fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs());
+          CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc();
+          break;
+        }
 
-    // FIXME: Ordering here?
-    while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>())
-      CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+        default:
+          HasDesugaredTypeLoc = false;
+          break;
+      }
+    }
 
     DeclaratorLocFiller(S.Context, State, D.getTypeObject(i)).Visit(CurrTL);
     CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to