clang  6.0.0svn
TypeLocBuilder.h
Go to the documentation of this file.
1 //===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines TypeLocBuilder, a class for building TypeLocs
11 // bottom-up.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H
16 #define LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H
17 
18 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/TypeLoc.h"
20 
21 namespace clang {
22 
24  enum { InlineCapacity = 8 * sizeof(SourceLocation) };
25 
26  /// The underlying location-data buffer. Data grows from the end
27  /// of the buffer backwards.
28  char *Buffer;
29 
30  /// The capacity of the current buffer.
31  size_t Capacity;
32 
33  /// The index of the first occupied byte in the buffer.
34  size_t Index;
35 
36 #ifndef NDEBUG
37  /// The last type pushed on this builder.
38  QualType LastTy;
39 #endif
40 
41  /// The inline buffer.
42  enum { BufferMaxAlignment = alignof(void *) };
43  llvm::AlignedCharArray<BufferMaxAlignment, InlineCapacity> InlineBuffer;
44  unsigned NumBytesAtAlign4, NumBytesAtAlign8;
45 
46  public:
48  : Buffer(InlineBuffer.buffer), Capacity(InlineCapacity),
49  Index(InlineCapacity), NumBytesAtAlign4(0), NumBytesAtAlign8(0)
50  {
51  }
52 
54  if (Buffer != InlineBuffer.buffer)
55  delete[] Buffer;
56  }
57 
58  /// Ensures that this buffer has at least as much capacity as described.
59  void reserve(size_t Requested) {
60  if (Requested > Capacity)
61  // For now, match the request exactly.
62  grow(Requested);
63  }
64 
65  /// Pushes a copy of the given TypeLoc onto this builder. The builder
66  /// must be empty for this to work.
67  void pushFullCopy(TypeLoc L);
68 
69  /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs
70  /// previously retrieved from this builder.
72  size_t LocalSize = TypeSpecTypeLoc::LocalDataSize;
73  unsigned LocalAlign = TypeSpecTypeLoc::LocalDataAlignment;
74  return pushImpl(T, LocalSize, LocalAlign).castAs<TypeSpecTypeLoc>();
75  }
76 
77  /// Resets this builder to the newly-initialized state.
78  void clear() {
79 #ifndef NDEBUG
80  LastTy = QualType();
81 #endif
82  Index = Capacity;
83  NumBytesAtAlign4 = NumBytesAtAlign8 = 0;
84  }
85 
86  /// \brief Tell the TypeLocBuilder that the type it is storing has been
87  /// modified in some safe way that doesn't affect type-location information.
89 #ifndef NDEBUG
90  LastTy = T;
91 #endif
92  }
93 
94  /// Pushes space for a new TypeLoc of the given type. Invalidates
95  /// any TypeLocs previously retrieved from this builder.
96  template <class TyLocType> TyLocType push(QualType T) {
97  TyLocType Loc = TypeLoc(T, nullptr).castAs<TyLocType>();
98  size_t LocalSize = Loc.getLocalDataSize();
99  unsigned LocalAlign = Loc.getLocalDataAlignment();
100  return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>();
101  }
102 
103  /// Creates a TypeSourceInfo for the given type.
105 #ifndef NDEBUG
106  assert(T == LastTy && "type doesn't match last type pushed!");
107 #endif
108 
109  size_t FullDataSize = Capacity - Index;
110  TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize);
111  memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
112  return DI;
113  }
114 
115  /// \brief Copies the type-location information to the given AST context and
116  /// returns a \c TypeLoc referring into the AST context.
118 #ifndef NDEBUG
119  assert(T == LastTy && "type doesn't match last type pushed!");
120 #endif
121 
122  size_t FullDataSize = Capacity - Index;
123  void *Mem = Context.Allocate(FullDataSize);
124  memcpy(Mem, &Buffer[Index], FullDataSize);
125  return TypeLoc(T, Mem);
126  }
127 
128 private:
129 
130  TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment);
131 
132  /// Grow to the given capacity.
133  void grow(size_t NewCapacity);
134 
135  /// \brief Retrieve a temporary TypeLoc that refers into this \c TypeLocBuilder
136  /// object.
137  ///
138  /// The resulting \c TypeLoc should only be used so long as the
139  /// \c TypeLocBuilder is active and has not had more type information
140  /// pushed into it.
141  TypeLoc getTemporaryTypeLoc(QualType T) {
142 #ifndef NDEBUG
143  assert(LastTy == T && "type doesn't match last type pushed!");
144 #endif
145  return TypeLoc(T, &Buffer[Index]);
146  }
147 };
148 
149 }
150 
151 #endif
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
Definition: Type.h:653
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:508
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:149
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...
const FunctionProtoType * T
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.
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:650
Dataflow Directional Tag Classes.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:239
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.