diff options
author | Guy Benyei <guy.benyei@intel.com> | 2012-12-18 12:30:03 +0000 |
---|---|---|
committer | Guy Benyei <guy.benyei@intel.com> | 2012-12-18 12:30:03 +0000 |
commit | b13abb952a99d74c6464ab5360bae635365ff8ff (patch) | |
tree | 73d912f69bd6eabad9cd99b82d2b5f659259b77c /clang/lib/AST/TypeLoc.cpp | |
parent | 42230ae21618d4d9406f2b8a130309246c7a7a12 (diff) |
Add OpenCL images as clang builtin types.
llvm-svn: 170428
Diffstat (limited to 'clang/lib/AST/TypeLoc.cpp')
-rw-r--r-- | clang/lib/AST/TypeLoc.cpp | 728 |
1 files changed, 367 insertions, 361 deletions
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index c021cf886b36..b86d2260a0c2 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -1,361 +1,367 @@ -//===--- 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; - } - } -} +//===--- 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;
+ }
+ }
+}
|