clang: lib/Sema/SemaBPF.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
20#include "llvm/ADT/APSInt.h"
21#include
22
24
26
29 return false;
30
31
32
33
34
38}
39
42 if (ArgType->getAsPlaceholderType())
43 return false;
44
45
46
47
48
49
52 return false;
53
54
56 return true;
57
58
59 if (const auto *RT = ArgType->getAsCanonical())
60 if (!RT->getDecl()->getDeclName().isEmpty())
61 return true;
62
63 return false;
64}
65
68 if (ArgType->getAsPlaceholderType())
69 return false;
70
71
72
73
74
75 const auto *UO = dyn_cast(Arg->IgnoreParens());
76 if (!UO)
77 return false;
78
79 const auto *CE = dyn_cast(UO->getSubExpr());
80 if (!CE)
81 return false;
82 if (CE->getCastKind() != CK_IntegralToPointer &&
83 CE->getCastKind() != CK_NullToPointer)
84 return false;
85
86
87 const auto *DR = dyn_cast(CE->getSubExpr());
88 if (!DR)
89 return false;
90
92 dyn_cast(DR->getDecl());
94 return false;
95
96
97 const auto *ED = ArgType->getAsEnumDecl();
98 if (!ED)
99 return false;
100
101
102 return llvm::is_contained(ED->enumerators(), Enumerator);
103}
104
107 assert((BuiltinID == BPF::BI__builtin_preserve_field_info ||
108 BuiltinID == BPF::BI__builtin_btf_type_id ||
109 BuiltinID == BPF::BI__builtin_preserve_type_info ||
110 BuiltinID == BPF::BI__builtin_preserve_enum_value) &&
111 "unexpected BPF builtin");
113 if (SemaRef.checkArgCount(TheCall, 2))
114 return true;
115
116
121 if (BuiltinID == BPF::BI__builtin_preserve_field_info)
122 kind = diag::err_preserve_field_info_not_const;
123 else if (BuiltinID == BPF::BI__builtin_btf_type_id)
124 kind = diag::err_btf_type_id_not_const;
125 else if (BuiltinID == BPF::BI__builtin_preserve_type_info)
126 kind = diag::err_preserve_type_info_not_const;
127 else
128 kind = diag::err_preserve_enum_value_not_const;
130 return true;
131 }
132
133
134 Arg = TheCall->getArg(0);
135 bool InvalidArg = false;
136 bool ReturnUnsignedInt = true;
137 if (BuiltinID == BPF::BI__builtin_preserve_field_info) {
139 InvalidArg = true;
140 kind = diag::err_preserve_field_info_not_field;
141 }
142 } else if (BuiltinID == BPF::BI__builtin_preserve_type_info) {
144 InvalidArg = true;
145 kind = diag::err_preserve_type_info_invalid;
146 }
147 } else if (BuiltinID == BPF::BI__builtin_preserve_enum_value) {
149 InvalidArg = true;
150 kind = diag::err_preserve_enum_value_invalid;
151 }
152 ReturnUnsignedInt = false;
153 } else if (BuiltinID == BPF::BI__builtin_btf_type_id) {
154 ReturnUnsignedInt = false;
155 }
156
157 if (InvalidArg) {
159 return true;
160 }
161
162 if (ReturnUnsignedInt)
163 TheCall->setType(Context.UnsignedIntTy);
164 else
165 TheCall->setType(Context.UnsignedLongTy);
166 return false;
167}
168
170
171 for (auto *D : RD->decls()) {
172 if (D->hasAttr())
173 continue;
174
175 D->addAttr(BPFPreserveAccessIndexAttr::CreateImplicit(getASTContext()));
176 if (auto *Rec = dyn_cast(D))
178 }
179}
180
187
188}
This file declares semantic analysis functions specific to BPF.
Enumerates target-specific builtins in their own namespaces within namespace clang.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
An instance of this object exists for each enum constant that is defined.
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
ParsedAttr - Represents a syntactic attribute.
A (possibly-)qualified type.
Represents a struct/union/class.
void handlePreserveAIRecord(RecordDecl *RD)
Definition SemaBPF.cpp:169
SemaBPF(Sema &S)
Definition SemaBPF.cpp:25
void handlePreserveAccessIndexAttr(Decl *D, const ParsedAttr &AL)
Definition SemaBPF.cpp:181
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
Definition SemaBPF.cpp:105
ASTContext & getASTContext() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
const BuiltinType * getAsPlaceholderType() const
unsigned kind
All of the diagnostics that can be emitted by the frontend.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
static bool isValidPreserveFieldInfoArg(Expr *Arg)
Definition SemaBPF.cpp:27
@ OK_BitField
A bitfield object is a bitfield on a C or C++ record.
static bool isValidPreserveEnumValueArg(Expr *Arg)
Definition SemaBPF.cpp:66
static bool isValidPreserveTypeInfoArg(Expr *Arg)
Definition SemaBPF.cpp:40
U cast(CodeGen::Address addr)
@ Enumerator
Enumerator value with fixed underlying type.