diff options
author | Guy Benyei <guy.benyei@intel.com> | 2012-12-18 14:30:41 +0000 |
---|---|---|
committer | Guy Benyei <guy.benyei@intel.com> | 2012-12-18 14:30:41 +0000 |
commit | 7f92f2d8d9b7a07900c030183bc13a9ff60057cc (patch) | |
tree | 052362adb489ba77d21629c894891132fdbbd25d /lib/AST/TypeLoc.cpp | |
parent | 736104a7619c53ef92553780273d7357a3cdde81 (diff) |
Revert changes from r170428, as I accidentally changed the line endings of these files to Windows style.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170431 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/TypeLoc.cpp')
-rw-r--r-- | lib/AST/TypeLoc.cpp | 728 |
1 files changed, 361 insertions, 367 deletions
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index b86d2260a0..c021cf886b 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -1,367 +1,361 @@ -//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TypeLoc subclasses implementations.
-//
-//===----------------------------------------------------------------------===//
-
-#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"
-#include "llvm/Support/raw_ostream.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// TypeLoc Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
- class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
- public:
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
- SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- return TyLoc.getLocalSourceRange(); \
- }
-#include "clang/AST/TypeLocNodes.def"
- };
-}
-
-SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
- if (TL.isNull()) return SourceRange();
- return TypeLocRanger().Visit(TL);
-}
-
-namespace {
- class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
- public:
-#define ABSTRACT_TYPELOC(CLASS, PARENT)
-#define TYPELOC(CLASS, PARENT) \
- unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- return TyLoc.getFullDataSize(); \
- }
-#include "clang/AST/TypeLocNodes.def"
- };
-}
-
-/// \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));
-}
-
-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 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::getNextTypeLocImpl(TypeLoc TL) {
- return NextLoc().Visit(TL);
-}
-
-/// \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 = cast<CLASS##TypeLoc>(TL); \
- TLCasted.initializeLocal(Context, Loc); \
- TL = TLCasted.getNextTypeLoc(); \
- if (!TL) return; \
- continue; \
- }
-#include "clang/AST/TypeLocNodes.def"
- }
- }
-}
-
-SourceLocation TypeLoc::getBeginLoc() const {
- TypeLoc Cur = *this;
- TypeLoc LeftMost = Cur;
- while (true) {
- switch (Cur.getTypeLocClass()) {
- case Elaborated:
- LeftMost = Cur;
- break;
- case FunctionProto:
- if (cast<FunctionProtoTypeLoc>(&Cur)->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().isInvalid())
- LeftMost = Cur;
- Cur = Cur.getNextTypeLoc();
- if (Cur.isNull())
- break;
- continue;
- } // switch
- break;
- } // while
- return LeftMost.getLocalSourceRange().getBegin();
-}
-
-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 (cast<FunctionProtoTypeLoc>(&Cur)->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();
- }
-}
-
-
-namespace {
- 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) \
- bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- return isTypeSpec(TyLoc); \
- }
-#include "clang/AST/TypeLocNodes.def"
- };
-}
-
-
-/// \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::classof(const TypeLoc *TL) {
- if (TL->getType().hasLocalQualifiers()) return false;
- return TSTChecker().Visit(*TL);
-}
-
-// 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());
-}
-
-
-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:
- 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:
- case BuiltinType::OCLImage1d:
- case BuiltinType::OCLImage1dArray:
- case BuiltinType::OCLImage1dBuffer:
- case BuiltinType::OCLImage2d:
- case BuiltinType::OCLImage2dArray:
- case BuiltinType::OCLImage3d:
- case BuiltinType::BuiltinFn:
- return TST_unspecified;
- }
-
- llvm_unreachable("Invalid BuiltinType Kind!");
-}
-
-TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
- while (ParenTypeLoc* PTL = dyn_cast<ParenTypeLoc>(&TL))
- TL = PTL->getInnerLoc();
- return TL;
-}
-
-void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
- SourceLocation Loc) {
- setElaboratedKeywordLoc(Loc);
- NestedNameSpecifierLocBuilder Builder;
- Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
- setQualifierLoc(Builder.getWithLocInContext(Context));
-}
-
-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);
-}
-
-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:
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::NullPtr:
- llvm_unreachable("Impossible TemplateArgument");
-
- 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].getAsTemplate();
- 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;
- }
- }
-}
+//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the TypeLoc subclasses implementations. +// +//===----------------------------------------------------------------------===// + +#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" +#include "llvm/Support/raw_ostream.h" +using namespace clang; + +//===----------------------------------------------------------------------===// +// TypeLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> { + public: +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return TyLoc.getLocalSourceRange(); \ + } +#include "clang/AST/TypeLocNodes.def" + }; +} + +SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) { + if (TL.isNull()) return SourceRange(); + return TypeLocRanger().Visit(TL); +} + +namespace { + class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> { + public: +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return TyLoc.getFullDataSize(); \ + } +#include "clang/AST/TypeLocNodes.def" + }; +} + +/// \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)); +} + +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 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::getNextTypeLocImpl(TypeLoc TL) { + return NextLoc().Visit(TL); +} + +/// \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 = cast<CLASS##TypeLoc>(TL); \ + TLCasted.initializeLocal(Context, Loc); \ + TL = TLCasted.getNextTypeLoc(); \ + if (!TL) return; \ + continue; \ + } +#include "clang/AST/TypeLocNodes.def" + } + } +} + +SourceLocation TypeLoc::getBeginLoc() const { + TypeLoc Cur = *this; + TypeLoc LeftMost = Cur; + while (true) { + switch (Cur.getTypeLocClass()) { + case Elaborated: + LeftMost = Cur; + break; + case FunctionProto: + if (cast<FunctionProtoTypeLoc>(&Cur)->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().isInvalid()) + LeftMost = Cur; + Cur = Cur.getNextTypeLoc(); + if (Cur.isNull()) + break; + continue; + } // switch + break; + } // while + return LeftMost.getLocalSourceRange().getBegin(); +} + +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 (cast<FunctionProtoTypeLoc>(&Cur)->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(); + } +} + + +namespace { + 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) \ + bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return isTypeSpec(TyLoc); \ + } +#include "clang/AST/TypeLocNodes.def" + }; +} + + +/// \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::classof(const TypeLoc *TL) { + if (TL->getType().hasLocalQualifiers()) return false; + return TSTChecker().Visit(*TL); +} + +// 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()); +} + + +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: + 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: + case BuiltinType::BuiltinFn: + return TST_unspecified; + } + + llvm_unreachable("Invalid BuiltinType Kind!"); +} + +TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) { + while (ParenTypeLoc* PTL = dyn_cast<ParenTypeLoc>(&TL)) + TL = PTL->getInnerLoc(); + return TL; +} + +void ElaboratedTypeLoc::initializeLocal(ASTContext &Context, + SourceLocation Loc) { + setElaboratedKeywordLoc(Loc); + NestedNameSpecifierLocBuilder Builder; + Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc); + setQualifierLoc(Builder.getWithLocInContext(Context)); +} + +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); +} + +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: + case TemplateArgument::Declaration: + case TemplateArgument::Integral: + case TemplateArgument::NullPtr: + llvm_unreachable("Impossible TemplateArgument"); + + 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].getAsTemplate(); + 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; + } + } +} |