From d6df6932e9e5f0e956b5df05462215482e18296e Mon Sep 17 00:00:00 2001 From: Theo Paris Date: Fri, 25 Sep 2026 20:58:24 -0700 Subject: [PATCH] Remove the need for RTTI --- tslang/CMakeLists.txt | 3 --- tslang/cmake/config_macros.cmake | 9 +++++++-- tslang/include/TypeScript/Helper.h | 14 +++++++------- tslang/lib/TypeScriptAsyncRuntime/CMakeLists.txt | 6 ------ tslang/lib/TypeScriptRuntime/CMakeLists.txt | 8 -------- tslang/ts-new-parser/parser_fwd_types.h | 6 ------ tslang/ts-new-parser/parser_types.h | 11 +++++++++++ tslang/ts-new-parser/utilities.h | 3 ++- 8 files changed, 27 insertions(+), 33 deletions(-) diff --git a/tslang/CMakeLists.txt b/tslang/CMakeLists.txt index 874b4e85a..e9ab0f080 100644 --- a/tslang/CMakeLists.txt +++ b/tslang/CMakeLists.txt @@ -144,9 +144,6 @@ set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin) set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib) set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR}) -set(LLVM_ENABLE_EH "ON") -set(LLVM_ENABLE_RTTI "ON") -set(LLVM_REQUIRES_RTTI "ON") set(LLVM_ENABLE_PIC "ON") # clang fix diff --git a/tslang/cmake/config_macros.cmake b/tslang/cmake/config_macros.cmake index 77265cc9f..109a80c6f 100644 --- a/tslang/cmake/config_macros.cmake +++ b/tslang/cmake/config_macros.cmake @@ -6,13 +6,18 @@ if(MSVC) else() #SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch -Wno-unused-function -Wno-unused-result -Wno-unused-variable -Wno-unused-private-field -Wno-sign-compare -Wno-implicit-fallthrough -Wno-logical-op-parentheses -Wno-parentheses -Wno-unused-command-line-argument -frtti -lstdc++fs") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch -Wno-unused-function -Wno-unused-result -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough -Wno-parentheses -Wno-type-limits -Wno-unused-const-variable -Wno-unused-private-field") + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch -Wno-unused-function -Wno-unused-result -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough -Wno-parentheses -Wno-type-limits -Wno-unused-const-variable -Wno-unused-private-field -Wno-dollar-in-identifier-extension -Wno-c++20-extensions") else() SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch -Wno-unused-function -Wno-unused-result -Wno-unused-variable -Wno-sign-compare -Wno-implicit-fallthrough -Wno-parentheses -Wno-type-limits -Wno-unused-but-set-variable -Wno-subobject-linkage") endif() # enable RTTI - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti -fexceptions") SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") + + if (LLVM_ENABLE_RTTI) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti -fexceptions") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fexceptions") + endif() endif() endmacro() diff --git a/tslang/include/TypeScript/Helper.h b/tslang/include/TypeScript/Helper.h index 3f5dde526..ff404c588 100644 --- a/tslang/include/TypeScript/Helper.h +++ b/tslang/include/TypeScript/Helper.h @@ -2,23 +2,23 @@ #define TYPESCRIPT_HELPER_H #include +#include "llvm/Support/Casting.h" // Add this header template< typename T, typename U > inline std::unique_ptr< T > dynamic_pointer_cast(std::unique_ptr< U > &&ptr) { U * const stored_ptr = ptr.release(); - T * const converted_stored_ptr = dynamic_cast< T * >(stored_ptr); - if (converted_stored_ptr) { - return std::unique_ptr< T >(converted_stored_ptr); + + // Check type using LLVM's custom, RTTI-free system + if (stored_ptr && llvm::isa< T >(stored_ptr)) { + return std::unique_ptr< T >(static_cast< T * >(stored_ptr)); } else { - if (stored_ptr) - { + if (stored_ptr) { throw "Invalid cast"; } - ptr.reset(stored_ptr); return std::unique_ptr< T >(); } } -#endif // TYPESCRIPT_HELPER_H \ No newline at end of file +#endif // TYPESCRIPT_HELPER_H diff --git a/tslang/lib/TypeScriptAsyncRuntime/CMakeLists.txt b/tslang/lib/TypeScriptAsyncRuntime/CMakeLists.txt index a7164bc72..589acb315 100644 --- a/tslang/lib/TypeScriptAsyncRuntime/CMakeLists.txt +++ b/tslang/lib/TypeScriptAsyncRuntime/CMakeLists.txt @@ -1,9 +1,3 @@ -if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR") -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti") -endif() - add_mlir_library(TypeScriptAsyncRuntime STATIC AsyncRuntime.cpp diff --git a/tslang/lib/TypeScriptRuntime/CMakeLists.txt b/tslang/lib/TypeScriptRuntime/CMakeLists.txt index 23fa004fa..f85b0c26f 100644 --- a/tslang/lib/TypeScriptRuntime/CMakeLists.txt +++ b/tslang/lib/TypeScriptRuntime/CMakeLists.txt @@ -1,11 +1,3 @@ -# Include dir + lib location come from the BDWgc::gc imported target (find_package -# in the top-level CMakeLists), so no hardcoded include_directories/link_directories. -if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR") -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti") -endif() - # On Windows the runtime takes Boehm from gc.dll rather than linking it in: under the JIT this # DLL shares the process with the default library's DLL and with user shared libraries, and a # second static collector frees what the others still hold. See the top-level CMakeLists and diff --git a/tslang/ts-new-parser/parser_fwd_types.h b/tslang/ts-new-parser/parser_fwd_types.h index 7aaf8ea70..7f48f8fb9 100644 --- a/tslang/ts-new-parser/parser_fwd_types.h +++ b/tslang/ts-new-parser/parser_fwd_types.h @@ -203,12 +203,6 @@ template struct ptr_t return U(instance); } - template inline auto is() -> boolean - { - // TODO: review and simplify using Kind - return !!std::dynamic_pointer_cast(instance); - } - REF_TYPE(T) instance; }; diff --git a/tslang/ts-new-parser/parser_types.h b/tslang/ts-new-parser/parser_types.h index c2ba63b61..7e12da5bf 100644 --- a/tslang/ts-new-parser/parser_types.h +++ b/tslang/ts-new-parser/parser_types.h @@ -223,6 +223,12 @@ struct Node : TextRange { } + // RTTI-free structural check used by isNamedDeclaration(); overridden by NamedDeclaration. + virtual auto getDeclarationName() -> PTR(DeclarationName) + { + return PTR(DeclarationName)(); + } + Node() = default; Node(SyntaxKind kind, pos_type pos, number end) : TextRange{pos, end}, _kind(kind) { @@ -370,6 +376,11 @@ struct Declaration : DeclarationStatement { struct NamedDeclaration : Declaration { PTR(DeclarationName) name; + + auto getDeclarationName() -> PTR(DeclarationName) override + { + return name; + } }; struct ClassElement : NamedDeclaration diff --git a/tslang/ts-new-parser/utilities.h b/tslang/ts-new-parser/utilities.h index 66301f775..0a7846cf7 100644 --- a/tslang/ts-new-parser/utilities.h +++ b/tslang/ts-new-parser/utilities.h @@ -1829,7 +1829,8 @@ inline auto isClassMemberModifier(SyntaxKind idToken) -> boolean inline static auto isNamedDeclaration(Node node) -> boolean { - return !!node.is(); // A 'name' property should always be a DeclarationName. + // A 'name' property should always be a DeclarationName; RTTI-free via virtual dispatch. + return !!node && !!node->getDeclarationName(); } inline static auto isPropertyName(Node node) -> boolean