In findAnyFunction, properly handle the template case.

As the other findFunction*, findAnyFunction does not
(yet?) instantiate the function template if has not
yet been instantiated.

Also add test for findAnyFunction.
This commit is contained in:
Philippe Canal 2013-11-03 23:22:41 -06:00 committed by sftnight
parent 6f87119b4b
commit 0adde75bd2
2 changed files with 52 additions and 6 deletions

View File

@ -921,8 +921,8 @@ namespace cling {
const llvm::SmallVector<Expr*, 4> &,
LookupResult &Result,
DeclarationNameInfo &,
const TemplateArgumentListInfo* ,
ASTContext&, Parser &, Sema &) {
const TemplateArgumentListInfo* ExplicitTemplateArgs,
ASTContext&, Parser &, Sema &S) {
//
// Check for lookup failure.
//
@ -930,11 +930,33 @@ namespace cling {
return 0;
if (Result.isSingleResult())
return dyn_cast<FunctionDecl>(Result.getFoundDecl());
else
return dyn_cast<FunctionDecl>(*(Result.begin()));
else {
NamedDecl *aResult = *(Result.begin());
FunctionDecl *res = dyn_cast<FunctionDecl>(aResult);
if (res) return res;
FunctionTemplateDecl *MethodTmpl =dyn_cast<FunctionTemplateDecl>(aResult);
if (MethodTmpl) {
// pick a specialization that result match the given arguments
SourceLocation loc;
sema::TemplateDeductionInfo Info(loc);
FunctionDecl *fdecl = 0;
Sema::TemplateDeductionResult Result
= S.DeduceTemplateArguments(MethodTmpl,
const_cast<TemplateArgumentListInfo*>(ExplicitTemplateArgs),
fdecl,
Info);
if (Result) {
// deduction failure
return 0;
} else {
return fdecl;
}
}
return 0;
}
}
const FunctionDecl* LookupHelper::findAnyFunction(const clang::Decl* scopeDecl,
const FunctionDecl* LookupHelper::findAnyFunction(const clang::Decl*scopeDecl,
llvm::StringRef funcName,
bool objectIsConst
) const{

View File

@ -900,7 +900,7 @@ func_B_m_proto->print(llvm::errs());
//
// Test finding a member function that const or not
// Test finding a member function that are const or not
//
const clang::FunctionDecl* func_B_n_args = lookup.findFunctionArgs(class_A, "B_n", "", false);
@ -1283,6 +1283,30 @@ dumpDecl("func_B_plus_proto", func_B_plus_proto);
//CHECK-NEXT: return b;
//CHECK-NEXT: }
//
// Test finding simple member function (including template instantiations
// from just the name.
//
const clang::FunctionDecl* func_B_j_name = lookup.findAnyFunction(class_A, "B_j");
printf("func_B_j_name: 0x%lx\n", (unsigned long) func_B_j_name);
//CHECK: func_B_j_name: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_j_name->print(llvm::errs());
//CHECK-NEXT: void B_j(int vi, int vj) {
//CHECK-NEXT: int x = vi;
//CHECK-NEXT: int y = vj;
//CHECK-NEXT: }
const clang::FunctionDecl* func_B_k1_name = lookup.findAnyFunction(class_A, "B_k<int>");
printf("func_B_k1_name: 0x%lx\n", (unsigned long) func_B_k1_name);
//CHECK: func_B_k1_name: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_k1_name->print(llvm::errs());
//CHECK-NEXT: void B_k(int v) {
//CHECK-NEXT: int x = v;
//CHECK-NEXT: }
//
// One final check to make sure we are at the right line in the output.