blob: e7556ad371cddbdee328ff42cdef5c09e5acc5d7 [file] [log] [blame]
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +00001// 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
Dmitri Gribenkoe4e77d02022-03-17 14:09:39 +00005#ifndef CRUBIT_RS_BINDINGS_FROM_CC_IMPORTER_H_
6#define CRUBIT_RS_BINDINGS_FROM_CC_IMPORTER_H_
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +00007
Marcel Hlopko7d739792021-08-12 07:52:47 +00008#include <memory>
Marcel Hlopko20f4ce42021-11-02 08:20:00 +00009#include <optional>
Lukasz Anforowicz49b5bbc2022-02-04 23:40:10 +000010#include <set>
Marcel Hlopkof1123c82021-08-19 11:38:52 +000011#include <string>
Marcel Hlopko20f4ce42021-11-02 08:20:00 +000012#include <utility>
Marcel Hlopko20f4ce42021-11-02 08:20:00 +000013#include <vector>
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +000014
Michael Forsterb3503e02022-04-25 00:24:14 -070015#include "rs_bindings_from_cc/decl_importer.h"
16#include "rs_bindings_from_cc/importers/class_template.h"
Michael Forsterc0bc9262022-04-25 00:30:26 -070017#include "rs_bindings_from_cc/importers/cxx_record.h"
Michael Forster4fa849d2022-04-25 00:32:59 -070018#include "rs_bindings_from_cc/importers/enum.h"
Michael Forster7e4244a2022-04-25 00:39:01 -070019#include "rs_bindings_from_cc/importers/function.h"
Michael Forster350d5312022-04-25 00:36:31 -070020#include "rs_bindings_from_cc/importers/function_template.h"
Michael Forster284fb5a2022-04-25 00:41:14 -070021#include "rs_bindings_from_cc/importers/namespace.h"
Michael Forsterc60df1e2022-04-25 00:55:44 -070022#include "rs_bindings_from_cc/importers/typedef_name.h"
Marcel Hlopko3b254b32022-03-09 14:10:49 +000023#include "rs_bindings_from_cc/ir.h"
Lukasz Anforowiczcec7a8a2022-04-27 10:24:51 -070024#include "clang/AST/Mangle.h"
Rosica Dejanovska2708a5f2022-06-22 06:54:59 -070025#include "clang/AST/RawCommentList.h"
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +000026
Marcel Hlopkof15e8ce2022-04-08 08:46:09 -070027namespace crubit {
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +000028
Michael Forster64217b42022-04-22 05:48:54 -070029// Iterates over the AST created from the invocation's entry headers and
30// creates an intermediate representation of the import (`IR`) into the
31// invocation object.
32class Importer : public ImportContext {
33 public:
34 explicit Importer(Invocation& invocation, clang::ASTContext& ctx,
35 clang::Sema& sema)
36 : ImportContext(invocation, ctx, sema),
37 mangler_(CRUBIT_DIE_IF_NULL(ctx_.createMangleContext())) {
38 decl_importers_.push_back(
39 std::make_unique<ClassTemplateDeclImporter>(*this));
40 decl_importers_.push_back(std::make_unique<CXXRecordDeclImporter>(*this));
41 decl_importers_.push_back(std::make_unique<EnumDeclImporter>(*this));
42 decl_importers_.push_back(std::make_unique<FunctionDeclImporter>(*this));
43 decl_importers_.push_back(
44 std::make_unique<FunctionTemplateDeclImporter>(*this));
45 decl_importers_.push_back(std::make_unique<NamespaceDeclImporter>(*this));
46 decl_importers_.push_back(std::make_unique<TypedefNameDeclImporter>(*this));
47 }
48
49 // Import all visible declarations from a translation unit.
50 void Import(clang::TranslationUnitDecl* decl);
51
52 protected:
53 // Implementation of `ImportContext`
54 void ImportDeclsFromDeclContext(
55 const clang::DeclContext* decl_context) override;
56 IR::Item ImportUnsupportedItem(const clang::Decl* decl,
57 std::string error) override;
58 IR::Item ImportUnsupportedItem(const clang::Decl* decl,
59 std::set<std::string> errors) override;
60 std::vector<ItemId> GetItemIdsInSourceOrder(clang::Decl* decl) override;
61 std::string GetMangledName(const clang::NamedDecl* named_decl) const override;
62 BazelLabel GetOwningTarget(const clang::Decl* decl) const override;
63 bool IsFromCurrentTarget(const clang::Decl* decl) const override;
64 std::optional<UnqualifiedIdentifier> GetTranslatedName(
65 const clang::NamedDecl* named_decl) const override;
Devin Jeanpierref2ec8712021-10-13 20:47:16 +000066 std::optional<Identifier> GetTranslatedIdentifier(
Michael Forster64217b42022-04-22 05:48:54 -070067 const clang::NamedDecl* named_decl) const override {
Devin Jeanpierref2ec8712021-10-13 20:47:16 +000068 if (std::optional<UnqualifiedIdentifier> name =
69 GetTranslatedName(named_decl)) {
70 return std::move(*std::get_if<Identifier>(&*name));
71 }
72 return std::nullopt;
73 }
Michael Forster64217b42022-04-22 05:48:54 -070074 llvm::Optional<std::string> GetComment(
75 const clang::Decl* decl) const override;
76 SourceLoc ConvertSourceLocation(clang::SourceLocation loc) const override;
Lukasz Anforowicz63559d32022-05-27 16:42:36 -070077 absl::StatusOr<MappedType> ConvertQualType(
78 clang::QualType qual_type,
79 std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
Lukasz Anforowicz14732b22022-06-02 09:11:08 -070080 bool nullable = true) override;
Lukasz Anforowicz0233f982022-05-27 16:38:20 -070081 void MarkAsSuccessfullyImported(const clang::TypeDecl* decl) override;
Lukasz Anforowicz5258f762022-05-27 16:14:46 -070082 bool HasBeenAlreadySuccessfullyImported(
83 const clang::TypeDecl* decl) const override;
Devin Jeanpierref2ec8712021-10-13 20:47:16 +000084
Michael Forster64217b42022-04-22 05:48:54 -070085 private:
Rosica Dejanovska2708a5f2022-06-22 06:54:59 -070086 class SourceOrderKey;
87 class SourceLocationComparator;
88
89 // Returns a SourceOrderKey for the given `decl` that should be used for
90 // ordering Items.
91 SourceOrderKey GetSourceOrderKey(const clang::Decl* decl) const;
92 // Returns a SourceOrderKey for the given `comment` that should be used for
93 // ordering Items.
94 SourceOrderKey GetSourceOrderKey(const clang::RawComment* comment) const;
95
96 // Returns a name for `decl` that should be used for ordering declarations.
97 std::string GetNameForSourceOrder(const clang::Decl* decl) const;
98
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -070099 // Returns the item ids of template instantiations that have been triggered
100 // from the current target. The returned items are in an arbitrary,
101 // deterministic/reproducible order.
102 std::vector<ItemId> GetOrderedItemIdsOfTemplateInstantiations() const;
103
Michael Forster64217b42022-04-22 05:48:54 -0700104 // Returns the Item of a Decl, importing it first if necessary.
105 std::optional<IR::Item> GetDeclItem(clang::Decl* decl);
Googler4e1bc132021-12-06 10:10:42 +0000106
Michael Forster64217b42022-04-22 05:48:54 -0700107 // Imports a decl and creates an IR item (or error messages).
108 // Does not use or update the cache.
109 std::optional<IR::Item> ImportDecl(clang::Decl* decl);
Marcel Hlopko3df72542021-11-30 09:38:36 +0000110
Michael Forster64217b42022-04-22 05:48:54 -0700111 // Stores the comments of this target in source order.
112 void ImportFreeComments();
Googler6c3de122022-03-28 11:40:41 +0000113
Lukasz Anforowicz63559d32022-05-27 16:42:36 -0700114 absl::StatusOr<MappedType> ConvertType(
115 const clang::Type* type,
116 std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
Lukasz Anforowicz14732b22022-06-02 09:11:08 -0700117 bool nullable);
Lukasz Anforowicz63559d32022-05-27 16:42:36 -0700118 absl::StatusOr<MappedType> ConvertTypeDecl(const clang::TypeDecl* decl) const;
119
Lukasz Anforowicz14732b22022-06-02 09:11:08 -0700120 // Converts `type` into a MappedType, after first importing the Record behind
121 // the template instantiation.
122 absl::StatusOr<MappedType> ConvertTemplateSpecializationType(
123 const clang::TemplateSpecializationType* type);
124
Michael Forster64217b42022-04-22 05:48:54 -0700125 std::vector<std::unique_ptr<DeclImporter>> decl_importers_;
Marcel Hlopko7d739792021-08-12 07:52:47 +0000126 std::unique_ptr<clang::MangleContext> mangler_;
Lukasz Anforowicz06f76b12022-03-23 13:48:39 +0000127 absl::flat_hash_map<const clang::Decl*, std::optional<IR::Item>>
128 import_cache_;
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -0700129 absl::flat_hash_set<const clang::ClassTemplateSpecializationDecl*>
130 class_template_instantiations_for_current_target_;
Rosica Dejanovskab2bd59e2022-04-11 09:02:03 -0700131 std::vector<const clang::RawComment*> comments_;
Lukasz Anforowicz23fdfad2022-05-27 16:43:43 -0700132
133 // Set of decls that have been successfully imported (i.e. that will be
134 // present in the IR output / that will not produce dangling ItemIds in the IR
135 // output).
136 absl::flat_hash_set<const clang::TypeDecl*> known_type_decls_;
Michael Forstera49d2e62022-01-28 07:26:40 +0000137}; // class Importer
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +0000138
Marcel Hlopkof15e8ce2022-04-08 08:46:09 -0700139} // namespace crubit
Marcel Hlopkoe8f1c4e2021-07-28 18:12:49 +0000140
Dmitri Gribenkoe4e77d02022-03-17 14:09:39 +0000141#endif // CRUBIT_RS_BINDINGS_FROM_CC_IMPORTER_H_