[clang] [clang][Interp] Implement __builtin_classify_type (PR #71972)
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)
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)
@@ -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)
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)
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)
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)
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)
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