Enable lifetime elision for lifetime-parameterized types.

PiperOrigin-RevId: 431932125
diff --git a/lifetime_annotations/lifetime_annotations.cc b/lifetime_annotations/lifetime_annotations.cc
index f197697..97c9867 100644
--- a/lifetime_annotations/lifetime_annotations.cc
+++ b/lifetime_annotations/lifetime_annotations.cc
@@ -30,7 +30,7 @@
 namespace {
 
 llvm::Expected<llvm::SmallVector<Lifetime>> GetAnnotatedOrElidedLifetimes(
-    llvm::ArrayRef<const clang::Attr*> /*attrs*/, int num_expected,
+    llvm::ArrayRef<const clang::Attr*> /*attrs*/, size_t num_expected,
     LifetimeSymbolTable& /*symbol_table*/,
     const std::function<llvm::Expected<Lifetime>()>& elided_lifetime_factory,
     const clang::ASTContext& /*ast_context*/) {
@@ -42,7 +42,7 @@
   // TODO(mboehme): Extract lifetime annotations from `attrs` if present.
 
   // No lifetime annotations: Use elided lifetimes.
-  for (int i = 0; i < num_expected; ++i) {
+  for (size_t i = 0; i < num_expected; ++i) {
     llvm::Expected<Lifetime> maybe_lifetime = elided_lifetime_factory();
     if (maybe_lifetime) {
       lifetimes.push_back(maybe_lifetime.get());
@@ -62,6 +62,18 @@
 
   llvm::SmallVector<const clang::Attr*> attrs;
 
+  size_t num_lifetime_params = GetLifetimeParameters(type).size();
+  if (num_lifetime_params > 0) {
+    llvm::Expected<llvm::SmallVector<Lifetime>> maybe_lifetime_args =
+        GetAnnotatedOrElidedLifetimes(attrs, num_lifetime_params, symbol_table,
+                                      elided_lifetime_factory, ast_context);
+    if (maybe_lifetime_args) {
+      lifetimes.append(maybe_lifetime_args.get());
+    } else {
+      return maybe_lifetime_args.takeError();
+    }
+  }
+
   const llvm::ArrayRef<clang::TemplateArgument> template_args =
       GetTemplateArgs(type);
   if (!template_args.empty()) {
diff --git a/lifetime_annotations/lifetime_annotations_test.cc b/lifetime_annotations/lifetime_annotations_test.cc
index 040cd05..d70253b 100644
--- a/lifetime_annotations/lifetime_annotations_test.cc
+++ b/lifetime_annotations/lifetime_annotations_test.cc
@@ -173,6 +173,15 @@
               IsOkAndHolds(LifetimesAre({{"f", "a -> a"}, {"g", "a -> a"}})));
 }
 
+TEST_F(LifetimeAnnotationsTest, LifetimeElision_LifetimeParameterizedType) {
+  EXPECT_THAT(GetNamedLifetimeAnnotations(R"(
+        #pragma clang lifetime_elision
+        struct [[clang::annotate("lifetime_params", "s")]] string_view{};
+        string_view f(string_view);
+  )"),
+              IsOkAndHolds(LifetimesAre({{"f", "a -> a"}})));
+}
+
 TEST_F(LifetimeAnnotationsTest, LifetimeElision_Method) {
   EXPECT_THAT(GetNamedLifetimeAnnotations(R"(
         #pragma clang lifetime_elision