1 // Copyright (C) 2019 The Android Open Source Project
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 //      http://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 HEADER_CHECKER_REPR_JSON_IR_READER_H_
16 #define HEADER_CHECKER_REPR_JSON_IR_READER_H_
17 
18 #include "repr/ir_dumper.h"
19 #include "repr/ir_reader.h"
20 #include "repr/ir_representation.h"
21 
22 #include <json/value.h>
23 
24 
25 namespace header_checker {
26 namespace repr {
27 
28 
29 template <typename T> class JsonArrayRef;
30 
31 // This class loads values from a read-only JSON object.
32 class JsonObjectRef {
33  public:
34   // The constructor sets ok to false if json_value is not an object.
35   JsonObjectRef(const Json::Value &json_value, bool &ok);
36 
37   // This method gets a value from the object and checks the type.
38   // If the type mismatches, it sets ok_ to false and returns default value.
39   // If the key doesn't exist, it doesn't change ok_ and returns default value.
40   // Default to false.
41   bool GetBool(const std::string &key) const;
42 
43   // Default to 0.
44   int64_t GetInt(const std::string &key) const;
45 
46   // Default to 0.
47   uint64_t GetUint(const std::string &key) const;
48 
49   // Default to 0.
50   const Json::Value &GetIntegralValue(const std::string &key) const;
51 
52   // Default to "".
53   std::string GetString(const std::string &key) const;
54 
55   std::string GetString(const std::string &key,
56                         const std::string &default_value) const;
57 
58   // Default to {}.
59   JsonObjectRef GetObject(const std::string &key) const;
60 
61   // Default to [].
62   JsonArrayRef<JsonObjectRef> GetObjects(const std::string &key) const;
63 
64   JsonArrayRef<std::string> GetStrings(const std::string &key) const;
65 
66  private:
67   typedef bool (Json::Value::*IsExpectedJsonType)() const;
68 
69   const Json::Value &Get(const std::string &key,
70                          const Json::Value &default_value,
71                          IsExpectedJsonType is_expected_type) const;
72 
73   const Json::Value &object_;
74   bool &ok_;
75 };
76 
77 // This class loads elements as type T from a read-only JSON array.
78 template <typename T> class JsonArrayRef {
79  public:
80   class Iterator {
81    public:
Iterator(const Json::Value & json_value,bool & ok,int index)82     Iterator(const Json::Value &json_value, bool &ok, int index)
83         : array_(json_value), ok_(ok), index_(index) {}
84 
85     Iterator &operator++() {
86       ++index_;
87       return *this;
88     }
89 
90     bool operator!=(const Iterator &other) const {
91       return index_ != other.index_;
92     }
93 
94     T operator*() const;
95 
96    private:
97     const Json::Value &array_;
98     bool &ok_;
99     int index_;
100   };
101 
102   // The caller ensures json_value.isArray() == true.
JsonArrayRef(const Json::Value & json_value,bool & ok)103   JsonArrayRef(const Json::Value &json_value, bool &ok)
104       : array_(json_value), ok_(ok) {}
105 
begin()106   Iterator begin() const { return Iterator(array_, ok_, 0); }
107 
end()108   Iterator end() const { return Iterator(array_, ok_, array_.size()); }
109 
110  private:
111   const Json::Value &array_;
112   bool &ok_;
113 };
114 
115 template <>
116 JsonObjectRef JsonArrayRef<JsonObjectRef>::Iterator::operator*() const;
117 
118 template <> std::string JsonArrayRef<std::string>::Iterator::operator*() const;
119 
120 class JsonIRReader : public IRReader {
121  public:
JsonIRReader(const std::set<std::string> * exported_headers)122   JsonIRReader(const std::set<std::string> *exported_headers)
123       : IRReader(exported_headers) {}
124 
125  private:
126   bool ReadDumpImpl(const std::string &dump_file) override;
127 
128   void ReadFunctions(const JsonObjectRef &tu);
129 
130   void ReadGlobalVariables(const JsonObjectRef &tu);
131 
132   void ReadEnumTypes(const JsonObjectRef &tu);
133 
134   void ReadRecordTypes(const JsonObjectRef &tu);
135 
136   void ReadFunctionTypes(const JsonObjectRef &tu);
137 
138   void ReadPointerTypes(const JsonObjectRef &tu);
139 
140   void ReadBuiltinTypes(const JsonObjectRef &tu);
141 
142   void ReadQualifiedTypes(const JsonObjectRef &tu);
143 
144   void ReadArrayTypes(const JsonObjectRef &tu);
145 
146   void ReadLvalueReferenceTypes(const JsonObjectRef &tu);
147 
148   void ReadRvalueReferenceTypes(const JsonObjectRef &tu);
149 
150   void ReadElfFunctions(const JsonObjectRef &tu);
151 
152   void ReadElfObjects(const JsonObjectRef &tu);
153 
154   static void ReadTemplateInfo(const JsonObjectRef &type_decl,
155                                TemplatedArtifactIR *template_ir);
156 
157   static void ReadTypeInfo(const JsonObjectRef &type_decl, TypeIR *type_ir);
158 
159   static void ReadRecordFields(const JsonObjectRef &record_type,
160                                RecordTypeIR *record_ir);
161 
162   static void ReadBaseSpecifiers(const JsonObjectRef &record_type,
163                                  RecordTypeIR *record_ir);
164 
165   static void ReadVTableLayout(const JsonObjectRef &record_type,
166                                RecordTypeIR *record_ir);
167 
168   static void ReadEnumFields(const JsonObjectRef &enum_type,
169                              EnumTypeIR *enum_ir);
170 
171   static void ReadFunctionParametersAndReturnType(const JsonObjectRef &function,
172                                                   CFunctionLikeIR *function_ir);
173 
174   static FunctionIR FunctionJsonToIR(const JsonObjectRef &function);
175 
176   static FunctionTypeIR
177   FunctionTypeJsonToIR(const JsonObjectRef &function_type);
178 
179   static RecordTypeIR RecordTypeJsonToIR(const JsonObjectRef &record_type);
180 
181   static EnumTypeIR EnumTypeJsonToIR(const JsonObjectRef &enum_type);
182 };
183 
184 
185 }  // namespace repr
186 }  // namespace header_checker
187 
188 
189 #endif  // HEADER_CHECKER_REPR_JSON_IR_READER_H_
190