clang  13.0.0git
OSLog.h
Go to the documentation of this file.
1 //= OSLog.h - Analysis of calls to os_log builtins --*- C++ -*-===============//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines APIs for determining the layout of the data buffer for
10 // os_log() and os_trace().
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
15 #define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
16 
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Expr.h"
19 
20 namespace clang {
21 namespace analyze_os_log {
22 
23 /// An OSLogBufferItem represents a single item in the data written by a call
24 /// to os_log() or os_trace().
26 public:
27  enum Kind {
28  // The item is a scalar (int, float, raw pointer, etc.). No further copying
29  // is required. This is the only kind allowed by os_trace().
31 
32  // The item is a count, which describes the length of the following item to
33  // be copied. A count may only be followed by an item of kind StringKind,
34  // WideStringKind, or PointerKind.
36 
37  // The item is a pointer to a C string. If preceded by a count 'n',
38  // os_log() will copy at most 'n' bytes from the pointer.
40 
41  // The item is a pointer to a block of raw data. This item must be preceded
42  // by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer.
44 
45  // The item is a pointer to an Objective-C object. os_log() may retain the
46  // object for later processing.
48 
49  // The item is a pointer to wide-char string.
51 
52  // The item is corresponding to the '%m' format specifier, no value is
53  // populated in the buffer and the runtime is loading the errno value.
55 
56  // The item is a mask type.
58  };
59 
60  enum {
61  // The item is marked "private" in the format string.
62  IsPrivate = 0x1,
63 
64  // The item is marked "public" in the format string.
65  IsPublic = 0x2,
66 
67  // The item is marked "sensitive" in the format string.
69  };
70 
71 private:
72  Kind TheKind = ScalarKind;
73  const Expr *TheExpr = nullptr;
74  CharUnits ConstValue;
75  CharUnits Size; // size of the data, not including the header bytes
76  unsigned Flags = 0;
77  StringRef MaskType;
78 
79 public:
80  OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags,
81  StringRef maskType = StringRef())
82  : TheKind(kind), TheExpr(expr), Size(size), Flags(flags),
83  MaskType(maskType) {
84  assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic) ||
85  (Flags == IsSensitive)) &&
86  "unexpected privacy flag");
87  }
88 
89  OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
90  : TheKind(CountKind), ConstValue(value),
91  Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}
92 
93  unsigned char getDescriptorByte() const {
94  unsigned char result = Flags;
95  result |= ((unsigned)getKind()) << 4;
96  return result;
97  }
98 
99  unsigned char getSizeByte() const { return size().getQuantity(); }
100 
101  Kind getKind() const { return TheKind; }
102  bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }
103 
104  const Expr *getExpr() const { return TheExpr; }
105  CharUnits getConstValue() const { return ConstValue; }
106  CharUnits size() const { return Size; }
107 
108  StringRef getMaskType() const { return MaskType; }
109 };
110 
112 public:
114 
115  enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 };
116 
117  CharUnits size() const {
118  CharUnits result;
119  result += CharUnits::fromQuantity(2); // summary byte, num-args byte
120  for (auto &item : Items) {
121  // descriptor byte, size byte
122  result += item.size() + CharUnits::fromQuantity(2);
123  }
124  return result;
125  }
126 
127  bool hasPrivateItems() const {
128  return llvm::any_of(
129  Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });
130  }
131 
132  bool hasNonScalarOrMask() const {
133  return llvm::any_of(Items, [](const OSLogBufferItem &Item) {
134  return Item.getKind() != OSLogBufferItem::ScalarKind ||
135  !Item.getMaskType().empty();
136  });
137  }
138 
139  unsigned char getSummaryByte() const {
140  unsigned char result = 0;
141  if (hasPrivateItems())
142  result |= HasPrivateItems;
143  if (hasNonScalarOrMask())
144  result |= HasNonScalarItems;
145  return result;
146  }
147 
148  unsigned char getNumArgsByte() const { return Items.size(); }
149 };
150 
151 // Given a call 'E' to one of the builtins __builtin_os_log_format() or
152 // __builtin_os_log_format_buffer_size(), compute the layout of the buffer that
153 // the call will write into and store it in 'layout'. Returns 'false' if there
154 // was some error encountered while computing the layout, and 'true' otherwise.
156  OSLogBufferLayout &layout);
157 
158 } // namespace analyze_os_log
159 } // namespace clang
160 #endif
clang::analyze_os_log::OSLogBufferLayout::Flags
Flags
Definition: OSLog.h:115
clang::analyze_os_log::OSLogBufferItem::IsPrivate
@ IsPrivate
Definition: OSLog.h:62
clang::analyze_os_log::OSLogBufferItem::IsPublic
@ IsPublic
Definition: OSLog.h:65
llvm::SmallVector
Definition: LLVM.h:38
clang::analyze_os_log::OSLogBufferItem::Kind
Kind
Definition: OSLog.h:27
clang::analyze_os_log::OSLogBufferItem::getMaskType
StringRef getMaskType() const
Definition: OSLog.h:108
clang::analyze_os_log::OSLogBufferItem::getIsPrivate
bool getIsPrivate() const
Definition: OSLog.h:102
clang::analyze_os_log::OSLogBufferItem
An OSLogBufferItem represents a single item in the data written by a call to os_log() or os_trace().
Definition: OSLog.h:25
clang::analyze_os_log::OSLogBufferLayout::Items
SmallVector< OSLogBufferItem, 4 > Items
Definition: OSLog.h:113
clang::analyze_os_log::OSLogBufferLayout::getSummaryByte
unsigned char getSummaryByte() const
Definition: OSLog.h:139
clang::ast_matchers::expr
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
Definition: ASTMatchersInternal.cpp:875
clang::analyze_os_log::OSLogBufferItem::ErrnoKind
@ ErrnoKind
Definition: OSLog.h:54
clang::analyze_os_log::OSLogBufferItem::OSLogBufferItem
OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags, StringRef maskType=StringRef())
Definition: OSLog.h:80
clang::CharUnits::fromQuantity
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
clang::analyze_os_log::OSLogBufferItem::OSLogBufferItem
OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
Definition: OSLog.h:89
clang::analyze_os_log::computeOSLogBufferLayout
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
Definition: OSLog.cpp:180
Expr.h
ASTContext.h
clang::analyze_os_log::OSLogBufferItem::ObjCObjKind
@ ObjCObjKind
Definition: OSLog.h:47
clang::analyze_os_log::OSLogBufferItem::size
CharUnits size() const
Definition: OSLog.h:106
clang::analyze_os_log::OSLogBufferItem::getDescriptorByte
unsigned char getDescriptorByte() const
Definition: OSLog.h:93
clang::analyze_os_log::OSLogBufferLayout::hasPrivateItems
bool hasPrivateItems() const
Definition: OSLog.h:127
clang::analyze_os_log::OSLogBufferItem::PointerKind
@ PointerKind
Definition: OSLog.h:43
clang::analyze_os_log::OSLogBufferItem::MaskKind
@ MaskKind
Definition: OSLog.h:57
clang::analyze_os_log::OSLogBufferItem::StringKind
@ StringKind
Definition: OSLog.h:39
clang::analyze_os_log::OSLogBufferItem::CountKind
@ CountKind
Definition: OSLog.h:35
clang::analyze_os_log::OSLogBufferLayout::size
CharUnits size() const
Definition: OSLog.h:117
clang::analyze_os_log::OSLogBufferItem::getSizeByte
unsigned char getSizeByte() const
Definition: OSLog.h:99
clang::analyze_os_log::OSLogBufferItem::WideStringKind
@ WideStringKind
Definition: OSLog.h:50
clang::analyze_os_log::OSLogBufferItem::IsSensitive
@ IsSensitive
Definition: OSLog.h:68
clang::analyze_os_log::OSLogBufferItem::getExpr
const Expr * getExpr() const
Definition: OSLog.h:104
clang
Dataflow Directional Tag Classes.
Definition: CalledOnceCheck.h:17
clang::analyze_os_log::OSLogBufferItem::getConstValue
CharUnits getConstValue() const
Definition: OSLog.h:105
clang::analyze_os_log::OSLogBufferLayout::hasNonScalarOrMask
bool hasNonScalarOrMask() const
Definition: OSLog.h:132
unsigned
clang::analyze_os_log::OSLogBufferItem::getKind
Kind getKind() const
Definition: OSLog.h:101
clang::CharUnits
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
clang::analyze_os_log::OSLogBufferLayout::getNumArgsByte
unsigned char getNumArgsByte() const
Definition: OSLog.h:148
clang::analyze_os_log::OSLogBufferLayout::HasPrivateItems
@ HasPrivateItems
Definition: OSLog.h:115
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::analyze_os_log::OSLogBufferLayout
Definition: OSLog.h:111
clang::analyze_os_log::OSLogBufferItem::ScalarKind
@ ScalarKind
Definition: OSLog.h:30
clang::analyze_os_log::OSLogBufferLayout::HasNonScalarItems
@ HasNonScalarItems
Definition: OSLog.h:115
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2730
clang::diag::kind
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:60
clang::CharUnits::getQuantity
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:179