Skip to content

Conversation

@lanza
Copy link
Member

@lanza lanza commented Nov 22, 2025

Stack from ghstack (oldest at bottom):

Summary:
This patch implements support for emitting typeid expressions as
l-values in ClangIR, enabling code patterns such as:
const std::type_info& ti = typeid(MyClass);
auto& ref = typeid(int);
void foo(const std::type_info& ti) { foo(typeid(SomeType)); }

This is a common pattern in C++ code that uses RTTI for logging,
serialization, debugging, and type introspection.

Implementation:
The implementation follows the traditional LLVM CodeGen approach:

  1. Added emitCXXTypeidExpr() in CIRGenExprCXX.cpp

    • Handles both type operands (typeid(Type)) and expression operands
      (typeid(expr))
    • Retrieves the RTTI descriptor via getAddrOfRTTIDescriptor()
    • Looks up the GlobalOp to determine the correct pointer type
    • Creates a GetGlobalOp to materialize the address at runtime
    • Polymorphic type vtable lookup is marked as NYI
  2. Added emitCXXTypeidLValue() in CIRGenExpr.cpp

    • Calls emitCXXTypeidExpr() to get the RTTI descriptor pointer
    • Performs a bitcast from !u8i pointer to the proper type_info type
    • Creates an LValue with appropriate alignment for reference binding
  3. Extended the emitLValue() switch statement to handle CXXTypeidExpr

What works:

  • typeid with type operands: typeid(int), typeid(MyClass)
  • typeid with non-polymorphic expression operands: typeid(obj)
  • Reference binding: const std::type_info& ti = typeid(...)
  • Function argument passing: foo(typeid(...))
  • Built-in types, class types, and struct types

What doesn't work yet:

  • typeid with polymorphic types requiring vtable lookup
    (e.g., typeid(*basePtr) where the dynamic type differs from static type)
    This is marked with llvm_unreachable() and will be implemented separately.

Test Plan:
Added comprehensive test coverage in clang/test/CIR/CodeGen/typeid-lvalue.cpp

  • Non-polymorphic struct types
  • Expression operands
  • Built-in types (int, double)
  • Function argument passing
  • All tests pass

Regression testing:

  • All 394 CIR CodeGen tests pass (379 passed, 14 unsupported, 1 expected fail)
  • Code formatted with clang-format
  • Code checked with clang-tidy (warnings consistent with existing codebase)

Differential Revision: N/A

[ghstack-poisoned]
lanza added a commit that referenced this pull request Nov 22, 2025
Summary:
This patch implements support for emitting typeid expressions as
l-values in ClangIR, enabling code patterns such as:
  const std::type_info& ti = typeid(MyClass);
  auto& ref = typeid(int);
  void foo(const std::type_info& ti) { foo(typeid(SomeType)); }

This is a common pattern in C++ code that uses RTTI for logging,
serialization, debugging, and type introspection.

Implementation:
The implementation follows the traditional LLVM CodeGen approach:

1. Added emitCXXTypeidExpr() in CIRGenExprCXX.cpp
   - Handles both type operands (typeid(Type)) and expression operands
     (typeid(expr))
   - Retrieves the RTTI descriptor via getAddrOfRTTIDescriptor()
   - Looks up the GlobalOp to determine the correct pointer type
   - Creates a GetGlobalOp to materialize the address at runtime
   - Polymorphic type vtable lookup is marked as NYI

2. Added emitCXXTypeidLValue() in CIRGenExpr.cpp
   - Calls emitCXXTypeidExpr() to get the RTTI descriptor pointer
   - Performs a bitcast from !u8i pointer to the proper type_info type
   - Creates an LValue with appropriate alignment for reference binding

3. Extended the emitLValue() switch statement to handle CXXTypeidExpr

What works:
- typeid with type operands: typeid(int), typeid(MyClass)
- typeid with non-polymorphic expression operands: typeid(obj)
- Reference binding: const std::type_info& ti = typeid(...)
- Function argument passing: foo(typeid(...))
- Built-in types, class types, and struct types

What doesn't work yet:
- typeid with polymorphic types requiring vtable lookup
  (e.g., typeid(*basePtr) where the dynamic type differs from static type)
  This is marked with llvm_unreachable() and will be implemented separately.

Test Plan:
Added comprehensive test coverage in clang/test/CIR/CodeGen/typeid-lvalue.cpp
- Non-polymorphic struct types
- Expression operands
- Built-in types (int, double)
- Function argument passing
- All tests pass

Regression testing:
- All 394 CIR CodeGen tests pass (379 passed, 14 unsupported, 1 expected fail)
- Code formatted with clang-format
- Code checked with clang-tidy (warnings consistent with existing codebase)

Differential Revision: N/A


ghstack-source-id: 261e71d
Pull-Request: #2000
@lanza lanza closed this Nov 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants