Bug 306197
| Summary: | JSC_CF_ENUM macro triggers -Welaborated-enum-base warnings with upstream clang | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | David Kilzer (:ddkilzer) <ddkilzer> |
| Component: | JavaScriptCore | Assignee: | David Kilzer (:ddkilzer) <ddkilzer> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | CC: | webkit-bug-importer |
| Priority: | P2 | Keywords: | InRadar |
| Version: | WebKit Nightly Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| Bug Depends on: | 250511 | ||
| Bug Blocks: | |||
David Kilzer (:ddkilzer)
The JSC_CF_ENUM macro in JavaScriptCore/API/JSBase.h triggers -Welaborated-enum-base warnings when compiling with upstream clang compilers that have this warning enabled as an error by default.
Error message:
"non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?"
The warning fires 561 times in WebKit builds, primarily from JSValueRef.h line 103:
```
JSC_CF_ENUM(JSRelationCondition,
kJSRelationConditionUndefined,
kJSRelationConditionEqual,
kJSRelationConditionGreaterThan,
kJSRelationConditionLessThan
) JSC_API_AVAILABLE(macos(15.0), ios(18.0));
```
Root Cause:
The JSC_CF_ENUM macro expands to Apple's CF_ENUM pattern which includes a forward declaration:
```
typedef enum _name : _type _name; enum _name : _type { ... }
```
Per C++11 [dcl.type.elab], forward declarations of enums with fixed underlying types are only permitted as standalone declarations, not embedded in typedef contexts.
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
David Kilzer (:ddkilzer)
Proposed Fix:
Modify JSC_CF_ENUM in Source/JavaScriptCore/API/JSBase.h to use different macro expansions for C++ vs Objective-C:
Current problematic code (lines 155-165):
```
#if JSC_OBJC_API_ENABLED
#define JSC_CF_ENUM(enumName, ...) \
typedef CF_ENUM(uint32_t, enumName) { \
__VA_ARGS__ \
}
#else
#define JSC_CF_ENUM(enumName, ...) \
typedef enum { \
__VA_ARGS__ \
} enumName
#endif
```
Proposed fix:
```
#if JSC_OBJC_API_ENABLED
#if defined(__cplusplus)
// In C++, avoid the forward declaration pattern from CF_ENUM
// that triggers -Welaborated-enum-base warnings
#define JSC_CF_ENUM(enumName, ...) \
enum enumName : uint32_t { \
__VA_ARGS__ \
}
#else
// In Objective-C, use CF_ENUM for full Swift interop support
#define JSC_CF_ENUM(enumName, ...) \
typedef CF_ENUM(uint32_t, enumName) { \
__VA_ARGS__ \
}
#endif
#else
#define JSC_CF_ENUM(enumName, ...) \
typedef enum { \
__VA_ARGS__ \
} enumName
#endif
```
Why this fix works:
1. **Root Cause**: CF_ENUM expands to `typedef enum _name : _type _name; enum _name : _type { ... }`. The first part is a forward declaration with fixed underlying type embedded in a typedef context, which violates C++11 [dcl.type.elab].
2. **Key Insight**: Swift imports headers in Objective-C mode, NOT C++ mode. When Swift's ClangImporter processes headers, `__cplusplus` is not defined, so it uses the Objective-C path with CF_ENUM.
3. **Fix Strategy**:
- C++ path: Use plain `enum name : type { ... }` (no forward declaration, no typedef)
- Objective-C path: Keep CF_ENUM for Swift interoperability
- The paths are completely separate - Swift never sees the C++ version
4. **Compatibility**:
- C++ code: Gets clean enum definition without warnings
- Objective-C code: Unchanged, keeps CF_ENUM attributes
- Swift code: Unchanged, still imports via Objective-C path with full CF_ENUM support
This eliminates all 561 -Welaborated-enum-base errors while maintaining full backward compatibility.
Radar WebKit Bug Importer
<rdar://problem/168848718>
Radar WebKit Bug Importer
<rdar://problem/168848723>
David Kilzer (:ddkilzer)
<rdar://168848718>
David Kilzer (:ddkilzer)
Pull request: https://github.com/WebKit/WebKit/pull/57192
EWS
Committed 306242@main (b769e2ee79c8): <https://commits.webkit.org/306242@main>
Reviewed commits have been landed. Closing PR #57192 and removing active labels.