33 return !
T->isDependentType() && !
T->isUndeducedAutoType() &&
34 !
T->isSpecificBuiltinType(BuiltinType::UnknownAny) &&
35 !
T->isIncompleteType();
39 :
Pointer(Pointee, Pointee->getMetadataSize(), Pointee->getMetadataSize()) {
43 :
Pointer(Pointee, BaseAndOffset, BaseAndOffset) {}
48 assert(
Base %
alignof(
void *) == 0 &&
"wrong base");
51 BS = {Pointee,
Base,
nullptr,
nullptr};
52 Pointee->addPointer(
this);
56 : Offset(P.Offset), StorageKind(P.StorageKind) {
57 switch (StorageKind) {
64 BS.Pointee->addPointer(
this);
82 switch (StorageKind) {
89 BS.Pointee->replacePointer(&P,
this);
110 if (
Block *Pointee =
BS.Pointee) {
111 Pointee->removePointer(
this);
112 BS.Pointee =
nullptr;
127 if (
Block *Pointee =
BS.Pointee) {
128 Pointee->removePointer(
this);
129 BS.Pointee =
nullptr;
134 StorageKind = P.StorageKind;
137 switch (StorageKind) {
145 BS.Pointee->addPointer(
this);
167 if (P.isBlockPointer() && this->block() == P.block()) {
173 if (
Block *Pointee =
BS.Pointee) {
174 Pointee->removePointer(
this);
175 BS.Pointee =
nullptr;
180 StorageKind = P.StorageKind;
183 switch (StorageKind) {
191 BS.Pointee->addPointer(
this);
210 if (StorageKind != P.StorageKind)
213 switch (StorageKind) {
220 return P.
Fn.
Func ==
Fn.Func && P.Offset == Offset;
222 llvm_unreachable(
"typeid in operator==?");
224 return Str.Base == P.
Str.
Base && Offset == P.Offset;
230 for (
unsigned I = 0; I !=
Opaque.PathLength; ++I) {
233 switch (
Opaque.Path[I].Kind) {
259 switch (StorageKind) {
285 if (Offset != 0 ||
Str.Decayed)
293 bool ValidBase =
Opaque.hasValidBase() || this->Offset <= 1;
295 size_t LayoutOffset =
Opaque.computeLayoutOffset(ASTCtx).value_or(0);
313 switch (Entry.Kind) {
319 {Entry.RD.getPointer(), Entry.RD.getInt()}));
336 Result.setConstexprUnknown(
Opaque.isConstexprUnknown());
347 else if (
const auto *E = Desc->
asExpr()) {
356 llvm_unreachable(
"Invalid allocation type");
366 unsigned FieldIndex = FD->getFieldIndex();
375 while (Ptr.isField() || Ptr.isArrayElement()) {
377 if (Ptr.isArrayRoot()) {
379 if (Ptr.isArrayElement()) {
382 unsigned Index = Ptr.getIndex();
385 if (Ptr.getArray().getFieldDesc()->IsArray)
387 Ptr = Ptr.getArray();
390 const auto *Dcl = Desc->
asDecl();
393 if (
const auto *FD = dyn_cast_if_present<FieldDecl>(Dcl)) {
395 Offset += *FieldOffset;
402 }
else if (Ptr.isArrayElement()) {
406 if (Ptr.isOnePastEnd()) {
407 Index = Ptr.getArray().getNumElems();
410 Index = Ptr.getIndex();
419 if (Ptr.getArray().getFieldDesc()->IsArray)
421 Ptr = Ptr.getArray();
426 if (
const auto *BaseOrMember = Desc->
asDecl()) {
427 bool IsVirtual =
false;
428 if (
const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
431 Offset += *FieldOffset;
434 }
else if (
const auto *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
435 IsVirtual = Ptr.isVirtualBaseClass();
437 const Record *BaseRecord = Ptr.getRecord();
455 llvm_unreachable(
"Invalid field type");
463 std::reverse(Path.begin(), Path.end());
471 switch (StorageKind) {
474 OS <<
"(Block) " << B <<
" {";
477 OS <<
"rootptr(" <<
BS.Base <<
"), ";
479 OS <<
BS.Base <<
", ";
484 OS << Offset <<
", ";
493 OS <<
"(Int) {" <<
Int.Value <<
" + " << Offset <<
", " <<
Int.getType()
494 <<
", " << (
Int.isNull() ?
"null" :
"nonnull") <<
'}';
497 OS <<
"(Fn) { " <<
Fn.Func <<
" + " << Offset <<
" }";
505 OS <<
"(String) { " << (
const void *)
Str.getLiteral() <<
' ';
506 Str.getLiteral()->outputString(OS);
507 OS <<
". ID: " <<
Str.ID <<
" + " << Offset <<
"}";
510 OS <<
"(Opaque) { Base: " <<
Opaque.Base <<
", "
511 <<
Opaque.FieldType.getPointer() <<
" Length: " <<
Opaque.PathLength
512 <<
". PastEnd: " <<
Opaque.isOnePastEnd();
513 OS <<
"} + " << Offset;
529 switch (StorageKind) {
531 return Int.Value + Offset;
540 return reinterpret_cast<uintptr_t>(
Str.getLiteral()) + Offset;
545 auto getTypeSize = [&](
QualType T) -> std::optional<size_t> {
555 Result += getInlineDesc()->Offset;
610 switch (StorageKind) {
612 return Int.Value + Offset;
621 return Offset *
Str.getLiteral()->getCharByteWidth();
623 if (
auto O =
Opaque.computeLayoutOffset(ASTCtx)) {
627 return *O + (Offset * TypeSize);
632 auto getTypeSize = [&](
QualType T) -> std::optional<size_t> {
639 if (
const Record *R = P.getRecord())
644 auto getRecordSize = [&](
const RecordDecl *RD) ->
unsigned {
664 Result += getRecordSize(RD);
673 if (std::optional<size_t> ElemSize =
685 if (std::optional<size_t> Size =
704 if (std::optional<size_t> Size = getTypeSize(F->
getType()))
813 if (LLVM_UNLIKELY(!
Pointee->isInitialized()))
831 assert(
Base != 0 &&
"Only composite fields can be initialised");
846 if (LLVM_UNLIKELY(!
Pointee->isInitialized()))
867 getInitMap().noteAllInitialized();
905 assert(
Base != 0 &&
"Only composite fields can be activated");
917 for (
const Record::Field &F : R->fields()) {
927 deactivate = [&deactivate](
PtrView &P) ->
void {
931 for (
const Record::Field &F : R->fields()) {
934 deactivate(FieldPtr);
954 for (
const Record::Field &F : BR->fields()) {
957 deactivate(FieldPtr);
970 if (A.StorageKind != B.StorageKind) {
986 switch (A.StorageKind) {
1006 llvm_unreachable(
"should have been handled by the fully covered switch");
1030 if (P.isArrayRoot())
1034 if (
V.isArrayElement() ||
V.isOnePastEnd())
1035 V =
V.expand().getArray();
1040 while (!
V.isRoot() && !
V.getFieldDesc()->IsArray) {
1041 if (
V.isArrayElement()) {
1042 V =
V.expand().getArray();
1050 if (closestArray(A) != closestArray(B))
1073 return isa_and_nonnull<AddrLabelExpr>(
Opaque.Base.asExpr());
1077std::optional<std::pair<PtrView, PtrView>>
1080 return std::nullopt;
1083 return std::nullopt;
1085 return std::nullopt;
1088 return std::make_pair(A.
view(), B.
view());
1091 if (P.isArrayElement())
1092 return P.expand().getArray();
1109 if (IterA == IterB) {
1113 return std::nullopt;
1114 return std::make_pair(CurA, CurB);
1118 return std::nullopt;
1121 llvm_unreachable(
"The loop above should've returned.");
1128 Ty = AT->getValueType();
1131 if (!Ptr.isLive() || Ptr.isPastEnd())
1136 const Descriptor *FieldDesc = Ptr.getFieldDesc();
1142 const auto *
Record = Ptr.getRecord();
1143 assert(
Record &&
"Missing record descriptor");
1146 if (RT->getDecl()->isUnion()) {
1150 PtrView FP = Ptr.atField(F.Offset);
1157 QualType FieldTy = F.Decl->getType();
1172 for (
unsigned I = 0; I != NF; ++I) {
1175 PtrView FP = Ptr.atField(FD->Offset);
1181 QualType FieldTy = FD->Decl->getType();
1186 for (
unsigned I = 0; I != NB; ++I) {
1189 PtrView BP = Ptr.atField(BD->Offset);
1190 Ok &=
toRValue(Ctx, BaseTy, BP, R.getStructBase(I));
1193 for (
unsigned I = 0; I != NV; ++I) {
1197 PtrView VP = Ptr.atField(VD->Offset);
1198 Ok &=
toRValue(Ctx, VirtBaseTy, VP, R.getStructVirtualBase(I));
1212 const size_t NumElems = Ptr.getNumElems();
1213 QualType ElemTy = AT->getElementType();
1218 for (
unsigned I = 0; I != NumElems; ++I) {
1219 APValue &Slot = R.getArrayInitializedElt(I);
1221 TYPE_SWITCH(*ElemT, Slot = Ptr.elem<
T>(I).toAPValue(ASTCtx));
1223 Ok &=
toRValue(Ctx, ElemTy, Ptr.atIndex(I).narrow(), Slot);
1238 auto V1 = Ptr.elem<
T>(0);
1239 auto V2 = Ptr.elem<
T>(1);
1240 R =
APValue(V1.toAPSInt(), V2.toAPSInt());
1258 Values.reserve(VT->getNumElements());
1259 for (
unsigned I = 0; I != VT->getNumElements(); ++I) {
1261 { Values.push_back(Ptr.elem<
T>(I).toAPValue(ASTCtx)); });
1264 assert(Values.size() == VT->getNumElements());
1265 R =
APValue(Values.data(), Values.size());
1274 unsigned NumElems = MT->getNumElementsFlattened();
1277 Values.reserve(NumElems);
1278 for (
unsigned I = 0; I != NumElems; ++I) {
1280 { Values.push_back(Ptr.elem<
T>(I).toAPValue(ASTCtx)); });
1283 R =
APValue(Values.data(), MT->getNumRows(), MT->getNumColumns());
1287 llvm_unreachable(
"invalid value to return");
1293 assert(!ResultType.
isNull());
1297 return std::nullopt;
1302 return std::nullopt;
1311 return std::nullopt;
1316 return std::nullopt;
1321 return std::nullopt;
1333 return Opaque.getBaseDecl();
1341 return Str.getLiteral();
1343 return Opaque.getBaseExpr();
1348 unsigned Offset)
const {
1351 return std::nullopt;
1357 const Record::Field *F = R->findField(Offset);
1363 return std::nullopt;
1368 uint64_t FieldOffset =
1372 uint64_t NewValue = this->
Value + FieldOffset;
1377 unsigned BaseOffset)
const {
1393 const Record::Base *B = R->findBase(BaseOffset);
1406 std::nullopt, RD,
false);
1408 return {{
T.getTypePtr(), NewValue == 0}, NewValue};
1411std::optional<size_t>
1416 switch (Entry.Kind) {
1420 return std::nullopt;
1424 return std::nullopt;
1427 if (Entry.RD.getInt())
1439 return std::nullopt;
1451 uint64_t Index = Entry.Index;
1463 return std::nullopt;
1487 switch (Entry.Kind) {
1489 CurType = Entry.RD.getPointer()->getASTContext().getCanonicalTagType(
1490 Entry.RD.getPointer());
1493 CurType = Entry.FD->getType();
1510 switch (Entry.Kind) {
1512 if (Entry.RD.getInt())
1514 CurType = Entry.RD.getPointer()->getASTContext().getCanonicalTagType(
1515 Entry.RD.getPointer());
1518 if (!Entry.FD->getParent()->isUnion() && Entry.FD->getFieldIndex() != 0)
1520 CurType = Entry.FD->getType();
1523 if (Entry.Index != 0)
1548 if (!
Base || !
Base->getType()->isRecordType() || !
Base->hasInit())
1578 if (
const auto *CAT =
1589 return !VD->hasExternalStorage();
1591 return !
Base.getType()->isPointerType();
Defines the clang::Expr interface and subclasses for C++ expressions.
static bool validType(QualType T)
static bool validType(QualType T)
static bool toRValue(const Context &Ctx, QualType Ty, PtrView Ptr, APValue &R)
Convert a pointer to a composite value to an rvalue.
#define INT_TYPE_SWITCH(Expr, B)
#define TYPE_SWITCH(Expr, B)
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
static const RecordDecl * getRecordDecl(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo)
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type)
A non-discriminated union of a base, field, or array index.
static LValuePathEntry ArrayIndex(uint64_t Index)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
std::string getAsString(const ASTContext &Ctx, QualType Ty) const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getTagType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TagDecl *TD, bool OwnsTag) const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
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 getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a C++ struct/union/class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Construct a CharUnits quantity of zero.
Represents a concrete matrix type with constant number of rows and columns.
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
Symbolic representation of a dynamic allocation.
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.
Represents a function declaration or definition.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Represents a struct/union/class.
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
Symbolic representation of typeid(T) for some type T.
bool isIncompleteArrayType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isLValueReferenceType() const
bool isAnyComplexType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isFunctionType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Represents a GCC generic vector type.
unsigned getSize() const
Returns the size of the block, including metadata.
const Descriptor * getDescriptor() const
Returns the block's descriptor.
unsigned getMetadataSize() const
Returns the size of the metadata.
Holds all information required to evaluate constexpr code in a module.
const Record * getRecord(const RecordDecl *D) const
ASTContext & getASTContext() const
Returns the AST context.
OptPrimType classify(QualType T) const
Classifies a type.
bool canClassify(QualType T) const
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
APFloat getAPFloat() const
const BlockExpr * getExpr() const
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
static bool hasSameBase(const Pointer &A, const Pointer &B)
Checks if two pointers are comparable.
const Expr * getRootExpr() const
bool pointsToLabel() const
Whether this points to a block created for an AddrLabelExpr.
bool isStatic() const
Checks if the storage is static.
bool isDynamic() const
Checks if the storage has been dynamically allocated.
const VarDecl * getRootVarDecl() const
bool isZeroSizeArray() const
Checks if the pointer is pointing to a zero-size array.
bool isDummy() const
Checks if the pointer points to a dummy value.
void print(llvm::raw_ostream &OS) const
Prints the pointer.
bool isOpaquePointer() const
bool isStringPointer() const
bool canDeref(PrimType T) const
Checks whether the pointer can be dereferenced to the given PrimType.
bool operator==(const Pointer &P) const
const TypeidPointer & asTypeidPointer() const
bool isIntegralPointer() const
QualType getType() const
Returns the type of the innermost field.
void initializeAllElements() const
Initialize all elements of a primitive array at once.
std::optional< size_t > computeOffsetForComparison(const ASTContext &ASTCtx) const
Compute an integer that can be used to compare this pointer to another one.
bool isArrayRoot() const
Whether this array refers to an array, but not to the first element.
bool isLive() const
Checks if the pointer is live.
static bool elemsOfSameArray(const Pointer &A, const Pointer &B)
Checks if two pointers can be subtracted.
bool isElementAlive(unsigned Index) const
bool pointsToLiteral() const
Whether this points to a block that's been created for a "literal lvalue", i.e.
std::optional< size_t > computeLayoutOffset(const ASTContext &ASTCtx) const
Compute the pointer offset as given by the ASTRecordLayout.
bool allElementsAlive() const
Pointer getBase() const
Returns a pointer to the object of which this pointer is a field.
std::string toDiagnosticString(const ASTContext &Ctx) const
Converts the pointer to a string usable in diagnostics.
bool isZero() const
Checks if the pointer is null.
Pointer & operator=(const Pointer &P)
bool isConstexprUnknown() const
const IntPointer & asIntPointer() const
bool isRoot() const
Pointer points directly to a block.
const Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
const ValueDecl * getRootValueDecl() const
static bool pointToSameBlock(const Pointer &A, const Pointer &B)
Checks if both given pointers point to the same block.
APValue toAPValue(const ASTContext &ASTCtx) const
Converts the pointer to an APValue.
bool isOnePastEnd() const
Checks if the index is one past end.
uint64_t getIntegerRepresentation() const
bool isPastEnd() const
Checks if the pointer points past the end of the object.
const FieldDecl * getField() const
Returns the field information.
bool isElementPastEnd() const
Checks if the pointer is an out-of-bounds element pointer.
bool isBlockPointer() const
std::optional< APValue > toRValue(const Context &Ctx, QualType ResultType) const
Converts the pointer to an APValue that is an rvalue.
const FunctionPointer & asFunctionPointer() const
const Block * block() const
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
bool isBaseClass() const
Checks if a structure is a base class.
size_t elemSize() const
Returns the element size of the innermost field.
const BlockPointer & asBlockPointer() const
static std::optional< std::pair< PtrView, PtrView > > computeSplitPoint(const Pointer &A, const Pointer &B)
Structure/Class descriptor.
const RecordDecl * getDecl() const
Returns the underlying declaration.
bool isUnion() const
Checks if the record is a union.
const Field * getField(unsigned I) const
unsigned getNumBases() const
const Base * getBase(unsigned I) const
const Base * getVirtualBase(unsigned I) const
unsigned getNumFields() const
unsigned getNumVirtualBases() const
llvm::iterator_range< const_field_iter > fields() const
constexpr bool isIntegerOrBoolType(PrimType T)
PrimType
Enumeration of the primitive types of the VM.
bool Add(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
int const char * function
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
unsigned Base
Start of the current subfield.
Block * Pointee
The block the pointer is pointing to.
const VarDecl * asVarDecl() const
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
QualType getElemQualType() const
const ValueDecl * asValueDecl() const
const Decl * asDecl() const
QualType getDataType(const ASTContext &Ctx) const
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
DynAllocKind getDynAllocKind() const
Returns the kind of dynamic allocation source of this block.
const FieldDecl * asFieldDecl() const
const VarDecl * asVarDecl() const
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.
const Expr * asExpr() const
bool isArray() const
Checks if the descriptor is of an array.
Descriptor used for global variables.
GlobalInitState InitState
A pointer-sized struct we use to allocate into data storage.
void noteAllInitialized()
bool allInitialized() const
Are all elements in the array already initialized?
void setInitMap(const InitMap *IM)
Bitfield tracking the initialisation status of elements of primitive arrays.
void startElementLifetime(unsigned I)
void endElementLifetime(unsigned I)
bool allElementsAlive() const
bool isElementInitialized(unsigned I) const
Checks if an element was initialized.
bool initializeElement(unsigned I)
Initializes an element. Returns true when object if fully initialized.
bool isElementAlive(unsigned I) const
Inline descriptor embedded in structures and arrays.
unsigned IsActive
Flag indicating if the field is the active member of a union.
unsigned Offset
Offset inside the structure/array.
unsigned IsInitialized
For primitive fields, it indicates if the field was initialized.
QualType getPointeeType() const
IntPointer baseCast(const Context &Ctx, unsigned BaseOffset) const
const Type * getType() const
std::optional< IntPointer > atOffset(const Context &Ctx, unsigned Offset) const
llvm::PointerIntPair< const Type *, 2, unsigned > FieldType
QualType getObjectType() const
bool isRoot() const
Check if the pointer has offset 0.
bool hasValidBase() const
QualType getSurroundingArray() const
If this is pointing to an array element, return the array.
bool isOnePastEndOrElementPastEnd() const
This is used in Pointer::isOnePastEnd().
const PointerPathEntry * Path
ArrayRef< PointerPathEntry > path() const
bool isArrayElement() const
QualType getFieldType() const
bool isOnePastEnd() const
bool isUnknownSizeArray() const
std::optional< size_t > computeLayoutOffset(const ASTContext &ASTCtx) const
llvm::PointerIntPair< const CXXRecordDecl *, 1, bool > RD
enum clang::interp::PointerPathEntry::@133156275124227243235357227301330162015140142322 Kind
const Descriptor * getDeclDesc() const
bool allElementsInitialized() const
PtrView atField(unsigned Offset) const
const Record * getRecord() const
const Descriptor * getFieldDesc() const
const FieldDecl * getField() const
bool isElementInitialized(unsigned Index) const
void startLifetime() const
bool isInitialized() const
bool isArrayElement() const
unsigned getNumElems() const
InitMapPtr & getInitMap() const
InlineDescriptor * getInlineDesc() const
void initializeElement(unsigned Index) const
bool isOnePastEnd() const
void setLifeState(Lifetime L) const
Lifetime getLifetime() const
bool isVirtualBaseClass() const
const StringLiteral * getLiteral() const
const Type * TypeInfoType