//===--- Type.h - C Language Family Type Representation ---------*- 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 Type interface and subclasses.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_TYPE_H
#define LLVM_CLANG_AST_TYPE_H
#include "llvm/Support/Casting.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/Bitcode/SerializationFwd.h"
using llvm::isa;
using llvm::cast;
using llvm::cast_or_null;
using llvm::dyn_cast;
using llvm::dyn_cast_or_null;
namespace clang {
class ASTContext;
class Type;
class TypedefDecl;
class TagDecl;
class RecordDecl;
class EnumDecl;
class FieldDecl;
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class ObjCMethodDecl;
class Expr;
class SourceLocation;
class PointerType;
class ReferenceType;
class VectorType;
class ArrayType;
class ConstantArrayType;
class VariableArrayType;
class RecordType;
class ComplexType;
class TagType;
class FunctionType;
class OCUVectorType;
class BuiltinType;
class ObjCQualifiedInterfaceType;
class StmtIteratorBase;
/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
/// their own: instead each reference to a type stores the qualifiers. This
/// greatly reduces the number of nodes we need to allocate for types (for
/// example we only need one for 'int', 'const int', 'volatile int',
/// 'const volatile int', etc).
///
/// As an added efficiency bonus, instead of making this a pair, we just store
/// the three bits we care about in the low bits of the pointer. To handle the
/// packing/unpacking, we make QualType be a simple wrapper class that acts like
/// a smart pointer.
class QualType {
uintptr_t ThePtr;
public:
enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
Const = 0x1,
Restrict = 0x2,
Volatile = 0x4,
CVRFlags = Const|Restrict|Volatile
};
QualType() : ThePtr(0) {}
QualType(Type *Ptr, unsigned Quals) {
assert((Quals & ~CVRFlags) == 0 && "Invalid type qualifiers!");
ThePtr = reinterpret_cast<uintptr_t>(Ptr);
assert((ThePtr & CVRFlags) == 0 && "Type pointer not 8-byte aligned?");
ThePtr |= Quals;
}
static QualType getFromOpaquePtr(void *Ptr) {
QualType T;
T.ThePtr = reinterpret_cast<uintptr_t>(Ptr);
return T;
}
unsigned getQualifiers() const {
return ThePtr & CVRFlags;
}
Type *getTypePtr() const {
return reinterpret_cast<Type*>(ThePtr & ~CVRFlags);
}
void *getAsOpaquePtr() const {
return reinterpret_cast<void*>(ThePtr);
}
Type &operator*() const {
return *getTypePtr();
}
Type *operator->() const {
return getTypePtr();
}
/// isNull - Return true if this QualType doesn't point to a type yet.
bool isNull() const {
return ThePtr == 0;
}
bool isConstQualified() const {
return (ThePtr & Const) ? true : false;
}
bool isVolatileQualified() const {
return (ThePtr & Volatile) ? true : false;
}
bool isRestrictQualified() const {
return (ThePtr & Restrict) ? true : false;
}
/// addConst/addVolatile/addRestrict - add the specified type qual to this
/// QualType.
void addConst() { ThePtr |= Const; }
void addVolatile() { ThePtr |= Volatile; }
void addRestrict() { ThePtr |= Restrict; }
QualType getQualifiedType(unsigned TQs) const {
return QualType(getTypePtr(), TQs);
}
QualType getUnqualifiedType() const {
return QualType(getTypePtr(), 0);
}
/// operator==/!= - Indicate whether the specified types and qualifiers are
/// identical.