TypeLoc.cpp revision 288943
153642Sguido//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
292685Sdarrenr//
353642Sguido//                     The LLVM Compiler Infrastructure
480482Sdarrenr//
553642Sguido// This file is distributed under the University of Illinois Open Source
653642Sguido// License. See LICENSE.TXT for details.
7110916Sdarrenr//
892685Sdarrenr//===----------------------------------------------------------------------===//
992685Sdarrenr//
1053642Sguido//  This file defines the TypeLoc subclasses implementations.
1153642Sguido//
1253642Sguido//===----------------------------------------------------------------------===//
1353642Sguido
1453642Sguido#include "clang/AST/TypeLoc.h"
1553642Sguido#include "clang/AST/ASTContext.h"
1653642Sguido#include "clang/AST/Expr.h"
1753642Sguido#include "clang/AST/TypeLocVisitor.h"
1860854Sdarrenr#include "llvm/Support/ErrorHandling.h"
1960854Sdarrenr#include "llvm/Support/raw_ostream.h"
2060854Sdarrenrusing namespace clang;
2160854Sdarrenr
2253642Sguidostatic const unsigned TypeLocMaxDataAlign = llvm::alignOf<void *>();
2353642Sguido
2453642Sguido//===----------------------------------------------------------------------===//
2553642Sguido// TypeLoc Implementation
2653642Sguido//===----------------------------------------------------------------------===//
2753642Sguido
2853642Sguidonamespace {
2953642Sguido  class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
3053642Sguido  public:
3153642Sguido#define ABSTRACT_TYPELOC(CLASS, PARENT)
3260854Sdarrenr#define TYPELOC(CLASS, PARENT) \
3353642Sguido    SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
3453642Sguido      return TyLoc.getLocalSourceRange(); \
3553642Sguido    }
3653642Sguido#include "clang/AST/TypeLocNodes.def"
3753642Sguido  };
3853642Sguido}
3953642Sguido
4053642SguidoSourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
4153642Sguido  if (TL.isNull()) return SourceRange();
4253642Sguido  return TypeLocRanger().Visit(TL);
4353642Sguido}
4453642Sguido
4553642Sguidonamespace {
4657096Sguido  class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
4753642Sguido  public:
4853642Sguido#define ABSTRACT_TYPELOC(CLASS, PARENT)
4953642Sguido#define TYPELOC(CLASS, PARENT) \
5053642Sguido    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
5153642Sguido      return TyLoc.getLocalDataAlignment(); \
5253642Sguido    }
5353642Sguido#include "clang/AST/TypeLocNodes.def"
5453642Sguido  };
5553642Sguido}
5653642Sguido
5753642Sguido/// \brief Returns the alignment of the type source info data block.
5853642Sguidounsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
5953642Sguido  if (Ty.isNull()) return 1;
6053642Sguido  return TypeAligner().Visit(TypeLoc(Ty, nullptr));
6153642Sguido}
6253642Sguido
6353642Sguidonamespace {
6453642Sguido  class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
6553642Sguido  public:
6653642Sguido#define ABSTRACT_TYPELOC(CLASS, PARENT)
6753642Sguido#define TYPELOC(CLASS, PARENT) \
6853642Sguido    unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
6953642Sguido      return TyLoc.getLocalDataSize(); \
7053642Sguido    }
7153642Sguido#include "clang/AST/TypeLocNodes.def"
7253642Sguido  };
7353642Sguido}
7453642Sguido
7553642Sguido/// \brief Returns the size of the type source info data block.
7653642Sguidounsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
7753642Sguido  unsigned Total = 0;
7853642Sguido  TypeLoc TyLoc(Ty, nullptr);
7953642Sguido  unsigned MaxAlign = 1;
8053642Sguido  while (!TyLoc.isNull()) {
8153642Sguido    unsigned Align = getLocalAlignmentForType(TyLoc.getType());
8253642Sguido    MaxAlign = std::max(Align, MaxAlign);
8353642Sguido    Total = llvm::RoundUpToAlignment(Total, Align);
8460854Sdarrenr    Total += TypeSizer().Visit(TyLoc);
8560854Sdarrenr    TyLoc = TyLoc.getNextTypeLoc();
8660854Sdarrenr  }
8753642Sguido  Total = llvm::RoundUpToAlignment(Total, MaxAlign);
8853642Sguido  return Total;
8953642Sguido}
9053642Sguido
9153642Sguidonamespace {
9253642Sguido  class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
9353642Sguido  public:
9453642Sguido#define ABSTRACT_TYPELOC(CLASS, PARENT)
9580482Sdarrenr#define TYPELOC(CLASS, PARENT) \
9680482Sdarrenr    TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
9780482Sdarrenr      return TyLoc.getNextTypeLoc(); \
9880482Sdarrenr    }
9980482Sdarrenr#include "clang/AST/TypeLocNodes.def"
10080482Sdarrenr  };
10153642Sguido}
10253642Sguido
10353642Sguido/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
10453642Sguido/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
10553642SguidoTypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
10653642Sguido  return NextLoc().Visit(TL);
10760854Sdarrenr}
10860854Sdarrenr
10967614Sdarrenr/// \brief Initializes a type location, and all of its children
11060854Sdarrenr/// recursively, as if the entire tree had been written in the
11153642Sguido/// given location.
11253642Sguidovoid TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
11353642Sguido                             SourceLocation Loc) {
11453642Sguido  while (true) {
11553642Sguido    switch (TL.getTypeLocClass()) {
11660854Sdarrenr#define ABSTRACT_TYPELOC(CLASS, PARENT)
11760854Sdarrenr#define TYPELOC(CLASS, PARENT)        \
11860854Sdarrenr    case CLASS: {                     \
11960854Sdarrenr      CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
12053642Sguido      TLCasted.initializeLocal(Context, Loc);  \
12153642Sguido      TL = TLCasted.getNextTypeLoc(); \
122110916Sdarrenr      if (!TL) return;                \
123110916Sdarrenr      continue;                       \
12453642Sguido    }
12553642Sguido#include "clang/AST/TypeLocNodes.def"
12660854Sdarrenr    }
12767614Sdarrenr  }
12895418Sdarrenr}
12960854Sdarrenr
13060854Sdarrenrnamespace {
13160854Sdarrenr  class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
13253642Sguido    TypeLoc Source;
13353642Sguido  public:
13453642Sguido    TypeLocCopier(TypeLoc source) : Source(source) { }
13553642Sguido
13653642Sguido#define ABSTRACT_TYPELOC(CLASS, PARENT)
13753642Sguido#define TYPELOC(CLASS, PARENT)                          \
13853642Sguido    void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) {   \
13953642Sguido      dest.copyLocal(Source.castAs<CLASS##TypeLoc>());  \
14053642Sguido    }
14167614Sdarrenr#include "clang/AST/TypeLocNodes.def"
14267614Sdarrenr  };
14353642Sguido}
14480482Sdarrenr
14580482Sdarrenr
14680482Sdarrenrvoid TypeLoc::copy(TypeLoc other) {
14753642Sguido  assert(getFullDataSize() == other.getFullDataSize());
14853642Sguido
14960854Sdarrenr  // If both data pointers are aligned to the maximum alignment, we
15060854Sdarrenr  // can memcpy because getFullDataSize() accurately reflects the
15192685Sdarrenr  // layout of the data.
15253642Sguido  if (reinterpret_cast<uintptr_t>(Data)
15360854Sdarrenr        == llvm::RoundUpToAlignment(reinterpret_cast<uintptr_t>(Data),
15492685Sdarrenr                                    TypeLocMaxDataAlign) &&
15592685Sdarrenr      reinterpret_cast<uintptr_t>(other.Data)
15692685Sdarrenr        == llvm::RoundUpToAlignment(reinterpret_cast<uintptr_t>(other.Data),
15753642Sguido                                    TypeLocMaxDataAlign)) {
15853642Sguido    memcpy(Data, other.Data, getFullDataSize());
15953642Sguido    return;
16060854Sdarrenr  }
16160854Sdarrenr
16253642Sguido  // Copy each of the pieces.
16353642Sguido  TypeLoc TL(getType(), Data);
16453642Sguido  do {
16553642Sguido    TypeLocCopier(other).Visit(TL);
16653642Sguido    other = other.getNextTypeLoc();
16760854Sdarrenr  } while ((TL = TL.getNextTypeLoc()));
16860854Sdarrenr}
16960854Sdarrenr
17060854SdarrenrSourceLocation TypeLoc::getBeginLoc() const {
17160854Sdarrenr  TypeLoc Cur = *this;
17260854Sdarrenr  TypeLoc LeftMost = Cur;
17360854Sdarrenr  while (true) {
17460854Sdarrenr    switch (Cur.getTypeLocClass()) {
17592685Sdarrenr    case Elaborated:
17692685Sdarrenr      LeftMost = Cur;
17792685Sdarrenr      break;
17892685Sdarrenr    case FunctionProto:
17992685Sdarrenr      if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()
18092685Sdarrenr              ->hasTrailingReturn()) {
18192685Sdarrenr        LeftMost = Cur;
18292685Sdarrenr        break;
18392685Sdarrenr      }
18492685Sdarrenr      /* Fall through */
18560854Sdarrenr    case FunctionNoProto:
18653642Sguido    case ConstantArray:
18753642Sguido    case DependentSizedArray:
18853642Sguido    case IncompleteArray:
18953642Sguido    case VariableArray:
19053642Sguido      // FIXME: Currently QualifiedTypeLoc does not have a source range
19153642Sguido    case Qualified:
19253642Sguido      Cur = Cur.getNextTypeLoc();
19353642Sguido      continue;
19460854Sdarrenr    default:
19553642Sguido      if (!Cur.getLocalSourceRange().getBegin().isInvalid())
19653642Sguido        LeftMost = Cur;
19753642Sguido      Cur = Cur.getNextTypeLoc();
19853642Sguido      if (Cur.isNull())
19953642Sguido        break;
20053642Sguido      continue;
20153642Sguido    } // switch
20253642Sguido    break;
20364580Sdarrenr  } // while
20492685Sdarrenr  return LeftMost.getLocalSourceRange().getBegin();
20592685Sdarrenr}
20692685Sdarrenr
20753642SguidoSourceLocation TypeLoc::getEndLoc() const {
208110916Sdarrenr  TypeLoc Cur = *this;
209110916Sdarrenr  TypeLoc Last;
21053642Sguido  while (true) {
21192685Sdarrenr    switch (Cur.getTypeLocClass()) {
21253642Sguido    default:
21353642Sguido      if (!Last)
21453642Sguido	Last = Cur;
21592685Sdarrenr      return Last.getLocalSourceRange().getEnd();
21653642Sguido    case Paren:
21753642Sguido    case ConstantArray:
21860854Sdarrenr    case DependentSizedArray:
21960854Sdarrenr    case IncompleteArray:
22053642Sguido    case VariableArray:
221110916Sdarrenr    case FunctionNoProto:
222110916Sdarrenr      Last = Cur;
223110916Sdarrenr      break;
22460854Sdarrenr    case FunctionProto:
22560854Sdarrenr      if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn())
22660854Sdarrenr        Last = TypeLoc();
22760854Sdarrenr      else
22860854Sdarrenr        Last = Cur;
22960854Sdarrenr      break;
23092685Sdarrenr    case Pointer:
23160854Sdarrenr    case BlockPointer:
23260854Sdarrenr    case MemberPointer:
23360854Sdarrenr    case LValueReference:
23460854Sdarrenr    case RValueReference:
23553642Sguido    case PackExpansion:
23660854Sdarrenr      if (!Last)
23760854Sdarrenr	Last = Cur;
23853642Sguido      break;
23960854Sdarrenr    case Qualified:
24060854Sdarrenr    case Elaborated:
24160854Sdarrenr      break;
24260854Sdarrenr    }
24360854Sdarrenr    Cur = Cur.getNextTypeLoc();
24453642Sguido  }
24560854Sdarrenr}
24653642Sguido
24760854Sdarrenr
24860854Sdarrenrnamespace {
24960854Sdarrenr  struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
25060854Sdarrenr    // Overload resolution does the real work for us.
25160854Sdarrenr    static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
25292685Sdarrenr    static bool isTypeSpec(TypeLoc _) { return false; }
25392685Sdarrenr
25492685Sdarrenr#define ABSTRACT_TYPELOC(CLASS, PARENT)
25592685Sdarrenr#define TYPELOC(CLASS, PARENT) \
25692685Sdarrenr    bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
25792685Sdarrenr      return isTypeSpec(TyLoc); \
25892685Sdarrenr    }
25992685Sdarrenr#include "clang/AST/TypeLocNodes.def"
26092685Sdarrenr  };
26192685Sdarrenr}
26292685Sdarrenr
26392685Sdarrenr
26492685Sdarrenr/// \brief Determines if the given type loc corresponds to a
26592685Sdarrenr/// TypeSpecTypeLoc.  Since there is not actually a TypeSpecType in
26692685Sdarrenr/// the type hierarchy, this is made somewhat complicated.
26792685Sdarrenr///
26892685Sdarrenr/// There are a lot of types that currently use TypeSpecTypeLoc
26992685Sdarrenr/// because it's a convenient base class.  Ideally we would not accept
27092685Sdarrenr/// those here, but ideally we would have better implementations for
27192685Sdarrenr/// them.
27292685Sdarrenrbool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
27392685Sdarrenr  if (TL.getType().hasLocalQualifiers()) return false;
27492685Sdarrenr  return TSTChecker().Visit(TL);
27592685Sdarrenr}
27692685Sdarrenr
27792685Sdarrenr// Reimplemented to account for GNU/C++ extension
27892685Sdarrenr//     typeof unary-expression
27992685Sdarrenr// where there are no parentheses.
28092685SdarrenrSourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
28192685Sdarrenr  if (getRParenLoc().isValid())
28292685Sdarrenr    return SourceRange(getTypeofLoc(), getRParenLoc());
28392685Sdarrenr  else
28492685Sdarrenr    return SourceRange(getTypeofLoc(),
28592685Sdarrenr                       getUnderlyingExpr()->getSourceRange().getEnd());
28653642Sguido}
28753642Sguido
28853642Sguido
28953642SguidoTypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
29053642Sguido  if (needsExtraLocalData())
29160854Sdarrenr    return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
29260854Sdarrenr  switch (getTypePtr()->getKind()) {
29360854Sdarrenr  case BuiltinType::Void:
29460854Sdarrenr    return TST_void;
29560854Sdarrenr  case BuiltinType::Bool:
29660854Sdarrenr    return TST_bool;
29760854Sdarrenr  case BuiltinType::Char_U:
29860854Sdarrenr  case BuiltinType::Char_S:
29960854Sdarrenr    return TST_char;
30060854Sdarrenr  case BuiltinType::Char16:
30160854Sdarrenr    return TST_char16;
30280482Sdarrenr  case BuiltinType::Char32:
30360854Sdarrenr    return TST_char32;
30460854Sdarrenr  case BuiltinType::WChar_S:
30567614Sdarrenr  case BuiltinType::WChar_U:
30667614Sdarrenr    return TST_wchar;
30795418Sdarrenr  case BuiltinType::UChar:
30867614Sdarrenr  case BuiltinType::UShort:
30967614Sdarrenr  case BuiltinType::UInt:
31067614Sdarrenr  case BuiltinType::ULong:
31160854Sdarrenr  case BuiltinType::ULongLong:
31260854Sdarrenr  case BuiltinType::UInt128:
31360854Sdarrenr  case BuiltinType::SChar:
31460854Sdarrenr  case BuiltinType::Short:
31560854Sdarrenr  case BuiltinType::Int:
31660854Sdarrenr  case BuiltinType::Long:
31760854Sdarrenr  case BuiltinType::LongLong:
31880482Sdarrenr  case BuiltinType::Int128:
31960854Sdarrenr  case BuiltinType::Half:
32060854Sdarrenr  case BuiltinType::Float:
32160854Sdarrenr  case BuiltinType::Double:
32260854Sdarrenr  case BuiltinType::LongDouble:
32353642Sguido    llvm_unreachable("Builtin type needs extra local data!");
32453642Sguido    // Fall through, if the impossible happens.
32553642Sguido
32653642Sguido  case BuiltinType::NullPtr:
32753642Sguido  case BuiltinType::Overload:
32853642Sguido  case BuiltinType::Dependent:
32953642Sguido  case BuiltinType::BoundMember:
33053642Sguido  case BuiltinType::UnknownAny:
33153642Sguido  case BuiltinType::ARCUnbridgedCast:
33260854Sdarrenr  case BuiltinType::PseudoObject:
33353642Sguido  case BuiltinType::ObjCId:
33453642Sguido  case BuiltinType::ObjCClass:
33553642Sguido  case BuiltinType::ObjCSel:
33660854Sdarrenr  case BuiltinType::OCLImage1d:
33760854Sdarrenr  case BuiltinType::OCLImage1dArray:
33860854Sdarrenr  case BuiltinType::OCLImage1dBuffer:
33953642Sguido  case BuiltinType::OCLImage2d:
34060854Sdarrenr  case BuiltinType::OCLImage2dArray:
34160854Sdarrenr  case BuiltinType::OCLImage3d:
34260854Sdarrenr  case BuiltinType::OCLSampler:
34353642Sguido  case BuiltinType::OCLEvent:
34460854Sdarrenr  case BuiltinType::BuiltinFn:
345110916Sdarrenr    return TST_unspecified;
34660854Sdarrenr  }
34760854Sdarrenr
34853642Sguido  llvm_unreachable("Invalid BuiltinType Kind!");
34953642Sguido}
35053642Sguido
351110916SdarrenrTypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
352110916Sdarrenr  while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())
353110916Sdarrenr    TL = PTL.getInnerLoc();
354110916Sdarrenr  return TL;
355110916Sdarrenr}
356110916Sdarrenr
357110916SdarrenrSourceLocation TypeLoc::findNullabilityLoc() const {
358110916Sdarrenr  if (auto attributedLoc = getAs<AttributedTypeLoc>()) {
359110916Sdarrenr    if (attributedLoc.getAttrKind() == AttributedType::attr_nullable ||
360110916Sdarrenr        attributedLoc.getAttrKind() == AttributedType::attr_nonnull ||
361110916Sdarrenr        attributedLoc.getAttrKind() == AttributedType::attr_null_unspecified)
362110916Sdarrenr      return attributedLoc.getAttrNameLoc();
363110916Sdarrenr  }
364110916Sdarrenr
36555929Sguido  return SourceLocation();
36655929Sguido}
36755929Sguido
36855929Sguidovoid ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,
36960854Sdarrenr                                        SourceLocation Loc) {
37060854Sdarrenr  setHasBaseTypeAsWritten(true);
37160854Sdarrenr  setTypeArgsLAngleLoc(Loc);
37260854Sdarrenr  setTypeArgsRAngleLoc(Loc);
37360854Sdarrenr  for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {
37460854Sdarrenr    setTypeArgTInfo(i,
37555929Sguido                   Context.getTrivialTypeSourceInfo(
37655929Sguido                     getTypePtr()->getTypeArgsAsWritten()[i], Loc));
37760854Sdarrenr  }
37860854Sdarrenr  setProtocolLAngleLoc(Loc);
37960854Sdarrenr  setProtocolRAngleLoc(Loc);
38053642Sguido  for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
38153642Sguido    setProtocolLoc(i, Loc);
38253642Sguido}
38372006Sdarrenr
38472006Sdarrenrvoid TypeOfTypeLoc::initializeLocal(ASTContext &Context,
38553642Sguido                                       SourceLocation Loc) {
38653642Sguido  TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
38760854Sdarrenr      ::initializeLocal(Context, Loc);
38860854Sdarrenr  this->getLocalData()->UnderlyingTInfo = Context.getTrivialTypeSourceInfo(
38960854Sdarrenr      getUnderlyingType(), Loc);
39060854Sdarrenr}
39160854Sdarrenr
39260854Sdarrenrvoid ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
39360854Sdarrenr                                        SourceLocation Loc) {
39460854Sdarrenr  setElaboratedKeywordLoc(Loc);
39560854Sdarrenr  NestedNameSpecifierLocBuilder Builder;
39660854Sdarrenr  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
39760854Sdarrenr  setQualifierLoc(Builder.getWithLocInContext(Context));
39860854Sdarrenr}
39960854Sdarrenr
40060854Sdarrenrvoid DependentNameTypeLoc::initializeLocal(ASTContext &Context,
40160854Sdarrenr                                           SourceLocation Loc) {
40260854Sdarrenr  setElaboratedKeywordLoc(Loc);
40360854Sdarrenr  NestedNameSpecifierLocBuilder Builder;
40453642Sguido  Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
40553642Sguido  setQualifierLoc(Builder.getWithLocInContext(Context));
40653642Sguido  setNameLoc(Loc);
40753642Sguido}
40853642Sguido
40953642Sguidovoid
41053642SguidoDependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
41153642Sguido                                                        SourceLocation Loc) {
41292685Sdarrenr  setElaboratedKeywordLoc(Loc);
41392685Sdarrenr  if (getTypePtr()->getQualifier()) {
41492685Sdarrenr    NestedNameSpecifierLocBuilder Builder;
41560854Sdarrenr    Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
41660854Sdarrenr    setQualifierLoc(Builder.getWithLocInContext(Context));
41760854Sdarrenr  } else {
41860854Sdarrenr    setQualifierLoc(NestedNameSpecifierLoc());
41992685Sdarrenr  }
42060854Sdarrenr  setTemplateKeywordLoc(Loc);
42160854Sdarrenr  setTemplateNameLoc(Loc);
42292685Sdarrenr  setLAngleLoc(Loc);
42360854Sdarrenr  setRAngleLoc(Loc);
42492685Sdarrenr  TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
42560854Sdarrenr                                                   getTypePtr()->getArgs(),
42660854Sdarrenr                                                   getArgInfos(), Loc);
42760854Sdarrenr}
42860854Sdarrenr
42960854Sdarrenrvoid TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
43060854Sdarrenr                                                      unsigned NumArgs,
43160854Sdarrenr                                                  const TemplateArgument *Args,
43260854Sdarrenr                                              TemplateArgumentLocInfo *ArgInfos,
43360854Sdarrenr                                                      SourceLocation Loc) {
43460854Sdarrenr  for (unsigned i = 0, e = NumArgs; i != e; ++i) {
43560854Sdarrenr    switch (Args[i].getKind()) {
43660854Sdarrenr    case TemplateArgument::Null:
43760854Sdarrenr      llvm_unreachable("Impossible TemplateArgument");
43860854Sdarrenr
43960854Sdarrenr    case TemplateArgument::Integral:
44060854Sdarrenr    case TemplateArgument::Declaration:
44160854Sdarrenr    case TemplateArgument::NullPtr:
44260854Sdarrenr      ArgInfos[i] = TemplateArgumentLocInfo();
44360854Sdarrenr      break;
44460854Sdarrenr
44560854Sdarrenr    case TemplateArgument::Expression:
44660854Sdarrenr      ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
44760854Sdarrenr      break;
44860854Sdarrenr
44960854Sdarrenr    case TemplateArgument::Type:
45060854Sdarrenr      ArgInfos[i] = TemplateArgumentLocInfo(
45192685Sdarrenr                          Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
45260854Sdarrenr                                                           Loc));
45364580Sdarrenr      break;
45464580Sdarrenr
45560854Sdarrenr    case TemplateArgument::Template:
45660854Sdarrenr    case TemplateArgument::TemplateExpansion: {
45760854Sdarrenr      NestedNameSpecifierLocBuilder Builder;
45860854Sdarrenr      TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();
45960854Sdarrenr      if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
46060854Sdarrenr        Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
46160854Sdarrenr      else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
46292685Sdarrenr        Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
46392685Sdarrenr
46460854Sdarrenr      ArgInfos[i] = TemplateArgumentLocInfo(
46592685Sdarrenr          Builder.getWithLocInContext(Context), Loc,
46660854Sdarrenr          Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
46792685Sdarrenr                                                          : Loc);
46860854Sdarrenr      break;
46992685Sdarrenr    }
47060854Sdarrenr
47160854Sdarrenr    case TemplateArgument::Pack:
47260854Sdarrenr      ArgInfos[i] = TemplateArgumentLocInfo();
47360854Sdarrenr      break;
47460854Sdarrenr    }
47560854Sdarrenr  }
47660854Sdarrenr}
47760854Sdarrenr