TypeLoc.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. //===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines the TypeLoc subclasses implementations.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/AST/TypeLoc.h"
  14. #include "clang/AST/ASTContext.h"
  15. #include "clang/AST/Expr.h"
  16. #include "clang/AST/TypeLocVisitor.h"
  17. #include "llvm/Support/ErrorHandling.h"
  18. #include "llvm/Support/raw_ostream.h"
  19. using namespace clang;
  20. //===----------------------------------------------------------------------===//
  21. // TypeLoc Implementation
  22. //===----------------------------------------------------------------------===//
  23. namespace {
  24. class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
  25. public:
  26. #define ABSTRACT_TYPELOC(CLASS, PARENT)
  27. #define TYPELOC(CLASS, PARENT) \
  28. SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
  29. return TyLoc.getLocalSourceRange(); \
  30. }
  31. #include "clang/AST/TypeLocNodes.def"
  32. };
  33. }
  34. SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
  35. if (TL.isNull()) return SourceRange();
  36. return TypeLocRanger().Visit(TL);
  37. }
  38. namespace {
  39. class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
  40. public:
  41. #define ABSTRACT_TYPELOC(CLASS, PARENT)
  42. #define TYPELOC(CLASS, PARENT) \
  43. unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
  44. return TyLoc.getFullDataSize(); \
  45. }
  46. #include "clang/AST/TypeLocNodes.def"
  47. };
  48. }
  49. /// \brief Returns the size of the type source info data block.
  50. unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
  51. if (Ty.isNull()) return 0;
  52. return TypeSizer().Visit(TypeLoc(Ty, 0));
  53. }
  54. namespace {
  55. class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
  56. public:
  57. #define ABSTRACT_TYPELOC(CLASS, PARENT)
  58. #define TYPELOC(CLASS, PARENT) \
  59. TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
  60. return TyLoc.getNextTypeLoc(); \
  61. }
  62. #include "clang/AST/TypeLocNodes.def"
  63. };
  64. }
  65. /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
  66. /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
  67. TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
  68. return NextLoc().Visit(TL);
  69. }
  70. /// \brief Initializes a type location, and all of its children
  71. /// recursively, as if the entire tree had been written in the
  72. /// given location.
  73. void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
  74. SourceLocation Loc) {
  75. while (true) {
  76. switch (TL.getTypeLocClass()) {
  77. #define ABSTRACT_TYPELOC(CLASS, PARENT)
  78. #define TYPELOC(CLASS, PARENT) \
  79. case CLASS: { \
  80. CLASS##TypeLoc TLCasted = cast<CLASS##TypeLoc>(TL); \
  81. TLCasted.initializeLocal(Context, Loc); \
  82. TL = TLCasted.getNextTypeLoc(); \
  83. if (!TL) return; \
  84. continue; \
  85. }
  86. #include "clang/AST/TypeLocNodes.def"
  87. }
  88. }
  89. }
  90. SourceLocation TypeLoc::getBeginLoc() const {
  91. TypeLoc Cur = *this;
  92. TypeLoc LeftMost = Cur;
  93. while (true) {
  94. switch (Cur.getTypeLocClass()) {
  95. case Elaborated:
  96. LeftMost = Cur;
  97. break;
  98. case FunctionProto:
  99. if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn()) {
  100. LeftMost = Cur;
  101. break;
  102. }
  103. /* Fall through */
  104. case FunctionNoProto:
  105. case ConstantArray:
  106. case DependentSizedArray:
  107. case IncompleteArray:
  108. case VariableArray:
  109. // FIXME: Currently QualifiedTypeLoc does not have a source range
  110. case Qualified:
  111. Cur = Cur.getNextTypeLoc();
  112. continue;
  113. default:
  114. if (!Cur.getLocalSourceRange().getBegin().isInvalid())
  115. LeftMost = Cur;
  116. Cur = Cur.getNextTypeLoc();
  117. if (Cur.isNull())
  118. break;
  119. continue;
  120. } // switch
  121. break;
  122. } // while
  123. return LeftMost.getLocalSourceRange().getBegin();
  124. }
  125. SourceLocation TypeLoc::getEndLoc() const {
  126. TypeLoc Cur = *this;
  127. TypeLoc Last;
  128. while (true) {
  129. switch (Cur.getTypeLocClass()) {
  130. default:
  131. if (!Last)
  132. Last = Cur;
  133. return Last.getLocalSourceRange().getEnd();
  134. case Paren:
  135. case ConstantArray:
  136. case DependentSizedArray:
  137. case IncompleteArray:
  138. case VariableArray:
  139. case FunctionNoProto:
  140. Last = Cur;
  141. break;
  142. case FunctionProto:
  143. if (cast<FunctionProtoTypeLoc>(&Cur)->getTypePtr()->hasTrailingReturn())
  144. Last = TypeLoc();
  145. else
  146. Last = Cur;
  147. break;
  148. case Pointer:
  149. case BlockPointer:
  150. case MemberPointer:
  151. case LValueReference:
  152. case RValueReference:
  153. case PackExpansion:
  154. if (!Last)
  155. Last = Cur;
  156. break;
  157. case Qualified:
  158. case Elaborated:
  159. break;
  160. }
  161. Cur = Cur.getNextTypeLoc();
  162. }
  163. }
  164. namespace {
  165. struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
  166. // Overload resolution does the real work for us.
  167. static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
  168. static bool isTypeSpec(TypeLoc _) { return false; }
  169. #define ABSTRACT_TYPELOC(CLASS, PARENT)
  170. #define TYPELOC(CLASS, PARENT) \
  171. bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
  172. return isTypeSpec(TyLoc); \
  173. }
  174. #include "clang/AST/TypeLocNodes.def"
  175. };
  176. }
  177. /// \brief Determines if the given type loc corresponds to a
  178. /// TypeSpecTypeLoc. Since there is not actually a TypeSpecType in
  179. /// the type hierarchy, this is made somewhat complicated.
  180. ///
  181. /// There are a lot of types that currently use TypeSpecTypeLoc
  182. /// because it's a convenient base class. Ideally we would not accept
  183. /// those here, but ideally we would have better implementations for
  184. /// them.
  185. bool TypeSpecTypeLoc::classof(const TypeLoc *TL) {
  186. if (TL->getType().hasLocalQualifiers()) return false;
  187. return TSTChecker().Visit(*TL);
  188. }
  189. // Reimplemented to account for GNU/C++ extension
  190. // typeof unary-expression
  191. // where there are no parentheses.
  192. SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
  193. if (getRParenLoc().isValid())
  194. return SourceRange(getTypeofLoc(), getRParenLoc());
  195. else
  196. return SourceRange(getTypeofLoc(),
  197. getUnderlyingExpr()->getSourceRange().getEnd());
  198. }
  199. TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
  200. if (needsExtraLocalData())
  201. return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
  202. switch (getTypePtr()->getKind()) {
  203. case BuiltinType::Void:
  204. return TST_void;
  205. case BuiltinType::Bool:
  206. return TST_bool;
  207. case BuiltinType::Char_U:
  208. case BuiltinType::Char_S:
  209. return TST_char;
  210. case BuiltinType::Char16:
  211. return TST_char16;
  212. case BuiltinType::Char32:
  213. return TST_char32;
  214. case BuiltinType::WChar_S:
  215. case BuiltinType::WChar_U:
  216. return TST_wchar;
  217. case BuiltinType::UChar:
  218. case BuiltinType::UShort:
  219. case BuiltinType::UInt:
  220. case BuiltinType::ULong:
  221. case BuiltinType::ULongLong:
  222. case BuiltinType::UInt128:
  223. case BuiltinType::SChar:
  224. case BuiltinType::Short:
  225. case BuiltinType::Int:
  226. case BuiltinType::Long:
  227. case BuiltinType::LongLong:
  228. case BuiltinType::Int128:
  229. case BuiltinType::Half:
  230. case BuiltinType::Float:
  231. case BuiltinType::Double:
  232. case BuiltinType::LongDouble:
  233. llvm_unreachable("Builtin type needs extra local data!");
  234. // Fall through, if the impossible happens.
  235. case BuiltinType::NullPtr:
  236. case BuiltinType::Overload:
  237. case BuiltinType::Dependent:
  238. case BuiltinType::BoundMember:
  239. case BuiltinType::UnknownAny:
  240. case BuiltinType::ARCUnbridgedCast:
  241. case BuiltinType::PseudoObject:
  242. case BuiltinType::ObjCId:
  243. case BuiltinType::ObjCClass:
  244. case BuiltinType::ObjCSel:
  245. case BuiltinType::OCLImage1d:
  246. case BuiltinType::OCLImage1dArray:
  247. case BuiltinType::OCLImage1dBuffer:
  248. case BuiltinType::OCLImage2d:
  249. case BuiltinType::OCLImage2dArray:
  250. case BuiltinType::OCLImage3d:
  251. case BuiltinType::OCLSampler:
  252. case BuiltinType::OCLEvent:
  253. case BuiltinType::BuiltinFn:
  254. return TST_unspecified;
  255. }
  256. llvm_unreachable("Invalid BuiltinType Kind!");
  257. }
  258. TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
  259. while (ParenTypeLoc* PTL = dyn_cast<ParenTypeLoc>(&TL))
  260. TL = PTL->getInnerLoc();
  261. return TL;
  262. }
  263. void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
  264. SourceLocation Loc) {
  265. setElaboratedKeywordLoc(Loc);
  266. NestedNameSpecifierLocBuilder Builder;
  267. Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
  268. setQualifierLoc(Builder.getWithLocInContext(Context));
  269. }
  270. void DependentNameTypeLoc::initializeLocal(ASTContext &Context,
  271. SourceLocation Loc) {
  272. setElaboratedKeywordLoc(Loc);
  273. NestedNameSpecifierLocBuilder Builder;
  274. Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
  275. setQualifierLoc(Builder.getWithLocInContext(Context));
  276. setNameLoc(Loc);
  277. }
  278. void
  279. DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
  280. SourceLocation Loc) {
  281. setElaboratedKeywordLoc(Loc);
  282. if (getTypePtr()->getQualifier()) {
  283. NestedNameSpecifierLocBuilder Builder;
  284. Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
  285. setQualifierLoc(Builder.getWithLocInContext(Context));
  286. } else {
  287. setQualifierLoc(NestedNameSpecifierLoc());
  288. }
  289. setTemplateKeywordLoc(Loc);
  290. setTemplateNameLoc(Loc);
  291. setLAngleLoc(Loc);
  292. setRAngleLoc(Loc);
  293. TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
  294. getTypePtr()->getArgs(),
  295. getArgInfos(), Loc);
  296. }
  297. void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
  298. unsigned NumArgs,
  299. const TemplateArgument *Args,
  300. TemplateArgumentLocInfo *ArgInfos,
  301. SourceLocation Loc) {
  302. for (unsigned i = 0, e = NumArgs; i != e; ++i) {
  303. switch (Args[i].getKind()) {
  304. case TemplateArgument::Null:
  305. case TemplateArgument::Declaration:
  306. case TemplateArgument::Integral:
  307. case TemplateArgument::NullPtr:
  308. llvm_unreachable("Impossible TemplateArgument");
  309. case TemplateArgument::Expression:
  310. ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
  311. break;
  312. case TemplateArgument::Type:
  313. ArgInfos[i] = TemplateArgumentLocInfo(
  314. Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
  315. Loc));
  316. break;
  317. case TemplateArgument::Template:
  318. case TemplateArgument::TemplateExpansion: {
  319. NestedNameSpecifierLocBuilder Builder;
  320. TemplateName Template = Args[i].getAsTemplate();
  321. if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
  322. Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
  323. else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
  324. Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
  325. ArgInfos[i] = TemplateArgumentLocInfo(
  326. Builder.getWithLocInContext(Context),
  327. Loc,
  328. Args[i].getKind() == TemplateArgument::Template
  329. ? SourceLocation()
  330. : Loc);
  331. break;
  332. }
  333. case TemplateArgument::Pack:
  334. ArgInfos[i] = TemplateArgumentLocInfo();
  335. break;
  336. }
  337. }
  338. }