[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)

2023-11-10 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/71972

This adds some infrastructure for unevaluated builtin calls, but the 
implementation is almost entirely copied from `ExprConstant.cpp`. I'm open for 
suggestions on how to share the code.

>From 01e541c726de7bd2aca290f51224e2cafcb4494d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 10 Nov 2023 19:33:21 +0100
Subject: [PATCH] [clang][Interp] Implement __builtin_classify_type

---
 clang/lib/AST/Interp/ByteCodeEmitter.cpp |  15 +-
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  10 +-
 clang/lib/AST/Interp/Function.cpp|   7 +-
 clang/lib/AST/Interp/Function.h  |   5 +-
 clang/lib/AST/Interp/Interp.cpp  |   3 +-
 clang/lib/AST/Interp/InterpBuiltin.cpp   | 193 +++
 clang/test/Sema/builtin-classify-type.c  |   1 +
 clang/test/SemaCXX/builtin-classify-type.cpp |   1 +
 8 files changed, 222 insertions(+), 13 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp 
b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index c8abb7c17a38ba2..89b7708c0c2a12f 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -14,6 +14,7 @@
 #include "Program.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/Basic/Builtins.h"
 #include 
 
 using namespace clang;
@@ -84,10 +85,16 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
 
   // Create a handle over the emitted code.
   Function *Func = P.getFunction(FuncDecl);
-  if (!Func)
-Func = P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
-std::move(ParamDescriptors),
-std::move(ParamOffsets), HasThisPointer, HasRVO);
+  if (!Func) {
+bool IsUnevaluatedBuiltin = false;
+if (unsigned BI = FuncDecl->getBuiltinID())
+  IsUnevaluatedBuiltin = Ctx.getASTContext().BuiltinInfo.isUnevaluated(BI);
+
+Func =
+P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
+ std::move(ParamDescriptors), std::move(ParamOffsets),
+ HasThisPointer, HasRVO, IsUnevaluatedBuiltin);
+  }
 
   assert(Func);
   // For not-yet-defined functions, we only create a Function instance and
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 15a717089660337..f1aa1d22315f658 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2226,10 +2226,12 @@ bool 
ByteCodeExprGen::VisitBuiltinCallExpr(const CallExpr *E) {
   if (!Func)
 return false;
 
-  // Put arguments on the stack.
-  for (const auto *Arg : E->arguments()) {
-if (!this->visit(Arg))
-  return false;
+  if (!Func->isUnevaluatedBuiltin()) {
+// Put arguments on the stack.
+for (const auto *Arg : E->arguments()) {
+  if (!this->visit(Arg))
+return false;
+}
   }
 
   if (!this->emitCallBI(Func, E, E))
diff --git a/clang/lib/AST/Interp/Function.cpp 
b/clang/lib/AST/Interp/Function.cpp
index 357aff7fe6229b9..784e6a2df1d8806 100644
--- a/clang/lib/AST/Interp/Function.cpp
+++ b/clang/lib/AST/Interp/Function.cpp
@@ -20,11 +20,12 @@ Function::Function(Program &P, const FunctionDecl *F, 
unsigned ArgSize,
llvm::SmallVectorImpl &&ParamTypes,
llvm::DenseMap &&Params,
llvm::SmallVectorImpl &&ParamOffsets,
-   bool HasThisPointer, bool HasRVO)
+   bool HasThisPointer, bool HasRVO, bool UnevaluatedBuiltin)
 : P(P), Loc(F->getBeginLoc()), F(F), ArgSize(ArgSize),
   ParamTypes(std::move(ParamTypes)), Params(std::move(Params)),
   ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer),
-  HasRVO(HasRVO), Variadic(F->isVariadic()) {}
+  HasRVO(HasRVO), Variadic(F->isVariadic()),
+  IsUnevaluatedBuiltin(UnevaluatedBuiltin) {}
 
 Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
   auto It = Params.find(Offset);
