Clone the full Type hierarchy into the TypeLoc hierarchy.  Normalize
TypeLoc class names to be $(Type classname)Loc.  Rewrite the visitor.
Provide skeleton implementations for all the new TypeLocs.

Handle all cases in PCH.  Handle a few more cases when inserting
location information in SemaType.

It should be extremely straightforward to add new location information
to existing TypeLoc objects now.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84386 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 9d7d3d0..0c413f6 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -336,8 +336,15 @@
 //===----------------------------------------------------------------------===//
 
 SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
-  if (DeclInfo)
-    return DeclInfo->getTypeLoc().getTypeSpecRange().getBegin();
+  if (DeclInfo) {
+    TypeLoc TL = DeclInfo->getTypeLoc();
+    while (true) {
+      TypeLoc NextTL = TL.getNextTypeLoc();
+      if (!NextTL)
+        return TL.getSourceRange().getBegin();
+      TL = NextTL;
+    }
+  }
   return SourceLocation();
 }
 
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index c216a29..7e6b110 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -20,55 +20,32 @@
 //===----------------------------------------------------------------------===//
 
 namespace {
-
-/// \brief Return the source range for the visited TypeSpecLoc.
-class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
-public:
-#define ABSTRACT_TYPELOC(CLASS)
+  class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
+  public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
 #define TYPELOC(CLASS, PARENT) \
-    SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); }
+    SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return TyLoc.getSourceRange(); \
+    }
 #include "clang/AST/TypeLocNodes.def"
-
-  SourceRange VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A typeloc wrapper was not handled!");
-    return SourceRange();
-  }
-};
-
+  };
 }
 
-SourceRange TypeLoc::getSourceRange() const {
-  if (isNull())
-    return SourceRange();
-  return TypeLocRanger().Visit(*this);
-}
-
-/// \brief Find the TypeSpecLoc that is part of this TypeLoc.
-TypeSpecLoc TypeLoc::getTypeSpecLoc() const {
-  if (isNull())
-    return TypeSpecLoc();
-  UnqualTypeLoc Cur = getUnqualifiedLoc();
-  if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(&Cur))
-    return DL->getTypeSpecLoc();
-  return cast<TypeSpecLoc>(Cur);
+SourceRange TypeLoc::getSourceRangeImpl(TypeLoc TL) {
+  if (TL.isNull()) return SourceRange();
+  return TypeLocRanger().Visit(TL);
 }
 
 namespace {
-
-/// \brief Report the full source info data size for the visited TypeLoc.
-class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
-public:
-#define ABSTRACT_TYPELOC(CLASS)
+  class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
+  public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
 #define TYPELOC(CLASS, PARENT) \
-    unsigned Visit##CLASS(CLASS TyLoc) { return TyLoc.getFullDataSize(); }
+    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return TyLoc.getFullDataSize(); \
+    }
 #include "clang/AST/TypeLocNodes.def"
-
-  unsigned VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A type loc wrapper was not handled!");
-    return 0;
-  }
-};
-
+  };
 }
 
 /// \brief Returns the size of the type source info data block.
@@ -78,153 +55,42 @@
 }
 
 namespace {
-
-/// \brief Return the "next" TypeLoc for the visited TypeLoc, e.g for "int*" the
-/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
-class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
-public:
-#define TYPELOC(CLASS, PARENT)
-#define DECLARATOR_TYPELOC(CLASS, TYPE) \
-  TypeLoc Visit##CLASS(CLASS TyLoc);
+  class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
+  public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return TyLoc.getNextTypeLoc(); \
+    }
 #include "clang/AST/TypeLocNodes.def"
-
-  TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); }
-  TypeLoc VisitObjCProtocolListLoc(ObjCProtocolListLoc TL);
-  TypeLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
-    return TyLoc.getNextTypeLoc();
-  }
-
-  TypeLoc VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A declarator loc wrapper was not handled!");
-    return TypeLoc();
-  }
-};
-
-}
-
-TypeLoc NextLoc::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) {
-  return TL.getNextTypeLoc();
-}
-
-TypeLoc NextLoc::VisitPointerLoc(PointerLoc TL) {
-  return TL.getNextTypeLoc();
-}
-TypeLoc NextLoc::VisitMemberPointerLoc(MemberPointerLoc TL) {
-  return TL.getNextTypeLoc();
-}
-TypeLoc NextLoc::VisitBlockPointerLoc(BlockPointerLoc TL) {
-  return TL.getNextTypeLoc();
-}
-TypeLoc NextLoc::VisitReferenceLoc(ReferenceLoc TL) {
-  return TL.getNextTypeLoc();
-}
-TypeLoc NextLoc::VisitFunctionLoc(FunctionLoc TL) {
-  return TL.getNextTypeLoc();
-}
-TypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) {
-  return TL.getNextTypeLoc();
+  };
 }
 
 /// \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 TypeLoc::getNextTypeLoc() const {
