1 // Copyright (C) 2016 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 "abi_diff_wrappers.h"
16
17 #pragma clang diagnostic push
18 #pragma clang diagnostic ignored "-Wunused-parameter"
19 #pragma clang diagnostic ignored "-Wnested-anon-types"
20 #include "proto/abi_dump.pb.h"
21 #include "proto/abi_diff.pb.h"
22 #pragma clang diagnostic pop
23
24 #include <memory>
25 #include <fstream>
26 #include <iostream>
27 #include <string>
28 #include <vector>
29
30
31 typedef abi_diff::CompatibilityStatus CompatibilityStatus;
32
33 class HeaderAbiDiff {
34 public:
HeaderAbiDiff(const std::string & lib_name,const std::string & arch,const std::string & old_dump,const std::string & new_dump,const std::string & compatibility_report,const std::set<std::string> & ignored_symbols)35 HeaderAbiDiff(const std::string &lib_name, const std::string &arch,
36 const std::string &old_dump, const std::string &new_dump,
37 const std::string &compatibility_report,
38 const std::set<std::string> &ignored_symbols)
39 : lib_name_(lib_name), arch_(arch), old_dump_(old_dump),
40 new_dump_(new_dump), cr_(compatibility_report),
41 ignored_symbols_(ignored_symbols) { }
42
43 CompatibilityStatus GenerateCompatibilityReport();
44
45 private:
46 CompatibilityStatus CompareTUs(const abi_dump::TranslationUnit &old_tu,
47 const abi_dump::TranslationUnit &new_tu);
48 // Collect* methods fill in the diff_tu.
49 template <typename T, typename TDiff>
50 static CompatibilityStatus Collect(
51 google::protobuf::RepeatedPtrField<T> *elements_added,
52 google::protobuf::RepeatedPtrField<T> *elements_removed,
53 google::protobuf::RepeatedPtrField<TDiff> *elements_diff,
54 const google::protobuf::RepeatedPtrField<T> &old_srcs,
55 const google::protobuf::RepeatedPtrField<T> &new_srcs,
56 const std::set<std::string> &ignored_symbols);
57
58 template <typename T>
59 static inline void AddToMap(std::map<std::string, const T *> *dst,
60 const google::protobuf::RepeatedPtrField<T> &src);
61
62 template <typename T>
63 static bool PopulateRemovedElements(
64 google::protobuf::RepeatedPtrField<T> *dst,
65 const std::map<std::string, const T *> &old_elements_map,
66 const std::map<std::string, const T *> &new_elements_map,
67 const std::set<std::string> &ignored_symbols);
68
69 template <typename T, typename TDiff>
70 static bool PopulateCommonElements(
71 google::protobuf::RepeatedPtrField<TDiff> *dst,
72 const std::map<std::string, const T *> &old_elements_map,
73 const std::map<std::string, const T *> &new_elements_map,
74 const std::set<std::string> &ignored_symbols);
75
76 template <typename T, typename TDiff>
77 static bool DumpDiffElements(
78 google::protobuf::RepeatedPtrField<TDiff> *dst,
79 std::vector<std::pair<const T *, const T *>> &pairs,
80 const std::set<std::string> &ignored_symbols);
81
82 template <typename T>
83 static bool DumpLoneElements(google::protobuf::RepeatedPtrField<T> *dst,
84 std::vector<const T *> &elements,
85 const std::set<std::string> &ignored_symbols);
86
87 private:
88 const std::string &lib_name_;
89 const std::string &arch_;
90 const std::string &old_dump_;
91 const std::string &new_dump_;
92 const std::string &cr_;
93 const std::set<std::string> &ignored_symbols_;
94 };
95
96 template <typename T>
AddToMap(std::map<std::string,const T * > * dst,const google::protobuf::RepeatedPtrField<T> & src)97 inline void HeaderAbiDiff::AddToMap(
98 std::map<std::string, const T *> *dst,
99 const google::protobuf::RepeatedPtrField<T> &src) {
100 for (auto &&element : src) {
101 dst->insert(std::make_pair(element.basic_abi().linker_set_key(), &element));
102 }
103 }
104
105 static inline CompatibilityStatus operator|(CompatibilityStatus f,
106 CompatibilityStatus s) {
107 return static_cast<CompatibilityStatus>(
108 static_cast<std::underlying_type<CompatibilityStatus>::type>(f) |
109 static_cast<std::underlying_type<CompatibilityStatus>::type>(s));
110 }
111
112 static inline CompatibilityStatus operator&(
113 CompatibilityStatus f, CompatibilityStatus s) {
114 return static_cast<CompatibilityStatus>(
115 static_cast<std::underlying_type<CompatibilityStatus>::type>(f) &
116 static_cast<std::underlying_type<CompatibilityStatus>::type>(s));
117 }
118