@@ -50,7 +51,7 @@ bool Function::isVirtual() const {
 }
 
 bool Function::needsRuntimeArgPop(const ASTContext &Ctx) const {
-  if (!isBuiltin())
+  if (!isBuiltin() || isUnevaluatedBuiltin())
 return false;
   return Ctx.BuiltinInfo.hasCustomTypechecking(getBuiltinID());
 }
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index be9b1733635f725..cbd17d90ada3944 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -179,6 +179,8 @@ class Function final {
 
   bool isBuiltin() const { return F->getBuiltinID() != 0; }
 
+  bool isUnevaluatedBuiltin() const { return IsUnevaluatedBuiltin; }
+
   /// Does this function need its arguments to be classified at runtime
   /// rather than at bytecode-compile-time?
   bool needsRuntimeArgPop(const ASTContext &Ctx) const;
@@ -195,7 +197,7 @@ class Functi

[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)

2023-11-10 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

This adds some infrastructure for unevaluated builtin calls, but the 
implementation is almost entirely copied from `ExprConstant.cpp`. I'm open for 
suggestions on how to share the code.

---
Full diff: https://github.com/llvm/llvm-project/pull/71972.diff


8 Files Affected:

- (modified) clang/lib/AST/Interp/ByteCodeEmitter.cpp (+11-4) 
- (modified) clang/lib/AST/Interp/ByteCodeExprGen.cpp (+6-4) 
- (modified) clang/lib/AST/Interp/Function.cpp (+4-3) 
- (modified) clang/lib/AST/Interp/Function.h (+4-1) 
- (modified) clang/lib/AST/Interp/Interp.cpp (+2-1) 
- (modified) clang/lib/AST/Interp/InterpBuiltin.cpp (+193) 
- (modified) clang/test/Sema/builtin-classify-type.c (+1) 
- (modified) clang/test/SemaCXX/builtin-classify-type.cpp (+1) 


``diff
diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp 
b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index c8abb7c17a38ba2..89b7708c0c2a12f 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -14,6 +14,7 @@
 #include "Program.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/Basic/Builtins.h"
 #include 
 
 using namespace clang;
@@ -84,10 +85,16 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) {
 
   // Create a handle over the emitted code.
   Function *Func = P.getFunction(FuncDecl);
-  if (!Func)
-Func = P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
-std::move(ParamDescriptors),
-std::move(ParamOffsets), HasThisPointer, HasRVO);
+  if (!Func) {
+bool IsUnevaluatedBuiltin = false;
+if (unsigned BI = FuncDecl->getBuiltinID())
+  IsUnevaluatedBuiltin = Ctx.getASTContext().BuiltinInfo.isUnevaluated(BI);
+
+Func =
+P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes),
+ std::move(ParamDescriptors), std::move(ParamOffsets),
+ HasThisPointer, HasRVO, IsUnevaluatedBuiltin);
+  }
 
   assert(Func);
   // For not-yet-defined functions, we only create a Function instance and
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 15a717089660337..f1aa1d22315f658 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2226,10 +2226,12 @@ bool 
ByteCodeExprGen::VisitBuiltinCallExpr(const CallExpr *E) {
   if (!Func)
 return false;
 
-  // Put arguments on the stack.
-  for (const auto *Arg : E->arguments()) {
-if (!this->visit(Arg))
-  return false;
+  if (!Func->isUnevaluatedBuiltin()) {
+// Put arguments on the stack.
+for (const auto *Arg : E->arguments()) {
+  if (!this->visit(Arg))
+return false;
+}
   }
 
   if (!this->emitCallBI(Func, E, E))
diff --git a/clang/lib/AST/Interp/Function.cpp 
b/clang/lib/AST/Interp/Function.cpp
index 357aff7fe6229b9..784e6a2df1d8806 100644
--- a/clang/lib/AST/Interp/Function.cpp
+++ b/clang/lib/AST/Interp/Function.cpp
@@ -20,11 +20,12 @@ Function::Function(Program &P, const FunctionDecl *F, 
unsigned ArgSize,
llvm::SmallVectorImpl &&ParamTypes,
llvm::DenseMap &&Params,
llvm::SmallVectorImpl &&ParamOffsets,
-   bool HasThisPointer, bool HasRVO)
+   bool HasThisPointer, bool HasRVO, bool UnevaluatedBuiltin)
 : P(P), Loc(F->getBeginLoc()), F(F), ArgSize(ArgSize),
   ParamTypes(std::move(ParamTypes)), Params(std::move(Params)),
   ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer),
-  HasRVO(HasRVO), Variadic(F->isVariadic()) {}
+  HasRVO(HasRVO), Variadic(F->isVariadic()),
+  IsUnevaluatedBuiltin(UnevaluatedBuiltin) {}
 
 Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
   auto It = Params.find(Offset);
