[cfe-commits] r84715 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/TypeLocBuilder.h lib/AST/ASTContext.cpp

John McCall rjmccall at apple.com
Tue Oct 20 17:23:54 PDT 2009


Author: rjmccall
Date: Tue Oct 20 19:23:54 2009
New Revision: 84715

URL: http://llvm.org/viewvc/llvm-project?rev=84715&view=rev
Log:
Add TypeLocBuilder, an API for incrementally creating TypeLocs.  Change
the API for creating DeclaratorInfos to allow callers to provide an exact
size.


Added:
    cfe/trunk/include/clang/AST/TypeLocBuilder.h
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=84715&r1=84714&r2=84715&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Oct 20 19:23:54 2009
@@ -1059,7 +1059,10 @@
   /// \param T the type that will be the basis for type source info. This type
   /// should refer to how the declarator was written in source code, not to
   /// what type semantic analysis resolved the declarator to.
-  DeclaratorInfo *CreateDeclaratorInfo(QualType T);
+  ///
+  /// \param Size the size of the type info to create, or 0 if the size
+  /// should be calculated based on the type.
+  DeclaratorInfo *CreateDeclaratorInfo(QualType T, unsigned Size = 0);
 
 private:
   ASTContext(const ASTContext&); // DO NOT IMPLEMENT

Added: cfe/trunk/include/clang/AST/TypeLocBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLocBuilder.h?rev=84715&view=auto

==============================================================================
--- cfe/trunk/include/clang/AST/TypeLocBuilder.h (added)
+++ cfe/trunk/include/clang/AST/TypeLocBuilder.h Tue Oct 20 19:23:54 2009
@@ -0,0 +1,122 @@
+//===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines TypeLocBuilder, a class for building TypeLocs
+//  bottom-up.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPELOCBUILDER_H
+#define LLVM_CLANG_AST_TYPELOCBUILDER_H
+
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class TypeLocBuilder {
+  enum { InlineCapacity = 8 * sizeof(SourceLocation) };
+
+  /// The underlying location-data buffer.  Data grows from the end
+  /// of the buffer backwards.
+  char *Buffer;
+
+  /// The capacity of the current buffer.
+  size_t Capacity;
+
+  /// The index of the first occupied byte in the buffer.
+  size_t Index;
+
+#ifndef NDEBUG
+  /// The last type pushed on this builder.
+  QualType LastTy;
+#endif
+    
+  /// The inline buffer.
+  char InlineBuffer[InlineCapacity];
+
+ public:
+  TypeLocBuilder()
+    : Buffer(InlineBuffer), Capacity(InlineCapacity), Index(InlineCapacity)
+  {}
+
+  ~TypeLocBuilder() {
+    if (Buffer != InlineBuffer)
+      delete[] Buffer;
+  }
+
+  /// Ensures that this buffer has at least as much capacity as described.
+  void reserve(size_t Requested) {
+    if (Requested > Capacity)
+      // For now, match the request exactly.
+      grow(Requested);
+  }
+
+  /// Pushes space for a new TypeLoc onto the given type.  Invalidates
+  /// any TypeLocs previously retrieved from this builder.
+  template <class TyLocType> TyLocType push(QualType T) {
+#ifndef NDEBUG
+    QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType();
+    assert(TLast == LastTy &&
+           "mismatch between last type and new type's inner type");
+    LastTy = T;
+#endif
+
+    size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize();
+
+    // If we need to grow, grow by a factor of 2.
+    if (LocalSize > Index) {
+      size_t RequiredCapacity = Capacity + (LocalSize - Index);
+      size_t NewCapacity = Capacity * 2;
+      while (RequiredCapacity > NewCapacity)
+        NewCapacity *= 2;
+      grow(NewCapacity);
+    }
+
+    Index -= LocalSize;
+
+    return cast<TyLocType>(TypeLoc(T, &Buffer[Index]));
+  }
+
+  /// Creates a DeclaratorInfo for the given type.
+  DeclaratorInfo *getDeclaratorInfo(ASTContext& Context, QualType T) {
+#ifndef NDEBUG
+    assert(T == LastTy && "type doesn't match last type pushed!");
+#endif
+
+    size_t FullDataSize = Capacity - Index;
+    DeclaratorInfo *DI = Context.CreateDeclaratorInfo(T, FullDataSize);
+    memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
+    return DI;
+  }
+
+ private:
+  /// Grow to the given capacity.
+  void grow(size_t NewCapacity) {
+    assert(NewCapacity > Capacity);
+
+    // Allocate the new buffer and copy the old data into it.
+    char *NewBuffer = new char[NewCapacity];
+    unsigned NewIndex = Index + NewCapacity - Capacity;
+    memcpy(&NewBuffer[NewIndex],
+           &Buffer[Index],
+           Capacity - Index);
+
+    if (Buffer != InlineBuffer)
+      delete[] Buffer;
+
+    Buffer = NewBuffer;
+    Capacity = NewCapacity;
+    Index = NewIndex;
+  }
+};
+
+}
+
+#endif

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=84715&r1=84714&r2=84715&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Oct 20 19:23:54 2009
@@ -943,8 +943,14 @@
 /// \param T the type that will be the basis for type source info. This type
 /// should refer to how the declarator was written in source code, not to
 /// what type semantic analysis resolved the declarator to.
-DeclaratorInfo *ASTContext::CreateDeclaratorInfo(QualType T) {
-  unsigned DataSize = TypeLoc::getFullDataSizeForType(T);
+DeclaratorInfo *ASTContext::CreateDeclaratorInfo(QualType T,
+                                                 unsigned DataSize) {
+  if (!DataSize)
+    DataSize = TypeLoc::getFullDataSizeForType(T);
+  else
+    assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&
+           "incorrect data size provided to CreateDeclaratorInfo!");
+
   DeclaratorInfo *DInfo =
     (DeclaratorInfo*)BumpAlloc.Allocate(sizeof(DeclaratorInfo) + DataSize, 8);
   new (DInfo) DeclaratorInfo(T);





More information about the cfe-commits mailing list