Unreal Header Tool fails to parse UPROPERTY after preprocessor directive block

If there is an inline function definition surrounded by compiler directives then UHT can miss the definition and consume the next definition instead.

Steps to Reproduce

For example in the code below UHT parses the file and finds “int InHeaderDefinition()”. It tries to get to the end of the definition via UhtTokenReaderUtilityExtensions::SkipDeclaration. When trying to get the remaining tokens for the definition the TokenBufferReader disregards the Preprocessor content through UhtHeaderFileParser::ParsePreprocessorDirective as it’s marked as UhtCompilerDirective.Unrecognized The result is that UHT thinks the function declaration is

int InHeaderDefinition() UPROPERTY(BlueprintAssignable) FMissingDelegateSignature MissingDelegate;

Which consumes the MissingDelegate property. The fix is easy, just move the compiler directives inside the brackets instead of duplicating them but it isn’t immediately obvious why a delegate would not be showing in this case.

int InHeaderDefinition()
#if SOME_DEFINITION
    {
        return 1;
    }
#else
    {
        return 2;
    }
#endif
	
    UPROPERTY(BlueprintAssignable)
    FMissingDelegateSignature MissingDelegate;

Hi Andrew,

Thank you for reporting this issue and including quick repro steps, that is extremely valuable to us. I was able to repro here in all Unreal 5.x versions.

Note that UHT is not a full C++ parser and is especially prone to making parsing mistakes around unrecognized preprocessor macros and blocks. The tool is not expected to work flawlessly in all cases that involve the C++ preprocessor, but Epic does try to at least warn users of some common pitfalls that may result in wrong Editor behavior, like placing UFUNCTION and UPROPERTY declarations inside preprocessor blocks.

The good news is that, since fairly recently, the situation you described does produce a message in Visual Studio’s Build Output window: “Deprecation: The identifier ‘UPROPERTY’ was detected in a block being skipped and is now being flagged. This will be a warning in a future version of Unreal.”. For now it is flagged as a “deprecation message” instead of an actual “warning” for some reason, but it is not anymore a silent parsing error.

If you are interested in integrating the change that makes UHT detect the issue, you can find it on CL 43146751, or commit 1423707 on GitHub.

Best regards,

Vitor

That’s great, thanks Vitor!

I see it just missed the 5.6 cutoff. I should’ve checked the files I mentioned for any updates!