brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · e84e79a Raw
158 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9//  This file defines TypeLocBuilder, a class for building TypeLocs10//  bottom-up.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H15#define LLVM_CLANG_LIB_SEMA_TYPELOCBUILDER_H16 17#include "clang/AST/ASTContext.h"18#include "clang/AST/TypeLoc.h"19 20namespace clang {21 22class TypeLocBuilder {23  static constexpr int InlineCapacity = 8 * sizeof(SourceLocation);24 25  /// The underlying location-data buffer.  Data grows from the end26  /// 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 NDEBUG36  /// The last type pushed on this builder.37  QualType LastTy;38#endif39 40  /// The inline buffer.41  static constexpr int BufferMaxAlignment = alignof(void *);42  alignas(BufferMaxAlignment) char InlineBuffer[InlineCapacity];43  unsigned NumBytesAtAlign4;44  bool AtAlign8;45 46public:47  TypeLocBuilder()48      : Buffer(InlineBuffer), Capacity(InlineCapacity), Index(InlineCapacity),49        NumBytesAtAlign4(0), AtAlign8(false) {}50 51  ~TypeLocBuilder() {52    if (Buffer != InlineBuffer)53      delete[] Buffer;54  }55 56  TypeLocBuilder(const TypeLocBuilder &) = delete;57  TypeLocBuilder &operator=(const TypeLocBuilder &) = delete;58 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);64  }65 66  /// Pushes a copy of the given TypeLoc onto this builder.  The builder67  /// must be empty for this to work.68  void pushFullCopy(TypeLoc L);69 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);73 74  /// Pushes space for a typespec TypeLoc.  Invalidates any TypeLocs75  /// 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>();80  }81 82  /// Resets this builder to the newly-initialized state.83  void clear() {84#ifndef NDEBUG85    LastTy = QualType();86#endif87    Index = Capacity;88    NumBytesAtAlign4 = 0;89    AtAlign8 = false;90  }91 92  /// Tell the TypeLocBuilder that the type it is storing has been93  /// modified in some safe way that doesn't affect type-location information.94  void TypeWasModifiedSafely(QualType T) {95#ifndef NDEBUG96    LastTy = T;97#endif98  }99 100  /// Pushes space for a new TypeLoc of the given type.  Invalidates101  /// 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>();107  }108 109  /// Creates a TypeSourceInfo for the given type.110  TypeSourceInfo *getTypeSourceInfo(ASTContext& Context, QualType T) {111#ifndef NDEBUG112    assert(T == LastTy && "type doesn't match last type pushed!");113#endif114 115    size_t FullDataSize = Capacity - Index;116    TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T, FullDataSize);117    memcpy(TSI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);118    return TSI;119  }120 121  /// Copies the type-location information to the given AST context and122  /// returns a \c TypeLoc referring into the AST context.123  TypeLoc getTypeLocInContext(ASTContext &Context, QualType T) {124#ifndef NDEBUG125    assert(T == LastTy && "type doesn't match last type pushed!");126#endif127 128    size_t FullDataSize = Capacity - Index;129    void *Mem = Context.Allocate(FullDataSize);130    memcpy(Mem, &Buffer[Index], FullDataSize);131    return TypeLoc(T, Mem);132  }133 134private:135 136  TypeLoc pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment);137 138  /// Grow to the given capacity.139  void grow(size_t NewCapacity);140 141  /// Retrieve a temporary TypeLoc that refers into this \c TypeLocBuilder142  /// object.143  ///144  /// The resulting \c TypeLoc should only be used so long as the145  /// \c TypeLocBuilder is active and has not had more type information146  /// pushed into it.147  TypeLoc getTemporaryTypeLoc(QualType T) {148#ifndef NDEBUG149    assert(LastTy == T && "type doesn't match last type pushed!");150#endif151    return TypeLoc(T, &Buffer[Index]);152  }153};154 155}156 157#endif158