-  return NextLoc().Visit(*this);
+TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
+  return NextLoc().Visit(TL);
 }
 
 namespace {
-struct TypeLocInitializer : public TypeLocVisitor<TypeLocInitializer> {
-  SourceLocation Loc;
-  TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {}
+  struct TypeLocInitializer : public TypeLocVisitor<TypeLocInitializer> {
+    SourceLocation Loc;
+    TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {}
   
-#define ABSTRACT_TYPELOC(CLASS)
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
 #define TYPELOC(CLASS, PARENT) \
-  void Visit##CLASS(CLASS TyLoc) { TyLoc.initializeLocal(Loc); }
+    void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      TyLoc.initializeLocal(Loc); \
+    }
 #include "clang/AST/TypeLocNodes.def"
-};
+  };
 }
 
+/// \brief Initializes a type location, and all of its children
+/// recursively, as if the entire tree had been written in the
+/// given location.
 void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) {
   do {
     TypeLocInitializer(Loc).Visit(TL);
   } while (TL = TL.getNextTypeLoc());
 }
-
-//===----------------------------------------------------------------------===//
-// TypeSpecLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-class TypeSpecChecker : public TypeLocVisitor<TypeSpecChecker, bool> {
-public:
-  bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; }
-};
-
-}
-
-bool TypeSpecLoc::classof(const UnqualTypeLoc *TL) {
-  return TypeSpecChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// DeclaratorLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc.
-class TypeSpecGetter : public TypeLocVisitor<TypeSpecGetter, TypeSpecLoc> {
-public:
-#define TYPELOC(CLASS, PARENT)
-#define DECLARATOR_TYPELOC(CLASS, TYPE) \
-    TypeSpecLoc Visit##CLASS(CLASS TyLoc) { return TyLoc.getTypeSpecLoc(); }
-#include "clang/AST/TypeLocNodes.def"
-
-  TypeSpecLoc VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A declarator loc wrapper was not handled!");
-    return TypeSpecLoc();
-  }
-
-  TypeSpecLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
-    return Visit(TyLoc.getUnqualifiedLoc());
-  }
-};
-
-}
-
-/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc.
-TypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const {
-  return TypeSpecGetter().Visit(*this);
-}
-
-namespace {
-
-class DeclaratorLocChecker : public TypeLocVisitor<DeclaratorLocChecker, bool> {
-public:
-  bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; }
-};
-
-}
-
-bool DeclaratorLoc::classof(const UnqualTypeLoc *TL) {
-  return DeclaratorLocChecker().Visit(*TL);
-}
-
-//===----------------------------------------------------------------------===//
-// DefaultTypeSpecLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class DefaultTypeSpecLocChecker :
-                        public TypeLocVisitor<DefaultTypeSpecLocChecker, bool> {
-public:
-  bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; }
-};
-
-}
-
-bool DefaultTypeSpecLoc::classofType(const Type *Ty) {
-  return
-    DefaultTypeSpecLocChecker().Visit(UnqualTypeLoc(const_cast<Type*>(Ty), 0));
-}
- 
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 87caf77..98f3f0b 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -1985,61 +1985,136 @@
                 unsigned &Idx)
     : Reader(Reader), Record(Record), Idx(Idx) { }
 
-#define ABSTRACT_TYPELOC(CLASS)
+  // We want compile-time assurance that we've enumerated all of
+  // these, so unfortunately we have to declare them first, then
+  // define them out-of-line.
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
 #define TYPELOC(CLASS, PARENT) \
-    void Visit##CLASS(CLASS TyLoc);
+  void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
 #include "clang/AST/TypeLocNodes.def"
 
