Bug Summary

File:tools/clang/lib/AST/TypeLoc.cpp
Warning:line 119, column 36
Undefined or garbage value returned to caller

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name TypeLoc.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/lib/AST -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/clang/lib/AST -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c++ /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/TypeLoc.cpp

/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/TypeLoc.cpp

1//===- TypeLoc.cpp - Type Source Info Wrapper -----------------------------===//
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
14#include "clang/AST/TypeLoc.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Expr.h"
17#include "clang/AST/NestedNameSpecifier.h"
18#include "clang/AST/TemplateBase.h"
19#include "clang/AST/TemplateName.h"
20#include "clang/AST/TypeLocVisitor.h"
21#include "clang/Basic/SourceLocation.h"
22#include "clang/Basic/Specifiers.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/MathExtras.h"
25#include <algorithm>
26#include <cassert>
27#include <cstdint>
28#include <cstring>
29
30using namespace clang;
31
32static const unsigned TypeLocMaxDataAlign = alignof(void *);
33
34//===----------------------------------------------------------------------===//
35// TypeLoc Implementation
36//===----------------------------------------------------------------------===//
37
38namespace {
39
40class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
41public:
42#define ABSTRACT_TYPELOC(CLASS, PARENT)
43#define TYPELOC(CLASS, PARENT) \
44 SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
45 return TyLoc.getLocalSourceRange(); \
46 }
47#include "clang/AST/TypeLocNodes.def"
48};
49
50} // namespace
51
52SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
53 if (TL.isNull()) return SourceRange();
54 return TypeLocRanger().Visit(TL);
55}
56
57namespace {
58
59class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
60public:
61#define ABSTRACT_TYPELOC(CLASS, PARENT)
62#define TYPELOC(CLASS, PARENT) \
63 unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
64 return TyLoc.getLocalDataAlignment(); \
65 }
66#include "clang/AST/TypeLocNodes.def"
67};
68
69} // namespace
70
71/// \brief Returns the alignment of the type source info data block.
72unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
73 if (Ty.isNull()) return 1;
74 return TypeAligner().Visit(TypeLoc(Ty, nullptr));
75}
76
77namespace {
78
79class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
80public:
81#define ABSTRACT_TYPELOC(CLASS, PARENT)
82#define TYPELOC(CLASS, PARENT) \
83 unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
84 return TyLoc.getLocalDataSize(); \
85 }
86#include "clang/AST/TypeLocNodes.def"
87};
88
89} // namespace
90
91/// \brief Returns the size of the type source info data block.
92unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
93 unsigned Total = 0;
94 TypeLoc TyLoc(Ty, nullptr);
95 unsigned MaxAlign = 1;
96 while (!TyLoc.isNull()) {
97 unsigned Align = getLocalAlignmentForType(TyLoc.getType());
98 MaxAlign = std::max(Align, MaxAlign);
99 Total = llvm::alignTo(Total, Align);
100 Total += TypeSizer().Visit(TyLoc);
101 TyLoc = TyLoc.getNextTypeLoc();
102 }
103 Total = llvm::alignTo(Total, MaxAlign);
104 return Total;
105}
106
107namespace {
108
109class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
110public:
111#define ABSTRACT_TYPELOC(CLASS, PARENT)
112#define TYPELOC(CLASS, PARENT) \
113 TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
114 return TyLoc.getNextTypeLoc(); \
115 }
116#include "clang/AST/TypeLocNodes.def"
117};
118
119} // namespace
120
121/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
122/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
123TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) {
124 return NextLoc().Visit(TL);
125}
126
127/// \brief Initializes a type location, and all of its children
128/// recursively, as if the entire tree had been written in the
129/// given location.
130void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
131 SourceLocation Loc) {
132 while (true) {
133 switch (TL.getTypeLocClass()) {
134#define ABSTRACT_TYPELOC(CLASS, PARENT)
135#define TYPELOC(CLASS, PARENT) \
136 case CLASS: { \
137 CLASS##TypeLoc TLCasted = TL.castAs<CLASS##TypeLoc>(); \
138 TLCasted.initializeLocal(Context, Loc); \
139 TL = TLCasted.getNextTypeLoc(); \
140 if (!TL) return; \
141 continue; \
142 }
143#include "clang/AST/TypeLocNodes.def"
144 }
145 }
146}
147
148namespace {
149
150class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
151 TypeLoc Source;
152
153public:
154 TypeLocCopier(TypeLoc source) : Source(source) {}
155
156#define ABSTRACT_TYPELOC(CLASS, PARENT)
157#define TYPELOC(CLASS, PARENT) \
158 void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) { \
159 dest.copyLocal(Source.castAs<CLASS##TypeLoc>()); \
160 }
161#include "clang/AST/TypeLocNodes.def"
162};
163
164} // namespace
165
166void TypeLoc::copy(TypeLoc other) {
167 assert(getFullDataSize() == other.getFullDataSize())(static_cast <bool> (getFullDataSize() == other.getFullDataSize
()) ? void (0) : __assert_fail ("getFullDataSize() == other.getFullDataSize()"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/TypeLoc.cpp"
, 167, __extension__ __PRETTY_FUNCTION__))
;
168
169 // If both data pointers are aligned to the maximum alignment, we
170 // can memcpy because getFullDataSize() accurately reflects the
171 // layout of the data.
172 if (reinterpret_cast<uintptr_t>(Data) ==
173 llvm::alignTo(reinterpret_cast<uintptr_t>(Data),
174 TypeLocMaxDataAlign) &&
175 reinterpret_cast<uintptr_t>(other.Data) ==
176 llvm::alignTo(reinterpret_cast<uintptr_t>(other.Data),
177 TypeLocMaxDataAlign)) {
178 memcpy(Data, other.Data, getFullDataSize());
179 return;
180 }
181
182 // Copy each of the pieces.
183 TypeLoc TL(getType(), Data);
184 do {
185 TypeLocCopier(other).Visit(TL);
186 other = other.getNextTypeLoc();
187 } while ((TL = TL.getNextTypeLoc()));
188}
189
190SourceLocation TypeLoc::getBeginLoc() const {
191 TypeLoc Cur = *this;
192 TypeLoc LeftMost = Cur;
193 while (true) {
194 switch (Cur.getTypeLocClass()) {
195 case Elaborated:
196 LeftMost = Cur;
197 break;
198 case FunctionProto:
199 if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()
200 ->hasTrailingReturn()) {
201 LeftMost = Cur;
202 break;
203 }
204 LLVM_FALLTHROUGH[[clang::fallthrough]];
205 case FunctionNoProto:
206 case ConstantArray:
207 case DependentSizedArray:
208 case IncompleteArray:
209 case VariableArray:
210 // FIXME: Currently QualifiedTypeLoc does not have a source range
211 case Qualified:
212 Cur = Cur.getNextTypeLoc();
213 continue;
214 default:
215 if (Cur.getLocalSourceRange().getBegin().isValid())
216 LeftMost = Cur;
217 Cur = Cur.getNextTypeLoc();
218 if (Cur.isNull())
219 break;
220 continue;
221 } // switch
222 break;
223 } // while
224 return LeftMost.getLocalSourceRange().getBegin();
225}
226
227SourceLocation TypeLoc::getEndLoc() const {
228 TypeLoc Cur = *this;
229 TypeLoc Last;
230 while (true) {
231 switch (Cur.getTypeLocClass()) {
232 default:
233 if (!Last)
234 Last = Cur;
235 return Last.getLocalSourceRange().getEnd();
236 case Paren:
237 case ConstantArray:
238 case DependentSizedArray:
239 case IncompleteArray:
240 case VariableArray:
241 case FunctionNoProto:
242 Last = Cur;
243 break;
244 case FunctionProto:
245 if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()->hasTrailingReturn())
246 Last = TypeLoc();
247 else
248 Last = Cur;
249 break;
250 case Pointer:
251 case BlockPointer:
252 case MemberPointer:
253 case LValueReference:
254 case RValueReference:
255 case PackExpansion:
256 if (!Last)
257 Last = Cur;
258 break;
259 case Qualified:
260 case Elaborated:
261 break;
262 }
263 Cur = Cur.getNextTypeLoc();
264 }
265}
266
267namespace {
268
269struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
270 // Overload resolution does the real work for us.
271 static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
272 static bool isTypeSpec(TypeLoc _) { return false; }
273
274#define ABSTRACT_TYPELOC(CLASS, PARENT)
275#define TYPELOC(CLASS, PARENT) \
276 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
277 return isTypeSpec(TyLoc); \
278 }
279#include "clang/AST/TypeLocNodes.def"
280};
281
282} // namespace
283
284/// \brief Determines if the given type loc corresponds to a
285/// TypeSpecTypeLoc. Since there is not actually a TypeSpecType in
286/// the type hierarchy, this is made somewhat complicated.
287///
288/// There are a lot of types that currently use TypeSpecTypeLoc
289/// because it's a convenient base class. Ideally we would not accept
290/// those here, but ideally we would have better implementations for
291/// them.
292bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
293 if (TL.getType().hasLocalQualifiers()) return false;
294 return TSTChecker().Visit(TL);
295}
296
297// Reimplemented to account for GNU/C++ extension
298// typeof unary-expression
299// where there are no parentheses.
300SourceRange TypeOfExprTypeLoc::getLocalSourceRange() const {
301 if (getRParenLoc().isValid())
302 return SourceRange(getTypeofLoc(), getRParenLoc());
303 else
304 return SourceRange(getTypeofLoc(),
305 getUnderlyingExpr()->getSourceRange().getEnd());
306}
307
308
309TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
310 if (needsExtraLocalData())
311 return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
312 switch (getTypePtr()->getKind()) {
313 case BuiltinType::Void:
314 return TST_void;
315 case BuiltinType::Bool:
316 return TST_bool;
317 case BuiltinType::Char_U:
318 case BuiltinType::Char_S:
319 return TST_char;
320 case BuiltinType::Char16:
321 return TST_char16;
322 case BuiltinType::Char32:
323 return TST_char32;
324 case BuiltinType::WChar_S:
325 case BuiltinType::WChar_U:
326 return TST_wchar;
327 case BuiltinType::UChar:
328 case BuiltinType::UShort:
329 case BuiltinType::UInt:
330 case BuiltinType::ULong:
331 case BuiltinType::ULongLong:
332 case BuiltinType::UInt128:
333 case BuiltinType::SChar:
334 case BuiltinType::Short:
335 case BuiltinType::Int:
336 case BuiltinType::Long:
337 case BuiltinType::LongLong:
338 case BuiltinType::Int128:
339 case BuiltinType::Half:
340 case BuiltinType::Float:
341 case BuiltinType::Double:
342 case BuiltinType::LongDouble:
343 case BuiltinType::Float16:
344 case BuiltinType::Float128:
345 llvm_unreachable("Builtin type needs extra local data!")::llvm::llvm_unreachable_internal("Builtin type needs extra local data!"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/TypeLoc.cpp"
, 345)
;
346 // Fall through, if the impossible happens.
347
348 case BuiltinType::NullPtr:
349 case BuiltinType::Overload:
350 case BuiltinType::Dependent:
351 case BuiltinType::BoundMember:
352 case BuiltinType::UnknownAny:
353 case BuiltinType::ARCUnbridgedCast:
354 case BuiltinType::PseudoObject:
355 case BuiltinType::ObjCId:
356 case BuiltinType::ObjCClass:
357 case BuiltinType::ObjCSel:
358#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
359 case BuiltinType::Id:
360#include "clang/Basic/OpenCLImageTypes.def"
361 case BuiltinType::OCLSampler:
362 case BuiltinType::OCLEvent:
363 case BuiltinType::OCLClkEvent:
364 case BuiltinType::OCLQueue:
365 case BuiltinType::OCLReserveID:
366 case BuiltinType::BuiltinFn:
367 case BuiltinType::OMPArraySection:
368 return TST_unspecified;
369 }
370
371 llvm_unreachable("Invalid BuiltinType Kind!")::llvm::llvm_unreachable_internal("Invalid BuiltinType Kind!"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/TypeLoc.cpp"
, 371)
;
372}
373
374TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
375 while (ParenTypeLoc PTL = TL.getAs<ParenTypeLoc>())
6
Calling 'TypeLoc::operator bool'
376 TL = PTL.getInnerLoc();
377 return TL;
378}
379
380SourceLocation TypeLoc::findNullabilityLoc() const {
381 if (auto attributedLoc = getAs<AttributedTypeLoc>()) {
382 if (attributedLoc.getAttrKind() == AttributedType::attr_nullable ||
383 attributedLoc.getAttrKind() == AttributedType::attr_nonnull ||
384 attributedLoc.getAttrKind() == AttributedType::attr_null_unspecified)
385 return attributedLoc.getAttrNameLoc();
386 }
387
388 return {};
389}
390
391TypeLoc TypeLoc::findExplicitQualifierLoc() const {
392 // Qualified types.
393 if (auto qual = getAs<QualifiedTypeLoc>())
1
Assuming the condition is false
2
Taking false branch
394 return qual;
395
396 TypeLoc loc = IgnoreParens();
3
Calling 'TypeLoc::IgnoreParens'
397
398 // Attributed types.
399 if (auto attr = loc.getAs<AttributedTypeLoc>()) {
400 if (attr.isQualifier()) return attr;
401 return attr.getModifiedLoc().findExplicitQualifierLoc();
402 }
403
404 // C11 _Atomic types.
405 if (auto atomic = loc.getAs<AtomicTypeLoc>()) {
406 return atomic;
407 }
408
409 return {};
410}
411
412void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
413 SourceLocation Loc) {
414 setNameLoc(Loc);
415 if (!getNumProtocols()) return;
416
417 setProtocolLAngleLoc(Loc);
418 setProtocolRAngleLoc(Loc);
419 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
420 setProtocolLoc(i, Loc);
421}
422
423void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,
424 SourceLocation Loc) {
425 setHasBaseTypeAsWritten(true);
426 setTypeArgsLAngleLoc(Loc);
427 setTypeArgsRAngleLoc(Loc);
428 for (unsigned i = 0, e = getNumTypeArgs(); i != e; ++i) {
429 setTypeArgTInfo(i,
430 Context.getTrivialTypeSourceInfo(
431 getTypePtr()->getTypeArgsAsWritten()[i], Loc));
432 }
433 setProtocolLAngleLoc(Loc);
434 setProtocolRAngleLoc(Loc);
435 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
436 setProtocolLoc(i, Loc);
437}
438
439void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
440 SourceLocation Loc) {
441 TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
442 ::initializeLocal(Context, Loc);
443 this->getLocalData()->UnderlyingTInfo = Context.getTrivialTypeSourceInfo(
444 getUnderlyingType(), Loc);
445}
446
447void UnaryTransformTypeLoc::initializeLocal(ASTContext &Context,
448 SourceLocation Loc) {
449 setKWLoc(Loc);
450 setRParenLoc(Loc);
451 setLParenLoc(Loc);
452 this->setUnderlyingTInfo(
453 Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc));
454}
455
456void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
457 SourceLocation Loc) {
458 setElaboratedKeywordLoc(Loc);
459 NestedNameSpecifierLocBuilder Builder;
460 Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
461 setQualifierLoc(Builder.getWithLocInContext(Context));
462}
463
464void DependentNameTypeLoc::initializeLocal(ASTContext &Context,
465 SourceLocation Loc) {
466 setElaboratedKeywordLoc(Loc);
467 NestedNameSpecifierLocBuilder Builder;
468 Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
469 setQualifierLoc(Builder.getWithLocInContext(Context));
470 setNameLoc(Loc);
471}
472
473void
474DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
475 SourceLocation Loc) {
476 setElaboratedKeywordLoc(Loc);
477 if (getTypePtr()->getQualifier()) {
478 NestedNameSpecifierLocBuilder Builder;
479 Builder.MakeTrivial(Context, getTypePtr()->getQualifier(), Loc);
480 setQualifierLoc(Builder.getWithLocInContext(Context));
481 } else {
482 setQualifierLoc(NestedNameSpecifierLoc());
483 }
484 setTemplateKeywordLoc(Loc);
485 setTemplateNameLoc(Loc);
486 setLAngleLoc(Loc);
487 setRAngleLoc(Loc);
488 TemplateSpecializationTypeLoc::initializeArgLocs(Context, getNumArgs(),
489 getTypePtr()->getArgs(),
490 getArgInfos(), Loc);
491}
492
493void TemplateSpecializationTypeLoc::initializeArgLocs(ASTContext &Context,
494 unsigned NumArgs,
495 const TemplateArgument *Args,
496 TemplateArgumentLocInfo *ArgInfos,
497 SourceLocation Loc) {
498 for (unsigned i = 0, e = NumArgs; i != e; ++i) {
499 switch (Args[i].getKind()) {
500 case TemplateArgument::Null:
501 llvm_unreachable("Impossible TemplateArgument")::llvm::llvm_unreachable_internal("Impossible TemplateArgument"
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/lib/AST/TypeLoc.cpp"
, 501)
;
502
503 case TemplateArgument::Integral:
504 case TemplateArgument::Declaration:
505 case TemplateArgument::NullPtr:
506 ArgInfos[i] = TemplateArgumentLocInfo();
507 break;
508
509 case TemplateArgument::Expression:
510 ArgInfos[i] = TemplateArgumentLocInfo(Args[i].getAsExpr());
511 break;
512
513 case TemplateArgument::Type:
514 ArgInfos[i] = TemplateArgumentLocInfo(
515 Context.getTrivialTypeSourceInfo(Args[i].getAsType(),
516 Loc));
517 break;
518
519 case TemplateArgument::Template:
520 case TemplateArgument::TemplateExpansion: {
521 NestedNameSpecifierLocBuilder Builder;
522 TemplateName Template = Args[i].getAsTemplateOrTemplatePattern();
523 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
524 Builder.MakeTrivial(Context, DTN->getQualifier(), Loc);
525 else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
526 Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
527
528 ArgInfos[i] = TemplateArgumentLocInfo(
529 Builder.getWithLocInContext(Context), Loc,
530 Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
531 : Loc);
532 break;
533 }
534
535 case TemplateArgument::Pack:
536 ArgInfos[i] = TemplateArgumentLocInfo();
537 break;
538 }
539 }
540}

