clang 22.0.0git
CIRGenBuiltin.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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 contains code to emit Builtin calls as CIR or a function call to be
10// later resolved.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CIRGenCall.h"
16#include "CIRGenFunction.h"
17#include "CIRGenModule.h"
18#include "CIRGenValue.h"
19#include "mlir/IR/BuiltinAttributes.h"
20#include "mlir/IR/Value.h"
21#include "mlir/Support/LLVM.h"
22#include "clang/AST/Expr.h"
26#include "llvm/Support/ErrorHandling.h"
27
28using namespace clang;
29using namespace clang::CIRGen;
30using namespace llvm;
31
33 const CallExpr *e, mlir::Operation *calleeValue) {
34 CIRGenCallee callee = CIRGenCallee::forDirect(calleeValue, GlobalDecl(fd));
35 return cgf.emitCall(e->getCallee()->getType(), callee, e, ReturnValueSlot());
36}
37
38template <typename Op>
40 bool poisonZero = false) {
42
43 mlir::Value arg = cgf.emitScalarExpr(e->getArg(0));
44 CIRGenBuilderTy &builder = cgf.getBuilder();
45
46 Op op;
47 if constexpr (std::is_same_v<Op, cir::BitClzOp> ||
48 std::is_same_v<Op, cir::BitCtzOp>)
49 op = builder.create<Op>(cgf.getLoc(e->getSourceRange()), arg, poisonZero);
50 else
51 op = builder.create<Op>(cgf.getLoc(e->getSourceRange()), arg);
52
53 mlir::Value result = op.getResult();
54 mlir::Type exprTy = cgf.convertType(e->getType());
55 if (exprTy != result.getType())
56 result = builder.createIntCast(result, exprTy);
57
58 return RValue::get(result);
59}
60
61RValue CIRGenFunction::emitRotate(const CallExpr *e, bool isRotateLeft) {
62 mlir::Value input = emitScalarExpr(e->getArg(0));
63 mlir::Value amount = emitScalarExpr(e->getArg(1));
64
65 // TODO(cir): MSVC flavor bit rotate builtins use different types for input
66 // and amount, but cir.rotate requires them to have the same type. Cast amount
67 // to the type of input when necessary.
69
70 auto r = builder.create<cir::RotateOp>(getLoc(e->getSourceRange()), input,
71 amount, isRotateLeft);
72 return RValue::get(r);
73}
74
75template <class Operation>
77 const CallExpr &e) {
78 mlir::Value arg = cgf.emitScalarExpr(e.getArg(0));
79
82
83 auto call =
84 Operation::create(cgf.getBuilder(), arg.getLoc(), arg.getType(), arg);
85 return RValue::get(call->getResult(0));
86}
87
89 const CallExpr *e,
90 ReturnValueSlot returnValue) {
91 mlir::Location loc = getLoc(e->getSourceRange());
92
93 // See if we can constant fold this builtin. If so, don't emit it at all.
94 // TODO: Extend this handling to all builtin calls that we can constant-fold.
95 Expr::EvalResult result;
96 if (e->isPRValue() && e->EvaluateAsRValue(result, cgm.getASTContext()) &&
97 !result.hasSideEffects()) {
98 if (result.Val.isInt())
99 return RValue::get(builder.getConstInt(loc, result.Val.getInt()));
100 if (result.Val.isFloat()) {
101 // Note: we are using result type of CallExpr to determine the type of
102 // the constant. Classic codegen uses the result value to determine the
103 // type. We feel it should be Ok to use expression type because it is
104 // hard to imagine a builtin function evaluates to a value that
105 // over/underflows its own defined type.
106 mlir::Type type = convertType(e->getType());
107 return RValue::get(builder.getConstFP(loc, type, result.Val.getFloat()));
108 }
109 }
110
111 const FunctionDecl *fd = gd.getDecl()->getAsFunction();
112
114
115 // If the builtin has been declared explicitly with an assembler label,
116 // disable the specialized emitting below. Ideally we should communicate the
117 // rename in IR, or at least avoid generating the intrinsic calls that are
118 // likely to get lowered to the renamed library functions.
119 unsigned builtinIDIfNoAsmLabel = fd->hasAttr<AsmLabelAttr>() ? 0 : builtinID;
120
123
124 switch (builtinIDIfNoAsmLabel) {
125 default:
126 break;
127
128 // C stdarg builtins.
129 case Builtin::BI__builtin_stdarg_start:
130 case Builtin::BI__builtin_va_start:
131 case Builtin::BI__va_start: {
132 mlir::Value vaList = builtinID == Builtin::BI__va_start
133 ? emitScalarExpr(e->getArg(0))
135 mlir::Value count = emitScalarExpr(e->getArg(1));
136 emitVAStart(vaList, count);
137 return {};
138 }
139
140 case Builtin::BI__builtin_va_end:
142 return {};
143
144 case Builtin::BIfabs:
145 case Builtin::BIfabsf:
146 case Builtin::BIfabsl:
147 case Builtin::BI__builtin_fabs:
148 case Builtin::BI__builtin_fabsf:
149 case Builtin::BI__builtin_fabsf16:
150 case Builtin::BI__builtin_fabsl:
151 case Builtin::BI__builtin_fabsf128:
152 return emitUnaryMaybeConstrainedFPBuiltin<cir::FAbsOp>(*this, *e);
153
154 case Builtin::BI__assume:
155 case Builtin::BI__builtin_assume: {
156 if (e->getArg(0)->HasSideEffects(getContext()))
157 return RValue::get(nullptr);
158
159 mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0));
160 builder.create<cir::AssumeOp>(loc, argValue);
161 return RValue::get(nullptr);
162 }
163
164 case Builtin::BI__builtin_assume_separate_storage: {
165 mlir::Value value0 = emitScalarExpr(e->getArg(0));
166 mlir::Value value1 = emitScalarExpr(e->getArg(1));
167 builder.create<cir::AssumeSepStorageOp>(loc, value0, value1);
168 return RValue::get(nullptr);
169 }
170
171 case Builtin::BI__builtin_assume_aligned: {
172 const Expr *ptrExpr = e->getArg(0);
173 mlir::Value ptrValue = emitScalarExpr(ptrExpr);
174 mlir::Value offsetValue =
175 (e->getNumArgs() > 2) ? emitScalarExpr(e->getArg(2)) : nullptr;
176
177 std::optional<llvm::APSInt> alignment =
179 assert(alignment.has_value() &&
180 "the second argument to __builtin_assume_aligned must be an "
181 "integral constant expression");
182
183 mlir::Value result =
184 emitAlignmentAssumption(ptrValue, ptrExpr, ptrExpr->getExprLoc(),
185 alignment->getSExtValue(), offsetValue);
186 return RValue::get(result);
187 }
188
189 case Builtin::BI__builtin_complex: {
190 mlir::Value real = emitScalarExpr(e->getArg(0));
191 mlir::Value imag = emitScalarExpr(e->getArg(1));
192 mlir::Value complex = builder.createComplexCreate(loc, real, imag);
193 return RValue::getComplex(complex);
194 }
195
196 case Builtin::BI__builtin_creal:
197 case Builtin::BI__builtin_crealf:
198 case Builtin::BI__builtin_creall:
199 case Builtin::BIcreal:
200 case Builtin::BIcrealf:
201 case Builtin::BIcreall: {
202 mlir::Value complex = emitComplexExpr(e->getArg(0));
203 mlir::Value real = builder.createComplexReal(loc, complex);
204 return RValue::get(real);
205 }
206
207 case Builtin::BI__builtin_cimag:
208 case Builtin::BI__builtin_cimagf:
209 case Builtin::BI__builtin_cimagl:
210 case Builtin::BIcimag:
211 case Builtin::BIcimagf:
212 case Builtin::BIcimagl: {
213 mlir::Value complex = emitComplexExpr(e->getArg(0));
214 mlir::Value imag = builder.createComplexImag(loc, complex);
215 return RValue::get(imag);
216 }
217
218 case Builtin::BI__builtin_conj:
219 case Builtin::BI__builtin_conjf:
220 case Builtin::BI__builtin_conjl:
221 case Builtin::BIconj:
222 case Builtin::BIconjf:
223 case Builtin::BIconjl: {
224 mlir::Value complex = emitComplexExpr(e->getArg(0));
225 mlir::Value conj = builder.createUnaryOp(getLoc(e->getExprLoc()),
226 cir::UnaryOpKind::Not, complex);
227 return RValue::getComplex(conj);
228 }
229
230 case Builtin::BI__builtin_clrsb:
231 case Builtin::BI__builtin_clrsbl:
232 case Builtin::BI__builtin_clrsbll:
233 return emitBuiltinBitOp<cir::BitClrsbOp>(*this, e);
234
235 case Builtin::BI__builtin_ctzs:
236 case Builtin::BI__builtin_ctz:
237 case Builtin::BI__builtin_ctzl:
238 case Builtin::BI__builtin_ctzll:
239 case Builtin::BI__builtin_ctzg:
241 return emitBuiltinBitOp<cir::BitCtzOp>(*this, e, /*poisonZero=*/true);
242
243 case Builtin::BI__builtin_clzs:
244 case Builtin::BI__builtin_clz:
245 case Builtin::BI__builtin_clzl:
246 case Builtin::BI__builtin_clzll:
247 case Builtin::BI__builtin_clzg:
249 return emitBuiltinBitOp<cir::BitClzOp>(*this, e, /*poisonZero=*/true);
250
251 case Builtin::BI__builtin_ffs:
252 case Builtin::BI__builtin_ffsl:
253 case Builtin::BI__builtin_ffsll:
254 return emitBuiltinBitOp<cir::BitFfsOp>(*this, e);
255
256 case Builtin::BI__builtin_parity:
257 case Builtin::BI__builtin_parityl:
258 case Builtin::BI__builtin_parityll:
259 return emitBuiltinBitOp<cir::BitParityOp>(*this, e);
260
261 case Builtin::BI__lzcnt16:
262 case Builtin::BI__lzcnt:
263 case Builtin::BI__lzcnt64:
265 return emitBuiltinBitOp<cir::BitClzOp>(*this, e, /*poisonZero=*/false);
266
267 case Builtin::BI__popcnt16:
268 case Builtin::BI__popcnt:
269 case Builtin::BI__popcnt64:
270 case Builtin::BI__builtin_popcount:
271 case Builtin::BI__builtin_popcountl:
272 case Builtin::BI__builtin_popcountll:
273 case Builtin::BI__builtin_popcountg:
274 return emitBuiltinBitOp<cir::BitPopcountOp>(*this, e);
275
276 case Builtin::BI__builtin_expect:
277 case Builtin::BI__builtin_expect_with_probability: {
278 mlir::Value argValue = emitScalarExpr(e->getArg(0));
279 mlir::Value expectedValue = emitScalarExpr(e->getArg(1));
280
281 mlir::FloatAttr probAttr;
282 if (builtinIDIfNoAsmLabel == Builtin::BI__builtin_expect_with_probability) {
283 llvm::APFloat probability(0.0);
284 const Expr *probArg = e->getArg(2);
285 [[maybe_unused]] bool evalSucceeded =
286 probArg->EvaluateAsFloat(probability, cgm.getASTContext());
287 assert(evalSucceeded &&
288 "probability should be able to evaluate as float");
289 bool loseInfo = false; // ignored
290 probability.convert(llvm::APFloat::IEEEdouble(),
291 llvm::RoundingMode::Dynamic, &loseInfo);
292 probAttr = mlir::FloatAttr::get(mlir::Float64Type::get(&getMLIRContext()),
293 probability);
294 }
295
296 auto result = builder.create<cir::ExpectOp>(
297 loc, argValue.getType(), argValue, expectedValue, probAttr);
298 return RValue::get(result);
299 }
300
301 case Builtin::BI__builtin_bswap16:
302 case Builtin::BI__builtin_bswap32:
303 case Builtin::BI__builtin_bswap64:
304 case Builtin::BI_byteswap_ushort:
305 case Builtin::BI_byteswap_ulong:
306 case Builtin::BI_byteswap_uint64: {
307 mlir::Value arg = emitScalarExpr(e->getArg(0));
308 return RValue::get(builder.create<cir::ByteSwapOp>(loc, arg));
309 }
310
311 case Builtin::BI__builtin_bitreverse8:
312 case Builtin::BI__builtin_bitreverse16:
313 case Builtin::BI__builtin_bitreverse32:
314 case Builtin::BI__builtin_bitreverse64: {
315 mlir::Value arg = emitScalarExpr(e->getArg(0));
316 return RValue::get(builder.create<cir::BitReverseOp>(loc, arg));
317 }
318
319 case Builtin::BI__builtin_rotateleft8:
320 case Builtin::BI__builtin_rotateleft16:
321 case Builtin::BI__builtin_rotateleft32:
322 case Builtin::BI__builtin_rotateleft64:
323 return emitRotate(e, /*isRotateLeft=*/true);
324
325 case Builtin::BI__builtin_rotateright8:
326 case Builtin::BI__builtin_rotateright16:
327 case Builtin::BI__builtin_rotateright32:
328 case Builtin::BI__builtin_rotateright64:
329 return emitRotate(e, /*isRotateLeft=*/false);
330
331 case Builtin::BI__builtin_return_address:
332 case Builtin::BI__builtin_frame_address: {
333 mlir::Location loc = getLoc(e->getExprLoc());
334 llvm::APSInt level = e->getArg(0)->EvaluateKnownConstInt(getContext());
335 if (builtinID == Builtin::BI__builtin_return_address) {
336 return RValue::get(cir::ReturnAddrOp::create(
337 builder, loc,
338 builder.getConstAPInt(loc, builder.getUInt32Ty(), level)));
339 }
340 return RValue::get(cir::FrameAddrOp::create(
341 builder, loc,
342 builder.getConstAPInt(loc, builder.getUInt32Ty(), level)));
343 }
344
345 case Builtin::BI__builtin_trap:
346 emitTrap(loc, /*createNewBlock=*/true);
347 return RValue::get(nullptr);
348
349 case Builtin::BI__builtin_unreachable:
350 emitUnreachable(e->getExprLoc(), /*createNewBlock=*/true);
351 return RValue::get(nullptr);
352 }
353
354 // If this is an alias for a lib function (e.g. __builtin_sin), emit
355 // the call using the normal call path, but using the unmangled
356 // version of the function name.
357 if (getContext().BuiltinInfo.isLibFunction(builtinID))
358 return emitLibraryCall(*this, fd, e,
359 cgm.getBuiltinLibFunction(fd, builtinID));
360
361 cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
362 return getUndefRValue(e->getType());
363}
364
365/// Given a builtin id for a function like "__builtin_fabsf", return a Function*
366/// for "fabsf".
368 unsigned builtinID) {
369 assert(astContext.BuiltinInfo.isLibFunction(builtinID));
370
371 // Get the name, skip over the __builtin_ prefix (if necessary). We may have
372 // to build this up so provide a small stack buffer to handle the vast
373 // majority of names.
375
377 name = astContext.BuiltinInfo.getName(builtinID).substr(10);
378
379 GlobalDecl d(fd);
380 mlir::Type type = convertType(fd->getType());
381 return getOrCreateCIRFunction(name, type, d, /*forVTable=*/false);
382}
383
385 mlir::Value argValue = evaluateExprAsBool(e);
386 if (!sanOpts.has(SanitizerKind::Builtin))
387 return argValue;
388
391 "emitCheckedArgForAssume: sanitizers are NYI");
392 return {};
393}
394
395void CIRGenFunction::emitVAStart(mlir::Value vaList, mlir::Value count) {
396 // LLVM codegen casts to *i8, no real gain on doing this for CIRGen this
397 // early, defer to LLVM lowering.
398 cir::VAStartOp::create(builder, vaList.getLoc(), vaList, count);
399}
400
401void CIRGenFunction::emitVAEnd(mlir::Value vaList) {
402 cir::VAEndOp::create(builder, vaList.getLoc(), vaList);
403}
404
405// FIXME(cir): This completely abstracts away the ABI with a generic CIR Op. By
406// default this lowers to llvm.va_arg which is incomplete and not ABI-compliant
407// on most targets so cir.va_arg will need some ABI handling in LoweringPrepare
411 mlir::Location loc = cgm.getLoc(ve->getExprLoc());
412 mlir::Type type = convertType(ve->getType());
413 mlir::Value vaList = emitVAListRef(ve->getSubExpr()).getPointer();
414 return cir::VAArgOp::create(builder, loc, type, vaList);
415}
Defines enum values for all the target-independent builtin functions.
static RValue emitUnaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf, const CallExpr &e)
static RValue emitLibraryCall(CIRGenFunction &cgf, const FunctionDecl *fd, const CallExpr *e, mlir::Operation *calleeValue)
static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const CallExpr *e, bool poisonZero=false)
mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, const llvm::APInt &val)
mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand)
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy)
mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real, mlir::Value imag)
mlir::Value createUnaryOp(mlir::Location loc, cir::UnaryOpKind kind, mlir::Value operand)
mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand)
APSInt & getInt()
Definition: APValue.h:489
bool isFloat() const
Definition: APValue.h:468
bool isInt() const
Definition: APValue.h:467
APFloat & getFloat()
Definition: APValue.h:503
Builtin::Context & BuiltinInfo
Definition: ASTContext.h:742
bool isLibFunction(unsigned ID) const
Return true if this is a builtin for a libc/libm function, with a "__builtin_" prefix (e....
Definition: Builtins.h:302
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
Definition: Builtins.cpp:80
mlir::Value getPointer() const
Definition: Address.h:81
cir::ConstantOp getConstFP(mlir::Location loc, mlir::Type t, llvm::APFloat fpVal)
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
Definition: CIRGenCall.h:90
mlir::Type convertType(clang::QualType t)
mlir::Value emitCheckedArgForAssume(const Expr *e)
Emits an argument for a call to a __builtin_assume.
void emitTrap(mlir::Location loc, bool createNewBlock)
Emit a trap instruction, which is used to abort the program in an abnormal way, usually for debugging...
mlir::Value emitComplexExpr(const Expr *e)
Emit the computation of the specified expression of complex type, returning the result.
mlir::Value evaluateExprAsBool(const clang::Expr *e)
Perform the usual unary conversions on the specified expression and compare the result against zero,...
Definition: CIRGenExpr.cpp:688
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
void emitVAStart(mlir::Value vaList, mlir::Value count)
Emits the start of a CIR variable-argument operation (cir.va_start)
clang::SanitizerSet sanOpts
Sanitizers enabled for this function.
void emitUnreachable(clang::SourceLocation loc, bool createNewBlock)
Emit a reached-unreachable diagnostic if loc is valid and runtime checking is enabled.
RValue getUndefRValue(clang::QualType ty)
Get an appropriate 'undef' rvalue for the given type.
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
Definition: CIRGenCall.cpp:500
mlir::Value emitScalarExpr(const clang::Expr *e)
Emit the computation of the specified expression of scalar type.
void emitVAEnd(mlir::Value vaList)
Emits the end of a CIR variable-argument operation (cir.va_start)
CIRGenBuilderTy & getBuilder()
mlir::MLIRContext & getMLIRContext()
mlir::Value emitAlignmentAssumption(mlir::Value ptrValue, QualType ty, SourceLocation loc, SourceLocation assumptionLoc, int64_t alignment, mlir::Value offsetValue=nullptr)
clang::ASTContext & getContext() const
RValue emitBuiltinExpr(const clang::GlobalDecl &gd, unsigned builtinID, const clang::CallExpr *e, ReturnValueSlot returnValue)
Address emitVAListRef(const Expr *e)
Build a "reference" to a va_list; this is either the address or the value of the expression,...
mlir::Value emitVAArg(VAArgExpr *ve)
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue emitRotate(const CallExpr *e, bool isRotateLeft)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
Definition: CIRGenModule.h:102
mlir::Type convertType(clang::QualType type)
cir::FuncOp getBuiltinLibFunction(const FunctionDecl *fd, unsigned builtinID)
Given a builtin id for a function like "__builtin_fabsf", return a Function* for "fabsf".
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::ArrayAttr extraAttrs={})
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
This trivial value class is used to represent the result of an expression that is evaluated.
Definition: CIRGenValue.h:33
static RValue get(mlir::Value v)
Definition: CIRGenValue.h:82
static RValue getComplex(mlir::Value v)
Definition: CIRGenValue.h:90
Contains the address where the return value of a function can be stored, and whether the address is v...
Definition: CIRGenCall.h:252
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:3083
Expr * getCallee()
Definition: Expr.h:3026
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:3070
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:251
bool hasAttr() const
Definition: DeclBase.h:577
This represents one expression.
Definition: Expr.h:112
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isPRValue() const
Definition: Expr.h:285
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
Definition: Expr.cpp:3624
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:273
QualType getType() const
Definition: Expr.h:144
Represents a function declaration or definition.
Definition: Decl.h:1999
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:57
const Decl * getDecl() const
Definition: GlobalDecl.h:106
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
Represents a call to the builtin function __builtin_va_arg.
Definition: Expr.h:4893
const Expr * getSubExpr() const
Definition: Expr.h:4909
QualType getType() const
Definition: Decl.h:722
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
static bool builtinCheckKind()
static bool asmLabelAttr()
static bool msvcBuiltins()
static bool cgFPOptionsRAII()
static bool sanitizers()
static bool builtinCallF128()
static bool fpConstraints()
static bool builtinCallMathErrno()
static bool builtinCall()
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:645
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:647
bool hasSideEffects() const
Definition: Expr.h:639
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition: Sanitizers.h:174
#define conj(__x)
Definition: tgmath.h:1303