Manipulating the DeclContext member order

Hello! (Accidentally sent this to cfe-users at first instead of cfe-dev – apologies if you get this message twice as a result).

I’m looking for some help in understanding how a DeclContext is created within Clang. More specifically, I’m curious to know how and when a DeclContext’s members are added so that I can safely manipulate their order. If I understand it correctly, this order is based on a linked list which is iterated over when it’s time to construct the layout.

The first member of the linked list being FirstDecl: https://clang.llvm.org/doxygen/classclang_1_1DeclContext.html#a6c8abf07fec5ca0ea9473e4df302191f

The linked list being generated with BuildDeclChain: https://clang.llvm.org/doxygen/classclang_1_1DeclContext.html#aeed74fdf591aa2cbf15c4170499b64da

And of course, iterating the fields with the begin and end iterators: https://clang.llvm.org/doxygen/classclang_1_1RecordDecl.html#afc36412f0657ec2e9810e6f9d321b29a

I’m trying to rearrange the order of fields within a RecordDecl before the record layout is finalized in lib/AST/RecordLayoutBuilder.cpp in which the record builder implementations do all of the low-level offset calculations based on the traversal of that linked list. I’m avoiding providing an ExternalASTSource that overrides the structure layout on the virtue that the only thing here that’s changing is the order of the fields and it seems wasteful to re-implement the RecordLayoutBuilders’ battle-hardened code in the ExternalASTSource to calculate the offsets.

I’ve got a basic version of this “working” for simple projects where fields are reordered as I want them to. However, I know there’s a lot of machinery in the compiler and I also don’t know what I don’t know.

Compiling more complicated projects, like the Linux kernel, results in a seg-faulting compiler when it comes to code generation on a call to “clang::TagType::getDecl()”, and this is where my question stems from.

The current approach involves modifying BuildDeclChain to set a tail pointer: https://github.com/clang-randstruct/llvm-project/commit/3b49de55975539e72279c7c45a4679c57aceea2a

Followed by invoking it with a new order of the FieldDecls: https://github.com/clang-randstruct/llvm-project/commit/af8ec9eafa1379a89a73183b88a46fb047c97d99#diff-88e7d1cb846dd215c4ab0a4fc7b5b57eR55
(Though I believe the boolean argument in that method call is wrong)

Right now, this rearrange occurs in RecordLayoutBuilder.cpp in getASTRecordLayout().

I think I’m compromising the integrity of the DeclContext somehow and am hoping for some guidance on mending it.

Any advice or further questions are greatly appreciated. Thank you.

Connor