diff options
| author | Tamas Koczka <poprdi@google.com> | 2026-01-28 14:34:43 +0000 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2026-01-28 16:30:57 +0000 |
| commit | 0ce7d86d6a53b38ed75045173da33b277415254d (patch) | |
| tree | 7adfdaafad8f402b3d1983426d7817c637664424 /tools/clang/codesearch/codesearch.cpp | |
| parent | bb732b9882d4a11b56b97fcf41ce9625d82171c9 (diff) | |
pkg/codesearch: expose struct layout in codesearch
- Extract struct field offsets and sizes in the C++ codesearch indexer.
- Add 'fields' to the JSON definition output.
- Update pkg/codesearch to parse and expose the new field information.
- Add 'struct-layout' command to syz-codesearch for debugging.
- Add 'codesearch-struct-layout' tool to pkg/aflow/tool/codesearcher/
to allow LLM agents to query struct memory layout and map byte offsets to fields.
- Support pointer marshaling for optional JSON values (e.g. *uint)
Diffstat (limited to 'tools/clang/codesearch/codesearch.cpp')
| -rw-r--r-- | tools/clang/codesearch/codesearch.cpp | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/tools/clang/codesearch/codesearch.cpp b/tools/clang/codesearch/codesearch.cpp index 11658f4ee..b54537d59 100644 --- a/tools/clang/codesearch/codesearch.cpp +++ b/tools/clang/codesearch/codesearch.cpp @@ -9,6 +9,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ParentMapContext.h" +#include "clang/AST/RecordLayout.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/SourceManager.h" #include "clang/Frontend/CompilerInstance.h" @@ -304,6 +305,24 @@ bool Indexer::TraverseRecordDecl(RecordDecl* Decl) { if (!Decl->isThisDeclarationADefinition()) return Base::TraverseRecordDecl(Decl); NamedDeclEmitter Emitter(this, Decl, Decl->isStruct() ? EntityKindStruct : EntityKindUnion, "", false); + if (Decl->isCompleteDefinition() && !Decl->isInvalidDecl()) { + const auto& Layout = Context.getASTRecordLayout(Decl); + for (const auto* Field : Decl->fields()) { + uint64_t OffsetInBits = Layout.getFieldOffset(Field->getFieldIndex()); + uint64_t SizeInBits; + if (Field->isBitField()) { + SizeInBits = Field->getBitWidthValue(Context); + } else { + TypeInfo Info = Context.getTypeInfo(Field->getType()); + SizeInBits = Info.Width; + } + Emitter.Def.Fields.push_back(FieldInfo{ + .Name = Field->getNameAsString(), + .OffsetBits = OffsetInBits, + .SizeBits = SizeInBits, + }); + } + } return Base::TraverseRecordDecl(Decl); } |
