Changeset View
Changeset View
Standalone View
Standalone View
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show All 28 Lines | |||||
#include "clang/Basic/Diagnostic.h" | #include "clang/Basic/Diagnostic.h" | ||||
#include "clang/Basic/FileManager.h" | #include "clang/Basic/FileManager.h" | ||||
#include "clang/Basic/FileSystemOptions.h" | #include "clang/Basic/FileSystemOptions.h" | ||||
#include "clang/Basic/LangStandard.h" | #include "clang/Basic/LangStandard.h" | ||||
#include "clang/Basic/SourceManager.h" | #include "clang/Basic/SourceManager.h" | ||||
#include "clang/Basic/TargetInfo.h" | #include "clang/Basic/TargetInfo.h" | ||||
#include "clang/Basic/TargetOptions.h" | #include "clang/Basic/TargetOptions.h" | ||||
#include "clang/Frontend/FrontendOptions.h" | #include "clang/Frontend/FrontendOptions.h" | ||||
#include "clang/Lex/HeaderSearch.h" | |||||
#include "clang/Lex/HeaderSearchOptions.h" | |||||
#include "clang/Lex/ModuleMap.h" | |||||
#include "clang/Sema/Sema.h" | #include "clang/Sema/Sema.h" | ||||
#include "llvm/Support/Signals.h" | #include "llvm/Support/Signals.h" | ||||
#include "llvm/Support/Threading.h" | #include "llvm/Support/Threading.h" | ||||
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" | #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" | ||||
#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" | #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" | ||||
#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h" | #include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h" | ||||
▲ Show 20 Lines • Show All 451 Lines • ▼ Show 20 Lines | |||||
unsigned Opt = 0; | unsigned Opt = 0; | ||||
// This is the __NO_INLINE__ define, which just depends on things like the | // This is the __NO_INLINE__ define, which just depends on things like the | ||||
// optimization level and -fno-inline, not actually whether the backend has | // optimization level and -fno-inline, not actually whether the backend has | ||||
// inlining enabled. | // inlining enabled. | ||||
// | // | ||||
// FIXME: This is affected by other options (-fno-inline). | // FIXME: This is affected by other options (-fno-inline). | ||||
Opts.NoInlineDefine = !Opt; | Opts.NoInlineDefine = !Opt; | ||||
// This is needed to allocate the extra space for the owning module | |||||
// on each decl. | |||||
Opts.ModulesLocalVisibility = 1; | |||||
} | } | ||||
TypeSystemClang::TypeSystemClang(llvm::StringRef name, | TypeSystemClang::TypeSystemClang(llvm::StringRef name, | ||||
llvm::Triple target_triple) { | llvm::Triple target_triple) { | ||||
m_display_name = name.str(); | m_display_name = name.str(); | ||||
if (!target_triple.str().empty()) | if (!target_triple.str().empty()) | ||||
SetTargetTriple(target_triple.str()); | SetTargetTriple(target_triple.str()); | ||||
// The caller didn't pass an ASTContext so create a new one for this | // The caller didn't pass an ASTContext so create a new one for this | ||||
▲ Show 20 Lines • Show All 665 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) { | CompilerType TypeSystemClang::GetTypeForDecl(ObjCInterfaceDecl *decl) { | ||||
return GetType(getASTContext().getObjCInterfaceType(decl)); | return GetType(getASTContext().getObjCInterfaceType(decl)); | ||||
} | } | ||||
#pragma mark Structure, Unions, Classes | #pragma mark Structure, Unions, Classes | ||||
CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx, | unsigned TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name, | ||||
unsigned parent, | |||||
bool is_framework, | |||||
bool is_explicit) { | |||||
// Get the external AST source which holds the modules. | |||||
auto *ast_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>( | |||||
getASTContext().getExternalSource()); | |||||
assert(ast_source && "external ast source was lost"); | |||||
if (!ast_source) | |||||
return 0; | |||||
// Lazily initialize the module map. | |||||
if (!m_header_search_up) { | |||||
auto HSOpts = std::make_shared<clang::HeaderSearchOptions>(); | |||||
m_header_search_up = std::make_unique<clang::HeaderSearch>( | |||||
HSOpts, *m_source_manager_up, *m_diagnostics_engine_up, | |||||
*m_language_options_up, m_target_info_up.get()); | |||||
m_module_map_up = std::make_unique<clang::ModuleMap>( | |||||
*m_source_manager_up, *m_diagnostics_engine_up, *m_language_options_up, | |||||
m_target_info_up.get(), *m_header_search_up); | |||||
teemperor: All the `m_*` variables that correspond to a part of ASTContext are only initialized when the… | |||||
} | |||||
// Get or create the module context. | |||||
bool created; | |||||
clang::Module *module; | |||||
auto parent_desc = ast_source->getSourceDescriptor(parent); | |||||
std::tie(module, created) = m_module_map_up->findOrCreateModule( | |||||
name, parent_desc ? parent_desc->getModuleOrNull() : nullptr, | |||||
is_framework, is_explicit); | |||||
if (!created) | |||||
return ast_source->getIDForModule(module); | |||||
module->Name = name.str(); | |||||
return ast_source->registerModule(module); | |||||
} | |||||
void TypeSystemClang::SetOwningModule(clang::Decl *decl, unsigned owning_module) { | |||||
if (!decl || !owning_module) | |||||
return; | |||||
decl->setFromASTFile(); | |||||
decl->setOwningModuleID(owning_module); | |||||
decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible); | |||||
} | |||||
CompilerType TypeSystemClang::CreateRecordType(clang::DeclContext *decl_ctx, | |||||
unsigned owning_module, | |||||
AccessType access_type, | AccessType access_type, | ||||
llvm::StringRef name, int kind, | llvm::StringRef name, int kind, | ||||
LanguageType language, | LanguageType language, | ||||
ClangASTMetadata *metadata, | ClangASTMetadata *metadata, | ||||
bool exports_symbols) { | bool exports_symbols) { | ||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
if (decl_ctx == nullptr) | if (decl_ctx == nullptr) | ||||
decl_ctx = ast.getTranslationUnitDecl(); | decl_ctx = ast.getTranslationUnitDecl(); | ||||
if (language == eLanguageTypeObjC || | if (language == eLanguageTypeObjC || | ||||
language == eLanguageTypeObjC_plus_plus) { | language == eLanguageTypeObjC_plus_plus) { | ||||
bool isForwardDecl = true; | bool isForwardDecl = true; | ||||
bool isInternal = false; | bool isInternal = false; | ||||
return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata); | return CreateObjCClass(name, decl_ctx, owning_module, isForwardDecl, | ||||
isInternal, metadata); | |||||
} | } | ||||
// NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and | // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and | ||||
// we will need to update this code. I was told to currently always use the | // we will need to update this code. I was told to currently always use the | ||||
// CXXRecordDecl class since we often don't know from debug information if | // CXXRecordDecl class since we often don't know from debug information if | ||||
// something is struct or a class, so we default to always use the more | // something is struct or a class, so we default to always use the more | ||||
// complete definition just in case. | // complete definition just in case. | ||||
bool has_name = !name.empty(); | bool has_name = !name.empty(); | ||||
CXXRecordDecl *decl = CXXRecordDecl::Create( | CXXRecordDecl *decl = CXXRecordDecl::Create( | ||||
ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), SourceLocation(), | ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), | ||||
has_name ? &ast.Idents.get(name) : nullptr); | SourceLocation(), has_name ? &ast.Idents.get(name) : nullptr); | ||||
SetOwningModule(decl, owning_module); | |||||
if (!has_name) { | if (!has_name) { | ||||
// In C++ a lambda is also represented as an unnamed class. This is | // In C++ a lambda is also represented as an unnamed class. This is | ||||
// different from an *anonymous class* that the user wrote: | // different from an *anonymous class* that the user wrote: | ||||
// | // | ||||
// struct A { | // struct A { | ||||
// // anonymous class (GNU/MSVC extension) | // // anonymous class (GNU/MSVC extension) | ||||
// struct { | // struct { | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
clang::Expr *const requires_clause = nullptr; // TODO: Concepts | clang::Expr *const requires_clause = nullptr; // TODO: Concepts | ||||
TemplateParameterList *template_param_list = TemplateParameterList::Create( | TemplateParameterList *template_param_list = TemplateParameterList::Create( | ||||
ast, SourceLocation(), SourceLocation(), template_param_decls, | ast, SourceLocation(), SourceLocation(), template_param_decls, | ||||
SourceLocation(), requires_clause); | SourceLocation(), requires_clause); | ||||
return template_param_list; | return template_param_list; | ||||
} | } | ||||
clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( | clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( | ||||
clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl, | clang::DeclContext *decl_ctx, unsigned owning_module, | ||||
const char *name, const TemplateParameterInfos &template_param_infos) { | clang::FunctionDecl *func_decl, const char *name, | ||||
const TemplateParameterInfos &template_param_infos) { | |||||
// /// Create a function template node. | // /// Create a function template node. | ||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
llvm::SmallVector<NamedDecl *, 8> template_param_decls; | llvm::SmallVector<NamedDecl *, 8> template_param_decls; | ||||
TemplateParameterList *template_param_list = CreateTemplateParameterList( | TemplateParameterList *template_param_list = CreateTemplateParameterList( | ||||
ast, template_param_infos, template_param_decls); | ast, template_param_infos, template_param_decls); | ||||
FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create( | FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create( | ||||
ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(), | ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(), | ||||
template_param_list, func_decl); | template_param_list, func_decl); | ||||
SetOwningModule(func_tmpl_decl, owning_module); | |||||
for (size_t i = 0, template_param_decl_count = template_param_decls.size(); | for (size_t i = 0, template_param_decl_count = template_param_decls.size(); | ||||
i < template_param_decl_count; ++i) { | i < template_param_decl_count; ++i) { | ||||
// TODO: verify which decl context we should put template_param_decls into.. | // TODO: verify which decl context we should put template_param_decls into.. | ||||
template_param_decls[i]->setDeclContext(func_decl); | template_param_decls[i]->setDeclContext(func_decl); | ||||
} | } | ||||
// Function templates inside a record need to have an access specifier. | // Function templates inside a record need to have an access specifier. | ||||
// It doesn't matter what access specifier we give the template as LLDB | // It doesn't matter what access specifier we give the template as LLDB | ||||
Show All 10 Lines | |||||
TemplateArgumentList *template_args_ptr = | TemplateArgumentList *template_args_ptr = | ||||
TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args); | TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args); | ||||
func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, | func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, | ||||
template_args_ptr, nullptr); | template_args_ptr, nullptr); | ||||
} | } | ||||
ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( | ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( | ||||
DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name, | DeclContext *decl_ctx, unsigned owning_module, lldb::AccessType access_type, | ||||
int kind, const TemplateParameterInfos &template_param_infos) { | const char *class_name, int kind, | ||||
const TemplateParameterInfos &template_param_infos) { | |||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
ClassTemplateDecl *class_template_decl = nullptr; | ClassTemplateDecl *class_template_decl = nullptr; | ||||
if (decl_ctx == nullptr) | if (decl_ctx == nullptr) | ||||
decl_ctx = ast.getTranslationUnitDecl(); | decl_ctx = ast.getTranslationUnitDecl(); | ||||
IdentifierInfo &identifier_info = ast.Idents.get(class_name); | IdentifierInfo &identifier_info = ast.Idents.get(class_name); | ||||
DeclarationName decl_name(&identifier_info); | DeclarationName decl_name(&identifier_info); | ||||
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); | clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); | ||||
for (NamedDecl *decl : result) { | for (NamedDecl *decl : result) { | ||||
class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl); | class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl); | ||||
if (class_template_decl) | if (class_template_decl) | ||||
return class_template_decl; | return class_template_decl; | ||||
} | } | ||||
llvm::SmallVector<NamedDecl *, 8> template_param_decls; | llvm::SmallVector<NamedDecl *, 8> template_param_decls; | ||||
TemplateParameterList *template_param_list = CreateTemplateParameterList( | TemplateParameterList *template_param_list = CreateTemplateParameterList( | ||||
ast, template_param_infos, template_param_decls); | ast, template_param_infos, template_param_decls); | ||||
CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create( | CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create( | ||||
ast, (TagDecl::TagKind)kind, | ast, (TagDecl::TagKind)kind, | ||||
decl_ctx, // What decl context do we use here? TU? The actual decl | decl_ctx, // What decl context do we use here? TU? The actual | ||||
// context? | // decl context? | ||||
labathUnsubmitted bad formatting labath: bad formatting | |||||
SourceLocation(), SourceLocation(), &identifier_info); | SourceLocation(), SourceLocation(), &identifier_info); | ||||
SetOwningModule(template_cxx_decl, owning_module); | |||||
for (size_t i = 0, template_param_decl_count = template_param_decls.size(); | for (size_t i = 0, template_param_decl_count = template_param_decls.size(); | ||||
i < template_param_decl_count; ++i) { | i < template_param_decl_count; ++i) { | ||||
template_param_decls[i]->setDeclContext(template_cxx_decl); | template_param_decls[i]->setDeclContext(template_cxx_decl); | ||||
} | } | ||||
// With templated classes, we say that a class is templated with | // With templated classes, we say that a class is templated with | ||||
// specializations, but that the bare class has no functions. | // specializations, but that the bare class has no functions. | ||||
// template_cxx_decl->startDefinition(); | // template_cxx_decl->startDefinition(); | ||||
// template_cxx_decl->completeDefinition(); | // template_cxx_decl->completeDefinition(); | ||||
class_template_decl = ClassTemplateDecl::Create( | class_template_decl = ClassTemplateDecl::Create( | ||||
ast, | ast, | ||||
decl_ctx, // What decl context do we use here? TU? The actual decl | decl_ctx, // What decl context do we use here? TU? The actual | ||||
// context? | // decl context? | ||||
SourceLocation(), decl_name, template_param_list, template_cxx_decl); | SourceLocation(), decl_name, template_param_list, template_cxx_decl); | ||||
template_cxx_decl->setDescribedClassTemplate(class_template_decl); | template_cxx_decl->setDescribedClassTemplate(class_template_decl); | ||||
SetOwningModule(class_template_decl, owning_module); | |||||
if (class_template_decl) { | if (class_template_decl) { | ||||
if (access_type != eAccessNone) | if (access_type != eAccessNone) | ||||
class_template_decl->setAccess( | class_template_decl->setAccess( | ||||
ConvertAccessTypeToAccessSpecifier(access_type)); | ConvertAccessTypeToAccessSpecifier(access_type)); | ||||
decl_ctx->addDecl(class_template_decl); | decl_ctx->addDecl(class_template_decl); | ||||
Show All 23 Lines | |||||
return TemplateTemplateParmDecl::Create( | return TemplateTemplateParmDecl::Create( | ||||
ast, decl_ctx, SourceLocation(), | ast, decl_ctx, SourceLocation(), | ||||
/*Depth*/ 0, /*Position*/ 0, | /*Depth*/ 0, /*Position*/ 0, | ||||
/*IsParameterPack*/ false, &identifier_info, template_param_list); | /*IsParameterPack*/ false, &identifier_info, template_param_list); | ||||
} | } | ||||
ClassTemplateSpecializationDecl * | ClassTemplateSpecializationDecl * | ||||
TypeSystemClang::CreateClassTemplateSpecializationDecl( | TypeSystemClang::CreateClassTemplateSpecializationDecl( | ||||
DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind, | DeclContext *decl_ctx, unsigned owning_module, | ||||
ClassTemplateDecl *class_template_decl, int kind, | |||||
const TemplateParameterInfos &template_param_infos) { | const TemplateParameterInfos &template_param_infos) { | ||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
llvm::SmallVector<clang::TemplateArgument, 2> args( | llvm::SmallVector<clang::TemplateArgument, 2> args( | ||||
template_param_infos.args.size() + | template_param_infos.args.size() + | ||||
(template_param_infos.packed_args ? 1 : 0)); | (template_param_infos.packed_args ? 1 : 0)); | ||||
std::copy(template_param_infos.args.begin(), template_param_infos.args.end(), | std::copy(template_param_infos.args.begin(), template_param_infos.args.end(), | ||||
args.begin()); | args.begin()); | ||||
if (template_param_infos.packed_args) { | if (template_param_infos.packed_args) { | ||||
args[args.size() - 1] = TemplateArgument::CreatePackCopy( | args[args.size() - 1] = TemplateArgument::CreatePackCopy( | ||||
ast, template_param_infos.packed_args->args); | ast, template_param_infos.packed_args->args); | ||||
} | } | ||||
ClassTemplateSpecializationDecl *class_template_specialization_decl = | ClassTemplateSpecializationDecl *class_template_specialization_decl = | ||||
ClassTemplateSpecializationDecl::Create( | ClassTemplateSpecializationDecl::Create( | ||||
ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), | ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), | ||||
SourceLocation(), class_template_decl, args, nullptr); | SourceLocation(), class_template_decl, args, nullptr); | ||||
SetOwningModule(class_template_decl, owning_module); | |||||
class_template_specialization_decl->setSpecializationKind( | class_template_specialization_decl->setSpecializationKind( | ||||
TSK_ExplicitSpecialization); | TSK_ExplicitSpecialization); | ||||
return class_template_specialization_decl; | return class_template_specialization_decl; | ||||
} | } | ||||
CompilerType TypeSystemClang::CreateClassTemplateSpecializationType( | CompilerType TypeSystemClang::CreateClassTemplateSpecializationType( | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
#pragma mark Objective-C Classes | #pragma mark Objective-C Classes | ||||
CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name, | CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name, | ||||
DeclContext *decl_ctx, | clang::DeclContext *decl_ctx, | ||||
unsigned owning_module, | |||||
bool isForwardDecl, | bool isForwardDecl, | ||||
bool isInternal, | bool isInternal, | ||||
ClangASTMetadata *metadata) { | ClangASTMetadata *metadata) { | ||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
assert(!name.empty()); | assert(!name.empty()); | ||||
if (decl_ctx == nullptr) | if (!decl_ctx) | ||||
decl_ctx = ast.getTranslationUnitDecl(); | decl_ctx = ast.getTranslationUnitDecl(); | ||||
ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create( | ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create( | ||||
ast, decl_ctx, SourceLocation(), &ast.Idents.get(name), nullptr, nullptr, | ast, decl_ctx, SourceLocation(), &ast.Idents.get(name), nullptr, nullptr, | ||||
SourceLocation(), | SourceLocation(), | ||||
/*isForwardDecl,*/ | /*isForwardDecl,*/ | ||||
isInternal); | isInternal); | ||||
SetOwningModule(decl, owning_module); | |||||
if (decl && metadata) | if (decl && metadata) | ||||
SetMetadata(decl, *metadata); | SetMetadata(decl, *metadata); | ||||
return GetType(ast.getObjCInterfaceType(decl)); | return GetType(ast.getObjCInterfaceType(decl)); | ||||
} | } | ||||
static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) { | static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) { | ||||
Show All 21 Lines | |||||
num_bases = cxx_record_decl->getNumBases(); | num_bases = cxx_record_decl->getNumBases(); | ||||
} | } | ||||
return num_bases; | return num_bases; | ||||
} | } | ||||
#pragma mark Namespace Declarations | #pragma mark Namespace Declarations | ||||
NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration( | NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration( | ||||
const char *name, DeclContext *decl_ctx, bool is_inline) { | const char *name, clang::DeclContext *decl_ctx, unsigned owning_module, | ||||
bool is_inline) { | |||||
NamespaceDecl *namespace_decl = nullptr; | NamespaceDecl *namespace_decl = nullptr; | ||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl(); | TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl(); | ||||
if (decl_ctx == nullptr) | if (!decl_ctx) | ||||
decl_ctx = translation_unit_decl; | decl_ctx = translation_unit_decl; | ||||
if (name) { | if (name) { | ||||
IdentifierInfo &identifier_info = ast.Idents.get(name); | IdentifierInfo &identifier_info = ast.Idents.get(name); | ||||
DeclarationName decl_name(&identifier_info); | DeclarationName decl_name(&identifier_info); | ||||
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); | clang::DeclContext::lookup_result result = | ||||
decl_ctx->lookup(decl_name); | |||||
for (NamedDecl *decl : result) { | for (NamedDecl *decl : result) { | ||||
namespace_decl = dyn_cast<clang::NamespaceDecl>(decl); | namespace_decl = dyn_cast<clang::NamespaceDecl>(decl); | ||||
if (namespace_decl) | if (namespace_decl) | ||||
return namespace_decl; | return namespace_decl; | ||||
} | } | ||||
namespace_decl = | namespace_decl = | ||||
NamespaceDecl::Create(ast, decl_ctx, is_inline, SourceLocation(), | NamespaceDecl::Create(ast, decl_ctx, is_inline, SourceLocation(), | ||||
Show All 26 Lines | |||||
assert(namespace_decl == | assert(namespace_decl == | ||||
parent_namespace_decl->getAnonymousNamespace()); | parent_namespace_decl->getAnonymousNamespace()); | ||||
} else { | } else { | ||||
assert(false && "GetUniqueNamespaceDeclaration called with no name and " | assert(false && "GetUniqueNamespaceDeclaration called with no name and " | ||||
"no namespace as decl_ctx"); | "no namespace as decl_ctx"); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Note: namespaces can span multiple modules, so perhaps this isn't a good idea. | |||||
SetOwningModule(namespace_decl, owning_module); | |||||
VerifyDecl(namespace_decl); | VerifyDecl(namespace_decl); | ||||
return namespace_decl; | return namespace_decl; | ||||
} | } | ||||
clang::BlockDecl * | clang::BlockDecl * | ||||
TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx) { | TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx, | ||||
if (ctx != nullptr) { | unsigned owning_module) { | ||||
clang::BlockDecl *decl = | if (ctx) { | ||||
clang::BlockDecl::Create(getASTContext(), ctx, clang::SourceLocation()); | clang::BlockDecl *decl = clang::BlockDecl::Create( | ||||
getASTContext(), ctx, clang::SourceLocation()); | |||||
ctx->addDecl(decl); | ctx->addDecl(decl); | ||||
SetOwningModule(decl, owning_module); | |||||
return decl; | return decl; | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left, | clang::DeclContext *FindLCABetweenDecls(clang::DeclContext *left, | ||||
clang::DeclContext *right, | clang::DeclContext *right, | ||||
clang::DeclContext *root) { | clang::DeclContext *root) { | ||||
if (root == nullptr) | if (root == nullptr) | ||||
return nullptr; | return nullptr; | ||||
std::set<clang::DeclContext *> path_left; | std::set<clang::DeclContext *> path_left; | ||||
for (clang::DeclContext *d = left; d != nullptr; d = d->getParent()) | for (clang::DeclContext *d = left; d != nullptr; d = d->getParent()) | ||||
path_left.insert(d); | path_left.insert(d); | ||||
for (clang::DeclContext *d = right; d != nullptr; d = d->getParent()) | for (clang::DeclContext *d = right; d != nullptr; d = d->getParent()) | ||||
if (path_left.find(d) != path_left.end()) | if (path_left.find(d) != path_left.end()) | ||||
return d; | return d; | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration( | clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration( | ||||
clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) { | clang::DeclContext *decl_ctx, unsigned owning_module, | ||||
if (decl_ctx != nullptr && ns_decl != nullptr) { | clang::NamespaceDecl *ns_decl) { | ||||
if (decl_ctx && ns_decl) { | |||||
auto *translation_unit = getASTContext().getTranslationUnitDecl(); | auto *translation_unit = getASTContext().getTranslationUnitDecl(); | ||||
clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create( | clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create( | ||||
getASTContext(), decl_ctx, clang::SourceLocation(), | getASTContext(), decl_ctx, clang::SourceLocation(), | ||||
clang::SourceLocation(), clang::NestedNameSpecifierLoc(), | clang::SourceLocation(), clang::NestedNameSpecifierLoc(), | ||||
clang::SourceLocation(), ns_decl, | clang::SourceLocation(), ns_decl, | ||||
FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit)); | FindLCABetweenDecls(decl_ctx, ns_decl, | ||||
decl_ctx->addDecl(using_decl); | translation_unit)); | ||||
return using_decl; | decl_ctx->addDecl(using_decl); | ||||
SetOwningModule(using_decl, owning_module); | |||||
return using_decl; | |||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
clang::UsingDecl * | clang::UsingDecl * | ||||
TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, | TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, | ||||
unsigned owning_module, | |||||
clang::NamedDecl *target) { | clang::NamedDecl *target) { | ||||
if (current_decl_ctx != nullptr && target != nullptr) { | if (current_decl_ctx && target) { | ||||
clang::UsingDecl *using_decl = clang::UsingDecl::Create( | clang::UsingDecl *using_decl = clang::UsingDecl::Create( | ||||
getASTContext(), current_decl_ctx, clang::SourceLocation(), | getASTContext(), current_decl_ctx, clang::SourceLocation(), | ||||
clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false); | clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false); | ||||
SetOwningModule(using_decl, owning_module); | |||||
clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create( | clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create( | ||||
getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl, | getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl, | ||||
target); | target); | ||||
SetOwningModule(shadow_decl, owning_module); | |||||
using_decl->addShadowDecl(shadow_decl); | using_decl->addShadowDecl(shadow_decl); | ||||
current_decl_ctx->addDecl(using_decl); | current_decl_ctx->addDecl(using_decl); | ||||
return using_decl; | return using_decl; | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
clang::VarDecl *TypeSystemClang::CreateVariableDeclaration( | clang::VarDecl *TypeSystemClang::CreateVariableDeclaration( | ||||
clang::DeclContext *decl_context, const char *name, clang::QualType type) { | clang::DeclContext *decl_context, unsigned owning_module, const char *name, | ||||
if (decl_context != nullptr) { | clang::QualType type) { | ||||
if (decl_context) { | |||||
clang::VarDecl *var_decl = clang::VarDecl::Create( | clang::VarDecl *var_decl = clang::VarDecl::Create( | ||||
getASTContext(), decl_context, clang::SourceLocation(), | getASTContext(), decl_context, clang::SourceLocation(), | ||||
clang::SourceLocation(), | clang::SourceLocation(), | ||||
name && name[0] ? &getASTContext().Idents.getOwn(name) : nullptr, type, | name && name[0] ? &getASTContext().Idents.getOwn(name) : nullptr, type, | ||||
nullptr, clang::SC_None); | nullptr, clang::SC_None); | ||||
SetOwningModule(var_decl, owning_module); | |||||
var_decl->setAccess(clang::AS_public); | var_decl->setAccess(clang::AS_public); | ||||
decl_context->addDecl(var_decl); | decl_context->addDecl(var_decl); | ||||
return var_decl; | return var_decl; | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
lldb::opaque_compiler_type_t | lldb::opaque_compiler_type_t | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount( | if (!TypeSystemClang::CheckOverloadedOperatorKindParameterCount( | ||||
is_method, op_kind, num_params)) | is_method, op_kind, num_params)) | ||||
return clang::DeclarationName(); | return clang::DeclarationName(); | ||||
return getASTContext().DeclarationNames.getCXXOperatorName(op_kind); | return getASTContext().DeclarationNames.getCXXOperatorName(op_kind); | ||||
} | } | ||||
FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( | FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( | ||||
DeclContext *decl_ctx, const char *name, | clang::DeclContext *decl_ctx, unsigned owning_module, const char *name, | ||||
const CompilerType &function_clang_type, int storage, bool is_inline) { | const CompilerType &function_clang_type, int storage, bool is_inline) { | ||||
FunctionDecl *func_decl = nullptr; | FunctionDecl *func_decl = nullptr; | ||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
if (decl_ctx == nullptr) | if (!decl_ctx) | ||||
decl_ctx = ast.getTranslationUnitDecl(); | decl_ctx = ast.getTranslationUnitDecl(); | ||||
const bool hasWrittenPrototype = true; | const bool hasWrittenPrototype = true; | ||||
const bool isConstexprSpecified = false; | const bool isConstexprSpecified = false; | ||||
clang::DeclarationName declarationName = | clang::DeclarationName declarationName = | ||||
GetDeclarationName(name, function_clang_type); | GetDeclarationName(name, function_clang_type); | ||||
func_decl = FunctionDecl::Create( | func_decl = FunctionDecl::Create( | ||||
ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName, | ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName, | ||||
ClangUtil::GetQualType(function_clang_type), nullptr, | ClangUtil::GetQualType(function_clang_type), nullptr, | ||||
(clang::StorageClass)storage, is_inline, hasWrittenPrototype, | (clang::StorageClass)storage, is_inline, hasWrittenPrototype, | ||||
isConstexprSpecified ? CSK_constexpr : CSK_unspecified); | isConstexprSpecified ? CSK_constexpr : CSK_unspecified); | ||||
SetOwningModule(func_decl, owning_module); | |||||
if (func_decl) | if (func_decl) | ||||
decl_ctx->addDecl(func_decl); | decl_ctx->addDecl(func_decl); | ||||
VerifyDecl(func_decl); | VerifyDecl(func_decl); | ||||
return func_decl; | return func_decl; | ||||
} | } | ||||
Show All 32 Lines | |||||
proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals); | proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals); | ||||
proto_info.RefQualifier = RQ_None; | proto_info.RefQualifier = RQ_None; | ||||
return GetType(getASTContext().getFunctionType( | return GetType(getASTContext().getFunctionType( | ||||
ClangUtil::GetQualType(result_type), qual_type_args, proto_info)); | ClangUtil::GetQualType(result_type), qual_type_args, proto_info)); | ||||
} | } | ||||
ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( | ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( | ||||
clang::DeclContext *decl_ctx, const char *name, | clang::DeclContext *decl_ctx, unsigned owning_module, const char *name, | ||||
const CompilerType ¶m_type, int storage, bool add_decl) { | const CompilerType ¶m_type, int storage, bool add_decl) { | ||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
auto *decl = | auto *decl = | ||||
ParmVarDecl::Create(ast, decl_ctx, SourceLocation(), SourceLocation(), | ParmVarDecl::Create(ast, decl_ctx, SourceLocation(), SourceLocation(), | ||||
name && name[0] ? &ast.Idents.get(name) : nullptr, | name && name[0] ? &ast.Idents.get(name) : nullptr, | ||||
ClangUtil::GetQualType(param_type), nullptr, | ClangUtil::GetQualType(param_type), nullptr, | ||||
(clang::StorageClass)storage, nullptr); | (clang::StorageClass)storage, nullptr); | ||||
SetOwningModule(decl, owning_module); | |||||
if (add_decl) | if (add_decl) | ||||
decl_ctx->addDecl(decl); | decl_ctx->addDecl(decl); | ||||
return decl; | return decl; | ||||
} | } | ||||
void TypeSystemClang::SetFunctionParameters(FunctionDecl *function_decl, | void TypeSystemClang::SetFunctionParameters(FunctionDecl *function_decl, | ||||
ParmVarDecl **params, | ParmVarDecl **params, | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
CompilerType type; | CompilerType type; | ||||
if (!type_name.IsEmpty() && | if (!type_name.IsEmpty() && | ||||
(type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)) | (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)) | ||||
.IsValid()) { | .IsValid()) { | ||||
lldbassert(0 && "Trying to create a type for an existing name"); | lldbassert(0 && "Trying to create a type for an existing name"); | ||||
return type; | return type; | ||||
} | } | ||||
type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), | type = | ||||
clang::TTK_Struct, lldb::eLanguageTypeC); | CreateRecordType(nullptr, 0, lldb::eAccessPublic, type_name.GetCString(), | ||||
clang::TTK_Struct, lldb::eLanguageTypeC); | |||||
StartTagDeclarationDefinition(type); | StartTagDeclarationDefinition(type); | ||||
for (const auto &field : type_fields) | for (const auto &field : type_fields) | ||||
AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic, | AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic, | ||||
0); | 0); | ||||
if (packed) | if (packed) | ||||
SetIsPacked(type); | SetIsPacked(type); | ||||
CompleteTagDeclarationDefinition(type); | CompleteTagDeclarationDefinition(type); | ||||
return type; | return type; | ||||
} | } | ||||
CompilerType TypeSystemClang::GetOrCreateStructForIdentifier( | CompilerType TypeSystemClang::GetOrCreateStructForIdentifier( | ||||
ConstString type_name, | ConstString type_name, | ||||
const std::initializer_list<std::pair<const char *, CompilerType>> | const std::initializer_list<std::pair<const char *, CompilerType>> | ||||
&type_fields, | &type_fields, | ||||
bool packed) { | bool packed) { | ||||
CompilerType type; | CompilerType type; | ||||
if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid()) | if ((type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)).IsValid()) | ||||
return type; | return type; | ||||
return CreateStructForIdentifier(type_name, type_fields, packed); | return CreateStructForIdentifier(type_name, type_fields, packed); | ||||
} | } | ||||
#pragma mark Enumeration Types | #pragma mark Enumeration Types | ||||
CompilerType | CompilerType TypeSystemClang::CreateEnumerationType( | ||||
TypeSystemClang::CreateEnumerationType(const char *name, DeclContext *decl_ctx, | const char *name, clang::DeclContext *decl_ctx, unsigned owning_module, | ||||
const Declaration &decl, | const Declaration &decl, const CompilerType &integer_clang_type, | ||||
const CompilerType &integer_clang_type, | bool is_scoped) { | ||||
bool is_scoped) { | |||||
// TODO: Do something intelligent with the Declaration object passed in | // TODO: Do something intelligent with the Declaration object passed in | ||||
// like maybe filling in the SourceLocation with it... | // like maybe filling in the SourceLocation with it... | ||||
ASTContext &ast = getASTContext(); | ASTContext &ast = getASTContext(); | ||||
// TODO: ask about these... | |||||
// const bool IsFixed = false; | |||||
EnumDecl *enum_decl = EnumDecl::Create( | EnumDecl *enum_decl = EnumDecl::Create( | ||||
ast, decl_ctx, SourceLocation(), SourceLocation(), | ast, decl_ctx, SourceLocation(), SourceLocation(), | ||||
name && name[0] ? &ast.Idents.get(name) : nullptr, nullptr, | name && name[0] ? &ast.Idents.get(name) : nullptr, nullptr, | ||||
is_scoped, // IsScoped | is_scoped, // IsScoped | ||||
is_scoped, // IsScopedUsingClassTag | is_scoped, // IsScopedUsingClassTag | ||||
false); // TODO: IsFixed | false); // TODO: IsFixed | ||||
SetOwningModule(enum_decl, owning_module); | |||||
if (enum_decl) { | if (enum_decl) { | ||||
if (decl_ctx) | if (decl_ctx) | ||||
decl_ctx->addDecl(enum_decl); | decl_ctx->addDecl(enum_decl); | ||||
// TODO: check if we should be setting the promotion type too? | // TODO: check if we should be setting the promotion type too? | ||||
enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); | enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); | ||||
enum_decl->setAccess(AS_public); // TODO respect what's in the debug info | enum_decl->setAccess(AS_public); // TODO respect what's in the debug info | ||||
▲ Show 20 Lines • Show All 1,982 Lines • ▼ Show 20 Lines | |||||
TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) { | TypeSystemClang::GetNonReferenceType(lldb::opaque_compiler_type_t type) { | ||||
if (type) | if (type) | ||||
return GetType(GetQualType(type).getNonReferenceType()); | return GetType(GetQualType(type).getNonReferenceType()); | ||||
return CompilerType(); | return CompilerType(); | ||||
} | } | ||||
CompilerType TypeSystemClang::CreateTypedefType( | CompilerType TypeSystemClang::CreateTypedefType( | ||||
const CompilerType &type, const char *typedef_name, | const CompilerType &type, const char *typedef_name, | ||||
const CompilerDeclContext &compiler_decl_ctx) { | const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) { | ||||
if (type && typedef_name && typedef_name[0]) { | if (type && typedef_name && typedef_name[0]) { | ||||
TypeSystemClang *ast = | TypeSystemClang *ast = | ||||
llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem()); | ||||
if (!ast) | if (!ast) | ||||
return CompilerType(); | return CompilerType(); | ||||
clang::ASTContext &clang_ast = ast->getASTContext(); | clang::ASTContext &clang_ast = ast->getASTContext(); | ||||
clang::QualType qual_type(ClangUtil::GetQualType(type)); | clang::QualType qual_type(ClangUtil::GetQualType(type)); | ||||
clang::DeclContext *decl_ctx = | clang::DeclContext *decl_ctx = | ||||
TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); | TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); | ||||
if (decl_ctx == nullptr) | if (!decl_ctx) | ||||
decl_ctx = ast->getASTContext().getTranslationUnitDecl(); | decl_ctx = ast->getASTContext().getTranslationUnitDecl(); | ||||
clang::TypedefDecl *decl = clang::TypedefDecl::Create( | clang::TypedefDecl *decl = clang::TypedefDecl::Create( | ||||
clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), | clang_ast, decl_ctx, clang::SourceLocation(), | ||||
&clang_ast.Idents.get(typedef_name), | clang::SourceLocation(), &clang_ast.Idents.get(typedef_name), | ||||
clang_ast.getTrivialTypeSourceInfo(qual_type)); | clang_ast.getTrivialTypeSourceInfo(qual_type)); | ||||
SetOwningModule(decl, TypePayloadClang(payload).GetOwningModuleID()); | |||||
decl->setAccess(clang::AS_public); // TODO respect proper access specifier | decl->setAccess(clang::AS_public); // TODO respect proper access specifier | ||||
decl_ctx->addDecl(decl); | decl_ctx->addDecl(decl); | ||||
// Get a uniqued clang::QualType for the typedef decl type | // Get a uniqued clang::QualType for the typedef decl type | ||||
return ast->GetType(clang_ast.getTypedefType(decl)); | return ast->GetType(clang_ast.getTypedefType(decl)); | ||||
} | } | ||||
return CompilerType(); | return CompilerType(); | ||||
▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
if (type) { | if (type) { | ||||
clang::QualType result(GetQualType(type)); | clang::QualType result(GetQualType(type)); | ||||
result.addRestrict(); | result.addRestrict(); | ||||
return GetType(result); | return GetType(result); | ||||
} | } | ||||
return CompilerType(); | return CompilerType(); | ||||
} | } | ||||
CompilerType | CompilerType TypeSystemClang::CreateTypedef( | ||||
TypeSystemClang::CreateTypedef(lldb::opaque_compiler_type_t type, | lldb::opaque_compiler_type_t type, const char *typedef_name, | ||||
const char *typedef_name, | const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) { | ||||
const CompilerDeclContext &compiler_decl_ctx) { | |||||
if (type) { | if (type) { | ||||
clang::ASTContext &clang_ast = getASTContext(); | clang::ASTContext &clang_ast = getASTContext(); | ||||
clang::QualType qual_type(GetQualType(type)); | clang::QualType qual_type(GetQualType(type)); | ||||
clang::DeclContext *decl_ctx = | clang::DeclContext *decl_ctx = | ||||
TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); | TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); | ||||
if (decl_ctx == nullptr) | if (!decl_ctx) | ||||
decl_ctx = getASTContext().getTranslationUnitDecl(); | decl_ctx = getASTContext().getTranslationUnitDecl(); | ||||
clang::TypedefDecl *decl = clang::TypedefDecl::Create( | clang::TypedefDecl *decl = clang::TypedefDecl::Create( | ||||
clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), | clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), | ||||
&clang_ast.Idents.get(typedef_name), | &clang_ast.Idents.get(typedef_name), | ||||
clang_ast.getTrivialTypeSourceInfo(qual_type)); | clang_ast.getTrivialTypeSourceInfo(qual_type)); | ||||
SetOwningModule(decl, TypePayloadClang(payload).GetOwningModuleID()); | |||||
clang::TagDecl *tdecl = nullptr; | clang::TagDecl *tdecl = nullptr; | ||||
if (!qual_type.isNull()) { | if (!qual_type.isNull()) { | ||||
if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>()) | if (const clang::RecordType *rt = qual_type->getAs<clang::RecordType>()) | ||||
tdecl = rt->getDecl(); | tdecl = rt->getDecl(); | ||||
if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>()) | if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>()) | ||||
tdecl = et->getDecl(); | tdecl = et->getDecl(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,982 Lines • ▼ Show 20 Lines | |||||
const clang::ObjCObjectType *objc_class_type = | const clang::ObjCObjectType *objc_class_type = | ||||
llvm::dyn_cast<clang::ObjCObjectType>( | llvm::dyn_cast<clang::ObjCObjectType>( | ||||
ClangUtil::GetCanonicalQualType(type)); | ClangUtil::GetCanonicalQualType(type)); | ||||
if (objc_class_type) | if (objc_class_type) | ||||
return objc_class_type->getInterface(); | return objc_class_type->getInterface(); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
static void SetMemberOwningModule(clang::Decl *member, | |||||
const clang::Decl *parent) { | |||||
if (!member || !parent) | |||||
return; | |||||
unsigned id = parent->getOwningModuleID(); | |||||
if (!id) | |||||
return; | |||||
member->setFromASTFile(); | |||||
member->setOwningModuleID(id); | |||||
member->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible); | |||||
} | |||||
clang::FieldDecl *TypeSystemClang::AddFieldToRecordType( | clang::FieldDecl *TypeSystemClang::AddFieldToRecordType( | ||||
const CompilerType &type, llvm::StringRef name, | const CompilerType &type, llvm::StringRef name, | ||||
const CompilerType &field_clang_type, AccessType access, | const CompilerType &field_clang_type, AccessType access, | ||||
uint32_t bitfield_bit_size) { | uint32_t bitfield_bit_size) { | ||||
if (!type.IsValid() || !field_clang_type.IsValid()) | if (!type.IsValid() || !field_clang_type.IsValid()) | ||||
return nullptr; | return nullptr; | ||||
TypeSystemClang *ast = | TypeSystemClang *ast = | ||||
llvm::dyn_cast_or_null<TypeSystemClang>(type.GetTypeSystem()); | llvm::dyn_cast_or_null<TypeSystemClang>(type.GetTypeSystem()); | ||||
Show All 21 Lines | |||||
clang_ast, record_decl, clang::SourceLocation(), | clang_ast, record_decl, clang::SourceLocation(), | ||||
clang::SourceLocation(), | clang::SourceLocation(), | ||||
ident, // Identifier | ident, // Identifier | ||||
ClangUtil::GetQualType(field_clang_type), // Field type | ClangUtil::GetQualType(field_clang_type), // Field type | ||||
nullptr, // TInfo * | nullptr, // TInfo * | ||||
bit_width, // BitWidth | bit_width, // BitWidth | ||||
false, // Mutable | false, // Mutable | ||||
clang::ICIS_NoInit); // HasInit | clang::ICIS_NoInit); // HasInit | ||||
SetMemberOwningModule(field, record_decl); | |||||
if (name.empty()) { | if (name.empty()) { | ||||
// Determine whether this field corresponds to an anonymous struct or | // Determine whether this field corresponds to an anonymous struct or | ||||
// union. | // union. | ||||
if (const clang::TagType *TagT = | if (const clang::TagType *TagT = | ||||
field->getType()->getAs<clang::TagType>()) { | field->getType()->getAs<clang::TagType>()) { | ||||
if (clang::RecordDecl *Rec = | if (clang::RecordDecl *Rec = | ||||
llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl())) | llvm::dyn_cast<clang::RecordDecl>(TagT->getDecl())) | ||||
Show All 24 Lines | |||||
field = clang::ObjCIvarDecl::Create( | field = clang::ObjCIvarDecl::Create( | ||||
clang_ast, class_interface_decl, clang::SourceLocation(), | clang_ast, class_interface_decl, clang::SourceLocation(), | ||||
clang::SourceLocation(), | clang::SourceLocation(), | ||||
ident, // Identifier | ident, // Identifier | ||||
ClangUtil::GetQualType(field_clang_type), // Field type | ClangUtil::GetQualType(field_clang_type), // Field type | ||||
nullptr, // TypeSourceInfo * | nullptr, // TypeSourceInfo * | ||||
ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, | ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, | ||||
is_synthesized); | is_synthesized); | ||||
SetMemberOwningModule(field, class_interface_decl); | |||||
if (field) { | if (field) { | ||||
class_interface_decl->addDecl(field); | class_interface_decl->addDecl(field); | ||||
VerifyDecl(field); | VerifyDecl(field); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
new (ast->getASTContext()) clang::NamedDecl *[2]; | new (ast->getASTContext()) clang::NamedDecl *[2]; | ||||
chain[0] = *field_pos; | chain[0] = *field_pos; | ||||
chain[1] = nested_field_decl; | chain[1] = nested_field_decl; | ||||
clang::IndirectFieldDecl *indirect_field = | clang::IndirectFieldDecl *indirect_field = | ||||
clang::IndirectFieldDecl::Create( | clang::IndirectFieldDecl::Create( | ||||
ast->getASTContext(), record_decl, clang::SourceLocation(), | ast->getASTContext(), record_decl, clang::SourceLocation(), | ||||
nested_field_decl->getIdentifier(), | nested_field_decl->getIdentifier(), | ||||
nested_field_decl->getType(), {chain, 2}); | nested_field_decl->getType(), {chain, 2}); | ||||
SetMemberOwningModule(indirect_field, record_decl); | |||||
indirect_field->setImplicit(); | indirect_field->setImplicit(); | ||||
indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( | indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( | ||||
field_pos->getAccess(), nested_field_decl->getAccess())); | field_pos->getAccess(), nested_field_decl->getAccess())); | ||||
indirect_fields.push_back(indirect_field); | indirect_fields.push_back(indirect_field); | ||||
} else if (clang::IndirectFieldDecl *nested_indirect_field_decl = | } else if (clang::IndirectFieldDecl *nested_indirect_field_decl = | ||||
Show All 14 Lines | |||||
} | } | ||||
clang::IndirectFieldDecl *indirect_field = | clang::IndirectFieldDecl *indirect_field = | ||||
clang::IndirectFieldDecl::Create( | clang::IndirectFieldDecl::Create( | ||||
ast->getASTContext(), record_decl, clang::SourceLocation(), | ast->getASTContext(), record_decl, clang::SourceLocation(), | ||||
nested_indirect_field_decl->getIdentifier(), | nested_indirect_field_decl->getIdentifier(), | ||||
nested_indirect_field_decl->getType(), | nested_indirect_field_decl->getType(), | ||||
{chain, nested_chain_size + 1}); | {chain, nested_chain_size + 1}); | ||||
SetMemberOwningModule(indirect_field, record_decl); | |||||
indirect_field->setImplicit(); | indirect_field->setImplicit(); | ||||
indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( | indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( | ||||
field_pos->getAccess(), nested_indirect_field_decl->getAccess())); | field_pos->getAccess(), nested_indirect_field_decl->getAccess())); | ||||
indirect_fields.push_back(indirect_field); | indirect_fields.push_back(indirect_field); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
ast->getASTContext(), // ASTContext & | ast->getASTContext(), // ASTContext & | ||||
record_decl, // DeclContext * | record_decl, // DeclContext * | ||||
clang::SourceLocation(), // clang::SourceLocation StartLoc | clang::SourceLocation(), // clang::SourceLocation StartLoc | ||||
clang::SourceLocation(), // clang::SourceLocation IdLoc | clang::SourceLocation(), // clang::SourceLocation IdLoc | ||||
ident, // clang::IdentifierInfo * | ident, // clang::IdentifierInfo * | ||||
ClangUtil::GetQualType(var_type), // Variable clang::QualType | ClangUtil::GetQualType(var_type), // Variable clang::QualType | ||||
nullptr, // TypeSourceInfo * | nullptr, // TypeSourceInfo * | ||||
clang::SC_Static); // StorageClass | clang::SC_Static); // StorageClass | ||||
SetMemberOwningModule(var_decl, record_decl); | |||||
if (!var_decl) | if (!var_decl) | ||||
return nullptr; | return nullptr; | ||||
var_decl->setAccess( | var_decl->setAccess( | ||||
TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access)); | TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access)); | ||||
record_decl->addDecl(var_decl); | record_decl->addDecl(var_decl); | ||||
VerifyDecl(var_decl); | VerifyDecl(var_decl); | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | |||||
cxx_method_decl = clang::CXXMethodDecl::Create( | cxx_method_decl = clang::CXXMethodDecl::Create( | ||||
getASTContext(), cxx_record_decl, clang::SourceLocation(), | getASTContext(), cxx_record_decl, clang::SourceLocation(), | ||||
clang::DeclarationNameInfo(decl_name, clang::SourceLocation()), | clang::DeclarationNameInfo(decl_name, clang::SourceLocation()), | ||||
method_qual_type, | method_qual_type, | ||||
nullptr, // TypeSourceInfo * | nullptr, // TypeSourceInfo * | ||||
SC, is_inline, CSK_unspecified, clang::SourceLocation()); | SC, is_inline, CSK_unspecified, clang::SourceLocation()); | ||||
} | } | ||||
} | } | ||||
SetMemberOwningModule(cxx_method_decl, cxx_record_decl); | |||||
clang::AccessSpecifier access_specifier = | clang::AccessSpecifier access_specifier = | ||||
TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access); | TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access); | ||||
cxx_method_decl->setAccess(access_specifier); | cxx_method_decl->setAccess(access_specifier); | ||||
cxx_method_decl->setVirtualAsWritten(is_virtual); | cxx_method_decl->setVirtualAsWritten(is_virtual); | ||||
if (is_attr_used) | if (is_attr_used) | ||||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | |||||
clang_ast, class_interface_decl, | clang_ast, class_interface_decl, | ||||
clang::SourceLocation(), // Source Location | clang::SourceLocation(), // Source Location | ||||
&clang_ast.Idents.get(property_name), | &clang_ast.Idents.get(property_name), | ||||
clang::SourceLocation(), // Source Location for AT | clang::SourceLocation(), // Source Location for AT | ||||
clang::SourceLocation(), // Source location for ( | clang::SourceLocation(), // Source location for ( | ||||
ivar_decl ? ivar_decl->getType() | ivar_decl ? ivar_decl->getType() | ||||
: ClangUtil::GetQualType(property_clang_type), | : ClangUtil::GetQualType(property_clang_type), | ||||
prop_type_source); | prop_type_source); | ||||
SetMemberOwningModule(property_decl, class_interface_decl); | |||||
if (!property_decl) | if (!property_decl) | ||||
return false; | return false; | ||||
if (metadata) | if (metadata) | ||||
ast->SetMetadata(property_decl, *metadata); | ast->SetMetadata(property_decl, *metadata); | ||||
class_interface_decl->addDecl(property_decl); | class_interface_decl->addDecl(property_decl); | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | |||||
const bool HasRelatedResultType = false; | const bool HasRelatedResultType = false; | ||||
getter = clang::ObjCMethodDecl::Create( | getter = clang::ObjCMethodDecl::Create( | ||||
clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel, | clang_ast, clang::SourceLocation(), clang::SourceLocation(), getter_sel, | ||||
ClangUtil::GetQualType(property_clang_type_to_access), nullptr, | ClangUtil::GetQualType(property_clang_type_to_access), nullptr, | ||||
class_interface_decl, isInstance, isVariadic, isPropertyAccessor, | class_interface_decl, isInstance, isVariadic, isPropertyAccessor, | ||||
isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, | isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, | ||||
HasRelatedResultType); | HasRelatedResultType); | ||||
SetMemberOwningModule(getter, class_interface_decl); | |||||
if (getter) { | if (getter) { | ||||
if (metadata) | if (metadata) | ||||
ast->SetMetadata(getter, *metadata); | ast->SetMetadata(getter, *metadata); | ||||
getter->setMethodParams(clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(), | getter->setMethodParams(clang_ast, llvm::ArrayRef<clang::ParmVarDecl *>(), | ||||
llvm::ArrayRef<clang::SourceLocation>()); | llvm::ArrayRef<clang::SourceLocation>()); | ||||
class_interface_decl->addDecl(getter); | class_interface_decl->addDecl(getter); | ||||
Show All 18 Lines | |||||
clang::ObjCMethodDecl::None; | clang::ObjCMethodDecl::None; | ||||
const bool HasRelatedResultType = false; | const bool HasRelatedResultType = false; | ||||
setter = clang::ObjCMethodDecl::Create( | setter = clang::ObjCMethodDecl::Create( | ||||
clang_ast, clang::SourceLocation(), clang::SourceLocation(), setter_sel, | clang_ast, clang::SourceLocation(), clang::SourceLocation(), setter_sel, | ||||
result_type, nullptr, class_interface_decl, isInstance, isVariadic, | result_type, nullptr, class_interface_decl, isInstance, isVariadic, | ||||
isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, | isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, | ||||
isDefined, impControl, HasRelatedResultType); | isDefined, impControl, HasRelatedResultType); | ||||
SetMemberOwningModule(setter, class_interface_decl); | |||||
labathUnsubmitted Not Done ReplyInline Actionshere too labath: here too | |||||
if (setter) { | if (setter) { | ||||
if (metadata) | if (metadata) | ||||
ast->SetMetadata(setter, *metadata); | ast->SetMetadata(setter, *metadata); | ||||
llvm::SmallVector<clang::ParmVarDecl *, 1> params; | llvm::SmallVector<clang::ParmVarDecl *, 1> params; | ||||
params.push_back(clang::ParmVarDecl::Create( | params.push_back(clang::ParmVarDecl::Create( | ||||
clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), | clang_ast, setter, clang::SourceLocation(), clang::SourceLocation(), | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | |||||
ast, | ast, | ||||
clang::SourceLocation(), // beginLoc, | clang::SourceLocation(), // beginLoc, | ||||
clang::SourceLocation(), // endLoc, | clang::SourceLocation(), // endLoc, | ||||
method_selector, method_function_prototype->getReturnType(), | method_selector, method_function_prototype->getReturnType(), | ||||
nullptr, // TypeSourceInfo *ResultTInfo, | nullptr, // TypeSourceInfo *ResultTInfo, | ||||
lldb_ast->GetDeclContextForType(ClangUtil::GetQualType(type)), isInstance, | lldb_ast->GetDeclContextForType(ClangUtil::GetQualType(type)), isInstance, | ||||
isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, | isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, | ||||
isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); | isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); | ||||
SetMemberOwningModule(objc_method_decl, class_interface_decl); | |||||
if (objc_method_decl == nullptr) | if (objc_method_decl == nullptr) | ||||
return nullptr; | return nullptr; | ||||
if (num_args > 0) { | if (num_args > 0) { | ||||
llvm::SmallVector<clang::ParmVarDecl *, 12> params; | llvm::SmallVector<clang::ParmVarDecl *, 12> params; | ||||
for (unsigned param_index = 0; param_index < num_args; ++param_index) { | for (unsigned param_index = 0; param_index < num_args; ++param_index) { | ||||
▲ Show 20 Lines • Show All 211 Lines • ▼ Show 20 Lines | |||||
if (!enutype) | if (!enutype) | ||||
return nullptr; | return nullptr; | ||||
clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create( | clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create( | ||||
getASTContext(), enutype->getDecl(), clang::SourceLocation(), | getASTContext(), enutype->getDecl(), clang::SourceLocation(), | ||||
name ? &getASTContext().Idents.get(name) : nullptr, // Identifier | name ? &getASTContext().Idents.get(name) : nullptr, // Identifier | ||||
clang::QualType(enutype, 0), nullptr, value); | clang::QualType(enutype, 0), nullptr, value); | ||||
SetMemberOwningModule(enumerator_decl, enutype->getDecl()); | |||||
if (!enumerator_decl) | if (!enumerator_decl) | ||||
return nullptr; | return nullptr; | ||||
enutype->getDecl()->addDecl(enumerator_decl); | enutype->getDecl()->addDecl(enumerator_decl); | ||||
VerifyDecl(enumerator_decl); | VerifyDecl(enumerator_decl); | ||||
return enumerator_decl; | return enumerator_decl; | ||||
▲ Show 20 Lines • Show All 878 Lines • ▼ Show 20 Lines | |||||
default: | default: | ||||
printf("TypeSystemClang::DumpTypeName() type_class = %u", type_class); | printf("TypeSystemClang::DumpTypeName() type_class = %u", type_class); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl( | clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl( | ||||
clang::DeclContext *decl_ctx, lldb::AccessType access_type, | clang::DeclContext *decl_ctx, unsigned owning_module, | ||||
const char *parent_name, int tag_decl_kind, | lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, | ||||
const TypeSystemClang::TemplateParameterInfos &template_param_infos) { | const TypeSystemClang::TemplateParameterInfos &template_param_infos) { | ||||
if (template_param_infos.IsValid()) { | if (template_param_infos.IsValid()) { | ||||
std::string template_basename(parent_name); | std::string template_basename(parent_name); | ||||
template_basename.erase(template_basename.find('<')); | template_basename.erase(template_basename.find('<')); | ||||
return CreateClassTemplateDecl(decl_ctx, access_type, | return CreateClassTemplateDecl(decl_ctx, owning_module, access_type, | ||||
template_basename.c_str(), tag_decl_kind, | template_basename.c_str(), tag_decl_kind, | ||||
template_param_infos); | template_param_infos); | ||||
} | } | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
void TypeSystemClang::CompleteTagDecl(clang::TagDecl *decl) { | void TypeSystemClang::CompleteTagDecl(clang::TagDecl *decl) { | ||||
SymbolFile *sym_file = GetSymbolFile(); | SymbolFile *sym_file = GetSymbolFile(); | ||||
▲ Show 20 Lines • Show All 512 Lines • Show Last 20 Lines |
All the m_* variables that correspond to a part of ASTContext are only initialized when the TypeSystemClang has created its own ASTContext, so this code would crash if that's not the case. Calling getASTContext().getX() is the way that always works.