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 : cip_(cip), 33 mangle_contextp_(mangle_contextp), 34 ast_contextp_(ast_contextp) { } 35 36 std::string ABIWrapper::GetDeclSourceFile(const clang::Decl *decl, 37 const clang::CompilerInstance *cip) { 38 clang::SourceManager &sm = cip->getSourceManager(); 39 clang::SourceLocation location = decl->getLocation(); 40 // We need to use the expansion location to identify whether we should recurse 41 // into the AST Node or not. For eg: macros specifying LinkageSpecDecl can 42 // have their spelling location defined somewhere outside a source / header 43 // file belonging to a library. This should not allow the AST node to be 44 // skipped. Its expansion location will still be the source-file / header 45 // belonging to the library. 46 clang::SourceLocation expansion_location = sm.getExpansionLoc(location); 47 llvm::StringRef file_name = sm.getFilename(expansion_location); 48 std::string file_name_adjusted = ""; 49 char file_abs_path[PATH_MAX]; 50 if (realpath(file_name.str().c_str(), file_abs_path) == nullptr) { 51 return ""; 52 } 53 return file_abs_path; 54 } 55 56 abi_dump::AccessSpecifier ABIWrapper::AccessClangToDump( 57 const clang::AccessSpecifier sp) const { 58 switch (sp) { 59 case clang::AS_private: { 60 return abi_dump::AccessSpecifier::private_access; 61 break; 62 } 63 case clang::AS_protected: { 64 return abi_dump::AccessSpecifier::protected_access; 65 break; 66 } 67 default: { 68 return abi_dump::AccessSpecifier::public_access; 69 break; 70 } 71 } 72 } 73 74 // Dumping the size and alignment is optional. This is since clang can lazily 75 // instantiate records as incomplete and therefore their sizes 'may' not be 76 // computable. b/62307940 77 bool ABIWrapper::SetupBasicTypeAbi(abi_dump::BasicTypeAbi *type_abi, 78 const clang::QualType type, 79 bool dump_size) const { 80 if (!type_abi) { 81 return false; 82 } 83 const clang::QualType canonical_type = type.getCanonicalType(); 84 type_abi->set_name(QualTypeToString(canonical_type)); 85 // Cannot determine the size and alignment for template parameter dependent 86 // types as well as incomplete types. 87 const clang::Type *base_type = canonical_type.getTypePtr(); 88 clang::Type::TypeClass type_class = base_type->getTypeClass(); 89 // Temporary Hack for auto type sizes. Not determinable. 90 if (dump_size && base_type && !(base_type->isDependentType()) && 91 !(base_type->isIncompleteType()) && (type_class != clang::Type::Auto)) { 92 std::pair<clang::CharUnits, clang::CharUnits> size_and_alignment = 93 ast_contextp_->getTypeInfoInChars(canonical_type); 94 int64_t size = size_and_alignment.first.getQuantity(); 95 int64_t alignment = size_and_alignment.second.getQuantity(); 96 type_abi->set_size(size); 97 type_abi->set_alignment(alignment); 98 } 99 return true; 100 } 101 102 bool ABIWrapper::SetupBasicNamedAndTypedDecl( 103 abi_dump::BasicNamedAndTypedDecl *basic_named_and_typed_decl, 104 const clang::QualType type, const std::string &name, 105 const clang::AccessSpecifier &access, std::string key, 106 bool dump_size) const { 107 if (!basic_named_and_typed_decl) { 108 return false; 109 } 110 abi_dump::AccessSpecifier access_dump = AccessClangToDump(access); 111 basic_named_and_typed_decl->set_name(name); 112 basic_named_and_typed_decl->set_access(access_dump); 113 if (key != "") { 114 basic_named_and_typed_decl->set_linker_set_key(key); 115 } 116 return SetupBasicTypeAbi(basic_named_and_typed_decl->mutable_type_abi(), 117 type, dump_size); 118 } 119 120 static bool ShouldDumpSize(clang::QualType qt) { 121 const clang::Type *type_ptr = qt.getTypePtr(); 122 assert(type_ptr != nullptr); 123 if (type_ptr->isBuiltinType() || type_ptr->isPointerType()) { 124 return true; 125 } 126 return false; 127 } 128 129 std::string ABIWrapper::GetTypeLinkageName(const clang::Type *typep) const { 130 assert(typep != nullptr); 131 clang::QualType qt = typep->getCanonicalTypeInternal(); 132 return QualTypeToString(qt); 133 } 134 135 std::string ABIWrapper::GetMangledNameDecl( 136 const clang::NamedDecl *decl, clang::MangleContext *mangle_contextp) { 137 if (!mangle_contextp->shouldMangleDeclName(decl)) { 138 clang::IdentifierInfo *identifier = decl->getIdentifier(); 139 return identifier ? identifier->getName() : ""; 140 } 141 std::string mangled_name; 142 llvm::raw_string_ostream ostream(mangled_name); 143 mangle_contextp->mangleName(decl, ostream); 144 ostream.flush(); 145 return mangled_name; 146 } 147 148 bool ABIWrapper::SetupTemplateParamNames( 149 abi_dump::TemplateInfo *tinfo, 150 clang::TemplateParameterList *pl) const { 151 if (tinfo->elements_size() > 0) { 152 return true; 153 } 154 155 clang::TemplateParameterList::iterator template_it = pl->begin(); 156 while (template_it != pl->end()) { 157 abi_dump::TemplateElement *template_parameterp = 158 tinfo->add_elements(); 159 if (!template_parameterp) { 160 return false; 161 } 162 abi_dump::TemplateElement::BasicTemplateElementAbi *basic_abi = 163 template_parameterp->mutable_basic_abi(); 164 if (!basic_abi) { 165 return false; 166 } 167 std::string name = (*template_it)->getName(); 168 basic_abi->set_name(name); 169 // TODO : Default arg ? 170 basic_abi->set_linker_set_key(name); 171 template_it++; 172 } 173 return true; 174 } 175 176 std::string ABIWrapper::GetTagDeclQualifiedName( 177 const clang::TagDecl *decl) const { 178 if (decl->getTypedefNameForAnonDecl()) { 179 return decl->getTypedefNameForAnonDecl()->getQualifiedNameAsString(); 180 } 181 return decl->getQualifiedNameAsString(); 182 } 183 184 bool ABIWrapper::SetupTemplateArguments( 185 abi_dump::TemplateInfo *tinfo, 186 const clang::TemplateArgumentList *tl) const { 187 for (int i = 0; i < tl->size(); i++) { 188 const clang::TemplateArgument &arg = (*tl)[i]; 189 //TODO: More comprehensive checking needed. 190 if (arg.getKind() != clang::TemplateArgument::Type) { 191 continue; 192 } 193 clang::QualType type = arg.getAsType(); 194 abi_dump::TemplateElement *template_parameterp = 195 tinfo->add_elements(); 196 if (!template_parameterp) { 197 return false; 198 } 199 abi_dump::TemplateElement::BasicTemplateElementAbi *basic_abi = 200 template_parameterp->mutable_basic_abi(); 201 if (!basic_abi || !SetupBasicTypeAbi(basic_abi->mutable_type_abi(), type, 202 false)) { 203 return false; 204 } 205 // TODO : default arg 206 basic_abi->set_linker_set_key(QualTypeToString(type)); 207 } 208 return true; 209 } 210 211 std::string ABIWrapper::QualTypeToString( 212 const clang::QualType &sweet_qt) const { 213 const clang::QualType salty_qt = sweet_qt.getCanonicalType(); 214 // clang::TypeName::getFullyQualifiedName removes the part of the type related 215 // to it being a template parameter. Don't use it for dependent types. 216 if (salty_qt.getTypePtr()->isDependentType()) { 217 return salty_qt.getAsString(); 218 } 219 return clang::TypeName::getFullyQualifiedName(salty_qt, *ast_contextp_); 220 } 221 222 FunctionDeclWrapper::FunctionDeclWrapper( 223 clang::MangleContext *mangle_contextp, 224 clang::ASTContext *ast_contextp, 225 const clang::CompilerInstance *compiler_instance_p, 226 const clang::FunctionDecl *decl) 227 : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p), 228 function_decl_(decl) { } 229 230 bool FunctionDeclWrapper::SetupFunctionParameters( 231 abi_dump::FunctionDecl *functionp) const { 232 clang::FunctionDecl::param_const_iterator param_it = 233 function_decl_->param_begin(); 234 while (param_it != function_decl_->param_end()) { 235 abi_dump::ParamDecl *function_fieldp = functionp->add_parameters(); 236 if (!function_fieldp) { 237 llvm::errs() << "Couldn't add parameter to method. Aborting\n"; 238 return false; 239 } 240 // The linker set key is blank since that shows up in the mangled name. 241 bool has_default_arg = (*param_it)->hasDefaultArg(); 242 clang::QualType param_qt = (*param_it)->getType(); 243 bool should_dump_size = ShouldDumpSize(param_qt); 244 if (!SetupBasicNamedAndTypedDecl( 245 function_fieldp->mutable_basic_abi(), 246 (*param_it)->getType(), (*param_it)->getName(), 247 (*param_it)->getAccess(), has_default_arg ? "true" : "false", 248 should_dump_size)) { 249 return false; 250 } 251 function_fieldp->set_default_arg(has_default_arg); 252 param_it++; 253 } 254 return true; 255 } 256 257 bool FunctionDeclWrapper::SetupFunction(abi_dump::FunctionDecl *functionp, 258 const std::string &source_file) const { 259 // Go through all the parameters in the method and add them to the fields. 260 // Also get the fully qualfied name. 261 functionp->set_source_file(source_file); 262 // Combine the function name and return type to form a NamedAndTypedDecl 263 clang::QualType return_type = function_decl_->getReturnType(); 264 bool should_dump_size = ShouldDumpSize(return_type); 265 return SetupBasicNamedAndTypedDecl( 266 functionp->mutable_basic_abi(), 267 return_type, function_decl_->getQualifiedNameAsString(), 268 function_decl_->getAccess(), "", should_dump_size) && 269 SetupTemplateInfo(functionp) && SetupFunctionParameters(functionp); 270 } 271 272 bool FunctionDeclWrapper::SetupTemplateInfo( 273 abi_dump::FunctionDecl *functionp) const { 274 switch (function_decl_->getTemplatedKind()) { 275 case clang::FunctionDecl::TK_FunctionTemplate: { 276 clang::FunctionTemplateDecl *template_decl = 277 function_decl_->getDescribedFunctionTemplate(); 278 if (template_decl) { 279 clang::TemplateParameterList *template_parameter_list = 280 template_decl->getTemplateParameters(); 281 if (template_parameter_list && 282 !SetupTemplateParamNames(functionp->mutable_template_info(), 283 template_parameter_list)) { 284 return false; 285 } 286 } 287 break; 288 } 289 case clang::FunctionDecl::TK_FunctionTemplateSpecialization: { 290 const clang::TemplateArgumentList *arg_list = 291 function_decl_->getTemplateSpecializationArgs(); 292 if (arg_list && 293 !SetupTemplateArguments(functionp->mutable_template_info(), 294 arg_list)) { 295 return false; 296 } 297 break; 298 } 299 default: { 300 break; 301 } 302 } 303 return true; 304 } 305 306 std::unique_ptr<abi_dump::FunctionDecl> 307 FunctionDeclWrapper::GetFunctionDecl() const { 308 std::unique_ptr<abi_dump::FunctionDecl> abi_decl( 309 new abi_dump::FunctionDecl()); 310 std::string source_file = GetDeclSourceFile(function_decl_, cip_); 311 if (!SetupFunction(abi_decl.get(), source_file)) { 312 return nullptr; 313 } 314 return abi_decl; 315 } 316 317 RecordDeclWrapper::RecordDeclWrapper( 318 clang::MangleContext *mangle_contextp, 319 clang::ASTContext *ast_contextp, 320 const clang::CompilerInstance *compiler_instance_p, 321 const clang::RecordDecl *decl) 322 : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p), 323 record_decl_(decl) { } 324 325 bool RecordDeclWrapper::SetupRecordFields(abi_dump::RecordDecl *recordp) const { 326 clang::RecordDecl::field_iterator field = record_decl_->field_begin(); 327 while (field != record_decl_->field_end()) { 328 abi_dump::RecordFieldDecl *record_fieldp = recordp->add_fields(); 329 if (!record_fieldp) { 330 llvm::errs() << " Couldn't add record field: " << field->getName() 331 << " to reference dump\n"; 332 return false; 333 } 334 if (!SetupBasicNamedAndTypedDecl(record_fieldp->mutable_basic_abi(), 335 field->getType(), field->getName(), 336 field->getAccess(), "", true)) { 337 return false; 338 } 339 field++; 340 } 341 return true; 342 } 343 344 bool RecordDeclWrapper::SetupCXXBases( 345 abi_dump::RecordDecl *cxxp, 346 const clang::CXXRecordDecl *cxx_record_decl) const { 347 assert(cxx_record_decl != nullptr); 348 clang::CXXRecordDecl::base_class_const_iterator base_class = 349 cxx_record_decl->bases_begin(); 350 while (base_class != cxx_record_decl->bases_end()) { 351 abi_dump::CXXBaseSpecifier *base_specifierp = cxxp->add_base_specifiers(); 352 if (!base_specifierp) { 353 llvm::errs() << " Couldn't add base specifier to reference dump\n"; 354 return false; 355 } 356 std::string name = QualTypeToString(base_class->getType()); 357 bool is_virtual = base_class->isVirtual(); 358 if (!SetupBasicNamedAndTypedDecl(base_specifierp->mutable_basic_abi(), 359 base_class->getType(), 360 "", base_class->getAccessSpecifier(), 361 "", false)) { 362 return false; 363 } 364 base_specifierp->set_is_virtual(is_virtual); 365 base_class++; 366 } 367 return true; 368 } 369 370 bool RecordDeclWrapper::SetupRecordVTable( 371 abi_dump::RecordDecl *record_declp, 372 const clang::CXXRecordDecl *cxx_record_decl) const { 373 assert(cxx_record_decl != nullptr); 374 clang::VTableContextBase *base_vtable_contextp = 375 ast_contextp_->getVTableContext(); 376 const clang::Type *typep = cxx_record_decl->getTypeForDecl(); 377 if (!base_vtable_contextp || !typep) { 378 return false; 379 } 380 // Skip Microsoft ABI. 381 clang::ItaniumVTableContext *itanium_vtable_contextp = 382 llvm::dyn_cast<clang::ItaniumVTableContext>(base_vtable_contextp); 383 if (!itanium_vtable_contextp || !cxx_record_decl->isPolymorphic() || 384 typep->isDependentType() || typep->isIncompleteType()) { 385 return true; 386 } 387 const clang::VTableLayout &vtable_layout = 388 itanium_vtable_contextp->getVTableLayout(cxx_record_decl); 389 abi_dump::VTableLayout *vtablep = record_declp->mutable_vtable_layout(); 390 if (!vtablep) { 391 return false; 392 } 393 for (const auto &vtable_component : vtable_layout.vtable_components()) { 394 abi_dump::VTableComponent *added_vtable_component = 395 vtablep->add_vtable_components(); 396 if (!added_vtable_component || 397 !SetupRecordVTableComponent(added_vtable_component, vtable_component)) { 398 return false; 399 } 400 } 401 return true; 402 } 403 404 bool RecordDeclWrapper::SetupRecordVTableComponent( 405 abi_dump::VTableComponent *added_vtable_component, 406 const clang::VTableComponent &vtable_component) const { 407 assert(added_vtable_component != nullptr); 408 abi_dump::VTableComponent_Kind kind = abi_dump::VTableComponent_Kind_RTTI; 409 std::string mangled_component_name = ""; 410 llvm::raw_string_ostream ostream(mangled_component_name); 411 int64_t value = 0; 412 clang::VTableComponent::Kind clang_component_kind = 413 vtable_component.getKind(); 414 switch (clang_component_kind) { 415 case clang::VTableComponent::CK_VCallOffset: 416 kind = abi_dump::VTableComponent_Kind_VCallOffset; 417 value = vtable_component.getVCallOffset().getQuantity(); 418 break; 419 case clang::VTableComponent::CK_VBaseOffset: 420 kind = abi_dump::VTableComponent_Kind_VBaseOffset; 421 value = vtable_component.getVBaseOffset().getQuantity(); 422 break; 423 case clang::VTableComponent::CK_OffsetToTop: 424 kind = abi_dump::VTableComponent_Kind_OffsetToTop; 425 value = vtable_component.getOffsetToTop().getQuantity(); 426 break; 427 case clang::VTableComponent::CK_RTTI: 428 { 429 kind = abi_dump::VTableComponent_Kind_RTTI; 430 const clang::CXXRecordDecl *rtti_decl = 431 vtable_component.getRTTIDecl(); 432 assert(rtti_decl != nullptr); 433 mangled_component_name = 434 ABIWrapper::GetTypeLinkageName(rtti_decl->getTypeForDecl()); 435 } 436 break; 437 case clang::VTableComponent::CK_FunctionPointer: 438 case clang::VTableComponent::CK_CompleteDtorPointer: 439 case clang::VTableComponent::CK_DeletingDtorPointer: 440 case clang::VTableComponent::CK_UnusedFunctionPointer: 441 { 442 const clang::CXXMethodDecl *method_decl = 443 vtable_component.getFunctionDecl(); 444 assert(method_decl != nullptr); 445 switch (clang_component_kind) { 446 case clang::VTableComponent::CK_FunctionPointer: 447 kind = abi_dump::VTableComponent_Kind_FunctionPointer; 448 mangled_component_name = GetMangledNameDecl(method_decl, 449 mangle_contextp_); 450 break; 451 case clang::VTableComponent::CK_CompleteDtorPointer: 452 kind = abi_dump::VTableComponent_Kind_CompleteDtorPointer; 453 mangle_contextp_->mangleCXXDtor( 454 vtable_component.getDestructorDecl(), 455 clang::CXXDtorType::Dtor_Complete, ostream); 456 ostream.flush(); 457 458 break; 459 case clang::VTableComponent::CK_DeletingDtorPointer: 460 kind = abi_dump::VTableComponent_Kind_DeletingDtorPointer; 461 mangle_contextp_->mangleCXXDtor( 462 vtable_component.getDestructorDecl(), 463 clang::CXXDtorType::Dtor_Deleting, ostream); 464 ostream.flush(); 465 break; 466 case clang::VTableComponent::CK_UnusedFunctionPointer: 467 kind = abi_dump::VTableComponent_Kind_UnusedFunctionPointer; 468 default: 469 break; 470 } 471 } 472 break; 473 default: 474 return false; 475 } 476 added_vtable_component->set_kind(kind); 477 added_vtable_component->set_component_value(value); 478 added_vtable_component->set_mangled_component_name(mangled_component_name); 479 return true; 480 } 481 482 bool RecordDeclWrapper::SetupTemplateInfo( 483 abi_dump::RecordDecl *record_declp, 484 const clang::CXXRecordDecl *cxx_record_decl) const { 485 assert(cxx_record_decl != nullptr); 486 if (cxx_record_decl->isTemplateDecl()) { 487 clang::ClassTemplateDecl *template_decl = 488 cxx_record_decl->getDescribedClassTemplate(); 489 if (template_decl) { 490 clang::TemplateParameterList *template_parameter_list = 491 template_decl->getTemplateParameters(); 492 if (template_parameter_list && 493 !SetupTemplateParamNames(record_declp->mutable_template_info(), 494 template_parameter_list)) { 495 return false; 496 } 497 } 498 } else { 499 const clang::ClassTemplateSpecializationDecl *specialization_decl = 500 clang::dyn_cast<clang::ClassTemplateSpecializationDecl>( 501 cxx_record_decl); 502 if(specialization_decl) { 503 const clang::TemplateArgumentList *arg_list = 504 &specialization_decl->getTemplateArgs(); 505 if (arg_list && 506 !SetupTemplateArguments(record_declp->mutable_template_info(), 507 arg_list)) { 508 return false; 509 } 510 } 511 } 512 return true; 513 } 514 515 bool RecordDeclWrapper::SetupRecordInfo(abi_dump::RecordDecl *record_declp, 516 const std::string &source_file) const { 517 std::string qualified_name = GetTagDeclQualifiedName(record_decl_); 518 const clang::Type *basic_type = nullptr; 519 if (!(basic_type = record_decl_->getTypeForDecl())) { 520 return false; 521 } 522 std::string mangled_name = ABIWrapper::GetTypeLinkageName(basic_type); 523 clang::QualType type = basic_type->getCanonicalTypeInternal(); 524 std::string linker_key = (mangled_name == "") ? qualified_name : mangled_name; 525 if (!SetupBasicNamedAndTypedDecl(record_declp->mutable_basic_abi(), 526 type, qualified_name, 527 record_decl_->getAccess(), linker_key, 528 true)) { 529 return false; 530 } 531 record_declp->set_mangled_record_name(mangled_name); 532 record_declp->set_source_file(source_file); 533 return true; 534 } 535 536 bool RecordDeclWrapper::SetupCXXRecordInfo( 537 abi_dump::RecordDecl *record_declp) const { 538 const clang::CXXRecordDecl *cxx_record_decl = 539 clang::dyn_cast<clang::CXXRecordDecl>(record_decl_); 540 if (!cxx_record_decl) { 541 return true; 542 } 543 return SetupTemplateInfo(record_declp, cxx_record_decl) && 544 SetupCXXBases(record_declp, cxx_record_decl) && 545 SetupRecordVTable(record_declp, cxx_record_decl); 546 } 547 548 std::unique_ptr<abi_dump::RecordDecl> RecordDeclWrapper::GetRecordDecl() const { 549 std::unique_ptr<abi_dump::RecordDecl> abi_decl(new abi_dump::RecordDecl()); 550 std::string source_file = GetDeclSourceFile(record_decl_, cip_); 551 abi_dump::RecordDecl *record_declp = abi_decl.get(); 552 if (!SetupRecordInfo(record_declp, source_file) || 553 !SetupRecordFields(record_declp) || 554 !SetupCXXRecordInfo(abi_decl.get())) { 555 llvm::errs() << "Setting up CXX Bases / Template Info failed\n"; 556 return nullptr; 557 } 558 return abi_decl; 559 } 560 561 EnumDeclWrapper::EnumDeclWrapper( 562 clang::MangleContext *mangle_contextp, 563 clang::ASTContext *ast_contextp, 564 const clang::CompilerInstance *compiler_instance_p, 565 const clang::EnumDecl *decl) 566 : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p), 567 enum_decl_(decl) { } 568 569 bool EnumDeclWrapper::SetupEnumFields(abi_dump::EnumDecl *enump) const { 570 clang::EnumDecl::enumerator_iterator enum_it = enum_decl_->enumerator_begin(); 571 while (enum_it != enum_decl_->enumerator_end()) { 572 abi_dump::EnumFieldDecl *enum_fieldp = enump->add_enum_fields(); 573 std::string name = enum_it->getQualifiedNameAsString(); 574 uint64_t field_value = enum_it->getInitVal().getExtValue(); 575 if (!enum_fieldp || 576 !SetupBasicNamedAndTypedDecl(enum_fieldp->mutable_basic_abi(), 577 enum_it->getType(), name, 578 enum_it->getAccess(), 579 std::to_string(field_value), true)) { 580 return false; 581 } 582 enum_fieldp->set_enum_field_value(field_value); 583 enum_it++; 584 } 585 return true; 586 } 587 588 bool EnumDeclWrapper::SetupEnum(abi_dump::EnumDecl *enump, 589 const std::string &source_file) const { 590 std::string enum_name = GetTagDeclQualifiedName(enum_decl_); 591 clang::QualType enum_type = enum_decl_->getIntegerType(); 592 if (!SetupBasicNamedAndTypedDecl(enump->mutable_basic_abi(), enum_type, 593 enum_name, enum_decl_->getAccess(), 594 enum_name, true) || 595 !SetupEnumFields(enump)) { 596 return false; 597 } 598 enump->set_source_file(source_file); 599 return true; 600 } 601 602 std::unique_ptr<abi_dump::EnumDecl> EnumDeclWrapper::GetEnumDecl() const { 603 std::unique_ptr<abi_dump::EnumDecl> abi_decl(new abi_dump::EnumDecl()); 604 std::string source_file = GetDeclSourceFile(enum_decl_, cip_); 605 606 if (!SetupEnum(abi_decl.get(), source_file)) { 607 llvm::errs() << "Setting up Enum fields failed\n"; 608 return nullptr; 609 } 610 return abi_decl; 611 } 612 613 GlobalVarDeclWrapper::GlobalVarDeclWrapper( 614 clang::MangleContext *mangle_contextp, 615 clang::ASTContext *ast_contextp, 616 const clang::CompilerInstance *compiler_instance_p, 617 const clang::VarDecl *decl) 618 : ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p), 619 global_var_decl_(decl) { } 620 621 bool GlobalVarDeclWrapper::SetupGlobalVar( 622 abi_dump::GlobalVarDecl *global_varp, 623 const std::string &source_file) const { 624 // Temporary fix : clang segfaults on trying to mangle global variable which 625 // is a dependent sized array type. 626 std::string qualified_name = global_var_decl_->getQualifiedNameAsString(); 627 std::string mangled_name = 628 GetMangledNameDecl(global_var_decl_, mangle_contextp_); 629 if (!SetupBasicNamedAndTypedDecl( 630 global_varp->mutable_basic_abi(),global_var_decl_->getType(), 631 qualified_name, global_var_decl_->getAccess(), 632 mangled_name, true)) { 633 return false; 634 } 635 global_varp->set_source_file(source_file); 636 return true; 637 } 638 639 std::unique_ptr<abi_dump::GlobalVarDecl> 640 GlobalVarDeclWrapper::GetGlobalVarDecl() const { 641 std::unique_ptr<abi_dump::GlobalVarDecl> 642 abi_decl(new abi_dump::GlobalVarDecl); 643 std::string source_file = GetDeclSourceFile(global_var_decl_, cip_); 644 if (!SetupGlobalVar(abi_decl.get(), source_file)) { 645 return nullptr; 646 } 647 return abi_decl; 648 } 649