//===--- 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/TemplateBase.h"
namespace clang {
class ParmVarDecl;
class DeclaratorInfo;
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
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(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);
}
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 full source range.
SourceRange getFullSourceRange() const {
SourceLocation End = getSourceRange().getEnd();
TypeLoc Cur = *this;
while (true) {
TypeLoc Next = Cur.getNextTypeLoc();
if (Next.isNull()) break;
Cur = Next;
}
return SourceRange(Cur.getSourceRange().getBegin(), End);
}
/// \brief Get the local source range.
SourceRange getSourceRange() const {
return getSourceRangeImpl(*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
/// \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(SourceLocation Loc) const {
initializeImpl(*this, Loc);
}
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(TypeLoc TL, SourceLocation Loc);
static TypeLoc getNextTypeLocImpl(TypeLoc TL);
static SourceRange getSourceRangeImpl(TypeLoc TL);
};
/// \brief Wrapper of type source information for a type with
/// no direct quqlaifiers.
class UnqualTypeLoc : public TypeLoc {
public:
UnqualTypeLoc() {}
UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
Type *getTypePtr() const {
return reinterpret_cast<Type*>(Ty);
}
TypeLocClass getTypeLocClass() const {
return (TypeLocClass) getTypePtr()->getTypeClass();
}
static bool classof(const