-  void VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A type loc wrapper was not handled!");
-  }
+  void VisitFunctionTypeLoc(FunctionTypeLoc);
+  void VisitArrayTypeLoc(ArrayTypeLoc);
 };
 
 }
 
-void TypeLocReader::VisitQualifiedLoc(QualifiedLoc TyLoc) {
+void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
   // nothing to do
 }
-void TypeLocReader::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) {
-  TyLoc.setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitTypedefLoc(TypedefLoc TyLoc) {
-  TyLoc.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitFixedWidthIntTypeLoc(FixedWidthIntTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitObjCInterfaceLoc(ObjCInterfaceLoc TyLoc) {
-  TyLoc.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitObjCProtocolListLoc(ObjCProtocolListLoc TyLoc) {
-  TyLoc.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  TyLoc.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  for (unsigned i = 0, e = TyLoc.getNumProtocols(); i != e; ++i)
-    TyLoc.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {
+  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitPointerLoc(PointerLoc TyLoc) {
-  TyLoc.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+  TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitBlockPointerLoc(BlockPointerLoc TyLoc) {
-  TyLoc.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+  TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitMemberPointerLoc(MemberPointerLoc TyLoc) {
-  TyLoc.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+  TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitReferenceLoc(ReferenceLoc TyLoc) {
-  TyLoc.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
-void TypeLocReader::VisitFunctionLoc(FunctionLoc TyLoc) {
-  TyLoc.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  TyLoc.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  for (unsigned i = 0, e = TyLoc.getNumArgs(); i != e; ++i)
-    TyLoc.setArg(i, cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
-}
-void TypeLocReader::VisitArrayLoc(ArrayLoc TyLoc) {
-  TyLoc.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  TyLoc.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   if (Record[Idx++])
-    TyLoc.setSizeExpr(Reader.ReadDeclExpr());
+    TL.setSizeExpr(Reader.ReadDeclExpr());
   else
-    TyLoc.setSizeExpr(0);
+    TL.setSizeExpr(0);
+}
+void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocReader::VisitDependentSizedArrayTypeLoc(
+                                            DependentSizedArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
+                                        DependentSizedExtVectorTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+  TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
+    TL.setArg(i, cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+  }
+}
+void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
+  VisitFunctionTypeLoc(TL);
+}
+void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
+  VisitFunctionTypeLoc(TL);
+}
+void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTemplateSpecializationTypeLoc(
+                                           TemplateSpecializationTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitTypenameTypeLoc(TypenameTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
+void TypeLocReader::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) {
+  TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+    TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++]));
 }
 
 DeclaratorInfo *PCHReader::GetDeclaratorInfo(const RecordData &Record,
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 40c9e1f..a15576a 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -259,60 +259,131 @@
   TypeLocWriter(PCHWriter &Writer, PCHWriter::RecordData &Record)
     : Writer(Writer), Record(Record) { }
 
-#define ABSTRACT_TYPELOC(CLASS)
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
 #define TYPELOC(CLASS, PARENT) \
-    void Visit##CLASS(CLASS TyLoc);
+    void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
 #include "clang/AST/TypeLocNodes.def"
 
-  void VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A type loc wrapper was not handled!");
-  }
+  void VisitArrayTypeLoc(ArrayTypeLoc TyLoc);
+  void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
 };
 
 }
 
-void TypeLocWriter::VisitQualifiedLoc(QualifiedLoc TyLoc) {
-  // nothing to do here
+void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+  // nothing to do
 }
-void TypeLocWriter::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getStartLoc(), Record);
+void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
 }
-void TypeLocWriter::VisitTypedefLoc(TypedefLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getNameLoc(), Record);
+void TypeLocWriter::VisitFixedWidthIntTypeLoc(FixedWidthIntTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
 }
-void TypeLocWriter::VisitObjCInterfaceLoc(ObjCInterfaceLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getNameLoc(), Record);
+void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
 }
-void TypeLocWriter::VisitObjCProtocolListLoc(ObjCProtocolListLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getLAngleLoc(), Record);
-  Writer.AddSourceLocation(TyLoc.getRAngleLoc(), Record);
-  for (unsigned i = 0, e = TyLoc.getNumProtocols(); i != e; ++i)
-    Writer.AddSourceLocation(TyLoc.getProtocolLoc(i), Record);
+void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getStarLoc(), Record);
 }
