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 #include "repr/ir_dumper.h"
16 
17 #include "repr/json/api.h"
18 #include "repr/protobuf/api.h"
19 
20 #include <algorithm>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include <llvm/Support/raw_ostream.h>
26 
27 
28 namespace header_checker {
29 namespace repr {
30 
31 
CreateIRDumper(TextFormatIR text_format,const std::string & dump_path)32 std::unique_ptr<IRDumper> IRDumper::CreateIRDumper(
33     TextFormatIR text_format, const std::string &dump_path) {
34   switch (text_format) {
35     case TextFormatIR::ProtobufTextFormat:
36       return CreateProtobufIRDumper(dump_path);
37     case TextFormatIR::Json:
38       return CreateJsonIRDumper(dump_path);
39     default:
40       llvm::errs() << "Text format not supported yet\n";
41       return nullptr;
42   }
43 }
44 
45 
46 // TODO: Replace AbiElementMap key with linker_set_key and use the natural
47 // ordering.
48 template <typename T>
SortAbiElements(const AbiElementMap<T> & m)49 static std::vector<const T *> SortAbiElements(const AbiElementMap<T> &m) {
50   std::vector<const T *> xs;
51 
52   xs.reserve(m.size());
53   for (auto &&item : m) {
54     xs.push_back(&item.second);
55   }
56 
57   auto &&compare = [](const T *lhs, const T *rhs) {
58     return lhs->GetLinkerSetKey() < rhs->GetLinkerSetKey();
59   };
60   std::stable_sort(xs.begin(), xs.end(), compare);
61 
62   return xs;
63 }
64 
65 
DumpModule(const ModuleIR & module)66 bool IRDumper::DumpModule(const ModuleIR &module) {
67   for (auto &&item : SortAbiElements(module.GetFunctions())) {
68     AddLinkableMessageIR(item);
69   }
70   for (auto &&item : SortAbiElements(module.GetGlobalVariables())) {
71     AddLinkableMessageIR(item);
72   }
73   for (auto &&item : SortAbiElements(module.GetRecordTypes())) {
74     AddLinkableMessageIR(item);
75   }
76   for (auto &&item : SortAbiElements(module.GetFunctionTypes())) {
77     AddLinkableMessageIR(item);
78   }
79   for (auto &&item : SortAbiElements(module.GetEnumTypes())) {
80     AddLinkableMessageIR(item);
81   }
82   for (auto &&item : SortAbiElements(module.GetLvalueReferenceTypes())) {
83     AddLinkableMessageIR(item);
84   }
85   for (auto &&item : SortAbiElements(module.GetRvalueReferenceTypes())) {
86     AddLinkableMessageIR(item);
87   }
88   for (auto &&item : SortAbiElements(module.GetQualifiedTypes())) {
89     AddLinkableMessageIR(item);
90   }
91   for (auto &&item : SortAbiElements(module.GetArrayTypes())) {
92     AddLinkableMessageIR(item);
93   }
94   for (auto &&item : SortAbiElements(module.GetPointerTypes())) {
95     AddLinkableMessageIR(item);
96   }
97   for (auto &&item : SortAbiElements(module.GetBuiltinTypes())) {
98     AddLinkableMessageIR(item);
99   }
100   for (auto &&item : module.GetElfFunctions()) {
101     AddElfSymbolMessageIR(&item.second);
102   }
103   for (auto &&item : module.GetElfObjects()) {
104     AddElfSymbolMessageIR(&item.second);
105   }
106   return true;
107 }
108 
109 
110 }  // namespace repr
111 }  // header_checker
112