TypeLoc.cpp revision ddf889a2ad2888f1dea573987bbe952d9912c1a0
1b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
2b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//
3b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
4b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//
5b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
6b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
7b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//
8b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
9b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//
10b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//  This file defines the TypeLoc subclasses implementations.
11b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//
12b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
13b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis
1434a0447b8072e0da14c0980597da9d03a1495662John McCall#include "llvm/Support/raw_ostream.h"
150c411806d540f7158bf12fee5c10f7de2647de76Argyrios Kyrtzidis#include "clang/AST/TypeLocVisitor.h"
16cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall#include "clang/AST/Expr.h"
17ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor#include "llvm/Support/ErrorHandling.h"
18b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidisusing namespace clang;
19b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis
20b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
21b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis// TypeLoc Implementation
22b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
23b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis
2468006af18fb880cd8547ce797152111b810aa0baArgyrios Kyrtzidisnamespace {
2551bd803fbdade51d674598ed45da3d54190a656cJohn McCall  class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
2651bd803fbdade51d674598ed45da3d54190a656cJohn McCall  public:
2751bd803fbdade51d674598ed45da3d54190a656cJohn McCall#define ABSTRACT_TYPELOC(CLASS, PARENT)
2834a0447b8072e0da14c0980597da9d03a1495662John McCall#define TYPELOC(CLASS, PARENT) \
2951bd803fbdade51d674598ed45da3d54190a656cJohn McCall    SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
3051bd803fbdade51d674598ed45da3d54190a656cJohn McCall      return TyLoc.getSourceRange(); \
3151bd803fbdade51d674598ed45da3d54190a656cJohn McCall    }
3268006af18fb880cd8547ce797152111b810aa0baArgyrios Kyrtzidis#include "clang/AST/TypeLocNodes.def"
3351bd803fbdade51d674598ed45da3d54190a656cJohn McCall  };
3468006af18fb880cd8547ce797152111b810aa0baArgyrios Kyrtzidis}
3568006af18fb880cd8547ce797152111b810aa0baArgyrios Kyrtzidis
3651bd803fbdade51d674598ed45da3d54190a656cJohn McCallSourceRange TypeLoc::getSourceRangeImpl(TypeLoc TL) {
3751bd803fbdade51d674598ed45da3d54190a656cJohn McCall  if (TL.isNull()) return SourceRange();
3851bd803fbdade51d674598ed45da3d54190a656cJohn McCall  return TypeLocRanger().Visit(TL);
39b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis}
40b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis
41b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidisnamespace {
4251bd803fbdade51d674598ed45da3d54190a656cJohn McCall  class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
4351bd803fbdade51d674598ed45da3d54190a656cJohn McCall  public:
4451bd803fbdade51d674598ed45da3d54190a656cJohn McCall#define ABSTRACT_TYPELOC(CLASS, PARENT)
4534a0447b8072e0da14c0980597da9d03a1495662John McCall#define TYPELOC(CLASS, PARENT) \
4651bd803fbdade51d674598ed45da3d54190a656cJohn McCall    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
4751bd803fbdade51d674598ed45da3d54190a656cJohn McCall      return TyLoc.getFullDataSize(); \
4851bd803fbdade51d674598ed45da3d54190a656cJohn McCall    }
49b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis#include "clang/AST/TypeLocNodes.def"
5051bd803fbdade51d674598ed45da3d54190a656cJohn McCall  };
51b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis}
52b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis
53b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis/// \brief Returns the size of the type source info data block.
5434a0447b8072e0da14c0980597da9d03a1495662John McCallunsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
5534a0447b8072e0da14c0980597da9d03a1495662John McCall  if (Ty.isNull()) return 0;
5634a0447b8072e0da14c0980597da9d03a1495662John McCall  return TypeSizer().Visit(TypeLoc(Ty, 0));
57b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis}
58b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis
59b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidisnamespace {
6051bd803fbdade51d674598ed45da3d54190a656cJohn McCall  class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
6151bd803fbdade51d674598ed45da3d54190a656cJohn McCall  public:
6251bd803fbdade51d674598ed45da3d54190a656cJohn McCall#define ABSTRACT_TYPELOC(CLASS, PARENT)
6351bd803fbdade51d674598ed45da3d54190a656cJohn McCall#define TYPELOC(CLASS, PARENT) \
6451bd803fbdade51d674598ed45da3d54190a656cJohn McCall    TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
6551bd803fbdade51d674598ed45da3d54190a656cJohn McCall      return TyLoc.getNextTypeLoc(); \
6651bd803fbdade51d674598ed45da3d54190a656cJohn McCall    }
67b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis#include "clang/AST/TypeLocNodes.def"
6851bd803fbdade51d674598ed45da3d54190a656cJohn McCall  };
69b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis}
70b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis
71b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
72b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
7351bd803fbdade51d674598ed45da3d54190a656cJohn McCallTypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
7451bd803fbdade51d674598ed45da3d54190a656cJohn McCall  return NextLoc().Visit(TL);
754ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall}
764ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall
774ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCallnamespace {
7851bd803fbdade51d674598ed45da3d54190a656cJohn McCall  struct TypeLocInitializer : public TypeLocVisitor<TypeLocInitializer> {
7951bd803fbdade51d674598ed45da3d54190a656cJohn McCall    SourceLocation Loc;
8051bd803fbdade51d674598ed45da3d54190a656cJohn McCall    TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {}
814ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall
8251bd803fbdade51d674598ed45da3d54190a656cJohn McCall#define ABSTRACT_TYPELOC(CLASS, PARENT)
834ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall#define TYPELOC(CLASS, PARENT) \
8451bd803fbdade51d674598ed45da3d54190a656cJohn McCall    void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
8551bd803fbdade51d674598ed45da3d54190a656cJohn McCall      TyLoc.initializeLocal(Loc); \
8651bd803fbdade51d674598ed45da3d54190a656cJohn McCall    }
874ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall#include "clang/AST/TypeLocNodes.def"
8851bd803fbdade51d674598ed45da3d54190a656cJohn McCall  };
894ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall}
904ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall
9151bd803fbdade51d674598ed45da3d54190a656cJohn McCall/// \brief Initializes a type location, and all of its children
9251bd803fbdade51d674598ed45da3d54190a656cJohn McCall/// recursively, as if the entire tree had been written in the
9351bd803fbdade51d674598ed45da3d54190a656cJohn McCall/// given location.
944ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCallvoid TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) {
954ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall  do {
964ce74bd425dccd9d9ad6ccfc9ffbc01698a6e71aJohn McCall    TypeLocInitializer(Loc).Visit(TL);
97a4ee4429e2e3d974edd121e26108d2ce6378c751Daniel Dunbar  } while ((TL = TL.getNextTypeLoc()));
98b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidis}
99ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
100ed97649e9574b9d854fa4d6109c9333ae0993554John McCallnamespace {
101ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
102ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    // Overload resolution does the real work for us.
103ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
104ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    static bool isTypeSpec(TypeLoc _) { return false; }
105ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
106ed97649e9574b9d854fa4d6109c9333ae0993554John McCall#define ABSTRACT_TYPELOC(CLASS, PARENT)
107ed97649e9574b9d854fa4d6109c9333ae0993554John McCall#define TYPELOC(CLASS, PARENT) \
108ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
109ed97649e9574b9d854fa4d6109c9333ae0993554John McCall      return isTypeSpec(TyLoc); \
110ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    }
111ed97649e9574b9d854fa4d6109c9333ae0993554John McCall#include "clang/AST/TypeLocNodes.def"
112ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  };
113ed97649e9574b9d854fa4d6109c9333ae0993554John McCall}
114ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
115ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
116ed97649e9574b9d854fa4d6109c9333ae0993554John McCall/// \brief Determines if the given type loc corresponds to a
117ed97649e9574b9d854fa4d6109c9333ae0993554John McCall/// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
118ed97649e9574b9d854fa4d6109c9333ae0993554John McCall/// the type hierarchy, this is made somewhat complicated.
119ed97649e9574b9d854fa4d6109c9333ae0993554John McCall///
120ed97649e9574b9d854fa4d6109c9333ae0993554John McCall/// There are a lot of types that currently use TypeSpecTypeLoc
121ed97649e9574b9d854fa4d6109c9333ae0993554John McCall/// because it's a convenient base class.  Ideally we would not accept
122ed97649e9574b9d854fa4d6109c9333ae0993554John McCall/// those here, but ideally we would have better implementations for
123ed97649e9574b9d854fa4d6109c9333ae0993554John McCall/// them.
124ed97649e9574b9d854fa4d6109c9333ae0993554John McCallbool TypeSpecTypeLoc::classof(const TypeLoc *TL) {
125ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  if (TL->getType().hasLocalQualifiers()) return false;
126ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  return TSTChecker().Visit(*TL);
127ed97649e9574b9d854fa4d6109c9333ae0993554John McCall}
128cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall
129cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall// Reimplemented to account for GNU/C++ extension
130cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall//     typeof unary-expression
131cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall// where there are no parentheses.
132cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCallSourceRange TypeOfExprTypeLoc::getSourceRange() const {
133cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall  if (getRParenLoc().isValid())
134cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall    return SourceRange(getTypeofLoc(), getRParenLoc());
135cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall  else
136cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall    return SourceRange(getTypeofLoc(),
137cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall                       getUnderlyingExpr()->getSourceRange().getEnd());
138cfb708c354e2f30ccc5cba9d644650f408a1ec3eJohn McCall}
139ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor
140ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor
141ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas GregorTypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
142ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor  if (needsExtraLocalData())
143ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
144ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor  else {
145ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    switch (getTypePtr()->getKind()) {
146ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Void:
147ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_void;
148ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Bool:
149ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_bool;
150ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Char_U:
151ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Char_S:
152ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_char;
153ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Char16:
154ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_char16;
155ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Char32:
156ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_char32;
157ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::WChar:
158ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_wchar;
159ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Float:
160ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_float;
161ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Double:
162ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::LongDouble:
163ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_double;
164ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::UndeducedAuto:
165ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_auto;
166ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor
167ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::UChar:
168ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::UShort:
169ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::UInt:
170ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::ULong:
171ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::ULongLong:
172ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::UInt128:
173ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::SChar:
174ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Short:
175ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Int:
176ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Long:
177ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::LongLong:
178ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Int128:
179ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      llvm_unreachable("Builtin type needs extra local data!");
180ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      // Fall through, if the impossible happens.
181ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor
182ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::NullPtr:
183ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Overload:
184ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::Dependent:
185ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::ObjCId:
186ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::ObjCClass:
187ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    case BuiltinType::ObjCSel:
188ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor      return TST_unspecified;
189ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor    }
190ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor  }
191ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor
192ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor  return TST_unspecified;
193ddf889a2ad2888f1dea573987bbe952d9912c1a0Douglas Gregor}
194