[modules] When we see a definition of a function for which we already… · llvm/llvm-project@b9fa996 (original) (raw)
`@@ -2272,9 +2272,17 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
`
2272
2272
` const Attr *NewAttribute = NewAttributes[I];
`
2273
2273
``
2274
2274
` if (isa(NewAttribute)) {
`
2275
``
`-
if (FunctionDecl *FD = dyn_cast(New))
`
2276
``
`-
S.CheckForFunctionRedefinition(FD, cast(Def));
`
2277
``
`-
else {
`
``
2275
`+
if (FunctionDecl *FD = dyn_cast(New)) {
`
``
2276
`+
Sema::SkipBodyInfo SkipBody;
`
``
2277
`+
S.CheckForFunctionRedefinition(FD, cast(Def), &SkipBody);
`
``
2278
+
``
2279
`+
// If we're skipping this definition, drop the "alias" attribute.
`
``
2280
`+
if (SkipBody.ShouldSkip) {
`
``
2281
`+
NewAttributes.erase(NewAttributes.begin() + I);
`
``
2282
`+
--E;
`
``
2283
`+
continue;
`
``
2284
`+
}
`
``
2285
`+
} else {
`
2278
2286
` VarDecl *VD = cast(New);
`
2279
2287
` unsigned Diag = cast(Def)->isThisDeclarationADefinition() ==
`
2280
2288
` VarDecl::TentativeDefinition
`
`@@ -10398,14 +10406,17 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
`
10398
10406
` }
`
10399
10407
`}
`
10400
10408
``
10401
``
`-
Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
`
``
10409
`+
Decl *
`
``
10410
`+
Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D,
`
``
10411
`+
MultiTemplateParamsArg TemplateParameterLists,
`
``
10412
`+
SkipBodyInfo *SkipBody) {
`
10402
10413
` assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
`
10403
10414
` assert(D.isFunctionDeclarator() && "Not a function declarator!");
`
10404
10415
` Scope *ParentScope = FnBodyScope->getParent();
`
10405
10416
``
10406
10417
` D.setFunctionDefinitionKind(FDK_Definition);
`
10407
``
`-
Decl *DP = HandleDeclarator(ParentScope, D, MultiTemplateParamsArg());
`
10408
``
`-
return ActOnStartOfFunctionDef(FnBodyScope, DP);
`
``
10418
`+
Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists);
`
``
10419
`+
return ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody);
`
10409
10420
`}
`
10410
10421
``
10411
10422
`void Sema::ActOnFinishInlineMethodDef(CXXMethodDecl *D) {
`
`@@ -10469,7 +10480,8 @@ static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
`
10469
10480
``
10470
10481
`void
`
10471
10482
`Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
`
10472
``
`-
const FunctionDecl *EffectiveDefinition) {
`
``
10483
`+
const FunctionDecl *EffectiveDefinition,
`
``
10484
`+
SkipBodyInfo *SkipBody) {
`
10473
10485
` // Don't complain if we're in GNU89 mode and the previous definition
`
10474
10486
` // was an extern inline function.
`
10475
10487
` const FunctionDecl *Definition = EffectiveDefinition;
`
`@@ -10481,17 +10493,20 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
`
10481
10493
` return;
`
10482
10494
``
10483
10495
` // If we don't have a visible definition of the function, and it's inline or
`
10484
``
`-
// a template, it's OK to form another definition of it.
`
10485
``
`-
//
`
10486
``
`-
// FIXME: Should we skip the body of the function and use the old definition
`
10487
``
`-
// in this case? That may be necessary for functions that return local types
`
10488
``
`-
// through a deduced return type, or instantiate templates with local types.
`
10489
``
`-
if (!hasVisibleDefinition(Definition) &&
`
``
10496
`+
// a template, skip the new definition.
`
``
10497
`+
if (SkipBody && !hasVisibleDefinition(Definition) &&
`
10490
10498
` (Definition->getFormalLinkage() == InternalLinkage ||
`
10491
10499
` Definition->isInlined() ||
`
10492
10500
` Definition->getDescribedFunctionTemplate() ||
`
10493
``
`-
Definition->getNumTemplateParameterLists()))
`
``
10501
`+
Definition->getNumTemplateParameterLists())) {
`
``
10502
`+
SkipBody->ShouldSkip = true;
`
``
10503
`+
if (auto *TD = Definition->getDescribedFunctionTemplate())
`
``
10504
`+
makeMergedDefinitionVisible(TD, FD->getLocation());
`
``
10505
`+
else
`
``
10506
`+
makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition),
`
``
10507
`+
FD->getLocation());
`
10494
10508
` return;
`
``
10509
`+
}
`
10495
10510
``
10496
10511
` if (getLangOpts().GNUMode && Definition->isInlineSpecified() &&
`
10497
10512
` Definition->getStorageClass() == SC_Extern)
`
`@@ -10552,7 +10567,8 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,
`
10552
10567
` }
`
10553
10568
`}
`
10554
10569
``
10555
``
`-
Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
`
``
10570
`+
Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
`
``
10571
`+
SkipBodyInfo *SkipBody) {
`
10556
10572
` // Clear the last template instantiation error context.
`
10557
10573
` LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
`
10558
10574
``
`@@ -10564,6 +10580,16 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
`
10564
10580
` FD = FunTmpl->getTemplatedDecl();
`
10565
10581
` else
`
10566
10582
` FD = cast(D);
`
``
10583
+
``
10584
`+
// See if this is a redefinition.
`
``
10585
`+
if (!FD->isLateTemplateParsed()) {
`
``
10586
`+
CheckForFunctionRedefinition(FD, nullptr, SkipBody);
`
``
10587
+
``
10588
`+
// If we're skipping the body, we're done. Don't enter the scope.
`
``
10589
`+
if (SkipBody && SkipBody->ShouldSkip)
`
``
10590
`+
return D;
`
``
10591
`+
}
`
``
10592
+
10567
10593
` // If we are instantiating a generic lambda call operator, push
`
10568
10594
` // a LambdaScopeInfo onto the function stack. But use the information
`
10569
10595
` // that's already been calculated (ActOnLambdaExpr) to prime the current
`
`@@ -10583,10 +10609,6 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
`
10583
10609
` // Enter a new function scope
`
10584
10610
` PushFunctionScope();
`
10585
10611
``
10586
``
`-
// See if this is a redefinition.
`
10587
``
`-
if (!FD->isLateTemplateParsed())
`
10588
``
`-
CheckForFunctionRedefinition(FD);
`
10589
``
-
10590
10612
` // Builtin functions cannot be defined.
`
10591
10613
` if (unsigned BuiltinID = FD->getBuiltinID()) {
`
10592
10614
` if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID) &&
`