xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/tools/clang_generator/emitter.h (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2020 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_H_
16 #define SANDBOXED_API_TOOLS_CLANG_GENERATOR_EMITTER_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 #include "sandboxed_api/tools/clang_generator/types.h"
30 
31 namespace sapi {
32 namespace internal {
33 
34 absl::StatusOr<std::string> ReformatGoogleStyle(const std::string& filename,
35                                                 const std::string& code,
36                                                 int column_limit = -1);
37 
38 }  // namespace internal
39 
40 class GeneratorOptions;
41 
42 class RenderedType {
43  public:
RenderedType(std::string ns_name,std::string spelling)44   RenderedType(std::string ns_name, std::string spelling)
45       : ns_name(std::move(ns_name)), spelling(std::move(spelling)) {}
46 
47   bool operator==(const RenderedType& other) const {
48     return ns_name == other.ns_name && spelling == other.spelling;
49   }
50 
51   template <typename H>
AbslHashValue(H h,RenderedType rt)52   friend H AbslHashValue(H h, RenderedType rt) {
53     return H::combine(std::move(h), rt.ns_name, rt.spelling);
54   }
55 
56   std::string ns_name;
57   std::string spelling;
58 };
59 
60 // Responsible for emitting the actual textual representation of the generated
61 // Sandboxed API header.
62 class Emitter {
63  public:
64   // Adds the declarations of previously collected types to the emitter,
65   // recording the spelling of each one. Types/declarations that are not
66   // supported by the current generator settings or that are unwanted or
67   // unnecessary are skipped. Other filtered types include C++ constructs or
68   // well-known standard library elements. The latter can be replaced by
69   // including the correct headers in the emitted header.
70   void AddTypeDeclarations(const std::vector<clang::TypeDecl*>& type_decls);
71 
72   absl::Status AddFunction(clang::FunctionDecl* decl);
73 
74   // Outputs a formatted header for a list of functions and their related types.
75   absl::StatusOr<std::string> EmitHeader(const GeneratorOptions& options);
76 
77  private:
78   void EmitType(clang::TypeDecl* type_decl);
79 
80  protected:
81   // Stores namespaces and a list of spellings for types. Keeps track of types
82   // that have been rendered so far. Using a node_hash_set for pointer
83   // stability.
84   absl::node_hash_set<RenderedType> rendered_types_;
85 
86   // A vector to preserve the order of type declarations needs to be preserved.
87   std::vector<const RenderedType*> rendered_types_ordered_;
88 
89   // Fully qualified names of functions for the sandboxed API. Keeps track of
90   // functions that have been rendered so far.
91   absl::flat_hash_set<std::string> rendered_functions_;
92 
93   // Rendered function bodies, as a vector to preserve source order. This is
94   // not strictly necessary, but makes the output look less surprising.
95   std::vector<std::string> rendered_functions_ordered_;
96 };
97 
98 // Constructs an include guard name for the given filename. The name is of the
99 // same form as the include guards in this project and conforms to the Google
100 // C++ style. For example,
101 //   sandboxed_api/examples/zlib/zlib-sapi.sapi.h
102 // will be mapped to
103 //   SANDBOXED_API_EXAMPLES_ZLIB_ZLIB_SAPI_SAPI_H_
104 std::string GetIncludeGuard(absl::string_view filename);
105 
106 }  // namespace sapi
107 
108 #endif  // SANDBOXED_API_TOOLS_CLANG_GENERATOR_EMITTER_H_
109