This is an archive of the discontinued LLVM Phabricator instance.

Itanium Mangling: Fix handling of <expr-primary> in <template-arg>.
ClosedPublic

Authored by jyknight on Jan 26 2021, 3:47 PM.

Details

Summary

Previously, we were emitting an extraneous X .. E in <template-arg>
around an <expr-primary> if the template argument was constructed from
an expression (rather than an already-evaluated literal value). In
such a case, we would then e.g. emit 'XLi0EE' instead of 'Li0E'.

We had one special-case for DeclRefExpr expressions, in particular, to
omit them the mangled-name without the surrounding X/E. However,
unfortunately, that special case also triggered for ParmVarDecl (a
subtype of VarDecl), and _incorrectly_ emitted 'L_Z .. E' instead of
the proper 'Xfp_E'.

This change causes mangleExpression itself to be responsible for
emitting X/E around non-primary expressions, which removes the
special-case, and corrects both these problems.

Diff Detail

Event Timeline

jyknight created this revision.Jan 26 2021, 3:47 PM
jyknight requested review of this revision.Jan 26 2021, 3:47 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 26 2021, 3:47 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
rjmccall added inline comments.Jan 27 2021, 1:23 AM
clang/lib/AST/ItaniumMangle.cpp
3914

I think it might be more reasonable to just check for the relatively small number of primary-expression cases in mangleTemplateArgExpr and skip the X...E there rather than pushing it down into this function.

5161

Oops.

jyknight added inline comments.Jan 27 2021, 6:43 AM
clang/lib/AST/ItaniumMangle.cpp
3914

I started out writing it that way, but it's more complex than it first seems.

First you have the 9 expression types that always fit into <expr-primary> -- those are simple enough, but that's already a lot more than one might think. But, then you also need to handle recusing on all the cases with no output (ParenExprClass etc. -- 10 cases of this). And, finally, you have complex cases like DeclRefExpr, CXXConstructExprClass, and UnaryExprOrTypeTraitExprClass, which sometimes emit a primary expression and sometimes do not.

Putting all of that together, the number of cases to handle with a separate function was large enough -- and duplicative enough -- that it seemed more confusing to have such an implementation split than it was helpful.

jyknight added inline comments.Jan 27 2021, 12:15 PM
clang/lib/AST/ItaniumMangle.cpp
3914

Ultimately, we'd end up with a second large switch in a second function -- but it must be carefully kept in sync with any changes to the switch in mangleExpression. I think that'd just end up more likely to cause problems in the future, when new expression types are added.

Additionally, the NotPrimaryExpr idiom is already in use in mangleValueInTemplateArg, and doing the same thing for both cases is helpful for understandability, IMO.

rjmccall accepted this revision.Jan 27 2021, 12:48 PM

Okay. I can accept this, then.

This revision is now accepted and ready to land.Jan 27 2021, 12:48 PM
rsmith accepted this revision.Jan 27 2021, 1:07 PM
rsmith added inline comments.
clang/lib/AST/ItaniumMangle.cpp
549–550

Looks like this is more than 80 columns.

5147

Given that we've now branched for the Clang 12 release, please make sure you either backport this to the Clang 12 release branch or bump this to > Ver12.

jyknight added inline comments.Jan 27 2021, 1:49 PM
clang/lib/AST/ItaniumMangle.cpp
5147

I think this series of patches should be pushed to clang 12, and will thus keep the version as-is, and ensure it makes it into the newly-created branch.

This revision was landed with ongoing or failed builds.Jan 27 2021, 1:52 PM
This revision was automatically updated to reflect the committed changes.

I agree, that seems like the right decision.