@@ -50,7 +51,7 @@ bool Function::isVirtual() const {
 }
 
 bool Function::needsRuntimeArgPop(const ASTContext &Ctx) const {
-  if (!isBuiltin())
+  if (!isBuiltin() || isUnevaluatedBuiltin())
 return false;
   return Ctx.BuiltinInfo.hasCustomTypechecking(getBuiltinID());
 }
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index be9b1733635f725..cbd17d90ada3944 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -179,6 +179,8 @@ class Function final {
 
   bool isBuiltin() const { return F->getBuiltinID() != 0; }
 
+  bool isUnevaluatedBuiltin() const { return IsUnevaluatedBuiltin; }
+
   /// Does this function need its arguments to be classified at runtime
   /// rather than at bytecode-compile-time?
   bool needsRuntimeArgPop(const ASTContext &Ctx) const;
@@ -195,7 +197,7 @@ class Function final {
llvm::SmallVectorImpl &&ParamTypes,
llvm::DenseMap &&Params,
llvm::SmallVectorImpl &&ParamOffsets, bool

[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)

2023-11-15 Thread Aaron Ballman via cfe-commits


@@ -439,6 +439,194 @@ static bool interp__builtin_popcount(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+// Values returned by __builtin_classify_type, chosen to match the values
+/// produced by GCC's builtin.
+enum class GCCTypeClass {
+  None = -1,
+  Void = 0,
+  Integer = 1,
+  // GCC reserves 2 for character types, but instead classifies them as
+  // integers.
+  Enum = 3,
+  Bool = 4,
+  Pointer = 5,
+  // GCC reserves 6 for references, but appears to never use it (because
+  // expressions never have reference type, presumably).
+  PointerToDataMember = 7,
+  RealFloat = 8,
+  Complex = 9,
+  // GCC reserves 10 for functions, but does not use it since GCC version 6 due
+  // to decay to pointer. (Prior to version 6 it was only used in C++ mode).
+  // GCC claims to reserve 11 for pointers to member functions, but *actually*
+  // uses 12 for that purpose, same as for a class or struct. Maybe it
+  // internally implements a pointer to member as a struct?  Who knows.
+  PointerToMemberFunction = 12, // Not a bug, see above.
+  ClassOrStruct = 12,
+  Union = 13,
+  // GCC reserves 14 for arrays, but does not use it since GCC version 6 due to
+  // decay to pointer. (Prior to version 6 it was only used in C++ mode).
+  // GCC reserves 15 for strings, but actually uses 5 (pointer) for string
+  // literals.

AaronBallman wrote:

Needs to be updated after https://github.com/llvm/llvm-project/pull/72036 
lands; sharing this with ExprConstant.cpp would be even better though. It might 
make sense to have a local header in `clang/lib/AST/` for contents that are 
shared between `Interp/*` and `ExprConstant.cpp`, WDYT?

https://github.com/llvm/llvm-project/pull/71972
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)

2023-11-15 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/71972

>From ddda59905a49415c9c5387d7a05ed4cf768cb74b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 10 Nov 2023 19:33:21 +0100
Subject: [PATCH] [clang][Interp] Implement __builtin_classify_type

---
 clang/lib/AST/ExprConstShared.h  | 49 
 clang/lib/AST/ExprConstant.cpp   | 35 ++
 clang/lib/AST/Interp/ByteCodeEmitter.cpp | 15 --
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 10 ++--
 clang/lib/AST/Interp/Function.cpp|  5 +-
 clang/lib/AST/Interp/Function.h  |  5 +-
 clang/lib/AST/Interp/Interp.cpp  |  3 +-
 clang/lib/AST/Interp/InterpBuiltin.cpp   | 21 +
 clang/test/Sema/builtin-classify-type.c  |  1 +
 clang/test/SemaCXX/builtin-classify-type.cpp |  1 +
 10 files changed, 101 insertions(+), 44 deletions(-)
 create mode 100644 clang/lib/AST/ExprConstShared.h

diff --git a/clang/lib/AST/ExprConstShared.h b/clang/lib/AST/ExprConstShared.h
new file mode 100644
index 000..84dd9b8d951b5b1
--- /dev/null
+++ b/clang/lib/AST/ExprConstShared.h
@@ -0,0 +1,49 @@
+//===--- ExprConstShared.h - Shared consetxpr functionality *- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
+#define LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
+
+using namespace clang;
+/// Values returned by __builtin_classify_type, chosen to match the values
+/// produced by GCC's builtin.
+enum class GCCTypeClass {
+  None = -1,
+  Void = 0,
+  Integer = 1,
+  // GCC reserves 2 for character types, but instead classifies them as
+  // integers.
+  Enum = 3,
+  Bool = 4,
+  Pointer = 5,
+  // GCC reserves 6 for references, but appears to never use it (because
+  // expressions never have reference type, presumably).
+  PointerToDataMember = 7,
+  RealFloat = 8,
+  Complex = 9,
+  // GCC reserves 10 for functions, but does not use it since GCC version 6 due
+  // to decay to pointer. (Prior to version 6 it was only used in C++ mode).
+  // GCC claims to reserve 11 for pointers to member functions, but *actually*
+  // uses 12 for that purpose, same as for a class or struct. Maybe it
+  // internally implements a pointer to member as a struct?  Who knows.
+  PointerToMemberFunction = 12, // Not a bug, see above.
+  ClassOrStruct = 12,
+  Union = 13,
+  // GCC reserves 14 for arrays, but does not use it since GCC version 6 due to
+  // decay to pointer. (Prior to version 6 it was only used in C++ mode).
+  // GCC reserves 15 for strings, but actually uses 5 (pointer) for string
+  // literals.
+};
+
+GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
+ const LangOptions &LangOpts);
+
+#endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 373972eb6cab11b..fadf62c95845be1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -32,6 +32,7 @@
 //
 
//===--===//
 
+#include "ExprConstShared.h"
 #include "Interp/Context.h"
 #include "Interp/Frame.h"
 #include "Interp/State.h"
@@ -11492,40 +11493,10 @@ bool IntExprEvaluator::CheckReferencedDecl(const 
Expr* E, const Decl* D) {
   return false;
 }
 
-/// Values returned by __builtin_classify_type, chosen to match the values
-/// produced by GCC's builtin.
-enum class GCCTypeClass {
-  None = -1,
-  Void = 0,
-  Integer = 1,
-  // GCC reserves 2 for character types, but instead classifies them as
-  // integers.
-  Enum = 3,
-  Bool = 4,
-  Pointer = 5,
-  // GCC reserves 6 for references, but appears to never use it (because
-  // expressions never have reference type, presumably).
-  PointerToDataMember = 7,
-  RealFloat = 8,
-  Complex = 9,
-  // GCC reserves 10 for functions, but does not use it since GCC version 6 due
-  // to decay to pointer. (Prior to version 6 it was only used in C++ mode).
-  // GCC claims to reserve 11 for pointers to member functions, but *actually*
-  // uses 12 for that purpose, same as for a class or struct. Maybe it
-  // internally implements a pointer to member as a struct?  Who knows.
-  PointerToMemberFunction = 12, // Not a bug, see above.
-  ClassOrStruct = 12,
-  Union = 13,
-  // GCC reserves 14 for arrays, but does not use it since GCC version 6 due to
-  // decay to pointer. (Prior to version 6 it was only used in C++ mode).
-  // GCC reserves 15 for strings, but actually uses 5 (pointer) for string
-  // literals.
-};
-
 /// EvaluateBuiltinClassifyType - Evaluate __builtin_classi

[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)

2023-11-15 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/71972

>From b4a4ce956f4aa6c084d112d519fe98eb9f585559 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 10 Nov 2023 19:33:21 +0100
Subject: [PATCH] [clang][Interp] Implement __builtin_classify_type

---
 clang/lib/AST/ExprConstShared.h  | 55 
 clang/lib/AST/ExprConstant.cpp   | 35 ++---
 clang/lib/AST/Interp/ByteCodeEmitter.cpp | 15 --
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 10 ++--
 clang/lib/AST/Interp/Function.cpp|  5 +-
 clang/lib/AST/Interp/Function.h  |  5 +-
 clang/lib/AST/Interp/Interp.cpp  |  3 ++
 clang/lib/AST/Interp/InterpBuiltin.cpp   | 21 
 clang/test/Sema/builtin-classify-type.c  |  1 +
 clang/test/SemaCXX/builtin-classify-type.cpp |  1 +
 10 files changed, 108 insertions(+), 43 deletions(-)
 create mode 100644 clang/lib/AST/ExprConstShared.h

diff --git a/clang/lib/AST/ExprConstShared.h b/clang/lib/AST/ExprConstShared.h
new file mode 100644
index ..855b667cee299d78
--- /dev/null
+++ b/clang/lib/AST/ExprConstShared.h
@@ -0,0 +1,55 @@
+//===--- ExprConstShared.h - Shared consetxpr functionality *- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Shared functionality between the new constant expression
+// interpreter (AST/Interp/) and the current one (ExprConstant.cpp).
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
+#define LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
+
+namespace clang {
+class QualType;
+class LangOptions;
+} // namespace clang
+using namespace clang;
+/// Values returned by __builtin_classify_type, chosen to match the values
+/// produced by GCC's builtin.
+enum class GCCTypeClass {
+  None = -1,
+  Void = 0,
+  Integer = 1,
+  // GCC reserves 2 for character types, but instead classifies them as
+  // integers.
+  Enum = 3,
+  Bool = 4,
+  Pointer = 5,
+  // GCC reserves 6 for references, but appears to never use it (because
+  // expressions never have reference type, presumably).
+  PointerToDataMember = 7,
+  RealFloat = 8,
+  Complex = 9,
+  // GCC reserves 10 for functions, but does not use it since GCC version 6 due
+  // to decay to pointer. (Prior to version 6 it was only used in C++ mode).
+  // GCC claims to reserve 11 for pointers to member functions, but *actually*
+  // uses 12 for that purpose, same as for a class or struct. Maybe it
+  // internally implements a pointer to member as a struct?  Who knows.
+  PointerToMemberFunction = 12, // Not a bug, see above.
+  ClassOrStruct = 12,
+  Union = 13,
+  // GCC reserves 14 for arrays, but does not use it since GCC version 6 due to
+  // decay to pointer. (Prior to version 6 it was only used in C++ mode).
+  // GCC reserves 15 for strings, but actually uses 5 (pointer) for string
+  // literals.
+};
+
+GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
+ const LangOptions &LangOpts);
+
+#endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 373972eb6cab11bd..fadf62c95845be18 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -32,6 +32,7 @@
 //
 
//===--===//
 
+#include "ExprConstShared.h"
 #include "Interp/Context.h"
 #include "Interp/Frame.h"
 #include "Interp/State.h"
@@ -11492,40 +11493,10 @@ bool IntExprEvaluator::CheckReferencedDecl(const 
Expr* E, const Decl* D) {
   return false;
 }
 
-/// Values returned by __builtin_classify_type, chosen to match the values
-/// produced by GCC's builtin.
-enum class GCCTypeClass {
-  None = -1,
-  Void = 0,
-  Integer = 1,
-  // GCC reserves 2 for character types, but instead classifies them as
-  // integers.
-  Enum = 3,
-  Bool = 4,
-  Pointer = 5,
-  // GCC reserves 6 for references, but appears to never use it (because
-  // expressions never have reference type, presumably).
-  PointerToDataMember = 7,
-  RealFloat = 8,
-  Complex = 9,
-  // GCC reserves 10 for functions, but does not use it since GCC version 6 due
-  // to decay to pointer. (Prior to version 6 it was only used in C++ mode).
-  // GCC claims to reserve 11 for pointers to member functions, but *actually*
-  // uses 12 for that purpose, same as for a class or struct. Maybe it
-  // internally implements a pointer to member as a struct?  Who knows.
-  PointerToMemberFunction = 12, // Not a bug, see above.
-  ClassOrStruct = 12,
-  Union = 13,
-  // GCC reserves 14 for arrays, but does not use it since GCC version 6 due to
-  // decay to pointer

[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)

2023-11-16 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman approved this pull request.

LGTM!

https://github.com/llvm/llvm-project/pull/71972
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)

2023-11-16 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/71972

>From 2aedc41694c554900c87993f77cbc87ae6ed52ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 10 Nov 2023 19:33:21 +0100
Subject: [PATCH] [clang][Interp] Implement __builtin_classify_type

---
 clang/lib/AST/ExprConstShared.h  | 58 
 clang/lib/AST/ExprConstant.cpp   | 38 +
 clang/lib/AST/Interp/ByteCodeEmitter.cpp | 15 +++--
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 10 ++--
 clang/lib/AST/Interp/Function.cpp|  5 +-
 clang/lib/AST/Interp/Function.h  |  5 +-
 clang/lib/AST/Interp/Interp.cpp  |  3 +
 clang/lib/AST/Interp/InterpBuiltin.cpp   | 21 +++
 clang/test/Sema/builtin-classify-type.c  |  1 +
 clang/test/SemaCXX/builtin-classify-type.cpp |  1 +
 10 files changed, 111 insertions(+), 46 deletions(-)
 create mode 100644 clang/lib/AST/ExprConstShared.h

diff --git a/clang/lib/AST/ExprConstShared.h b/clang/lib/AST/ExprConstShared.h
new file mode 100644
index 000..53ec9c6c7a3ef2e
--- /dev/null
+++ b/clang/lib/AST/ExprConstShared.h
@@ -0,0 +1,58 @@
+//===--- ExprConstShared.h - Shared consetxpr functionality *- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Shared functionality between the new constant expression
+// interpreter (AST/Interp/) and the current one (ExprConstant.cpp).
+//
+//===--===//
+
+#ifndef LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
+#define LLVM_CLANG_LIB_AST_EXPRCONSTSHARED_H
+
+namespace clang {
+class QualType;
+class LangOptions;
+} // namespace clang
+using namespace clang;
+/// Values returned by __builtin_classify_type, chosen to match the values
+/// produced by GCC's builtin.
+enum class GCCTypeClass {
+  None = -1,
+  Void = 0,
+  Integer = 1,
+  // GCC reserves 2 for character types, but instead classifies them as
+  // integers.
+  Enum = 3,
+  Bool = 4,
+  Pointer = 5,
+  // GCC reserves 6 for references, but appears to never use it (because
+  // expressions never have reference type, presumably).
+  PointerToDataMember = 7,
+  RealFloat = 8,
+  Complex = 9,
+  // GCC reserves 10 for functions, but does not use it since GCC version 6 due
+  // to decay to pointer. (Prior to version 6 it was only used in C++ mode).
+  // GCC claims to reserve 11 for pointers to member functions, but *actually*
+  // uses 12 for that purpose, same as for a class or struct. Maybe it
+  // internally implements a pointer to member as a struct?  Who knows.
+  PointerToMemberFunction = 12, // Not a bug, see above.
+  ClassOrStruct = 12,
+  Union = 13,
+  // GCC reserves 14 for arrays, but does not use it since GCC version 6 due to
+  // decay to pointer. (Prior to version 6 it was only used in C++ mode).
+  // GCC reserves 15 for strings, but actually uses 5 (pointer) for string
+  // literals.
+  // Lang = 16,
+  // OpaqueType = 17,
+  BitInt = 18
+};
+
+GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
+ const LangOptions &LangOpts);
+
+#endif
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 4fb444e3b9f7e1b..3a41e9718bb5875 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -32,6 +32,7 @@
 //
 
