Merge changes I3295f029,Idb524a7e,Idcbc6e67,I5b3e03d6,Ib1351092, ...

* changes:
  header-checker: Add file name to error messages
  header-checker: Re-use GetODRListMapKey
  header-checker: Hide GetKeyForTypeId implementation
  header-checker: Remove unused variable and dead code
  header-checker: Remove indecipherable comment
  header-checker: Re-group the code in abi_wrappers
  header-checker: Remove dead GetTypeLinkageName
This commit is contained in:
Logan Chien
2019-04-04 16:27:42 +00:00
committed by Gerrit Code Review
4 changed files with 255 additions and 230 deletions

View File

@@ -32,13 +32,18 @@ namespace diff {
repr::CompatibilityStatusIR HeaderAbiDiff::GenerateCompatibilityReport() {
std::unique_ptr<repr::IRReader> old_reader =
repr::IRReader::CreateIRReader(text_format_old_);
std::unique_ptr<repr::IRReader> new_reader =
repr::IRReader::CreateIRReader(text_format_new_);
if (!old_reader || !new_reader || !old_reader->ReadDump(old_dump_) ||
!new_reader->ReadDump(new_dump_)) {
llvm::errs() << "Could not create Text Format readers\n";
if (!old_reader || !old_reader->ReadDump(old_dump_)) {
llvm::errs() << "Failed to read old ABI dump: " << old_dump_ << "\n";
::exit(1);
}
std::unique_ptr<repr::IRReader> new_reader =
repr::IRReader::CreateIRReader(text_format_new_);
if (!new_reader || !new_reader->ReadDump(new_dump_)) {
llvm::errs() << "Failed to read new ABI dump: " << new_dump_ << "\n";
::exit(1);
}
std::unique_ptr<repr::IRDiffDumper> ir_diff_dumper =
repr::IRDiffDumper::CreateIRDiffDumper(text_format_diff_, cr_);
repr::CompatibilityStatusIR status =

View File

@@ -31,6 +31,30 @@ namespace header_checker {
namespace dumper {
//------------------------------------------------------------------------------
// Helper Function
//------------------------------------------------------------------------------
static repr::AccessSpecifierIR AccessClangToIR(
const clang::AccessSpecifier sp) {
switch (sp) {
case clang::AS_private: {
return repr::AccessSpecifierIR::PrivateAccess;
}
case clang::AS_protected: {
return repr::AccessSpecifierIR::ProtectedAccess;
}
default: {
return repr::AccessSpecifierIR::PublicAccess;
}
}
}
//------------------------------------------------------------------------------
// ABI Wrapper
//------------------------------------------------------------------------------
ABIWrapper::ABIWrapper(
clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
@@ -43,6 +67,21 @@ ABIWrapper::ABIWrapper(
module_(module),
ast_caches_(ast_caches) {}
std::string ABIWrapper::GetDeclSourceFile(const clang::Decl *decl,
const clang::CompilerInstance *cip) {
clang::SourceManager &sm = cip->getSourceManager();
clang::SourceLocation location = decl->getLocation();
// We need to use the expansion location to identify whether we should recurse
// into the AST Node or not. For eg: macros specifying LinkageSpecDecl can
// have their spelling location defined somewhere outside a source / header
// file belonging to a library. This should not allow the AST node to be
// skipped. Its expansion location will still be the source-file / header
// belonging to the library.
clang::SourceLocation expansion_location = sm.getExpansionLoc(location);
llvm::StringRef file_name = sm.getFilename(expansion_location);
return utils::RealPath(file_name.str());
}
std::string ABIWrapper::GetCachedDeclSourceFile(
const clang::Decl *decl, const clang::CompilerInstance *cip) {
assert(decl != nullptr);
@@ -53,6 +92,53 @@ std::string ABIWrapper::GetCachedDeclSourceFile(
return result->second;
}
std::string ABIWrapper::GetMangledNameDecl(
const clang::NamedDecl *decl, clang::MangleContext *mangle_contextp) {
if (!mangle_contextp->shouldMangleDeclName(decl)) {
clang::IdentifierInfo *identifier = decl->getIdentifier();
return identifier ? identifier->getName() : "";
}
std::string mangled_name;
llvm::raw_string_ostream ostream(mangled_name);
mangle_contextp->mangleName(decl, ostream);
ostream.flush();
return mangled_name;
}
bool ABIWrapper::SetupTemplateArguments(const clang::TemplateArgumentList *tl,
repr::TemplatedArtifactIR *ta,
const std::string &source_file) {
repr::TemplateInfoIR template_info;
for (int i = 0; i < tl->size(); i++) {
const clang::TemplateArgument &arg = (*tl)[i];
// TODO: More comprehensive checking needed.
if (arg.getKind() != clang::TemplateArgument::Type) {
continue;
}
clang::QualType type = arg.getAsType();
template_info.AddTemplateElement(
repr::TemplateElementIR(GetTypeId(type)));
if (!CreateBasicNamedAndTypedDecl(type, source_file)) {
llvm::errs() << "Setting up template arguments failed\n";
return false;
}
}
ta->SetTemplateInfo(std::move(template_info));
return true;
}
bool ABIWrapper::SetupFunctionParameter(
repr::CFunctionLikeIR *functionp, const clang::QualType qual_type,
bool has_default_arg, const std::string &source_file, bool is_this_ptr) {
if (!CreateBasicNamedAndTypedDecl(qual_type, source_file)) {
llvm::errs() << "Setting up function parameter failed\n";
return false;
}
functionp->AddParameter(repr::ParamIR(
GetTypeId(qual_type), has_default_arg, is_this_ptr));
return true;
}
static const clang::TagDecl *GetTagDecl(clang::QualType qual_type) {
const clang::Type *type_ptr = qual_type.getCanonicalType().getTypePtr();
assert(type_ptr != nullptr);
@@ -105,81 +191,6 @@ static bool IsReferencingType(clang::QualType qual_type) {
return is_array || is_ptr || is_reference || qual_type.hasLocalQualifiers();
}
static clang::QualType GetReferencedType(const clang::QualType qual_type);
static clang::QualType GetFinalReferencedType(clang::QualType qual_type) {
while (IsReferencingType(qual_type)) {
qual_type = GetReferencedType(qual_type);
}
return qual_type;
}
std::string ABIWrapper::TypeNameWithFinalDestination(clang::QualType qual_type) {
clang::QualType canonical_qual_type = qual_type.getCanonicalType();
const std::string qual_type_name = QualTypeToString(canonical_qual_type);
clang::QualType final_destination_type =
GetFinalReferencedType(canonical_qual_type);
const clang::RecordDecl *anon_record =
GetAnonymousRecord(final_destination_type);
if (anon_record) {
clang::SourceManager &sm = cip_->getSourceManager();
clang::SourceLocation location = anon_record->getLocation();
return qual_type_name + " at " + location.printToString(sm);
}
return qual_type_name;
}
std::string ABIWrapper::GetKeyForTypeId(clang::QualType qual_type) {
clang::QualType canonical_qual_type = qual_type.getCanonicalType();
clang::QualType final_destination_type =
GetFinalReferencedType(canonical_qual_type);
// Get the tag id for final destionation and add that to the type name with
// final destination. This helps in avoiding aliasing of types when fully
// qualified type-name doesn't expand all template parameters with their
// namespaces.
return TypeNameWithFinalDestination(qual_type) +
GetTypeUniqueId(GetTagDecl(final_destination_type));
}
std::string ABIWrapper::GetDeclSourceFile(const clang::Decl *decl,
const clang::CompilerInstance *cip) {
clang::SourceManager &sm = cip->getSourceManager();
clang::SourceLocation location = decl->getLocation();
// We need to use the expansion location to identify whether we should recurse
// into the AST Node or not. For eg: macros specifying LinkageSpecDecl can
// have their spelling location defined somewhere outside a source / header
// file belonging to a library. This should not allow the AST node to be
// skipped. Its expansion location will still be the source-file / header
// belonging to the library.
clang::SourceLocation expansion_location = sm.getExpansionLoc(location);
llvm::StringRef file_name = sm.getFilename(expansion_location);
return utils::RealPath(file_name.str());
}
static repr::AccessSpecifierIR AccessClangToIR(
const clang::AccessSpecifier sp) {
switch (sp) {
case clang::AS_private: {
return repr::AccessSpecifierIR::PrivateAccess;
break;
}
case clang::AS_protected: {
return repr::AccessSpecifierIR::ProtectedAccess;
break;
}
default: {
return repr::AccessSpecifierIR::PublicAccess;
break;
}
}
}
bool ABIWrapper::CreateAnonymousRecord(const clang::RecordDecl *record_decl) {
RecordDeclWrapper record_decl_wrapper(mangle_contextp_, ast_contextp_, cip_,
record_decl, module_, ast_caches_);
return record_decl_wrapper.GetRecordDecl();
}
// Get type 'referenced' by qual_type. Referenced type implies, in order:
// 1) Strip off all qualifiers if qual_type has CVR qualifiers.
// 2) Strip off a pointer level if qual_type is a pointer.
@@ -200,6 +211,51 @@ static clang::QualType GetReferencedType(const clang::QualType qual_type) {
return qual_type.getNonReferenceType();
}
static clang::QualType GetFinalReferencedType(clang::QualType qual_type) {
while (IsReferencingType(qual_type)) {
qual_type = GetReferencedType(qual_type);
}
return qual_type;
}
std::string ABIWrapper::TypeNameWithFinalDestination(
clang::QualType qual_type) {
clang::QualType canonical_qual_type = qual_type.getCanonicalType();
const std::string qual_type_name = QualTypeToString(canonical_qual_type);
clang::QualType final_destination_type =
GetFinalReferencedType(canonical_qual_type);
const clang::RecordDecl *anon_record =
GetAnonymousRecord(final_destination_type);
if (anon_record) {
clang::SourceManager &sm = cip_->getSourceManager();
clang::SourceLocation location = anon_record->getLocation();
return qual_type_name + " at " + location.printToString(sm);
}
return qual_type_name;
}
std::string ABIWrapper::GetTypeId(clang::QualType qual_type) {
return ast_caches_->GetTypeId(GetKeyForTypeId(qual_type));
}
std::string ABIWrapper::GetKeyForTypeId(clang::QualType qual_type) {
clang::QualType canonical_qual_type = qual_type.getCanonicalType();
clang::QualType final_destination_type =
GetFinalReferencedType(canonical_qual_type);
// Get the tag id for final destionation and add that to the type name with
// final destination. This helps in avoiding aliasing of types when fully
// qualified type-name doesn't expand all template parameters with their
// namespaces.
return TypeNameWithFinalDestination(qual_type) +
GetTypeUniqueId(GetTagDecl(final_destination_type));
}
bool ABIWrapper::CreateAnonymousRecord(const clang::RecordDecl *record_decl) {
RecordDeclWrapper record_decl_wrapper(mangle_contextp_, ast_contextp_, cip_,
record_decl, module_, ast_caches_);
return record_decl_wrapper.GetRecordDecl();
}
bool ABIWrapper::CreateExtendedType(clang::QualType qual_type,
repr::TypeIR *typep) {
const clang::QualType canonical_type = qual_type.getCanonicalType();
@@ -207,50 +263,6 @@ bool ABIWrapper::CreateExtendedType(clang::QualType qual_type,
return CreateBasicNamedAndTypedDecl(canonical_type, typep, "");
}
// This overload takes in a qualtype and adds its information to the abi-dump on
// its own.
bool ABIWrapper::CreateBasicNamedAndTypedDecl(clang::QualType qual_type,
const std::string &source_file) {
const std::string &type_key = GetKeyForTypeId(qual_type);
const clang::QualType canonical_type = qual_type.getCanonicalType();
const clang::Type *base_type = canonical_type.getTypePtr();
bool is_builtin = base_type->isBuiltinType();
bool should_continue_with_recursive_type_creation =
IsReferencingType(canonical_type) || is_builtin ||
base_type->isFunctionType() ||
(GetAnonymousRecord(canonical_type) != nullptr);
if (!should_continue_with_recursive_type_creation ||
!ast_caches_->type_cache_.insert(type_key).second) {
return true;
}
// Do something similar to what is being done right now. Create an object
// extending Type and return a pointer to that and pass it to CreateBasic...
// CreateBasic...(qualtype, Type *) fills in size, alignemnt etc.
auto type_and_status = SetTypeKind(canonical_type, source_file);
std::unique_ptr<repr::TypeIR> typep = std::move(type_and_status.typep_);
if (!base_type->isVoidType() && type_and_status.should_create_type_ &&
!typep) {
llvm::errs() << "nullptr with valid type while creating basic type\n";
return false;
}
if (!type_and_status.should_create_type_) {
return true;
}
return (CreateBasicNamedAndTypedDecl(
canonical_type, typep.get(), source_file) &&
module_->AddLinkableMessage(*typep));
}
std::string RecordDeclWrapper::GetMangledRTTI(
const clang::CXXRecordDecl *cxx_record_decl) {
clang::QualType qual_type =
cxx_record_decl->getTypeForDecl()->getCanonicalTypeInternal();
llvm::SmallString<256> uid;
llvm::raw_svector_ostream out(uid);
mangle_contextp_->mangleCXXRTTI(qual_type, out);
return uid.str();
}
std::string ABIWrapper::GetTypeUniqueId(const clang::TagDecl *tag_decl) {
if (!tag_decl) {
return "";
@@ -277,36 +289,68 @@ bool ABIWrapper::CreateBasicNamedAndTypedDecl(
const clang::Type *base_type = canonical_type.getTypePtr();
assert(base_type != nullptr);
clang::Type::TypeClass type_class = base_type->getTypeClass();
// Temporary hack for auto type sizes. Not determinable.
if ((type_class != clang::Type::Auto) && !base_type->isIncompleteType() &&
!(base_type->isDependentType())) {
// Set the size and alignment of the type.
// Temporary hack: Skip the auto types, incomplete types and dependent types.
if (type_class != clang::Type::Auto && !base_type->isIncompleteType() &&
!base_type->isDependentType()) {
std::pair<clang::CharUnits, clang::CharUnits> size_and_alignment =
ast_contextp_->getTypeInfoInChars(canonical_type);
size_t size = size_and_alignment.first.getQuantity();
size_t alignment = size_and_alignment.second.getQuantity();
typep->SetSize(size);
typep->SetAlignment(alignment);
ast_contextp_->getTypeInfoInChars(canonical_type);
typep->SetSize(size_and_alignment.first.getQuantity());
typep->SetAlignment(size_and_alignment.second.getQuantity());
}
std::string type_name_with_destination =
TypeNameWithFinalDestination(canonical_type);
typep->SetName(type_name_with_destination);
typep->SetLinkerSetKey(type_name_with_destination);
// Default values are false, we don't set them since explicitly doing that
// makes the ABI dumps more verbose.
// This type has a reference type if its a pointer / reference OR it has CVR
// qualifiers.
clang::QualType referenced_type = GetReferencedType(canonical_type);
typep->SetReferencedType(
ast_caches_->GetTypeId(GetKeyForTypeId(referenced_type)));
typep->SetSelfType(ast_caches_->GetTypeId(GetKeyForTypeId(canonical_type)));
typep->SetReferencedType(GetTypeId(referenced_type));
typep->SetSelfType(GetTypeId(canonical_type));
// Create the type for referenced type.
return CreateBasicNamedAndTypedDecl(referenced_type, source_file);
}
std::string ABIWrapper::GetTypeLinkageName(const clang::Type *typep) {
assert(typep != nullptr);
clang::QualType qt = typep->getCanonicalTypeInternal();
return QualTypeToString(qt);
// This overload takes in a qualtype and adds its information to the abi-dump on
// its own.
bool ABIWrapper::CreateBasicNamedAndTypedDecl(clang::QualType qual_type,
const std::string &source_file) {
const std::string &type_key = GetKeyForTypeId(qual_type);
const clang::QualType canonical_type = qual_type.getCanonicalType();
const clang::Type *base_type = canonical_type.getTypePtr();
bool is_builtin = base_type->isBuiltinType();
bool should_continue_with_recursive_type_creation =
IsReferencingType(canonical_type) || is_builtin ||
base_type->isFunctionType() ||
(GetAnonymousRecord(canonical_type) != nullptr);
if (!should_continue_with_recursive_type_creation ||
!ast_caches_->type_cache_.insert(type_key).second) {
return true;
}
// Do something similar to what is being done right now. Create an object
// extending Type and return a pointer to that and pass it to CreateBasic...
// CreateBasic...(qualtype, Type *) fills in size, alignemnt etc.
auto type_and_status = SetTypeKind(canonical_type, source_file);
std::unique_ptr<repr::TypeIR> typep = std::move(type_and_status.typep_);
if (!base_type->isVoidType() && type_and_status.should_create_type_ &&
!typep) {
llvm::errs() << "nullptr with valid type while creating basic type\n";
return false;
}
if (!type_and_status.should_create_type_) {
return true;
}
return (CreateBasicNamedAndTypedDecl(
canonical_type, typep.get(), source_file) &&
module_->AddLinkableMessage(*typep));
}
// This method returns a TypeAndCreationStatus object. This object contains a
@@ -379,49 +423,6 @@ TypeAndCreationStatus ABIWrapper::SetTypeKind(
return TypeAndCreationStatus(nullptr, false);
}
std::string ABIWrapper::GetMangledNameDecl(
const clang::NamedDecl *decl, clang::MangleContext *mangle_contextp) {
if (!mangle_contextp->shouldMangleDeclName(decl)) {
clang::IdentifierInfo *identifier = decl->getIdentifier();
return identifier ? identifier->getName() : "";
}
std::string mangled_name;
llvm::raw_string_ostream ostream(mangled_name);
mangle_contextp->mangleName(decl, ostream);
ostream.flush();
return mangled_name;
}
std::string ABIWrapper::GetTagDeclQualifiedName(const clang::TagDecl *decl) {
if (decl->getTypedefNameForAnonDecl()) {
return decl->getTypedefNameForAnonDecl()->getQualifiedNameAsString();
}
return decl->getQualifiedNameAsString();
}
bool ABIWrapper::SetupTemplateArguments(const clang::TemplateArgumentList *tl,
repr::TemplatedArtifactIR *ta,
const std::string &source_file) {
repr::TemplateInfoIR template_info;
for (int i = 0; i < tl->size(); i++) {
const clang::TemplateArgument &arg = (*tl)[i];
// TODO: More comprehensive checking needed.
if (arg.getKind() != clang::TemplateArgument::Type) {
continue;
}
clang::QualType type = arg.getAsType();
template_info.AddTemplateElement(
repr::TemplateElementIR(
ast_caches_->GetTypeId(GetKeyForTypeId(type))));
if (!CreateBasicNamedAndTypedDecl(type, source_file)) {
llvm::errs() << "Setting up template arguments failed\n";
return false;
}
}
ta->SetTemplateInfo(std::move(template_info));
return true;
}
std::string ABIWrapper::QualTypeToString(const clang::QualType &sweet_qt) {
const clang::QualType salty_qt = sweet_qt.getCanonicalType();
// clang::TypeName::getFullyQualifiedName removes the part of the type related
@@ -433,6 +434,11 @@ std::string ABIWrapper::QualTypeToString(const clang::QualType &sweet_qt) {
salty_qt, *ast_contextp_, ast_contextp_->getPrintingPolicy());
}
//------------------------------------------------------------------------------
// Function Type Wrapper
//------------------------------------------------------------------------------
FunctionTypeWrapper::FunctionTypeWrapper(
clang::MangleContext *mangle_contextp, clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
@@ -446,8 +452,7 @@ FunctionTypeWrapper::FunctionTypeWrapper(
bool FunctionTypeWrapper::SetupFunctionType(
repr::FunctionTypeIR *function_type_ir) {
// Add ReturnType
function_type_ir->SetReturnType(
ast_caches_->GetTypeId(GetKeyForTypeId(function_type_->getReturnType())));
function_type_ir->SetReturnType(GetTypeId(function_type_->getReturnType()));
function_type_ir->SetSourceFile(source_file_);
const clang::FunctionProtoType *function_pt =
llvm::dyn_cast<clang::FunctionProtoType>(function_type_);
@@ -475,6 +480,11 @@ bool FunctionTypeWrapper::GetFunctionType() {
module_->AddLinkableMessage(*abi_decl);
}
//------------------------------------------------------------------------------
// Function Decl Wrapper
//------------------------------------------------------------------------------
FunctionDeclWrapper::FunctionDeclWrapper(
clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
@@ -498,19 +508,6 @@ bool FunctionDeclWrapper::SetupThisParameter(repr::FunctionIR *functionp,
return SetupFunctionParameter(functionp, this_type, false, source_file, true);
}
bool ABIWrapper::SetupFunctionParameter(
repr::CFunctionLikeIR *functionp, const clang::QualType qual_type,
bool has_default_arg, const std::string &source_file, bool is_this_ptr) {
if (!CreateBasicNamedAndTypedDecl(qual_type, source_file)) {
llvm::errs() << "Setting up function parameter failed\n";
return false;
}
functionp->AddParameter(repr::ParamIR(
ast_caches_->GetTypeId(GetKeyForTypeId(qual_type)), has_default_arg,
is_this_ptr));
return true;
}
bool FunctionDeclWrapper::SetupFunctionParameters(
repr::FunctionIR *functionp,
const std::string &source_file) {
@@ -544,8 +541,7 @@ bool FunctionDeclWrapper::SetupFunction(repr::FunctionIR *functionp,
functionp->SetSourceFile(source_file);
clang::QualType return_type = function_decl_->getReturnType();
functionp->SetReturnType(
ast_caches_->GetTypeId(GetKeyForTypeId(return_type)));
functionp->SetReturnType(GetTypeId(return_type));
functionp->SetAccess(AccessClangToIR(function_decl_->getAccess()));
return CreateBasicNamedAndTypedDecl(return_type, source_file) &&
SetupFunctionParameters(functionp, source_file) &&
@@ -580,6 +576,11 @@ std::unique_ptr<repr::FunctionIR> FunctionDeclWrapper::GetFunctionDecl() {
return abi_decl;
}
//------------------------------------------------------------------------------
// Record Decl Wrapper
//------------------------------------------------------------------------------
RecordDeclWrapper::RecordDeclWrapper(
clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
@@ -598,11 +599,9 @@ bool RecordDeclWrapper::SetupRecordFields(repr::RecordTypeIR *recordp,
ast_contextp_->getASTRecordLayout(record_decl_);
while (field != record_decl_->field_end()) {
clang::QualType field_type = field->getType();
std::string key_for_type_id = GetKeyForTypeId(field_type);
if (const clang::EnumDecl *enum_decl =
GetAnonymousEnum(field_type)) {
if (const clang::EnumDecl *enum_decl = GetAnonymousEnum(field_type)) {
// Handle anonymous enums.
key_for_type_id = GetKeyForTypeId(enum_decl->getIntegerType());
field_type = enum_decl->getIntegerType();
}
if (!CreateBasicNamedAndTypedDecl(field_type, source_file)) {
llvm::errs() << "Creation of Type failed\n";
@@ -611,7 +610,7 @@ bool RecordDeclWrapper::SetupRecordFields(repr::RecordTypeIR *recordp,
std::string field_name = field->getName();
uint64_t field_offset = record_layout.getFieldOffset(field_index);
recordp->AddRecordField(repr::RecordFieldIR(
field_name, ast_caches_->GetTypeId(key_for_type_id), field_offset,
field_name, GetTypeId(field_type), field_offset,
AccessClangToIR(field->getAccess())));
field++;
field_index++;
@@ -627,14 +626,11 @@ bool RecordDeclWrapper::SetupCXXBases(
clang::CXXRecordDecl::base_class_const_iterator base_class =
cxx_record_decl->bases_begin();
while (base_class != cxx_record_decl->bases_end()) {
std::string name = QualTypeToString(base_class->getType());
bool is_virtual = base_class->isVirtual();
repr::AccessSpecifierIR access =
AccessClangToIR(base_class->getAccessSpecifier());
cxxp->AddCXXBaseSpecifier(
repr::CXXBaseSpecifierIR(
ast_caches_->GetTypeId(GetKeyForTypeId(base_class->getType())),
is_virtual, access));
cxxp->AddCXXBaseSpecifier(repr::CXXBaseSpecifierIR(
GetTypeId(base_class->getType()), is_virtual, access));
base_class++;
}
return true;
@@ -858,6 +854,21 @@ bool RecordDeclWrapper::GetRecordDecl() {
return module_->AddLinkableMessage(*abi_decl);
}
std::string RecordDeclWrapper::GetMangledRTTI(
const clang::CXXRecordDecl *cxx_record_decl) {
clang::QualType qual_type =
cxx_record_decl->getTypeForDecl()->getCanonicalTypeInternal();
llvm::SmallString<256> uid;
llvm::raw_svector_ostream out(uid);
mangle_contextp_->mangleCXXRTTI(qual_type, out);
return uid.str();
}
//------------------------------------------------------------------------------
// Enum Decl Wrapper
//------------------------------------------------------------------------------
EnumDeclWrapper::EnumDeclWrapper(
clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
@@ -884,15 +895,13 @@ bool EnumDeclWrapper::SetupEnumFields(repr::EnumTypeIR *enump) {
bool EnumDeclWrapper::SetupEnum(repr::EnumTypeIR *enum_type,
const std::string &source_file) {
std::string enum_name = GetTagDeclQualifiedName(enum_decl_);
clang::QualType enum_qual_type =
enum_decl_->getTypeForDecl()->getCanonicalTypeInternal();
if (!CreateExtendedType(enum_qual_type, enum_type)) {
return false;
}
enum_type->SetSourceFile(source_file);
enum_type->SetUnderlyingType(
ast_caches_->GetTypeId(GetKeyForTypeId(enum_decl_->getIntegerType())));
enum_type->SetUnderlyingType(GetTypeId(enum_decl_->getIntegerType()));
enum_type->SetAccess(AccessClangToIR(enum_decl_->getAccess()));
enum_type->SetUniqueId(GetTypeUniqueId(enum_decl_));
return SetupEnumFields(enum_type) &&
@@ -910,6 +919,11 @@ bool EnumDeclWrapper::GetEnumDecl() {
return module_->AddLinkableMessage(*abi_decl);
}
//------------------------------------------------------------------------------
// Global Decl Wrapper
//------------------------------------------------------------------------------
GlobalVarDeclWrapper::GlobalVarDeclWrapper(
clang::MangleContext *mangle_contextp,
clang::ASTContext *ast_contextp,
@@ -933,8 +947,7 @@ bool GlobalVarDeclWrapper::SetupGlobalVar(repr::GlobalVarIR *global_varp,
global_varp->SetName(global_var_decl_->getQualifiedNameAsString());
global_varp->SetLinkerSetKey(mangled_name);
global_varp->SetAccess(AccessClangToIR(global_var_decl_->getAccess()));
global_varp->SetReferencedType(
ast_caches_->GetTypeId(GetKeyForTypeId(global_var_decl_->getType())));
global_varp->SetReferencedType(GetTypeId(global_var_decl_->getType()));
return true;
}

View File

@@ -46,33 +46,35 @@ class ABIWrapper {
repr::ModuleIR *module,
ASTCaches *ast_caches);
public:
static std::string GetDeclSourceFile(const clang::Decl *decl,
const clang::CompilerInstance *cip);
static std::string GetMangledNameDecl(const clang::NamedDecl *decl,
clang::MangleContext *mangle_context);
protected:
std::string GetCachedDeclSourceFile(const clang::Decl *decl,
const clang::CompilerInstance *cip);
std::string GetKeyForTypeId(clang::QualType qual_type);
std::string TypeNameWithFinalDestination(clang::QualType qual_type);
public:
static std::string GetMangledNameDecl(const clang::NamedDecl *decl,
clang::MangleContext *mangle_context);
protected:
// Shared between FunctionDeclWrapper and RecordDeclWrapper.
bool SetupTemplateArguments(const clang::TemplateArgumentList *tl,
repr::TemplatedArtifactIR *ta,
const std::string &source_file);
protected:
// Shared between FunctionTypeWrapper and FunctionDeclWrapper.
bool SetupFunctionParameter(repr::CFunctionLikeIR *functionp,
const clang::QualType qual_type,
bool has_default_arg,
const std::string &source_file,
bool is_this_parameter = false);
std::string QualTypeToString(const clang::QualType &sweet_qt);
std::string GetTagDeclQualifiedName(const clang::TagDecl *decl);
protected:
// Type-related functions
std::string GetTypeId(clang::QualType qual_type);
bool CreateBasicNamedAndTypedDecl(clang::QualType,
const std::string &source_file);
@@ -84,14 +86,19 @@ class ABIWrapper {
bool CreateExtendedType(clang::QualType canonical_type,
repr::TypeIR *typep);
bool CreateAnonymousRecord(const clang::RecordDecl *decl);
std::string GetTypeUniqueId(const clang::TagDecl *tag_decl);
std::string GetTypeLinkageName(const clang::Type *typep);
private:
std::string QualTypeToString(const clang::QualType &sweet_qt);
std::string GetKeyForTypeId(clang::QualType qual_type);
std::string TypeNameWithFinalDestination(clang::QualType qual_type);
TypeAndCreationStatus SetTypeKind(const clang::QualType qtype,
const std::string &source_file);
std::string GetTypeUniqueId(const clang::TagDecl *tag_decl);
bool CreateAnonymousRecord(const clang::RecordDecl *decl);
protected:
const clang::CompilerInstance *cip_;

View File

@@ -130,8 +130,8 @@ void ModuleIR::AddEnumType(EnumTypeIR &&enum_type) {
}
auto it = AddToMapAndTypeGraph(
std::move(enum_type), &enum_types_, &type_graph_);
AddToODRListMap(it->second.GetUniqueId() + it->second.GetSourceFile(),
(&it->second));
const std::string &key = GetODRListMapKey(&(it->second));
AddToODRListMap(key, (&it->second));
}