Almost have templatized functions working (templatized classes are already

working, but not functions). I need to check on a few things to make sure 
I am registering everything correctly in the right order and in the right
contexts.

llvm-svn: 149858
This commit is contained in:
Greg Clayton 2012-02-06 06:42:51 +00:00
parent 662beed828
commit 3c2e3ae490
6 changed files with 248 additions and 117 deletions

View File

@ -67,6 +67,8 @@ namespace clang
class FloatingLiteral;
class FrontendOptions;
class FunctionDecl;
class FunctionTemplateDecl;
class FunctionTemplateSpecializationInfo;
class GotoStmt;
class HeaderSearchOptions;
class IdentifierTable;
@ -109,6 +111,7 @@ namespace clang
class TargetOptions;
class TemplateArgument;
class TemplateDecl;
class TemplateParameterList;
class TemplateTemplateParmDecl;
class TemplateTypeParmDecl;
class TextDiagnosticBuffer;

View File

@ -342,6 +342,17 @@ public:
llvm::SmallVector<clang::TemplateArgument, 8> 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,

View File

@ -101,7 +101,7 @@
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "/Volumes/work/gclayton/Documents/src/args/a.out"
argument = "/private/tmp/a.out"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>

View File

@ -15,6 +15,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
@ -733,7 +734,18 @@ SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompile
if (die->Tag() != DW_TAG_subprogram)
return NULL;
if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
if (die->GetDIENamesAndRanges (this,
dwarf_cu,
name,
mangled,
func_ranges,
decl_file,
decl_line,
decl_column,
call_file,
call_line,
call_column,
&frame_base))
{
// Union of all ranges in the function DIE (if the function is discontiguous)
AddressRange func_range;
@ -1181,21 +1193,10 @@ SymbolFileDWARF::ParseFunctionBlocks
}
bool
SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *die,
ClangASTContext::TemplateParameterInfos &template_param_infos)
{
if (parent_die == NULL)
return NULL;
const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Args template_parameter_names;
for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild();
die != NULL;
die = die->GetSibling())
{
const dw_tag_t tag = die->Tag();
switch (tag)
@ -1203,6 +1204,8 @@ SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
case DW_TAG_template_type_parameter:
case DW_TAG_template_value_parameter:
{
const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
DWARFDebugInfoEntry::Attributes attributes;
const size_t num_attributes = die->GetAttributes (this,
dwarf_cu,
@ -1271,6 +1274,37 @@ SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
}
}
return true;
default:
break;
}
return false;
}
bool
SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *parent_die,
ClangASTContext::TemplateParameterInfos &template_param_infos)
{
if (parent_die == NULL)
return NULL;
const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
Args template_parameter_names;
for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild();
die != NULL;
die = die->GetSibling())
{
const dw_tag_t tag = die->Tag();
switch (tag)
{
case DW_TAG_template_type_parameter:
case DW_TAG_template_value_parameter:
ParseTemplateDIE (dwarf_cu, die, template_param_infos);
break;
default:
@ -3329,7 +3363,8 @@ SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
TypeList* type_list,
std::vector<clang_type_t>& function_param_types,
std::vector<clang::ParmVarDecl*>& function_param_decls,
unsigned &type_quals)
unsigned &type_quals,
ClangASTContext::TemplateParameterInfos &template_param_infos)
{
if (parent_die == NULL)
return 0;
@ -3466,6 +3501,11 @@ SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
}
break;
case DW_TAG_template_type_parameter:
case DW_TAG_template_value_parameter:
ParseTemplateDIE (dwarf_cu, die,template_param_infos);
break;
default:
break;
}
@ -5089,6 +5129,7 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
// if we find a "this" paramters as the first parameter
if (is_cxx_method)
is_static = true;
ClangASTContext::TemplateParameterInfos template_param_infos;
if (die->HasChildren())
{
@ -5102,7 +5143,8 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
type_list,
function_param_types,
function_param_decls,
type_quals);
type_quals,
template_param_infos);
}
// clang_type will get the function prototype clang type after this call
@ -5302,6 +5344,17 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu,
storage,
is_inline);
// if (template_param_infos.GetSize() > 0)
// {
// clang::FunctionTemplateDecl *func_template_decl = ast.CreateFunctionTemplateDecl (containing_decl_ctx,
// function_decl,
// type_name_cstr,
// template_param_infos);
//
// ast.CreateFunctionTemplateSpecializationInfo (function_decl,
// func_template_decl,
// template_param_infos);
// }
// Add the decl to our DIE to decl context map
assert (function_decl);
LinkDeclContextToDIE(function_decl, die);

