TypeLoc.cpp revision 198398
1//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the TypeLoc subclasses implementations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Support/raw_ostream.h"
15#include "clang/AST/TypeLocVisitor.h"
16using namespace clang;
17
18//===----------------------------------------------------------------------===//
19// TypeLoc Implementation
20//===----------------------------------------------------------------------===//
21
22namespace {
23  class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
24  public:
25#define ABSTRACT_TYPELOC(CLASS, PARENT)
26#define TYPELOC(CLASS, PARENT) \
27    SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
28      return TyLoc.getSourceRange(); \
29    }
30#include "clang/AST/TypeLocNodes.def"
31  };
32}
33
34SourceRange TypeLoc::getSourceRangeImpl(TypeLoc TL) {
35  if (TL.isNull()) return SourceRange();
36  return TypeLocRanger().Visit(TL);
37}
38
39namespace {
40  class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
41  public:
42#define ABSTRACT_TYPELOC(CLASS, PARENT)
43#define TYPELOC(CLASS, PARENT) \
44    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
45      return TyLoc.getFullDataSize(); \
46    }
47#include "clang/AST/TypeLocNodes.def"
48  };
49}
50
51/// \brief Returns the size of the type source info data block.
52unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
53  if (Ty.isNull()) return 0;
54  return TypeSizer().Visit(TypeLoc(Ty, 0));
55}
56
57namespace {
58  class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
59  public:
60#define ABSTRACT_TYPELOC(CLASS, PARENT)
61#define TYPELOC(CLASS, PARENT) \
62    TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
63      return TyLoc.getNextTypeLoc(); \
64    }
65#include "clang/AST/TypeLocNodes.def"
66  };
67}
68
69/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
70/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
71TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
72  return NextLoc().Visit(TL);
73}
74
75namespace {
76  struct TypeLocInitializer : public TypeLocVisitor<TypeLocInitializer> {
77    SourceLocation Loc;
78    TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {}
79
80#define ABSTRACT_TYPELOC(CLASS, PARENT)
81#define TYPELOC(CLASS, PARENT) \
82    void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
83      TyLoc.initializeLocal(Loc); \
84    }
85#include "clang/AST/TypeLocNodes.def"
86  };
87}
88
89/// \brief Initializes a type location, and all of its children
90/// recursively, as if the entire tree had been written in the
91/// given location.
92void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) {
93  do {
94    TypeLocInitializer(Loc).Visit(TL);
95  } while ((TL = TL.getNextTypeLoc()));
96}
97