-void TypeLocWriter::VisitPointerLoc(PointerLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getStarLoc(), Record);
+void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getCaretLoc(), Record);
 }
-void TypeLocWriter::VisitBlockPointerLoc(BlockPointerLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getCaretLoc(), Record);
+void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getAmpLoc(), Record);
 }
-void TypeLocWriter::VisitMemberPointerLoc(MemberPointerLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getStarLoc(), Record);
+void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record);
 }
-void TypeLocWriter::VisitReferenceLoc(ReferenceLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getAmpLoc(), Record);
+void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getStarLoc(), Record);
 }
-void TypeLocWriter::VisitFunctionLoc(FunctionLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getLParenLoc(), Record);
-  Writer.AddSourceLocation(TyLoc.getRParenLoc(), Record);
-  for (unsigned i = 0, e = TyLoc.getNumArgs(); i != e; ++i)
-    Writer.AddDeclRef(TyLoc.getArg(i), Record);
+void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getLBracketLoc(), Record);
+  Writer.AddSourceLocation(TL.getRBracketLoc(), Record);
+  Record.push_back(TL.getSizeExpr() ? 1 : 0);
+  if (TL.getSizeExpr())
+    Writer.AddStmt(TL.getSizeExpr());
 }
-void TypeLocWriter::VisitArrayLoc(ArrayLoc TyLoc) {
-  Writer.AddSourceLocation(TyLoc.getLBracketLoc(), Record);
-  Writer.AddSourceLocation(TyLoc.getRBracketLoc(), Record);
-  Record.push_back(TyLoc.getSizeExpr() ? 1 : 0);
-  if (TyLoc.getSizeExpr())
-    Writer.AddStmt(TyLoc.getSizeExpr());
+void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
+                                            DependentSizedArrayTypeLoc TL) {
+  VisitArrayTypeLoc(TL);
+}
+void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
+                                        DependentSizedExtVectorTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getLParenLoc(), Record);
+  Writer.AddSourceLocation(TL.getRParenLoc(), Record);
+  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+    Writer.AddDeclRef(TL.getArg(i), Record);
+}
+void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
+  VisitFunctionTypeLoc(TL);
+}
+void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
+  VisitFunctionTypeLoc(TL);
+}
+void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
+                                           TemplateSpecializationTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitTypenameTypeLoc(TypenameTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
+void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getStarLoc(), Record);
+}
+void TypeLocWriter::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) {
+  Writer.AddSourceLocation(TL.getLAngleLoc(), Record);
+  Writer.AddSourceLocation(TL.getRAngleLoc(), Record);
+  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+    Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);
 }
 
 //===----------------------------------------------------------------------===//
@@ -2032,7 +2103,7 @@
     return;
   }
 
-  AddTypeRef(DInfo->getTypeLoc().getSourceType(), Record);
+  AddTypeRef(DInfo->getType(), Record);
   TypeLocWriter TLW(*this, Record);
   for (TypeLoc TL = DInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc())
     TLW.Visit(TL);  
diff --git a/lib/Index/ASTLocation.cpp b/lib/Index/ASTLocation.cpp
index 6294d69..c24f3bf 100644
--- a/lib/Index/ASTLocation.cpp
+++ b/lib/Index/ASTLocation.cpp
@@ -101,7 +101,7 @@
     break;
     
   case N_Type: {
-    QualType T = AsTypeLoc().getSourceType();
+    QualType T = AsTypeLoc().getType();
     OS << "[Type: " << T->getTypeClassName() << " " << T.getAsString();
   }
   }
diff --git a/lib/Index/ASTVisitor.h b/lib/Index/ASTVisitor.h
index e18aa57..0ae78fb 100644
--- a/lib/Index/ASTVisitor.h
+++ b/lib/Index/ASTVisitor.h
@@ -123,14 +123,14 @@
       BaseTypeLocVisitor::Visit(TL);
   }
   