/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h

1//===- TypeLoc.h - 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/// \file
11/// \brief Defines the clang::TypeLoc interface and its subclasses.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_TYPELOC_H
16#define LLVM_CLANG_AST_TYPELOC_H
17
18#include "clang/AST/Decl.h"
19#include "clang/AST/NestedNameSpecifier.h"
20#include "clang/AST/TemplateBase.h"
21#include "clang/AST/Type.h"
22#include "clang/Basic/LLVM.h"
23#include "clang/Basic/SourceLocation.h"
24#include "clang/Basic/Specifiers.h"
25#include "llvm/ADT/ArrayRef.h"
26#include "llvm/Support/Casting.h"
27#include "llvm/Support/Compiler.h"
28#include "llvm/Support/MathExtras.h"
29#include <algorithm>
30#include <cassert>
31#include <cstdint>
32#include <cstring>
33
34namespace clang {
35
36class ASTContext;
37class CXXRecordDecl;
38class Expr;
39class ObjCInterfaceDecl;
40class ObjCProtocolDecl;
41class ObjCTypeParamDecl;
42class TemplateTypeParmDecl;
43class UnqualTypeLoc;
44class UnresolvedUsingTypenameDecl;
45
46// Predeclare all the type nodes.
47#define ABSTRACT_TYPELOC(Class, Base)
48#define TYPELOC(Class, Base) \
49 class Class##TypeLoc;
50#include "clang/AST/TypeLocNodes.def"
51
52/// \brief Base wrapper for a particular "section" of type source info.
53///
54/// A client should use the TypeLoc subclasses through castAs()/getAs()
55/// in order to get at the actual information.
56class TypeLoc {
57protected:
58 // The correctness of this relies on the property that, for Type *Ty,
59 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
60 const void *Ty = nullptr;
61 void *Data = nullptr;
62
63public:
64 TypeLoc() = default;
65 TypeLoc(QualType ty, void *opaqueData)
66 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {}
67 TypeLoc(const Type *ty, void *opaqueData)
68 : Ty(ty), Data(opaqueData) {}
69
70 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
71 /// is of the desired type.
72 ///
73 /// \pre T::isKind(*this)
74 template<typename T>
75 T castAs() const {
76 assert(T::isKind(*this))(static_cast <bool> (T::isKind(*this)) ? void (0) : __assert_fail
("T::isKind(*this)", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 76, __extension__ __PRETTY_FUNCTION__))
;
77 T t;
78 TypeLoc& tl = t;
79 tl = *this;
80 return t;
81 }
82
83 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
84 /// this TypeLoc is not of the desired type.
85 template<typename T>
86 T getAs() const {
87 if (!T::isKind(*this))
88 return {};
89 T t;
90 TypeLoc& tl = t;
91 tl = *this;
92 return t;
93 }
94
95 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
96 /// this TypeLock is not of the desired type. It will consider type
97 /// adjustments from a type that wad written as a T to another type that is
98 /// still canonically a T (ignores parens, attributes, elaborated types, etc).
99 template <typename T>
100 T getAsAdjusted() const;
101
102 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
103 /// except it also defines a Qualified enum that corresponds to the
104 /// QualifiedLoc class.
105 enum TypeLocClass {
106#define ABSTRACT_TYPE(Class, Base)
107#define TYPE(Class, Base) \
108 Class = Type::Class,
109#include "clang/AST/TypeNodes.def"
110 Qualified
111 };
112
113 TypeLocClass getTypeLocClass() const {
114 if (getType().hasLocalQualifiers()) return Qualified;
115 return (TypeLocClass) getType()->getTypeClass();
116 }
117
118 bool isNull() const { return !Ty; }
119 explicit operator bool() const { return Ty; }
7
Undefined or garbage value returned to caller
120
121 /// \brief Returns the size of type source info data block for the given type.
122 static unsigned getFullDataSizeForType(QualType Ty);
123
124 /// \brief Returns the alignment of type source info data block for
125 /// the given type.
126 static unsigned getLocalAlignmentForType(QualType Ty);
127
128 /// \brief Get the type for which this source info wrapper provides
129 /// information.
130 QualType getType() const {
131 return QualType::getFromOpaquePtr(Ty);
132 }
133
134 const Type *getTypePtr() const {
135 return QualType::getFromOpaquePtr(Ty).getTypePtr();
136 }
137
138 /// \brief Get the pointer where source information is stored.
139 void *getOpaqueData() const {
140 return Data;
141 }
142
143 /// \brief Get the begin source location.
144 SourceLocation getBeginLoc() const;
145
146 /// \brief Get the end source location.
147 SourceLocation getEndLoc() const;
148
149 /// \brief Get the full source range.
150 SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__)) {
151 return SourceRange(getBeginLoc(), getEndLoc());
152 }
153
154 SourceLocation getLocStart() const LLVM_READONLY__attribute__((__pure__)) { return getBeginLoc(); }
155 SourceLocation getLocEnd() const LLVM_READONLY__attribute__((__pure__)) { return getEndLoc(); }
156
157 /// \brief Get the local source range.
158 SourceRange getLocalSourceRange() const {
159 return getLocalSourceRangeImpl(*this);
160 }
161
162 /// \brief Returns the size of the type source info data block.
163 unsigned getFullDataSize() const {
164 return getFullDataSizeForType(getType());
165 }
166
167 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
168 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
169 TypeLoc getNextTypeLoc() const {
170 return getNextTypeLocImpl(*this);
171 }
172
173 /// \brief Skips past any qualifiers, if this is qualified.
174 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
175
176 TypeLoc IgnoreParens() const;
177
178 /// \brief Find a type with the location of an explicit type qualifier.
179 ///
180 /// The result, if non-null, will be one of:
181 /// QualifiedTypeLoc
182 /// AtomicTypeLoc
183 /// AttributedTypeLoc, for those type attributes that behave as qualifiers
184 TypeLoc findExplicitQualifierLoc() const;
185
186 /// \brief Initializes this to state that every location in this
187 /// type is the given location.
188 ///
189 /// This method exists to provide a simple transition for code that
190 /// relies on location-less types.
191 void initialize(ASTContext &Context, SourceLocation Loc) const {
192 initializeImpl(Context, *this, Loc);
193 }
194
195 /// \brief Initializes this by copying its information from another
196 /// TypeLoc of the same type.
197 void initializeFullCopy(TypeLoc Other) {
198 assert(getType() == Other.getType())(static_cast <bool> (getType() == Other.getType()) ? void
(0) : __assert_fail ("getType() == Other.getType()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 198, __extension__ __PRETTY_FUNCTION__))
;
199 copy(Other);
200 }
201
202 /// \brief Initializes this by copying its information from another
203 /// TypeLoc of the same type. The given size must be the full data
204 /// size.
205 void initializeFullCopy(TypeLoc Other, unsigned Size) {
206 assert(getType() == Other.getType())(static_cast <bool> (getType() == Other.getType()) ? void
(0) : __assert_fail ("getType() == Other.getType()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 206, __extension__ __PRETTY_FUNCTION__))
;
207 assert(getFullDataSize() == Size)(static_cast <bool> (getFullDataSize() == Size) ? void (
0) : __assert_fail ("getFullDataSize() == Size", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 207, __extension__ __PRETTY_FUNCTION__))
;
208 copy(Other);
209 }
210
211 /// Copies the other type loc into this one.
212 void copy(TypeLoc other);
213
214 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
215 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
216 }
217
218 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
219 return !(LHS == RHS);
220 }
221
222 /// Find the location of the nullability specifier (__nonnull,
223 /// __nullable, or __null_unspecifier), if there is one.
224 SourceLocation findNullabilityLoc() const;
225
226private:
227 static bool isKind(const TypeLoc&) {
228 return true;
229 }
230
231 static void initializeImpl(ASTContext &Context, TypeLoc TL,
232 SourceLocation Loc);
233 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
234 static TypeLoc IgnoreParensImpl(TypeLoc TL);
235 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
236};
237
238/// \brief Return the TypeLoc for a type source info.
239inline TypeLoc TypeSourceInfo::getTypeLoc() const {
240 // TODO: is this alignment already sufficient?
241 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
242}
243
244/// \brief Wrapper of type source information for a type with
245/// no direct qualifiers.
246class UnqualTypeLoc : public TypeLoc {
247public:
248 UnqualTypeLoc() = default;
249 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
250
251 const Type *getTypePtr() const {
252 return reinterpret_cast<const Type*>(Ty);
253 }
254
255 TypeLocClass getTypeLocClass() const {
256 return (TypeLocClass) getTypePtr()->getTypeClass();
257 }
258
259private:
260 friend class TypeLoc;
261
262 static bool isKind(const TypeLoc &TL) {
263 return !TL.getType().hasLocalQualifiers();
264 }
265};
266
267/// \brief Wrapper of type source information for a type with
268/// non-trivial direct qualifiers.
269///
270/// Currently, we intentionally do not provide source location for
271/// type qualifiers.
272class QualifiedTypeLoc : public TypeLoc {
273public:
274 SourceRange getLocalSourceRange() const { return {}; }
275
276 UnqualTypeLoc getUnqualifiedLoc() const {
277 unsigned align =
278 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
279 auto dataInt = reinterpret_cast<uintptr_t>(Data);
280 dataInt = llvm::alignTo(dataInt, align);
281 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
282 }
283
284 /// Initializes the local data of this type source info block to
285 /// provide no information.
286 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
287 // do nothing
288 }
289
290 void copyLocal(TypeLoc other) {
291 // do nothing
292 }
293
294 TypeLoc getNextTypeLoc() const {
295 return getUnqualifiedLoc();
296 }
297
298 /// \brief Returns the size of the type source info data block that is
299 /// specific to this type.
300 unsigned getLocalDataSize() const {
301 // In fact, we don't currently preserve any location information
302 // for qualifiers.
303 return 0;
304 }
305
306 /// \brief Returns the alignment of the type source info data block that is
307 /// specific to this type.
308 unsigned getLocalDataAlignment() const {
309 // We don't preserve any location information.
310 return 1;
311 }
312
313private:
314 friend class TypeLoc;
315
316 static bool isKind(const TypeLoc &TL) {
317 return TL.getType().hasLocalQualifiers();
318 }
319};
320
321inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
322 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
323 return Loc.getUnqualifiedLoc();
324 return castAs<UnqualTypeLoc>();
325}
326
327/// A metaprogramming base class for TypeLoc classes which correspond
328/// to a particular Type subclass. It is accepted for a single
329/// TypeLoc class to correspond to multiple Type classes.
330///
331/// \tparam Base a class from which to derive
332/// \tparam Derived the class deriving from this one
333/// \tparam TypeClass the concrete Type subclass associated with this
334/// location type
335/// \tparam LocalData the structure type of local location data for
336/// this type
337///
338/// TypeLocs with non-constant amounts of local data should override
339/// getExtraLocalDataSize(); getExtraLocalData() will then point to
340/// this extra memory.
341///
342/// TypeLocs with an inner type should define
343/// QualType getInnerType() const
344/// and getInnerTypeLoc() will then point to this inner type's
345/// location data.
346///
347/// A word about hierarchies: this template is not designed to be
348/// derived from multiple times in a hierarchy. It is also not
349/// designed to be used for classes where subtypes might provide
350/// different amounts of source information. It should be subclassed
351/// only at the deepest portion of the hierarchy where all children
352/// have identical source information; if that's an abstract type,
353/// then further descendents should inherit from
354/// InheritingConcreteTypeLoc instead.
355template <class Base, class Derived, class TypeClass, class LocalData>
356class ConcreteTypeLoc : public Base {
357 friend class TypeLoc;
358
359 const Derived *asDerived() const {
360 return static_cast<const Derived*>(this);
361 }
362
363 static bool isKind(const TypeLoc &TL) {
364 return !TL.getType().hasLocalQualifiers() &&
365 Derived::classofType(TL.getTypePtr());
366 }
367
368 static bool classofType(const Type *Ty) {
369 return TypeClass::classof(Ty);
370 }
371
372public:
373 unsigned getLocalDataAlignment() const {
374 return std::max(unsigned(alignof(LocalData)),
375 asDerived()->getExtraLocalDataAlignment());
376 }
377
378 unsigned getLocalDataSize() const {
379 unsigned size = sizeof(LocalData);
380 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
381 size = llvm::alignTo(size, extraAlign);
382 size += asDerived()->getExtraLocalDataSize();
383 return size;
384 }
385
386 void copyLocal(Derived other) {
387 // Some subclasses have no data to copy.
388 if (asDerived()->getLocalDataSize() == 0) return;
389
390 // Copy the fixed-sized local data.
391 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
392
393 // Copy the variable-sized local data. We need to do this
394 // separately because the padding in the source and the padding in
395 // the destination might be different.
396 memcpy(getExtraLocalData(), other.getExtraLocalData(),
397 asDerived()->getExtraLocalDataSize());
398 }
399
400 TypeLoc getNextTypeLoc() const {
401 return getNextTypeLoc(asDerived()->getInnerType());
402 }
403
404 const TypeClass *getTypePtr() const {
405 return cast<TypeClass>(Base::getTypePtr());
406 }
407
408protected:
409 unsigned getExtraLocalDataSize() const {
410 return 0;
411 }
412
413 unsigned getExtraLocalDataAlignment() const {
414 return 1;
415 }
416
417 LocalData *getLocalData() const {
418 return static_cast<LocalData*>(Base::Data);
419 }
420
421 /// Gets a pointer past the Info structure; useful for classes with
422 /// local data that can't be captured in the Info (e.g. because it's
423 /// of variable size).
424 void *getExtraLocalData() const {
425 unsigned size = sizeof(LocalData);
426 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
427 size = llvm::alignTo(size, extraAlign);
428 return reinterpret_cast<char*>(Base::Data) + size;
429 }
430
431 void *getNonLocalData() const {
432 auto data = reinterpret_cast<uintptr_t>(Base::Data);
433 data += asDerived()->getLocalDataSize();
434 data = llvm::alignTo(data, getNextTypeAlign());
435 return reinterpret_cast<void*>(data);
436 }
437
438 struct HasNoInnerType {};
439 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
440
441 TypeLoc getInnerTypeLoc() const {
442 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
443 }
444
445private:
446 unsigned getInnerTypeSize() const {
447 return getInnerTypeSize(asDerived()->getInnerType());
448 }
449
450 unsigned getInnerTypeSize(HasNoInnerType _) const {
451 return 0;
452 }
453
454 unsigned getInnerTypeSize(QualType _) const {
455 return getInnerTypeLoc().getFullDataSize();
456 }
457
458 unsigned getNextTypeAlign() const {
459 return getNextTypeAlign(asDerived()->getInnerType());
460 }
461
462 unsigned getNextTypeAlign(HasNoInnerType _) const {
463 return 1;
464 }
465
466 unsigned getNextTypeAlign(QualType T) const {
467 return TypeLoc::getLocalAlignmentForType(T);
468 }
469
470 TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
471
472 TypeLoc getNextTypeLoc(QualType T) const {
473 return TypeLoc(T, getNonLocalData());
474 }
475};
476
477/// A metaprogramming class designed for concrete subtypes of abstract
478/// types where all subtypes share equivalently-structured source
479/// information. See the note on ConcreteTypeLoc.
480template <class Base, class Derived, class TypeClass>
481class InheritingConcreteTypeLoc : public Base {
482 friend class TypeLoc;
483
484 static bool classofType(const Type *Ty) {
485 return TypeClass::classof(Ty);
486 }
487
488 static bool isKind(const TypeLoc &TL) {
489 return !TL.getType().hasLocalQualifiers() &&
490 Derived::classofType(TL.getTypePtr());
491 }
492 static bool isKind(const UnqualTypeLoc &TL) {
493 return Derived::classofType(TL.getTypePtr());
494 }
495
496public:
497 const TypeClass *getTypePtr() const {
498 return cast<TypeClass>(Base::getTypePtr());
499 }
500};
501
502struct TypeSpecLocInfo {
503 SourceLocation NameLoc;
504};
505
506/// \brief A reasonable base class for TypeLocs that correspond to
507/// types that are written as a type-specifier.
508class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
509 TypeSpecTypeLoc,
510 Type,
511 TypeSpecLocInfo> {
512public:
513 enum {
514 LocalDataSize = sizeof(TypeSpecLocInfo),
515 LocalDataAlignment = alignof(TypeSpecLocInfo)
516 };
517
518 SourceLocation getNameLoc() const {
519 return this->getLocalData()->NameLoc;
520 }
521
522 void setNameLoc(SourceLocation Loc) {
523 this->getLocalData()->NameLoc = Loc;
524 }
525
526 SourceRange getLocalSourceRange() const {
527 return SourceRange(getNameLoc(), getNameLoc());
528 }
529
530 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
531 setNameLoc(Loc);
532 }
533
534private:
535 friend class TypeLoc;
536
537 static bool isKind(const TypeLoc &TL);
538};
539
540struct BuiltinLocInfo {
541 SourceRange BuiltinRange;
542};
543
544/// \brief Wrapper for source info for builtin types.
545class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
546 BuiltinTypeLoc,
547 BuiltinType,
548 BuiltinLocInfo> {
549public:
550 SourceLocation getBuiltinLoc() const {
551 return getLocalData()->BuiltinRange.getBegin();
552 }
553
554 void setBuiltinLoc(SourceLocation Loc) {
555 getLocalData()->BuiltinRange = Loc;
556 }
557
558 void expandBuiltinRange(SourceRange Range) {
559 SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
560 if (!BuiltinRange.getBegin().isValid()) {
561 BuiltinRange = Range;
562 } else {
563 BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
564 BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
565 }
566 }
567
568 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
569
570 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
571 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
572 }
573 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
574 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
575 }
576
577 bool needsExtraLocalData() const {
578 BuiltinType::Kind bk = getTypePtr()->getKind();
579 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
580 || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
581 || bk == BuiltinType::UChar
582 || bk == BuiltinType::SChar;
583 }
584
585 unsigned getExtraLocalDataSize() const {
586 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
587 }
588
589 unsigned getExtraLocalDataAlignment() const {
590 return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
591 }
592
593 SourceRange getLocalSourceRange() const {
594 return getLocalData()->BuiltinRange;
595 }
596
597 TypeSpecifierSign getWrittenSignSpec() const {
598 if (needsExtraLocalData())
599 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
600 else
601 return TSS_unspecified;
602 }
603
604 bool hasWrittenSignSpec() const {
605 return getWrittenSignSpec() != TSS_unspecified;
606 }
607
608 void setWrittenSignSpec(TypeSpecifierSign written) {
609 if (needsExtraLocalData())
610 getWrittenBuiltinSpecs().Sign = written;
611 }
612
613 TypeSpecifierWidth getWrittenWidthSpec() const {
614 if (needsExtraLocalData())
615 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
616 else
617 return TSW_unspecified;
618 }
619
620 bool hasWrittenWidthSpec() const {
621 return getWrittenWidthSpec() != TSW_unspecified;
622 }
623
624 void setWrittenWidthSpec(TypeSpecifierWidth written) {
625 if (needsExtraLocalData())
626 getWrittenBuiltinSpecs().Width = written;
627 }
628
629 TypeSpecifierType getWrittenTypeSpec() const;
630
631 bool hasWrittenTypeSpec() const {
632 return getWrittenTypeSpec() != TST_unspecified;
633 }
634
635 void setWrittenTypeSpec(TypeSpecifierType written) {
636 if (needsExtraLocalData())
637 getWrittenBuiltinSpecs().Type = written;
638 }
639
640 bool hasModeAttr() const {
641 if (needsExtraLocalData())
642 return getWrittenBuiltinSpecs().ModeAttr;
643 else
644 return false;
645 }
646
647 void setModeAttr(bool written) {
648 if (needsExtraLocalData())
649 getWrittenBuiltinSpecs().ModeAttr = written;
650 }
651
652 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
653 setBuiltinLoc(Loc);
654 if (needsExtraLocalData()) {
655 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
656 wbs.Sign = TSS_unspecified;
657 wbs.Width = TSW_unspecified;
658 wbs.Type = TST_unspecified;
659 wbs.ModeAttr = false;
660 }
661 }
662};
663
664/// \brief Wrapper for source info for typedefs.
665class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
666 TypedefTypeLoc,
667 TypedefType> {
668public:
669 TypedefNameDecl *getTypedefNameDecl() const {
670 return getTypePtr()->getDecl();
671 }
672};
673
674/// \brief Wrapper for source info for injected class names of class
675/// templates.
676class InjectedClassNameTypeLoc :
677 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
678 InjectedClassNameTypeLoc,
679 InjectedClassNameType> {
680public:
681 CXXRecordDecl *getDecl() const {
682 return getTypePtr()->getDecl();
683 }
684};
685
686/// \brief Wrapper for source info for unresolved typename using decls.
687class UnresolvedUsingTypeLoc :
688 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
689 UnresolvedUsingTypeLoc,
690 UnresolvedUsingType> {
691public:
692 UnresolvedUsingTypenameDecl *getDecl() const {
693 return getTypePtr()->getDecl();
694 }
695};
696
697/// \brief Wrapper for source info for tag types. Note that this only
698/// records source info for the name itself; a type written 'struct foo'
699/// should be represented as an ElaboratedTypeLoc. We currently
700/// only do that when C++ is enabled because of the expense of
701/// creating an ElaboratedType node for so many type references in C.
702class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
703 TagTypeLoc,
704 TagType> {
705public:
706 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
707
708 /// \brief True if the tag was defined in this type specifier.
709 bool isDefinition() const {
710 TagDecl *D = getDecl();
711 return D->isCompleteDefinition() &&
712 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
713 }
714};
715
716/// \brief Wrapper for source info for record types.
717class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
718 RecordTypeLoc,
719 RecordType> {
720public:
721 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
722};
723
724/// \brief Wrapper for source info for enum types.
725class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
726 EnumTypeLoc,
727 EnumType> {
728public:
729 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
730};
731
732/// \brief Wrapper for template type parameters.
733class TemplateTypeParmTypeLoc :
734 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
735 TemplateTypeParmTypeLoc,
736 TemplateTypeParmType> {
737public:
738 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
739};
740
741struct ObjCTypeParamTypeLocInfo {
742 SourceLocation NameLoc;
743};
744
745/// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
746/// protocol qualifiers are stored after Info.
747class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
748 ObjCTypeParamTypeLoc,
749 ObjCTypeParamType,
750 ObjCTypeParamTypeLocInfo> {
751 // SourceLocations are stored after Info, one for each protocol qualifier.
752 SourceLocation *getProtocolLocArray() const {
753 return (SourceLocation*)this->getExtraLocalData() + 2;
754 }
755
756public:
757 ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
758
759 SourceLocation getNameLoc() const {
760 return this->getLocalData()->NameLoc;
761 }
762
763 void setNameLoc(SourceLocation Loc) {
764 this->getLocalData()->NameLoc = Loc;
765 }
766
767 SourceLocation getProtocolLAngleLoc() const {
768 return getNumProtocols() ?
769 *((SourceLocation*)this->getExtraLocalData()) :
770 SourceLocation();
771 }
772
773 void setProtocolLAngleLoc(SourceLocation Loc) {
774 *((SourceLocation*)this->getExtraLocalData()) = Loc;
775 }
776
777 SourceLocation getProtocolRAngleLoc() const {
778 return getNumProtocols() ?
779 *((SourceLocation*)this->getExtraLocalData() + 1) :
780 SourceLocation();
781 }
782
783 void setProtocolRAngleLoc(SourceLocation Loc) {
784 *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
785 }
786
787 unsigned getNumProtocols() const {
788 return this->getTypePtr()->getNumProtocols();
789 }
790
791 SourceLocation getProtocolLoc(unsigned i) const {
792 assert(i < getNumProtocols() && "Index is out of bounds!")(static_cast <bool> (i < getNumProtocols() &&
"Index is out of bounds!") ? void (0) : __assert_fail ("i < getNumProtocols() && \"Index is out of bounds!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 792, __extension__ __PRETTY_FUNCTION__))
;
793 return getProtocolLocArray()[i];
794 }
795
796 void setProtocolLoc(unsigned i, SourceLocation Loc) {
797 assert(i < getNumProtocols() && "Index is out of bounds!")(static_cast <bool> (i < getNumProtocols() &&
"Index is out of bounds!") ? void (0) : __assert_fail ("i < getNumProtocols() && \"Index is out of bounds!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 797, __extension__ __PRETTY_FUNCTION__))
;
798 getProtocolLocArray()[i] = Loc;
799 }
800
801 ObjCProtocolDecl *getProtocol(unsigned i) const {
802 assert(i < getNumProtocols() && "Index is out of bounds!")(static_cast <bool> (i < getNumProtocols() &&
"Index is out of bounds!") ? void (0) : __assert_fail ("i < getNumProtocols() && \"Index is out of bounds!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 802, __extension__ __PRETTY_FUNCTION__))
;
803 return *(this->getTypePtr()->qual_begin() + i);
804 }
805
806 ArrayRef<SourceLocation> getProtocolLocs() const {
807 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
808 }
809
810 void initializeLocal(ASTContext &Context, SourceLocation Loc);
811
812 unsigned getExtraLocalDataSize() const {
813 if (!this->getNumProtocols()) return 0;
814 // When there are protocol qualifers, we have LAngleLoc and RAngleLoc
815 // as well.
816 return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
817 }
818
819 unsigned getExtraLocalDataAlignment() const {
820 return alignof(SourceLocation);
821 }
822
823 SourceRange getLocalSourceRange() const {
824 SourceLocation start = getNameLoc();
825 SourceLocation end = getProtocolRAngleLoc();
826 if (end.isInvalid()) return SourceRange(start, start);
827 return SourceRange(start, end);
828 }
829};
830
831/// \brief Wrapper for substituted template type parameters.
832class SubstTemplateTypeParmTypeLoc :
833 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
834 SubstTemplateTypeParmTypeLoc,
835 SubstTemplateTypeParmType> {
836};
837
838 /// \brief Wrapper for substituted template type parameters.
839class SubstTemplateTypeParmPackTypeLoc :
840 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
841 SubstTemplateTypeParmPackTypeLoc,
842 SubstTemplateTypeParmPackType> {
843};
844
845struct AttributedLocInfo {
846 union {
847 Expr *ExprOperand;
848
849 /// A raw SourceLocation.
850 unsigned EnumOperandLoc;
851 };
852
853 SourceRange OperandParens;
854
855 SourceLocation AttrLoc;
856};
857
858/// \brief Type source information for an attributed type.
859class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
860 AttributedTypeLoc,
861 AttributedType,
862 AttributedLocInfo> {
863public:
864 AttributedType::Kind getAttrKind() const {
865 return getTypePtr()->getAttrKind();
866 }
867
868 bool hasAttrExprOperand() const {
869 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
870 getAttrKind() <= AttributedType::LastExprOperandKind);
871 }
872
873 bool hasAttrEnumOperand() const {
874 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
875 getAttrKind() <= AttributedType::LastEnumOperandKind);
876 }
877
878 bool hasAttrOperand() const {
879 return hasAttrExprOperand() || hasAttrEnumOperand();
880 }
881
882 bool isQualifier() const {
883 return getTypePtr()->isQualifier();
884 }
885
886 /// The modified type, which is generally canonically different from
887 /// the attribute type.
888 /// int main(int, char**) __attribute__((noreturn))
889 /// ~~~ ~~~~~~~~~~~~~
890 TypeLoc getModifiedLoc() const {
891 return getInnerTypeLoc();
892 }
893
894 /// The location of the attribute name, i.e.
895 /// __attribute__((regparm(1000)))
896 /// ^~~~~~~
897 SourceLocation getAttrNameLoc() const {
898 return getLocalData()->AttrLoc;
899 }
900 void setAttrNameLoc(SourceLocation loc) {
901 getLocalData()->AttrLoc = loc;
902 }
903
904 /// The attribute's expression operand, if it has one.
905 /// void *cur_thread __attribute__((address_space(21)))
906 /// ^~
907 Expr *getAttrExprOperand() const {
908 assert(hasAttrExprOperand())(static_cast <bool> (hasAttrExprOperand()) ? void (0) :
__assert_fail ("hasAttrExprOperand()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 908, __extension__ __PRETTY_FUNCTION__))
;
909 return getLocalData()->ExprOperand;
910 }
911 void setAttrExprOperand(Expr *e) {
912 assert(hasAttrExprOperand())(static_cast <bool> (hasAttrExprOperand()) ? void (0) :
__assert_fail ("hasAttrExprOperand()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 912, __extension__ __PRETTY_FUNCTION__))
;
913 getLocalData()->ExprOperand = e;
914 }
915
916 /// The location of the attribute's enumerated operand, if it has one.
917 /// void * __attribute__((objc_gc(weak)))
918 /// ^~~~
919 SourceLocation getAttrEnumOperandLoc() const {
920 assert(hasAttrEnumOperand())(static_cast <bool> (hasAttrEnumOperand()) ? void (0) :
__assert_fail ("hasAttrEnumOperand()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 920, __extension__ __PRETTY_FUNCTION__))
;
921 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
922 }
923 void setAttrEnumOperandLoc(SourceLocation loc) {
924 assert(hasAttrEnumOperand())(static_cast <bool> (hasAttrEnumOperand()) ? void (0) :
__assert_fail ("hasAttrEnumOperand()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 924, __extension__ __PRETTY_FUNCTION__))
;
925 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
926 }
927
928 /// The location of the parentheses around the operand, if there is
929 /// an operand.
930 /// void * __attribute__((objc_gc(weak)))
931 /// ^ ^
932 SourceRange getAttrOperandParensRange() const {
933 assert(hasAttrOperand())(static_cast <bool> (hasAttrOperand()) ? void (0) : __assert_fail
("hasAttrOperand()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 933, __extension__ __PRETTY_FUNCTION__))
;
934 return getLocalData()->OperandParens;
935 }
936 void setAttrOperandParensRange(SourceRange range) {
937 assert(hasAttrOperand())(static_cast <bool> (hasAttrOperand()) ? void (0) : __assert_fail
("hasAttrOperand()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 937, __extension__ __PRETTY_FUNCTION__))
;
938 getLocalData()->OperandParens = range;
939 }
940
941 SourceRange getLocalSourceRange() const {
942 // Note that this does *not* include the range of the attribute
943 // enclosure, e.g.:
944 // __attribute__((foo(bar)))
945 // ^~~~~~~~~~~~~~~ ~~
946 // or
947 // [[foo(bar)]]
948 // ^~ ~~
949 // That enclosure doesn't necessarily belong to a single attribute
950 // anyway.
951 SourceRange range(getAttrNameLoc());
952 if (hasAttrOperand())
953 range.setEnd(getAttrOperandParensRange().getEnd());
954 return range;
955 }
956
957 void initializeLocal(ASTContext &Context, SourceLocation loc) {
958 setAttrNameLoc(loc);
959 if (hasAttrExprOperand()) {
960 setAttrOperandParensRange(SourceRange(loc));
961 setAttrExprOperand(nullptr);
962 } else if (hasAttrEnumOperand()) {
963 setAttrOperandParensRange(SourceRange(loc));
964 setAttrEnumOperandLoc(loc);
965 }
966 }
967
968 QualType getInnerType() const {
969 return getTypePtr()->getModifiedType();
970 }
971};
972
973struct ObjCObjectTypeLocInfo {
974 SourceLocation TypeArgsLAngleLoc;
975 SourceLocation TypeArgsRAngleLoc;
976 SourceLocation ProtocolLAngleLoc;
977 SourceLocation ProtocolRAngleLoc;
978 bool HasBaseTypeAsWritten;
979};
980
981// A helper class for defining ObjC TypeLocs that can qualified with
982// protocols.
983//
984// TypeClass basically has to be either ObjCInterfaceType or
985// ObjCObjectPointerType.
986class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
987 ObjCObjectTypeLoc,
988 ObjCObjectType,
989 ObjCObjectTypeLocInfo> {
990 // TypeSourceInfo*'s are stored after Info, one for each type argument.
991 TypeSourceInfo **getTypeArgLocArray() const {
992 return (TypeSourceInfo**)this->getExtraLocalData();
993 }
994
995 // SourceLocations are stored after the type argument information, one for
996 // each Protocol.
997 SourceLocation *getProtocolLocArray() const {
998 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
999 }
1000
1001public:
1002 SourceLocation getTypeArgsLAngleLoc() const {
1003 return this->getLocalData()->TypeArgsLAngleLoc;
1004 }
1005
1006 void setTypeArgsLAngleLoc(SourceLocation Loc) {
1007 this->getLocalData()->TypeArgsLAngleLoc = Loc;
1008 }
1009
1010 SourceLocation getTypeArgsRAngleLoc() const {
1011 return this->getLocalData()->TypeArgsRAngleLoc;
1012 }
1013
1014 void setTypeArgsRAngleLoc(SourceLocation Loc) {
1015 this->getLocalData()->TypeArgsRAngleLoc = Loc;
1016 }
1017
1018 unsigned getNumTypeArgs() const {
1019 return this->getTypePtr()->getTypeArgsAsWritten().size();
1020 }
1021
1022 TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
1023 assert(i < getNumTypeArgs() && "Index is out of bounds!")(static_cast <bool> (i < getNumTypeArgs() &&
"Index is out of bounds!") ? void (0) : __assert_fail ("i < getNumTypeArgs() && \"Index is out of bounds!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 1023, __extension__ __PRETTY_FUNCTION__))
;
1024 return getTypeArgLocArray()[i];
1025 }
1026
1027 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
1028 assert(i < getNumTypeArgs() && "Index is out of bounds!")(static_cast <bool> (i < getNumTypeArgs() &&
"Index is out of bounds!") ? void (0) : __assert_fail ("i < getNumTypeArgs() && \"Index is out of bounds!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 1028, __extension__ __PRETTY_FUNCTION__))
;
1029 getTypeArgLocArray()[i] = TInfo;
1030 }
1031
1032 SourceLocation getProtocolLAngleLoc() const {
1033 return this->getLocalData()->ProtocolLAngleLoc;
1034 }
1035
1036 void setProtocolLAngleLoc(SourceLocation Loc) {
1037 this->getLocalData()->ProtocolLAngleLoc = Loc;
1038 }
1039
1040 SourceLocation getProtocolRAngleLoc() const {
1041 return this->getLocalData()->ProtocolRAngleLoc;
1042 }
1043
1044 void setProtocolRAngleLoc(SourceLocation Loc) {
1045 this->getLocalData()->ProtocolRAngleLoc = Loc;
1046 }
1047
1048 unsigned getNumProtocols() const {
1049 return this->getTypePtr()->getNumProtocols();
1050 }
1051
1052 SourceLocation getProtocolLoc(unsigned i) const {
1053 assert(i < getNumProtocols() && "Index is out of bounds!")(static_cast <bool> (i < getNumProtocols() &&
"Index is out of bounds!") ? void (0) : __assert_fail ("i < getNumProtocols() && \"Index is out of bounds!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 1053, __extension__ __PRETTY_FUNCTION__))
;
1054 return getProtocolLocArray()[i];
1055 }
1056
1057 void setProtocolLoc(unsigned i, SourceLocation Loc) {
1058 assert(i < getNumProtocols() && "Index is out of bounds!")(static_cast <bool> (i < getNumProtocols() &&
"Index is out of bounds!") ? void (0) : __assert_fail ("i < getNumProtocols() && \"Index is out of bounds!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 1058, __extension__ __PRETTY_FUNCTION__))
;
1059 getProtocolLocArray()[i] = Loc;
1060 }
1061
1062 ObjCProtocolDecl *getProtocol(unsigned i) const {
1063 assert(i < getNumProtocols() && "Index is out of bounds!")(static_cast <bool> (i < getNumProtocols() &&
"Index is out of bounds!") ? void (0) : __assert_fail ("i < getNumProtocols() && \"Index is out of bounds!\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 1063, __extension__ __PRETTY_FUNCTION__))
;
1064 return *(this->getTypePtr()->qual_begin() + i);
1065 }
1066
1067
1068 ArrayRef<SourceLocation> getProtocolLocs() const {
1069 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
1070 }
1071
1072 bool hasBaseTypeAsWritten() const {
1073 return getLocalData()->HasBaseTypeAsWritten;
1074 }
1075
1076 void setHasBaseTypeAsWritten(bool HasBaseType) {
1077 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1078 }
1079
1080 TypeLoc getBaseLoc() const {
1081 return getInnerTypeLoc();
1082 }
1083
1084 SourceRange getLocalSourceRange() const {
1085 SourceLocation start = getTypeArgsLAngleLoc();
1086 if (start.isInvalid())
1087 start = getProtocolLAngleLoc();
1088 SourceLocation end = getProtocolRAngleLoc();
1089 if (end.isInvalid())
1090 end = getTypeArgsRAngleLoc();
1091 return SourceRange(start, end);
1092 }
1093
1094 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1095
1096 unsigned getExtraLocalDataSize() const {
1097 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1098 + this->getNumProtocols() * sizeof(SourceLocation);
1099 }
1100
1101 unsigned getExtraLocalDataAlignment() const {
1102 static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1103 "not enough alignment for tail-allocated data");
1104 return alignof(TypeSourceInfo *);
1105 }
1106
1107 QualType getInnerType() const {
1108 return getTypePtr()->getBaseType();
1109 }
1110};
1111
1112struct ObjCInterfaceLocInfo {
1113 SourceLocation NameLoc;
1114 SourceLocation NameEndLoc;
1115};
1116
1117/// \brief Wrapper for source info for ObjC interfaces.
1118class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1119 ObjCInterfaceTypeLoc,
1120 ObjCInterfaceType,
1121 ObjCInterfaceLocInfo> {
1122public:
1123 ObjCInterfaceDecl *getIFaceDecl() const {
1124 return getTypePtr()->getDecl();
1125 }
1126
1127 SourceLocation getNameLoc() const {
1128 return getLocalData()->NameLoc;
1129 }
1130
1131 void setNameLoc(SourceLocation Loc) {
1132 getLocalData()->NameLoc = Loc;
1133 }
1134
1135 SourceRange getLocalSourceRange() const {
1136 return SourceRange(getNameLoc(), getNameEndLoc());
1137 }
1138
1139 SourceLocation getNameEndLoc() const {
1140 return getLocalData()->NameEndLoc;
1141 }
1142
1143 void setNameEndLoc(SourceLocation Loc) {
1144 getLocalData()->NameEndLoc = Loc;
1145 }
1146
1147 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1148 setNameLoc(Loc);
1149 setNameEndLoc(Loc);
1150 }
1151};
1152
1153struct ParenLocInfo {
1154 SourceLocation LParenLoc;
1155 SourceLocation RParenLoc;
1156};
1157
1158class ParenTypeLoc
1159 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1160 ParenLocInfo> {
1161public:
1162 SourceLocation getLParenLoc() const {
1163 return this->getLocalData()->LParenLoc;
1164 }
1165
1166 SourceLocation getRParenLoc() const {
1167 return this->getLocalData()->RParenLoc;
1168 }
1169
1170 void setLParenLoc(SourceLocation Loc) {
1171 this->getLocalData()->LParenLoc = Loc;
1172 }
1173
1174 void setRParenLoc(SourceLocation Loc) {
1175 this->getLocalData()->RParenLoc = Loc;
1176 }
1177
1178 SourceRange getLocalSourceRange() const {
1179 return SourceRange(getLParenLoc(), getRParenLoc());
1180 }
1181
1182 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1183 setLParenLoc(Loc);
1184 setRParenLoc(Loc);
1185 }
1186
1187 TypeLoc getInnerLoc() const {
1188 return getInnerTypeLoc();
1189 }
1190
1191 QualType getInnerType() const {
1192 return this->getTypePtr()->getInnerType();
1193 }
1194};
1195
1196inline TypeLoc TypeLoc::IgnoreParens() const {
1197 if (ParenTypeLoc::isKind(*this))
4
Taking true branch
1198 return IgnoreParensImpl(*this);
5
Calling 'TypeLoc::IgnoreParensImpl'
1199 return *this;
1200}
1201
1202struct AdjustedLocInfo {}; // Nothing.
1203
1204class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1205 AdjustedType, AdjustedLocInfo> {
1206public:
1207 TypeLoc getOriginalLoc() const {
1208 return getInnerTypeLoc();
1209 }
1210
1211 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1212 // do nothing
1213 }
1214
1215 QualType getInnerType() const {
1216 // The inner type is the undecayed type, since that's what we have source
1217 // location information for.
1218 return getTypePtr()->getOriginalType();
1219 }
1220
1221 SourceRange getLocalSourceRange() const { return {}; }
1222
1223 unsigned getLocalDataSize() const {
1224 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1225 // anyway. TypeLocBuilder can't handle data sizes of 1.
1226 return 0; // No data.
1227 }
1228};
1229
1230/// \brief Wrapper for source info for pointers decayed from arrays and
1231/// functions.
1232class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1233 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1234};
1235
1236struct PointerLikeLocInfo {
1237 SourceLocation StarLoc;
1238};
1239
1240/// A base class for
1241template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1242class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1243 TypeClass, LocalData> {
1244public:
1245 SourceLocation getSigilLoc() const {
1246 return this->getLocalData()->StarLoc;
1247 }
1248
1249 void setSigilLoc(SourceLocation Loc) {
1250 this->getLocalData()->StarLoc = Loc;
1251 }
1252
1253 TypeLoc getPointeeLoc() const {
1254 return this->getInnerTypeLoc();
1255 }
1256
1257 SourceRange getLocalSourceRange() const {
1258 return SourceRange(getSigilLoc(), getSigilLoc());
1259 }
1260
1261 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1262 setSigilLoc(Loc);
1263 }
1264
1265 QualType getInnerType() const {
1266 return this->getTypePtr()->getPointeeType();
1267 }
1268};
1269
1270/// \brief Wrapper for source info for pointers.
1271class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1272 PointerType> {
1273public:
1274 SourceLocation getStarLoc() const {
1275 return getSigilLoc();
1276 }
1277
1278 void setStarLoc(SourceLocation Loc) {
1279 setSigilLoc(Loc);
1280 }
1281};
1282
1283/// \brief Wrapper for source info for block pointers.
1284class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1285 BlockPointerType> {
1286public:
1287 SourceLocation getCaretLoc() const {
1288 return getSigilLoc();
1289 }
1290
1291 void setCaretLoc(SourceLocation Loc) {
1292 setSigilLoc(Loc);
1293 }
1294};
1295
1296struct MemberPointerLocInfo : public PointerLikeLocInfo {
1297 TypeSourceInfo *ClassTInfo;
1298};
1299
1300/// \brief Wrapper for source info for member pointers.
1301class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1302 MemberPointerType,
1303 MemberPointerLocInfo> {
1304public:
1305 SourceLocation getStarLoc() const {
1306 return getSigilLoc();
1307 }
1308
1309 void setStarLoc(SourceLocation Loc) {
1310 setSigilLoc(Loc);
1311 }
1312
1313 const Type *getClass() const {
1314 return getTypePtr()->getClass();
1315 }
1316
1317 TypeSourceInfo *getClassTInfo() const {
1318 return getLocalData()->ClassTInfo;
1319 }
1320
1321 void setClassTInfo(TypeSourceInfo* TI) {
1322 getLocalData()->ClassTInfo = TI;
1323 }
1324
1325 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1326 setSigilLoc(Loc);
1327 setClassTInfo(nullptr);
1328 }
1329
1330 SourceRange getLocalSourceRange() const {
1331 if (TypeSourceInfo *TI = getClassTInfo())
1332 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1333 else
1334 return SourceRange(getStarLoc());
1335 }
1336};
1337
1338/// Wraps an ObjCPointerType with source location information.
1339class ObjCObjectPointerTypeLoc :
1340 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1341 ObjCObjectPointerType> {
1342public:
1343 SourceLocation getStarLoc() const {
1344 return getSigilLoc();
1345 }
1346
1347 void setStarLoc(SourceLocation Loc) {
1348 setSigilLoc(Loc);
1349 }
1350};
1351
1352class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1353 ReferenceType> {
1354public:
1355 QualType getInnerType() const {
1356 return getTypePtr()->getPointeeTypeAsWritten();
1357 }
1358};
1359
1360class LValueReferenceTypeLoc :
1361 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1362 LValueReferenceTypeLoc,
1363 LValueReferenceType> {
1364public:
1365 SourceLocation getAmpLoc() const {
1366 return getSigilLoc();
1367 }
1368
1369 void setAmpLoc(SourceLocation Loc) {
1370 setSigilLoc(Loc);
1371 }
1372};
1373
1374class RValueReferenceTypeLoc :
1375 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1376 RValueReferenceTypeLoc,
1377 RValueReferenceType> {
1378public:
1379 SourceLocation getAmpAmpLoc() const {
1380 return getSigilLoc();
1381 }
1382
1383 void setAmpAmpLoc(SourceLocation Loc) {
1384 setSigilLoc(Loc);
1385 }
1386};
1387
1388struct FunctionLocInfo {
1389 SourceLocation LocalRangeBegin;
1390 SourceLocation LParenLoc;
1391 SourceLocation RParenLoc;
1392 SourceLocation LocalRangeEnd;
1393};
1394
1395/// \brief Wrapper for source info for functions.
1396class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1397 FunctionTypeLoc,
1398 FunctionType,
1399 FunctionLocInfo> {
1400 bool hasExceptionSpec() const {
1401 if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1402 return FPT->hasExceptionSpec();
1403 }
1404 return false;
1405 }
1406
1407 SourceRange *getExceptionSpecRangePtr() const {
1408 assert(hasExceptionSpec() && "No exception spec range")(static_cast <bool> (hasExceptionSpec() && "No exception spec range"
) ? void (0) : __assert_fail ("hasExceptionSpec() && \"No exception spec range\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 1408, __extension__ __PRETTY_FUNCTION__))
;
1409 // After the Info comes the ParmVarDecl array, and after that comes the
1410 // exception specification information.
1411 return (SourceRange *)(getParmArray() + getNumParams());
1412 }
1413
1414public:
1415 SourceLocation getLocalRangeBegin() const {
1416 return getLocalData()->LocalRangeBegin;
1417 }
1418
1419 void setLocalRangeBegin(SourceLocation L) {
1420 getLocalData()->LocalRangeBegin = L;
1421 }
1422
1423 SourceLocation getLocalRangeEnd() const {
1424 return getLocalData()->LocalRangeEnd;
1425 }
1426
1427 void setLocalRangeEnd(SourceLocation L) {
1428 getLocalData()->LocalRangeEnd = L;
1429 }
1430
1431 SourceLocation getLParenLoc() const {
1432 return this->getLocalData()->LParenLoc;
1433 }
1434
1435 void setLParenLoc(SourceLocation Loc) {
1436 this->getLocalData()->LParenLoc = Loc;
1437 }
1438
1439 SourceLocation getRParenLoc() const {
1440 return this->getLocalData()->RParenLoc;
1441 }
1442
1443 void setRParenLoc(SourceLocation Loc) {
1444 this->getLocalData()->RParenLoc = Loc;
1445 }
1446
1447 SourceRange getParensRange() const {
1448 return SourceRange(getLParenLoc(), getRParenLoc());
1449 }
1450
1451 SourceRange getExceptionSpecRange() const {
1452 if (hasExceptionSpec())
1453 return *getExceptionSpecRangePtr();
1454 return {};
1455 }
1456
1457 void setExceptionSpecRange(SourceRange R) {
1458 if (hasExceptionSpec())
1459 *getExceptionSpecRangePtr() = R;
1460 }
1461
1462 ArrayRef<ParmVarDecl *> getParams() const {
1463 return llvm::makeArrayRef(getParmArray(), getNumParams());
1464 }
1465
1466 // ParmVarDecls* are stored after Info, one for each parameter.
1467 ParmVarDecl **getParmArray() const {
1468 return (ParmVarDecl**) getExtraLocalData();
1469 }
1470
1471 unsigned getNumParams() const {
1472 if (isa<FunctionNoProtoType>(getTypePtr()))
1473 return 0;
1474 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1475 }
1476
1477 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1478 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1479
1480 TypeLoc getReturnLoc() const {
1481 return getInnerTypeLoc();
1482 }
1483
1484 SourceRange getLocalSourceRange() const {
1485 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1486 }
1487
1488 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1489 setLocalRangeBegin(Loc);
1490 setLParenLoc(Loc);
1491 setRParenLoc(Loc);
1492 setLocalRangeEnd(Loc);
1493 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1494 setParam(i, nullptr);
1495 if (hasExceptionSpec())
1496 setExceptionSpecRange(Loc);
1497 }
1498
1499 /// \brief Returns the size of the type source info data block that is
1500 /// specific to this type.
1501 unsigned getExtraLocalDataSize() const {
1502 unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1503 return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1504 }
1505
1506 unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1507
1508 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1509};
1510
1511class FunctionProtoTypeLoc :
1512 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1513 FunctionProtoTypeLoc,
1514 FunctionProtoType> {
1515};
1516
1517class FunctionNoProtoTypeLoc :
1518 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1519 FunctionNoProtoTypeLoc,
1520 FunctionNoProtoType> {
1521};
1522
1523struct ArrayLocInfo {
1524 SourceLocation LBracketLoc, RBracketLoc;
1525 Expr *Size;
1526};
1527
1528/// \brief Wrapper for source info for arrays.
1529class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1530 ArrayTypeLoc,
1531 ArrayType,
1532 ArrayLocInfo> {
1533public:
1534 SourceLocation getLBracketLoc() const {
1535 return getLocalData()->LBracketLoc;
1536 }
1537
1538 void setLBracketLoc(SourceLocation Loc) {
1539 getLocalData()->LBracketLoc = Loc;
1540 }
1541
1542 SourceLocation getRBracketLoc() const {
1543 return getLocalData()->RBracketLoc;
1544 }
1545
1546 void setRBracketLoc(SourceLocation Loc) {
1547 getLocalData()->RBracketLoc = Loc;
1548 }
1549
1550 SourceRange getBracketsRange() const {
1551 return SourceRange(getLBracketLoc(), getRBracketLoc());
1552 }
1553
1554 Expr *getSizeExpr() const {
1555 return getLocalData()->Size;
1556 }
1557
1558 void setSizeExpr(Expr *Size) {
1559 getLocalData()->Size = Size;
1560 }
1561
1562 TypeLoc getElementLoc() const {
1563 return getInnerTypeLoc();
1564 }
1565
1566 SourceRange getLocalSourceRange() const {
1567 return SourceRange(getLBracketLoc(), getRBracketLoc());
1568 }
1569
1570 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1571 setLBracketLoc(Loc);
1572 setRBracketLoc(Loc);
1573 setSizeExpr(nullptr);
1574 }
1575
1576 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1577};
1578
1579class ConstantArrayTypeLoc :
1580 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1581 ConstantArrayTypeLoc,
1582 ConstantArrayType> {
1583};
1584
1585class IncompleteArrayTypeLoc :
1586 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1587 IncompleteArrayTypeLoc,
1588 IncompleteArrayType> {
1589};
1590
1591class DependentSizedArrayTypeLoc :
1592 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1593 DependentSizedArrayTypeLoc,
1594 DependentSizedArrayType> {
1595public:
1596 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1597 ArrayTypeLoc::initializeLocal(Context, Loc);
1598 setSizeExpr(getTypePtr()->getSizeExpr());
1599 }
1600};
1601
1602class VariableArrayTypeLoc :
1603 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1604 VariableArrayTypeLoc,
1605 VariableArrayType> {
1606};
1607
1608// Location information for a TemplateName. Rudimentary for now.
1609struct TemplateNameLocInfo {
1610 SourceLocation NameLoc;
1611};
1612
1613struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1614 SourceLocation TemplateKWLoc;
1615 SourceLocation LAngleLoc;
1616 SourceLocation RAngleLoc;
1617};
1618
1619class TemplateSpecializationTypeLoc :
1620 public ConcreteTypeLoc<UnqualTypeLoc,
1621 TemplateSpecializationTypeLoc,
1622 TemplateSpecializationType,
1623 TemplateSpecializationLocInfo> {
1624public:
1625 SourceLocation getTemplateKeywordLoc() const {
1626 return getLocalData()->TemplateKWLoc;
1627 }
1628
1629 void setTemplateKeywordLoc(SourceLocation Loc) {
1630 getLocalData()->TemplateKWLoc = Loc;
1631 }
1632
1633 SourceLocation getLAngleLoc() const {
1634 return getLocalData()->LAngleLoc;
1635 }
1636
1637 void setLAngleLoc(SourceLocation Loc) {
1638 getLocalData()->LAngleLoc = Loc;
1639 }
1640
1641 SourceLocation getRAngleLoc() const {
1642 return getLocalData()->RAngleLoc;
1643 }
1644
1645 void setRAngleLoc(SourceLocation Loc) {
1646 getLocalData()->RAngleLoc = Loc;
1647 }
1648
1649 unsigned getNumArgs() const {
1650 return getTypePtr()->getNumArgs();
1651 }
1652
1653 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1654 getArgInfos()[i] = AI;
1655 }
1656
1657 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1658 return getArgInfos()[i];
1659 }
1660
1661 TemplateArgumentLoc getArgLoc(unsigned i) const {
1662 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1663 }
1664
1665 SourceLocation getTemplateNameLoc() const {
1666 return getLocalData()->NameLoc;
1667 }
1668
1669 void setTemplateNameLoc(SourceLocation Loc) {
1670 getLocalData()->NameLoc = Loc;
1671 }
1672
1673 /// \brief - Copy the location information from the given info.
1674 void copy(TemplateSpecializationTypeLoc Loc) {
1675 unsigned size = getFullDataSize();
1676 assert(size == Loc.getFullDataSize())(static_cast <bool> (size == Loc.getFullDataSize()) ? void
(0) : __assert_fail ("size == Loc.getFullDataSize()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 1676, __extension__ __PRETTY_FUNCTION__))
;
1677
1678 // We're potentially copying Expr references here. We don't
1679 // bother retaining them because TypeSourceInfos live forever, so
1680 // as long as the Expr was retained when originally written into
1681 // the TypeLoc, we're okay.
1682 memcpy(Data, Loc.Data, size);
1683 }
1684
1685 SourceRange getLocalSourceRange() const {
1686 if (getTemplateKeywordLoc().isValid())
1687 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1688 else
1689 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1690 }
1691
1692 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1693 setTemplateKeywordLoc(Loc);
1694 setTemplateNameLoc(Loc);
1695 setLAngleLoc(Loc);
1696 setRAngleLoc(Loc);
1697 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1698 getArgInfos(), Loc);
1699 }
1700
1701 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1702 const TemplateArgument *Args,
1703 TemplateArgumentLocInfo *ArgInfos,
1704 SourceLocation Loc);
1705
1706 unsigned getExtraLocalDataSize() const {
1707 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1708 }
1709
1710 unsigned getExtraLocalDataAlignment() const {
1711 return alignof(TemplateArgumentLocInfo);
1712 }
1713
1714private:
1715 TemplateArgumentLocInfo *getArgInfos() const {
1716 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1717 }
1718};
1719
1720struct DependentAddressSpaceLocInfo {
1721 Expr *ExprOperand;
1722 SourceRange OperandParens;
1723 SourceLocation AttrLoc;
1724};
1725
1726class DependentAddressSpaceTypeLoc
1727 : public ConcreteTypeLoc<UnqualTypeLoc,
1728 DependentAddressSpaceTypeLoc,
1729 DependentAddressSpaceType,
1730 DependentAddressSpaceLocInfo> {
1731public:
1732 /// The location of the attribute name, i.e.
1733 /// int * __attribute__((address_space(11)))
1734 /// ^~~~~~~~~~~~~
1735 SourceLocation getAttrNameLoc() const {
1736 return getLocalData()->AttrLoc;
1737 }
1738 void setAttrNameLoc(SourceLocation loc) {
1739 getLocalData()->AttrLoc = loc;
1740 }
1741
1742 /// The attribute's expression operand, if it has one.
1743 /// int * __attribute__((address_space(11)))
1744 /// ^~
1745 Expr *getAttrExprOperand() const {
1746 return getLocalData()->ExprOperand;
1747 }
1748 void setAttrExprOperand(Expr *e) {
1749 getLocalData()->ExprOperand = e;
1750 }
1751
1752 /// The location of the parentheses around the operand, if there is
1753 /// an operand.
1754 /// int * __attribute__((address_space(11)))
1755 /// ^ ^
1756 SourceRange getAttrOperandParensRange() const {
1757 return getLocalData()->OperandParens;
1758 }
1759 void setAttrOperandParensRange(SourceRange range) {
1760 getLocalData()->OperandParens = range;
1761 }
1762
1763 SourceRange getLocalSourceRange() const {
1764 SourceRange range(getAttrNameLoc());
1765 range.setEnd(getAttrOperandParensRange().getEnd());
1766 return range;
1767 }
1768
1769 /// Returns the type before the address space attribute application
1770 /// area.
1771 /// int * __attribute__((address_space(11))) *
1772 /// ^ ^
1773 QualType getInnerType() const {
1774 return this->getTypePtr()->getPointeeType();
1775 }
1776
1777 TypeLoc getPointeeTypeLoc() const {
1778 return this->getInnerTypeLoc();
1779 }
1780
1781 void initializeLocal(ASTContext &Context, SourceLocation loc) {
1782 setAttrNameLoc(loc);
1783 setAttrOperandParensRange(SourceRange(loc));
1784 setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1785 }
1786};
1787
1788//===----------------------------------------------------------------------===//
1789//
1790// All of these need proper implementations.
1791//
1792//===----------------------------------------------------------------------===//
1793
1794// FIXME: size expression and attribute locations (or keyword if we
1795// ever fully support altivec syntax).
1796class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1797 VectorTypeLoc,
1798 VectorType> {
1799};
1800
1801// FIXME: size expression and attribute locations.
1802class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1803 ExtVectorTypeLoc,
1804 ExtVectorType> {
1805};
1806
1807// FIXME: attribute locations.
1808// For some reason, this isn't a subtype of VectorType.
1809class DependentSizedExtVectorTypeLoc :
1810 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1811 DependentSizedExtVectorTypeLoc,
1812 DependentSizedExtVectorType> {
1813};
1814
1815// FIXME: location of the '_Complex' keyword.
1816class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1817 ComplexTypeLoc,
1818 ComplexType> {
1819};
1820
1821struct TypeofLocInfo {
1822 SourceLocation TypeofLoc;
1823 SourceLocation LParenLoc;
1824 SourceLocation RParenLoc;
1825};
1826
1827struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1828};
1829
1830struct TypeOfTypeLocInfo : public TypeofLocInfo {
1831 TypeSourceInfo* UnderlyingTInfo;
1832};
1833
1834template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1835class TypeofLikeTypeLoc
1836 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1837public:
1838 SourceLocation getTypeofLoc() const {
1839 return this->getLocalData()->TypeofLoc;
1840 }
1841
1842 void setTypeofLoc(SourceLocation Loc) {
1843 this->getLocalData()->TypeofLoc = Loc;
1844 }
1845
1846 SourceLocation getLParenLoc() const {
1847 return this->getLocalData()->LParenLoc;
1848 }
1849
1850 void setLParenLoc(SourceLocation Loc) {
1851 this->getLocalData()->LParenLoc = Loc;
1852 }
1853
1854 SourceLocation getRParenLoc() const {
1855 return this->getLocalData()->RParenLoc;
1856 }
1857
1858 void setRParenLoc(SourceLocation Loc) {
1859 this->getLocalData()->RParenLoc = Loc;
1860 }
1861
1862 SourceRange getParensRange() const {
1863 return SourceRange(getLParenLoc(), getRParenLoc());
1864 }
1865
1866 void setParensRange(SourceRange range) {
1867 setLParenLoc(range.getBegin());
1868 setRParenLoc(range.getEnd());
1869 }
1870
1871 SourceRange getLocalSourceRange() const {
1872 return SourceRange(getTypeofLoc(), getRParenLoc());
1873 }
1874
1875 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1876 setTypeofLoc(Loc);
1877 setLParenLoc(Loc);
1878 setRParenLoc(Loc);
1879 }
1880};
1881
1882class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1883 TypeOfExprType,
1884 TypeOfExprTypeLocInfo> {
1885public:
1886 Expr* getUnderlyingExpr() const {
1887 return getTypePtr()->getUnderlyingExpr();
1888 }
1889
1890 // Reimplemented to account for GNU/C++ extension
1891 // typeof unary-expression
1892 // where there are no parentheses.
1893 SourceRange getLocalSourceRange() const;
1894};
1895
1896class TypeOfTypeLoc
1897 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1898public:
1899 QualType getUnderlyingType() const {
1900 return this->getTypePtr()->getUnderlyingType();
1901 }
1902
1903 TypeSourceInfo* getUnderlyingTInfo() const {
1904 return this->getLocalData()->UnderlyingTInfo;
1905 }
1906
1907 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1908 this->getLocalData()->UnderlyingTInfo = TI;
1909 }
1910
1911 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1912};
1913
1914// FIXME: location of the 'decltype' and parens.
1915class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1916 DecltypeTypeLoc,
1917 DecltypeType> {
1918public:
1919 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1920};
1921
1922struct UnaryTransformTypeLocInfo {
1923 // FIXME: While there's only one unary transform right now, future ones may
1924 // need different representations
1925 SourceLocation KWLoc, LParenLoc, RParenLoc;
1926 TypeSourceInfo *UnderlyingTInfo;
1927};
1928
1929class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1930 UnaryTransformTypeLoc,
1931 UnaryTransformType,
1932 UnaryTransformTypeLocInfo> {
1933public:
1934 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1935 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1936
1937 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1938 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1939
1940 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1941 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1942
1943 TypeSourceInfo* getUnderlyingTInfo() const {
1944 return getLocalData()->UnderlyingTInfo;
1945 }
1946
1947 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1948 getLocalData()->UnderlyingTInfo = TInfo;
1949 }
1950
1951 SourceRange getLocalSourceRange() const {
1952 return SourceRange(getKWLoc(), getRParenLoc());
1953 }
1954
1955 SourceRange getParensRange() const {
1956 return SourceRange(getLParenLoc(), getRParenLoc());
1957 }
1958
1959 void setParensRange(SourceRange Range) {
1960 setLParenLoc(Range.getBegin());
1961 setRParenLoc(Range.getEnd());
1962 }
1963
1964 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1965};
1966
1967class DeducedTypeLoc
1968 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
1969 DeducedType> {};
1970
1971class AutoTypeLoc
1972 : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
1973};
1974
1975class DeducedTemplateSpecializationTypeLoc
1976 : public InheritingConcreteTypeLoc<DeducedTypeLoc,
1977 DeducedTemplateSpecializationTypeLoc,
1978 DeducedTemplateSpecializationType> {
1979public:
1980 SourceLocation getTemplateNameLoc() const {
1981 return getNameLoc();
1982 }
1983
1984 void setTemplateNameLoc(SourceLocation Loc) {
1985 setNameLoc(Loc);
1986 }
1987};
1988
1989struct ElaboratedLocInfo {
1990 SourceLocation ElaboratedKWLoc;
1991
1992 /// \brief Data associated with the nested-name-specifier location.
1993 void *QualifierData;
1994};
1995
1996class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1997 ElaboratedTypeLoc,
1998 ElaboratedType,
1999 ElaboratedLocInfo> {
2000public:
2001 SourceLocation getElaboratedKeywordLoc() const {
2002 return this->getLocalData()->ElaboratedKWLoc;
2003 }
2004
2005 void setElaboratedKeywordLoc(SourceLocation Loc) {
2006 this->getLocalData()->ElaboratedKWLoc = Loc;
2007 }
2008
2009 NestedNameSpecifierLoc getQualifierLoc() const {
2010 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2011 getLocalData()->QualifierData);
2012 }
2013
2014 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2015 assert(QualifierLoc.getNestedNameSpecifier()(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2017, __extension__ __PRETTY_FUNCTION__))
2016 == getTypePtr()->getQualifier() &&(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2017, __extension__ __PRETTY_FUNCTION__))
2017 "Inconsistent nested-name-specifier pointer")(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2017, __extension__ __PRETTY_FUNCTION__))
;
2018 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2019 }
2020
2021 SourceRange getLocalSourceRange() const {
2022 if (getElaboratedKeywordLoc().isValid())
2023 if (getQualifierLoc())
2024 return SourceRange(getElaboratedKeywordLoc(),
2025 getQualifierLoc().getEndLoc());
2026 else
2027 return SourceRange(getElaboratedKeywordLoc());
2028 else
2029 return getQualifierLoc().getSourceRange();
2030 }
2031
2032 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2033
2034 TypeLoc getNamedTypeLoc() const {
2035 return getInnerTypeLoc();
2036 }
2037
2038 QualType getInnerType() const {
2039 return getTypePtr()->getNamedType();
2040 }
2041
2042 void copy(ElaboratedTypeLoc Loc) {
2043 unsigned size = getFullDataSize();
2044 assert(size == Loc.getFullDataSize())(static_cast <bool> (size == Loc.getFullDataSize()) ? void
(0) : __assert_fail ("size == Loc.getFullDataSize()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2044, __extension__ __PRETTY_FUNCTION__))
;
2045 memcpy(Data, Loc.Data, size);
2046 }
2047};
2048
2049// This is exactly the structure of an ElaboratedTypeLoc whose inner
2050// type is some sort of TypeDeclTypeLoc.
2051struct DependentNameLocInfo : ElaboratedLocInfo {
2052 SourceLocation NameLoc;
2053};
2054
2055class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2056 DependentNameTypeLoc,
2057 DependentNameType,
2058 DependentNameLocInfo> {
2059public:
2060 SourceLocation getElaboratedKeywordLoc() const {
2061 return this->getLocalData()->ElaboratedKWLoc;
2062 }
2063
2064 void setElaboratedKeywordLoc(SourceLocation Loc) {
2065 this->getLocalData()->ElaboratedKWLoc = Loc;
2066 }
2067
2068 NestedNameSpecifierLoc getQualifierLoc() const {
2069 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2070 getLocalData()->QualifierData);
2071 }
2072
2073 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2074 assert(QualifierLoc.getNestedNameSpecifier()(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2076, __extension__ __PRETTY_FUNCTION__))
2075 == getTypePtr()->getQualifier() &&(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2076, __extension__ __PRETTY_FUNCTION__))
2076 "Inconsistent nested-name-specifier pointer")(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2076, __extension__ __PRETTY_FUNCTION__))
;
2077 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2078 }
2079
2080 SourceLocation getNameLoc() const {
2081 return this->getLocalData()->NameLoc;
2082 }
2083
2084 void setNameLoc(SourceLocation Loc) {
2085 this->getLocalData()->NameLoc = Loc;
2086 }
2087
2088 SourceRange getLocalSourceRange() const {
2089 if (getElaboratedKeywordLoc().isValid())
2090 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
2091 else
2092 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
2093 }
2094
2095 void copy(DependentNameTypeLoc Loc) {
2096 unsigned size = getFullDataSize();
2097 assert(size == Loc.getFullDataSize())(static_cast <bool> (size == Loc.getFullDataSize()) ? void
(0) : __assert_fail ("size == Loc.getFullDataSize()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2097, __extension__ __PRETTY_FUNCTION__))
;
2098 memcpy(Data, Loc.Data, size);
2099 }
2100
2101 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2102};
2103
2104struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
2105 SourceLocation TemplateKWLoc;
2106 SourceLocation LAngleLoc;
2107 SourceLocation RAngleLoc;
2108 // followed by a TemplateArgumentLocInfo[]
2109};
2110
2111class DependentTemplateSpecializationTypeLoc :
2112 public ConcreteTypeLoc<UnqualTypeLoc,
2113 DependentTemplateSpecializationTypeLoc,
2114 DependentTemplateSpecializationType,
2115 DependentTemplateSpecializationLocInfo> {
2116public:
2117 SourceLocation getElaboratedKeywordLoc() const {
2118 return this->getLocalData()->ElaboratedKWLoc;
2119 }
2120
2121 void setElaboratedKeywordLoc(SourceLocation Loc) {
2122 this->getLocalData()->ElaboratedKWLoc = Loc;
2123 }
2124
2125 NestedNameSpecifierLoc getQualifierLoc() const {
2126 if (!getLocalData()->QualifierData)
2127 return NestedNameSpecifierLoc();
2128
2129 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2130 getLocalData()->QualifierData);
2131 }
2132
2133 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2134 if (!QualifierLoc) {
2135 // Even if we have a nested-name-specifier in the dependent
2136 // template specialization type, we won't record the nested-name-specifier
2137 // location information when this type-source location information is
2138 // part of a nested-name-specifier.
2139 getLocalData()->QualifierData = nullptr;
2140 return;
2141 }
2142
2143 assert(QualifierLoc.getNestedNameSpecifier()(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2145, __extension__ __PRETTY_FUNCTION__))
2144 == getTypePtr()->getQualifier() &&(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2145, __extension__ __PRETTY_FUNCTION__))
2145 "Inconsistent nested-name-specifier pointer")(static_cast <bool> (QualifierLoc.getNestedNameSpecifier
() == getTypePtr()->getQualifier() && "Inconsistent nested-name-specifier pointer"
) ? void (0) : __assert_fail ("QualifierLoc.getNestedNameSpecifier() == getTypePtr()->getQualifier() && \"Inconsistent nested-name-specifier pointer\""
, "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2145, __extension__ __PRETTY_FUNCTION__))
;
2146 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2147 }
2148
2149 SourceLocation getTemplateKeywordLoc() const {
2150 return getLocalData()->TemplateKWLoc;
2151 }
2152
2153 void setTemplateKeywordLoc(SourceLocation Loc) {
2154 getLocalData()->TemplateKWLoc = Loc;
2155 }
2156
2157 SourceLocation getTemplateNameLoc() const {
2158 return this->getLocalData()->NameLoc;
2159 }
2160
2161 void setTemplateNameLoc(SourceLocation Loc) {
2162 this->getLocalData()->NameLoc = Loc;
2163 }
2164
2165 SourceLocation getLAngleLoc() const {
2166 return this->getLocalData()->LAngleLoc;
2167 }
2168
2169 void setLAngleLoc(SourceLocation Loc) {
2170 this->getLocalData()->LAngleLoc = Loc;
2171 }
2172
2173 SourceLocation getRAngleLoc() const {
2174 return this->getLocalData()->RAngleLoc;
2175 }
2176
2177 void setRAngleLoc(SourceLocation Loc) {
2178 this->getLocalData()->RAngleLoc = Loc;
2179 }
2180
2181 unsigned getNumArgs() const {
2182 return getTypePtr()->getNumArgs();
2183 }
2184
2185 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2186 getArgInfos()[i] = AI;
2187 }
2188
2189 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2190 return getArgInfos()[i];
2191 }
2192
2193 TemplateArgumentLoc getArgLoc(unsigned i) const {
2194 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2195 }
2196
2197 SourceRange getLocalSourceRange() const {
2198 if (getElaboratedKeywordLoc().isValid())
2199 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2200 else if (getQualifierLoc())
2201 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2202 else if (getTemplateKeywordLoc().isValid())
2203 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2204 else
2205 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2206 }
2207
2208 void copy(DependentTemplateSpecializationTypeLoc Loc) {
2209 unsigned size = getFullDataSize();
2210 assert(size == Loc.getFullDataSize())(static_cast <bool> (size == Loc.getFullDataSize()) ? void
(0) : __assert_fail ("size == Loc.getFullDataSize()", "/build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include/clang/AST/TypeLoc.h"
, 2210, __extension__ __PRETTY_FUNCTION__))
;
2211 memcpy(Data, Loc.Data, size);
2212 }
2213
2214 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2215
2216 unsigned getExtraLocalDataSize() const {
2217 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2218 }
2219
2220 unsigned getExtraLocalDataAlignment() const {
2221 return alignof(TemplateArgumentLocInfo);
2222 }
2223
2224private:
2225 TemplateArgumentLocInfo *getArgInfos() const {
2226 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2227 }
2228};
2229
2230struct PackExpansionTypeLocInfo {
2231 SourceLocation EllipsisLoc;
2232};
2233
2234class PackExpansionTypeLoc
2235 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2236 PackExpansionType, PackExpansionTypeLocInfo> {
2237public:
2238 SourceLocation getEllipsisLoc() const {
2239 return this->getLocalData()->EllipsisLoc;
2240 }
2241
2242 void setEllipsisLoc(SourceLocation Loc) {
2243 this->getLocalData()->EllipsisLoc = Loc;
2244 }
2245
2246 SourceRange getLocalSourceRange() const {
2247 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2248 }
2249
2250 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2251 setEllipsisLoc(Loc);
2252 }
2253
2254 TypeLoc getPatternLoc() const {
2255 return getInnerTypeLoc();
2256 }
2257
2258 QualType getInnerType() const {
2259 return this->getTypePtr()->getPattern();
2260 }
2261};
2262
2263struct AtomicTypeLocInfo {
2264 SourceLocation KWLoc, LParenLoc, RParenLoc;
2265};
2266
2267class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2268 AtomicType, AtomicTypeLocInfo> {
2269public:
2270 TypeLoc getValueLoc() const {
2271 return this->getInnerTypeLoc();
2272 }
2273
2274 SourceRange getLocalSourceRange() const {
2275 return SourceRange(getKWLoc(), getRParenLoc());
2276 }
2277
2278 SourceLocation getKWLoc() const {
2279 return this->getLocalData()->KWLoc;
2280 }
2281
2282 void setKWLoc(SourceLocation Loc) {
2283 this->getLocalData()->KWLoc = Loc;
2284 }
2285
2286 SourceLocation getLParenLoc() const {
2287 return this->getLocalData()->LParenLoc;
2288 }
2289
2290 void setLParenLoc(SourceLocation Loc) {
2291 this->getLocalData()->LParenLoc = Loc;
2292 }
2293
2294 SourceLocation getRParenLoc() const {
2295 return this->getLocalData()->RParenLoc;
2296 }
2297
2298 void setRParenLoc(SourceLocation Loc) {
2299 this->getLocalData()->RParenLoc = Loc;
2300 }
2301
2302 SourceRange getParensRange() const {
2303 return SourceRange(getLParenLoc(), getRParenLoc());
2304 }
2305
2306 void setParensRange(SourceRange Range) {
2307 setLParenLoc(Range.getBegin());
2308 setRParenLoc(Range.getEnd());
2309 }
2310
2311 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2312 setKWLoc(Loc);
2313 setLParenLoc(Loc);
2314 setRParenLoc(Loc);
2315 }
2316
2317 QualType getInnerType() const {
2318 return this->getTypePtr()->getValueType();
2319 }
2320};
2321
2322struct PipeTypeLocInfo {
2323 SourceLocation KWLoc;
2324};
2325
2326class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2327 PipeTypeLocInfo> {
2328public:
2329 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2330
2331 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2332
2333 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2334 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2335
2336 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2337 setKWLoc(Loc);
2338 }
2339
2340 QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2341};
2342
2343template <typename T>
2344inline T TypeLoc::getAsAdjusted() const {
2345 TypeLoc Cur = *this;
2346 while (!T::isKind(Cur)) {
2347 if (auto PTL = Cur.getAs<ParenTypeLoc>())
2348 Cur = PTL.getInnerLoc();
2349 else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2350 Cur = ATL.getModifiedLoc();
2351 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2352 Cur = ETL.getNamedTypeLoc();
2353 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2354 Cur = ATL.getOriginalLoc();
2355 else
2356 break;
2357 }
2358 return Cur.getAs<T>();
2359}
2360
2361} // namespace clang
2362
2363#endif // LLVM_CLANG_AST_TYPELOC_H