llvm-project
2ef41cca - [clang-format] Fix Macros configuration not working with try/catch expansions (#184891)

Commit
44 days ago
[clang-format] Fix Macros configuration not working with try/catch expansions (#184891) This is a superseding followup to my previous PR, https://github.com/llvm/llvm-project/pull/183352. In my previous PR, I proposed adding TryMacros and CatchMacros configuration options, similar in spirit to IfMacros and ForEachMacros. I did so because I noticed that configuration like `Macros=["TRY_MACRO=try", "CATCH_MACRO(e)=catch(e)]` did not format configured macro(s) as try/catch blocks. @owenca confirmed in my previous PR that this observed behavior is undesired, and we should prefer to fix it rather than introduce new features. This PR proposes a fix, described in detail in the commit message below the break. In general terms, it deletes a heuristic from the lexing phase, where it interacted poorly with the Macros option, and moves its functionality to the parsing phase instead. I describe a possibly cleaner fix in [a comment here](https://github.com/llvm/llvm-project/pull/183352#issuecomment-3992773126), but it has the disadvantage of unintended behavior changes for Objective-C code using `try` as an identifier. The fix in this PR avoids that unintended behavior change; the only behavior change is the bugfix itself. cc @HazardyKnusperkeks as previous reviewer, and @mydeveloperday as the heuristic's original author. --- The lexer heuristic `tryTransformTryUsageForC()` was intended to allow C code to use `try` as an identifier by demoting `tok::kw_try` to `tok::identifier` when the following token did not look like the start of a try body. However, when `MacroExpander::parseDefinition()` lexed a macro like `"TRY_MACRO=try"`, the `try` token in the expansion body was followed by `eof`, triggering the heuristic. This caused `try` to be demoted to an identifier in the macro definition, so expanded code was never parsed as a try/catch statement. Delete `tryTransformTryUsageForC()` and instead guard the two `case tok::kw_try:` dispatch sites in `UnwrappedLineParser::parseStructuralElement()`. The guard is restricted to `Style.isCpp()` (which covers C, C++, and Objective-C) and checks whether the next non-comment token is `{`, `:`, or `#` -- the tokens that can legitimately begin a try body or precede one. The old heuristic also had to check for a preceding `@` token to avoid demoting `try` in Objective-C `@try` constructs. The parser-level guard does not need this check because `@try` is routed through `case tok::at` and dispatched via `getObjCKeywordID()` to `tok::objc_try`, which calls `parseTryCatch()` directly. The bare `kw_try` token never reaches `case tok::kw_try` when parsing `@try`. Assisted-by: Claude (anthropic.com)
Author
Parents
Loading