10 #include "llvm/ADT/SmallBitVector.h"
12 using namespace clang;
18 class OSLogFormatStringHandler
22 const Expr *E =
nullptr;
28 unsigned char Flags = 0;
38 return OSLogBufferItem::StringKind;
40 return OSLogBufferItem::WideStringKind;
42 return OSLogBufferItem::PointerKind;
44 return OSLogBufferItem::ObjCObjKind;
46 return OSLogBufferItem::ErrnoKind;
48 return OSLogBufferItem::ScalarKind;
55 ArgsData.reserve(Args.size());
59 const char *StartSpecifier,
60 unsigned SpecifierLen)
override {
61 if (!FS.consumesDataArgument() &&
62 FS.getConversionSpecifier().getKind() !=
66 ArgsData.emplace_back();
67 unsigned ArgIndex = FS.getArgIndex();
68 if (ArgIndex < Args.size())
69 ArgsData.back().E = Args[ArgIndex];
72 ArgsData.back().Kind =
getKind(FS.getConversionSpecifier().getKind());
73 if (ArgsData.back().Kind != OSLogBufferItem::ErrnoKind &&
80 switch (FS.getConversionSpecifier().getKind()) {
83 auto &precision = FS.getPrecision();
84 switch (precision.getHowSpecified()) {
88 ArgsData.back().Size = precision.getConstantAmount();
91 ArgsData.back().Count = Args[precision.getArgIndex()];
99 auto &precision = FS.getPrecision();
100 switch (precision.getHowSpecified()) {
104 ArgsData.back().Size = precision.getConstantAmount();
107 ArgsData.back().Count = Args[precision.getArgIndex()];
115 if (FS.getPrecision().hasDataArgument()) {
116 ArgsData.back().Precision = Args[FS.getPrecision().getArgIndex()];
120 if (FS.getFieldWidth().hasDataArgument()) {
121 ArgsData.back().FieldWidth = Args[FS.getFieldWidth().getArgIndex()];
124 if (FS.isSensitive())
125 ArgsData.back().Flags |= OSLogBufferItem::IsSensitive;
126 else if (FS.isPrivate())
127 ArgsData.back().Flags |= OSLogBufferItem::IsPrivate;
128 else if (FS.isPublic())
129 ArgsData.back().Flags |= OSLogBufferItem::IsPublic;
131 ArgsData.back().MaskType = FS.getMaskType();
136 Layout.
Items.clear();
137 for (
auto &Data : ArgsData) {
138 if (!Data.MaskType.empty()) {
140 Layout.
Items.emplace_back(OSLogBufferItem::MaskKind,
nullptr,
141 Size, 0, Data.MaskType);
144 if (Data.FieldWidth) {
146 Layout.
Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.FieldWidth,
149 if (Data.Precision) {
151 Layout.
Items.emplace_back(OSLogBufferItem::ScalarKind, *Data.Precision,
157 Layout.
Items.emplace_back(OSLogBufferItem::CountKind, *Data.Count, Size,
165 if (*Data.Kind == OSLogBufferItem::ErrnoKind)
169 Layout.
Items.emplace_back(*Data.Kind, Data.E, Size, Data.Flags);
172 Layout.
Items.emplace_back(OSLogBufferItem::ScalarKind, Data.E, Size,
184 const Expr *StringArg;
187 case Builtin::BI__builtin_os_log_format_buffer_size:
189 "__builtin_os_log_format_buffer_size takes at least 1 argument");
191 VarArgs = Args.slice(1);
193 case Builtin::BI__builtin_os_log_format:
195 "__builtin_os_log_format takes at least 2 arguments");
197 VarArgs = Args.slice(2);
200 llvm_unreachable(
"non-os_log builtin passed to computeOSLogBufferLayout");
206 OSLogFormatStringHandler H(VarArgs);
210 H.computeLayout(Ctx, Layout);