@@ -1196,8 +1196,31 @@ void Module::AddFunctionTemplateInstantiation(const std::string &name,
1196
1196
}
1197
1197
1198
1198
void Module::AddFunctionTemplateSpecializationDefinition (const std::string &name, const FunctionType *ftype, Stmt *code,
1199
+ const std::vector<std::pair<const Type *, SourcePos>> &types,
1199
1200
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);
1201
1224
if (sym == nullptr || ftype == nullptr || code == nullptr ) {
1202
1225
Assert (m->errorCount > 0 );
1203
1226
return ;
@@ -1236,68 +1259,10 @@ void Module::AddFunctionTemplateSpecializationDeclaration(const std::string &nam
1236
1259
return ;
1237
1260
}
1238
1261
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 ;
1301
1266
}
1302
1267
}
1303
1268
0 commit comments