TypeLoc.cpp revision 198112
1198092Srdivacky//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===// 2198092Srdivacky// 3198092Srdivacky// The LLVM Compiler Infrastructure 4198092Srdivacky// 5198092Srdivacky// This file is distributed under the University of Illinois Open Source 6198092Srdivacky// License. See LICENSE.TXT for details. 7198092Srdivacky// 8198092Srdivacky//===----------------------------------------------------------------------===// 9198092Srdivacky// 10198092Srdivacky// This file defines the TypeLoc subclasses implementations. 11198092Srdivacky// 12198092Srdivacky//===----------------------------------------------------------------------===// 13198092Srdivacky 14198112Srdivacky#include "llvm/Support/raw_ostream.h" 15198092Srdivacky#include "clang/AST/TypeLocVisitor.h" 16198092Srdivackyusing namespace clang; 17198092Srdivacky 18198092Srdivacky//===----------------------------------------------------------------------===// 19198092Srdivacky// TypeLoc Implementation 20198092Srdivacky//===----------------------------------------------------------------------===// 21198092Srdivacky 22198092Srdivackynamespace { 23198092Srdivacky 24198092Srdivacky/// \brief Return the source range for the visited TypeSpecLoc. 25198092Srdivackyclass TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> { 26198092Srdivackypublic: 27198092Srdivacky#define ABSTRACT_TYPELOC(CLASS) 28198112Srdivacky#define TYPELOC(CLASS, PARENT) \ 29198092Srdivacky SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); } 30198092Srdivacky#include "clang/AST/TypeLocNodes.def" 31198092Srdivacky 32198092Srdivacky SourceRange VisitTypeLoc(TypeLoc TyLoc) { 33198092Srdivacky assert(0 && "A typeloc wrapper was not handled!"); 34198092Srdivacky return SourceRange(); 35198092Srdivacky } 36198092Srdivacky}; 37198092Srdivacky 38198092Srdivacky} 39198092Srdivacky 40198092SrdivackySourceRange TypeLoc::getSourceRange() const { 41198092Srdivacky if (isNull()) 42198092Srdivacky return SourceRange(); 43198092Srdivacky return TypeLocRanger().Visit(*this); 44198092Srdivacky} 45198092Srdivacky 46198092Srdivacky/// \brief Find the TypeSpecLoc that is part of this TypeLoc. 47198092SrdivackyTypeSpecLoc TypeLoc::getTypeSpecLoc() const { 48198092Srdivacky if (isNull()) 49198092Srdivacky return TypeSpecLoc(); 50198112Srdivacky UnqualTypeLoc Cur = getUnqualifiedLoc(); 51198112Srdivacky if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(&Cur)) 52198092Srdivacky return DL->getTypeSpecLoc(); 53198112Srdivacky return cast<TypeSpecLoc>(Cur); 54198092Srdivacky} 55198092Srdivacky 56198092Srdivackynamespace { 57198092Srdivacky 58198092Srdivacky/// \brief Report the full source info data size for the visited TypeLoc. 59198092Srdivackyclass TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> { 60198092Srdivackypublic: 61198092Srdivacky#define ABSTRACT_TYPELOC(CLASS) 62198112Srdivacky#define TYPELOC(CLASS, PARENT) \ 63198092Srdivacky unsigned Visit##CLASS(CLASS TyLoc) { return TyLoc.getFullDataSize(); } 64198092Srdivacky#include "clang/AST/TypeLocNodes.def" 65198092Srdivacky 66198092Srdivacky unsigned VisitTypeLoc(TypeLoc TyLoc) { 67198092Srdivacky assert(0 && "A type loc wrapper was not handled!"); 68198092Srdivacky return 0; 69198092Srdivacky } 70198092Srdivacky}; 71198092Srdivacky 72198092Srdivacky} 73198092Srdivacky 74198092Srdivacky/// \brief Returns the size of the type source info data block. 75198112Srdivackyunsigned TypeLoc::getFullDataSizeForType(QualType Ty) { 76198112Srdivacky if (Ty.isNull()) return 0; 77198112Srdivacky return TypeSizer().Visit(TypeLoc(Ty, 0)); 78198092Srdivacky} 79198092Srdivacky 80198092Srdivackynamespace { 81198092Srdivacky 82198092Srdivacky/// \brief Return the "next" TypeLoc for the visited TypeLoc, e.g for "int*" the 83198092Srdivacky/// TypeLoc is a PointerLoc and next TypeLoc is for "int". 84198092Srdivackyclass NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> { 85198092Srdivackypublic: 86198112Srdivacky#define TYPELOC(CLASS, PARENT) 87198092Srdivacky#define DECLARATOR_TYPELOC(CLASS, TYPE) \ 88198112Srdivacky TypeLoc Visit##CLASS(CLASS TyLoc); 89198092Srdivacky#include "clang/AST/TypeLocNodes.def" 90198092Srdivacky 91198092Srdivacky TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); } 92198092Srdivacky TypeLoc VisitObjCProtocolListLoc(ObjCProtocolListLoc TL); 93198112Srdivacky TypeLoc VisitQualifiedLoc(QualifiedLoc TyLoc) { 94198112Srdivacky return TyLoc.getUnqualifiedLoc(); 95198112Srdivacky } 96198092Srdivacky 97198092Srdivacky TypeLoc VisitTypeLoc(TypeLoc TyLoc) { 98198092Srdivacky assert(0 && "A declarator loc wrapper was not handled!"); 99198092Srdivacky return TypeLoc(); 100198092Srdivacky } 101198092Srdivacky}; 102198092Srdivacky 103198092Srdivacky} 104198092Srdivacky 105198092SrdivackyTypeLoc NextLoc::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) { 106198092Srdivacky return TL.getBaseTypeLoc(); 107198092Srdivacky} 108198092Srdivacky 109198092SrdivackyTypeLoc NextLoc::VisitPointerLoc(PointerLoc TL) { 110198092Srdivacky return TL.getPointeeLoc(); 111198092Srdivacky} 112198092SrdivackyTypeLoc NextLoc::VisitMemberPointerLoc(MemberPointerLoc TL) { 113198092Srdivacky return TL.getPointeeLoc(); 114198092Srdivacky} 115198092SrdivackyTypeLoc NextLoc::VisitBlockPointerLoc(BlockPointerLoc TL) { 116198092Srdivacky return TL.getPointeeLoc(); 117198092Srdivacky} 118198092SrdivackyTypeLoc NextLoc::VisitReferenceLoc(ReferenceLoc TL) { 119198092Srdivacky return TL.getPointeeLoc(); 120198092Srdivacky} 121198092SrdivackyTypeLoc NextLoc::VisitFunctionLoc(FunctionLoc TL) { 122198092Srdivacky return TL.getResultLoc(); 123198092Srdivacky} 124198092SrdivackyTypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) { 125198092Srdivacky return TL.getElementLoc(); 126198092Srdivacky} 127198092Srdivacky 128198092Srdivacky/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the 129198092Srdivacky/// TypeLoc is a PointerLoc and next TypeLoc is for "int". 130198092SrdivackyTypeLoc TypeLoc::getNextTypeLoc() const { 131198112Srdivacky //llvm::errs() << "getNextTypeLoc: Ty=" << Ty << ", Data=" << Data << "\n"; 132198112Srdivacky TypeLoc Tmp = NextLoc().Visit(*this); 133198112Srdivacky //llvm::errs() << " result: Ty=" << Tmp.Ty << ", Data=" << Tmp.Data << "\n"; 134198112Srdivacky return Tmp; 135198092Srdivacky} 136198092Srdivacky 137198092Srdivacky//===----------------------------------------------------------------------===// 138198092Srdivacky// TypeSpecLoc Implementation 139198092Srdivacky//===----------------------------------------------------------------------===// 140198092Srdivacky 141198092Srdivackynamespace { 142198092Srdivackyclass TypeSpecChecker : public TypeLocVisitor<TypeSpecChecker, bool> { 143198092Srdivackypublic: 144198092Srdivacky bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; } 145198092Srdivacky}; 146198092Srdivacky 147198092Srdivacky} 148198092Srdivacky 149198112Srdivackybool TypeSpecLoc::classof(const UnqualTypeLoc *TL) { 150198092Srdivacky return TypeSpecChecker().Visit(*TL); 151198092Srdivacky} 152198092Srdivacky 153198092Srdivacky//===----------------------------------------------------------------------===// 154198092Srdivacky// DeclaratorLoc Implementation 155198092Srdivacky//===----------------------------------------------------------------------===// 156198092Srdivacky 157198092Srdivackynamespace { 158198092Srdivacky 159198092Srdivacky/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc. 160198092Srdivackyclass TypeSpecGetter : public TypeLocVisitor<TypeSpecGetter, TypeSpecLoc> { 161198092Srdivackypublic: 162198112Srdivacky#define TYPELOC(CLASS, PARENT) 163198092Srdivacky#define DECLARATOR_TYPELOC(CLASS, TYPE) \ 164198092Srdivacky TypeSpecLoc Visit##CLASS(CLASS TyLoc) { return TyLoc.getTypeSpecLoc(); } 165198092Srdivacky#include "clang/AST/TypeLocNodes.def" 166198092Srdivacky 167198092Srdivacky TypeSpecLoc VisitTypeLoc(TypeLoc TyLoc) { 168198092Srdivacky assert(0 && "A declarator loc wrapper was not handled!"); 169198092Srdivacky return TypeSpecLoc(); 170198092Srdivacky } 171198112Srdivacky 172198112Srdivacky TypeSpecLoc VisitQualifiedLoc(QualifiedLoc TyLoc) { 173198112Srdivacky return Visit(TyLoc.getUnqualifiedLoc()); 174198112Srdivacky } 175198092Srdivacky}; 176198092Srdivacky 177198092Srdivacky} 178198092Srdivacky 179198092Srdivacky/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc. 180198092SrdivackyTypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const { 181198092Srdivacky return TypeSpecGetter().Visit(*this); 182198092Srdivacky} 183198092Srdivacky 184198092Srdivackynamespace { 185198092Srdivacky 186198092Srdivackyclass DeclaratorLocChecker : public TypeLocVisitor<DeclaratorLocChecker, bool> { 187198092Srdivackypublic: 188198092Srdivacky bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; } 189198092Srdivacky}; 190198092Srdivacky 191198092Srdivacky} 192198092Srdivacky 193198112Srdivackybool DeclaratorLoc::classof(const UnqualTypeLoc *TL) { 194198092Srdivacky return DeclaratorLocChecker().Visit(*TL); 195198092Srdivacky} 196198092Srdivacky 197198092Srdivacky//===----------------------------------------------------------------------===// 198198092Srdivacky// DefaultTypeSpecLoc Implementation 199198092Srdivacky//===----------------------------------------------------------------------===// 200198092Srdivacky 201198092Srdivackynamespace { 202198092Srdivacky 203198092Srdivackyclass DefaultTypeSpecLocChecker : 204198092Srdivacky public TypeLocVisitor<DefaultTypeSpecLocChecker, bool> { 205198092Srdivackypublic: 206198092Srdivacky bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; } 207198092Srdivacky}; 208198092Srdivacky 209198092Srdivacky} 210198092Srdivacky 211198112Srdivackybool DefaultTypeSpecLoc::classofType(const Type *Ty) { 212198112Srdivacky return 213198112Srdivacky DefaultTypeSpecLocChecker().Visit(UnqualTypeLoc(const_cast<Type*>(Ty), 0)); 214198092Srdivacky} 215198112Srdivacky 216