[HLSL] Implement RWBuffer::operator[] via __builtin_hlsl_resource_getpointer (#117017)
[llvm-project.git] / clang / lib / Sema / TypeLocBuilder.h
blob15eb2226cdf7f47e0570aaed62a1b2fff98c9bbd
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.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H
15 #define LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/TypeLoc.h"
20 namespace clang {
22 class TypeLocBuilder {
23 enum { InlineCapacity = 8 * sizeof(SourceLocation) };
25 /// The underlying location-data buffer. Data grows from the end
26 /// of the buffer backwards.
27 char *Buffer;
29 /// The capacity of the current buffer.
30 size_t Capacity;
32 /// The index of the first occupied byte in the buffer.
33 size_t Index;
35 #ifndef NDEBUG
36 /// The last type pushed on this builder.
37 QualType LastTy;
38 #endif
40 /// The inline buffer.
41 enum { BufferMaxAlignment = alignof(void *) };
42 alignas(BufferMaxAlignment) char InlineBuffer[InlineCapacity];
43 unsigned NumBytesAtAlign4;
44 bool AtAlign8;
46 public:
47 TypeLocBuilder()
48 : Buffer(InlineBuffer), Capacity(InlineCapacity), Index(InlineCapacity),
49 NumBytesAtAlign4(0), AtAlign8(false) {}
51 ~TypeLocBuilder() {
52 if (Buffer != InlineBuffer)
53 delete[] Buffer;
56 TypeLocBuilder(const TypeLocBuilder &) = delete;
57 TypeLocBuilder &operator=(const TypeLocBuilder &) = delete;
59 /// Ensures that this buffer has at least as much capacity as described.
60 void reserve(size_t Requested) {
61 if (Requested > Capacity)
62 // For now, match the request exactly.
63 grow(Requested);
66 /// Pushes a copy of the given TypeLoc onto this builder. The builder
67 /// must be empty for this to work.
68 void pushFullCopy(TypeLoc L);
70 /// Pushes 'T' with all locations pointing to 'Loc'.
71 /// The builder must be empty for this to work.
72 void pushTrivial(ASTContext &Context, QualType T, SourceLocation Loc);
74 /// Pushes space for a typespec TypeLoc. Invalidates any TypeLocs
75 /// previously retrieved from this builder.
76 TypeSpecTypeLoc pushTypeSpec(QualType T) {
77 size_t LocalSize = TypeSpecTypeLoc::LocalDataSize;
78 unsigned LocalAlign = TypeSpecTypeLoc::LocalDataAlignment;
79 return pushImpl(T, LocalSize, LocalAlign).castAs<TypeSpecTypeLoc>();
82 /// Resets this builder to the newly-initialized state.
83 void clear() {
84 #ifndef NDEBUG
85 LastTy = QualType();
86 #endif
87 Index = Capacity;
88 NumBytesAtAlign4 = 0;
89 AtAlign8 = false;
92 /// Tell the TypeLocBuilder that the type it is storing has been
93 /// modified in some safe way that doesn't affect type-location information.
94 void TypeWasModifiedSafely(QualType T) {
95 #ifndef NDEBUG
96 LastTy = T;
97 #endif
100 /// Pushes space for a new TypeLoc of the given type. Invalidates
101 /// any TypeLocs previously retrieved from this builder.
102 template <class TyLocType> TyLocType push(QualType T) {
103 TyLocType Loc = TypeLoc(T, nullptr).castAs<TyLocType>();
104 size_t LocalSize = Loc.getLocalDataSize();
105 unsigned LocalAlign = Loc.getLocalDataAlignment();
106 return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>();
109 /// Creates a TypeSourceInfo for the given type.
110 TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) {
111 #ifndef NDEBUG
112 assert(T == LastTy && "type doesn't match last type pushed!");
113 #endif
115 size_t FullDataSize = Capacity - Index;
116 TypeSourceInfo *DI = Context.CreateTypeSourceInfo(T, FullDataSize);
117 memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
118 return DI;
121 /// Copies the type-location information to the given AST context and
122 /// returns a \c TypeLoc referring into the AST context.
123 TypeLoc getTypeLocInContext(ASTContext &Context, QualType T) {
124 #ifndef NDEBUG
125 assert(T == LastTy && "type doesn't match last type pushed!");
126 #endif
128 size_t FullDataSize = Capacity - Index;
129 void *Mem = Context.Allocate(FullDataSize);
130 memcpy(Mem, &Buffer[Index], FullDataSize);
131 return TypeLoc(T, Mem);
134 private:
136 TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment);
138 /// Grow to the given capacity.
139 void grow(size_t NewCapacity);
141 /// Retrieve a temporary TypeLoc that refers into this \c TypeLocBuilder
142 /// object.
144 /// The resulting \c TypeLoc should only be used so long as the
145 /// \c TypeLocBuilder is active and has not had more type information
146 /// pushed into it.
147 TypeLoc getTemporaryTypeLoc(QualType T) {
148 #ifndef NDEBUG
149 assert(LastTy == T && "type doesn't match last type pushed!");
150 #endif
151 return TypeLoc(T, &Buffer[Index]);
157 #endif