27class AggExprEmitter :
public StmtVisitor<AggExprEmitter> {
38 void withReturnValueSlot(
const Expr *e,
39 llvm::function_ref<RValue(ReturnValueSlot)> fn);
41 AggValueSlot ensureSlot(mlir::Location loc, QualType t) {
42 if (!dest.isIgnored())
45 cgf.cgm.errorNYI(loc,
"Slot for ignored address");
50 AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest)
51 : cgf(cgf), dest(dest) {}
56 void emitAggLoadOfLValue(
const Expr *e);
58 void emitArrayInit(Address destPtr, cir::ArrayType arrayTy, QualType arrayQTy,
59 Expr *exprToVisit, ArrayRef<Expr *> args,
63 void emitFinalDestCopy(QualType
type,
const LValue &src);
65 void emitCopy(QualType
type,
const AggValueSlot &dest,
66 const AggValueSlot &src);
68 void emitInitializationToLValue(Expr *e, LValue lv);
70 void emitNullInitializationToLValue(mlir::Location loc, LValue lv);
72 void Visit(Expr *e) { StmtVisitor<AggExprEmitter>::Visit(e); }
74 void VisitArraySubscriptExpr(ArraySubscriptExpr *e) {
75 emitAggLoadOfLValue(e);
78 void VisitCallExpr(
const CallExpr *e);
79 void VisitStmtExpr(
const StmtExpr *e) {
80 CIRGenFunction::StmtExprEvaluation eval(cgf);
83 (void)cgf.emitCompoundStmt(*e->
getSubStmt(), &retAlloca, dest);
86 void VisitDeclRefExpr(DeclRefExpr *e) { emitAggLoadOfLValue(e); }
88 void VisitInitListExpr(InitListExpr *e);
89 void VisitCXXConstructExpr(
const CXXConstructExpr *e);
91 void visitCXXParenListOrInitListExpr(Expr *e, ArrayRef<Expr *> args,
92 FieldDecl *initializedFieldInUnion,
94 void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die) {
95 CIRGenFunction::CXXDefaultInitExprScope Scope(cgf, die);
98 void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *e) {
106 case CK_LValueToRValue:
111 "AggExprEmitter: volatile lvalue-to-rvalue cast");
114 case CK_UserDefinedConversion:
115 case CK_ConstructorConversion:
118 "Implicit cast types must be compatible");
123 std::string(
"AggExprEmitter: VisitCastExpr: ") +
128 void VisitStmt(Stmt *
s) {
129 cgf.cgm.errorNYI(
s->getSourceRange(),
130 std::string(
"AggExprEmitter::VisitStmt: ") +
131 s->getStmtClassName());
133 void VisitParenExpr(ParenExpr *pe) {
134 cgf.cgm.errorNYI(pe->
getSourceRange(),
"AggExprEmitter: VisitParenExpr");
136 void VisitGenericSelectionExpr(GenericSelectionExpr *ge) {
138 "AggExprEmitter: VisitGenericSelectionExpr");
140 void VisitCoawaitExpr(CoawaitExpr *e) {
141 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitCoawaitExpr");
143 void VisitCoyieldExpr(CoyieldExpr *e) {
144 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitCoyieldExpr");
146 void VisitUnaryCoawait(UnaryOperator *e) {
147 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitUnaryCoawait");
149 void VisitUnaryExtension(UnaryOperator *e) {
151 "AggExprEmitter: VisitUnaryExtension");
153 void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e) {
155 "AggExprEmitter: VisitSubstNonTypeTemplateParmExpr");
157 void VisitConstantExpr(ConstantExpr *e) {
158 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitConstantExpr");
160 void VisitMemberExpr(MemberExpr *e) {
161 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitMemberExpr");
163 void VisitUnaryDeref(UnaryOperator *e) {
164 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitUnaryDeref");
166 void VisitStringLiteral(StringLiteral *e) {
167 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitStringLiteral");
169 void VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
171 "AggExprEmitter: VisitCompoundLiteralExpr");
173 void VisitPredefinedExpr(
const PredefinedExpr *e) {
175 "AggExprEmitter: VisitPredefinedExpr");
177 void VisitBinaryOperator(
const BinaryOperator *e) {
179 "AggExprEmitter: VisitBinaryOperator");
181 void VisitPointerToDataMemberBinaryOperator(
const BinaryOperator *e) {
183 "AggExprEmitter: VisitPointerToDataMemberBinaryOperator");
185 void VisitBinAssign(
const BinaryOperator *e) {
186 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitBinAssign");
188 void VisitBinComma(
const BinaryOperator *e) {
189 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitBinComma");
191 void VisitBinCmp(
const BinaryOperator *e) {
192 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitBinCmp");
194 void VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *e) {
196 "AggExprEmitter: VisitCXXRewrittenBinaryOperator");
198 void VisitObjCMessageExpr(ObjCMessageExpr *e) {
200 "AggExprEmitter: VisitObjCMessageExpr");
202 void VisitObjCIVarRefExpr(ObjCIvarRefExpr *e) {
204 "AggExprEmitter: VisitObjCIVarRefExpr");
207 void VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e) {
209 "AggExprEmitter: VisitDesignatedInitUpdateExpr");
211 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *e) {
213 "AggExprEmitter: VisitAbstractConditionalOperator");
215 void VisitChooseExpr(
const ChooseExpr *e) {
216 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitChooseExpr");
218 void VisitCXXParenListInitExpr(CXXParenListInitExpr *e) {
220 "AggExprEmitter: VisitCXXParenListInitExpr");
222 void VisitArrayInitLoopExpr(
const ArrayInitLoopExpr *e,
223 llvm::Value *outerBegin =
nullptr) {
225 "AggExprEmitter: VisitArrayInitLoopExpr");
227 void VisitImplicitValueInitExpr(ImplicitValueInitExpr *e) {
229 "AggExprEmitter: VisitImplicitValueInitExpr");
231 void VisitNoInitExpr(NoInitExpr *e) {
232 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitNoInitExpr");
234 void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {
236 "AggExprEmitter: VisitCXXDefaultArgExpr");
238 void VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *e) {
240 "AggExprEmitter: VisitCXXInheritedCtorInitExpr");
243 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitLambdaExpr");
245 void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *e) {
247 "AggExprEmitter: VisitCXXStdInitializerListExpr");
250 void VisitExprWithCleanups(ExprWithCleanups *e) {
252 "AggExprEmitter: VisitExprWithCleanups");
254 void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {
256 "AggExprEmitter: VisitCXXScalarValueInitExpr");
258 void VisitCXXTypeidExpr(CXXTypeidExpr *e) {
259 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitCXXTypeidExpr");
261 void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *e) {
263 "AggExprEmitter: VisitMaterializeTemporaryExpr");
265 void VisitOpaqueValueExpr(OpaqueValueExpr *e) {
267 "AggExprEmitter: VisitOpaqueValueExpr");
270 void VisitPseudoObjectExpr(PseudoObjectExpr *e) {
272 "AggExprEmitter: VisitPseudoObjectExpr");
275 void VisitVAArgExpr(VAArgExpr *e) {
276 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitVAArgExpr");
279 void VisitCXXThrowExpr(
const CXXThrowExpr *e) {
280 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitCXXThrowExpr");
282 void VisitAtomicExpr(AtomicExpr *e) {
283 cgf.cgm.errorNYI(e->
getSourceRange(),
"AggExprEmitter: VisitAtomicExpr");
296 if (
auto *ile = dyn_cast<InitListExpr>(e)) {
297 if (ile->getNumInits())
302 if (
const auto *cons = dyn_cast_or_null<CXXConstructExpr>(e))
303 return cons->getConstructor()->isDefaultConstructor() &&
304 cons->getConstructor()->isTrivial();
311void AggExprEmitter::emitAggLoadOfLValue(
const Expr *e) {
317 emitFinalDestCopy(e->
getType(), lv);
320void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy,
321 QualType arrayQTy, Expr *e,
322 ArrayRef<Expr *> args, Expr *arrayFiller) {
326 const uint64_t numInitElements = args.size();
328 const QualType elementType =
332 cgf.
cgm.
errorNYI(loc,
"initialized array requires destruction");
338 const mlir::Type cirElementType = cgf.
convertType(elementType);
339 const cir::PointerType cirElementPtrType =
342 auto begin = cir::CastOp::create(builder, loc, cirElementPtrType,
343 cir::CastKind::array_to_ptrdecay,
346 const CharUnits elementSize =
348 const CharUnits elementAlign =
356 mlir::Value element = begin;
363 for (uint64_t i = 0; i != numInitElements; ++i) {
370 const Address address = Address(element, cirElementType, elementAlign);
371 const LValue elementLV = cgf.
makeAddrLValue(address, elementType);
372 emitInitializationToLValue(args[i], elementLV);
375 const uint64_t numArrayElements = arrayTy.getSize();
383 if (numInitElements != numArrayElements &&
384 !(dest.
isZeroed() && hasTrivialFiller &&
387 if (numInitElements) {
389 element = cir::PtrStrideOp::create(builder, loc, cirElementPtrType,
401 cir::ConstantOp numArrayElementsConst = builder.
getConstInt(
402 loc, mlir::cast<cir::IntType>(cgf.
PtrDiffTy), numArrayElements);
403 mlir::Value end = cir::PtrStrideOp::create(builder, loc, cirElementPtrType,
404 begin, numArrayElementsConst);
409 [&](mlir::OpBuilder &
b, mlir::Location loc) {
410 cir::LoadOp currentElement = builder.
createLoad(loc, tmpAddr);
412 cir::CmpOp cmp = cir::CmpOp::create(
413 builder, loc, boolTy, cir::CmpOpKind::ne, currentElement, end);
417 [&](mlir::OpBuilder &
b, mlir::Location loc) {
418 cir::LoadOp currentElement = builder.
createLoad(loc, tmpAddr);
424 Address(currentElement, cirElementType, elementAlign),
427 emitInitializationToLValue(arrayFiller, elementLV);
429 emitNullInitializationToLValue(loc, elementLV);
433 cgf.
cgm.
errorNYI(loc,
"update destructed array element for EH");
439 loc, mlir::cast<cir::IntType>(cgf.
PtrDiffTy), 1);
440 auto nextElement = cir::PtrStrideOp::create(
441 builder, loc, cirElementPtrType, currentElement, one);
450void AggExprEmitter::emitFinalDestCopy(QualType
type,
const LValue &src) {
465 emitCopy(
type, dest, srcAgg);
472void AggExprEmitter::emitCopy(QualType
type,
const AggValueSlot &dest,
473 const AggValueSlot &src) {
485void AggExprEmitter::emitInitializationToLValue(Expr *e, LValue lv) {
486 const QualType
type = lv.getType();
492 return emitNullInitializationToLValue(loc, lv);
498 if (
type->isReferenceType())
499 cgf.
cgm.
errorNYI(
"emitInitializationToLValue ReferenceType");
503 cgf.
cgm.
errorNYI(
"emitInitializationToLValue TEK_Complex");
521void AggExprEmitter::VisitCXXConstructExpr(
const CXXConstructExpr *e) {
526void AggExprEmitter::emitNullInitializationToLValue(mlir::Location loc,
528 const QualType
type = lv.getType();
543 cgf.
cgm.
errorNYI(
"emitStoreThroughBitfieldLValue");
553void AggExprEmitter::VisitCallExpr(
const CallExpr *e) {
560 e, [&](ReturnValueSlot slot) {
return cgf.
emitCallExpr(e, slot); });
563void AggExprEmitter::withReturnValueSlot(
564 const Expr *e, llvm::function_ref<RValue(ReturnValueSlot)> fn) {
568 bool requiresDestruction =
570 if (requiresDestruction)
573 "withReturnValueSlot: return value requiring destruction is NYI");
588 fn(ReturnValueSlot(retAddr));
591void AggExprEmitter::VisitInitListExpr(InitListExpr *e) {
593 llvm_unreachable(
"GNU array range designator extension");
598 visitCXXParenListOrInitListExpr(
602void AggExprEmitter::visitCXXParenListOrInitListExpr(
603 Expr *e, ArrayRef<Expr *> args, FieldDecl *initializedFieldInUnion,
606 const AggValueSlot dest =
610 cir::ArrayType arrayTy =
617 "visitCXXParenListOrInitListExpr variable array type");
623 "visitCXXParenListOrInitListExpr array type");
633 unsigned numInitElements = args.size();
640 unsigned curInitIndex = 0;
643 if (
auto *cxxrd = dyn_cast<CXXRecordDecl>(record)) {
644 assert(numInitElements >= cxxrd->getNumBases() &&
645 "missing initializer for base class");
646 if (cxxrd->getNumBases() > 0) {
648 "visitCXXParenListOrInitListExpr base class init");
655 if (record->isUnion()) {
657 "visitCXXParenListOrInitListExpr union type");
663 for (
const FieldDecl *field : record->fields()) {
665 if (field->getType()->isIncompleteArrayType())
669 if (field->isUnnamedBitField())
675 if (curInitIndex == numInitElements && dest.
isZeroed() &&
683 if (curInitIndex < numInitElements) {
685 CIRGenFunction::SourceLocRAIIObject loc{
686 cgf, cgf.
getLoc(record->getSourceRange())};
687 emitInitializationToLValue(args[curInitIndex++], lv);
696 if (field->getType().isDestructedType()) {
698 "visitCXXParenListOrInitListExpr destructor");
722 getContext().getASTRecordLayout(baseRD).getSize() <=
731 AggExprEmitter(*
this, slot).Visit(
const_cast<Expr *
>(e));
745 assert((record->hasTrivialCopyConstructor() ||
746 record->hasTrivialCopyAssignment() ||
747 record->hasTrivialMoveConstructor() ||
748 record->hasTrivialMoveAssignment() ||
749 record->hasAttr<TrivialABIAttr>() || record->isUnion()) &&
750 "Trying to aggregate-copy a type without a trivial copy/move "
751 "constructor or assignment operator");
753 if (record->isEmpty())
776 typeInfo =
getContext().getTypeInfoDataSizeInChars(ty);
778 typeInfo =
getContext().getTypeInfoInChars(ty);
788 cgm.errorNYI(
"emitAggregateCopy: GC");
790 [[maybe_unused]] cir::CopyOp copyOp =
static bool isTrivialFiller(Expr *e)
__device__ __2f16 float __ockl_bool s
cir::ConditionOp createCondition(mlir::Value condition)
Create a loop condition.
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)
cir::PointerType getPointerTo(mlir::Type ty)
cir::DoWhileOp createDoWhile(mlir::Location loc, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> condBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> bodyBuilder)
Create a do-while operation.
cir::ConstantOp getConstantInt(mlir::Location loc, mlir::Type ty, int64_t value)
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
QualType getElementType() const
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
IsZeroed_t isZeroed() const
Overlap_t mayOverlap() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Address getAddress() const
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
static bool hasScalarEvaluationKind(clang::QualType type)
mlir::Type convertType(clang::QualType t)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
CIRGenTypes & getTypes() const
const clang::LangOptions & getLangOpts() const
cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, bool insertIntoFnEntryBlock=false)
This creates an alloca and inserts it into the entry block if ArraySize is nullptr,...
RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, bool isInit=false, bool isNontemporal=false)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
void emitNullInitialization(mlir::Location loc, Address destPtr, QualType ty)
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *fd)
void emitCXXConstructExpr(const clang::CXXConstructExpr *e, AggValueSlot dest)
LValue emitAggExprToLValue(const Expr *e)
static bool hasAggregateEvaluationKind(clang::QualType type)
void emitScalarInit(const clang::Expr *init, mlir::Location loc, LValue lvalue, bool capturedByInit=false)
LValue emitLValueForFieldInitialization(LValue base, const clang::FieldDecl *field, llvm::StringRef fieldName)
Like emitLValueForField, excpet that if the Field is a reference, this will return the address of the...
mlir::Value emitScalarExpr(const clang::Expr *e)
Emit the computation of the specified expression of scalar type.
CIRGenBuilderTy & getBuilder()
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *rd, const CXXRecordDecl *baseRD, bool isVirtual)
Determine whether a base class initialization may overlap some other object.
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, AggValueSlot::Overlap_t mayOverlap)
Emit an aggregate copy.
void emitStoreThroughLValue(RValue src, LValue dst, bool isInit=false)
Store the specified rvalue into the specified lvalue, where both are guaranteed to the have the same ...
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
const clang::LangOptions & getLangOpts() const
mlir::Value emitNullConstant(QualType t, mlir::Location loc)
Return the result of value-initializing the given type, i.e.
bool isZeroInitializable(clang::QualType ty)
Return whether a type can be zero-initialized (in the C++ sense) with an LLVM zeroinitializer.
Address getAddress() const
static RValue get(mlir::Value v)
const Expr * getSubExpr() const
Expr * getExpr()
Get the initialization expression that will be used.
SourceRange getSourceRange() const LLVM_READONLY
Represents a C++ struct/union/class.
SourceRange getSourceRange() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range of the expression.
SourceRange getSourceRange() const LLVM_READONLY
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastKind getCastKind() const
static const char * getCastKindName(CastKind CK)
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
This represents one expression.
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
FieldDecl * getInitializedFieldInUnion()
If this initializes a union, specifies which field in the union to initialize.
bool hadArrayRangeDesignator() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
Represents a struct/union/class.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
bool isReferenceType() const
bool isVariableArrayType() const
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isRecordType() const
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
U cast(CodeGen::Address addr)
static bool emitLifetimeMarkers()
static bool aggValueSlotDestructedFlag()
static bool aggValueSlotGC()
static bool aggValueSlotAlias()
static bool opLoadStoreAtomic()
static bool aggEmitFinalDestCopyRValue()
static bool aggValueSlotVolatile()
static bool cudaSupport()
static bool requiresCleanups()
clang::CharUnits getPointerAlign() const