View File

@ -354,7 +354,8 @@ protected:
lldb_private::TypeList* type_list,
std::vector<lldb::clang_type_t>& function_args,
std::vector<clang::ParmVarDecl*>& function_param_decls,
unsigned &type_quals);
unsigned &type_quals,
lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
size_t ParseChildEnumerators(
const lldb_private::SymbolContext& sc,
@ -496,6 +497,11 @@ protected:
const DWARFDebugInfoEntry *parent_die,
lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
bool
ParseTemplateDIE (DWARFCompileUnit* dwarf_cu,
const DWARFDebugInfoEntry *die,
lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos);
clang::ClassTemplateDecl *
ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
lldb::AccessType access_type,

View File

@ -1140,31 +1140,11 @@ ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type
return ast->getTagDeclType(decl).getAsOpaquePtr();
}
ClassTemplateDecl *
ClangASTContext::CreateClassTemplateDecl (DeclContext *decl_ctx,
lldb::AccessType access_type,
const char *class_name,
int kind,
const TemplateParameterInfos &template_param_infos)
static TemplateParameterList *
CreateTemplateParameterList (ASTContext *ast,
const ClangASTContext::TemplateParameterInfos &template_param_infos,
llvm::SmallVector<NamedDecl *, 8> &template_param_decls)
{
ASTContext *ast = getASTContext();
ClassTemplateDecl *class_template_decl = NULL;
if (decl_ctx == NULL)
decl_ctx = ast->getTranslationUnitDecl();
IdentifierInfo &identifier_info = ast->Idents.get(class_name);
DeclarationName decl_name (&identifier_info);
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
{
class_template_decl = dyn_cast<clang::ClassTemplateDecl>(*pos);
if (class_template_decl)
return class_template_decl;
}
llvm::SmallVector<NamedDecl *, 8> template_param_decls;
const bool parameter_pack = false;
const bool is_typename = false;
const unsigned depth = 0;
@ -1206,7 +1186,85 @@ ClangASTContext::CreateClassTemplateDecl (DeclContext *decl_ctx,
&template_param_decls.front(),
template_param_decls.size(),
SourceLocation());
return template_param_list;
}
clang::FunctionTemplateDecl *
ClangASTContext::CreateFunctionTemplateDecl (clang::DeclContext *decl_ctx,
clang::FunctionDecl *func_decl,
const char *name,
const TemplateParameterInfos &template_param_infos)
{
// /// \brief Create a function template node.
ASTContext *ast = getASTContext();
llvm::SmallVector<NamedDecl *, 8> template_param_decls;
TemplateParameterList *template_param_list = CreateTemplateParameterList (ast,
template_param_infos,
template_param_decls);
FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create (*ast,
decl_ctx,
func_decl->getLocation(),
func_decl->getDeclName(),
template_param_list,
func_decl);
for (size_t i=0, template_param_decl_count = template_param_decls.size();
i < template_param_decl_count;
++i)
{
// TODO: verify which decl context we should put template_param_decls into..
template_param_decls[i]->setDeclContext (func_decl);
}
return func_tmpl_decl;
}
void
ClangASTContext::CreateFunctionTemplateSpecializationInfo (FunctionDecl *func_decl,
clang::FunctionTemplateDecl *func_tmpl_decl,
const TemplateParameterInfos &infos)
{
TemplateArgumentList template_args (TemplateArgumentList::OnStack,
infos.args.data(),
infos.args.size());
func_decl->setFunctionTemplateSpecialization (func_tmpl_decl,
&template_args,
NULL);
}
ClassTemplateDecl *
ClangASTContext::CreateClassTemplateDecl (DeclContext *decl_ctx,
lldb::AccessType access_type,
const char *class_name,
int kind,
const TemplateParameterInfos &template_param_infos)
{
ASTContext *ast = getASTContext();
ClassTemplateDecl *class_template_decl = NULL;
if (decl_ctx == NULL)
decl_ctx = ast->getTranslationUnitDecl();
IdentifierInfo &identifier_info = ast->Idents.get(class_name);
DeclarationName decl_name (&identifier_info);
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
{
class_template_decl = dyn_cast<clang::ClassTemplateDecl>(*pos);
if (class_template_decl)
return class_template_decl;
}
llvm::SmallVector<NamedDecl *, 8> template_param_decls;
TemplateParameterList *template_param_list = CreateTemplateParameterList (ast,
template_param_infos,
template_param_decls);
CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create (*ast,
(TagDecl::TagKind)kind,