blob: bdb0b9b438a6263f8f689b24b3b53fc4c532a4b9 [file] [log] [blame]
//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- 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 the TypeLoc interface and subclasses.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_TYPELOC_H
#define LLVM_CLANG_AST_TYPELOC_H
#include "clang/AST/Type.h"
#include "clang/AST/Decl.h"
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/Specifiers.h"
namespace clang {
class ASTContext;
class ParmVarDecl;
class TypeSourceInfo;
class UnqualTypeLoc;
// Predeclare all the type nodes.
#define ABSTRACT_TYPELOC(Class, Base)
#define TYPELOC(Class, Base) \
class Class##TypeLoc;
#include "clang/AST/TypeLocNodes.def"
/// \brief Base wrapper for a particular "section" of type source info.
///
/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
/// get at the actual information.
class TypeLoc {
protected:
// The correctness of this relies on the property that, for Type *Ty,
// QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
const void *Ty;
void *Data;
public:
/// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
/// except it also defines a Qualified enum that corresponds to the
/// QualifiedLoc class.
enum TypeLocClass {
#define ABSTRACT_TYPE(Class, Base)
#define TYPE(Class, Base) \
Class = Type::Class,
#include "clang/AST/TypeNodes.def"
Qualified
};
TypeLoc() : Ty(0), Data(0) { }
TypeLoc(QualType ty, void *opaqueData)
: Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
TypeLoc(const Type *ty, void *opaqueData)
: Ty(ty), Data(opaqueData) { }
TypeLocClass getTypeLocClass() const {
if (getType().hasLocalQualifiers()) return Qualified;
return (TypeLocClass) getType()->getTypeClass();
}
bool isNull() const { return !Ty; }
operator bool() const { return Ty; }
/// \brief Returns the size of type source info data block for the given type.
static unsigned getFullDataSizeForType(QualType Ty);
/// \brief Get the type for which this source info wrapper provides
/// information.
QualType getType() const {
return QualType::getFromOpaquePtr(Ty);
}
const Type *getTypePtr() const {
return QualType::getFromOpaquePtr(Ty).getTypePtr();
}
/// \brief Get the pointer where source information is stored.
void *getOpaqueData() const {
return Data;
}
/// \brief Get the begin source location.
SourceLocation getBeginLoc() const;
/// \brief Get the end source location.
SourceLocation getEndLoc() const;
/// \brief Get the full source range.
SourceRange getSourceRange() const {
return SourceRange(getBeginLoc(), getEndLoc());
}
/// \brief Get the local source range.
SourceRange getLocalSourceRange() const {
return getLocalSourceRangeImpl(*this);
}
/// \brief Returns the size of the type source info data block.
unsigned getFullDataSize() const {
return getFullDataSizeForType(getType());
}
/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
TypeLoc getNextTypeLoc() const {
return getNextTypeLocImpl(*this);
}
/// \brief Skips past any qualifiers, if this is qualified.
UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
TypeLoc IgnoreParens() const {
if (isa<ParenTypeLoc>(this))
return IgnoreParensImpl(*this);
return *this;
}
/// \brief Initializes this to state that every location in this
/// type is the given location.
///
/// This method exists to provide a simple transition for code that
/// relies on location-less types.
void initialize(ASTContext &Context, SourceLocation Loc) const {
initializeImpl(Context, *this, Loc);
}
/// \brief Initializes this by copying its information from another
/// TypeLoc of the same type.
void initializeFullCopy(TypeLoc Other) const {
assert(getType() == Other.getType());
size_t Size = getFullDataSize();
memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
}
/// \brief Initializes this by copying its information from another
/// TypeLoc of the same type. The given size must be the full data
/// size.
void initializeFullCopy(TypeLoc Other, unsigned Size) const {
assert(getType() == Other.getType());
assert(getFullDataSize() == Size);
memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
}
friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
}
friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
return !(LHS == RHS);
}
static bool classof(const TypeLoc *TL) { return true; }
private:
static void initializeImpl(ASTContext &Context, TypeLoc TL,
SourceLocation Loc);
static TypeLoc getNextTypeLocImpl(TypeLoc TL);
static TypeLoc IgnoreParensImpl(TypeLoc TL);
static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
};
/// \brief Return the TypeLoc for a type source info.
inline TypeLoc TypeSourceInfo::getTypeLoc() const {
return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
}
/// \brief Wrapper of type source information for a type with
/// no direct qualifiers.
class UnqualTypeLoc : public TypeLoc {
public:
UnqualTypeLoc() {}
UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
const Type *getTypePtr() const {
return reinterpret_cast<const Type*>(Ty);
}
TypeLocClass getTypeLocClass() const {
return (TypeLocClass) getTypePtr()->getTypeClass();
}
static bool classof(const TypeLoc *TL) {
return !TL->getType().hasLocalQualifiers();
}
static bool classof(const UnqualTypeLoc *TL) { return true; }
};
/// \brief Wrapper of type source information for a type with
/// non-trivial direct qualifiers.
///
/// Currently, we intentionally do not provide source location for
/// type qualifiers.
class QualifiedTypeLoc : public TypeLoc {
public:
SourceRange getLocalSourceRange() const {
return SourceRange();
}
UnqualTypeLoc getUnqualifiedLoc() const {
return UnqualTypeLoc(getTypePtr(), Data);
}
/// Initializes the local data of this type source info block to
/// provide no information.
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
// do nothing
}
TypeLoc getNextTypeLoc() const {
return getUnqualifiedLoc();
}
/// \brief Returns the size of the type source info data block that is
/// specific to this type.
unsigned getLocalDataSize() const {
// In fact, we don't currently preserve any location information
// for qualifiers.
return 0;
}
/// \brief Returns the size of the type source info data block.
unsigned getFullDataSize() const {
return getLocalDataSize() +
getFullDataSizeForType(getType().getLocalUnqualifiedType());
}
static bool classof(const TypeLoc *TL) {
return TL->getType().hasLocalQualifiers();
}
static bool classof(const QualifiedTypeLoc *TL) { return true; }
};
inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
if (isa<QualifiedTypeLoc>(this))
return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
return cast<UnqualTypeLoc>(*this);
}
/// A metaprogramming base class for TypeLoc classes which correspond
/// to a particular Type subclass. It is accepted for a single
/// TypeLoc class to correspond to multiple Type classes.
///
/// \param Base a class from which to derive
/// \param Derived the class deriving from this one
/// \param TypeClass the concrete Type subclass associated with this
/// location type
/// \param LocalData the structure type of local location data for
/// this type
///
/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
/// else the world will end.
///
/// TypeLocs with non-constant amounts of local data should override
/// getExtraLocalDataSize(); getExtraLocalData() will then point to
/// this extra memory.
///
/// TypeLocs with an inner type should define
/// QualType getInnerType() const
/// and getInnerTypeLoc() will then point to this inner type's
/// location data.
///
/// A word about hierarchies: this template is not designed to be
/// derived from multiple times in a hierarchy. It is also not
/// designed to be used for classes where subtypes might provide
/// different amounts of source information. It should be subclassed
/// only at the deepest portion of the hierarchy where all children
/// have identical source information; if that's an abstract type,
/// then further descendents should inherit from
/// InheritingConcreteTypeLoc instead.
template <class Base, class Derived, class TypeClass, class LocalData>
class ConcreteTypeLoc : public Base {
const Derived *asDerived() const {
return static_cast<const Derived*>(this);
}
public:
unsigned getLocalDataSize() const {
return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
}
// Give a default implementation that's useful for leaf types.
unsigned getFullDataSize() const {
return asDerived()->getLocalDataSize() + getInnerTypeSize();
}
static bool classofType(const Type *Ty) {
return TypeClass::classof(Ty);
}
static bool classof(const TypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
static bool classof(const UnqualTypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
static bool classof(const Derived *TL) {
return true;
}
TypeLoc getNextTypeLoc() const {
return getNextTypeLoc(asDerived()->getInnerType());
}
const TypeClass *getTypePtr() const {
return cast<TypeClass>(Base::getTypePtr());
}
protected:
unsigned getExtraLocalDataSize() const {
return 0;
}
LocalData *getLocalData() const {
return static_cast<LocalData*>(Base::Data);
}
/// Gets a pointer past the Info structure; useful for classes with
/// local data that can't be captured in the Info (e.g. because it's
/// of variable size).
void *getExtraLocalData() const {
return getLocalData() + 1;
}
void *getNonLocalData() const {
return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
}
struct HasNoInnerType {};
HasNoInnerType getInnerType() const { return HasNoInnerType(); }
TypeLoc getInnerTypeLoc() const {
return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
}
private:
unsigned getInnerTypeSize() const {
return getInnerTypeSize(asDerived()->getInnerType());
}
unsigned getInnerTypeSize(HasNoInnerType _) const {
return 0;
}
unsigned getInnerTypeSize(QualType _) const {
return getInnerTypeLoc().getFullDataSize();
}
TypeLoc getNextTypeLoc(HasNoInnerType _) const {
return TypeLoc();
}
TypeLoc getNextTypeLoc(QualType T) const {
return TypeLoc(T, getNonLocalData());
}
};
/// A metaprogramming class designed for concrete subtypes of abstract
/// types where all subtypes share equivalently-structured source
/// information. See the note on ConcreteTypeLoc.
template <class Base, class Derived, class TypeClass>
class InheritingConcreteTypeLoc : public Base {
public:
static bool classofType(const Type *Ty) {
return TypeClass::classof(Ty);
}
static bool classof(const TypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
static bool classof(const UnqualTypeLoc *TL) {
return Derived::classofType(TL->getTypePtr());
}
static bool classof(const Derived *TL) {
return true;
}
const TypeClass *getTypePtr() const {
return cast<TypeClass>(Base::getTypePtr());
}
};
struct TypeSpecLocInfo {
SourceLocation NameLoc;
};
/// \brief A reasonable base class for TypeLocs that correspond to
/// types that are written as a type-specifier.
class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
TypeSpecTypeLoc,
Type,
TypeSpecLocInfo> {
public:
enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
}
static bool classof(const TypeLoc *TL);
static bool classof(const TypeSpecTypeLoc *TL) { return true; }
};
struct BuiltinLocInfo {
SourceLocation BuiltinLoc;
};
/// \brief Wrapper for source info for builtin types.
class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
BuiltinTypeLoc,
BuiltinType,
BuiltinLocInfo> {
public:
enum { LocalDataSize = sizeof(BuiltinLocInfo) };
SourceLocation getBuiltinLoc() const {
return getLocalData()->BuiltinLoc;
}
void setBuiltinLoc(SourceLocation Loc) {
getLocalData()->BuiltinLoc = Loc;
}
SourceLocation getNameLoc() const { return getBuiltinLoc(); }
WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
}
const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
}
bool needsExtraLocalData() const {
BuiltinType::Kind bk = getTypePtr()->getKind();
return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
|| (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
|| bk == BuiltinType::UChar
|| bk == BuiltinType::SChar;
}
unsigned getExtraLocalDataSize() const {
return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
}
SourceRange getLocalSourceRange() const {
return SourceRange(getBuiltinLoc(), getBuiltinLoc());
}
TypeSpecifierSign getWrittenSignSpec() const {
if (needsExtraLocalData())
return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
else
return TSS_unspecified;
}
bool hasWrittenSignSpec() const {
return getWrittenSignSpec() != TSS_unspecified;
}
void setWrittenSignSpec(TypeSpecifierSign written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().Sign = written;
}
TypeSpecifierWidth getWrittenWidthSpec() const {
if (needsExtraLocalData())
return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
else
return TSW_unspecified;
}
bool hasWrittenWidthSpec() const {
return getWrittenWidthSpec() != TSW_unspecified;
}
void setWrittenWidthSpec(TypeSpecifierWidth written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().Width = written;
}
TypeSpecifierType getWrittenTypeSpec() const;
bool hasWrittenTypeSpec() const {
return getWrittenTypeSpec() != TST_unspecified;
}
void setWrittenTypeSpec(TypeSpecifierType written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().Type = written;
}
bool hasModeAttr() const {
if (needsExtraLocalData())
return getWrittenBuiltinSpecs().ModeAttr;
else
return false;
}
void setModeAttr(bool written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().ModeAttr = written;
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setBuiltinLoc(Loc);
if (needsExtraLocalData()) {
WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
wbs.Sign = TSS_unspecified;
wbs.Width = TSW_unspecified;
wbs.Type = TST_unspecified;
wbs.ModeAttr = false;
}
}
};
/// \brief Wrapper for source info for typedefs.
class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TypedefTypeLoc,
TypedefType> {
public:
TypedefNameDecl *getTypedefNameDecl() const {
return getTypePtr()->getDecl();
}
};
/// \brief Wrapper for source info for injected class names of class
/// templates.
class InjectedClassNameTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
InjectedClassNameTypeLoc,
InjectedClassNameType> {
public:
CXXRecordDecl *getDecl() const {
return getTypePtr()->getDecl();
}
};
/// \brief Wrapper for source info for unresolved typename using decls.
class UnresolvedUsingTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
UnresolvedUsingTypeLoc,
UnresolvedUsingType> {
public:
UnresolvedUsingTypenameDecl *getDecl() const {
return getTypePtr()->getDecl();
}
};
/// \brief Wrapper for source info for tag types. Note that this only
/// records source info for the name itself; a type written 'struct foo'
/// should be represented as an ElaboratedTypeLoc. We currently
/// only do that when C++ is enabled because of the expense of
/// creating an ElaboratedType node for so many type references in C.
class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TagTypeLoc,
TagType> {
public:
TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
/// \brief True if the tag was defined in this type specifier.
bool isDefinition() const {
return getDecl()->isCompleteDefinition() &&
(getNameLoc().isInvalid() || getNameLoc() == getDecl()->getLocation());
}
};
/// \brief Wrapper for source info for record types.
class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
RecordTypeLoc,
RecordType> {
public:
RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
/// \brief Wrapper for source info for enum types.
class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
EnumTypeLoc,
EnumType> {
public:
EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
/// \brief Wrapper for template type parameters.
class TemplateTypeParmTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
TemplateTypeParmTypeLoc,
TemplateTypeParmType> {
public:
TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
};
/// \brief Wrapper for substituted template type parameters.
class SubstTemplateTypeParmTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
SubstTemplateTypeParmTypeLoc,
SubstTemplateTypeParmType> {
};
/// \brief Wrapper for substituted template type parameters.
class SubstTemplateTypeParmPackTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
SubstTemplateTypeParmPackTypeLoc,
SubstTemplateTypeParmPackType> {
};
struct AttributedLocInfo {
union {
Expr *ExprOperand;
/// A raw SourceLocation.
unsigned EnumOperandLoc;
};
SourceRange OperandParens;
SourceLocation AttrLoc;
};
/// \brief Type source information for an attributed type.
class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
AttributedTypeLoc,
AttributedType,
AttributedLocInfo> {
public:
AttributedType::Kind getAttrKind() const {
return getTypePtr()->getAttrKind();
}
bool hasAttrExprOperand() const {
return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
getAttrKind() <= AttributedType::LastExprOperandKind);
}
bool hasAttrEnumOperand() const {
return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
getAttrKind() <= AttributedType::LastEnumOperandKind);
}
bool hasAttrOperand() const {
return hasAttrExprOperand() || hasAttrEnumOperand();
}
/// The modified type, which is generally canonically different from
/// the attribute type.
/// int main(int, char**) __attribute__((noreturn))
/// ~~~ ~~~~~~~~~~~~~
TypeLoc getModifiedLoc() const {
return getInnerTypeLoc();
}
/// The location of the attribute name, i.e.
/// __attribute__((regparm(1000)))
/// ^~~~~~~
SourceLocation getAttrNameLoc() const {
return getLocalData()->AttrLoc;
}
void setAttrNameLoc(SourceLocation loc) {
getLocalData()->AttrLoc = loc;
}
/// The attribute's expression operand, if it has one.
/// void *cur_thread __attribute__((address_space(21)))
/// ^~
Expr *getAttrExprOperand() const {
assert(hasAttrExprOperand());
return getLocalData()->ExprOperand;
}
void setAttrExprOperand(Expr *e) {
assert(hasAttrExprOperand());
getLocalData()->ExprOperand = e;
}
/// The location of the attribute's enumerated operand, if it has one.
/// void * __attribute__((objc_gc(weak)))
/// ^~~~
SourceLocation getAttrEnumOperandLoc() const {
assert(hasAttrEnumOperand());
return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
}
void setAttrEnumOperandLoc(SourceLocation loc) {
assert(hasAttrEnumOperand());
getLocalData()->EnumOperandLoc = loc.getRawEncoding();
}
/// The location of the parentheses around the operand, if there is
/// an operand.
/// void * __attribute__((objc_gc(weak)))
/// ^ ^
SourceRange getAttrOperandParensRange() const {
assert(hasAttrOperand());
return getLocalData()->OperandParens;
}
void setAttrOperandParensRange(SourceRange range) {
assert(hasAttrOperand());
getLocalData()->OperandParens = range;
}
SourceRange getLocalSourceRange() const {
// Note that this does *not* include the range of the attribute
// enclosure, e.g.:
// __attribute__((foo(bar)))
// ^~~~~~~~~~~~~~~ ~~
// or
// [[foo(bar)]]
// ^~ ~~
// That enclosure doesn't necessarily belong to a single attribute
// anyway.
SourceRange range(getAttrNameLoc());
if (hasAttrOperand())
range.setEnd(getAttrOperandParensRange().getEnd());
return range;
}
void initializeLocal(ASTContext &Context, SourceLocation loc) {
setAttrNameLoc(loc);
if (hasAttrExprOperand()) {
setAttrOperandParensRange(SourceRange(loc));
setAttrExprOperand(0);
} else if (hasAttrEnumOperand()) {
setAttrOperandParensRange(SourceRange(loc));
setAttrEnumOperandLoc(loc);
}
}
QualType getInnerType() const {
return getTypePtr()->getModifiedType();
}
};
struct ObjCProtocolListLocInfo {
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
bool HasBaseTypeAsWritten;
};
// A helper class for defining ObjC TypeLocs that can qualified with
// protocols.
//
// TypeClass basically has to be either ObjCInterfaceType or
// ObjCObjectPointerType.
class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ObjCObjectTypeLoc,
ObjCObjectType,
ObjCProtocolListLocInfo> {
// SourceLocations are stored after Info, one for each Protocol.
SourceLocation *getProtocolLocArray() const {
return (SourceLocation*) this->getExtraLocalData();
}
public:
SourceLocation getLAngleLoc() const {
return this->getLocalData()->LAngleLoc;
}
void setLAngleLoc(SourceLocation Loc) {
this->getLocalData()->LAngleLoc = Loc;
}
SourceLocation getRAngleLoc() const {
return this->getLocalData()->RAngleLoc;
}
void setRAngleLoc(SourceLocation Loc) {
this->getLocalData()->RAngleLoc = Loc;
}
unsigned getNumProtocols() const {
return this->getTypePtr()->getNumProtocols();
}
SourceLocation getProtocolLoc(unsigned i) const {
assert(i < getNumProtocols() && "Index is out of bounds!");
return getProtocolLocArray()[i];
}
void setProtocolLoc(unsigned i, SourceLocation Loc) {
assert(i < getNumProtocols() && "Index is out of bounds!");
getProtocolLocArray()[i] = Loc;
}
ObjCProtocolDecl *getProtocol(unsigned i) const {
assert(i < getNumProtocols() && "Index is out of bounds!");
return *(this->getTypePtr()->qual_begin() + i);
}
bool hasBaseTypeAsWritten() const {
return getLocalData()->HasBaseTypeAsWritten;
}
void setHasBaseTypeAsWritten(bool HasBaseType) {
getLocalData()->HasBaseTypeAsWritten = HasBaseType;
}
TypeLoc getBaseLoc() const {
return getInnerTypeLoc();
}
SourceRange getLocalSourceRange() const {
return SourceRange(getLAngleLoc(), getRAngleLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setHasBaseTypeAsWritten(true);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
setProtocolLoc(i, Loc);
}
unsigned getExtraLocalDataSize() const {
return this->getNumProtocols() * sizeof(SourceLocation);
}
QualType getInnerType() const {
return getTypePtr()->getBaseType();
}
};
struct ObjCInterfaceLocInfo {
SourceLocation NameLoc;
};
/// \brief Wrapper for source info for ObjC interfaces.
class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
ObjCInterfaceTypeLoc,
ObjCInterfaceType,
ObjCInterfaceLocInfo> {
public:
ObjCInterfaceDecl *getIFaceDecl() const {
return getTypePtr()->getDecl();
}
SourceLocation getNameLoc() const {
return getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
getLocalData()->NameLoc = Loc;
}
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
}
};
struct ParenLocInfo {
SourceLocation LParenLoc;
SourceLocation RParenLoc;
};
class ParenTypeLoc
: public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
ParenLocInfo> {
public:
SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc;
}
SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc;
}
void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc;
}
void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc;
}
SourceRange getLocalSourceRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLParenLoc(Loc);
setRParenLoc(Loc);
}
TypeLoc getInnerLoc() const {
return getInnerTypeLoc();
}
QualType getInnerType() const {
return this->getTypePtr()->getInnerType();
}
};
struct PointerLikeLocInfo {
SourceLocation StarLoc;
};
/// A base class for
template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
TypeClass, LocalData> {
public:
SourceLocation getSigilLoc() const {
return this->getLocalData()->StarLoc;
}
void setSigilLoc(SourceLocation Loc) {
this->getLocalData()->StarLoc = Loc;
}
TypeLoc getPointeeLoc() const {
return this->getInnerTypeLoc();
}
SourceRange getLocalSourceRange() const {
return SourceRange(getSigilLoc(), getSigilLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
}
QualType getInnerType() const {
return this->getTypePtr()->getPointeeType();
}
};
/// \brief Wrapper for source info for pointers.
class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
PointerType> {
public:
SourceLocation getStarLoc() const {
return getSigilLoc();
}
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
};
/// \brief Wrapper for source info for block pointers.
class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
BlockPointerType> {
public:
SourceLocation getCaretLoc() const {
return getSigilLoc();
}
void setCaretLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
};
struct MemberPointerLocInfo : public PointerLikeLocInfo {
TypeSourceInfo *ClassTInfo;
};
/// \brief Wrapper for source info for member pointers.
class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
MemberPointerType,
MemberPointerLocInfo> {
public:
SourceLocation getStarLoc() const {
return getSigilLoc();
}
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
const Type *getClass() const {
return getTypePtr()->getClass();
}
TypeSourceInfo *getClassTInfo() const {
return getLocalData()->ClassTInfo;
}
void setClassTInfo(TypeSourceInfo* TI) {
getLocalData()->ClassTInfo = TI;
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
setClassTInfo(0);
}
SourceRange getLocalSourceRange() const {
if (TypeSourceInfo *TI = getClassTInfo())
return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
else
return SourceRange(getStarLoc());
}
};
/// Wraps an ObjCPointerType with source location information.
class ObjCObjectPointerTypeLoc :
public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
ObjCObjectPointerType> {
public:
SourceLocation getStarLoc() const {
return getSigilLoc();
}
void setStarLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
};
class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
ReferenceType> {
public:
QualType getInnerType() const {
return getTypePtr()->getPointeeTypeAsWritten();
}
};
class LValueReferenceTypeLoc :
public InheritingConcreteTypeLoc<ReferenceTypeLoc,
LValueReferenceTypeLoc,
LValueReferenceType> {
public:
SourceLocation getAmpLoc() const {
return getSigilLoc();
}
void setAmpLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
};
class RValueReferenceTypeLoc :
public InheritingConcreteTypeLoc<ReferenceTypeLoc,
RValueReferenceTypeLoc,
RValueReferenceType> {
public:
SourceLocation getAmpAmpLoc() const {
return getSigilLoc();
}
void setAmpAmpLoc(SourceLocation Loc) {
setSigilLoc(Loc);
}
};
struct FunctionLocInfo {
SourceLocation LocalRangeBegin;
SourceLocation LocalRangeEnd;
bool TrailingReturn;
};
/// \brief Wrapper for source info for functions.
class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
FunctionTypeLoc,
FunctionType,
FunctionLocInfo> {
public:
SourceLocation getLocalRangeBegin() const {
return getLocalData()->LocalRangeBegin;
}
void setLocalRangeBegin(SourceLocation L) {
getLocalData()->LocalRangeBegin = L;
}
SourceLocation getLocalRangeEnd() const {
return getLocalData()->LocalRangeEnd;
}
void setLocalRangeEnd(SourceLocation L) {
getLocalData()->LocalRangeEnd = L;
}
bool getTrailingReturn() const {
return getLocalData()->TrailingReturn;
}
void setTrailingReturn(bool Trailing) {
getLocalData()->TrailingReturn = Trailing;
}
ArrayRef<ParmVarDecl *> getParams() const {
return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
}
// ParmVarDecls* are stored after Info, one for each argument.
ParmVarDecl **getParmArray() const {
return (ParmVarDecl**) getExtraLocalData();
}
unsigned getNumArgs() const {
if (isa<FunctionNoProtoType>(getTypePtr()))
return 0;
return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
}
ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
TypeLoc getResultLoc() const {
return getInnerTypeLoc();
}
SourceRange getLocalSourceRange() const {
return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLocalRangeBegin(Loc);
setLocalRangeEnd(Loc);
setTrailingReturn(false);
for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
setArg(i, NULL);
}
/// \brief Returns the size of the type source info data block that is
/// specific to this type.
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(ParmVarDecl*);
}
QualType getInnerType() const { return getTypePtr()->getResultType(); }
};
class FunctionProtoTypeLoc :
public InheritingConcreteTypeLoc<FunctionTypeLoc,
FunctionProtoTypeLoc,
FunctionProtoType> {
};
class FunctionNoProtoTypeLoc :
public InheritingConcreteTypeLoc<FunctionTypeLoc,
FunctionNoProtoTypeLoc,
FunctionNoProtoType> {
};
struct ArrayLocInfo {
SourceLocation LBracketLoc, RBracketLoc;
Expr *Size;
};
/// \brief Wrapper for source info for arrays.
class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ArrayTypeLoc,
ArrayType,
ArrayLocInfo> {
public:
SourceLocation getLBracketLoc() const {
return getLocalData()->LBracketLoc;
}
void setLBracketLoc(SourceLocation Loc) {
getLocalData()->LBracketLoc = Loc;
}
SourceLocation getRBracketLoc() const {
return getLocalData()->RBracketLoc;
}
void setRBracketLoc(SourceLocation Loc) {
getLocalData()->RBracketLoc = Loc;
}
SourceRange getBracketsRange() const {
return SourceRange(getLBracketLoc(), getRBracketLoc());
}
Expr *getSizeExpr() const {
return getLocalData()->Size;
}
void setSizeExpr(Expr *Size) {
getLocalData()->Size = Size;
}
TypeLoc getElementLoc() const {
return getInnerTypeLoc();
}
SourceRange getLocalSourceRange() const {
return SourceRange(getLBracketLoc(), getRBracketLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setLBracketLoc(Loc);
setRBracketLoc(Loc);
setSizeExpr(NULL);
}
QualType getInnerType() const { return getTypePtr()->getElementType(); }
};
class ConstantArrayTypeLoc :
public InheritingConcreteTypeLoc<ArrayTypeLoc,
ConstantArrayTypeLoc,
ConstantArrayType> {
};
class IncompleteArrayTypeLoc :
public InheritingConcreteTypeLoc<ArrayTypeLoc,
IncompleteArrayTypeLoc,
IncompleteArrayType> {
};
class DependentSizedArrayTypeLoc :
public InheritingConcreteTypeLoc<ArrayTypeLoc,
DependentSizedArrayTypeLoc,
DependentSizedArrayType> {
};
class VariableArrayTypeLoc :
public InheritingConcreteTypeLoc<ArrayTypeLoc,
VariableArrayTypeLoc,
VariableArrayType> {
};
// Location information for a TemplateName. Rudimentary for now.
struct TemplateNameLocInfo {
SourceLocation NameLoc;
};
struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
SourceLocation TemplateKWLoc;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
};
class TemplateSpecializationTypeLoc :
public ConcreteTypeLoc<UnqualTypeLoc,
TemplateSpecializationTypeLoc,
TemplateSpecializationType,
TemplateSpecializationLocInfo> {
public:
SourceLocation getTemplateKeywordLoc() const {
return getLocalData()->TemplateKWLoc;
}
void setTemplateKeywordLoc(SourceLocation Loc) {
getLocalData()->TemplateKWLoc = Loc;
}
SourceLocation getLAngleLoc() const {
return getLocalData()->LAngleLoc;
}
void setLAngleLoc(SourceLocation Loc) {
getLocalData()->LAngleLoc = Loc;
}
SourceLocation getRAngleLoc() const {
return getLocalData()->RAngleLoc;
}
void setRAngleLoc(SourceLocation Loc) {
getLocalData()->RAngleLoc = Loc;
}
unsigned getNumArgs() const {
return getTypePtr()->getNumArgs();
}
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
getArgInfos()[i] = AI;
}
TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
return getArgInfos()[i];
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
}
SourceLocation getTemplateNameLoc() const {
return getLocalData()->NameLoc;
}
void setTemplateNameLoc(SourceLocation Loc) {
getLocalData()->NameLoc = Loc;
}
/// \brief - Copy the location information from the given info.
void copy(TemplateSpecializationTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
// We're potentially copying Expr references here. We don't
// bother retaining them because TypeSourceInfos live forever, so
// as long as the Expr was retained when originally written into
// the TypeLoc, we're okay.
memcpy(Data, Loc.Data, size);
}
SourceRange getLocalSourceRange() const {
if (getTemplateKeywordLoc().isValid())
return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
else
return SourceRange(getTemplateNameLoc(), getRAngleLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setTemplateKeywordLoc(Loc);
setTemplateNameLoc(Loc);
setLAngleLoc(Loc);
setRAngleLoc(Loc);
initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
getArgInfos(), Loc);
}
static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
const TemplateArgument *Args,
TemplateArgumentLocInfo *ArgInfos,
SourceLocation Loc);
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(TemplateArgumentLocInfo);
}
private:
TemplateArgumentLocInfo *getArgInfos() const {
return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
}
};
//===----------------------------------------------------------------------===//
//
// All of these need proper implementations.
//
//===----------------------------------------------------------------------===//
// FIXME: size expression and attribute locations (or keyword if we
// ever fully support altivec syntax).
class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
VectorTypeLoc,
VectorType> {
};
// FIXME: size expression and attribute locations.
class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
ExtVectorTypeLoc,
ExtVectorType> {
};
// FIXME: attribute locations.
// For some reason, this isn't a subtype of VectorType.
class DependentSizedExtVectorTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DependentSizedExtVectorTypeLoc,
DependentSizedExtVectorType> {
};
// FIXME: location of the '_Complex' keyword.
class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
ComplexTypeLoc,
ComplexType> {
};
struct TypeofLocInfo {
SourceLocation TypeofLoc;
SourceLocation LParenLoc;
SourceLocation RParenLoc;
};
struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
};
struct TypeOfTypeLocInfo : public TypeofLocInfo {
TypeSourceInfo* UnderlyingTInfo;
};
template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
class TypeofLikeTypeLoc
: public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
public:
SourceLocation getTypeofLoc() const {
return this->getLocalData()->TypeofLoc;
}
void setTypeofLoc(SourceLocation Loc) {
this->getLocalData()->TypeofLoc = Loc;
}
SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc;
}
void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc;
}
SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc;
}
void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc;
}
SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
void setParensRange(SourceRange range) {
setLParenLoc(range.getBegin());
setRParenLoc(range.getEnd());
}
SourceRange getLocalSourceRange() const {
return SourceRange(getTypeofLoc(), getRParenLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setTypeofLoc(Loc);
setLParenLoc(Loc);
setRParenLoc(Loc);
}
};
class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
TypeOfExprType,
TypeOfExprTypeLocInfo> {
public:
Expr* getUnderlyingExpr() const {
return getTypePtr()->getUnderlyingExpr();
}
// Reimplemented to account for GNU/C++ extension
// typeof unary-expression
// where there are no parentheses.
SourceRange getLocalSourceRange() const;
};
class TypeOfTypeLoc
: public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
public:
QualType getUnderlyingType() const {
return this->getTypePtr()->getUnderlyingType();
}
TypeSourceInfo* getUnderlyingTInfo() const {
return this->getLocalData()->UnderlyingTInfo;
}
void setUnderlyingTInfo(TypeSourceInfo* TI) const {
this->getLocalData()->UnderlyingTInfo = TI;
}
};
// FIXME: location of the 'decltype' and parens.
class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DecltypeTypeLoc,
DecltypeType> {
public:
Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
};
struct UnaryTransformTypeLocInfo {
// FIXME: While there's only one unary transform right now, future ones may
// need different representations
SourceLocation KWLoc, LParenLoc, RParenLoc;
TypeSourceInfo *UnderlyingTInfo;
};
class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
UnaryTransformTypeLoc,
UnaryTransformType,
UnaryTransformTypeLocInfo> {
public:
SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
TypeSourceInfo* getUnderlyingTInfo() const {
return getLocalData()->UnderlyingTInfo;
}
void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
getLocalData()->UnderlyingTInfo = TInfo;
}
SourceRange getLocalSourceRange() const {
return SourceRange(getKWLoc(), getRParenLoc());
}
SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
void setParensRange(SourceRange Range) {
setLParenLoc(Range.getBegin());
setRParenLoc(Range.getEnd());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKWLoc(Loc);
setRParenLoc(Loc);
setLParenLoc(Loc);
}
};
class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
AutoTypeLoc,
AutoType> {
};
struct ElaboratedLocInfo {
SourceLocation ElaboratedKWLoc;
/// \brief Data associated with the nested-name-specifier location.
void *QualifierData;
};
class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
ElaboratedTypeLoc,
ElaboratedType,
ElaboratedLocInfo> {
public:
SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc;
}
void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc;
}
NestedNameSpecifierLoc getQualifierLoc() const {
return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
getLocalData()->QualifierData);
}
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
assert(QualifierLoc.getNestedNameSpecifier()
== getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceRange getLocalSourceRange() const {
if (getElaboratedKeywordLoc().isValid())
if (getQualifierLoc())
return SourceRange(getElaboratedKeywordLoc(),
getQualifierLoc().getEndLoc());
else
return SourceRange(getElaboratedKeywordLoc());
else
return getQualifierLoc().getSourceRange();
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
TypeLoc getNamedTypeLoc() const {
return getInnerTypeLoc();
}
QualType getInnerType() const {
return getTypePtr()->getNamedType();
}
void copy(ElaboratedTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
memcpy(Data, Loc.Data, size);
}
};
// This is exactly the structure of an ElaboratedTypeLoc whose inner
// type is some sort of TypeDeclTypeLoc.
struct DependentNameLocInfo : ElaboratedLocInfo {
SourceLocation NameLoc;
};
class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
DependentNameTypeLoc,
DependentNameType,
DependentNameLocInfo> {
public:
SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc;
}
void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc;
}
NestedNameSpecifierLoc getQualifierLoc() const {
return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
getLocalData()->QualifierData);
}
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
assert(QualifierLoc.getNestedNameSpecifier()
== getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceLocation getNameLoc() const {
return this->getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
SourceRange getLocalSourceRange() const {
if (getElaboratedKeywordLoc().isValid())
return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
else
return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
}
void copy(DependentNameTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
memcpy(Data, Loc.Data, size);
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
SourceLocation TemplateKWLoc;
SourceLocation LAngleLoc;
SourceLocation RAngleLoc;
// followed by a TemplateArgumentLocInfo[]
};
class DependentTemplateSpecializationTypeLoc :
public ConcreteTypeLoc<UnqualTypeLoc,
DependentTemplateSpecializationTypeLoc,
DependentTemplateSpecializationType,
DependentTemplateSpecializationLocInfo> {
public:
SourceLocation getElaboratedKeywordLoc() const {
return this->getLocalData()->ElaboratedKWLoc;
}
void setElaboratedKeywordLoc(SourceLocation Loc) {
this->getLocalData()->ElaboratedKWLoc = Loc;
}
NestedNameSpecifierLoc getQualifierLoc() const {
if (!getLocalData()->QualifierData)
return NestedNameSpecifierLoc();
return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
getLocalData()->QualifierData);
}
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
if (!QualifierLoc) {
// Even if we have a nested-name-specifier in the dependent
// template specialization type, we won't record the nested-name-specifier
// location information when this type-source location information is
// part of a nested-name-specifier.
getLocalData()->QualifierData = 0;
return;
}
assert(QualifierLoc.getNestedNameSpecifier()
== getTypePtr()->getQualifier() &&
"Inconsistent nested-name-specifier pointer");
getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
SourceLocation getTemplateKeywordLoc() const {
return getLocalData()->TemplateKWLoc;
}
void setTemplateKeywordLoc(SourceLocation Loc) {
getLocalData()->TemplateKWLoc = Loc;
}
SourceLocation getTemplateNameLoc() const {
return this->getLocalData()->NameLoc;
}
void setTemplateNameLoc(SourceLocation Loc) {
this->getLocalData()->NameLoc = Loc;
}
SourceLocation getLAngleLoc() const {
return this->getLocalData()->LAngleLoc;
}
void setLAngleLoc(SourceLocation Loc) {
this->getLocalData()->LAngleLoc = Loc;
}
SourceLocation getRAngleLoc() const {
return this->getLocalData()->RAngleLoc;
}
void setRAngleLoc(SourceLocation Loc) {
this->getLocalData()->RAngleLoc = Loc;
}
unsigned getNumArgs() const {
return getTypePtr()->getNumArgs();
}
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
getArgInfos()[i] = AI;
}
TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
return getArgInfos()[i];
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
}
SourceRange getLocalSourceRange() const {
if (getElaboratedKeywordLoc().isValid())
return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
else if (getQualifierLoc())
return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
else if (getTemplateKeywordLoc().isValid())
return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
else
return SourceRange(getTemplateNameLoc(), getRAngleLoc());
}
void copy(DependentTemplateSpecializationTypeLoc Loc) {
unsigned size = getFullDataSize();
assert(size == Loc.getFullDataSize());
memcpy(Data, Loc.Data, size);
}
void initializeLocal(ASTContext &Context, SourceLocation Loc);
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(TemplateArgumentLocInfo);
}
private:
TemplateArgumentLocInfo *getArgInfos() const {
return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
}
};
struct PackExpansionTypeLocInfo {
SourceLocation EllipsisLoc;
};
class PackExpansionTypeLoc
: public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
PackExpansionType, PackExpansionTypeLocInfo> {
public:
SourceLocation getEllipsisLoc() const {
return this->getLocalData()->EllipsisLoc;
}
void setEllipsisLoc(SourceLocation Loc) {
this->getLocalData()->EllipsisLoc = Loc;
}
SourceRange getLocalSourceRange() const {
return SourceRange(getEllipsisLoc(), getEllipsisLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setEllipsisLoc(Loc);
}
TypeLoc getPatternLoc() const {
return getInnerTypeLoc();
}
QualType getInnerType() const {
return this->getTypePtr()->getPattern();
}
};
struct AtomicTypeLocInfo {
SourceLocation KWLoc, LParenLoc, RParenLoc;
};
class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
AtomicType, AtomicTypeLocInfo> {
public:
TypeLoc getValueLoc() const {
return this->getInnerTypeLoc();
}
SourceRange getLocalSourceRange() const {
return SourceRange(getKWLoc(), getRParenLoc());
}
SourceLocation getKWLoc() const {
return this->getLocalData()->KWLoc;
}
void setKWLoc(SourceLocation Loc) {
this->getLocalData()->KWLoc = Loc;
}
SourceLocation getLParenLoc() const {
return this->getLocalData()->LParenLoc;
}
void setLParenLoc(SourceLocation Loc) {
this->getLocalData()->LParenLoc = Loc;
}
SourceLocation getRParenLoc() const {
return this->getLocalData()->RParenLoc;
}
void setRParenLoc(SourceLocation Loc) {
this->getLocalData()->RParenLoc = Loc;
}
SourceRange getParensRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
void setParensRange(SourceRange Range) {
setLParenLoc(Range.getBegin());
setRParenLoc(Range.getEnd());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setKWLoc(Loc);
setLParenLoc(Loc);
setRParenLoc(Loc);
}
QualType getInnerType() const {
return this->getTypePtr()->getValueType();
}
};
}
#endif