240 lines
7.5 KiB
C++
240 lines
7.5 KiB
C++
//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines interfaces used to represent Designators in the parser and
|
|
// is the input to Actions module.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_PARSE_DESIGNATOR_H
|
|
#define LLVM_CLANG_PARSE_DESIGNATOR_H
|
|
|
|
#include "clang/Parse/Action.h"
|
|
|
|
namespace clang {
|
|
|
|
/// Designator - This class is a discriminated union which holds the various
|
|
/// different sorts of designators possible. A Designation is an array of
|
|
/// these. An example of a designator are things like this:
|
|
/// [8] .field [47] // C99 designation: 3 designators
|
|
/// [8 ... 47] field: // GNU extensions: 2 designators
|
|
/// These occur in initializers, e.g.:
|
|
/// int a[10] = {2, 4, [8]=9, 10};
|
|
///
|
|
class Designator {
|
|
public:
|
|
enum DesignatorKind {
|
|
FieldDesignator, ArrayDesignator, ArrayRangeDesignator
|
|
};
|
|
private:
|
|
DesignatorKind Kind;
|
|
|
|
struct FieldDesignatorInfo {
|
|
const IdentifierInfo *II;
|
|
unsigned DotLoc;
|
|
unsigned NameLoc;
|
|
};
|
|
struct ArrayDesignatorInfo {
|
|
ActionBase::ExprTy *Index;
|
|
unsigned LBracketLoc;
|
|
mutable unsigned RBracketLoc;
|
|
};
|
|
struct ArrayRangeDesignatorInfo {
|
|
ActionBase::ExprTy *Start, *End;
|
|
unsigned LBracketLoc, EllipsisLoc;
|
|
mutable unsigned RBracketLoc;
|
|
};
|
|
|
|
union {
|
|
FieldDesignatorInfo FieldInfo;
|
|
ArrayDesignatorInfo ArrayInfo;
|
|
ArrayRangeDesignatorInfo ArrayRangeInfo;
|
|
};
|
|
|
|
public:
|
|
|
|
DesignatorKind getKind() const { return Kind; }
|
|
bool isFieldDesignator() const { return Kind == FieldDesignator; }
|
|
bool isArrayDesignator() const { return Kind == ArrayDesignator; }
|
|
bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
|
|
|
|
const IdentifierInfo *getField() const {
|
|
assert(isFieldDesignator() && "Invalid accessor");
|
|
return FieldInfo.II;
|
|
}
|
|
|
|
SourceLocation getDotLoc() const {
|
|
assert(isFieldDesignator() && "Invalid accessor");
|
|
return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
|
|
}
|
|
|
|
SourceLocation getFieldLoc() const {
|
|
assert(isFieldDesignator() && "Invalid accessor");
|
|
return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
|
|
}
|
|
|
|
ActionBase::ExprTy *getArrayIndex() const {
|
|
assert(isArrayDesignator() && "Invalid accessor");
|
|
return ArrayInfo.Index;
|
|
}
|
|
|
|
ActionBase::ExprTy *getArrayRangeStart() const {
|
|
assert(isArrayRangeDesignator() && "Invalid accessor");
|
|
return ArrayRangeInfo.Start;
|
|
}
|
|
ActionBase::ExprTy *getArrayRangeEnd() const {
|
|
assert(isArrayRangeDesignator() && "Invalid accessor");
|
|
return ArrayRangeInfo.End;
|
|
}
|
|
|
|
SourceLocation getLBracketLoc() const {
|
|
assert((isArrayDesignator() || isArrayRangeDesignator()) &&
|
|
"Invalid accessor");
|
|
if (isArrayDesignator())
|
|
return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
|
|
else
|
|
return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
|
|
}
|
|
|
|
SourceLocation getRBracketLoc() const {
|
|
assert((isArrayDesignator() || isArrayRangeDesignator()) &&
|
|
"Invalid accessor");
|
|
if (isArrayDesignator())
|
|
return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
|
|
else
|
|
return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
|
|
}
|
|
|
|
SourceLocation getEllipsisLoc() const {
|
|
assert(isArrayRangeDesignator() && "Invalid accessor");
|
|
return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
|
|
}
|
|
|
|
static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
|
|
SourceLocation NameLoc) {
|
|
Designator D;
|
|
D.Kind = FieldDesignator;
|
|
D.FieldInfo.II = II;
|
|
D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
|
|
D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
|
|
return D;
|
|
}
|
|
|
|
static Designator getArray(ActionBase::ExprTy *Index,
|
|
SourceLocation LBracketLoc) {
|
|
Designator D;
|
|
D.Kind = ArrayDesignator;
|
|
D.ArrayInfo.Index = Index;
|
|
D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
|
|
D.ArrayInfo.RBracketLoc = 0;
|
|
return D;
|
|
}
|
|
|
|
static Designator getArrayRange(ActionBase::ExprTy *Start,
|
|
ActionBase::ExprTy *End,
|
|
SourceLocation LBracketLoc,
|
|
SourceLocation EllipsisLoc) {
|
|
Designator D;
|
|
D.Kind = ArrayRangeDesignator;
|
|
D.ArrayRangeInfo.Start = Start;
|
|
D.ArrayRangeInfo.End = End;
|
|
D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
|
|
D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
|
|
D.ArrayRangeInfo.RBracketLoc = 0;
|
|
return D;
|
|
}
|
|
|
|
void setRBracketLoc(SourceLocation RBracketLoc) const {
|
|
assert((isArrayDesignator() || isArrayRangeDesignator()) &&
|
|
"Invalid accessor");
|
|
if (isArrayDesignator())
|
|
ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
|
|
else
|
|
ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
|
|
}
|
|
|
|
/// ClearExprs - Null out any expression references, which prevents them from
|
|
/// being 'delete'd later.
|
|
void ClearExprs(Action &Actions) {
|
|
switch (Kind) {
|
|
case FieldDesignator: return;
|
|
case ArrayDesignator:
|
|
ArrayInfo.Index = 0;
|
|
return;
|
|
case ArrayRangeDesignator:
|
|
ArrayRangeInfo.Start = 0;
|
|
ArrayRangeInfo.End = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
/// FreeExprs - Release any unclaimed memory for the expressions in this
|
|
/// designator.
|
|
void FreeExprs(Action &Actions) {
|
|
switch (Kind) {
|
|
case FieldDesignator: return; // nothing to free.
|
|
case ArrayDesignator:
|
|
Actions.DeleteExpr(getArrayIndex());
|
|
return;
|
|
case ArrayRangeDesignator:
|
|
Actions.DeleteExpr(getArrayRangeStart());
|
|
Actions.DeleteExpr(getArrayRangeEnd());
|
|
return;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
/// Designation - Represent a full designation, which is a sequence of
|
|
/// designators. This class is mostly a helper for InitListDesignations.
|
|
class Designation {
|
|
/// InitIndex - The index of the initializer expression this is for. For
|
|
/// example, if the initializer were "{ A, .foo=B, C }" a Designation would
|
|
/// exist with InitIndex=1, because element #1 has a designation.
|
|
unsigned InitIndex;
|
|
|
|
/// Designators - The actual designators for this initializer.
|
|
llvm::SmallVector<Designator, 2> Designators;
|
|
|
|
Designation(unsigned Idx) : InitIndex(Idx) {}
|
|
public:
|
|
Designation() : InitIndex(4000) {}
|
|
|
|
/// AddDesignator - Add a designator to the end of this list.
|
|
void AddDesignator(Designator D) {
|
|
Designators.push_back(D);
|
|
}
|
|
|
|
bool empty() const { return Designators.empty(); }
|
|
|
|
unsigned getNumDesignators() const { return Designators.size(); }
|
|
const Designator &getDesignator(unsigned Idx) const {
|
|
assert(Idx < Designators.size());
|
|
return Designators[Idx];
|
|
}
|
|
|
|
/// ClearExprs - Null out any expression references, which prevents them from
|
|
/// being 'delete'd later.
|
|
void ClearExprs(Action &Actions) {
|
|
for (unsigned i = 0, e = Designators.size(); i != e; ++i)
|
|
Designators[i].ClearExprs(Actions);
|
|
}
|
|
|
|
/// FreeExprs - Release any unclaimed memory for the expressions in this
|
|
/// designation.
|
|
void FreeExprs(Action &Actions) {
|
|
for (unsigned i = 0, e = Designators.size(); i != e; ++i)
|
|
Designators[i].FreeExprs(Actions);
|
|
}
|
|
};
|
|
|
|
} // end namespace clang
|
|
|
|
#endif
|