summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h')
-rw-r--r--contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h1817
1 files changed, 1817 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h
new file mode 100644
index 0000000..aab87be
--- /dev/null
+++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h
@@ -0,0 +1,1817 @@
+//===--- 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"
+#include "llvm/Support/Compiler.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 LLVM_READONLY {
+ return SourceRange(getBeginLoc(), getEndLoc());
+ }
+ SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return 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 {
+ TagDecl *D = getDecl();
+ return D->isCompleteDefinition() &&
+ (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
+ }
+};
+
+/// \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
OpenPOWER on IntegriCloud