]> granicus.if.org Git - clang/blobdiff - lib/AST/TypeLoc.cpp
[OPENMP] Initial support for 'task_reduction' clause.
[clang] / lib / AST / TypeLoc.cpp
index c216a29e644f93d8a8aa61242e84147331ad20ec..c9a268655723b53360f047362024b74cb9fbe7d3 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Support/raw_ostream.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/TypeLocVisitor.h"
+#include "llvm/Support/ErrorHandling.h"
 using namespace clang;
 
+static const unsigned TypeLocMaxDataAlign = alignof(void *);
+
 //===----------------------------------------------------------------------===//
 // TypeLoc Implementation
 //===----------------------------------------------------------------------===//
 
 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.getLocalSourceRange(); \
+    }
 #include "clang/AST/TypeLocNodes.def"
+  };
+}
 
-  SourceRange VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A typeloc wrapper was not handled!");
-    return SourceRange();
-  }
-};
-
+SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
+  if (TL.isNull()) return SourceRange();
+  return TypeLocRanger().Visit(TL);
 }
 
-SourceRange TypeLoc::getSourceRange() const {
-  if (isNull())
-    return SourceRange();
-  return TypeLocRanger().Visit(*this);
+namespace {
+  class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
+  public:
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return TyLoc.getLocalDataAlignment(); \
+    }
+#include "clang/AST/TypeLocNodes.def"
+  };
 }
 
-/// \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);
+/// \brief Returns the alignment of the type source info data block.
+unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
+  if (Ty.isNull()) return 1;
+  return TypeAligner().Visit(TypeLoc(Ty, nullptr));
 }
 
 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.getLocalDataSize(); \
+    }
 #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.
 unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
-  if (Ty.isNull()) return 0;
-  return TypeSizer().Visit(TypeLoc(Ty, 0));
+  unsigned Total = 0;
+  TypeLoc TyLoc(Ty, nullptr);
+  unsigned MaxAlign = 1;
+  while (!TyLoc.isNull()) {
+    unsigned Align = getLocalAlignmentForType(TyLoc.getType());
+    MaxAlign = std::max(Align, MaxAlign);
+    Total = llvm::alignTo(Total, Align);
+    Total += TypeSizer().Visit(TyLoc);
+    TyLoc = TyLoc.getNextTypeLoc();
+  }
+  Total = llvm::alignTo(Total, MaxAlign);
+  return Total;
 }
 
 namespace {
+  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"
+  };
+}
 
-/// \brief Return the "next" TypeLoc for the visited TypeLoc, e.g for "int*" the
+/// \brief Get the next TypeLoc pointed by this 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);
-#include "clang/AST/TypeLocNodes.def"
+TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
+  return NextLoc().Visit(TL);
+}
 
-  TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); }
-  TypeLoc VisitObjCProtocolListLoc(ObjCProtocolListLoc TL);
-  TypeLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
-    return TyLoc.getNextTypeLoc();
+/// \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(ASTContext &Context, TypeLoc TL, 
+                             SourceLocation Loc) {
+  while (true) {
+    switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT)        \
+    case CLASS: {                     \
+      CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
+      TLCasted.initializeLocal(Context, Loc);  \
+      TL = TLCasted.getNextTypeLoc(); \
+      if (!TL) return;                \
+      continue;                       \
+    }
+#include "clang/AST/TypeLocNodes.def"
+    }
   }
+}
+
+namespace {
+  class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
+    TypeLoc Source;
+  public:
+    TypeLocCopier(TypeLoc source) : Source(source) { }
+
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT)                          \
+    void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) {   \
+      dest.copyLocal(Source.castAs<CLASS##TypeLoc>());  \
+    }
+#include "clang/AST/TypeLocNodes.def"
+  };
+}
 
-  TypeLoc VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A declarator loc wrapper was not handled!");
-    return TypeLoc();
+
+void TypeLoc::copy(TypeLoc other) {
+  assert(getFullDataSize() == other.getFullDataSize());
+
+  // If both data pointers are aligned to the maximum alignment, we
+  // can memcpy because getFullDataSize() accurately reflects the
+  // layout of the data.
+  if (reinterpret_cast<uintptr_t>(Data) ==
+          llvm::alignTo(reinterpret_cast<uintptr_t>(Data),
+                        TypeLocMaxDataAlign) &&
+      reinterpret_cast<uintptr_t>(other.Data) ==
+          llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data),
+                        TypeLocMaxDataAlign)) {
+    memcpy(Data, other.Data, getFullDataSize());
+    return;
   }
-};
 
