[Clang][ItaniumMangle][NFC] Refactor FunctionTypeDepthState - #196240
Conversation
|
@llvm/pr-subscribers-clang Author: eiytoq (eiytoq) ChangesThis patch refactors Full diff: https://github.com/llvm/llvm-project/pull/196240.diff 1 Files Affected:
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index f58faa03bfa8c..d07b4b38a0950 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -243,42 +243,34 @@ class CXXNameMangler {
unsigned SeqID = 0;
class FunctionTypeDepthState {
- unsigned Bits = 0;
-
- enum { InResultTypeMask = 1 };
+ unsigned Depth : 31;
+ unsigned InFunctionDeclSuffix : 1;
public:
- FunctionTypeDepthState() = default;
-
- /// The number of function types we're inside.
- unsigned getDepth() const {
- return Bits >> 1;
- }
-
- /// True if we're in the return type of the innermost function type.
- bool isInResultType() const {
- return Bits & InResultTypeMask;
+ FunctionTypeDepthState() : Depth(0), InFunctionDeclSuffix(0) {}
+
+ unsigned getNestingDepth(unsigned ParmDepth) const {
+ // ParmDepth does not include the declaring function prototype.
+ // FunctionTypeDepth does account for that.
+ assert(ParmDepth < Depth &&
+ "ParmVarDecl is not visible in current parameter environment");
+ return Depth - ParmDepth - InFunctionDeclSuffix;
}
FunctionTypeDepthState push() {
- FunctionTypeDepthState tmp = *this;
- Bits = (Bits & ~InResultTypeMask) + 2;
- return tmp;
- }
-
- void enterResultType() {
- Bits |= InResultTypeMask;
- }
-
- void leaveResultType() {
- Bits &= ~InResultTypeMask;
+ FunctionTypeDepthState Saved = *this;
+ ++Depth;
+ InFunctionDeclSuffix = 0;
+ return Saved;
}
- void pop(FunctionTypeDepthState saved) {
- assert(getDepth() == saved.getDepth() + 1);
- Bits = saved.Bits;
+ void pop(FunctionTypeDepthState Saved) {
+ assert(Depth == Saved.Depth + 1 && "unbalanced function type depth pop");
+ *this = Saved;
}
+ void enterFunctionDeclSuffix() { InFunctionDeclSuffix = 1; }
+ void leaveFunctionDeclSuffix() { InFunctionDeclSuffix = 0; }
} FunctionTypeDepth;
// abi_tag is a gcc attribute, taking one or more strings called "tags".
@@ -3752,9 +3744,9 @@ void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
FunctionTypeDepthState saved = FunctionTypeDepth.push();
- FunctionTypeDepth.enterResultType();
+ FunctionTypeDepth.enterFunctionDeclSuffix();
mangleType(T->getReturnType());
- FunctionTypeDepth.leaveResultType();
+ FunctionTypeDepth.leaveFunctionDeclSuffix();
FunctionTypeDepth.pop(saved);
Out << 'E';
@@ -3769,7 +3761,7 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto,
// <bare-function-type> ::= <signature type>+
if (MangleReturnType) {
- FunctionTypeDepth.enterResultType();
+ FunctionTypeDepth.enterFunctionDeclSuffix();
// Mangle ns_returns_retained as an order-sensitive qualifier here.
if (Proto->getExtInfo().getProducesResult() && FD == nullptr)
@@ -3784,7 +3776,7 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto,
}
mangleType(ReturnTy);
- FunctionTypeDepth.leaveResultType();
+ FunctionTypeDepth.leaveFunctionDeclSuffix();
}
if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
@@ -3821,7 +3813,7 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionProtoType *Proto,
}
if (FD) {
- FunctionTypeDepth.enterResultType();
+ FunctionTypeDepth.enterFunctionDeclSuffix();
mangleRequiresClause(FD->getTrailingRequiresClause().ConstraintExpr);
}
@@ -5716,7 +5708,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
Out << '_';
// The rest of the mangling is in the immediate scope of the parameters.
- FunctionTypeDepth.enterResultType();
+ FunctionTypeDepth.enterFunctionDeclSuffix();
for (const concepts::Requirement *Req : RE->getRequirements())
mangleRequirement(RE->getExprLoc(), Req);
FunctionTypeDepth.pop(saved);
@@ -6013,14 +6005,8 @@ void CXXNameMangler::mangleFunctionParam(const ParmVarDecl *parm) {
unsigned parmIndex = parm->getFunctionScopeIndex();
// Compute 'L'.
- // parmDepth does not include the declaring function prototype.
- // FunctionTypeDepth does account for that.
- assert(parmDepth < FunctionTypeDepth.getDepth());
- unsigned nestingDepth = FunctionTypeDepth.getDepth() - parmDepth;
- if (FunctionTypeDepth.isInResultType())
- nestingDepth--;
-
- if (nestingDepth == 0) {
+ if (unsigned nestingDepth = FunctionTypeDepth.getNestingDepth(parmDepth);
+ nestingDepth == 0) {
Out << "fp";
} else {
Out << "fL" << (nestingDepth - 1) << 'p';
@@ -7254,9 +7240,9 @@ CXXNameMangler::makeFunctionReturnTypeTags(const FunctionDecl *FD) {
const FunctionProtoType *Proto =
cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>());
FunctionTypeDepthState saved = TrackReturnTypeTags.FunctionTypeDepth.push();
- TrackReturnTypeTags.FunctionTypeDepth.enterResultType();
+ TrackReturnTypeTags.FunctionTypeDepth.enterFunctionDeclSuffix();
TrackReturnTypeTags.mangleType(Proto->getReturnType());
- TrackReturnTypeTags.FunctionTypeDepth.leaveResultType();
+ TrackReturnTypeTags.FunctionTypeDepth.leaveFunctionDeclSuffix();
TrackReturnTypeTags.FunctionTypeDepth.pop(saved);
return TrackReturnTypeTags.AbiTagsRoot.getSortedUniqueUsedAbiTags();
|
aef4610 to
3a82d0c
Compare
3a82d0c to
dfea8e8
Compare
ojhunt
left a comment
There was a problem hiding this comment.
This looks like a good improvement to me - it took me a while to go through the cursed bit manipulation, but the logic all seems correct to me.
I don't know about the renaming - I'm not sufficiently familiar with mangling terminology so I'd like @erichkeane or @shafik to ok that separately
|
Currently, the flag indicates whether the mangler is processing the function declaration suffix(e.g. return type or trailing requires-clause), so we could rename it to match its role. |
|
If there are no further comments, I plan to merge this PR. |
I'll note that this is absolutely inappropriate to do here. You had an approver who said to wait for other reviewers, and a reviewer with questions that you ignored. Additionally, you gave only 1 'business' day of warning before committing here. THis sort of "speak now or I'll merge it" type of comment is completely inappropriate for this project, and is a great way to lose your ability to contribute to clang. @AaronBallman |
|
@erichkeane This was my mistake. I treated silence as approval and landed this too quickly and I didn't account for the weekend. I can revert the PR if you think that's best. Do you have any thoughts on the renaming? |
We don't take silence as approval, we need positive approval from folks. As far as the rename: I don't think I feel strongly here, but perhaps our maintainers of this (@efriedma-quic ?) might have an idea. As the questions/concerns are minor so far, I think I'm OK with us holding off on reverting unless someone spots one that needs it. I WOULD like @shafik to make sure he's happy though, since he had a number of questions that I tried to answer but we should make sure he was satisfied by them. |
| void enterFunctionDeclSuffix() { InFunctionDeclSuffix = 1; } | ||
| void leaveFunctionDeclSuffix() { InFunctionDeclSuffix = 0; } |
There was a problem hiding this comment.
Should we guard against mismatched calls? e.g., assert that we cannot leave if we've not entered, and assert that we cannot enter if we're already entered?
There was a problem hiding this comment.
I think this makes sense. Because every time FunctionTypeDepth.push() is called, InFunctionDeclSuffix is reset, and at the same depth, enterFunctionDeclSuffix should not be entered repeatedly. However, I'm not entirely sure if I've missed any details.
| mangleType(ReturnTy); | ||
|
|
||
| FunctionTypeDepth.leaveResultType(); | ||
| FunctionTypeDepth.leaveFunctionDeclSuffix(); |
There was a problem hiding this comment.
Would it make sense to add an RAII object to do the enter/leave calls? I worry about the possibility of adding a return in here someday that breaks this.
There was a problem hiding this comment.
We could introduce an RAII object (because the missing leave below is actually omitted), but that might require guarding every call site.
|
|
||
| if (FD) { | ||
| FunctionTypeDepth.enterResultType(); | ||
| FunctionTypeDepth.enterFunctionDeclSuffix(); |
There was a problem hiding this comment.
Ohhh, RAII object might not make sense, what ends up leaving this?
There was a problem hiding this comment.
The state will be restored by the following FunctionTypeDepth.pop(saved), so leaveFunctionDeclSuffix can be omitted here.
|
|
||
| // The rest of the mangling is in the immediate scope of the parameters. | ||
| FunctionTypeDepth.enterResultType(); | ||
| FunctionTypeDepth.enterFunctionDeclSuffix(); |
There was a problem hiding this comment.
What ends up leaving this?
Thanks for catching this @erichkeane! I don't think we need a revert yet, but I also had some questions on the PR. |
shafik
left a comment
There was a problem hiding this comment.
I got my answers but it looks like Aaron has more.
This patch refactors
FunctionTypeDepthStateto use bit-fields and moves thegetNestingDepthlogic into it. It also renames{enter,leave}ResultTypeto{enter,leave}FunctionDeclSuffix, since the old names no longer match theircurrent role.