-  void VisitArrayLoc(ArrayLoc TL) {
-    BaseTypeLocVisitor::VisitArrayLoc(TL);
+  void VisitArrayLoc(ArrayTypeLoc TL) {
+    BaseTypeLocVisitor::VisitArrayTypeLoc(TL);
     if (TL.getSizeExpr())
       Visit(TL.getSizeExpr());
   }
   
-  void VisitFunctionLoc(FunctionLoc TL) {
-    BaseTypeLocVisitor::VisitFunctionLoc(TL);
+  void VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+    BaseTypeLocVisitor::VisitFunctionTypeLoc(TL);
     for (unsigned i = 0; i != TL.getNumArgs(); ++i)
       Visit(TL.getArg(i));
   }
diff --git a/lib/Index/DeclReferenceMap.cpp b/lib/Index/DeclReferenceMap.cpp
index 0e48a36..366cf1b 100644
--- a/lib/Index/DeclReferenceMap.cpp
+++ b/lib/Index/DeclReferenceMap.cpp
@@ -31,8 +31,8 @@
   void VisitMemberExpr(MemberExpr *Node);
   void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node);
   
-  void VisitTypedefLoc(TypedefLoc TL);
-  void VisitObjCInterfaceLoc(ObjCInterfaceLoc TL);
+  void VisitTypedefTypeLoc(TypedefTypeLoc TL);
+  void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
 };
 
 } // anonymous namespace
@@ -55,12 +55,12 @@
   Map.insert(std::make_pair(Node->getDecl(), ASTLocation(CurrentDecl, Node)));
 }
 
-void RefMapper::VisitTypedefLoc(TypedefLoc TL) {
+void RefMapper::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
   NamedDecl *ND = TL.getTypedefDecl();
   Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc())));
 }
 
-void RefMapper::VisitObjCInterfaceLoc(ObjCInterfaceLoc TL) {
+void RefMapper::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
   NamedDecl *ND = TL.getIFaceDecl();
   Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc())));
 }
diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp
index 229669d..b94d48e 100644
--- a/lib/Index/ResolveLocation.cpp
+++ b/lib/Index/ResolveLocation.cpp
@@ -120,11 +120,11 @@
   TypeLocResolver(ASTContext &ctx, SourceLocation loc, Decl *pd)
     : LocResolverBase(ctx, loc), ParentDecl(pd) { }
 
-  ASTLocation VisitTypedefLoc(TypedefLoc TL);
-  ASTLocation VisitFunctionLoc(FunctionLoc TL);
-  ASTLocation VisitArrayLoc(ArrayLoc TL);
-  ASTLocation VisitObjCInterfaceLoc(ObjCInterfaceLoc TL);
-  ASTLocation VisitObjCProtocolListLoc(ObjCProtocolListLoc TL);
+  ASTLocation VisitTypedefTypeLoc(TypedefTypeLoc TL);
+  ASTLocation VisitFunctionTypeLoc(FunctionTypeLoc TL);
+  ASTLocation VisitArrayTypeLoc(ArrayTypeLoc TL);
+  ASTLocation VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL);
+  ASTLocation VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL);
   ASTLocation VisitTypeLoc(TypeLoc TL);
 };
 
@@ -349,7 +349,7 @@
   return ASTLocation(D);
 }
 
-ASTLocation TypeLocResolver::VisitTypedefLoc(TypedefLoc TL) {
+ASTLocation TypeLocResolver::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
   assert(ContainsLocation(TL) &&
          "Should visit only after verifying that loc is in range");
   if (ContainsLocation(TL.getNameLoc()))
@@ -357,7 +357,7 @@
   return ASTLocation(ParentDecl, TL);
 }
 
-ASTLocation TypeLocResolver::VisitFunctionLoc(FunctionLoc TL) {
+ASTLocation TypeLocResolver::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
   assert(ContainsLocation(TL) &&
          "Should visit only after verifying that loc is in range");
 
@@ -373,7 +373,7 @@
   return ASTLocation(ParentDecl, TL);
 }
 
