clang 22.0.0git
CIRGenExprConstant.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 Constant Expr nodes as LLVM code.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Address.h"
15#include "CIRGenFunction.h"
16#include "CIRGenModule.h"
17#include "CIRGenRecordLayout.h"
18#include "mlir/IR/Attributes.h"
19#include "mlir/IR/BuiltinAttributeInterfaces.h"
20#include "mlir/IR/BuiltinAttributes.h"
21#include "clang/AST/APValue.h"
23#include "clang/AST/Attr.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/Sequence.h"
33#include "llvm/Support/ErrorHandling.h"
34
35using namespace clang;
36using namespace clang::CIRGen;
37
38//===----------------------------------------------------------------------===//
39// ConstExprEmitter
40//===----------------------------------------------------------------------===//
41
42// This class only needs to handle arrays, structs and unions.
43//
44// In LLVM codegen, when outside C++11 mode, those types are not constant
45// folded, while all other types are handled by constant folding.
46//
47// In CIR codegen, instead of folding things here, we should defer that work
48// to MLIR: do not attempt to do much here.
50 : public StmtVisitor<ConstExprEmitter, mlir::Attribute, QualType> {
51 CIRGenModule &cgm;
52 LLVM_ATTRIBUTE_UNUSED ConstantEmitter &emitter;
53
54public:
56 : cgm(emitter.cgm), emitter(emitter) {}
57
58 //===--------------------------------------------------------------------===//
59 // Visitor Methods
60 //===--------------------------------------------------------------------===//
61
62 mlir::Attribute VisitStmt(Stmt *S, QualType T) { return {}; }
63
64 mlir::Attribute VisitConstantExpr(ConstantExpr *ce, QualType t) {
65 if (mlir::Attribute result = emitter.tryEmitConstantExpr(ce))
66 return result;
67 return Visit(ce->getSubExpr(), t);
68 }
69
70 mlir::Attribute VisitParenExpr(ParenExpr *pe, QualType t) {
71 return Visit(pe->getSubExpr(), t);
72 }
73
74 mlir::Attribute
76 QualType t) {
77 return Visit(pe->getReplacement(), t);
78 }
79
81 QualType t) {
82 return Visit(ge->getResultExpr(), t);
83 }
84
85 mlir::Attribute VisitChooseExpr(ChooseExpr *ce, QualType t) {
86 return Visit(ce->getChosenSubExpr(), t);
87 }
88
90 return Visit(e->getInitializer(), t);
91 }
92
93 mlir::Attribute VisitCastExpr(CastExpr *e, QualType destType) {
94 if (isa<ExplicitCastExpr>(e))
95 cgm.errorNYI(e->getBeginLoc(),
96 "ConstExprEmitter::VisitCastExpr explicit cast");
97
98 Expr *subExpr = e->getSubExpr();
99
100 switch (e->getCastKind()) {
101 case CK_ToUnion:
102 case CK_AddressSpaceConversion:
103 case CK_ReinterpretMemberPointer:
104 case CK_DerivedToBaseMemberPointer:
105 case CK_BaseToDerivedMemberPointer:
106 cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitCastExpr");
107 return {};
108
109 case CK_LValueToRValue:
110 case CK_AtomicToNonAtomic:
111 case CK_NonAtomicToAtomic:
112 case CK_NoOp:
113 case CK_ConstructorConversion:
114 return Visit(subExpr, destType);
115
116 case CK_IntToOCLSampler:
117 llvm_unreachable("global sampler variables are not generated");
118
119 case CK_Dependent:
120 llvm_unreachable("saw dependent cast!");
121
122 case CK_BuiltinFnToFnPtr:
123 llvm_unreachable("builtin functions are handled elsewhere");
124
125 // These will never be supported.
126 case CK_ObjCObjectLValueCast:
127 case CK_ARCProduceObject:
128 case CK_ARCConsumeObject:
129 case CK_ARCReclaimReturnedObject:
130 case CK_ARCExtendBlockObject:
131 case CK_CopyAndAutoreleaseBlockObject:
132 return {};
133
134 // These don't need to be handled here because Evaluate knows how to
135 // evaluate them in the cases where they can be folded.
136 case CK_BitCast:
137 case CK_ToVoid:
138 case CK_Dynamic:
139 case CK_LValueBitCast:
140 case CK_LValueToRValueBitCast:
141 case CK_NullToMemberPointer:
142 case CK_UserDefinedConversion:
143 case CK_CPointerToObjCPointerCast:
144 case CK_BlockPointerToObjCPointerCast:
145 case CK_AnyPointerToBlockPointerCast:
146 case CK_ArrayToPointerDecay:
147 case CK_FunctionToPointerDecay:
148 case CK_BaseToDerived:
149 case CK_DerivedToBase:
150 case CK_UncheckedDerivedToBase:
151 case CK_MemberPointerToBoolean:
152 case CK_VectorSplat:
153 case CK_FloatingRealToComplex:
154 case CK_FloatingComplexToReal:
155 case CK_FloatingComplexToBoolean:
156 case CK_FloatingComplexCast:
157 case CK_FloatingComplexToIntegralComplex:
158 case CK_IntegralRealToComplex:
159 case CK_IntegralComplexToReal:
160 case CK_IntegralComplexToBoolean:
161 case CK_IntegralComplexCast:
162 case CK_IntegralComplexToFloatingComplex:
163 case CK_PointerToIntegral:
164 case CK_PointerToBoolean:
165 case CK_NullToPointer:
166 case CK_IntegralCast:
167 case CK_BooleanToSignedIntegral:
168 case CK_IntegralToPointer:
169 case CK_IntegralToBoolean:
170 case CK_IntegralToFloating:
171 case CK_FloatingToIntegral:
172 case CK_FloatingToBoolean:
173 case CK_FloatingCast:
174 case CK_FloatingToFixedPoint:
175 case CK_FixedPointToFloating:
176 case CK_FixedPointCast:
177 case CK_FixedPointToBoolean:
178 case CK_FixedPointToIntegral:
179 case CK_IntegralToFixedPoint:
180 case CK_ZeroToOCLOpaqueType:
181 case CK_MatrixCast:
182 case CK_HLSLArrayRValue:
183 case CK_HLSLVectorTruncation:
184 case CK_HLSLElementwiseCast:
185 case CK_HLSLAggregateSplatCast:
186 return {};
187 }
188 llvm_unreachable("Invalid CastKind");
189 }
190
192 cgm.errorNYI(die->getBeginLoc(),
193 "ConstExprEmitter::VisitCXXDefaultInitExpr");
194 return {};
195 }
196
198 // Since this about constant emission no need to wrap this under a scope.
199 return Visit(e->getSubExpr(), t);
200 }
201
203 QualType t) {
204 return Visit(e->getSubExpr(), t);
205 }
206
208 QualType T) {
209 cgm.errorNYI(E->getBeginLoc(),
210 "ConstExprEmitter::VisitImplicitValueInitExpr");
211 return {};
212 }
213
214 mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t) {
215 if (ile->isTransparent())
216 return Visit(ile->getInit(0), t);
217
218 if (ile->getType()->isArrayType()) {
219 // If we return null here, the non-constant initializer will take care of
220 // it, but we would prefer to handle it here.
222 return {};
223 }
224
225 if (ile->getType()->isRecordType()) {
226 cgm.errorNYI(ile->getBeginLoc(), "ConstExprEmitter: record ILE");
227 return {};
228 }
229
230 if (ile->getType()->isVectorType()) {
231 // If we return null here, the non-constant initializer will take care of
232 // it, but we would prefer to handle it here.
234 return {};
235 }
236
237 return {};
238 }
239
241 QualType destType) {
242 mlir::Attribute c = Visit(e->getBase(), destType);
243 if (!c)
244 return {};
245
246 cgm.errorNYI(e->getBeginLoc(),
247 "ConstExprEmitter::VisitDesignatedInitUpdateExpr");
248 return {};
249 }
250
252 cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitCXXConstructExpr");
253 return {};
254 }
255
257 // This is a string literal initializing an array in an initializer.
259 }
260
262 cgm.errorNYI(e->getBeginLoc(), "ConstExprEmitter::VisitObjCEncodeExpr");
263 return {};
264 }
265
266 mlir::Attribute VisitUnaryExtension(const UnaryOperator *e, QualType t) {
267 return Visit(e->getSubExpr(), t);
268 }
269
270 // Utility methods
271 mlir::Type convertType(QualType t) { return cgm.convertType(t); }
272};
273
274// TODO(cir): this can be shared with LLVM's codegen
276 if (const auto *at = type->getAs<AtomicType>()) {
277 return cgm.getASTContext().getQualifiedType(at->getValueType(),
278 type.getQualifiers());
279 }
280 return type;
281}
282
283static mlir::Attribute
284emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType,
285 mlir::Type commonElementType, unsigned arrayBound,
287 mlir::TypedAttr filler) {
288 CIRGenBuilderTy &builder = cgm.getBuilder();
289
290 unsigned nonzeroLength = arrayBound;
291 if (elements.size() < nonzeroLength && builder.isNullValue(filler))
292 nonzeroLength = elements.size();
293
294 if (nonzeroLength == elements.size()) {
295 while (nonzeroLength > 0 &&
296 builder.isNullValue(elements[nonzeroLength - 1]))
297 --nonzeroLength;
298 }
299
300 if (nonzeroLength == 0)
301 return cir::ZeroAttr::get(desiredType);
302
303 const unsigned trailingZeroes = arrayBound - nonzeroLength;
304
305 // Add a zeroinitializer array filler if we have lots of trailing zeroes.
306 if (trailingZeroes >= 8) {
307 assert(elements.size() >= nonzeroLength &&
308 "missing initializer for non-zero element");
309
310 if (commonElementType && nonzeroLength >= 8) {
311 // If all the elements had the same type up to the trailing zeroes and
312 // there are eight or more nonzero elements, emit a struct of two arrays
313 // (the nonzero data and the zeroinitializer).
315 eles.reserve(nonzeroLength);
316 for (const auto &element : elements)
317 eles.push_back(element);
318 auto initial = cir::ConstArrayAttr::get(
319 cir::ArrayType::get(commonElementType, nonzeroLength),
320 mlir::ArrayAttr::get(builder.getContext(), eles));
321 elements.resize(2);
322 elements[0] = initial;
323 } else {
324 // Otherwise, emit a struct with individual elements for each nonzero
325 // initializer, followed by a zeroinitializer array filler.
326 elements.resize(nonzeroLength + 1);
327 }
328
329 mlir::Type fillerType =
330 commonElementType
331 ? commonElementType
332 : mlir::cast<cir::ArrayType>(desiredType).getElementType();
333 fillerType = cir::ArrayType::get(fillerType, trailingZeroes);
334 elements.back() = cir::ZeroAttr::get(fillerType);
335 commonElementType = nullptr;
336 } else if (elements.size() != arrayBound) {
337 elements.resize(arrayBound, filler);
338
339 if (filler.getType() != commonElementType)
340 commonElementType = {};
341 }
342
343 if (commonElementType) {
345 eles.reserve(elements.size());
346
347 for (const auto &element : elements)
348 eles.push_back(element);
349
350 return cir::ConstArrayAttr::get(
351 cir::ArrayType::get(commonElementType, arrayBound),
352 mlir::ArrayAttr::get(builder.getContext(), eles));
353 }
354
356 eles.reserve(elements.size());
357 for (auto const &element : elements)
358 eles.push_back(element);
359
360 auto arrAttr = mlir::ArrayAttr::get(builder.getContext(), eles);
361 return builder.getAnonConstRecord(arrAttr, /*isPacked=*/true);
362}
363
364//===----------------------------------------------------------------------===//
365// ConstantLValueEmitter
366//===----------------------------------------------------------------------===//
367
368namespace {
369/// A struct which can be used to peephole certain kinds of finalization
370/// that normally happen during l-value emission.
371struct ConstantLValue {
372 llvm::PointerUnion<mlir::Value, mlir::Attribute> value;
373 bool hasOffsetApplied;
374
375 /*implicit*/ ConstantLValue(std::nullptr_t)
376 : value(nullptr), hasOffsetApplied(false) {}
377 /*implicit*/ ConstantLValue(cir::GlobalViewAttr address)
378 : value(address), hasOffsetApplied(false) {}
379
380 ConstantLValue() : value(nullptr), hasOffsetApplied(false) {}
381};
382
383/// A helper class for emitting constant l-values.
384class ConstantLValueEmitter
385 : public ConstStmtVisitor<ConstantLValueEmitter, ConstantLValue> {
386 CIRGenModule &cgm;
387 ConstantEmitter &emitter;
388 const APValue &value;
389 QualType destType;
390
391 // Befriend StmtVisitorBase so that we don't have to expose Visit*.
392 friend StmtVisitorBase;
393
394public:
395 ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value,
396 QualType destType)
397 : cgm(emitter.cgm), emitter(emitter), value(value), destType(destType) {}
398
399 mlir::Attribute tryEmit();
400
401private:
402 mlir::Attribute tryEmitAbsolute(mlir::Type destTy);
403 ConstantLValue tryEmitBase(const APValue::LValueBase &base);
404
405 ConstantLValue VisitStmt(const Stmt *s) { return nullptr; }
406 ConstantLValue VisitConstantExpr(const ConstantExpr *e);
407 ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *e);
408 ConstantLValue VisitStringLiteral(const StringLiteral *e);
409 ConstantLValue VisitObjCBoxedExpr(const ObjCBoxedExpr *e);
410 ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *e);
411 ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *e);
412 ConstantLValue VisitPredefinedExpr(const PredefinedExpr *e);
413 ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *e);
414 ConstantLValue VisitCallExpr(const CallExpr *e);
415 ConstantLValue VisitBlockExpr(const BlockExpr *e);
416 ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *e);
417 ConstantLValue
418 VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *e);
419
420 /// Return GEP-like value offset
421 mlir::ArrayAttr getOffset(mlir::Type ty) {
422 int64_t offset = value.getLValueOffset().getQuantity();
423 cir::CIRDataLayout layout(cgm.getModule());
425 cgm.getBuilder().computeGlobalViewIndicesFromFlatOffset(offset, ty, layout,
426 idxVec);
427
429 for (int64_t i : idxVec) {
430 mlir::IntegerAttr intAttr = cgm.getBuilder().getI32IntegerAttr(i);
431 indices.push_back(intAttr);
432 }
433
434 if (indices.empty())
435 return {};
436 return cgm.getBuilder().getArrayAttr(indices);
437 }
438
439 /// Apply the value offset to the given constant.
440 ConstantLValue applyOffset(ConstantLValue &c) {
441 // Handle attribute constant LValues.
442 if (auto attr = mlir::dyn_cast<mlir::Attribute>(c.value)) {
443 if (auto gv = mlir::dyn_cast<cir::GlobalViewAttr>(attr)) {
444 auto baseTy = mlir::cast<cir::PointerType>(gv.getType()).getPointee();
445 mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
446 assert(!gv.getIndices() && "Global view is already indexed");
447 return cir::GlobalViewAttr::get(destTy, gv.getSymbol(),
448 getOffset(baseTy));
449 }
450 llvm_unreachable("Unsupported attribute type to offset");
451 }
452
453 cgm.errorNYI("ConstantLValue: non-attribute offset");
454 return {};
455 }
456};
457
458} // namespace
459
460mlir::Attribute ConstantLValueEmitter::tryEmit() {
461 const APValue::LValueBase &base = value.getLValueBase();
462
463 // The destination type should be a pointer or reference
464 // type, but it might also be a cast thereof.
465 //
466 // FIXME: the chain of casts required should be reflected in the APValue.
467 // We need this in order to correctly handle things like a ptrtoint of a
468 // non-zero null pointer and addrspace casts that aren't trivially
469 // represented in LLVM IR.
470 mlir::Type destTy = cgm.getTypes().convertTypeForMem(destType);
471 assert(mlir::isa<cir::PointerType>(destTy));
472
473 // If there's no base at all, this is a null or absolute pointer,
474 // possibly cast back to an integer type.
475 if (!base)
476 return tryEmitAbsolute(destTy);
477
478 // Otherwise, try to emit the base.
479 ConstantLValue result = tryEmitBase(base);
480
481 // If that failed, we're done.
482 llvm::PointerUnion<mlir::Value, mlir::Attribute> &value = result.value;
483 if (!value)
484 return {};
485
486 // Apply the offset if necessary and not already done.
487 if (!result.hasOffsetApplied)
488 value = applyOffset(result).value;
489
490 // Convert to the appropriate type; this could be an lvalue for
491 // an integer. FIXME: performAddrSpaceCast
492 if (mlir::isa<cir::PointerType>(destTy)) {
493 if (auto attr = mlir::dyn_cast<mlir::Attribute>(value))
494 return attr;
495 cgm.errorNYI("ConstantLValueEmitter: non-attribute pointer");
496 return {};
497 }
498
499 cgm.errorNYI("ConstantLValueEmitter: other?");
500 return {};
501}
502
503/// Try to emit an absolute l-value, such as a null pointer or an integer
504/// bitcast to pointer type.
505mlir::Attribute ConstantLValueEmitter::tryEmitAbsolute(mlir::Type destTy) {
506 // If we're producing a pointer, this is easy.
507 auto destPtrTy = mlir::cast<cir::PointerType>(destTy);
508 return cgm.getBuilder().getConstPtrAttr(
509 destPtrTy, value.getLValueOffset().getQuantity());
510}
511
512ConstantLValue
513ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
514 // Handle values.
515 if (const ValueDecl *d = base.dyn_cast<const ValueDecl *>()) {
516 // The constant always points to the canonical declaration. We want to look
517 // at properties of the most recent declaration at the point of emission.
518 d = cast<ValueDecl>(d->getMostRecentDecl());
519
520 if (d->hasAttr<WeakRefAttr>()) {
521 cgm.errorNYI(d->getSourceRange(),
522 "ConstantLValueEmitter: emit pointer base for weakref");
523 return {};
524 }
525
526 if (auto *fd = dyn_cast<FunctionDecl>(d)) {
527 cir::FuncOp fop = cgm.getAddrOfFunction(fd);
528 CIRGenBuilderTy &builder = cgm.getBuilder();
529 mlir::MLIRContext *mlirContext = builder.getContext();
530 return cir::GlobalViewAttr::get(
531 builder.getPointerTo(fop.getFunctionType()),
532 mlir::FlatSymbolRefAttr::get(mlirContext, fop.getSymNameAttr()));
533 }
534
535 if (auto *vd = dyn_cast<VarDecl>(d)) {
536 // We can never refer to a variable with local storage.
537 if (!vd->hasLocalStorage()) {
538 if (vd->isFileVarDecl() || vd->hasExternalStorage())
539 return cgm.getAddrOfGlobalVarAttr(vd);
540
541 if (vd->isLocalVarDecl()) {
542 cgm.errorNYI(vd->getSourceRange(),
543 "ConstantLValueEmitter: local var decl");
544 return {};
545 }
546 }
547 }
548
549 // Classic codegen handles MSGuidDecl,UnnamedGlobalConstantDecl, and
550 // TemplateParamObjectDecl, but it can also fall through from VarDecl,
551 // in which case it silently returns nullptr. For now, let's emit an
552 // error to see what cases we need to handle.
553 cgm.errorNYI(d->getSourceRange(),
554 "ConstantLValueEmitter: unhandled value decl");
555 return {};
556 }
557
558 // Handle typeid(T).
559 if (base.dyn_cast<TypeInfoLValue>()) {
560 cgm.errorNYI("ConstantLValueEmitter: typeid");
561 return {};
562 }
563
564 // Otherwise, it must be an expression.
565 return Visit(base.get<const Expr *>());
566}
567
568ConstantLValue ConstantLValueEmitter::VisitConstantExpr(const ConstantExpr *e) {
569 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: constant expr");
570 return {};
571}
572
573ConstantLValue
574ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *e) {
575 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: compound literal");
576 return {};
577}
578
579ConstantLValue
580ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *e) {
582}
583
584ConstantLValue
585ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *e) {
586 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc encode expr");
587 return {};
588}
589
590ConstantLValue
591ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *e) {
592 cgm.errorNYI(e->getSourceRange(),
593 "ConstantLValueEmitter: objc string literal");
594 return {};
595}
596
597ConstantLValue
598ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *e) {
599 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: objc boxed expr");
600 return {};
601}
602
603ConstantLValue
604ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *e) {
605 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: predefined expr");
606 return {};
607}
608
609ConstantLValue
610ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *e) {
611 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: addr label expr");
612 return {};
613}
614
615ConstantLValue ConstantLValueEmitter::VisitCallExpr(const CallExpr *e) {
616 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: call expr");
617 return {};
618}
619
620ConstantLValue ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *e) {
621 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: block expr");
622 return {};
623}
624
625ConstantLValue
626ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *e) {
627 cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: cxx typeid expr");
628 return {};
629}
630
631ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
632 const MaterializeTemporaryExpr *e) {
633 cgm.errorNYI(e->getSourceRange(),
634 "ConstantLValueEmitter: materialize temporary expr");
635 return {};
636}
637
638//===----------------------------------------------------------------------===//
639// ConstantEmitter
640//===----------------------------------------------------------------------===//
641
643 initializeNonAbstract();
644 return markIfFailed(tryEmitPrivateForVarInit(d));
645}
646
647void ConstantEmitter::finalize(cir::GlobalOp gv) {
648 assert(initializedNonAbstract &&
649 "finalizing emitter that was used for abstract emission?");
650 assert(!finalized && "finalizing emitter multiple times");
651 assert(!gv.isDeclaration());
652#ifndef NDEBUG
653 // Note that we might also be Failed.
654 finalized = true;
655#endif // NDEBUG
656}
657
658mlir::Attribute
660 AbstractStateRAII state(*this, true);
661 return tryEmitPrivateForVarInit(d);
662}
663
665 assert((!initializedNonAbstract || finalized || failed) &&
666 "not finalized after being initialized for non-abstract emission");
667}
668
670 // Make a quick check if variable can be default NULL initialized
671 // and avoid going through rest of code which may do, for c++11,
672 // initialization of memory to all NULLs.
673 if (!d.hasLocalStorage()) {
675 if (ty->isRecordType()) {
676 if (const auto *e = dyn_cast_or_null<CXXConstructExpr>(d.getInit())) {
677 const CXXConstructorDecl *cd = e->getConstructor();
678 // FIXME: we should probably model this more closely to C++ than
679 // just emitting a global with zero init (mimic what we do for trivial
680 // assignments and whatnots). Since this is for globals shouldn't
681 // be a problem for the near future.
682 if (cd->isTrivial() && cd->isDefaultConstructor()) {
683 const auto *cxxrd = ty->castAsCXXRecordDecl();
684 if (cxxrd->getNumBases() != 0) {
685 // There may not be anything additional to do here, but this will
686 // force us to pause and test this path when it is supported.
687 cgm.errorNYI("tryEmitPrivateForVarInit: cxx record with bases");
688 return {};
689 }
690 if (!cgm.getTypes().isZeroInitializable(cxxrd)) {
691 // To handle this case, we really need to go through
692 // emitNullConstant, but we need an attribute, not a value
694 "tryEmitPrivateForVarInit: non-zero-initializable cxx record");
695 return {};
696 }
697 return cir::ZeroAttr::get(cgm.convertType(d.getType()));
698 }
699 }
700 }
701 }
702 inConstantContext = d.hasConstantInitialization();
703
704 const Expr *e = d.getInit();
705 assert(e && "No initializer to emit");
706
707 QualType destType = d.getType();
708
709 if (!destType->isReferenceType()) {
710 QualType nonMemoryDestType = getNonMemoryType(cgm, destType);
711 if (mlir::Attribute c = ConstExprEmitter(*this).Visit(const_cast<Expr *>(e),
712 nonMemoryDestType))
713 return emitForMemory(c, destType);
714 }
715
716 // Try to emit the initializer. Note that this can allow some things that
717 // are not allowed by tryEmitPrivateForMemory alone.
718 if (APValue *value = d.evaluateValue())
719 return tryEmitPrivateForMemory(*value, destType);
720
721 return {};
722}
723
725 if (!ce->hasAPValueResult())
726 return {};
727
728 QualType retType = ce->getType();
729 if (ce->isGLValue())
730 retType = cgm.getASTContext().getLValueReferenceType(retType);
731
732 return emitAbstract(ce->getBeginLoc(), ce->getAPValueResult(), retType);
733}
734
736 QualType destType) {
737 QualType nonMemoryDestType = getNonMemoryType(cgm, destType);
738 mlir::Attribute c = tryEmitPrivate(value, nonMemoryDestType);
739 return (c ? emitForMemory(c, destType) : nullptr);
740}
741
742mlir::Attribute ConstantEmitter::emitAbstract(const Expr *e,
743 QualType destType) {
744 AbstractStateRAII state{*this, true};
745 mlir::Attribute c = mlir::cast<mlir::Attribute>(tryEmitPrivate(e, destType));
746 if (!c)
748 "emitAbstract failed, emit null constaant");
749 return c;
750}
751
753 const APValue &value,
754 QualType destType) {
755 AbstractStateRAII state(*this, true);
756 mlir::Attribute c = tryEmitPrivate(value, destType);
757 if (!c)
758 cgm.errorNYI(loc, "emitAbstract failed, emit null constaant");
759 return c;
760}
761
762mlir::Attribute ConstantEmitter::emitForMemory(mlir::Attribute c,
763 QualType destType) {
764 // For an _Atomic-qualified constant, we may need to add tail padding.
765 if (destType->getAs<AtomicType>()) {
766 cgm.errorNYI("emitForMemory: atomic type");
767 return {};
768 }
769
770 return c;
771}
772
773mlir::TypedAttr ConstantEmitter::tryEmitPrivate(const Expr *e,
774 QualType destType) {
775 assert(!destType->isVoidType() && "can't emit a void constant");
776
777 if (mlir::Attribute c =
778 ConstExprEmitter(*this).Visit(const_cast<Expr *>(e), destType))
779 return llvm::dyn_cast<mlir::TypedAttr>(c);
780
781 Expr::EvalResult result;
782
783 bool success = false;
784
785 if (destType->isReferenceType())
786 success = e->EvaluateAsLValue(result, cgm.getASTContext());
787 else
788 success =
789 e->EvaluateAsRValue(result, cgm.getASTContext(), inConstantContext);
790
791 if (success && !result.hasSideEffects()) {
792 mlir::Attribute c = tryEmitPrivate(result.Val, destType);
793 return llvm::dyn_cast<mlir::TypedAttr>(c);
794 }
795
796 return nullptr;
797}
798
799mlir::Attribute ConstantEmitter::tryEmitPrivate(const APValue &value,
800 QualType destType) {
801 auto &builder = cgm.getBuilder();
802 switch (value.getKind()) {
803 case APValue::None:
805 cgm.errorNYI("ConstExprEmitter::tryEmitPrivate none or indeterminate");
806 return {};
807 case APValue::Int: {
808 mlir::Type ty = cgm.convertType(destType);
809 if (mlir::isa<cir::BoolType>(ty))
810 return builder.getCIRBoolAttr(value.getInt().getZExtValue());
811 assert(mlir::isa<cir::IntType>(ty) && "expected integral type");
812 return cir::IntAttr::get(ty, value.getInt());
813 }
814 case APValue::Float: {
815 const llvm::APFloat &init = value.getFloat();
816 if (&init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
817 !cgm.getASTContext().getLangOpts().NativeHalfType &&
819 cgm.errorNYI("ConstExprEmitter::tryEmitPrivate half");
820 return {};
821 }
822
823 mlir::Type ty = cgm.convertType(destType);
824 assert(mlir::isa<cir::FPTypeInterface>(ty) &&
825 "expected floating-point type");
826 return cir::FPAttr::get(ty, init);
827 }
828 case APValue::Array: {
829 const ArrayType *arrayTy = cgm.getASTContext().getAsArrayType(destType);
830 const QualType arrayElementTy = arrayTy->getElementType();
831 const unsigned numElements = value.getArraySize();
832 const unsigned numInitElts = value.getArrayInitializedElts();
833
834 mlir::Attribute filler;
835 if (value.hasArrayFiller()) {
836 filler = tryEmitPrivate(value.getArrayFiller(), arrayElementTy);
837 if (!filler)
838 return {};
839 }
840
842 if (filler && builder.isNullValue(filler))
843 elements.reserve(numInitElts + 1);
844 else
845 elements.reserve(numInitElts);
846
847 mlir::Type commonElementType;
848 for (unsigned i = 0; i < numInitElts; ++i) {
849 const APValue &arrayElement = value.getArrayInitializedElt(i);
850 const mlir::Attribute element =
851 tryEmitPrivateForMemory(arrayElement, arrayElementTy);
852 if (!element)
853 return {};
854
855 const mlir::TypedAttr elementTyped = mlir::cast<mlir::TypedAttr>(element);
856 if (i == 0)
857 commonElementType = elementTyped.getType();
858 else if (elementTyped.getType() != commonElementType) {
859 commonElementType = {};
860 }
861
862 elements.push_back(elementTyped);
863 }
864
865 mlir::TypedAttr typedFiller = llvm::cast_or_null<mlir::TypedAttr>(filler);
866 if (filler && !typedFiller)
867 cgm.errorNYI("array filler should always be typed");
868
869 mlir::Type desiredType = cgm.convertType(destType);
870 return emitArrayConstant(cgm, desiredType, commonElementType, numElements,
871 elements, typedFiller);
872 }
873 case APValue::Vector: {
874 const QualType elementType =
875 destType->castAs<VectorType>()->getElementType();
876 const unsigned numElements = value.getVectorLength();
877
879 elements.reserve(numElements);
880
881 for (unsigned i = 0; i < numElements; ++i) {
882 const mlir::Attribute element =
883 tryEmitPrivateForMemory(value.getVectorElt(i), elementType);
884 if (!element)
885 return {};
886 elements.push_back(element);
887 }
888
889 const auto desiredVecTy =
890 mlir::cast<cir::VectorType>(cgm.convertType(destType));
891
892 return cir::ConstVectorAttr::get(
893 desiredVecTy,
894 mlir::ArrayAttr::get(cgm.getBuilder().getContext(), elements));
895 }
897 cgm.errorNYI("ConstExprEmitter::tryEmitPrivate member pointer");
898 return {};
899 }
900 case APValue::LValue:
901 return ConstantLValueEmitter(*this, value, destType).tryEmit();
902 case APValue::Struct:
903 case APValue::Union:
904 cgm.errorNYI("ConstExprEmitter::tryEmitPrivate struct or union");
905 return {};
908 mlir::Type desiredType = cgm.convertType(destType);
909 cir::ComplexType complexType =
910 mlir::dyn_cast<cir::ComplexType>(desiredType);
911
912 mlir::Type complexElemTy = complexType.getElementType();
913 if (isa<cir::IntType>(complexElemTy)) {
914 llvm::APSInt real = value.getComplexIntReal();
915 llvm::APSInt imag = value.getComplexIntImag();
916 return builder.getAttr<cir::ConstComplexAttr>(
917 complexType, cir::IntAttr::get(complexElemTy, real),
918 cir::IntAttr::get(complexElemTy, imag));
919 }
920
921 assert(isa<cir::FPTypeInterface>(complexElemTy) &&
922 "expected floating-point type");
923 llvm::APFloat real = value.getComplexFloatReal();
924 llvm::APFloat imag = value.getComplexFloatImag();
925 return builder.getAttr<cir::ConstComplexAttr>(
926 complexType, cir::FPAttr::get(complexElemTy, real),
927 cir::FPAttr::get(complexElemTy, imag));
928 }
932 "ConstExprEmitter::tryEmitPrivate fixed point, addr label diff");
933 return {};
934 }
935 llvm_unreachable("Unknown APValue kind");
936}
937
938mlir::Value CIRGenModule::emitNullConstant(QualType t, mlir::Location loc) {
939 if (t->getAs<PointerType>()) {
940 return builder.getNullPtr(getTypes().convertTypeForMem(t), loc);
941 }
942
943 if (getTypes().isZeroInitializable(t))
944 return builder.getNullValue(getTypes().convertTypeForMem(t), loc);
945
946 if (getASTContext().getAsConstantArrayType(t)) {
947 errorNYI("CIRGenModule::emitNullConstant ConstantArrayType");
948 }
949
950 if (t->isRecordType())
951 errorNYI("CIRGenModule::emitNullConstant RecordType");
952
953 assert(t->isMemberDataPointerType() &&
954 "Should only see pointers to data members here!");
955
956 errorNYI("CIRGenModule::emitNullConstant unsupported type");
957 return {};
958}
Defines the clang::ASTContext interface.
Defines enum values for all the target-independent builtin functions.
static mlir::Attribute emitArrayConstant(CIRGenModule &cgm, mlir::Type desiredType, mlir::Type commonElementType, unsigned arrayBound, SmallVectorImpl< mlir::TypedAttr > &elements, mlir::TypedAttr filler)
static QualType getNonMemoryType(CIRGenModule &cgm, QualType type)
Expr * E
Defines various enumerations that describe declaration and type specifiers.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
mlir::Attribute VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe, QualType t)
mlir::Attribute VisitCXXConstructExpr(CXXConstructExpr *e, QualType ty)
mlir::Attribute VisitInitListExpr(InitListExpr *ile, QualType t)
mlir::Attribute VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die, QualType t)
mlir::Attribute VisitCastExpr(CastExpr *e, QualType destType)
mlir::Attribute VisitExprWithCleanups(ExprWithCleanups *e, QualType t)
mlir::Attribute VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e, QualType destType)
mlir::Attribute VisitUnaryExtension(const UnaryOperator *e, QualType t)
mlir::Attribute VisitStringLiteral(StringLiteral *e, QualType t)
mlir::Attribute VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e, QualType t)
mlir::Attribute VisitParenExpr(ParenExpr *pe, QualType t)
mlir::Attribute VisitImplicitValueInitExpr(ImplicitValueInitExpr *E, QualType T)
mlir::Attribute VisitConstantExpr(ConstantExpr *ce, QualType t)
mlir::Attribute VisitChooseExpr(ChooseExpr *ce, QualType t)
ConstExprEmitter(ConstantEmitter &emitter)
mlir::Attribute VisitGenericSelectionExpr(GenericSelectionExpr *ge, QualType t)
mlir::Attribute VisitCompoundLiteralExpr(CompoundLiteralExpr *e, QualType t)
mlir::Attribute VisitStmt(Stmt *S, QualType T)
mlir::Type convertType(QualType t)
mlir::Attribute VisitObjCEncodeExpr(ObjCEncodeExpr *e, QualType t)
cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc)
cir::BoolAttr getCIRBoolAttr(bool state)
cir::PointerType getPointerTo(mlir::Type ty)
mlir::TypedAttr getConstPtrAttr(mlir::Type type, int64_t value)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
bool hasArrayFiller() const
Definition: APValue.h:584
const LValueBase getLValueBase() const
Definition: APValue.cpp:983
APValue & getArrayInitializedElt(unsigned I)
Definition: APValue.h:576
APSInt & getInt()
Definition: APValue.h:489
APSInt & getComplexIntImag()
Definition: APValue.h:527
ValueKind getKind() const
Definition: APValue.h:461
unsigned getArrayInitializedElts() const
Definition: APValue.h:595
CharUnits & getLValueOffset()
Definition: APValue.cpp:993
APValue & getVectorElt(unsigned I)
Definition: APValue.h:563
APValue & getArrayFiller()
Definition: APValue.h:587
unsigned getVectorLength() const
Definition: APValue.h:571
unsigned getArraySize() const
Definition: APValue.h:599
@ Indeterminate
This object has an indeterminate value (C++ [basic.indet]).
Definition: APValue.h:131
@ None
There is no such object (it's outside its lifetime).
Definition: APValue.h:129
APSInt & getComplexIntReal()
Definition: APValue.h:519
APFloat & getComplexFloatImag()
Definition: APValue.h:543
APFloat & getComplexFloatReal()
Definition: APValue.h:535
APFloat & getFloat()
Definition: APValue.h:503
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
const LangOptions & getLangOpts() const
Definition: ASTContext.h:894
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2442
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:859
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition: Expr.h:4486
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: TypeBase.h:3738
QualType getElementType() const
Definition: TypeBase.h:3750
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6560
cir::ConstRecordAttr getAnonConstRecord(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type ty={})
Definition: CIRGenBuilder.h:63
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
bool isNullValue(mlir::Attribute attr) const
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
This class organizes the cross-function state that is used while generating CIR code.
Definition: CIRGenModule.h:56
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)
CIRGenBuilderTy & getBuilder()
Definition: CIRGenModule.h:101
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
mlir::Value emitNullConstant(QualType t, mlir::Location loc)
Return the result of value-initializing the given type, i.e.
mlir::ModuleOp getModule() const
Definition: CIRGenModule.h:100
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
bool isZeroInitializable(clang::QualType ty)
Return whether a type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
mlir::Attribute emitForMemory(mlir::Attribute c, QualType destType)
mlir::TypedAttr tryEmitPrivate(const Expr *e, QualType destType)
mlir::Attribute tryEmitPrivateForVarInit(const VarDecl &d)
mlir::Attribute emitAbstract(const Expr *e, QualType destType)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
mlir::Attribute tryEmitPrivateForMemory(const APValue &value, QualType t)
mlir::Attribute tryEmitForInitializer(const VarDecl &d)
Try to emit the initializer of the given declaration as an abstract constant.
mlir::Attribute tryEmitAbstractForInitializer(const VarDecl &d)
Try to emit the initializer of the given declaration as an abstract constant.
mlir::Attribute tryEmitConstantExpr(const ConstantExpr *ce)
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1549
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.cpp:575
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2604
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Definition: DeclCXX.cpp:2999
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1378
SourceLocation getBeginLoc() const
Definition: ExprCXX.h:1442
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition: ExprCXX.h:848
SourceRange getSourceRange() const LLVM_READONLY
Definition: ExprCXX.h:902
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3612
CastKind getCastKind() const
Definition: Expr.h:3656
Expr * getSubExpr()
Definition: Expr.h:3662
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4784
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition: Expr.h:4820
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3541
const Expr * getInitializer() const
Definition: Expr.h:3569
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:196
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1084
APValue getAPValueResult() const
Definition: Expr.cpp:409
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.h:1134
bool hasAPValueResult() const
Definition: Expr.h:1159
Expr * getBase() const
Definition: Expr.h:5869
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:4788
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3655
This represents one expression.
Definition: Expr.h:112
bool isGLValue() const
Definition: Expr.h:287
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
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...
QualType getType() const
Definition: Expr.h:144
const Expr * getSubExpr() const
Definition: Expr.h:1064
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2376
Represents a C11 generic selection.
Definition: Expr.h:6114
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition: Expr.h:6398
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5993
Describes an C or C++ initializer list.
Definition: Expr.h:5235
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
Definition: Expr.cpp:2457
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:2491
const Expr * getInit(unsigned Init) const
Definition: Expr.h:5289
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4914
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
Definition: ExprCXX.h:4931
ObjCBoxedExpr - used for generalized expression boxing.
Definition: ExprObjC.h:128
SourceRange getSourceRange() const LLVM_READONLY
Definition: ExprObjC.h:162
ObjCEncodeExpr, used for @encode in Objective-C.
Definition: ExprObjC.h:409
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprObjC.h:436
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition: ExprObjC.h:52
ParenExpr - This represents a parenthesized expression, e.g.
Definition: Expr.h:2184
const Expr * getSubExpr() const
Definition: Expr.h:2201
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
[C99 6.4.2.2] - A predefined identifier such as func.
Definition: Expr.h:2007
A (possibly-)qualified type.
Definition: TypeBase.h:937
Encodes a location in the source.
StmtVisitorBase - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:38
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Definition: StmtVisitor.h:45
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:186
Stmt - This represents one statement.
Definition: Stmt.h:85
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:346
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1801
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4658
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
Definition: TargetInfo.h:1015
Symbolic representation of typeid(T) for some type T.
Definition: APValue.h:44
bool isVoidType() const
Definition: TypeBase.h:8936
bool isArrayType() const
Definition: TypeBase.h:8679
CXXRecordDecl * castAsCXXRecordDecl() const
Definition: Type.h:36
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isReferenceType() const
Definition: TypeBase.h:8604
bool isMemberDataPointerType() const
Definition: TypeBase.h:8672
bool isVectorType() const
Definition: TypeBase.h:8719
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
bool isRecordType() const
Definition: TypeBase.h:8707
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2246
Expr * getSubExpr() const
Definition: Expr.h:2287
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:711
QualType getType() const
Definition: Decl.h:722
Represents a variable declaration or definition.
Definition: Decl.h:925
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
Definition: Decl.cpp:2575
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
Definition: Decl.cpp:2648
const Expr * getInit() const
Definition: Decl.h:1367
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1183
Represents a GCC generic vector type.
Definition: TypeBase.h:4191
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ComplexType > complexType
Matches C99 complex types.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
long int64_t
#define false
Definition: stdbool.h:26
static bool constEmitterArrayILE()
static bool constEmitterVectorILE()
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