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 "diff/abi_diff_wrappers.h"
16 
17 #include "utils/header_abi_util.h"
18 
19 #include <llvm/Support/raw_ostream.h>
20 
21 
22 namespace header_checker {
23 namespace diff {
24 
25 
26 using repr::AbiElementMap;
27 using repr::DiffStatus;
28 using repr::TypeStackGuard;
29 
30 template <>
DumpDiff(repr::DiffMessageIR::DiffKind diff_kind)31 bool DiffWrapper<repr::RecordTypeIR>::DumpDiff(
32     repr::DiffMessageIR::DiffKind diff_kind) {
33   if (!type_cache_->insert(
34           oldp_->GetSelfType() + newp_->GetSelfType()).second) {
35     return true;
36   }
37   CompareRecordTypes(oldp_, newp_, diff_kind);
38   return true;
39 }
40 
41 template <>
DumpDiff(repr::DiffMessageIR::DiffKind diff_kind)42 bool DiffWrapper<repr::EnumTypeIR>::DumpDiff(
43     repr::DiffMessageIR::DiffKind diff_kind) {
44   if (!type_cache_->insert(
45       oldp_->GetSelfType() + newp_->GetSelfType()).second) {
46     return true;
47   }
48   CompareEnumTypes(oldp_, newp_, diff_kind);
49   return true;
50 }
51 
52 template <>
DumpDiff(repr::DiffMessageIR::DiffKind diff_kind)53 bool DiffWrapper<repr::GlobalVarIR>::DumpDiff(
54     repr::DiffMessageIR::DiffKind diff_kind) {
55   TypeStackGuard guard(type_stack_, oldp_->GetName());
56   DiffStatus type_diff = CompareAndDumpTypeDiff(
57       oldp_->GetReferencedType(), newp_->GetReferencedType(), diff_kind);
58 
59   if (type_diff.IsDirectDiff() || oldp_->GetAccess() != newp_->GetAccess()) {
60     repr::GlobalVarIR old_global_var = *oldp_;
61     repr::GlobalVarIR new_global_var = *newp_;
62     ReplaceTypeIdsWithTypeNames(old_types_, &old_global_var);
63     ReplaceTypeIdsWithTypeNames(new_types_, &new_global_var);
64     repr::GlobalVarDiffIR global_var_diff_ir(&old_global_var,
65                                                  &new_global_var);
66     global_var_diff_ir.SetName(oldp_->GetName());
67     return ir_diff_dumper_->AddDiffMessageIR(&global_var_diff_ir,
68                                              UnwindTypeStack(), diff_kind);
69   }
70   return true;
71 }
72 
73 template <>
DumpDiff(repr::DiffMessageIR::DiffKind diff_kind)74 bool DiffWrapper<repr::FunctionIR>::DumpDiff(
75     repr::DiffMessageIR::DiffKind diff_kind) {
76   TypeStackGuard guard(type_stack_, oldp_->GetName());
77   DiffStatus function_type_diff = CompareFunctionTypes(oldp_, newp_, diff_kind);
78 
79   CompareTemplateInfo(oldp_->GetTemplateElements(),
80                       newp_->GetTemplateElements(), diff_kind);
81 
82   if (function_type_diff.IsDirectDiff() ||
83       (oldp_->GetAccess() != newp_->GetAccess())) {
84     repr::FunctionIR old_function = *oldp_;
85     repr::FunctionIR new_function = *newp_;
86     ReplaceTypeIdsWithTypeNames(old_types_, &old_function);
87     ReplaceTypeIdsWithTypeNames(new_types_, &new_function);
88     repr::FunctionDiffIR function_diff_ir(&old_function, &new_function,
89                                           function_type_diff.IsExtension());
90     function_diff_ir.SetName(oldp_->GetName());
91     return ir_diff_dumper_->AddDiffMessageIR(&function_diff_ir,
92                                              UnwindTypeStack(), diff_kind);
93   }
94   return true;
95 }
96 
97 
98 }  // namespace diff
99 }  // namespace header_checker
100