//===--===//
 
+#include "ExprConstShared.h"
 #include "Interp/Context.h"
 #include "Interp/Frame.h"
 #include "Interp/State.h"
@@ -11492,43 +11493,10 @@ bool IntExprEvaluator::CheckReferencedDecl(const 
Expr* E, const Decl* D) {
   return false;
 }
 
-/// Values returned by __builtin_classify_type, chosen to match the values
-/// produced by GCC's builtin.
-enum class GCCTypeClass {
-  None = -1,
-  Void = 0,
-  Integer = 1,
-  // GCC reserves 2 for character types, but instead classifies them as
-  // integers.
-  Enum = 3,
-  Bool = 4,
-  Pointer = 5,
-  // GCC reserves 6 for references, but appears to never use it (because
-  // expressions never have reference type, presumably).
-  PointerToDataMember = 7,
-  RealFloat = 8,
-  Complex = 9,
-  // GCC reserves 10 for functions, but does not use it since GCC version 6 due
-  // to decay to pointer. (Prior to version 6 it was only used in C++ mode).
-  // GCC claims to reserve 11 for pointers to member functions, but *actually*
-  // uses 12 for that purpose, same as for a class or struct. Maybe it
-  // internally implements a pointer to member as a struct?  Who knows.
-  PointerToMemberFunction = 12, // Not a bug, see above.
-  ClassOrStruct = 12,
-  Union = 13,
-  // GCC reserves 14 for arrays, but does not use it s

[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)

2023-11-17 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/71972
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits