Thanks to visit codestin.com
Credit goes to clang.llvm.org

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
88template <class Operation>
90 mlir::Value arg = cgf.emitScalarExpr(e.getArg(0));
91 auto call =
92 Operation::create(cgf.getBuilder(), arg.getLoc(), arg.getType(), arg);
93 return RValue::get(call->getResult(0));
94}
95
97 const CallExpr *e,
99 mlir::Location loc = getLoc(e->getSourceRange());
100
101 // See if we can constant fold this builtin. If so, don't emit it at all.
102 // TODO: Extend this handling to all builtin calls that we can constant-fold.
103 Expr::EvalResult result;
104 if (e->isPRValue() && e->EvaluateAsRValue(result, cgm.getASTContext()) &&
105 !result.hasSideEffects()) {
106 if (result.Val.isInt())
107 return RValue::get(builder.getConstInt(loc, result.Val.getInt()));
108 if (result.Val.isFloat()) {
109 // Note: we are using result type of CallExpr to determine the type of
110 // the constant. Classic codegen uses the result value to determine the
111 // type. We feel it should be Ok to use expression type because it is
112 // hard to imagine a builtin function evaluates to a value that
113 // over/underflows its own defined type.
114 mlir::Type type = convertType(e->getType());
115 return RValue::get(builder.getConstFP(loc, type, result.Val.getFloat()));
116 }
117 }
118
119 const FunctionDecl *fd = gd.getDecl()->getAsFunction();
120
122
123 // If the builtin has been declared explicitly with an assembler label,
124 // disable the specialized emitting below. Ideally we should communicate the
125 // rename in IR, or at least avoid generating the intrinsic calls that are
126 // likely to get lowered to the renamed library functions.
127 unsigned builtinIDIfNoAsmLabel = fd->hasAttr<AsmLabelAttr>() ? 0 : builtinID;
128
131
132 switch (builtinIDIfNoAsmLabel) {
133 default:
134 break;
135
136 // C stdarg builtins.
137 case Builtin::BI__builtin_stdarg_start:
138 case Builtin::BI__builtin_va_start:
139 case Builtin::BI__va_start: {
140 mlir::Value vaList = builtinID == Builtin::BI__va_start
141 ? emitScalarExpr(e->getArg(0))
143 mlir::Value count = emitScalarExpr(e->getArg(1));
144 emitVAStart(vaList, count);
145 return {};
146 }
147
148 case Builtin::BI__builtin_va_end:
150 return {};
151
152 case Builtin::BIalloca:
153 case Builtin::BI_alloca:
154 case Builtin::BI__builtin_alloca_uninitialized:
155 case Builtin::BI__builtin_alloca: {
156 // Get alloca size input
157 mlir::Value size = emitScalarExpr(e->getArg(0));
158
159 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
160 const TargetInfo &ti = getContext().getTargetInfo();
161 const CharUnits suitableAlignmentInBytes =
163
164 // Emit the alloca op with type `u8 *` to match the semantics of
165 // `llvm.alloca`. We later bitcast the type to `void *` to match the
166 // semantics of C/C++
167 // FIXME(cir): It may make sense to allow AllocaOp of type `u8` to return a
168 // pointer of type `void *`. This will require a change to the allocaOp
169 // verifier.
170 mlir::Value allocaAddr = builder.createAlloca(
171 getLoc(e->getSourceRange()), builder.getUInt8PtrTy(),
172 builder.getUInt8Ty(), "bi_alloca", suitableAlignmentInBytes, size);
173
174 // Initialize the allocated buffer if required.
175 if (builtinID != Builtin::BI__builtin_alloca_uninitialized) {
176 // Initialize the alloca with the given size and alignment according to
177 // the lang opts. Only the trivial non-initialization is supported for
178 // now.
179
180 switch (getLangOpts().getTrivialAutoVarInit()) {
182 // Nothing to initialize.
183 break;
186 cgm.errorNYI("trivial auto var init");
187 break;
188 }
189 }
190
191 // An alloca will always return a pointer to the alloca (stack) address
192 // space. This address space need not be the same as the AST / Language
193 // default (e.g. in C / C++ auto vars are in the generic address space). At
194 // the AST level this is handled within CreateTempAlloca et al., but for the
195 // builtin / dynamic alloca we have to handle it here.
197
198 // Bitcast the alloca to the expected type.
199 return RValue::get(
200 builder.createBitcast(allocaAddr, builder.getVoidPtrTy()));
201 }
202
203 case Builtin::BIcos:
204 case Builtin::BIcosf:
205 case Builtin::BIcosl:
206 case Builtin::BI__builtin_cos:
207 case Builtin::BI__builtin_cosf:
208 case Builtin::BI__builtin_cosf16:
209 case Builtin::BI__builtin_cosl:
210 case Builtin::BI__builtin_cosf128:
213
214 case Builtin::BIfabs:
215 case Builtin::BIfabsf:
216 case Builtin::BIfabsl:
217 case Builtin::BI__builtin_fabs:
218 case Builtin::BI__builtin_fabsf:
219 case Builtin::BI__builtin_fabsf16:
220 case Builtin::BI__builtin_fabsl:
221 case Builtin::BI__builtin_fabsf128:
223
224 case Builtin::BI__assume:
225 case Builtin::BI__builtin_assume: {
226 if (e->getArg(0)->HasSideEffects(getContext()))
227 return RValue::get(nullptr);
228
229 mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0));
230 builder.create<cir::AssumeOp>(loc, argValue);
231 return RValue::get(nullptr);
232 }
233
234 case Builtin::BI__builtin_assume_separate_storage: {
235 mlir::Value value0 = emitScalarExpr(e->getArg(0));
236 mlir::Value value1 = emitScalarExpr(e->getArg(1));
237 builder.create<cir::AssumeSepStorageOp>(loc, value0, value1);
238 return RValue::get(nullptr);
239 }
240
241 case Builtin::BI__builtin_assume_aligned: {
242 const Expr *ptrExpr = e->getArg(0);
243 mlir::Value ptrValue = emitScalarExpr(ptrExpr);
244 mlir::Value offsetValue =
245 (e->getNumArgs() > 2) ? emitScalarExpr(e->getArg(2)) : nullptr;
246
247 std::optional<llvm::APSInt> alignment =
249 assert(alignment.has_value() &&
250 "the second argument to __builtin_assume_aligned must be an "
251 "integral constant expression");
252
253 mlir::Value result =
254 emitAlignmentAssumption(ptrValue, ptrExpr, ptrExpr->getExprLoc(),
255 alignment->getSExtValue(), offsetValue);
256 return RValue::get(result);
257 }
258
259 case Builtin::BI__builtin_complex: {
260 mlir::Value real = emitScalarExpr(e->getArg(0));
261 mlir::Value imag = emitScalarExpr(e->getArg(1));
262 mlir::Value complex = builder.createComplexCreate(loc, real, imag);
263 return RValue::getComplex(complex);
264 }
265
266 case Builtin::BI__builtin_creal:
267 case Builtin::BI__builtin_crealf:
268 case Builtin::BI__builtin_creall:
269 case Builtin::BIcreal:
270 case Builtin::BIcrealf:
271 case Builtin::BIcreall: {
272 mlir::Value complex = emitComplexExpr(e->getArg(0));
273 mlir::Value real = builder.createComplexReal(loc, complex);
274 return RValue::get(real);
275 }
276
277 case Builtin::BI__builtin_cimag:
278 case Builtin::BI__builtin_cimagf:
279 case Builtin::BI__builtin_cimagl:
280 case Builtin::BIcimag:
281 case Builtin::BIcimagf:
282 case Builtin::BIcimagl: {
283 mlir::Value complex = emitComplexExpr(e->getArg(0));
284 mlir::Value imag = builder.createComplexImag(loc, complex);
285 return RValue::get(imag);
286 }
287
288 case Builtin::BI__builtin_conj:
289 case Builtin::BI__builtin_conjf:
290 case Builtin::BI__builtin_conjl:
291 case Builtin::BIconj:
292 case Builtin::BIconjf:
293 case Builtin::BIconjl: {
294 mlir::Value complex = emitComplexExpr(e->getArg(0));
295 mlir::Value conj = builder.createUnaryOp(getLoc(e->getExprLoc()),
296 cir::UnaryOpKind::Not, complex);
297 return RValue::getComplex(conj);
298 }
299
300 case Builtin::BI__builtin_clrsb:
301 case Builtin::BI__builtin_clrsbl:
302 case Builtin::BI__builtin_clrsbll:
303 return emitBuiltinBitOp<cir::BitClrsbOp>(*this, e);
304
305 case Builtin::BI__builtin_ctzs:
306 case Builtin::BI__builtin_ctz:
307 case Builtin::BI__builtin_ctzl:
308 case Builtin::BI__builtin_ctzll:
309 case Builtin::BI__builtin_ctzg:
311 return emitBuiltinBitOp<cir::BitCtzOp>(*this, e, /*poisonZero=*/true);
312
313 case Builtin::BI__builtin_clzs:
314 case Builtin::BI__builtin_clz:
315 case Builtin::BI__builtin_clzl:
316 case Builtin::BI__builtin_clzll:
317 case Builtin::BI__builtin_clzg:
319 return emitBuiltinBitOp<cir::BitClzOp>(*this, e, /*poisonZero=*/true);
320
321 case Builtin::BI__builtin_ffs:
322 case Builtin::BI__builtin_ffsl:
323 case Builtin::BI__builtin_ffsll:
324 return emitBuiltinBitOp<cir::BitFfsOp>(*this, e);
325
326 case Builtin::BI__builtin_parity:
327 case Builtin::BI__builtin_parityl:
328 case Builtin::BI__builtin_parityll:
329 return emitBuiltinBitOp<cir::BitParityOp>(*this, e);
330
331 case Builtin::BI__lzcnt16:
332 case Builtin::BI__lzcnt:
333 case Builtin::BI__lzcnt64:
335 return emitBuiltinBitOp<cir::BitClzOp>(*this, e, /*poisonZero=*/false);
336
337 case Builtin::BI__popcnt16:
338 case Builtin::BI__popcnt:
339 case Builtin::BI__popcnt64:
340 case Builtin::BI__builtin_popcount:
341 case Builtin::BI__builtin_popcountl:
342 case Builtin::BI__builtin_popcountll:
343 case Builtin::BI__builtin_popcountg:
345
346 case Builtin::BI__builtin_expect:
347 case Builtin::BI__builtin_expect_with_probability: {
348 mlir::Value argValue = emitScalarExpr(e->getArg(0));
349 mlir::Value expectedValue = emitScalarExpr(e->getArg(1));
350
351 mlir::FloatAttr probAttr;
352 if (builtinIDIfNoAsmLabel == Builtin::BI__builtin_expect_with_probability) {
353 llvm::APFloat probability(0.0);
354 const Expr *probArg = e->getArg(2);
355 [[maybe_unused]] bool evalSucceeded =
356 probArg->EvaluateAsFloat(probability, cgm.getASTContext());
357 assert(evalSucceeded &&
358 "probability should be able to evaluate as float");
359 bool loseInfo = false; // ignored
360 probability.convert(llvm::APFloat::IEEEdouble(),
361 llvm::RoundingMode::Dynamic, &loseInfo);
362 probAttr = mlir::FloatAttr::get(mlir::Float64Type::get(&getMLIRContext()),
363 probability);
364 }
365
366 auto result = builder.create<cir::ExpectOp>(
367 loc, argValue.getType(), argValue, expectedValue, probAttr);
368 return RValue::get(result);
369 }
370
371 case Builtin::BI__builtin_bswap16:
372 case Builtin::BI__builtin_bswap32:
373 case Builtin::BI__builtin_bswap64:
374 case Builtin::BI_byteswap_ushort:
375 case Builtin::BI_byteswap_ulong:
376 case Builtin::BI_byteswap_uint64: {
377 mlir::Value arg = emitScalarExpr(e->getArg(0));
378 return RValue::get(builder.create<cir::ByteSwapOp>(loc, arg));
379 }
380
381 case Builtin::BI__builtin_bitreverse8:
382 case Builtin::BI__builtin_bitreverse16:
383 case Builtin::BI__builtin_bitreverse32:
384 case Builtin::BI__builtin_bitreverse64: {
385 mlir::Value arg = emitScalarExpr(e->getArg(0));
386 return RValue::get(builder.create<cir::BitReverseOp>(loc, arg));
387 }
388
389 case Builtin::BI__builtin_rotateleft8:
390 case Builtin::BI__builtin_rotateleft16:
391 case Builtin::BI__builtin_rotateleft32:
392 case Builtin::BI__builtin_rotateleft64:
393 return emitRotate(e, /*isRotateLeft=*/true);
394
395 case Builtin::BI__builtin_rotateright8:
396 case Builtin::BI__builtin_rotateright16:
397 case Builtin::BI__builtin_rotateright32:
398 case Builtin::BI__builtin_rotateright64:
399 return emitRotate(e, /*isRotateLeft=*/false);
400
401 case Builtin::BI__builtin_return_address:
402 case Builtin::BI__builtin_frame_address: {
403 mlir::Location loc = getLoc(e->getExprLoc());
404 llvm::APSInt level = e->getArg(0)->EvaluateKnownConstInt(getContext());
405 if (builtinID == Builtin::BI__builtin_return_address) {
406 return RValue::get(cir::ReturnAddrOp::create(
407 builder, loc,
408 builder.getConstAPInt(loc, builder.getUInt32Ty(), level)));
409 }
410 return RValue::get(cir::FrameAddrOp::create(
411 builder, loc,
412 builder.getConstAPInt(loc, builder.getUInt32Ty(), level)));
413 }
414
415 case Builtin::BI__builtin_trap:
416 emitTrap(loc, /*createNewBlock=*/true);
417 return RValue::get(nullptr);
418
419 case Builtin::BI__builtin_unreachable:
420 emitUnreachable(e->getExprLoc(), /*createNewBlock=*/true);
421 return RValue::get(nullptr);
422
423 case Builtin::BI__builtin_elementwise_acos:
424 return emitUnaryFPBuiltin<cir::ACosOp>(*this, *e);
425 case Builtin::BI__builtin_elementwise_asin:
426 return emitUnaryFPBuiltin<cir::ASinOp>(*this, *e);
427 case Builtin::BI__builtin_elementwise_atan:
428 return emitUnaryFPBuiltin<cir::ATanOp>(*this, *e);
429 case Builtin::BI__builtin_elementwise_cos:
430 return emitUnaryFPBuiltin<cir::CosOp>(*this, *e);
431 }
432
433 // If this is an alias for a lib function (e.g. __builtin_sin), emit
434 // the call using the normal call path, but using the unmangled
435 // version of the function name.
436 if (getContext().BuiltinInfo.isLibFunction(builtinID))
437 return emitLibraryCall(*this, fd, e,
438 cgm.getBuiltinLibFunction(fd, builtinID));
439
440 cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
441 return getUndefRValue(e->getType());
442}
443
444/// Given a builtin id for a function like "__builtin_fabsf", return a Function*
445/// for "fabsf".
447 unsigned builtinID) {
448 assert(astContext.BuiltinInfo.isLibFunction(builtinID));
449
450 // Get the name, skip over the __builtin_ prefix (if necessary). We may have
451 // to build this up so provide a small stack buffer to handle the vast
452 // majority of names.
454
456 name = astContext.BuiltinInfo.getName(builtinID).substr(10);
457
458 GlobalDecl d(fd);
459 mlir::Type type = convertType(fd->getType());
460 return getOrCreateCIRFunction(name, type, d, /*forVTable=*/false);
461}
462
464 mlir::Value argValue = evaluateExprAsBool(e);
465 if (!sanOpts.has(SanitizerKind::Builtin))
466 return argValue;
467
469 cgm.errorNYI(e->getSourceRange(),
470 "emitCheckedArgForAssume: sanitizers are NYI");
471 return {};
472}
473
474void CIRGenFunction::emitVAStart(mlir::Value vaList, mlir::Value count) {
475 // LLVM codegen casts to *i8, no real gain on doing this for CIRGen this
476 // early, defer to LLVM lowering.
477 cir::VAStartOp::create(builder, vaList.getLoc(), vaList, count);
478}
479
480void CIRGenFunction::emitVAEnd(mlir::Value vaList) {
481 cir::VAEndOp::create(builder, vaList.getLoc(), vaList);
482}
483
484// FIXME(cir): This completely abstracts away the ABI with a generic CIR Op. By
485// default this lowers to llvm.va_arg which is incomplete and not ABI-compliant
486// on most targets so cir.va_arg will need some ABI handling in LoweringPrepare
490 mlir::Location loc = cgm.getLoc(ve->getExprLoc());
491 mlir::Type type = convertType(ve->getType());
492 mlir::Value vaList = emitVAListRef(ve->getSubExpr()).getPointer();
493 return cir::VAArgOp::create(builder, loc, type, vaList);
494}
Defines enum values for all the target-independent builtin functions.
static RValue emitUnaryMaybeConstrainedFPBuiltin(CIRGenFunction &cgf, const CallExpr &e)
static RValue emitUnaryFPBuiltin(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 createIntCast(mlir::Value src, mlir::Type newTy)
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
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:856
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
mlir::Value getPointer() const
Definition Address.h:81
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.
const clang::LangOptions & getLangOpts() const
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,...
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.
Address returnValue
The temporary alloca to hold the return value.
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
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)
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={})
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:2877
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3081
Expr * getCallee()
Definition Expr.h:3024
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3068
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
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) 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:3665
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
Exposes information about the current target.
Definition TargetInfo.h:226
unsigned getSuitableAlign() const
Return the alignment that is the largest alignment ever used for any scalar/SIMD data type on the tar...
Definition TargetInfo.h:742
Represents a call to the builtin function __builtin_va_arg.
Definition Expr.h:4891
const Expr * getSubExpr() const
Definition Expr.h:4907
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 addressSpace()
static bool asmLabelAttr()
static bool msvcBuiltins()
static bool cgFPOptionsRAII()
static bool builtinCallF128()
static bool fpConstraints()
static bool builtinCallMathErrno()
static bool fastMathFlags()
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
Return true if the evaluated expression has side effects.
Definition Expr.h:639
#define conj(__x)
Definition tgmath.h:1303