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