Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

clang-format and driver code

Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 544

. . . I am now free to return to banging my fucking head against the wall trying to make clang-format (as packaged in VS 2019) actually do what I want it to do. Because, you know, that's something easy to accomplish.

My head still has bruises from my fights with clang-format. I can't say I'm 100% happy with the current cease-fire, but I have been able to coax clang into doing something ... passable ... with NDIS code.

The hard part was SAL annotations. I eventually solved that using a feature that was just introduced in the very recent clang 9.0 release: StatementMacros. This 9.0 release isn't currently bundled with Visual Studio, so you have to download it separately and configure VS to use your custom clang-format.exe. Tools > Options > Text Editor > C/C++ > Formatting > General > Use custom clang-format.exe file.

Then in your .clang-format, put something like this:

StatementMacros: [
    'EXTERN_C',
    '_At_',
    '_When_',
    '_Success_',
    '_Check_return_',
    '_Must_inspect_result_',
    '_IRQL_requires_',
    '_IRQL_requires_max_',
    '_IRQL_requires_min_',
    '_IRQL_saves_',
    '_IRQL_restores_',
    '_IRQL_saves_global_',
    '_IRQL_restores_global_',
    '_IRQL_raises_',
    '_IRQL_lowers_',
    '_Acquires_lock_',
    '_Releases_lock_',
    '_Acquires_exclusive_lock_',
    '_Releases_exclusive_lock_',
    '_Acquires_shared_lock_',
    '_Releases_shared_lock_',
    '_Requires_lock_held_',
    '_Use_decl_annotations_',
    '_Guarded_by_',
    ]

That'll ensure that each function-level annotation winds up on its own line, like this:

_IRQL_requires_(PASSIVE_LEVEL)
NTSTATUS Foo()
{
    return STATUS_NOT_IMPLEMENTED;
}

Another tip for drivers. If you use WPP tracing, you'll probably want this .clang-format directive:

CommentPragmas: '^begin_wpp|^end_wpp'

Otherwise, clang-format will permit itself to mangle the special //begin_wpp comment blocks.

That all being said, there's still brokenness here. For example, clang-format recognizes __declspec as a built-in token, so it won't let you hack it using StatementMacros. So NDIS code currently has this unfortunate spot of indentation:

__declspec(noinline)
    VOID ndisNblTrackerDebugBreak(. . . something . . .)
{
    . . .;
}

I also have some issues with clang-format's "binpacking" of arguments, but that's a general style issue and not specific to drivers, so I'll not discuss it here.

Comments

  • zx2c4zx2c4 Member Posts: 6

    Have you got a complete .clang-format file that works well for you generally? I wouldn't mind just adopting whatever code style you use wholesale.

  • Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 544
    edited June 25

    I won't say I'm completely happy about clang-format's output. Let's just say this format file is the best I could do, before my patience expired. But it is what we're using now for NDIS code.

    Some small parts of it are specific to NDIS code, like the PAGED and INITCODE tokens. You almost certainly don't need those.

    https://gist.github.com/jtippet/443c3769d5ff81691ebe6cdd9b9edd42

  • zx2c4zx2c4 Member Posts: 6

    Thanks! It's not so bad, and generally some enforced style even if not ideal is better than nothing.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,376

    If I could only get the damn thing to wrap function arguments, one argument per line and aligned with the left brace. Always. I'd be a happy man.

            status = WdfDeviceCreate(&FxDeviceInit, 
                                     &deviceAttributes,
                                     &fxDevice);
    
    

    (let's hope everyone can read that. The point is the ampersands are all directly under each other)

    There is no setting -- none at all -- that I could use to get clang-format to produce anything even remotely like this. I don't even care if the first argument is on the same line as the function. I just want them all lined-up under each other, and with the left bracket, as Gxd himself so very obviously intended.

    I know, it defies common sense. I wasn't the only one who spent a whole day trying to get this to work, even :(

    Peter Viscarola
    OSR
    @OSRDrivers

  • Jeffrey_Tippet_[MSFT]Jeffrey_Tippet_[MSFT] Member - All Emails Posts: 544

    +1 I really don't like clang-format's love of what it calls "bin-packing". It's nice that the feature exists for whoever wants it, but I just want to turn it off everywhere. I got so frustrated that I tried to go fix their code, but then I discovered that it's this generic soup of crap that is designed to be equally bad at whitespacing both javascript, C++, Objective C, and google protobuf files. Because those are all clearly the same thing and need the same whitespacing rules.

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,376

    I got so frustrated that I tried to go fix their code, but then I discovered ...

    :D LOL LOL LOL

    That’s exactly what we did: “It’s open source. Pull the fucking repo and change the code to make it work. I mean, how hard can it be?”

    Most of my worst experiences have been prefaced with the phrase: how hard can it be?

    Yeah. Well. The answer is “Not hard. Rather, it’s effectively impossible unless you want to make clang-format your life's work. And, while my life may be pitifully silly in some respects, it’s not nearly pitiful enough to want to spend more than an hour of it on making clang-format do what it already should.

    “Oh well, whatever never mind”

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Developing Minifilters 29 July 2019 OSR Seminar Space
Writing WDF Drivers 23 Sept 2019 OSR Seminar Space
Kernel Debugging 21 Oct 2019 OSR Seminar Space
Internals & Software Drivers 18 Nov 2019 Dulles, VA