Skip to content

Commit 7493679

Browse files
committed
Fixed overloading
1 parent 0a03a31 commit 7493679

File tree

5 files changed

+46
-72
lines changed

5 files changed

+46
-72
lines changed

src/func.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,13 +1001,14 @@ Symbol *FunctionTemplate::AddSpecialization(const FunctionType *ftype,
10011001
instSym->type = ftype;
10021002
instSym->pos = pos;
10031003

1004-
bool ok = m->symbolTable->AddFunction(instSym);
1005-
Assert(ok);
1004+
// bool ok = m->symbolTable->AddFunction(instSym);
1005+
// Assert(ok);
10061006

10071007
TemplateArgs *templArgs = new TemplateArgs(types);
1008+
// Check if we have previously declared specialization and we are about to define it.
10081009
Symbol *funcSym = LookupInstantiation(types);
10091010
if (funcSym != nullptr) {
1010-
Error(pos, "Function template specialization already exists.");
1011+
return funcSym;
10111012
} else {
10121013
instantiations.push_back(std::make_pair(templArgs, instSym));
10131014
}

src/module.cpp

Lines changed: 28 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,8 +1196,31 @@ void Module::AddFunctionTemplateInstantiation(const std::string &name,
11961196
}
11971197

11981198
void Module::AddFunctionTemplateSpecializationDefinition(const std::string &name, const FunctionType *ftype, Stmt *code,
1199+
const std::vector<std::pair<const Type *, SourcePos>> &types,
11991200
SourcePos pos) {
1200-
Symbol *sym = symbolTable->LookupFunction(name.c_str(), ftype);
1201+
if (ftype == nullptr) {
1202+
Assert(m->errorCount > 0);
1203+
return;
1204+
}
1205+
1206+
if (types.size() == 0) {
1207+
Error(pos, "Template function specialization without explicit template arguments is not supported yet.");
1208+
return;
1209+
}
1210+
std::vector<TemplateSymbol *> matches;
1211+
bool found = symbolTable->LookupFunctionTemplate(name, &matches);
1212+
if (!found) {
1213+
Error(pos, "No matching function template found for specialization.");
1214+
return;
1215+
}
1216+
std::vector<std::pair<const Type *, SourcePos>> normTypes(types);
1217+
1218+
FunctionTemplate *templ = lNormalizeAndMatchFunctionTemplate(ftype, normTypes, matches);
1219+
if (templ == nullptr) {
1220+
Error(pos, "No matching function template found for specialization.");
1221+
return;
1222+
}
1223+
Symbol *sym = templ->LookupInstantiation(normTypes);
12011224
if (sym == nullptr || ftype == nullptr || code == nullptr) {
12021225
Assert(m->errorCount > 0);
12031226
return;
@@ -1236,68 +1259,10 @@ void Module::AddFunctionTemplateSpecializationDeclaration(const std::string &nam
12361259
return;
12371260
}
12381261
Symbol *funcSym = templ->LookupInstantiation(normTypes);
1239-
if (funcSym != nullptr && Type::Equal(funcSym->type, ftype) && funcSym->parentFunction != nullptr) {
1240-
Error(pos, "Template function specialization was already defined.");
1241-
return;
1242-
}
1243-
1244-
/* TODO: We should allow coexistense of template function specialization and overload functions. For example:
1245-
template <> noinline int goo<int, float>(int argGooOne, float argGooTwo) {
1246-
return argGooOne * argGooTwo;
1247-
}
1248-
1249-
noinline int goo(int argGooOne, float argGooTwo) {
1250-
return argGooOne * argGooTwo;
1251-
}
1252-
*/
1253-
std::vector<Symbol *> overloadFuncs;
1254-
symbolTable->LookupFunction(name.c_str(), &overloadFuncs);
1255-
if (overloadFuncs.size() > 0) {
1256-
for (unsigned int i = 0; i < overloadFuncs.size(); ++i) {
1257-
Symbol *overloadFunc = overloadFuncs[i];
1258-
1259-
const FunctionType *overloadType = CastType<FunctionType>(overloadFunc->type);
1260-
if (overloadType == nullptr) {
1261-
Assert(m->errorCount == 0);
1262-
continue;
1263-
}
1264-
1265-
// Check for a redeclaration of a function with the same name
1266-
// and type. This also hits when we have previously declared
1267-
// the function and are about to define it.
1268-
if (Type::Equal(overloadFunc->type, ftype))
1269-
return;
1270-
1271-
if (ftype->isExported || overloadType->isExported)
1272-
Error(pos,
1273-
"Illegal to provide \"export\" qualifier for "
1274-
"functions with the same name but different types. "
1275-
"(Previous function declaration (%s:%d).)",
1276-
overloadFunc->pos.name, overloadFunc->pos.first_line);
1277-
1278-
// If all of the parameter types match but the return type is
1279-
// different, return an error--overloading by return type isn't
1280-
// allowed.
1281-
const FunctionType *ofType = CastType<FunctionType>(overloadFunc->type);
1282-
Assert(ofType != nullptr);
1283-
if (ofType->GetNumParameters() == ftype->GetNumParameters()) {
1284-
int i;
1285-
for (i = 0; i < ftype->GetNumParameters(); ++i) {
1286-
if (Type::Equal(ofType->GetParameterType(i), ftype->GetParameterType(i)) == false)
1287-
break;
1288-
}
1289-
if (i == ftype->GetNumParameters()) {
1290-
std::string thisRetType = ftype->GetReturnTypeString();
1291-
std::string otherRetType = ofType->GetReturnTypeString();
1292-
Error(pos,
1293-
"Illegal to overload function by return "
1294-
"type only. This function returns \"%s\" while "
1295-
"previous declaration at %s:%d returns \"%s\".",
1296-
thisRetType.c_str(), overloadFunc->pos.name, overloadFunc->pos.first_line,
1297-
otherRetType.c_str());
1298-
return;
1299-
}
1300-
}
1262+
if (funcSym != nullptr) {
1263+
if (Type::Equal(funcSym->type, ftype) && funcSym->parentFunction != nullptr) {
1264+
Error(pos, "Template function specialization was already defined.");
1265+
return;
13011266
}
13021267
}
13031268

src/module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class Module {
9595
const FunctionType *ftype, SourcePos pos);
9696

9797
void AddFunctionTemplateSpecializationDefinition(const std::string &name, const FunctionType *ftype, Stmt *code,
98+
const std::vector<std::pair<const Type *, SourcePos>> &types,
9899
SourcePos pos);
99100

100101
/** Adds the given type to the set of types that have their definitions

src/parse.yy

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ struct ForeachDimension {
226226
%type <declarationList> parameter_list parameter_type_list
227227
%type <declarator> declarator pointer reference
228228
%type <declarator> init_declarator direct_declarator struct_declarator
229-
%type <declarator> abstract_declarator direct_abstract_declarator template_function_specialization_declaration
229+
%type <declarator> abstract_declarator direct_abstract_declarator
230230

231231
%type <structDeclaratorList> struct_declarator_list
232232
%type <structDeclaration> struct_declaration
@@ -262,7 +262,7 @@ struct ForeachDimension {
262262

263263
%type <constCharPtr> template_identifier
264264
%type <typeList> template_argument_list
265-
%type <simpleTemplateID> simple_template_id
265+
%type <simpleTemplateID> simple_template_id template_function_specialization_declaration
266266
%type <templateParm> template_type_parameter template_int_parameter template_parameter
267267
%type <templateParmList> template_parameter_list template_head
268268
%type <functionTemplateSym> template_declaration
@@ -2595,8 +2595,8 @@ template_function_specialization_declaration
25952595
lAddFunctionParams(d);
25962596
lAddMaskToSymbolTable(@5);
25972597

2598-
lFreeSimpleTemplateID($5);
2599-
$$ = d;
2598+
//lFreeSimpleTemplateID($5);
2599+
$$ = new std::pair(d, $5->second);
26002600
}
26012601
;
26022602

@@ -2610,14 +2610,14 @@ template_function_specialization
26102610
}
26112611
| template_function_specialization_declaration compound_statement
26122612
{
2613-
Declarator *d = $1;
2613+
Declarator *d = $1->first;
26142614
const FunctionType *ftype = CastType<FunctionType>(d->type);
26152615
if (ftype == nullptr)
26162616
AssertPos(@1, m->errorCount > 0);
26172617
else {
26182618
Stmt *code = $2;
26192619
if (code == nullptr) code = new StmtList(@2);
2620-
m->AddFunctionTemplateSpecializationDefinition(d->name, ftype, code, Union(@1, @2));
2620+
m->AddFunctionTemplateSpecializationDefinition(d->name, ftype, code, *$1->second, Union(@1, @2));
26212621
}
26222622
m->symbolTable->PopScope();
26232623

tests/lit-tests/func_template_spec_1.ispc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Check basic scenario for functions specializations.
22
// RUN: %{ispc} %s --emit-llvm-text --target=host --nostdlib -o - | FileCheck %s
33

4+
// Regular function
5+
// CHECK-LABEL: define <{{[0-9]*}} x i32> @goo___vyivyf(<{{[0-9]*}} x i32> %argGooOne, <{{[0-9]*}} x float> %argGooTwo, <{{[0-9]*}} x {{.*}}> %__mask)
6+
47
// Specialized function
58
// CHECK-LABEL: define {{.*}} <{{[0-9]*}} x i32> @goo___vyivyf___vyivyf(<{{[0-9]*}} x i32> %argGooOne, <{{[0-9]*}} x float> %argGooTwo)
69
// Check that implementation of specialized function is generated from specialization
@@ -19,6 +22,10 @@ template <typename T, typename C> noinline int goo(T argGooOne, C argGooTwo) {
1922
return argGooOne + argGooTwo;
2023
}
2124

25+
noinline int goo(int argGooOne, float argGooTwo) {
26+
return argGooOne * argGooTwo;
27+
}
28+
2229
template <> noinline int goo<int, float>(int argGooOne, float argGooTwo) {
2330
return argGooOne * argGooTwo;
2431
}

0 commit comments

Comments
 (0)