+  // Copy each of the pieces.
+  TypeLoc TL(getType(), Data);
+  do {
+    TypeLocCopier(other).Visit(TL);
+    other = other.getNextTypeLoc();
+  } while ((TL = TL.getNextTypeLoc()));
 }
 
-TypeLoc NextLoc::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) {
-  return TL.getNextTypeLoc();
+SourceLocation TypeLoc::getBeginLoc() const {
+  TypeLoc Cur = *this;
+  TypeLoc LeftMost = Cur;
+  while (true) {
+    switch (Cur.getTypeLocClass()) {
+    case Elaborated:
+      LeftMost = Cur;
+      break;
+    case FunctionProto:
+      if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()
+              ->hasTrailingReturn()) {
+        LeftMost = Cur;
+        break;
+      }
+      /* Fall through */
+    case FunctionNoProto:
+    case ConstantArray:
+    case DependentSizedArray:
+    case IncompleteArray:
+    case VariableArray:
+      // FIXME: Currently QualifiedTypeLoc does not have a source range
+    case Qualified:
+      Cur = Cur.getNextTypeLoc();
+      continue;
+    default:
+      if (Cur.getLocalSourceRange().getBegin().isValid())
+        LeftMost = Cur;
+      Cur = Cur.getNextTypeLoc();
+      if (Cur.isNull())
+        break;
+      continue;
+    } // switch
+    break;
+  } // while
+  return LeftMost.getLocalSourceRange().getBegin();
 }
 
-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();
+SourceLocation TypeLoc::getEndLoc() const {
+  TypeLoc Cur = *this;
+  TypeLoc Last;
+  while (true) {
+    switch (Cur.getTypeLocClass()) {
+    default:
+      if (!Last)
+        Last = Cur;
+      return Last.getLocalSourceRange().getEnd();
+    case Paren:
+    case ConstantArray:
+    case DependentSizedArray:
+    case IncompleteArray:
+    case VariableArray:
+    case FunctionNoProto:
+      Last = Cur;
+      break;
+    case FunctionProto:
+      if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn())
+        Last = TypeLoc();
+      else
+        Last = Cur;
+      break;
+    case Pointer:
+    case BlockPointer:
+    case MemberPointer:
+    case LValueReference:
+    case RValueReference:
+    case PackExpansion:
+      if (!Last)
+       Last = Cur;
+      break;
+    case Qualified:
+    case Elaborated:
+      break;
+    }
+    Cur = Cur.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);
-}
 
 namespace {
-struct TypeLocInitializer : public TypeLocVisitor<TypeLocInitializer> {
-  SourceLocation Loc;
-  TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {}
-  
-#define ABSTRACT_TYPELOC(CLASS)
+  struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
+    // Overload resolution does the real work for us.
+    static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
+    static bool isTypeSpec(TypeLoc _) { return false; }
+
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
 #define TYPELOC(CLASS, PARENT) \
-  void Visit##CLASS(CLASS TyLoc) { TyLoc.initializeLocal(Loc); }
+    bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+      return isTypeSpec(TyLoc); \
+    }
 #include "clang/AST/TypeLocNodes.def"
-};
+  };
 }
 
-void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) {
-  do {
-    TypeLocInitializer(Loc).Visit(TL);
-  } while (TL = TL.getNextTypeLoc());
+
+/// \brief Determines if the given type loc corresponds to a
+/// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
+/// the type hierarchy, this is made somewhat complicated.
+///
+/// There are a lot of types that currently use TypeSpecTypeLoc
+/// because it's a convenient base class.  Ideally we would not accept
+/// those here, but ideally we would have better implementations for
+/// them.
+bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
+  if (TL.getType().hasLocalQualifiers()) return false;
+  return TSTChecker().Visit(TL);
 }
 
-//===----------------------------------------------------------------------===//
-// TypeSpecLoc Implementation
-//===----------------------------------------------------------------------===//
+// Reimplemented to account for GNU/C++ extension
+//     typeof unary-expression
+// where there are no parentheses.
+SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
+  if (getRParenLoc().isValid())
+    return SourceRange(getTypeofLoc(), getRParenLoc());
+  else
+    return SourceRange(getTypeofLoc(),
+                       getUnderlyingExpr()->getSourceRange().getEnd());
+}
 
-namespace {
-class TypeSpecChecker : public TypeLocVisitor<TypeSpecChecker, bool> {
-public:
-  bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; }
-};
 
+TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
+  if (needsExtraLocalData())
+    return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
+  switch (getTypePtr()->getKind()) {
+  case BuiltinType::Void:
+    return TST_void;
+  case BuiltinType::Bool:
+    return TST_bool;
+  case BuiltinType::Char_U:
+  case BuiltinType::Char_S:
+    return TST_char;
+  case BuiltinType::Char16:
+    return TST_char16;
+  case BuiltinType::Char32:
+    return TST_char32;
+  case BuiltinType::WChar_S:
+  case BuiltinType::WChar_U:
+    return TST_wchar;
+  case BuiltinType::UChar:
+  case BuiltinType::UShort:
+  case BuiltinType::UInt:
+  case BuiltinType::ULong:
+  case BuiltinType::ULongLong:
+  case BuiltinType::UInt128:
+  case BuiltinType::SChar:
+  case BuiltinType::Short:
+  case BuiltinType::Int:
+  case BuiltinType::Long:
+  case BuiltinType::LongLong:
+  case BuiltinType::Int128:
+  case BuiltinType::Half:
+  case BuiltinType::Float:
+  case BuiltinType::Double:
+  case BuiltinType::LongDouble:
+  case BuiltinType::Float128:
+    llvm_unreachable("Builtin type needs extra local data!");
+    // Fall through, if the impossible happens.
+      
+  case BuiltinType::NullPtr:
+  case BuiltinType::Overload:
+  case BuiltinType::Dependent:
+  case BuiltinType::BoundMember:
+  case BuiltinType::UnknownAny:
+  case BuiltinType::ARCUnbridgedCast:
+  case BuiltinType::PseudoObject:
+  case BuiltinType::ObjCId:
+  case BuiltinType::ObjCClass:
+  case BuiltinType::ObjCSel:
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
+  case BuiltinType::Id:
+#include "clang/Basic/OpenCLImageTypes.def"
+  case BuiltinType::OCLSampler:
+  case BuiltinType::OCLEvent:
+  case BuiltinType::OCLClkEvent:
+  case BuiltinType::OCLQueue:
+  case BuiltinType::OCLReserveID:
+  case BuiltinType::BuiltinFn:
+  case BuiltinType::OMPArraySection:
+    return TST_unspecified;
+  }
+
+  llvm_unreachable("Invalid BuiltinType Kind!");
 }
 
-bool TypeSpecLoc::classof(const UnqualTypeLoc *TL) {
-  return TypeSpecChecker().Visit(*TL);
+TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
+  while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())
+    TL = PTL.getInnerLoc();
+  return TL;
 }
 
-//===----------------------------------------------------------------------===//
-// DeclaratorLoc Implementation
-//===----------------------------------------------------------------------===//
+SourceLocation TypeLoc::findNullabilityLoc() const {
+  if (auto attributedLoc = getAs<AttributedTypeLoc>()) {
+    if (attributedLoc.getAttrKind() == AttributedType::attr_nullable ||
+        attributedLoc.getAttrKind() == AttributedType::attr_nonnull ||
+        attributedLoc.getAttrKind() == AttributedType::attr_null_unspecified)
+      return attributedLoc.getAttrNameLoc();
+  }
 
-namespace {
+  return SourceLocation();
+}
 
-/// \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"
+TypeLoc TypeLoc::findExplicitQualifierLoc() const {
+  // Qualified types.
+  if (auto qual = getAs<QualifiedTypeLoc>())
+    return qual;
 
-  TypeSpecLoc VisitTypeLoc(TypeLoc TyLoc) {
-    assert(0 && "A declarator loc wrapper was not handled!");
-    return TypeSpecLoc();
-  }
+  TypeLoc loc = IgnoreParens();
 
-  TypeSpecLoc VisitQualifiedLoc(QualifiedLoc TyLoc) {
-    return Visit(TyLoc.getUnqualifiedLoc());
+  // Attributed types.
+  if (auto attr = loc.getAs<AttributedTypeLoc>()) {
+    if (attr.isQualifier()) return attr;
+    return attr.getModifiedLoc().findExplicitQualifierLoc();
   }
-};
 
-}
+  // C11 _Atomic types.
+  if (auto atomic = loc.getAs<AtomicTypeLoc>()) {
+    return atomic;
+  }
 
-/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc.
-TypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const {
-  return TypeSpecGetter().Visit(*this);
+  return TypeLoc();
 }
 
-namespace {
-
-class DeclaratorLocChecker : public TypeLocVisitor<DeclaratorLocChecker, bool> {
-public:
-  bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; }
-};
+void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
+                                           SourceLocation Loc) {
+  setNameLoc(Loc);
+  if (!getNumProtocols()) return;
 
+  setProtocolLAngleLoc(Loc);
+  setProtocolRAngleLoc(Loc);
+  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+    setProtocolLoc(i, Loc);
 }
 
