blob: dda9f4347f0cd82a9b3a873adc6e3971827cd218 [file] [log] [blame]
//===-- ClangASTContext.h ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_ClangASTContext_h_
#define liblldb_ClangASTContext_h_
#include <stdint.h>
#include <functional>
#include <initializer_list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "clang/AST/ASTContext.h"
#include "clang/AST/ExternalASTMerger.h"
#include "clang/AST/TemplateBase.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-enumerations.h"
class DWARFASTParserClang;
class PDBASTParser;
namespace lldb_private {
class Declaration;
class ClangASTContext : public TypeSystem {
public:
typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton,
clang::ObjCInterfaceDecl *);
// llvm casting support
static bool classof(const TypeSystem *ts) {
return ts->getKind() == TypeSystem::eKindClang;
}
// Constructors and Destructors
ClangASTContext(const char *triple = nullptr);
~ClangASTContext() override;
void Finalize() override;
// PluginInterface functions
ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
static ConstString GetPluginNameStatic();
static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
Module *module, Target *target);
static void EnumerateSupportedLanguages(
std::set<lldb::LanguageType> &languages_for_types,
std::set<lldb::LanguageType> &languages_for_expressions);
static void Initialize();
static void Terminate();
static ClangASTContext *GetASTContext(clang::ASTContext *ast_ctx);
clang::ASTContext *getASTContext();
void setASTContext(clang::ASTContext *ast_ctx);
clang::Builtin::Context *getBuiltinContext();
clang::IdentifierTable *getIdentifierTable();
clang::LangOptions *getLanguageOptions();
clang::SelectorTable *getSelectorTable();
clang::FileManager *getFileManager();
clang::SourceManager *getSourceManager();
clang::DiagnosticsEngine *getDiagnosticsEngine();
clang::DiagnosticConsumer *getDiagnosticConsumer();
clang::MangleContext *getMangleContext();
std::shared_ptr<clang::TargetOptions> &getTargetOptions();
clang::TargetInfo *getTargetInfo();
void setSema(clang::Sema *s);
clang::Sema *getSema() { return m_sema; }
void Clear();
const char *GetTargetTriple();
void SetTargetTriple(const char *target_triple);
void SetArchitecture(const ArchSpec &arch);
bool HasExternalSource();
void SetExternalSource(
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> &ast_source_up);
void RemoveExternalSource();
bool GetCompleteDecl(clang::Decl *decl) {
return ClangASTContext::GetCompleteDecl(getASTContext(), decl);
}
static void DumpDeclHiearchy(clang::Decl *decl);
static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx);
static bool DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl);
static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl);
void SetMetadataAsUserID(const void *object, lldb::user_id_t user_id);
void SetMetadata(const void *object, ClangASTMetadata &meta_data) {
SetMetadata(getASTContext(), object, meta_data);
}
static void SetMetadata(clang::ASTContext *ast, const void *object,
ClangASTMetadata &meta_data);
ClangASTMetadata *GetMetadata(const void *object) {
return GetMetadata(getASTContext(), object);
}
static ClangASTMetadata *GetMetadata(clang::ASTContext *ast,
const void *object);
// Basic Types
CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
size_t bit_size) override;
static CompilerType GetBuiltinTypeForEncodingAndBitSize(
clang::ASTContext *ast, lldb::Encoding encoding, uint32_t bit_size);
CompilerType GetBasicType(lldb::BasicType type);
static CompilerType GetBasicType(clang::ASTContext *ast,
lldb::BasicType type);
static CompilerType GetBasicType(clang::ASTContext *ast,
ConstString name);
static lldb::BasicType GetBasicTypeEnumeration(ConstString name);
CompilerType GetBuiltinTypeForDWARFEncodingAndBitSize(const char *type_name,
uint32_t dw_ate,
uint32_t bit_size);
CompilerType GetCStringType(bool is_const);
static CompilerType GetUnknownAnyType(clang::ASTContext *ast);
CompilerType GetUnknownAnyType() {
return ClangASTContext::GetUnknownAnyType(getASTContext());
}
static clang::DeclContext *GetDeclContextForType(clang::QualType type);
static clang::DeclContext *GetDeclContextForType(const CompilerType &type);
uint32_t GetPointerByteSize() override;
static clang::DeclContext *GetTranslationUnitDecl(clang::ASTContext *ast);
clang::DeclContext *GetTranslationUnitDecl() {
return GetTranslationUnitDecl(getASTContext());
}
static clang::Decl *CopyDecl(clang::ASTContext *dest_context,
clang::ASTContext *source_context,
clang::Decl *source_decl);
static bool AreTypesSame(CompilerType type1, CompilerType type2,
bool ignore_qualifiers = false);
static CompilerType GetTypeForDecl(clang::NamedDecl *decl);
static CompilerType GetTypeForDecl(clang::TagDecl *decl);
static CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl);
template <typename RecordDeclType>
CompilerType
GetTypeForIdentifier(ConstString type_name,
clang::DeclContext *decl_context = nullptr) {
CompilerType compiler_type;
if (type_name.GetLength()) {
clang::ASTContext *ast = getASTContext();
if (ast) {
if (!decl_context)
decl_context = ast->getTranslationUnitDecl();
clang::IdentifierInfo &myIdent =
ast->Idents.get(type_name.GetCString());
clang::DeclarationName myName =
ast->DeclarationNames.getIdentifier(&myIdent);
clang::DeclContext::lookup_result result =
decl_context->lookup(myName);
if (!result.empty()) {
clang::NamedDecl *named_decl = result[0];
if (const RecordDeclType *record_decl =
llvm::dyn_cast<RecordDeclType>(named_decl))
compiler_type.SetCompilerType(
ast, clang::QualType(record_decl->getTypeForDecl(), 0));
}
}
}
return compiler_type;
}
CompilerType CreateStructForIdentifier(
ConstString type_name,
const std::initializer_list<std::pair<const char *, CompilerType>>
&type_fields,
bool packed = false);
CompilerType GetOrCreateStructForIdentifier(
ConstString type_name,
const std::initializer_list<std::pair<const char *, CompilerType>>
&type_fields,
bool packed = false);
static bool IsOperator(const char *name,
clang::OverloadedOperatorKind &op_kind);
// Structure, Unions, Classes
static clang::AccessSpecifier
ConvertAccessTypeToAccessSpecifier(lldb::AccessType access);
static clang::AccessSpecifier
UnifyAccessSpecifiers(clang::AccessSpecifier lhs, clang::AccessSpecifier rhs);
static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl,
bool omit_empty_base_classes);
CompilerType CreateRecordType(clang::DeclContext *decl_ctx,
lldb::AccessType access_type, const char *name,
int kind, lldb::LanguageType language,
ClangASTMetadata *metadata = nullptr);
class TemplateParameterInfos {
public:
bool IsValid() const {
if (args.empty())
return false;
return args.size() == names.size() &&
((bool)pack_name == (bool)packed_args) &&
(!packed_args || !packed_args->packed_args);
}
llvm::SmallVector<const char *, 2> names;
llvm::SmallVector<clang::TemplateArgument, 2> args;
const char * pack_name = nullptr;
std::unique_ptr<TemplateParameterInfos> packed_args;
};
clang::FunctionTemplateDecl *
CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
clang::FunctionDecl *func_decl, const char *name,
const TemplateParameterInfos &infos);
void CreateFunctionTemplateSpecializationInfo(
clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template,
const TemplateParameterInfos &infos);
clang::ClassTemplateDecl *
CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
lldb::AccessType access_type, const char *class_name,
int kind, const TemplateParameterInfos &infos);
clang::TemplateTemplateParmDecl *
CreateTemplateTemplateParmDecl(const char *template_name);
clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl(
clang::DeclContext *decl_ctx,
clang::ClassTemplateDecl *class_template_decl, int kind,
const TemplateParameterInfos &infos);
CompilerType
CreateClassTemplateSpecializationType(clang::ClassTemplateSpecializationDecl *
class_template_specialization_decl);
static clang::DeclContext *
GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl);
static clang::DeclContext *
GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl);
static bool CheckOverloadedOperatorKindParameterCount(
bool is_method, clang::OverloadedOperatorKind op_kind,
uint32_t num_params);
bool FieldIsBitfield(clang::FieldDecl *field, uint32_t &bitfield_bit_size);
static bool FieldIsBitfield(clang::ASTContext *ast, clang::FieldDecl *field,
uint32_t &bitfield_bit_size);
static bool RecordHasFields(const clang::RecordDecl *record_decl);
CompilerType CreateObjCClass(const char *name, clang::DeclContext *decl_ctx,
bool isForwardDecl, bool isInternal,
ClangASTMetadata *metadata = nullptr);
bool SetTagTypeKind(clang::QualType type, int kind) const;
bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl,
int default_accessibility,
int *assigned_accessibilities,
size_t num_assigned_accessibilities);
// Returns a mask containing bits from the ClangASTContext::eTypeXXX
// enumerations
// Namespace Declarations
clang::NamespaceDecl *
GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
bool is_inline = false);
static clang::NamespaceDecl *
GetUniqueNamespaceDeclaration(clang::ASTContext *ast, const char *name,
clang::DeclContext *decl_ctx,
bool is_inline = false);
// Function Types
clang::FunctionDecl *
CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name,
const CompilerType &function_Type, int storage,
bool is_inline);
static CompilerType CreateFunctionType(clang::ASTContext *ast,
const CompilerType &result_type,
const CompilerType *args,
unsigned num_args, bool is_variadic,
unsigned type_quals,
clang::CallingConv cc);
static CompilerType CreateFunctionType(clang::ASTContext *ast,
const CompilerType &result_type,
const CompilerType *args,
unsigned num_args, bool is_variadic,
unsigned type_quals) {
return ClangASTContext::CreateFunctionType(
ast, result_type, args, num_args, is_variadic, type_quals, clang::CC_C);
}
CompilerType CreateFunctionType(const CompilerType &result_type,
const CompilerType *args, unsigned num_args,
bool is_variadic, unsigned type_quals) {
return ClangASTContext::CreateFunctionType(
getASTContext(), result_type, args, num_args, is_variadic, type_quals);
}
CompilerType CreateFunctionType(const CompilerType &result_type,
const CompilerType *args, unsigned num_args,
bool is_variadic, unsigned type_quals,
clang::CallingConv cc) {
return ClangASTContext::CreateFunctionType(getASTContext(), result_type,
args, num_args, is_variadic,
type_quals, cc);
}
clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
const char *name,
const CompilerType &param_type,
int storage);
void SetFunctionParameters(clang::FunctionDecl *function_decl,
clang::ParmVarDecl **params, unsigned num_params);
CompilerType CreateBlockPointerType(const CompilerType &function_type);
// Array Types
CompilerType CreateArrayType(const CompilerType &element_type,
size_t element_count, bool is_vector);
// Enumeration Types
CompilerType CreateEnumerationType(const char *name,
clang::DeclContext *decl_ctx,
const Declaration &decl,
const CompilerType &integer_qual_type,
bool is_scoped);
// Integer type functions
static CompilerType GetIntTypeFromBitSize(clang::ASTContext *ast,
size_t bit_size, bool is_signed);
CompilerType GetPointerSizedIntType(bool is_signed) {
return GetPointerSizedIntType(getASTContext(), is_signed);
}
static CompilerType GetPointerSizedIntType(clang::ASTContext *ast,
bool is_signed);
// Floating point functions
static CompilerType GetFloatTypeFromBitSize(clang::ASTContext *ast,
size_t bit_size);
// TypeSystem methods
DWARFASTParser *GetDWARFParser() override;
PDBASTParser *GetPDBParser() override;
// ClangASTContext callbacks for external source lookups.
static void CompleteTagDecl(void *baton, clang::TagDecl *);
static void CompleteObjCInterfaceDecl(void *baton,
clang::ObjCInterfaceDecl *);
static bool LayoutRecordType(
void *baton, const clang::RecordDecl *record_decl, uint64_t &size,
uint64_t &alignment,
llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
&base_offsets,
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
&vbase_offsets);
// CompilerDecl override functions
ConstString DeclGetName(void *opaque_decl) override;
ConstString DeclGetMangledName(void *opaque_decl) override;
CompilerDeclContext DeclGetDeclContext(void *opaque_decl) override;
CompilerType DeclGetFunctionReturnType(void *opaque_decl) override;
size_t DeclGetFunctionNumArguments(void *opaque_decl) override;
CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
size_t arg_idx) override;
// CompilerDeclContext override functions
std::vector<CompilerDecl>
DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
const bool ignore_using_decls) override;
bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override;
ConstString DeclContextGetName(void *opaque_decl_ctx) override;
ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override;
bool DeclContextIsClassMethod(void *opaque_decl_ctx,
lldb::LanguageType *language_ptr,
bool *is_instance_method_ptr,
ConstString *language_object_name_ptr) override;
bool DeclContextIsContainedInLookup(void *opaque_decl_ctx,
void *other_opaque_decl_ctx) override;
// Clang specific clang::DeclContext functions
static clang::DeclContext *
DeclContextGetAsDeclContext(const CompilerDeclContext &dc);
static clang::ObjCMethodDecl *
DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc);
static clang::CXXMethodDecl *
DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc);
static clang::FunctionDecl *
DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc);
static clang::NamespaceDecl *
DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc);
static ClangASTMetadata *DeclContextGetMetaData(const CompilerDeclContext &dc,
const void *object);
static clang::ASTContext *
DeclContextGetClangASTContext(const CompilerDeclContext &dc);
// Tests
bool IsArrayType(lldb::opaque_compiler_type_t type,
CompilerType *element_type, uint64_t *size,
bool *is_incomplete) override;
bool IsVectorType(lldb::opaque_compiler_type_t type,
CompilerType *element_type, uint64_t *size) override;
bool IsAggregateType(lldb::opaque_compiler_type_t type) override;
bool IsAnonymousType(lldb::opaque_compiler_type_t type) override;
bool IsBeingDefined(lldb::opaque_compiler_type_t type) override;
bool IsCharType(lldb::opaque_compiler_type_t type) override;
bool IsCompleteType(lldb::opaque_compiler_type_t type) override;
bool IsConst(lldb::opaque_compiler_type_t type) override;
bool IsCStringType(lldb::opaque_compiler_type_t type,
uint32_t &length) override;
static bool IsCXXClassType(const CompilerType &type);
bool IsDefined(lldb::opaque_compiler_type_t type) override;
bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count,
bool &is_complex) override;
bool IsFunctionType(lldb::opaque_compiler_type_t type,
bool *is_variadic_ptr) override;
uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
CompilerType *base_type_ptr) override;
size_t
GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override;
CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
const size_t index) override;
bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;
bool IsBlockPointerType(lldb::opaque_compiler_type_t type,
CompilerType *function_pointer_type_ptr) override;
bool IsIntegerType(lldb::opaque_compiler_type_t type,
bool &is_signed) override;
bool IsEnumerationType(lldb::opaque_compiler_type_t type,
bool &is_signed) override;
static bool IsObjCClassType(const CompilerType &type);
static bool IsObjCClassTypeAndHasIVars(const CompilerType &type,
bool check_superclass);
static bool IsObjCObjectOrInterfaceType(const CompilerType &type);
static bool IsObjCObjectPointerType(const CompilerType &type,
CompilerType *target_type = nullptr);
bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override;
static bool IsClassType(lldb::opaque_compiler_type_t type);
static bool IsEnumType(lldb::opaque_compiler_type_t type);
bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
CompilerType *target_type, // Can pass nullptr
bool check_cplusplus, bool check_objc) override;
bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override;
bool IsPointerType(lldb::opaque_compiler_type_t type,
CompilerType *pointee_type) override;
bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
CompilerType *pointee_type) override;
bool IsReferenceType(lldb::opaque_compiler_type_t type,
CompilerType *pointee_type, bool *is_rvalue) override;
bool IsScalarType(lldb::opaque_compiler_type_t type) override;
bool IsTypedefType(lldb::opaque_compiler_type_t type) override;
bool IsVoidType(lldb::opaque_compiler_type_t type) override;
bool CanPassInRegisters(const CompilerType &type) override;
bool SupportsLanguage(lldb::LanguageType language) override;
static bool GetCXXClassName(const CompilerType &type,
std::string &class_name);
static bool GetObjCClassName(const CompilerType &type,
std::string &class_name);
// Type Completion
bool GetCompleteType(lldb::opaque_compiler_type_t type) override;
// Accessors
ConstString GetTypeName(lldb::opaque_compiler_type_t type) override;
uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type,
CompilerType *pointee_or_element_compiler_type) override;
lldb::LanguageType
GetMinimumLanguage(lldb::opaque_compiler_type_t type) override;
lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override;
unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override;
// Creating related types
// Using the current type, create a new typedef to that type using
// "typedef_name" as the name and "decl_ctx" as the decl context.
static CompilerType
CreateTypedefType(const CompilerType &type, const char *typedef_name,
const CompilerDeclContext &compiler_decl_ctx);
CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type,
uint64_t *stride) override;
CompilerType GetArrayType(lldb::opaque_compiler_type_t type,
uint64_t size) override;
CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override;
// Returns -1 if this isn't a function of if the function doesn't have a
// prototype Returns a value >= 0 if there is a prototype.
int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override;
CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type,
size_t idx) override;
CompilerType
GetFunctionReturnType(lldb::opaque_compiler_type_t type) override;
size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override;
TypeMemberFunctionImpl
GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
size_t idx) override;
CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override;
CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override;
CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetLValueReferenceType(lldb::opaque_compiler_type_t type) override;
CompilerType
GetRValueReferenceType(lldb::opaque_compiler_type_t type) override;
CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override;
CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override;
CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override;
CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
const char *name,
const CompilerDeclContext &decl_ctx) override;
// If the current object represents a typedef type, get the underlying type
CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override;
// Create related types using the current type's AST
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override;
// Exploring the type
llvm::Optional<uint64_t> GetByteSize(lldb::opaque_compiler_type_t type,
ExecutionContextScope *exe_scope) {
if (llvm::Optional<uint64_t> bit_size = GetBitSize(type, exe_scope))
return (*bit_size + 7) / 8;
return llvm::None;
}
llvm::Optional<uint64_t>
GetBitSize(lldb::opaque_compiler_type_t type,
ExecutionContextScope *exe_scope) override;
lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type,
uint64_t &count) override;
lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override;
size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override;
uint32_t GetNumChildren(lldb::opaque_compiler_type_t type,
bool omit_empty_base_classes,
const ExecutionContext *exe_ctx) override;
CompilerType GetBuiltinTypeByName(ConstString name) override;
lldb::BasicType
GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;
static lldb::BasicType
GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type,
ConstString name);
void ForEachEnumerator(
lldb::opaque_compiler_type_t type,
std::function<bool(const CompilerType &integer_type,
ConstString name,
const llvm::APSInt &value)> const &callback) override;
uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override;
CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
std::string &name, uint64_t *bit_offset_ptr,
uint32_t *bitfield_bit_size_ptr,
bool *is_bitfield_ptr) override;
uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override;
uint32_t GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override;
CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type,
size_t idx,
uint32_t *bit_offset_ptr) override;
CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type,
size_t idx,
uint32_t *bit_offset_ptr) override;
static uint32_t GetNumPointeeChildren(clang::QualType type);
CompilerType GetChildCompilerTypeAtIndex(
lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
bool transparent_pointers, bool omit_empty_base_classes,
bool ignore_array_bounds, std::string &child_name,
uint32_t &child_byte_size, int32_t &child_byte_offset,
uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
bool &child_is_base_class, bool &child_is_deref_of_parent,
ValueObject *valobj, uint64_t &language_flags) override;
// Lookup a child given a name. This function will match base class names and
// member member names in "clang_type" only, not descendants.
uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
const char *name,
bool omit_empty_base_classes) override;
// Lookup a child member given a name. This function will match member names
// only and will descend into "clang_type" children in search for the first
// member in this class, or any base class that matches "name".
// TODO: Return all matches for a given name by returning a
// vector<vector<uint32_t>>
// so we catch all names that match a given child name, not just the first.
size_t
GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
const char *name, bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) override;
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
lldb::TemplateArgumentKind
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
size_t idx) override;
CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) override;
llvm::Optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) override;
CompilerType GetTypeForFormatters(void *type) override;
#define LLDB_INVALID_DECL_LEVEL UINT32_MAX
// LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if child_decl_ctx
// could not be found in decl_ctx.
uint32_t CountDeclLevels(clang::DeclContext *frame_decl_ctx,
clang::DeclContext *child_decl_ctx,
ConstString *child_name = nullptr,
CompilerType *child_type = nullptr);
// Modifying RecordType
static clang::FieldDecl *AddFieldToRecordType(const CompilerType &type,
llvm::StringRef name,
const CompilerType &field_type,
lldb::AccessType access,
uint32_t bitfield_bit_size);
static void BuildIndirectFields(const CompilerType &type);
static void SetIsPacked(const CompilerType &type);
static clang::VarDecl *AddVariableToRecordType(const CompilerType &type,
llvm::StringRef name,
const CompilerType &var_type,
lldb::AccessType access);
clang::CXXMethodDecl *
AddMethodToCXXRecordType(lldb::opaque_compiler_type_t type, const char *name,
const char *mangled_name,
const CompilerType &method_type,
lldb::AccessType access, bool is_virtual,
bool is_static, bool is_inline, bool is_explicit,
bool is_attr_used, bool is_artificial);
void AddMethodOverridesForCXXRecordType(lldb::opaque_compiler_type_t type);
// C++ Base Classes
std::unique_ptr<clang::CXXBaseSpecifier>
CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
lldb::AccessType access, bool is_virtual,
bool base_of_class);
bool TransferBaseClasses(
lldb::opaque_compiler_type_t type,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases);
static bool SetObjCSuperClass(const CompilerType &type,
const CompilerType &superclass_compiler_type);
static bool AddObjCClassProperty(const CompilerType &type,
const char *property_name,
const CompilerType &property_compiler_type,
clang::ObjCIvarDecl *ivar_decl,
const char *property_setter_name,
const char *property_getter_name,
uint32_t property_attributes,
ClangASTMetadata *metadata);
static clang::ObjCMethodDecl *AddMethodToObjCObjectType(
const CompilerType &type,
const char *name, // the full symbol name as seen in the symbol table
// (lldb::opaque_compiler_type_t type, "-[NString
// stringWithCString:]")
const CompilerType &method_compiler_type, lldb::AccessType access,
bool is_artificial, bool is_variadic);
static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type,
bool has_extern);
static bool GetHasExternalStorage(const CompilerType &type);
// Tag Declarations
static bool StartTagDeclarationDefinition(const CompilerType &type);
static bool CompleteTagDeclarationDefinition(const CompilerType &type);
// Modifying Enumeration types
clang::EnumConstantDecl *AddEnumerationValueToEnumerationType(
const CompilerType &enum_type, const Declaration &decl, const char *name,
int64_t enum_value, uint32_t enum_value_bit_size);
clang::EnumConstantDecl *AddEnumerationValueToEnumerationType(
const CompilerType &enum_type, const Declaration &decl, const char *name,
const llvm::APSInt &value);
CompilerType GetEnumerationIntegerType(lldb::opaque_compiler_type_t type);
// Pointers & References
// Call this function using the class type when you want to make a member
// pointer type to pointee_type.
static CompilerType CreateMemberPointerType(const CompilerType &type,
const CompilerType &pointee_type);
// Converts "s" to a floating point value and place resulting floating point
// bytes in the "dst" buffer.
size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
const char *s, uint8_t *dst,
size_t dst_size) override;
// Dumping types
#ifndef NDEBUG
/// Convenience LLVM-style dump method for use in the debugger only.
/// In contrast to the other \p Dump() methods this directly invokes
/// \p clang::QualType::dump().
LLVM_DUMP_METHOD void dump(lldb::opaque_compiler_type_t type) const override;
#endif
void Dump(Stream &s);
void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
Stream *s, lldb::Format format, const DataExtractor &data,
lldb::offset_t data_offset, size_t data_byte_size,
uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
bool show_types, bool show_summary, bool verbose,
uint32_t depth) override;
bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
lldb::Format format, const DataExtractor &data,
lldb::offset_t data_offset, size_t data_byte_size,
uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
ExecutionContextScope *exe_scope) override;
void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
Stream *s, const DataExtractor &data,
lldb::offset_t data_offset, size_t data_byte_size) override;
void DumpTypeDescription(
lldb::opaque_compiler_type_t type) override; // Dump to stdout
void DumpTypeDescription(lldb::opaque_compiler_type_t type,
Stream *s) override;
static void DumpTypeName(const CompilerType &type);
static clang::EnumDecl *GetAsEnumDecl(const CompilerType &type);
static clang::RecordDecl *GetAsRecordDecl(const CompilerType &type);
static clang::TagDecl *GetAsTagDecl(const CompilerType &type);
static clang::TypedefNameDecl *GetAsTypedefDecl(const CompilerType &type);
clang::CXXRecordDecl *GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type);
static clang::ObjCInterfaceDecl *
GetAsObjCInterfaceDecl(const CompilerType &type);
clang::ClassTemplateDecl *ParseClassTemplateDecl(
clang::DeclContext *decl_ctx, lldb::AccessType access_type,
const char *parent_name, int tag_decl_kind,
const ClangASTContext::TemplateParameterInfos &template_param_infos);
clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx);
clang::UsingDirectiveDecl *
CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx,
clang::NamespaceDecl *ns_decl);
clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
clang::NamedDecl *target);
clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context,
const char *name,
clang::QualType type);
static lldb::opaque_compiler_type_t
GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type);
static clang::QualType GetQualType(lldb::opaque_compiler_type_t type) {
if (type)
return clang::QualType::getFromOpaquePtr(type);
return clang::QualType();
}
static clang::QualType
GetCanonicalQualType(lldb::opaque_compiler_type_t type) {
if (type)
return clang::QualType::getFromOpaquePtr(type).getCanonicalType();
return clang::QualType();
}
clang::DeclarationName
GetDeclarationName(const char *name, const CompilerType &function_clang_type);
virtual const clang::ExternalASTMerger::OriginMap &GetOriginMap() {
return m_origins;
}
protected:
const clang::ClassTemplateSpecializationDecl *
GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type);
// Classes that inherit from ClangASTContext can see and modify these
// clang-format off
std::string m_target_triple;
std::unique_ptr<clang::ASTContext> m_ast_up;
std::unique_ptr<clang::LangOptions> m_language_options_up;
std::unique_ptr<clang::FileManager> m_file_manager_up;
std::unique_ptr<clang::FileSystemOptions> m_file_system_options_up;
std::unique_ptr<clang::SourceManager> m_source_manager_up;
std::unique_ptr<clang::DiagnosticsEngine> m_diagnostics_engine_up;
std::unique_ptr<clang::DiagnosticConsumer> m_diagnostic_consumer_up;
std::shared_ptr<clang::TargetOptions> m_target_options_rp;
std::unique_ptr<clang::TargetInfo> m_target_info_up;
std::unique_ptr<clang::IdentifierTable> m_identifier_table_up;
std::unique_ptr<clang::SelectorTable> m_selector_table_up;
std::unique_ptr<clang::Builtin::Context> m_builtins_up;
std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up;
std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up;
std::unique_ptr<ClangASTSource> m_scratch_ast_source_up;
std::unique_ptr<clang::MangleContext> m_mangle_ctx_up;
CompleteTagDeclCallback m_callback_tag_decl;
CompleteObjCInterfaceDeclCallback m_callback_objc_decl;
void * m_callback_baton;
clang::ExternalASTMerger::OriginMap m_origins;
uint32_t m_pointer_byte_size;
bool m_ast_owned;
bool m_can_evaluate_expressions;
/// The sema associated that is currently used to build this ASTContext.
/// May be null if we are already done parsing this ASTContext or the
/// ASTContext wasn't created by parsing source code.
clang::Sema * m_sema = nullptr;
// clang-format on
private:
// For ClangASTContext only
ClangASTContext(const ClangASTContext &);
const ClangASTContext &operator=(const ClangASTContext &);
};
class ClangASTContextForExpressions : public ClangASTContext {
public:
ClangASTContextForExpressions(Target &target);
~ClangASTContextForExpressions() override = default;
UserExpression *
GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
lldb::LanguageType language,
Expression::ResultType desired_type,
const EvaluateExpressionOptions &options,
ValueObject *ctx_obj) override;
FunctionCaller *GetFunctionCaller(const CompilerType &return_type,
const Address &function_address,
const ValueList &arg_value_list,
const char *name) override;
UtilityFunction *GetUtilityFunction(const char *text,
const char *name) override;
PersistentExpressionState *GetPersistentExpressionState() override;
clang::ExternalASTMerger &GetMergerUnchecked();
const clang::ExternalASTMerger::OriginMap &GetOriginMap() override {
return GetMergerUnchecked().GetOrigins();
}
private:
lldb::TargetWP m_target_wp;
lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the
///persistent
///variables
///associated with
///this process for
///the expression
///parser.
};
} // namespace lldb_private
#endif // liblldb_ClangASTContext_h_