|
| 1 | +# Herbception Implementation in LLVM |
| 2 | + |
| 3 | +## Overview |
| 4 | +This document summarizes the implementation of herbception (P0709R4) in LLVM/Clang, a zero-overhead deterministic exception mechanism using carry flag for error propagation. |
| 5 | + |
| 6 | +## Design Decisions |
| 7 | + |
| 8 | +### 1. Syntax |
| 9 | +- **`herbthrows`/`herbthrows(bool)`**: Function exception specification for herbception |
| 10 | + - `herbthrows` or `herbthrows(true)`: Function can throw herbceptions |
| 11 | + - `herbthrows(false)`: Function cannot throw herbceptions |
| 12 | +- **`herbthrow (domain_ptr) (value)`**: Throw a herbception with domain and error value |
| 13 | +- **`herbcatch (type var)`**: Catch herbceptions after try-catch blocks |
| 14 | +- **Coexistence**: `herbthrows` and `noexcept` are independent - functions can use both |
| 15 | + |
| 16 | +### 2. Error Representation |
| 17 | +- **Domain**: Pointer to global object (ensures uniqueness across static libraries) |
| 18 | +- **Value**: `size_t` user-defined error code |
| 19 | +- **Default type**: `std::error` with `void* domain` and `size_t value` |
| 20 | +- **Custom types**: Support via conversion operator `operator herbthrows(void*, size_t)` |
| 21 | + |
| 22 | +### 3. x86-64 ABI |
| 23 | +- **RAX**: Domain pointer |
| 24 | +- **RDX**: Error value |
| 25 | +- **CF=1**: Indicates error occurred |
| 26 | +- **Control flow**: `jc error_handler` for error path (cold path) |
| 27 | +- **Propagation**: Maintain CF=1 for automatic error propagation |
| 28 | + |
| 29 | +## Implementation Status |
| 30 | + |
| 31 | +### ✅ Completed |
| 32 | + |
| 33 | +#### 1. Frontend - Keywords and Tokens |
| 34 | +- Added `herbthrows`, `herbthrow`, `herbcatch` keywords to `TokenKinds.def` |
| 35 | +- Updated exception specification types in `ExceptionSpecificationType.h` |
| 36 | +- Added helper functions `isHerbThrowsSpec()`, `isComputedHerbThrows()` |
| 37 | + |
| 38 | +#### 2. AST Nodes |
| 39 | +- **`HerbThrowExpr`**: AST node for herbthrow expressions in `ExprCXX.h` |
| 40 | +- **`HerbCatchStmt`**: AST node for herbcatch statements in `StmtCXX.h` |
| 41 | +- Added statement classes to `StmtNodes.td` |
| 42 | +- Added bitfields to `Stmt.h` for herbthrow expressions |
| 43 | + |
| 44 | +#### 3. Parser |
| 45 | +- **`ParseHerbThrowExpression()`**: Parses `herbthrow (domain) (value)` in `ParseExprCXX.cpp` |
| 46 | +- Modified `tryParseExceptionSpecification()` to handle `herbthrows` in `ParseDeclCXX.cpp` |
| 47 | +- Added herbthrow handling to expression parser in `ParseExpr.cpp` |
| 48 | +- Added declaration to `Parser.h` |
| 49 | + |
| 50 | +#### 4. Semantic Analysis |
| 51 | +- **`ActOnHerbThrow()`**: Semantic action for herbthrow in `SemaExprCXX.cpp` |
| 52 | + - Validates domain is pointer type |
| 53 | + - Validates value convertible to size_t |
| 54 | + - Checks function can throw herbceptions |
| 55 | +- Added declaration to `Sema.h` |
| 56 | + |
| 57 | +### 🔄 In Progress |
| 58 | + |
| 59 | +#### 5. CodeGen - LLVM IR Generation |
| 60 | +Need to implement in `CGException.cpp`: |
| 61 | +- Generate carry flag check/set instructions |
| 62 | +- Use RAX/RDX for domain/value passing |
| 63 | +- Generate `jc` for error path branching |
| 64 | + |
| 65 | +### ⏳ Pending |
| 66 | + |
| 67 | +#### 6. X86 Backend |
| 68 | +- Modify X86 instruction selection to preserve carry flag |
| 69 | +- Add intrinsics for `setc`/`jc` if needed |
| 70 | +- Ensure calling convention respects RAX/RDX/CF usage |
| 71 | + |
| 72 | +#### 7. herbcatch Implementation |
| 73 | +- Parse herbcatch blocks following try-catch |
| 74 | +- Generate CF check before herbcatch entry |
| 75 | +- Load domain/value from RAX/RDX |
| 76 | + |
| 77 | +#### 8. Runtime Support |
| 78 | +- Define `std::error` type structure |
| 79 | +- Implement domain generation mechanism |
| 80 | +- Add conversion operator support |
| 81 | + |
| 82 | +#### 9. Testing |
| 83 | +- Unit tests for parser |
| 84 | +- Semantic analysis tests |
| 85 | +- CodeGen tests |
| 86 | +- End-to-end execution tests |
| 87 | + |
| 88 | +## File Changes Summary |
| 89 | + |
| 90 | +### Modified Files |
| 91 | +1. `clang/include/clang/Basic/TokenKinds.def` - Added keywords |
| 92 | +2. `clang/include/clang/Basic/ExceptionSpecificationType.h` - Added EST types |
| 93 | +3. `clang/include/clang/Basic/StmtNodes.td` - Added statement nodes |
| 94 | +4. `clang/include/clang/AST/ExprCXX.h` - Added HerbThrowExpr |
| 95 | +5. `clang/include/clang/AST/StmtCXX.h` - Added HerbCatchStmt |
| 96 | +6. `clang/include/clang/AST/Stmt.h` - Added bitfields |
| 97 | +7. `clang/include/clang/Parse/Parser.h` - Added ParseHerbThrowExpression |
| 98 | +8. `clang/include/clang/Sema/Sema.h` - Added ActOnHerbThrow |
| 99 | +9. `clang/lib/Parse/ParseDeclCXX.cpp` - Handle herbthrows spec |
| 100 | +10. `clang/lib/Parse/ParseExprCXX.cpp` - Parse herbthrow expression |
| 101 | +11. `clang/lib/Parse/ParseExpr.cpp` - Recognize herbthrow |
| 102 | +12. `clang/lib/Sema/SemaExprCXX.cpp` - Implement ActOnHerbThrow |
| 103 | + |
| 104 | +### Test File |
| 105 | +- `test_herbception.cpp` - Example usage demonstrating syntax |
| 106 | + |
| 107 | +## Next Steps |
| 108 | + |
| 109 | +1. **Complete CodeGen**: Implement LLVM IR generation for herbthrow/herbcatch |
| 110 | +2. **X86 Backend**: Add carry flag handling in instruction selection |
| 111 | +3. **Runtime Library**: Create minimal runtime for std::error |
| 112 | +4. **Testing**: Comprehensive test suite |
| 113 | +5. **Optimization**: Inline error checks, optimize propagation paths |
| 114 | + |
| 115 | +## Notes |
| 116 | + |
| 117 | +- The implementation maintains complete separation between C++ exceptions and herbceptions |
| 118 | +- Functions can support both exception models simultaneously |
| 119 | +- Zero-overhead when no errors occur (just CF check) |
| 120 | +- Deterministic, no hidden control flow |
| 121 | +- Compatible with static libraries, no DLL boundary issues |
0 commit comments