-bool DeclaratorLoc::classof(const UnqualTypeLoc *TL) {
-  return DeclaratorLocChecker().Visit(*TL);
+void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context, 
+                                        SourceLocation Loc) {
+  setHasBaseTypeAsWritten(true);
+  setTypeArgsLAngleLoc(Loc);
+  setTypeArgsRAngleLoc(Loc);
+  for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {
+    setTypeArgTInfo(i, 
+                   Context.getTrivialTypeSourceInfo(
+                     getTypePtr()->getTypeArgsAsWritten()[i], Loc));
+  }
+  setProtocolLAngleLoc(Loc);
+  setProtocolRAngleLoc(Loc);
+  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+    setProtocolLoc(i, Loc);
 }
 
-//===----------------------------------------------------------------------===//
-// DefaultTypeSpecLoc Implementation
-//===----------------------------------------------------------------------===//
+void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
+                                       SourceLocation Loc) {
+  TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
+      ::initializeLocal(Context, Loc);
+  this->getLocalData()->UnderlyingTInfo = Context.getTrivialTypeSourceInfo(
+      getUnderlyingType(), Loc);
+}
 
-namespace {
+void ElaboratedTypeLoc::initializeLocal(ASTContext &Context, 
+                                        SourceLocation Loc) {
+  setElaboratedKeywordLoc(Loc);
+  NestedNameSpecifierLocBuilder Builder;
+  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
+  setQualifierLoc(Builder.getWithLocInContext(Context));
+}
 
-class DefaultTypeSpecLocChecker :
-                        public TypeLocVisitor<DefaultTypeSpecLocChecker, bool> {
-public:
-  bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; }
-};
+void DependentNameTypeLoc::initializeLocal(ASTContext &Context, 
+                                           SourceLocation Loc) {
+  setElaboratedKeywordLoc(Loc);
+  NestedNameSpecifierLocBuilder Builder;
+  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
+  setQualifierLoc(Builder.getWithLocInContext(Context));
+  setNameLoc(Loc);
+}
 
+void
+DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
+                                                        SourceLocation Loc) {
+  setElaboratedKeywordLoc(Loc);
+  if (getTypePtr()->getQualifier()) {
+    NestedNameSpecifierLocBuilder Builder;
+    Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
+    setQualifierLoc(Builder.getWithLocInContext(Context));
+  } else {
+    setQualifierLoc(NestedNameSpecifierLoc());
+  }
+  setTemplateKeywordLoc(Loc);
+  setTemplateNameLoc(Loc);
+  setLAngleLoc(Loc);
+  setRAngleLoc(Loc);
+  TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
+                                                   getTypePtr()->getArgs(),
+                                                   getArgInfos(), Loc);
 }
 
-bool DefaultTypeSpecLoc::classofType(const Type *Ty) {
-  return
-    DefaultTypeSpecLocChecker().Visit(UnqualTypeLoc(const_cast<Type*>(Ty), 0));
+void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context, 
+                                                      unsigned NumArgs,
+                                                  const TemplateArgument *Args,
+                                              TemplateArgumentLocInfo *ArgInfos,
+                                                      SourceLocation Loc) {
+  for (unsigned i = 0, e = NumArgs; i != e; ++i) {
+    switch (Args[i].getKind()) {
+    case TemplateArgument::Null: 
+      llvm_unreachable("Impossible TemplateArgument");
+
+    case TemplateArgument::Integral:
+    case TemplateArgument::Declaration:
+    case TemplateArgument::NullPtr:
+      ArgInfos[i] = TemplateArgumentLocInfo();
+      break;
+
+    case TemplateArgument::Expression:
+      ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
+      break;
+      
+    case TemplateArgument::Type:
+      ArgInfos[i] = TemplateArgumentLocInfo(
+                          Context.getTrivialTypeSourceInfo(Args[i].getAsType(), 
+                                                           Loc));
+      break;
+
+    case TemplateArgument::Template:
+    case TemplateArgument::TemplateExpansion: {
+      NestedNameSpecifierLocBuilder Builder;
+      TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();
+      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+        Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
+      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+        Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
+
+      ArgInfos[i] = TemplateArgumentLocInfo(
+          Builder.getWithLocInContext(Context), Loc,
+          Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
+                                                          : Loc);
+      break;
+    }
+
+    case TemplateArgument::Pack:
+      ArgInfos[i] = TemplateArgumentLocInfo();
+      break;
+    }
+  }
 }