-ASTLocation TypeLocResolver::VisitArrayLoc(ArrayLoc TL) {
+ASTLocation TypeLocResolver::VisitArrayTypeLoc(ArrayTypeLoc TL) {
   assert(ContainsLocation(TL) &&
          "Should visit only after verifying that loc is in range");
 
@@ -384,7 +384,7 @@
   return ASTLocation(ParentDecl, TL);
 }
 
-ASTLocation TypeLocResolver::VisitObjCInterfaceLoc(ObjCInterfaceLoc TL) {
+ASTLocation TypeLocResolver::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
   assert(ContainsLocation(TL) &&
          "Should visit only after verifying that loc is in range");
   if (ContainsLocation(TL.getNameLoc()))
@@ -392,7 +392,7 @@
   return ASTLocation(ParentDecl, TL);
 }
 
-ASTLocation TypeLocResolver::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) {
+ASTLocation TypeLocResolver::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) {
   assert(ContainsLocation(TL) &&
          "Should visit only after verifying that loc is in range");
 
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 99b2a51..117f595 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeLocVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Parse/DeclSpec.h"
@@ -1298,28 +1299,102 @@
   return T;
 }
 
-static void FillTypeSpecLoc(TypeLoc TSL, const DeclSpec &DS) {
-  if (TSL.isNull()) return;
+namespace {
+  class TypeSpecLocFiller : public TypeLocVisitor<TypeSpecLocFiller> {
+    const DeclSpec &DS;
 
-  if (TypedefLoc *TL = dyn_cast<TypedefLoc>(&TSL)) {
-    TL->setNameLoc(DS.getTypeSpecTypeLoc());
+  public:
+    TypeSpecLocFiller(const DeclSpec &DS) : DS(DS) {}
 
-  } else if (ObjCInterfaceLoc *TL = dyn_cast<ObjCInterfaceLoc>(&TSL)) {
-    TL->setNameLoc(DS.getTypeSpecTypeLoc());
+    void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+      Visit(TL.getUnqualifiedLoc());
+    }
+    void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+      TL.setNameLoc(DS.getTypeSpecTypeLoc());
+    }
+    void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
+      TL.setNameLoc(DS.getTypeSpecTypeLoc());
+    }
+    void VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) {
+      assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers());
+      TL.setLAngleLoc(DS.getProtocolLAngleLoc());
+      TL.setRAngleLoc(DS.getSourceRange().getEnd());
+      for (unsigned i = 0; i != DS.getNumProtocolQualifiers(); ++i)
+        TL.setProtocolLoc(i, DS.getProtocolLocs()[i]);
 
-  } else if (ObjCProtocolListLoc *PLL = dyn_cast<ObjCProtocolListLoc>(&TSL)) {
-    assert(PLL->getNumProtocols() == DS.getNumProtocolQualifiers());
-    PLL->setLAngleLoc(DS.getProtocolLAngleLoc());
-    PLL->setRAngleLoc(DS.getSourceRange().getEnd());
-    for (unsigned i = 0; i != DS.getNumProtocolQualifiers(); ++i)
-      PLL->setProtocolLoc(i, DS.getProtocolLocs()[i]);
-    FillTypeSpecLoc(PLL->getBaseTypeLoc(), DS);
+      TypeLoc BaseLoc = TL.getBaseTypeLoc();
+      if (BaseLoc)
+        Visit(TL.getBaseTypeLoc());
+    }
+    void VisitTypeLoc(TypeLoc TL) {
+      // FIXME: add other typespec types and change this to an assert.
+      TL.initialize(DS.getTypeSpecTypeLoc());
+    }
+  };
 
