clang  9.0.0svn
TypeLocBuilder.h
Go to the documentation of this file.
1 //===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines TypeLocBuilder, a class for building TypeLocs
10 // bottom-up.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H
15 #define LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H
16 
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/TypeLoc.h"
19 
20 namespace clang {
21 
23  enum { InlineCapacity = 8 * sizeof(SourceLocation) };
24 
25  /// The underlying location-data buffer. Data grows from the end
26  /// of the buffer backwards.
27  char *Buffer;
28 
29  /// The capacity of the current buffer.
30  size_t Capacity;
31 
32  /// The index of the first occupied byte in the buffer.
33  size_t Index;
34 
35 #ifndef NDEBUG
36  /// The last type pushed on this builder.
37  QualType LastTy;
38 #endif
39 
40  /// The inline buffer.
41  enum { BufferMaxAlignment = alignof(void *) };
42  llvm::AlignedCharArray<BufferMaxAlignment, InlineCapacity> InlineBuffer;
43  unsigned NumBytesAtAlign4, NumBytesAtAlign8;
44 
45  public:
47  : Buffer(InlineBuffer.buffer), Capacity(InlineCapacity),
48  Index(InlineCapacity), NumBytesAtAlign4(0), NumBytesAtAlign8(0)
49  {
50  }
51 
53  if (Buffer != InlineBuffer.buffer)
54  delete[] Buffer;
55  }
56 
57  /// Ensures that this buffer has at least as much capacity as described.
58  void reserve(size_t Requested) {
59  if (Requested > Capacity)
60  // For now, match the request exactly.
61  grow(Requested);
62  }
63 
64  /// Pushes a copy of the given TypeLoc onto this builder. The builder
65  /// must be empty for this to work.
66  void pushFullCopy(TypeLoc L);
67 
68  /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs
69  /// previously retrieved from this builder.
71  size_t LocalSize = TypeSpecTypeLoc::LocalDataSize;
72  unsigned LocalAlign = TypeSpecTypeLoc::LocalDataAlignment;
73  return pushImpl(T, LocalSize, LocalAlign).castAs<TypeSpecTypeLoc>();
74  }
75 
76  /// Resets this builder to the newly-initialized state.
77  void clear() {
78 #ifndef NDEBUG
79  LastTy = QualType();
80 #endif
81  Index = Capacity;
82  NumBytesAtAlign4 = NumBytesAtAlign8 = 0;
83  }
84 
85  /// Tell the TypeLocBuilder that the type it is storing has been
86  /// modified in some safe way that doesn't affect type-location information.
88 #ifndef NDEBUG
89  LastTy = T;
90 #endif
91  }
92 
93  /// Pushes space for a new TypeLoc of the given type. Invalidates
94  /// any TypeLocs previously retrieved from this builder.
95  template <class TyLocType> TyLocType push(QualType T) {
96  TyLocType Loc = TypeLoc(T, nullptr).castAs<TyLocType>();
97  size_t LocalSize = Loc.getLocalDataSize();
98  unsigned LocalAlign = Loc.getLocalDataAlignment();
99  return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>();
100  }
101 
102  /// Creates a TypeSourceInfo for the given type.
104 #ifndef NDEBUG
105  assert(T == LastTy && "type doesn't match last type pushed!");
106 #endif
107 
108  size_t FullDataSize = Capacity - Index;
109  TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize);
110  memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
111  return DI;
112  }
113 
114  /// Copies the type-location information to the given AST context and
115  /// returns a \c TypeLoc referring into the AST context.
117 #ifndef NDEBUG
118  assert(T == LastTy && "type doesn't match last type pushed!");
119 #endif
120 
121  size_t FullDataSize = Capacity - Index;
122  void *Mem = Context.Allocate(FullDataSize);
123  memcpy(Mem, &Buffer[Index], FullDataSize);
124  return TypeLoc(T, Mem);
125  }
126 
127 private:
128 
129  TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment);
130 
131  /// Grow to the given capacity.
132  void grow(size_t NewCapacity);
133 
134  /// Retrieve a temporary TypeLoc that refers into this \c TypeLocBuilder
135  /// object.
136  ///
137  /// The resulting \c TypeLoc should only be used so long as the
138  /// \c TypeLocBuilder is active and has not had more type information
139  /// pushed into it.
140  TypeLoc getTemporaryTypeLoc(QualType T) {
141 #ifndef NDEBUG
142  assert(LastTy == T && "type doesn't match last type pushed!");
143 #endif
144  return TypeLoc(T, &Buffer[Index]);
145  }
146 };
147 
148 }
149 
150 #endif
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
Definition: Type.h:639
A container of type source information.
Definition: Decl.h:86
A reasonable base class for TypeLocs that correspond to types that are written as a type-specifier...
Definition: TypeLoc.h:506
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:56
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
TypeSpecTypeLoc pushTypeSpec(QualType T)
Pushes space for a typespec TypeLoc.
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void * getOpaqueData() const
Get the pointer where source information is stored.
Definition: TypeLoc.h:139
void TypeWasModifiedSafely(QualType T)
Tell the TypeLocBuilder that the type it is storing has been modified in some safe way that doesn&#39;t a...
Defines the clang::TypeLoc interface and its subclasses.
TypeLoc getTypeLocInContext(ASTContext &Context, QualType T)
Copies the type-location information to the given AST context and returns a TypeLoc referring into th...
void clear()
Resets this builder to the newly-initialized state.
Encodes a location in the source.
TypeSourceInfo * CreateTypeSourceInfo(QualType T, unsigned Size=0) const
Allocate an uninitialized TypeSourceInfo.
void reserve(size_t Requested)
Ensures that this buffer has at least as much capacity as described.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:668
Dataflow Directional Tag Classes.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:237
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type...
Definition: TypeLoc.h:75
void pushFullCopy(TypeLoc L)
Pushes a copy of the given TypeLoc onto this builder.