[clang] 8a25145 - [clang][Interp] Pass CallExpr to builtin functions

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 17 01:21:32 PDT 2023


Author: Timm Bäder
Date: 2023-08-17T10:20:58+02:00
New Revision: 8a25145058d29fe0fa06cd3cdb90fea7e21228bb

URL: https://github.com/llvm/llvm-project/commit/8a25145058d29fe0fa06cd3cdb90fea7e21228bb
DIFF: https://github.com/llvm/llvm-project/commit/8a25145058d29fe0fa06cd3cdb90fea7e21228bb.diff

LOG: [clang][Interp] Pass CallExpr to builtin functions

For some builtins, we need to do quite a bit of type checking ourselves,
so pass the call expression along. This way we can inspect arguments,
expected return value, etc.

Differential Revision: https://reviews.llvm.org/D155545

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/Interp.h
    clang/lib/AST/Interp/InterpBuiltin.cpp
    clang/lib/AST/Interp/Opcodes.td

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 8a756e4fc2db42..1d528f642e10be 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1824,7 +1824,7 @@ bool ByteCodeExprGen<Emitter>::VisitBuiltinCallExpr(const CallExpr *E) {
       return false;
   }
 
-  if (!this->emitCallBI(Func, E))
+  if (!this->emitCallBI(Func, E, E))
     return false;
 
   QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index c278144a387130..560daca1de6eda 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -174,7 +174,8 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, APFloat::opStatus Status);
 bool Interpret(InterpState &S, APValue &Result);
 
 /// Interpret a builtin function.
-bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F);
+bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
+                      const CallExpr *Call);
 
 enum class ArithOp { Add, Sub };
 
@@ -1741,13 +1742,14 @@ inline bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func) {
   return Call(S, OpPC, Func);
 }
 
-inline bool CallBI(InterpState &S, CodePtr &PC, const Function *Func) {
+inline bool CallBI(InterpState &S, CodePtr &PC, const Function *Func,
+                   const CallExpr *CE) {
   auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
 
   InterpFrame *FrameBefore = S.Current;
   S.Current = NewFrame.get();
 
-  if (InterpretBuiltin(S, PC, Func)) {
+  if (InterpretBuiltin(S, PC, Func, CE)) {
     NewFrame.release();
     return true;
   }

diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 2632ec7224379e..5277d05c82adfb 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -240,10 +240,9 @@ static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC,
 /// second one is an integral value.
 static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC,
                                       const InterpFrame *Frame,
-                                      const Function *Func) {
-  const Expr *E = S.Current->getExpr(OpPC);
-  const CallExpr *CE = cast<CallExpr>(E);
-  PrimType FPClassArgT = *S.getContext().classify(CE->getArgs()[1]->getType());
+                                      const Function *Func,
+                                      const CallExpr *Call) {
+  PrimType FPClassArgT = *S.getContext().classify(Call->getArg(1)->getType());
   APSInt FPClassArg = peekToAPSInt(S.Stk, FPClassArgT);
   const Floating &F =
       S.Stk.peek<Floating>(align(primSize(FPClassArgT) + primSize(PT_Float)));
@@ -300,7 +299,8 @@ static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC,
   return true;
 }
 
-bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) {
+bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
+                      const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
   APValue Dummy;
 
@@ -394,7 +394,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F) {
       return Ret<PT_Sint32>(S, OpPC, Dummy);
     break;
   case Builtin::BI__builtin_isfpclass:
-    if (interp__builtin_isfpclass(S, OpPC, Frame, F))
+    if (interp__builtin_isfpclass(S, OpPC, Frame, F, Call))
       return Ret<PT_Sint32>(S, OpPC, Dummy);
     break;
   case Builtin::BI__builtin_fpclassify:

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 0f494c530b2568..a990d1ed976600 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -52,6 +52,7 @@ def ArgFltSemantics : ArgType { let Name = "const llvm::fltSemantics *"; }
 def ArgRoundingMode : ArgType { let Name = "llvm::RoundingMode"; }
 def ArgLETD: ArgType { let Name = "const LifetimeExtendedTemporaryDecl *"; }
 def ArgCastKind : ArgType { let Name = "CastKind"; }
+def ArgCallExpr : ArgType { let Name = "const CallExpr *"; }
 
 //===----------------------------------------------------------------------===//
 // Classes of types instructions operate on.
@@ -188,7 +189,7 @@ def CallVirt : Opcode {
 }
 
 def CallBI : Opcode {
-  let Args = [ArgFunction];
+  let Args = [ArgFunction, ArgCallExpr];
   let Types = [];
 }
 


        


More information about the cfe-commits mailing list