-  } else {
-    //FIXME: Other typespecs.
-    DefaultTypeSpecLoc &DTL = cast<DefaultTypeSpecLoc>(TSL);
-    DTL.setStartLoc(DS.getSourceRange().getBegin());
-  }
+  class DeclaratorLocFiller : public TypeLocVisitor<DeclaratorLocFiller> {
+    const DeclaratorChunk &Chunk;
+
+  public:
+    DeclaratorLocFiller(const DeclaratorChunk &Chunk) : Chunk(Chunk) {}
+
+    void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
+      llvm::llvm_unreachable("qualified type locs not expected here!");
+    }
+
+    void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::BlockPointer);
+      TL.setCaretLoc(Chunk.Loc);
+    }
+    void VisitPointerTypeLoc(PointerTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Pointer);
+      TL.setStarLoc(Chunk.Loc);
+    }
+    void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Pointer);
+      TL.setStarLoc(Chunk.Loc);
+    }
+    void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::MemberPointer);
+      TL.setStarLoc(Chunk.Loc);
+      // FIXME: nested name specifier
+    }
+    void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Reference);
+      assert(Chunk.Ref.LValueRef);
+      TL.setAmpLoc(Chunk.Loc);
+    }
+    void VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Reference);
+      assert(!Chunk.Ref.LValueRef);
+      TL.setAmpAmpLoc(Chunk.Loc);
+    }
+    void VisitArrayTypeLoc(ArrayTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Array);
+      TL.setLBracketLoc(Chunk.Loc);
+      TL.setRBracketLoc(Chunk.EndLoc);
+      TL.setSizeExpr(static_cast<Expr*>(Chunk.Arr.NumElts));
+    }
+    void VisitFunctionTypeLoc(FunctionTypeLoc TL) {
+      assert(Chunk.Kind == DeclaratorChunk::Function);
+      TL.setLParenLoc(Chunk.Loc);
+      TL.setRParenLoc(Chunk.EndLoc);
+
+      const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
+      for (unsigned i = 0, e = FTI.NumArgs, tpi = 0; i != e; ++i) {
+        ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
+        if (Param) {
+          assert(tpi < TL.getNumArgs());
+          TL.setArg(tpi++, Param);
+        }
+      }
+      // FIXME: exception specs
+    }
+
+    void VisitTypeLoc(TypeLoc TL) {
+      llvm::llvm_unreachable("unsupported TypeLoc kind in declarator!");
+    }
+  };
 }
 
 /// \brief Create and instantiate a DeclaratorInfo with type source information.
@@ -1328,70 +1403,14 @@
 DeclaratorInfo *
 Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) {
   DeclaratorInfo *DInfo = Context.CreateDeclaratorInfo(T);
-  TypeLoc CurrTL = DInfo->getTypeLoc();
+  UnqualTypeLoc CurrTL = DInfo->getTypeLoc().getUnqualifiedLoc();
 
   for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
-    assert(!CurrTL.isNull());
-    
-    // Don't bother recording source locations for qualifiers.
-    CurrTL = CurrTL.getUnqualifiedLoc();
-
-    DeclaratorChunk &DeclType = D.getTypeObject(i);
-    switch (DeclType.Kind) {
-    default: assert(0 && "Unknown decltype!");
-    case DeclaratorChunk::BlockPointer: {
-      BlockPointerLoc &BPL = cast<BlockPointerLoc>(CurrTL);
-      BPL.setCaretLoc(DeclType.Loc);
-      break;
-    }
-    case DeclaratorChunk::Pointer: {
-      //FIXME: ObjCObject pointers.
-      PointerLoc &PL = cast<PointerLoc>(CurrTL);
-      PL.setStarLoc(DeclType.Loc);
-      break;
-    }
-    case DeclaratorChunk::Reference: {
-      ReferenceLoc &RL = cast<ReferenceLoc>(CurrTL);
-      RL.setAmpLoc(DeclType.Loc);
-      break;
-    }
-    case DeclaratorChunk::Array: {
-      DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr;
-      ArrayLoc &AL = cast<ArrayLoc>(CurrTL);
-      AL.setLBracketLoc(DeclType.Loc);
-      AL.setRBracketLoc(DeclType.EndLoc);
-      AL.setSizeExpr(static_cast<Expr*>(ATI.NumElts));
-      //FIXME: Star location for [*].
-      break;
-    }
-    case DeclaratorChunk::Function: {
-      const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
-      FunctionLoc &FL = cast<FunctionLoc>(CurrTL);
-      FL.setLParenLoc(DeclType.Loc);
-      FL.setRParenLoc(DeclType.EndLoc);
-      for (unsigned i = 0, e = FTI.NumArgs, tpi = 0; i != e; ++i) {
-        ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
-        if (Param) {
-          assert(tpi < FL.getNumArgs());
-          FL.setArg(tpi++, Param);
-        }
-      }
-      break;
-      //FIXME: Exception specs.
-    }
-    case DeclaratorChunk::MemberPointer: {
-      MemberPointerLoc &MPL = cast<MemberPointerLoc>(CurrTL);
-      MPL.setStarLoc(DeclType.Loc);
-      //FIXME: Class location.
-      break;
-    }
-
-    }
-
-    CurrTL = CurrTL.getNextTypeLoc();
+    DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL);
+    CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
   }
   
-  FillTypeSpecLoc(CurrTL, D.getDeclSpec());
+  TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
 
   return DInfo;
 }