• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SANDBOXED_API_TOOLS_CLANG_GENERATOR_EMITTER_BASE_H_
16 #define SANDBOXED_API_TOOLS_CLANG_GENERATOR_EMITTER_BASE_H_
17 
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "absl/container/flat_hash_set.h"
23 #include "absl/container/node_hash_set.h"
24 #include "absl/status/status.h"
25 #include "absl/status/statusor.h"
26 #include "absl/strings/string_view.h"
27 #include "clang/AST/Decl.h"
28 #include "clang/AST/Type.h"
29 
30 namespace sapi {
31 // TODO b/347118045 - Refactor the naming of internal namespaces across the
32 // codebase.
33 namespace internal {
34 
35 // Returns a string of the specified code reformatted to conform to the Google
36 // style.
37 // Ill-formed code will return an error status.
38 absl::StatusOr<std::string> ReformatGoogleStyle(const std::string& filename,
39                                                 const std::string& code,
40                                                 int column_limit = -1);
41 
42 }  // namespace internal
43 
44 // Text template arguments:
45 //   1. Namespace name
46 inline constexpr absl::string_view kNamespaceBeginTemplate =
47     R"(
48 namespace %1$s {
49 
50 )";
51 
52 // Text template arguments:
53 //   1. Namespace name
54 inline constexpr absl::string_view kNamespaceEndTemplate =
55     R"(
56 }  // namespace %1$s
57 )";
58 
59 // Text template arguments:
60 //   1. Header guard
61 inline constexpr absl::string_view kHeaderProlog =
62     R"(
63 #ifndef %1$s
64 #define %1$s
65 
66 )";
67 
68 // Text template arguments:
69 //   1. Header guard
70 inline constexpr absl::string_view kHeaderEpilog =
71     R"(
72 #endif  // %1$s)";
73 
74 class RenderedType {
75  public:
RenderedType(std::string ns_name,std::string spelling)76   RenderedType(std::string ns_name, std::string spelling)
77       : ns_name(std::move(ns_name)), spelling(std::move(spelling)) {}
78 
79   bool operator==(const RenderedType& other) const {
80     return ns_name == other.ns_name && spelling == other.spelling;
81   }
82 
83   template <typename H>
AbslHashValue(H h,RenderedType rt)84   friend H AbslHashValue(H h, RenderedType rt) {
85     return H::combine(std::move(h), rt.ns_name, rt.spelling);
86   }
87 
88   std::string ns_name;
89   std::string spelling;
90 };
91 
92 class EmitterBase {
93  public:
94   virtual ~EmitterBase() = default;
95 
96   // Adds the declarations of previously collected types to the emitter,
97   // recording the spelling of each one. Types/declarations that are not
98   // supported by the current generator settings or that are unwanted or
99   // unnecessary are skipped. Other filtered types include C++ constructs or
100   // well-known standard library elements. The latter can be replaced by
101   // including the correct headers in the emitted header.
102   void AddTypeDeclarations(const std::vector<clang::TypeDecl*>& type_decls);
103 
104   // Adds the declarations of previously collected functions to the emitter.
105   virtual absl::Status AddFunction(clang::FunctionDecl* decl) = 0;
106 
107   // Stores namespaces and a list of spellings for types. Keeps track of types
108   // that have been rendered so far. Using a node_hash_set for pointer
109   // stability.
110   absl::node_hash_set<RenderedType> rendered_types_;
111 
112   // A vector to preserve the order of type declarations needs to be preserved.
113   std::vector<const RenderedType*> rendered_types_ordered_;
114 
115   // Fully qualified names of functions for the sandboxed API. Keeps track of
116   // functions that have been rendered so far.
117   absl::flat_hash_set<std::string> rendered_functions_;
118 
119  private:
120   void EmitType(clang::TypeDecl* type_decl);
121 };
122 
123 // Constructs an include guard for the given filename. The generated string
124 // conforms to the Google C++ style. For example,
125 //   sandboxed_api/examples/zlib/zlib-sapi.sapi.h
126 // will be mapped to
127 //   SANDBOXED_API_EXAMPLES_ZLIB_ZLIB_SAPI_SAPI_H_
128 std::string GetIncludeGuard(absl::string_view filename);
129 
130 }  // namespace sapi
131 
132 #endif  // SANDBOXED_API_TOOLS_CLANG_GENERATOR_EMITTER_BASE_H_
133