This is an archive of the discontinued LLVM Phabricator instance.

[modules] Add a flag for TagDecl if it was a definition demoted to a declaration.
ClosedPublic

Authored by vsapsai on Feb 2 2022, 3:40 PM.

Details

Summary

For redeclaration chains we maintain an invariant of having only a
single definition in the chain. In a single translation unit we make
sure not to create duplicates. But modules are separate translation
units and they can contain definitions for the same symbol
independently. When we load such modules together, we need to demote
duplicate definitions to keep the AST invariants.

Some AST clients are interested in distinguishing
declaration-that-was-demoted-from-definition and
declaration-that-was-never-a-definition. For that purpose introducing
IsThisDeclarationADemotedDefinition. No functional change intended.

rdar://84677782

Diff Detail

Event Timeline

vsapsai created this revision.Feb 2 2022, 3:40 PM
vsapsai requested review of this revision.Feb 2 2022, 3:40 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 2 2022, 3:40 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

Relevant discussion on how this is used in Swift is in https://github.com/apple/swift/pull/41144 Also it contains links to various [successful] test runs.

libomptarget :: x86_64-pc-linux-gnu :: mapping/delete_inf_refcount.c has failed due to

/usr/bin/ld: final link failed: bad value

As far as I can tell, it's not related to my change.

Ping. Swift PR testing is happy with this change and I've tested it successfully on >100 swift projects. So looks like this change is safe and does what it intends to do.

This revision is now accepted and ready to land.Feb 14 2022, 11:04 AM

Change seems reasonable but I don't have expertise on this code. I've left a few minor nits.

clang/include/clang/AST/Decl.h
3494

This name feels a little clunky. How about isDemotedDefinition()?

3500

Given the name of this function (suggesting it always demotes) it probably should

assert(!isThisDeclarationADemotedDefinition() && "decl already demoted");

alternatively comments saying the operation is idempotent is probably fine too.

3500

The demoteThisDefinitionToDeclaration() name feels a little bit clunky. How about demoteDefinitionToDecl()?

Thanks for the review, Dan!

clang/include/clang/AST/Decl.h
1383–1398

Naming for my change is mimicking this API.

3494

I agree the name is awkward but I am using the same name as NonParmVarDecl does. Based on similarities in implementation I think the similarities in the name are useful. Also we have isThisDeclarationADefinition in multiple places, so it is good to follow the same naming pattern, even if it is clunky.

3500

Interesting suggestion, made me think about what exactly I'm trying to do here. The strict requirement is not to set the flag on forward declarations (aka non-definitions). To achieve that the alternative would be

if (!isCompleteDefinition())
  return;
setCompleteDefinition(false);
TagDeclBits.IsThisDeclarationADemotedDefinition = true;

Which is similar to the current code with the assertion. Demoting already demoted definition again is acceptable but there is really no need for that.

I agree the assertion makes the code less robust but its purpose is to enforce expected API usage, so being picky about the way it is called is intended. Though let me change the assertion message to something more actionable rather than state-of-the-world-observation.

vsapsai updated this revision to Diff 408536.Feb 14 2022, 11:50 AM

Update assertion message wording to be more actionable.

lgtm.

Thanks for the review, Michael! I'll give some time to the pre-merge checks to run, then will land the change.