forked from OSchip/llvm-project
[TrailingObjects] Convert OffsetOfExpr.
That necessitated moving the OffsetOfNode class out of OffsetOfExpr. llvm-svn: 256590
This commit is contained in:
parent
e77de75d7e
commit
7281c357b1
|
@ -1749,25 +1749,11 @@ public:
|
|||
child_range children() { return child_range(&Val, &Val+1); }
|
||||
};
|
||||
|
||||
/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
|
||||
/// offsetof(record-type, member-designator). For example, given:
|
||||
/// @code
|
||||
/// struct S {
|
||||
/// float f;
|
||||
/// double d;
|
||||
/// };
|
||||
/// struct T {
|
||||
/// int i;
|
||||
/// struct S s[10];
|
||||
/// };
|
||||
/// @endcode
|
||||
/// we can represent and evaluate the expression @c offsetof(struct T, s[2].d).
|
||||
/// Helper class for OffsetOfExpr.
|
||||
|
||||
class OffsetOfExpr : public Expr {
|
||||
// __builtin_offsetof(type, identifier(.identifier|[expr])*)
|
||||
class OffsetOfNode {
|
||||
public:
|
||||
// __builtin_offsetof(type, identifier(.identifier|[expr])*)
|
||||
class OffsetOfNode {
|
||||
public:
|
||||
/// \brief The kind of offsetof node we have.
|
||||
enum Kind {
|
||||
/// \brief An index into an array.
|
||||
|
@ -1781,7 +1767,7 @@ public:
|
|||
Base = 0x03
|
||||
};
|
||||
|
||||
private:
|
||||
private:
|
||||
enum { MaskBits = 2, Mask = 0x03 };
|
||||
|
||||
/// \brief The source range that covers this part of the designator.
|
||||
|
@ -1798,32 +1784,29 @@ public:
|
|||
/// base class.
|
||||
uintptr_t Data;
|
||||
|
||||
public:
|
||||
public:
|
||||
/// \brief Create an offsetof node that refers to an array element.
|
||||
OffsetOfNode(SourceLocation LBracketLoc, unsigned Index,
|
||||
SourceLocation RBracketLoc)
|
||||
: Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) { }
|
||||
: Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) {}
|
||||
|
||||
/// \brief Create an offsetof node that refers to a field.
|
||||
OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field,
|
||||
SourceLocation NameLoc)
|
||||
: Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc),
|
||||
Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) { }
|
||||
OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field, SourceLocation NameLoc)
|
||||
: Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
|
||||
Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) {}
|
||||
|
||||
/// \brief Create an offsetof node that refers to an identifier.
|
||||
OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
|
||||
SourceLocation NameLoc)
|
||||
: Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc),
|
||||
Data(reinterpret_cast<uintptr_t>(Name) | Identifier) { }
|
||||
: Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc),
|
||||
Data(reinterpret_cast<uintptr_t>(Name) | Identifier) {}
|
||||
|
||||
/// \brief Create an offsetof node that refers into a C++ base class.
|
||||
explicit OffsetOfNode(const CXXBaseSpecifier *Base)
|
||||
: Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
|
||||
|
||||
/// \brief Determine what kind of offsetof node this is.
|
||||
Kind getKind() const {
|
||||
return static_cast<Kind>(Data & Mask);
|
||||
}
|
||||
Kind getKind() const { return static_cast<Kind>(Data & Mask); }
|
||||
|
||||
/// \brief For an array element node, returns the index into the array
|
||||
/// of expressions.
|
||||
|
@ -1857,10 +1840,25 @@ public:
|
|||
SourceRange getSourceRange() const LLVM_READONLY { return Range; }
|
||||
SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
|
||||
SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
|
||||
};
|
||||
};
|
||||
|
||||
private:
|
||||
/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
|
||||
/// offsetof(record-type, member-designator). For example, given:
|
||||
/// @code
|
||||
/// struct S {
|
||||
/// float f;
|
||||
/// double d;
|
||||
/// };
|
||||
/// struct T {
|
||||
/// int i;
|
||||
/// struct S s[10];
|
||||
/// };
|
||||
/// @endcode
|
||||
/// we can represent and evaluate the expression @c offsetof(struct T, s[2].d).
|
||||
|
||||
class OffsetOfExpr final
|
||||
: public Expr,
|
||||
private llvm::TrailingObjects<OffsetOfExpr, OffsetOfNode, Expr *> {
|
||||
SourceLocation OperatorLoc, RParenLoc;
|
||||
// Base type;
|
||||
TypeSourceInfo *TSInfo;
|
||||
|
@ -1869,6 +1867,10 @@ private:
|
|||
// Number of sub-expressions (i.e. array subscript expressions).
|
||||
unsigned NumExprs;
|
||||
|
||||
size_t numTrailingObjects(OverloadToken<OffsetOfNode>) const {
|
||||
return NumComps;
|
||||
}
|
||||
|
||||
OffsetOfExpr(const ASTContext &C, QualType type,
|
||||
SourceLocation OperatorLoc, TypeSourceInfo *tsi,
|
||||
ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs,
|
||||
|
@ -1905,12 +1907,12 @@ public:
|
|||
|
||||
const OffsetOfNode &getComponent(unsigned Idx) const {
|
||||
assert(Idx < NumComps && "Subscript out of range");
|
||||
return reinterpret_cast<const OffsetOfNode *> (this + 1)[Idx];
|
||||
return getTrailingObjects<OffsetOfNode>()[Idx];
|
||||
}
|
||||
|
||||
void setComponent(unsigned Idx, OffsetOfNode ON) {
|
||||
assert(Idx < NumComps && "Subscript out of range");
|
||||
reinterpret_cast<OffsetOfNode *> (this + 1)[Idx] = ON;
|
||||
getTrailingObjects<OffsetOfNode>()[Idx] = ON;
|
||||
}
|
||||
|
||||
unsigned getNumComponents() const {
|
||||
|
@ -1919,17 +1921,17 @@ public:
|
|||
|
||||
Expr* getIndexExpr(unsigned Idx) {
|
||||
assert(Idx < NumExprs && "Subscript out of range");
|
||||
return reinterpret_cast<Expr **>(
|
||||
reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx];
|
||||
return getTrailingObjects<Expr *>()[Idx];
|
||||
}
|
||||
|
||||
const Expr *getIndexExpr(unsigned Idx) const {
|
||||
return const_cast<OffsetOfExpr*>(this)->getIndexExpr(Idx);
|
||||
assert(Idx < NumExprs && "Subscript out of range");
|
||||
return getTrailingObjects<Expr *>()[Idx];
|
||||
}
|
||||
|
||||
void setIndexExpr(unsigned Idx, Expr* E) {
|
||||
assert(Idx < NumComps && "Subscript out of range");
|
||||
reinterpret_cast<Expr **>(
|
||||
reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx] = E;
|
||||
getTrailingObjects<Expr *>()[Idx] = E;
|
||||
}
|
||||
|
||||
unsigned getNumExpressions() const {
|
||||
|
@ -1945,11 +1947,10 @@ public:
|
|||
|
||||
// Iterators
|
||||
child_range children() {
|
||||
Stmt **begin =
|
||||
reinterpret_cast<Stmt**>(reinterpret_cast<OffsetOfNode*>(this + 1)
|
||||
+ NumComps);
|
||||
Stmt **begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
|
||||
return child_range(begin, begin + NumExprs);
|
||||
}
|
||||
friend TrailingObjects;
|
||||
};
|
||||
|
||||
/// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated)
|
||||
|
|
|
@ -1314,9 +1314,8 @@ OffsetOfExpr *OffsetOfExpr::Create(const ASTContext &C, QualType type,
|
|||
ArrayRef<OffsetOfNode> comps,
|
||||
ArrayRef<Expr*> exprs,
|
||||
SourceLocation RParenLoc) {
|
||||
void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
|
||||
sizeof(OffsetOfNode) * comps.size() +
|
||||
sizeof(Expr*) * exprs.size());
|
||||
void *Mem = C.Allocate(
|
||||
totalSizeToAlloc<OffsetOfNode, Expr *>(comps.size(), exprs.size()));
|
||||
|
||||
return new (Mem) OffsetOfExpr(C, type, OperatorLoc, tsi, comps, exprs,
|
||||
RParenLoc);
|
||||
|
@ -1324,9 +1323,8 @@ OffsetOfExpr *OffsetOfExpr::Create(const ASTContext &C, QualType type,
|
|||
|
||||
OffsetOfExpr *OffsetOfExpr::CreateEmpty(const ASTContext &C,
|
||||
unsigned numComps, unsigned numExprs) {
|
||||
void *Mem = C.Allocate(sizeof(OffsetOfExpr) +
|
||||
sizeof(OffsetOfNode) * numComps +
|
||||
sizeof(Expr*) * numExprs);
|
||||
void *Mem =
|
||||
C.Allocate(totalSizeToAlloc<OffsetOfNode, Expr *>(numComps, numExprs));
|
||||
return new (Mem) OffsetOfExpr(numComps, numExprs);
|
||||
}
|
||||
|
||||
|
@ -1356,7 +1354,7 @@ OffsetOfExpr::OffsetOfExpr(const ASTContext &C, QualType type,
|
|||
}
|
||||
}
|
||||
|
||||
IdentifierInfo *OffsetOfExpr::OffsetOfNode::getFieldName() const {
|
||||
IdentifierInfo *OffsetOfNode::getFieldName() const {
|
||||
assert(getKind() == Field || getKind() == Identifier);
|
||||
if (getKind() == Field)
|
||||
return getField()->getIdentifier();
|
||||
|
|
|
@ -7617,9 +7617,9 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
|
|||
return Error(OOE);
|
||||
QualType CurrentType = OOE->getTypeSourceInfo()->getType();
|
||||
for (unsigned i = 0; i != n; ++i) {
|
||||
OffsetOfExpr::OffsetOfNode ON = OOE->getComponent(i);
|
||||
OffsetOfNode ON = OOE->getComponent(i);
|
||||
switch (ON.getKind()) {
|
||||
case OffsetOfExpr::OffsetOfNode::Array: {
|
||||
case OffsetOfNode::Array: {
|
||||
const Expr *Idx = OOE->getIndexExpr(ON.getArrayExprIndex());
|
||||
APSInt IdxResult;
|
||||
if (!EvaluateInteger(Idx, IdxResult, Info))
|
||||
|
@ -7633,7 +7633,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
|
|||
break;
|
||||
}
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Field: {
|
||||
case OffsetOfNode::Field: {
|
||||
FieldDecl *MemberDecl = ON.getField();
|
||||
const RecordType *RT = CurrentType->getAs<RecordType>();
|
||||
if (!RT)
|
||||
|
@ -7648,10 +7648,10 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
|
|||
break;
|
||||
}
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Identifier:
|
||||
case OffsetOfNode::Identifier:
|
||||
llvm_unreachable("dependent __builtin_offsetof");
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Base: {
|
||||
case OffsetOfNode::Base: {
|
||||
CXXBaseSpecifier *BaseSpec = ON.getBase();
|
||||
if (BaseSpec->isVirtual())
|
||||
return Error(OOE);
|
||||
|
|
|
@ -1305,8 +1305,8 @@ void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
|
|||
OS << ", ";
|
||||
bool PrintedSomething = false;
|
||||
for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
|
||||
OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i);
|
||||
if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) {
|
||||
OffsetOfNode ON = Node->getComponent(i);
|
||||
if (ON.getKind() == OffsetOfNode::Array) {
|
||||
// Array node
|
||||
OS << "[";
|
||||
PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
|
||||
|
@ -1316,7 +1316,7 @@ void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
|
|||
}
|
||||
|
||||
// Skip implicit base indirections.
|
||||
if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base)
|
||||
if (ON.getKind() == OffsetOfNode::Base)
|
||||
continue;
|
||||
|
||||
// Field or identifier node.
|
||||
|
|
|
@ -675,22 +675,22 @@ void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
|
|||
VisitType(S->getTypeSourceInfo()->getType());
|
||||
unsigned n = S->getNumComponents();
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
const OffsetOfExpr::OffsetOfNode& ON = S->getComponent(i);
|
||||
const OffsetOfNode &ON = S->getComponent(i);
|
||||
ID.AddInteger(ON.getKind());
|
||||
switch (ON.getKind()) {
|
||||
case OffsetOfExpr::OffsetOfNode::Array:
|
||||
case OffsetOfNode::Array:
|
||||
// Expressions handled below.
|
||||
break;
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Field:
|
||||
case OffsetOfNode::Field:
|
||||
VisitDecl(ON.getField());
|
||||
break;
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Identifier:
|
||||
case OffsetOfNode::Identifier:
|
||||
ID.AddPointer(ON.getFieldName());
|
||||
break;
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Base:
|
||||
case OffsetOfNode::Base:
|
||||
// These nodes are implicit, and therefore don't need profiling.
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1924,10 +1924,10 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
|||
llvm::Value* Result = llvm::Constant::getNullValue(ResultType);
|
||||
QualType CurrentType = E->getTypeSourceInfo()->getType();
|
||||
for (unsigned i = 0; i != n; ++i) {
|
||||
OffsetOfExpr::OffsetOfNode ON = E->getComponent(i);
|
||||
OffsetOfNode ON = E->getComponent(i);
|
||||
llvm::Value *Offset = nullptr;
|
||||
switch (ON.getKind()) {
|
||||
case OffsetOfExpr::OffsetOfNode::Array: {
|
||||
case OffsetOfNode::Array: {
|
||||
// Compute the index
|
||||
Expr *IdxExpr = E->getIndexExpr(ON.getArrayExprIndex());
|
||||
llvm::Value* Idx = CGF.EmitScalarExpr(IdxExpr);
|
||||
|
@ -1947,7 +1947,7 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
|||
break;
|
||||
}
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Field: {
|
||||
case OffsetOfNode::Field: {
|
||||
FieldDecl *MemberDecl = ON.getField();
|
||||
RecordDecl *RD = CurrentType->getAs<RecordType>()->getDecl();
|
||||
const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
|
||||
|
@ -1973,10 +1973,10 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
|||
break;
|
||||
}
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Identifier:
|
||||
case OffsetOfNode::Identifier:
|
||||
llvm_unreachable("dependent __builtin_offsetof");
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Base: {
|
||||
case OffsetOfNode::Base: {
|
||||
if (ON.getBase()->isVirtual()) {
|
||||
CGF.ErrorUnsupported(E, "virtual base in offsetof");
|
||||
continue;
|
||||
|
|
|
@ -11189,7 +11189,6 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
|
|||
|
||||
bool DidWarnAboutNonPOD = false;
|
||||
QualType CurrentType = ArgTy;
|
||||
typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
|
||||
SmallVector<OffsetOfNode, 4> Comps;
|
||||
SmallVector<Expr*, 4> Exprs;
|
||||
for (const OffsetOfComponent &OC : Components) {
|
||||
|
|
|
@ -8063,16 +8063,15 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
|
|||
// template code that we don't care.
|
||||
bool ExprChanged = false;
|
||||
typedef Sema::OffsetOfComponent Component;
|
||||
typedef OffsetOfExpr::OffsetOfNode Node;
|
||||
SmallVector<Component, 4> Components;
|
||||
for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
|
||||
const Node &ON = E->getComponent(I);
|
||||
const OffsetOfNode &ON = E->getComponent(I);
|
||||
Component Comp;
|
||||
Comp.isBrackets = true;
|
||||
Comp.LocStart = ON.getSourceRange().getBegin();
|
||||
Comp.LocEnd = ON.getSourceRange().getEnd();
|
||||
switch (ON.getKind()) {
|
||||
case Node::Array: {
|
||||
case OffsetOfNode::Array: {
|
||||
Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
|
||||
ExprResult Index = getDerived().TransformExpr(FromIndex);
|
||||
if (Index.isInvalid())
|
||||
|
@ -8084,8 +8083,8 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
|
|||
break;
|
||||
}
|
||||
|
||||
case Node::Field:
|
||||
case Node::Identifier:
|
||||
case OffsetOfNode::Field:
|
||||
case OffsetOfNode::Identifier:
|
||||
Comp.isBrackets = false;
|
||||
Comp.U.IdentInfo = ON.getFieldName();
|
||||
if (!Comp.U.IdentInfo)
|
||||
|
@ -8093,7 +8092,7 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
|
|||
|
||||
break;
|
||||
|
||||
case Node::Base:
|
||||
case OffsetOfNode::Base:
|
||||
// Will be recomputed during the rebuild.
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -550,7 +550,6 @@ void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
|
|||
}
|
||||
|
||||
void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
||||
typedef OffsetOfExpr::OffsetOfNode Node;
|
||||
VisitExpr(E);
|
||||
assert(E->getNumComponents() == Record[Idx]);
|
||||
++Idx;
|
||||
|
@ -560,29 +559,29 @@ void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
|||
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
||||
E->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
|
||||
for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
|
||||
Node::Kind Kind = static_cast<Node::Kind>(Record[Idx++]);
|
||||
OffsetOfNode::Kind Kind = static_cast<OffsetOfNode::Kind>(Record[Idx++]);
|
||||
SourceLocation Start = ReadSourceLocation(Record, Idx);
|
||||
SourceLocation End = ReadSourceLocation(Record, Idx);
|
||||
switch (Kind) {
|
||||
case Node::Array:
|
||||
E->setComponent(I, Node(Start, Record[Idx++], End));
|
||||
case OffsetOfNode::Array:
|
||||
E->setComponent(I, OffsetOfNode(Start, Record[Idx++], End));
|
||||
break;
|
||||
|
||||
case Node::Field:
|
||||
E->setComponent(I, Node(Start, ReadDeclAs<FieldDecl>(Record, Idx), End));
|
||||
case OffsetOfNode::Field:
|
||||
E->setComponent(
|
||||
I, OffsetOfNode(Start, ReadDeclAs<FieldDecl>(Record, Idx), End));
|
||||
break;
|
||||
|
||||
case Node::Identifier:
|
||||
E->setComponent(I,
|
||||
Node(Start,
|
||||
Reader.GetIdentifierInfo(F, Record, Idx),
|
||||
End));
|
||||
case OffsetOfNode::Identifier:
|
||||
E->setComponent(
|
||||
I,
|
||||
OffsetOfNode(Start, Reader.GetIdentifierInfo(F, Record, Idx), End));
|
||||
break;
|
||||
|
||||
case Node::Base: {
|
||||
case OffsetOfNode::Base: {
|
||||
CXXBaseSpecifier *Base = new (Reader.getContext()) CXXBaseSpecifier();
|
||||
*Base = Reader.ReadCXXBaseSpecifier(F, Record, Idx);
|
||||
E->setComponent(I, Node(Base));
|
||||
E->setComponent(I, OffsetOfNode(Base));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -484,24 +484,24 @@ void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
|||
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
||||
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
||||
for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
|
||||
const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
|
||||
const OffsetOfNode &ON = E->getComponent(I);
|
||||
Record.push_back(ON.getKind()); // FIXME: Stable encoding
|
||||
Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
|
||||
Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
|
||||
switch (ON.getKind()) {
|
||||
case OffsetOfExpr::OffsetOfNode::Array:
|
||||
case OffsetOfNode::Array:
|
||||
Record.push_back(ON.getArrayExprIndex());
|
||||
break;
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Field:
|
||||
case OffsetOfNode::Field:
|
||||
Writer.AddDeclRef(ON.getField(), Record);
|
||||
break;
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Identifier:
|
||||
case OffsetOfNode::Identifier:
|
||||
Writer.AddIdentifierRef(ON.getFieldName(), Record);
|
||||
break;
|
||||
|
||||
case OffsetOfExpr::OffsetOfNode::Base:
|
||||
case OffsetOfNode::Base:
|
||||
Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2434,7 +2434,6 @@ void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
|
|||
void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
|
||||
// Visit the components of the offsetof expression.
|
||||
for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
|
||||
typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
|
||||
const OffsetOfNode &Node = E->getComponent(I-1);
|
||||
switch (Node.getKind()) {
|
||||
case OffsetOfNode::Array:
|
||||
|
|
Loading…
Reference in New Issue