Home | History | Annotate | Download | only in src
      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 #include <header_abi_util.h>
     18 
     19 #include <llvm/Support/raw_ostream.h>
     20 
     21 namespace abi_diff_wrappers {
     22 
     23 using abi_util::AbiElementMap;
     24 using abi_util::DiffStatus;
     25 using abi_util::Unwind;
     26 
     27 template <>
     28 bool DiffWrapper<abi_util::RecordTypeIR>::DumpDiff(
     29     abi_util::DiffMessageIR::DiffKind diff_kind) {
     30   std::deque<std::string> type_queue;
     31   if (oldp_->GetUniqueId() != newp_->GetUniqueId()) {
     32     llvm::errs() << "Comparing two different unreferenced records\n";
     33     return false;
     34   }
     35   if (!type_cache_->insert(
     36       oldp_->GetSelfType() + newp_->GetSelfType()).second) {
     37     return true;
     38   }
     39   CompareRecordTypes(oldp_, newp_, &type_queue, diff_kind);
     40   return true;
     41 }
     42 
     43 template <>
     44 bool DiffWrapper<abi_util::EnumTypeIR>::DumpDiff(
     45     abi_util::DiffMessageIR::DiffKind diff_kind) {
     46   std::deque<std::string> type_queue;
     47   if (oldp_->GetUniqueId() != newp_->GetUniqueId()) {
     48     llvm::errs() << "Comparing two different unreferenced enums\n";
     49     return false;
     50   }
     51   if (!type_cache_->insert(
     52       oldp_->GetSelfType() + newp_->GetSelfType()).second) {
     53     return true;
     54   }
     55   CompareEnumTypes(oldp_, newp_, &type_queue, diff_kind);
     56   return true;
     57 }
     58 
     59 template <>
     60 bool DiffWrapper<abi_util::GlobalVarIR>::DumpDiff(
     61     abi_util::DiffMessageIR::DiffKind diff_kind) {
     62   std::deque<std::string> type_queue;
     63   type_queue.push_back(oldp_->GetName());
     64   DiffStatus type_diff = CompareAndDumpTypeDiff(oldp_->GetReferencedType(),
     65                                                 newp_->GetReferencedType(),
     66                                                 &type_queue, diff_kind);
     67   DiffStatus access_diff = (oldp_->GetAccess() == newp_->GetAccess()) ?
     68       DiffStatus::no_diff : DiffStatus::direct_diff;
     69   if ((type_diff | access_diff) & DiffStatus::direct_diff) {
     70     abi_util::GlobalVarIR old_global_var = *oldp_;
     71     abi_util::GlobalVarIR new_global_var = *newp_;
     72     ReplaceTypeIdsWithTypeNames(old_types_, &old_global_var);
     73     ReplaceTypeIdsWithTypeNames(new_types_, &new_global_var);
     74     abi_util::GlobalVarDiffIR global_var_diff_ir(&old_global_var,
     75                                                  &new_global_var);
     76     global_var_diff_ir.SetName(oldp_->GetName());
     77     return ir_diff_dumper_->AddDiffMessageIR(&global_var_diff_ir,
     78                                              Unwind(&type_queue), diff_kind);
     79   }
     80   return true;
     81 }
     82 
     83 template <>
     84 bool DiffWrapper<abi_util::FunctionIR>::DumpDiff(
     85     abi_util::DiffMessageIR::DiffKind diff_kind) {
     86   std::deque<std::string> type_queue;
     87   type_queue.push_back(oldp_->GetName());
     88   DiffStatus param_diffs = CompareFunctionParameters(oldp_->GetParameters(),
     89                                                      newp_->GetParameters(),
     90                                                      &type_queue, diff_kind);
     91   DiffStatus return_type_diff =
     92       CompareAndDumpTypeDiff(oldp_->GetReturnType(),
     93                              newp_->GetReturnType(),
     94                              &type_queue, diff_kind);
     95   CompareTemplateInfo(oldp_->GetTemplateElements(),
     96                       newp_->GetTemplateElements(),
     97                       &type_queue, diff_kind);
     98 
     99   if ((param_diffs == DiffStatus::direct_diff ||
    100        return_type_diff == DiffStatus::direct_diff) ||
    101       (oldp_->GetAccess() != newp_->GetAccess())) {
    102     abi_util::FunctionIR old_function = *oldp_;
    103     abi_util::FunctionIR new_function = *newp_;
    104     ReplaceTypeIdsWithTypeNames(old_types_, &old_function);
    105     ReplaceTypeIdsWithTypeNames(new_types_, &new_function);
    106     abi_util::FunctionDiffIR function_diff_ir(&old_function, &new_function);
    107     function_diff_ir.SetName(oldp_->GetName());
    108     return ir_diff_dumper_->AddDiffMessageIR(&function_diff_ir,
    109                                              Unwind(&type_queue), diff_kind);
    110   }
    111   return true;
    112 }
    113 
    114 } // abi_diff_wrappers
    115