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_wrappers.h"
     16 
     17 #include <header_abi_util.h>
     18 
     19 #include <limits.h>
     20 #include <stdlib.h>
     21 #include <clang/Tooling/Core/QualTypeNames.h>
     22 #include <clang/Index/CodegenNameGenerator.h>
     23 
     24 #include <string>
     25 
     26 using namespace abi_wrapper;
     27 
     28 ABIWrapper::ABIWrapper(
     29     clang::MangleContext *mangle_contextp,
     30     clang::ASTContext *ast_contextp,
     31     const clang::CompilerInstance *cip,
     32     abi_util::IRDumper *ir_dumper,
     33     ast_util::ASTCaches *ast_caches)
     34   : cip_(cip),
     35     mangle_contextp_(mangle_contextp),
     36     ast_contextp_(ast_contextp),
     37     ir_dumper_(ir_dumper),
     38     ast_caches_(ast_caches) { }
     39 
     40 std::string ABIWrapper::GetCachedDeclSourceFile(
     41     const clang::Decl *decl, const clang::CompilerInstance *cip) {
     42   assert(decl != nullptr);
     43   auto result = ast_caches_->decl_to_source_file_cache_.find(decl);
     44   if (result == ast_caches_->decl_to_source_file_cache_.end()) {
     45     return GetDeclSourceFile(decl, cip);
     46   }
     47   return result->second;
     48 }
     49 
     50 static const clang::TagDecl *GetTagDecl(clang::QualType qual_type) {
     51   const clang::Type *type_ptr = qual_type.getCanonicalType().getTypePtr();
     52   assert(type_ptr != nullptr);
     53   const clang::TagDecl *tag_decl = type_ptr->getAsTagDecl();
     54   return tag_decl;
     55 }
     56 
     57 static const clang::RecordDecl *GetAnonymousRecord(clang::QualType type) {
     58   const clang::Type *type_ptr = type.getTypePtr();
     59   assert(type_ptr != nullptr);
     60   if (!type_ptr->isRecordType()) {
     61     return nullptr;
     62   }
     63   const clang::TagDecl *tag_decl = type_ptr->getAsTagDecl();
     64   if (!tag_decl) {
     65     return nullptr;
     66   }
     67   const clang::RecordDecl *record_decl =
     68       llvm::dyn_cast<clang::RecordDecl>(tag_decl);
     69 
     70   if (record_decl != nullptr && (!record_decl->hasNameForLinkage() ||
     71       record_decl->isAnonymousStructOrUnion())) {
     72     return record_decl;
     73   }
     74   return nullptr;
     75 }
     76 
     77 static const clang::EnumDecl *GetAnonymousEnum(
     78     const clang::QualType qual_type) {
     79   const clang::Type *type_ptr = qual_type.getTypePtr();
     80   assert(type_ptr != nullptr);
     81   const clang::TagDecl *tag_decl = type_ptr->getAsTagDecl();
     82   if (!tag_decl) {
     83     return nullptr;
     84   }
     85   const clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(tag_decl);
     86   if (!enum_decl || enum_decl->hasNameForLinkage()) {
     87     return nullptr;
     88   }
     89   return enum_decl;
     90 }
     91 
     92 static bool IsReferencingType(clang::QualType qual_type) {
     93   const clang::QualType canonical_type = qual_type.getCanonicalType();
     94   const clang::Type *base_type = canonical_type.getTypePtr();
     95   bool is_ptr = base_type->isPointerType();
     96   bool is_reference = base_type->isReferenceType();
     97   bool is_array = base_type->isArrayType();
     98   return is_array || is_ptr || is_reference ||
     99       qual_type.hasLocalQualifiers();
    100 }
    101 
    102 static clang::QualType GetReferencedType(const clang::QualType qual_type);
    103 
    104 static clang::QualType GetFinalReferencedType(clang::QualType qual_type) {
    105   while (IsReferencingType(qual_type)) {
    106     qual_type = GetReferencedType(qual_type);
    107   }
    108   return qual_type;
    109 }
    110 
    111 std::string ABIWrapper::TypeNameWithFinalDestination(clang::QualType qual_type) {
    112   clang::QualType canonical_qual_type = qual_type.getCanonicalType();
    113   const std::string qual_type_name = QualTypeToString(canonical_qual_type);
    114   clang::QualType final_destination_type =
    115       GetFinalReferencedType(canonical_qual_type);
    116   const clang::RecordDecl *anon_record =
    117       GetAnonymousRecord(final_destination_type);
    118   if (anon_record) {
    119     clang::SourceManager &sm = cip_->getSourceManager();
    120     clang::SourceLocation location = anon_record->getLocation();
    121     return qual_type_name + " at " + location.printToString(sm);
    122   }
    123   return qual_type_name;
    124 }
    125 
    126 std::string ABIWrapper::GetKeyForTypeId(clang::QualType qual_type) {
    127   clang::QualType canonical_qual_type = qual_type.getCanonicalType();
    128   clang::QualType final_destination_type =
    129       GetFinalReferencedType(canonical_qual_type);
    130   // Get the tag id for final destionation and add that to the type name with
    131   // final destination. This helps in avoiding aliasing of types when fully
    132   // qualified type-name doesn't expand all template parameters with their
    133   // namespaces.
    134   return TypeNameWithFinalDestination(qual_type) +
    135       GetTypeUniqueId(GetTagDecl(final_destination_type));
    136 }
    137 
    138 std::string ABIWrapper::GetDeclSourceFile(const clang::Decl *decl,
    139                                           const clang::CompilerInstance *cip) {
    140   clang::SourceManager &sm = cip->getSourceManager();
    141   clang::SourceLocation location = decl->getLocation();
    142   // We need to use the expansion location to identify whether we should recurse
    143   // into the AST Node or not. For eg: macros specifying LinkageSpecDecl can
    144   // have their spelling location defined somewhere outside a source / header
    145   // file belonging to a library. This should not allow the AST node to be
    146   // skipped. Its expansion location will still be the source-file / header
    147   // belonging to the library.
    148   clang::SourceLocation expansion_location = sm.getExpansionLoc(location);
    149   llvm::StringRef file_name = sm.getFilename(expansion_location);
    150   return abi_util::RealPath(file_name.str());
    151 }
    152 
    153 static abi_util::AccessSpecifierIR AccessClangToIR(
    154     const clang::AccessSpecifier sp)  {
    155   switch (sp) {
    156     case clang::AS_private: {
    157       return abi_util::AccessSpecifierIR::PrivateAccess;
    158       break;
    159     }
    160     case clang::AS_protected: {
    161       return abi_util::AccessSpecifierIR::ProtectedAccess;
    162       break;
    163     }
    164     default: {
    165       return abi_util::AccessSpecifierIR::PublicAccess;
    166       break;
    167     }
    168   }
    169 }
    170 
    171 bool ABIWrapper::CreateAnonymousRecord(const clang::RecordDecl *record_decl) {
    172   RecordDeclWrapper record_decl_wrapper(mangle_contextp_, ast_contextp_, cip_,
    173                                         record_decl, ir_dumper_, ast_caches_);
    174   return record_decl_wrapper.GetRecordDecl();
    175 }
    176 
    177 // Get type 'referenced' by qual_type. Referenced type implies, in order:
    178 // 1) Strip off all qualifiers if qual_type has CVR qualifiers.
    179 // 2) Strip off a pointer level if qual_type is a pointer.
    180 // 3) Strip off the reference if qual_type is a reference.
    181 // Note: qual_type is expected to be a canonical type.
    182 static clang::QualType GetReferencedType(const clang::QualType qual_type) {
    183   const clang::Type *type_ptr = qual_type.getTypePtr();
    184   if (qual_type.hasLocalQualifiers()) {
    185     return qual_type.getLocalUnqualifiedType();
    186   }
    187   if (type_ptr->isPointerType()) {
    188     return type_ptr->getPointeeType();
    189   }
    190   if (type_ptr->isArrayType()) {
    191     return
    192         type_ptr->getArrayElementTypeNoTypeQual()->getCanonicalTypeInternal();
    193   }
    194   return qual_type.getNonReferenceType();
    195 }
    196 
    197 bool ABIWrapper::CreateExtendedType(
    198     clang::QualType qual_type,
    199     abi_util::TypeIR *typep) {
    200   const clang::QualType canonical_type = qual_type.getCanonicalType();
    201   // The source file is going to be set later anyway.
    202   return CreateBasicNamedAndTypedDecl(canonical_type, typep, "");
    203 }
    204 
    205 //This overload takes in a qualtype and adds its information to the abi-dump on
    206 //its own.
    207 bool ABIWrapper::CreateBasicNamedAndTypedDecl(
    208     clang::QualType qual_type, const std::string &source_file) {
    209   const std::string &type_key = GetKeyForTypeId(qual_type);
    210   const clang::QualType canonical_type = qual_type.getCanonicalType();
    211   const clang::Type *base_type = canonical_type.getTypePtr();
    212   bool is_builtin = base_type->isBuiltinType();
    213   bool should_continue_with_recursive_type_creation =
    214       IsReferencingType(canonical_type) || is_builtin ||
    215       base_type->isFunctionType() ||
    216       (GetAnonymousRecord(canonical_type) != nullptr);
    217   if (!should_continue_with_recursive_type_creation ||
    218       !ast_caches_->type_cache_.insert(type_key).second) {
    219     return true;
    220   }
    221   // Do something similar to what is being done right now. Create an object
    222   // extending Type and return a pointer to that and pass it to CreateBasic...
    223   // CreateBasic...(qualtype, Type *) fills in size, alignemnt etc.
    224   auto type_and_status = SetTypeKind(canonical_type, source_file);
    225   std::unique_ptr<abi_util::TypeIR> typep = std::move(type_and_status.typep_);
    226   if (!base_type->isVoidType() && type_and_status.should_create_type_ &&
    227       !typep) {
    228     llvm::errs() << "nullptr with valid type while creating basic type\n";
    229     return false;
    230   }
    231   return type_and_status.should_create_type_ ?
    232       CreateBasicNamedAndTypedDecl(canonical_type, typep.get(), source_file) &&
    233       ir_dumper_->AddLinkableMessageIR(typep.get()) : true;
    234 }
    235 
    236 std::string RecordDeclWrapper::GetMangledRTTI(
    237     const clang::CXXRecordDecl *cxx_record_decl) {
    238   clang::QualType qual_type =
    239       cxx_record_decl->getTypeForDecl()->getCanonicalTypeInternal();
    240   llvm::SmallString<256> uid;
    241   llvm::raw_svector_ostream out(uid);
    242   mangle_contextp_->mangleCXXRTTI(qual_type, out);
    243   return uid.str();
    244 }
    245 
    246 std::string ABIWrapper::GetTypeUniqueId(const clang::TagDecl *tag_decl) {
    247   if (!tag_decl) {
    248     return "";
    249   }
    250   clang::QualType qual_type =
    251       tag_decl->getTypeForDecl()->getCanonicalTypeInternal();
    252   if (!tag_decl->isExternCContext() && ast_contextp_->getLangOpts().CPlusPlus) {
    253     llvm::SmallString<256> uid;
    254     llvm::raw_svector_ostream out(uid);
    255     mangle_contextp_->mangleCXXRTTIName(qual_type, out);
    256     return uid.str();
    257   }
    258   return QualTypeToString(qual_type);
    259 }
    260 
    261 // CreateBasicNamedAndTypedDecl creates a BasicNamedAndTypedDecl : that'll
    262 // include all the generic information a basic type will have:
    263 // abi_dump::BasicNamedAndTypedDecl. Other methods fill in more specific
    264 // information, eg: RecordDecl, EnumDecl.
    265 bool ABIWrapper::CreateBasicNamedAndTypedDecl(
    266     clang::QualType canonical_type,
    267     abi_util::TypeIR *typep, const std::string &source_file) {
    268   // Cannot determine the size and alignment for template parameter dependent
    269   // types as well as incomplete types.
    270   const clang::Type *base_type = canonical_type.getTypePtr();
    271   assert(base_type != nullptr);
    272   clang::Type::TypeClass type_class = base_type->getTypeClass();
    273   // Temporary Hack for auto type sizes. Not determinable.
    274   if ((type_class != clang::Type::Auto) && !base_type->isIncompleteType() &&
    275       !(base_type->isDependentType())) {
    276     std::pair<clang::CharUnits, clang::CharUnits> size_and_alignment =
    277     ast_contextp_->getTypeInfoInChars(canonical_type);
    278     size_t size = size_and_alignment.first.getQuantity();
    279     size_t alignment = size_and_alignment.second.getQuantity();
    280     typep->SetSize(size);
    281     typep->SetAlignment(alignment);
    282   }
    283   std::string type_name_with_destination =
    284       TypeNameWithFinalDestination(canonical_type);
    285   typep->SetName(type_name_with_destination);
    286   typep->SetLinkerSetKey(type_name_with_destination);
    287   // default values are false, we don't set them since explicitly doing that
    288   // makes the abi dumps more verbose.
    289   // This type has a reference type if its a pointer / reference OR it has CVR
    290   // qualifiers.
    291   clang::QualType referenced_type = GetReferencedType(canonical_type);
    292   typep->SetReferencedType(
    293       ast_caches_->GetTypeId(GetKeyForTypeId(referenced_type)));
    294   typep->SetSelfType(ast_caches_->GetTypeId(GetKeyForTypeId(canonical_type)));
    295   // Create the type for referenced type.
    296   return CreateBasicNamedAndTypedDecl(referenced_type, source_file);
    297 }
    298 
    299 std::string ABIWrapper::GetTypeLinkageName(const clang::Type *typep)  {
    300   assert(typep != nullptr);
    301   clang::QualType qt = typep->getCanonicalTypeInternal();
    302   return QualTypeToString(qt);
    303 }
    304 
    305 // This method returns a TypeAndCreationStatus object. This object contains a
    306 // type and information to tell the clients of this method whether the caller
    307 // should continue creating the type.
    308 TypeAndCreationStatus ABIWrapper::SetTypeKind(
    309     const clang::QualType canonical_type, const std::string &source_file) {
    310   if (canonical_type.hasLocalQualifiers()) {
    311     auto qual_type_ir =
    312         std::make_unique<abi_util::QualifiedTypeIR>();
    313     qual_type_ir->SetConstness(canonical_type.isConstQualified());
    314     qual_type_ir->SetRestrictedness(canonical_type.isRestrictQualified());
    315     qual_type_ir->SetVolatility(canonical_type.isVolatileQualified());
    316     qual_type_ir->SetSourceFile(source_file);
    317     return TypeAndCreationStatus(std::move(qual_type_ir));
    318   }
    319   const clang::Type *type_ptr = canonical_type.getTypePtr();
    320   if (type_ptr->isPointerType()) {
    321     auto pointer_type_ir = std::make_unique<abi_util::PointerTypeIR>();
    322     pointer_type_ir->SetSourceFile(source_file);
    323     return TypeAndCreationStatus(std::move(pointer_type_ir));
    324   }
    325   if (type_ptr->isLValueReferenceType()) {
    326     auto lvalue_reference_type_ir =
    327         std::make_unique<abi_util::LvalueReferenceTypeIR>();
    328     lvalue_reference_type_ir->SetSourceFile(source_file);
    329     return TypeAndCreationStatus(std::move(lvalue_reference_type_ir));
    330   }
    331   if (type_ptr->isRValueReferenceType()) {
    332    auto rvalue_reference_type_ir =
    333        std::make_unique<abi_util::RvalueReferenceTypeIR>();
    334    rvalue_reference_type_ir->SetSourceFile(source_file);
    335    return TypeAndCreationStatus(std::move(rvalue_reference_type_ir));
    336   }
    337   if (type_ptr->isArrayType()) {
    338     auto array_type_ir = std::make_unique<abi_util::ArrayTypeIR>();
    339     array_type_ir->SetSourceFile(source_file);
    340     return TypeAndCreationStatus(std::move(array_type_ir));
    341   }
    342   if (type_ptr->isEnumeralType()) {
    343     return TypeAndCreationStatus(std::make_unique<abi_util::EnumTypeIR>());
    344   }
    345   if (type_ptr->isBuiltinType()) {
    346     auto builtin_type_ir = std::make_unique<abi_util::BuiltinTypeIR>();
    347     builtin_type_ir->SetSignedness(type_ptr->isUnsignedIntegerType());
    348     builtin_type_ir->SetIntegralType(type_ptr->isIntegralType(*ast_contextp_));
    349     return TypeAndCreationStatus(std::move(builtin_type_ir));
    350   }
    351   if (auto &&func_type_ptr =
    352       llvm::dyn_cast<const clang::FunctionType>(type_ptr)) {
    353     FunctionTypeWrapper function_type_wrapper(mangle_contextp_, ast_contextp_,
    354                                               cip_, func_type_ptr, ir_dumper_,
    355                                               ast_caches_, source_file);
    356     if (!function_type_wrapper.GetFunctionType()) {
    357       llvm::errs() << "FunctionType could not be created\n";
    358       ::exit(1);
    359     }
    360   }
    361   if (type_ptr->isRecordType()) {
    362     // If this record is anonymous, create it.
    363     const clang::RecordDecl *anon_record = GetAnonymousRecord(canonical_type);
    364     if (anon_record && !CreateAnonymousRecord(anon_record)) {
    365       llvm::errs() << "Anonymous record could not be created\n";
    366       ::exit(1);
    367     }
    368   }
    369   return TypeAndCreationStatus(nullptr, false);
    370 }
    371 
    372 std::string ABIWrapper::GetMangledNameDecl(
    373     const clang::NamedDecl *decl, clang::MangleContext *mangle_contextp) {
    374   if (!mangle_contextp->shouldMangleDeclName(decl)) {
    375     clang::IdentifierInfo *identifier = decl->getIdentifier();
    376     return identifier ? identifier->getName() : "";
    377   }
    378   std::string mangled_name;
    379   llvm::raw_string_ostream ostream(mangled_name);
    380   mangle_contextp->mangleName(decl, ostream);
    381   ostream.flush();
    382   return mangled_name;
    383 }
    384 
    385 std::string ABIWrapper::GetTagDeclQualifiedName(
    386     const clang::TagDecl *decl) {
    387   if (decl->getTypedefNameForAnonDecl()) {
    388     return decl->getTypedefNameForAnonDecl()->getQualifiedNameAsString();
    389   }
    390   return decl->getQualifiedNameAsString();
    391 }
    392 
    393 bool ABIWrapper::SetupTemplateArguments(
    394     const clang::TemplateArgumentList *tl,
    395     abi_util::TemplatedArtifactIR *ta,
    396     const std::string &source_file) {
    397   abi_util::TemplateInfoIR template_info;
    398   for (int i = 0; i < tl->size(); i++) {
    399     const clang::TemplateArgument &arg = (*tl)[i];
    400     //TODO: More comprehensive checking needed.
    401     if (arg.getKind() != clang::TemplateArgument::Type) {
    402       continue;
    403     }
    404     clang::QualType type = arg.getAsType();
    405     template_info.AddTemplateElement(
    406         abi_util::TemplateElementIR(
    407             ast_caches_->GetTypeId(GetKeyForTypeId(type))));
    408     if (!CreateBasicNamedAndTypedDecl(type, source_file)) {
    409       llvm::errs() << "Setting up template arguments failed\n";
    410       return false;
    411     }
    412   }
    413   ta->SetTemplateInfo(std::move(template_info));
    414   return true;
    415 }
    416 
    417 std::string ABIWrapper::QualTypeToString(
    418     const clang::QualType &sweet_qt) {
    419   const clang::QualType salty_qt = sweet_qt.getCanonicalType();
    420   // clang::TypeName::getFullyQualifiedName removes the part of the type related
    421   // to it being a template parameter. Don't use it for dependent types.
    422   if (salty_qt.getTypePtr()->isDependentType()) {
    423     return salty_qt.getAsString();
    424   }
    425   return clang::TypeName::getFullyQualifiedName(salty_qt, *ast_contextp_);
    426 }
    427 
    428 FunctionTypeWrapper::FunctionTypeWrapper(
    429     clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp,
    430     const clang::CompilerInstance *compiler_instance_p,
    431     const clang::FunctionType *function_type, abi_util::IRDumper *ir_dumper,
    432     ast_util::ASTCaches *ast_caches, const std::string &source_file)
    433   : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper,
    434                ast_caches), function_type_(function_type),
    435     source_file_(source_file) { }
    436 
    437 bool FunctionTypeWrapper::SetupFunctionType(
    438     abi_util::FunctionTypeIR *function_type_ir) {
    439   // Add ReturnType
    440   function_type_ir->SetReturnType(
    441       ast_caches_->GetTypeId(GetKeyForTypeId(function_type_->getReturnType())));
    442   function_type_ir->SetSourceFile(source_file_);
    443   const clang::FunctionProtoType *function_pt =
    444       llvm::dyn_cast<clang::FunctionProtoType>(function_type_);
    445   if (!function_pt) {
    446     return true;
    447   }
    448   for (unsigned i = 0, e = function_pt->getNumParams(); i != e; ++i) {
    449     clang::QualType param_type = function_pt->getParamType(i);
    450     if (!SetupFunctionParameter(function_type_ir, param_type, false,
    451                                 source_file_)) {
    452       return false;
    453     }
    454   }
    455   return true;
    456 }
    457 
    458 bool FunctionTypeWrapper::GetFunctionType() {
    459   auto abi_decl = std::make_unique<abi_util::FunctionTypeIR>();
    460   clang::QualType canonical_type = function_type_->getCanonicalTypeInternal();
    461   if (!CreateBasicNamedAndTypedDecl(canonical_type, abi_decl.get(), "")) {
    462     llvm::errs() << "Couldn't create (function type) extended type\n";
    463     return false;
    464   }
    465   return SetupFunctionType(abi_decl.get()) &&
    466       ir_dumper_->AddLinkableMessageIR(abi_decl.get());
    467 }
    468 
    469 FunctionDeclWrapper::FunctionDeclWrapper(
    470     clang::MangleContext *mangle_contextp,
    471     clang::ASTContext *ast_contextp,
    472     const clang::CompilerInstance *compiler_instance_p,
    473     const clang::FunctionDecl *decl,
    474     abi_util::IRDumper *ir_dumper,
    475     ast_util::ASTCaches *ast_caches)
    476   : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper,
    477                ast_caches),
    478     function_decl_(decl) { }
    479 
    480 bool FunctionDeclWrapper::SetupThisParameter(abi_util::FunctionIR *functionp,
    481                                              const std::string &source_file) {
    482   const clang::CXXMethodDecl *cxx_method_decl =
    483       llvm::dyn_cast<clang::CXXMethodDecl>(function_decl_);
    484   // No this pointer for static methods.
    485   if (!cxx_method_decl || cxx_method_decl->isStatic()) {
    486     return true;
    487   }
    488   clang::QualType this_type = cxx_method_decl->getThisType(*ast_contextp_);
    489   return SetupFunctionParameter(functionp, this_type, false, source_file, true);
    490 }
    491 
    492 bool ABIWrapper::SetupFunctionParameter(
    493     abi_util::CFunctionLikeIR *functionp, const clang::QualType qual_type,
    494     bool has_default_arg, const std::string &source_file, bool is_this_ptr) {
    495   if (!CreateBasicNamedAndTypedDecl(qual_type, source_file)) {
    496     llvm::errs() << "Setting up function parameter failed\n";
    497     return false;
    498   }
    499   functionp->AddParameter(abi_util::ParamIR(
    500       ast_caches_->GetTypeId(GetKeyForTypeId(qual_type)), has_default_arg,
    501       is_this_ptr));
    502   return true;
    503 }
    504 
    505 bool FunctionDeclWrapper::SetupFunctionParameters(
    506     abi_util::FunctionIR *functionp,
    507     const std::string &source_file) {
    508   clang::FunctionDecl::param_const_iterator param_it =
    509       function_decl_->param_begin();
    510   // If this is a CXXMethodDecl, we need to add the "this" pointer.
    511   if (!SetupThisParameter(functionp, source_file)) {
    512     llvm::errs() << "Setting up 'this' parameter failed\n";
    513     return false;
    514   }
    515 
    516   while (param_it != function_decl_->param_end()) {
    517     // The linker set key is blank since that shows up in the mangled name.
    518     bool has_default_arg = (*param_it)->hasDefaultArg();
    519     clang::QualType param_qt = (*param_it)->getType();
    520     if (!SetupFunctionParameter(functionp, param_qt, has_default_arg,
    521                                 source_file)) {
    522       return false;
    523     }
    524     param_it++;
    525   }
    526   return true;
    527 }
    528 
    529 bool FunctionDeclWrapper::SetupFunction(abi_util::FunctionIR *functionp,
    530                                         const std::string &source_file)  {
    531   // Go through all the parameters in the method and add them to the fields.
    532   // Also get the fully qualfied name.
    533   // TODO: Change this to get the complete function signature
    534   functionp->SetName(function_decl_->getQualifiedNameAsString());
    535   functionp->SetSourceFile(source_file);
    536   clang::QualType return_type = function_decl_->getReturnType();
    537 
    538   functionp->SetReturnType(
    539       ast_caches_->GetTypeId(GetKeyForTypeId(return_type)));
    540   functionp->SetAccess(AccessClangToIR(function_decl_->getAccess()));
    541   return CreateBasicNamedAndTypedDecl(return_type, source_file) &&
    542       SetupFunctionParameters(functionp, source_file) &&
    543       SetupTemplateInfo(functionp, source_file);
    544 }
    545 
    546 bool FunctionDeclWrapper::SetupTemplateInfo(
    547     abi_util::FunctionIR *functionp,
    548     const std::string &source_file)  {
    549   switch (function_decl_->getTemplatedKind()) {
    550     case clang::FunctionDecl::TK_FunctionTemplateSpecialization: {
    551       const clang::TemplateArgumentList *arg_list =
    552           function_decl_->getTemplateSpecializationArgs();
    553       if (arg_list && !SetupTemplateArguments(arg_list, functionp,
    554                                               source_file)) {
    555         return false;
    556       }
    557       break;
    558     }
    559     default: {
    560       break;
    561     }
    562   }
    563   return true;
    564 }
    565 
    566 std::unique_ptr<abi_util::FunctionIR> FunctionDeclWrapper::GetFunctionDecl() {
    567   auto abi_decl = std::make_unique<abi_util::FunctionIR>();
    568   std::string source_file = GetCachedDeclSourceFile(function_decl_, cip_);
    569   if (!SetupFunction(abi_decl.get(), source_file)) {
    570     return nullptr;
    571   }
    572   return abi_decl;
    573 }
    574 
    575 RecordDeclWrapper::RecordDeclWrapper(
    576     clang::MangleContext *mangle_contextp,
    577     clang::ASTContext *ast_contextp,
    578     const clang::CompilerInstance *compiler_instance_p,
    579     const clang::RecordDecl *decl, abi_util::IRDumper *ir_dumper,
    580     ast_util::ASTCaches *ast_caches)
    581   : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper,
    582                ast_caches),
    583     record_decl_(decl) { }
    584 
    585 bool RecordDeclWrapper::SetupRecordFields(abi_util::RecordTypeIR *recordp,
    586                                           const std::string &source_file) {
    587   clang::RecordDecl::field_iterator field = record_decl_->field_begin();
    588   uint32_t field_index = 0;
    589   const clang::ASTRecordLayout &record_layout =
    590       ast_contextp_->getASTRecordLayout(record_decl_);
    591   while (field != record_decl_->field_end()) {
    592     clang::QualType field_type = field->getType();
    593     std::string key_for_type_id = GetKeyForTypeId(field_type);
    594     if (const clang::EnumDecl *enum_decl =
    595                GetAnonymousEnum(field_type)) {
    596       // Handle anonymous enums.
    597       key_for_type_id = GetKeyForTypeId(enum_decl->getIntegerType());
    598     }
    599     if (!CreateBasicNamedAndTypedDecl(field_type, source_file)) {
    600       llvm::errs() << "Creation of Type failed\n";
    601       return false;
    602     }
    603     std::string field_name = field->getName();
    604     uint64_t field_offset = record_layout.getFieldOffset(field_index);
    605     recordp->AddRecordField(abi_util::RecordFieldIR(
    606         field_name, ast_caches_->GetTypeId(key_for_type_id), field_offset,
    607         AccessClangToIR(field->getAccess())));
    608     field++;
    609     field_index++;
    610   }
    611   return true;
    612 }
    613 
    614 bool RecordDeclWrapper::SetupCXXBases(
    615     abi_util::RecordTypeIR *cxxp,
    616     const clang::CXXRecordDecl *cxx_record_decl) {
    617   if (!cxx_record_decl || !cxxp) {
    618     return false;
    619   }
    620   clang::CXXRecordDecl::base_class_const_iterator base_class =
    621       cxx_record_decl->bases_begin();
    622   while (base_class != cxx_record_decl->bases_end()) {
    623     std::string name = QualTypeToString(base_class->getType());
    624     bool is_virtual = base_class->isVirtual();
    625     abi_util::AccessSpecifierIR access =
    626         AccessClangToIR(base_class->getAccessSpecifier());
    627     cxxp->AddCXXBaseSpecifier(
    628         abi_util::CXXBaseSpecifierIR(
    629             ast_caches_->GetTypeId(GetKeyForTypeId(base_class->getType())),
    630             is_virtual, access));
    631     base_class++;
    632   }
    633   return true;
    634 }
    635 
    636 bool RecordDeclWrapper::SetupRecordVTable(
    637     abi_util::RecordTypeIR *record_declp,
    638     const clang::CXXRecordDecl *cxx_record_decl) {
    639   if (!cxx_record_decl || !record_declp) {
    640     return false;
    641   }
    642   clang::VTableContextBase *base_vtable_contextp =
    643       ast_contextp_->getVTableContext();
    644   const clang::Type *typep = cxx_record_decl->getTypeForDecl();
    645   if (!base_vtable_contextp || !typep) {
    646     return false;
    647   }
    648   // Skip Microsoft ABI.
    649   clang::ItaniumVTableContext *itanium_vtable_contextp =
    650         llvm::dyn_cast<clang::ItaniumVTableContext>(base_vtable_contextp);
    651   if (!itanium_vtable_contextp || !cxx_record_decl->isPolymorphic() ||
    652       typep->isDependentType() || typep->isIncompleteType()) {
    653     return true;
    654   }
    655   const clang::VTableLayout &vtable_layout =
    656       itanium_vtable_contextp->getVTableLayout(cxx_record_decl);
    657   abi_util::VTableLayoutIR vtable_ir_layout;
    658   for (const auto &vtable_component : vtable_layout.vtable_components()) {
    659     abi_util::VTableComponentIR added_component=
    660         SetupRecordVTableComponent(vtable_component);
    661     vtable_ir_layout.AddVTableComponent(std::move(added_component));
    662   }
    663   record_declp->SetVTableLayout(std::move(vtable_ir_layout));
    664   return true;
    665 }
    666 
    667 abi_util::VTableComponentIR RecordDeclWrapper::SetupRecordVTableComponent(
    668     const clang::VTableComponent &vtable_component) {
    669   abi_util::VTableComponentIR::Kind kind =
    670       abi_util::VTableComponentIR::Kind::RTTI;
    671   std::string mangled_component_name = "";
    672   llvm::raw_string_ostream ostream(mangled_component_name);
    673   int64_t value = 0;
    674   clang::VTableComponent::Kind clang_component_kind =
    675       vtable_component.getKind();
    676   switch (clang_component_kind) {
    677     case clang::VTableComponent::CK_VCallOffset:
    678       kind = abi_util::VTableComponentIR::Kind::VCallOffset;
    679       value = vtable_component.getVCallOffset().getQuantity();
    680       break;
    681     case clang::VTableComponent::CK_VBaseOffset:
    682       kind = abi_util::VTableComponentIR::Kind::VBaseOffset;
    683       value = vtable_component.getVBaseOffset().getQuantity();
    684       break;
    685     case clang::VTableComponent::CK_OffsetToTop:
    686       kind = abi_util::VTableComponentIR::Kind::OffsetToTop;
    687       value = vtable_component.getOffsetToTop().getQuantity();
    688       break;
    689     case clang::VTableComponent::CK_RTTI:
    690       {
    691         kind = abi_util::VTableComponentIR::Kind::RTTI;
    692         const clang::CXXRecordDecl *rtti_decl =
    693             vtable_component.getRTTIDecl();
    694         assert(rtti_decl != nullptr);
    695         mangled_component_name = GetMangledRTTI(rtti_decl);
    696       }
    697       break;
    698     case clang::VTableComponent::CK_FunctionPointer:
    699     case clang::VTableComponent::CK_CompleteDtorPointer:
    700     case clang::VTableComponent::CK_DeletingDtorPointer:
    701     case clang::VTableComponent::CK_UnusedFunctionPointer:
    702       {
    703         const clang::CXXMethodDecl *method_decl =
    704             vtable_component.getFunctionDecl();
    705         assert(method_decl != nullptr);
    706         switch (clang_component_kind) {
    707           case clang::VTableComponent::CK_FunctionPointer:
    708             kind = abi_util::VTableComponentIR::Kind::FunctionPointer;
    709             mangled_component_name = GetMangledNameDecl(method_decl,
    710                                                         mangle_contextp_);
    711               break;
    712           case clang::VTableComponent::CK_CompleteDtorPointer:
    713             kind = abi_util::VTableComponentIR::Kind::CompleteDtorPointer;
    714             mangle_contextp_->mangleCXXDtor(
    715                 vtable_component.getDestructorDecl(),
    716                 clang::CXXDtorType::Dtor_Complete, ostream);
    717             ostream.flush();
    718             break;
    719           case clang::VTableComponent::CK_DeletingDtorPointer:
    720             kind = abi_util::VTableComponentIR::Kind::DeletingDtorPointer;
    721             mangle_contextp_->mangleCXXDtor(
    722                 vtable_component.getDestructorDecl(),
    723                 clang::CXXDtorType::Dtor_Deleting, ostream);
    724             ostream.flush();
    725             break;
    726           case clang::VTableComponent::CK_UnusedFunctionPointer:
    727             kind = abi_util::VTableComponentIR::Kind::UnusedFunctionPointer;
    728             break;
    729           default:
    730             break;
    731         }
    732       }
    733       break;
    734     default:
    735       break;
    736   }
    737   return abi_util::VTableComponentIR(mangled_component_name, kind, value);
    738 }
    739 
    740 bool RecordDeclWrapper::SetupTemplateInfo(
    741     abi_util::RecordTypeIR *record_declp,
    742     const clang::CXXRecordDecl *cxx_record_decl,
    743     const std::string &source_file) {
    744   assert(cxx_record_decl != nullptr);
    745   const clang::ClassTemplateSpecializationDecl *specialization_decl =
    746       clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(cxx_record_decl);
    747   if (specialization_decl) {
    748     const clang::TemplateArgumentList *arg_list =
    749         &specialization_decl->getTemplateArgs();
    750     if (arg_list &&
    751         !SetupTemplateArguments(arg_list, record_declp, source_file)) {
    752       return false;
    753     }
    754   }
    755   return true;
    756 }
    757 
    758 bool RecordDeclWrapper::SetupRecordInfo(abi_util::RecordTypeIR *record_declp,
    759                                         const std::string &source_file) {
    760   if (!record_declp) {
    761     return false;
    762   }
    763   if (record_decl_->isStruct()) {
    764     record_declp->SetRecordKind(
    765         abi_util::RecordTypeIR::RecordKind::struct_kind);
    766   } else if (record_decl_->isClass()) {
    767     record_declp->SetRecordKind(
    768         abi_util::RecordTypeIR::RecordKind::class_kind);
    769   } else {
    770     record_declp->SetRecordKind(
    771         abi_util::RecordTypeIR::RecordKind::union_kind);
    772   }
    773 
    774   const clang::Type *basic_type = nullptr;
    775   if (!(basic_type = record_decl_->getTypeForDecl())) {
    776     return false;
    777   }
    778   clang::QualType qual_type = basic_type->getCanonicalTypeInternal();
    779   if (!CreateExtendedType(qual_type, record_declp)) {
    780     return false;
    781   }
    782   record_declp->SetSourceFile(source_file);
    783   if (!record_decl_->hasNameForLinkage() ||
    784       record_decl_->isAnonymousStructOrUnion()) {
    785     record_declp->SetAnonymity(true);
    786   }
    787   record_declp->SetUniqueId(GetTypeUniqueId(record_decl_));
    788   record_declp->SetAccess(AccessClangToIR(record_decl_->getAccess()));
    789   return SetupRecordFields(record_declp, source_file) &&
    790       SetupCXXRecordInfo(record_declp, source_file);
    791 }
    792 
    793 bool RecordDeclWrapper::SetupCXXRecordInfo(
    794     abi_util::RecordTypeIR *record_declp, const std::string &source_file) {
    795   const clang::CXXRecordDecl *cxx_record_decl =
    796       clang::dyn_cast<clang::CXXRecordDecl>(record_decl_);
    797   if (!cxx_record_decl) {
    798     return true;
    799   }
    800   return SetupTemplateInfo(record_declp, cxx_record_decl, source_file) &&
    801       SetupCXXBases(record_declp, cxx_record_decl) &&
    802       SetupRecordVTable(record_declp, cxx_record_decl);
    803 }
    804 
    805 // TODO: Can we use clang's ODR hash to do faster ODR checking ?
    806 bool RecordDeclWrapper::GetRecordDecl() {
    807   auto abi_decl = std::make_unique<abi_util::RecordTypeIR>();
    808   std::string source_file = GetCachedDeclSourceFile(record_decl_, cip_);
    809   if (!SetupRecordInfo(abi_decl.get(), source_file)) {
    810     llvm::errs() << "Setting up CXX Bases / Template Info failed\n";
    811     return false;
    812   }
    813   if ((abi_decl->GetReferencedType() == "") ||
    814       (abi_decl->GetSelfType() == "")) {
    815     // The only way to have an empty referenced / self type is when the type was
    816     // cached, don't add the record.
    817     return true;
    818   }
    819   return ir_dumper_->AddLinkableMessageIR(abi_decl.get());
    820 }
    821 
    822 EnumDeclWrapper::EnumDeclWrapper(
    823     clang::MangleContext *mangle_contextp,
    824     clang::ASTContext *ast_contextp,
    825     const clang::CompilerInstance *compiler_instance_p,
    826     const clang::EnumDecl *decl, abi_util::IRDumper *ir_dumper,
    827     ast_util::ASTCaches *ast_caches)
    828   : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper,
    829                ast_caches),
    830     enum_decl_(decl) { }
    831 
    832 bool EnumDeclWrapper::SetupEnumFields(abi_util::EnumTypeIR *enump) {
    833   if (!enump) {
    834     return false;
    835   }
    836   clang::EnumDecl::enumerator_iterator enum_it = enum_decl_->enumerator_begin();
    837   while (enum_it != enum_decl_->enumerator_end()) {
    838     std::string name = enum_it->getQualifiedNameAsString();
    839     uint64_t field_value = enum_it->getInitVal().getExtValue();
    840     enump->AddEnumField(abi_util::EnumFieldIR(name, field_value));
    841     enum_it++;
    842   }
    843   return true;
    844 }
    845 
    846 bool EnumDeclWrapper::SetupEnum(abi_util::EnumTypeIR *enum_type,
    847                                 const std::string &source_file) {
    848   std::string enum_name = GetTagDeclQualifiedName(enum_decl_);
    849   clang::QualType enum_qual_type =
    850       enum_decl_->getTypeForDecl()->getCanonicalTypeInternal();
    851   if (!CreateExtendedType(enum_qual_type, enum_type)) {
    852     return false;
    853   }
    854   enum_type->SetSourceFile(source_file);
    855   enum_type->SetUnderlyingType(
    856       ast_caches_->GetTypeId(GetKeyForTypeId(enum_decl_->getIntegerType())));
    857   enum_type->SetAccess(AccessClangToIR(enum_decl_->getAccess()));
    858   enum_type->SetUniqueId(GetTypeUniqueId(enum_decl_));
    859   return SetupEnumFields(enum_type) &&
    860       CreateBasicNamedAndTypedDecl(enum_decl_->getIntegerType(), "");
    861 }
    862 
    863 bool EnumDeclWrapper::GetEnumDecl() {
    864   auto abi_decl = std::make_unique<abi_util::EnumTypeIR>();
    865   std::string source_file = GetCachedDeclSourceFile(enum_decl_, cip_);
    866 
    867   if (!SetupEnum(abi_decl.get(), source_file)) {
    868     llvm::errs() << "Setting up Enum failed\n";
    869     return false;
    870   }
    871   return ir_dumper_->AddLinkableMessageIR(abi_decl.get());
    872 }
    873 
    874 GlobalVarDeclWrapper::GlobalVarDeclWrapper(
    875     clang::MangleContext *mangle_contextp,
    876     clang::ASTContext *ast_contextp,
    877     const clang::CompilerInstance *compiler_instance_p,
    878     const clang::VarDecl *decl, abi_util::IRDumper *ir_dumper,
    879     ast_util::ASTCaches *ast_caches)
    880   : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p, ir_dumper,
    881                ast_caches),
    882     global_var_decl_(decl) { }
    883 
    884 bool GlobalVarDeclWrapper::SetupGlobalVar(
    885     abi_util::GlobalVarIR *global_varp,
    886     const std::string &source_file) {
    887   // Temporary fix : clang segfaults on trying to mangle global variable which
    888   // is a dependent sized array type.
    889   std::string mangled_name =
    890       GetMangledNameDecl(global_var_decl_, mangle_contextp_);
    891   if (!CreateBasicNamedAndTypedDecl(global_var_decl_->getType(), source_file)) {
    892     return false;
    893   }
    894   global_varp->SetSourceFile(source_file);
    895   global_varp->SetName(global_var_decl_->getQualifiedNameAsString());
    896   global_varp->SetLinkerSetKey(mangled_name);
    897   global_varp->SetAccess(AccessClangToIR(global_var_decl_->getAccess()));
    898   global_varp->SetReferencedType(
    899       ast_caches_->GetTypeId(GetKeyForTypeId(global_var_decl_->getType())));
    900   return true;
    901 }
    902 
    903 bool GlobalVarDeclWrapper::GetGlobalVarDecl() {
    904   auto abi_decl = std::make_unique<abi_util::GlobalVarIR>();
    905   std::string source_file = GetCachedDeclSourceFile(global_var_decl_, cip_);
    906   return SetupGlobalVar(abi_decl.get(), source_file) &&
    907       ir_dumper_->AddLinkableMessageIR(abi_decl.get());
    908 }
    909