blob: cc9ce0dc664abd416d481fca0907379e23413fd0 [file] [log] [blame]
Luca Versari99fddff2022-05-25 10:22:32 -07001// Part of the Crubit project, under the Apache License v2.0 with LLVM
2// Exceptions. See /LICENSE for license information.
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#include "lifetime_analysis/builtin_lifetimes.h"
6
7#include <optional>
8#include <string>
9
10#include "absl/strings/str_cat.h"
11#include "lifetime_annotations/function_lifetimes.h"
12#include "lifetime_annotations/lifetime.h"
13#include "lifetime_annotations/lifetime_annotations.h"
14#include "lifetime_annotations/type_lifetimes.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/Type.h"
18#include "clang/Basic/Builtins.h"
19#include "llvm/ADT/StringRef.h"
20
21namespace clang {
22namespace tidy {
23namespace lifetimes {
24
25namespace {
26
27class ForwardAndMoveFactory : public FunctionLifetimeFactory {
Martin Brænne1c097f22022-06-23 01:14:09 -070028 llvm::Expected<ValueLifetimes> CreateThisLifetimes(
29 clang::QualType type, const clang::Expr*) const override {
30 return CreateParamLifetimes(type, clang::TypeLoc());
31 }
Luca Versari99fddff2022-05-25 10:22:32 -070032 llvm::Expected<ValueLifetimes> CreateParamLifetimes(
Martin Brænne712b7f42022-06-23 00:55:17 -070033 clang::QualType type, clang::TypeLoc) const override {
Martin Brænne03d93302022-06-23 00:23:38 -070034 return ValueLifetimes::Create(
35 type, [](const clang::Expr*) { return Lifetime::CreateVariable(); });
Luca Versari99fddff2022-05-25 10:22:32 -070036 }
37
38 llvm::Expected<ValueLifetimes> CreateReturnLifetimes(
Martin Brænne712b7f42022-06-23 00:55:17 -070039 clang::QualType type, clang::TypeLoc,
Luca Versari99fddff2022-05-25 10:22:32 -070040 const llvm::SmallVector<ValueLifetimes>& param_lifetimes,
41 const std::optional<ValueLifetimes>& /*this_lifetimes*/) const override {
42 assert(param_lifetimes.size() == 1);
43 // `forward` and `move` convert from one type of reference to the other; the
44 // lifetimes in the pointees of these references are the same.
45 return ValueLifetimes::ForPointerLikeType(
46 type, param_lifetimes[0].GetPointeeLifetimes());
47 }
48};
49
50} // namespace
51
52FunctionLifetimesOrError GetBuiltinLifetimes(const clang::FunctionDecl* decl) {
53 unsigned builtin_id = decl->getBuiltinID();
54 const auto& builtin_info = decl->getASTContext().BuiltinInfo;
55 assert(builtin_id != 0);
56
57 if (!builtin_info.hasPtrArgsOrResult(builtin_id) &&
58 !builtin_info.hasReferenceArgsOrResult(builtin_id)) {
59 return FunctionLifetimes::CreateForDecl(
Martin Brænne03d93302022-06-23 00:23:38 -070060 decl,
61 FunctionLifetimeFactorySingleCallback([](const clang::Expr*) {
Martin Brænnebcdfe322022-06-23 00:13:55 -070062 assert(false);
63 return Lifetime();
64 }))
Luca Versari99fddff2022-05-25 10:22:32 -070065 .get();
66 }
67 switch (builtin_id) {
68 case clang::Builtin::BI__builtin_addressof:
69 return ParseLifetimeAnnotations(decl, "a -> a").get();
70 case clang::Builtin::BIstrtod:
71 case clang::Builtin::BIstrtof:
72 return ParseLifetimeAnnotations(decl, "a, (a, b)").get();
73 case clang::Builtin::BIstrtoll:
74 case clang::Builtin::BIstrtol:
75 return ParseLifetimeAnnotations(decl, "a, (a, b), ()").get();
76 case clang::Builtin::BI__builtin_memchr:
77 return ParseLifetimeAnnotations(decl, "a, (), () -> a").get();
78 case clang::Builtin::BI__builtin_strchr:
79 case clang::Builtin::BI__builtin_strrchr:
80 return ParseLifetimeAnnotations(decl, "a, () -> a").get();
81 case clang::Builtin::BI__builtin_strstr:
82 case clang::Builtin::BI__builtin_strpbrk:
83 return ParseLifetimeAnnotations(decl, "a, b -> a").get();
84 case clang::Builtin::BIforward:
85 case clang::Builtin::BImove: {
86 FunctionLifetimes result;
87 return FunctionLifetimes::CreateForDecl(decl, ForwardAndMoveFactory())
88 .get();
89 }
90 // TODO(veluca): figure out variadic functions.
91 default:
Googler4273a7b2022-12-27 20:29:27 -080092 return FunctionAnalysisError(
93 ("Unknown builtin: '" + builtin_info.getName(builtin_id) + "'")
94 .str());
Luca Versari99fddff2022-05-25 10:22:32 -070095 }
96}
97
98} // namespace lifetimes
99} // namespace tidy
100} // namespace clang