aboutsummaryrefslogtreecommitdiffstats
path: root/tools/clang/codesearch/codesearch.cpp
diff options
context:
space:
mode:
authorTamas Koczka <poprdi@google.com>2026-01-28 14:34:43 +0000
committerDmitry Vyukov <dvyukov@google.com>2026-01-28 16:30:57 +0000
commit0ce7d86d6a53b38ed75045173da33b277415254d (patch)
tree7adfdaafad8f402b3d1983426d7817c637664424 /tools/clang/codesearch/codesearch.cpp
parentbb732b9882d4a11b56b97fcf41ce9625d82171c9 (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.cpp19
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);
}