================
@@ -1353,6 +1354,92 @@ void CodeGenFunction::EmitAllocToken(llvm::CallBase *CB,
QualType AllocType) {
CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN);
}
+/// Infer type from a simple sizeof expression.
+static QualType inferTypeFromSizeofExpr(const Expr *E) {
+ const Expr *Arg = E->IgnoreParenImpCasts();
+ if (const auto *UET = dyn_cast<UnaryExprOrTypeTraitExpr>(Arg)) {
+ if (UET->getKind() == UETT_SizeOf) {
+ if (UET->isArgumentType())
+ return UET->getArgumentTypeInfo()->getType();
+ else
+ return UET->getArgumentExpr()->getType();
+ }
+ }
+ return QualType();
+}
+
+/// Infer type from an arithmetic expression involving a sizeof.
+static QualType inferTypeFromArithSizeofExpr(const Expr *E) {
+ const Expr *Arg = E->IgnoreParenImpCasts();
+ // The argument is a lone sizeof expression.
+ if (QualType T = inferTypeFromSizeofExpr(Arg); !T.isNull())
+ return T;
+ if (const auto *BO = dyn_cast<BinaryOperator>(Arg)) {
+ // Argument is an arithmetic expression. Cover common arithmetic patterns
+ // involving sizeof.
+ switch (BO->getOpcode()) {
+ case BO_Add:
+ case BO_Div:
+ case BO_Mul:
+ case BO_Shl:
+ case BO_Shr:
+ case BO_Sub:
+ if (QualType T = inferTypeFromArithSizeofExpr(BO->getLHS()); !T.isNull())
+ return T;
+ if (QualType T = inferTypeFromArithSizeofExpr(BO->getRHS()); !T.isNull())
+ return T;
+ break;
+ default:
+ break;
+ }
+ }
+ return QualType();
+}
+
+/// If the expression E is a reference to a variable, infer the type from a
+/// variable's initializer if it contains a sizeof. Beware, this is a heuristic
+/// and ignores if a variable is later reassigned.
+static QualType inferTypeFromVarInitSizeofExpr(const Expr *E) {
+ const Expr *Arg = E->IgnoreParenImpCasts();
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg)) {
+ if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+ if (const Expr *Init = VD->getInit())
+ return inferTypeFromArithSizeofExpr(Init);
+ }
+ }
+ return QualType();
+}
+
+/// Deduces the allocated type by checking if the allocation call's result
+/// is immediately used in a cast expression.
+static QualType inferTypeFromCastExpr(const CallExpr *CallE,
----------------
melver wrote:
You mean for inferTypeFromCastExpr specifically, or in general for all?
General: I think some of the recursive visitors (RecursiveASTVisitor or also
EvaluatedExprVisitor) could help, but they could only give us a differently
shaped inferPossibleTypeFromArithSizeofExpr(). They also don't make early
return and control over the order of visits that easy (unless we override the
Visit function, which defeats the point). And as for efficiency, as I wrote
elsewhere, here we can do more targeted visiting of relevant AST nodes and the
overall algorithm is much more lightweight.
For the "infer from cast" problem specifically, I used to have this
implementation:
```
static QualType inferTypeFromCastExpr(const CallExpr *E, ASTContext &Ctx) {
DynTypedNodeList Parents = Ctx.getParentMapContext().getParents(*E);
if (Parents.empty())
return QualType();
// We only care about the most direct parent for this heuristic.
if (const auto *CE = Parents[0].get<CastExpr>()) {
QualType PtrType = CE->getType();
if (PtrType->isPointerType())
return PtrType->getPointeeType();
}
return QualType();
}
```
But the `getParents` implementation uses RecursiveASTVisitor underneath, which
turned out to be really slow and also ended up crashing on some code using
coroutines. So instead, the current inferTypeFromCastExpr() implementation is
just O(1) by keeping the innermost CurCast saved during normal AST walk.
https://github.com/llvm/llvm-project/pull/156841
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits