@@ -4418,6 +4418,85 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
4418
4418
return false;
4419
4419
}
4420
4420
4421
+ // The same as MergeCompatibleFunctionDecls, but for MSVC-compatible
4422
+ bool Sema::MergeMSVCCompatibleFunctionDecls(FunctionDecl *New,
4423
+ FunctionDecl *Old, Scope *S,
4424
+ bool MergeTypeWithOld) {
4425
+ QualType OldQType = Context.getCanonicalType(Old->getType());
4426
+ QualType NewQType = Context.getCanonicalType(New->getType());
4427
+
4428
+ const FunctionType *OldFuncType = OldQType->getAs<FunctionType>();
4429
+ const FunctionType *NewFuncType = NewQType->getAs<FunctionType>();
4430
+
4431
+ const FunctionProtoType *OldProto = nullptr;
4432
+ const FunctionProtoType *NewProto = nullptr;
4433
+
4434
+ // If the types are not funtion types, do not merge the declarations.
4435
+ if (!((NewProto = dyn_cast<FunctionProtoType>(NewFuncType)) &&
4436
+ (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))))
4437
+ return true;
4438
+
4439
+ // If the parameter types are different, do not merge the declarations.
4440
+ if (OldProto->param_types().size() != NewProto->param_types().size())
4441
+ return true;
4442
+
4443
+ // Check parameter types if we can merge the declarations.
4444
+ bool CanMerge = false;
4445
+ if (OldProto->param_types().size() != 0) {
4446
+ for (size_t i = 0; i < OldProto->param_types().size(); ++i) {
4447
+ QualType OldParamType = OldProto->param_types()[i];
4448
+ QualType NewParamType = NewProto->param_types()[i];
4449
+
4450
+ // Remove local const/volatile qualifiers from the parameter types.
4451
+ OldParamType.removeLocalConst();
4452
+ NewParamType.removeLocalConst();
4453
+ OldParamType.removeLocalVolatile();
4454
+ NewParamType.removeLocalVolatile();
4455
+
4456
+ // If the parameter types are different, we need to check if we can
4457
+ // merge the declarations.
4458
+ if (OldParamType.getAsString() != NewParamType.getAsString()) {
4459
+ // If the parameter types are PointerType, we can merge the
4460
+ // declarations.
4461
+ if (isa<PointerType>(OldParamType) &&
4462
+ isa<PointerType>(NewParamType)) {
4463
+ CanMerge = true;
4464
+ continue;
4465
+ }
4466
+ CanMerge = false;
4467
+ break;
4468
+ }
4469
+ }
4470
+ }
4471
+ if (!CanMerge)
4472
+ return true;
4473
+
4474
+ if (MergeTypeWithOld) {
4475
+ // The old declaration provided a function prototype, but the
4476
+ // new declaration does not. Merge in the prototype.
4477
+ assert(!OldProto->hasExceptionSpec() && "Exception spec in C");
4478
+ NewQType = Context.getFunctionType(NewFuncType->getReturnType(),
4479
+ OldProto->getParamTypes(),
4480
+ OldProto->getExtProtoInfo());
4481
+ New->setType(NewQType);
4482
+ New->setHasInheritedPrototype();
4483
+
4484
+ // Synthesize parameters with the same types.
4485
+ SmallVector<ParmVarDecl *, 16> Params;
4486
+ for (const auto &ParamType : OldProto->param_types()) {
4487
+ ParmVarDecl *Param = ParmVarDecl::Create(
4488
+ Context, New, SourceLocation(), SourceLocation(), nullptr,
4489
+ ParamType, /*TInfo=*/nullptr, SC_None, nullptr);
4490
+ Param->setScopeInfo(0, Params.size());
4491
+ Param->setImplicit();
4492
+ Params.push_back(Param);
4493
+ }
4494
+
4495
+ New->setParams(Params);
4496
+ }
4497
+ return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld);
4498
+ }
4499
+
4421
4500
void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,
4422
4501
ObjCMethodDecl *oldMethod) {
4423
4502
// Merge the attributes, including deprecated/unavailable
0 commit comments