Home | History | Annotate | Line # | Download | only in Serialization
      1 //===- ASTRecordWriter.h - Helper classes for writing AST -------*- 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 the ASTRecordWriter class, a helper class useful
     10 //  when serializing AST.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H
     15 #define LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H
     16 
     17 #include "clang/AST/AbstractBasicWriter.h"
     18 #include "clang/AST/OpenMPClause.h"
     19 #include "clang/Serialization/ASTWriter.h"
     20 
     21 namespace clang {
     22 
     23 class TypeLoc;
     24 
     25 /// An object for streaming information to a record.
     26 class ASTRecordWriter
     27     : public serialization::DataStreamBasicWriter<ASTRecordWriter> {
     28   ASTWriter *Writer;
     29   ASTWriter::RecordDataImpl *Record;
     30 
     31   /// Statements that we've encountered while serializing a
     32   /// declaration or type.
     33   SmallVector<Stmt *, 16> StmtsToEmit;
     34 
     35   /// Indices of record elements that describe offsets within the
     36   /// bitcode. These will be converted to offsets relative to the current
     37   /// record when emitted.
     38   SmallVector<unsigned, 8> OffsetIndices;
     39 
     40   /// Flush all of the statements and expressions that have
     41   /// been added to the queue via AddStmt().
     42   void FlushStmts();
     43   void FlushSubStmts();
     44 
     45   void PrepareToEmit(uint64_t MyOffset) {
     46     // Convert offsets into relative form.
     47     for (unsigned I : OffsetIndices) {
     48       auto &StoredOffset = (*Record)[I];
     49       assert(StoredOffset < MyOffset && "invalid offset");
     50       if (StoredOffset)
     51         StoredOffset = MyOffset - StoredOffset;
     52     }
     53     OffsetIndices.clear();
     54   }
     55 
     56 public:
     57   /// Construct a ASTRecordWriter that uses the default encoding scheme.
     58   ASTRecordWriter(ASTWriter &W, ASTWriter::RecordDataImpl &Record)
     59       : DataStreamBasicWriter(W.getASTContext()), Writer(&W), Record(&Record) {}
     60 
     61   /// Construct a ASTRecordWriter that uses the same encoding scheme as another
     62   /// ASTRecordWriter.
     63   ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record)
     64       : DataStreamBasicWriter(Parent.getASTContext()), Writer(Parent.Writer),
     65         Record(&Record) {}
     66 
     67   /// Copying an ASTRecordWriter is almost certainly a bug.
     68   ASTRecordWriter(const ASTRecordWriter &) = delete;
     69   ASTRecordWriter &operator=(const ASTRecordWriter &) = delete;
     70 
     71   /// Extract the underlying record storage.
     72   ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }
     73 
     74   /// Minimal vector-like interface.
     75   /// @{
     76   void push_back(uint64_t N) { Record->push_back(N); }
     77   template<typename InputIterator>
     78   void append(InputIterator begin, InputIterator end) {
     79     Record->append(begin, end);
     80   }
     81   bool empty() const { return Record->empty(); }
     82   size_t size() const { return Record->size(); }
     83   uint64_t &operator[](size_t N) { return (*Record)[N]; }
     84   /// @}
     85 
     86   /// Emit the record to the stream, followed by its substatements, and
     87   /// return its offset.
     88   // FIXME: Allow record producers to suggest Abbrevs.
     89   uint64_t Emit(unsigned Code, unsigned Abbrev = 0) {
     90     uint64_t Offset = Writer->Stream.GetCurrentBitNo();
     91     PrepareToEmit(Offset);
     92     Writer->Stream.EmitRecord(Code, *Record, Abbrev);
     93     FlushStmts();
     94     return Offset;
     95   }
     96 
     97   /// Emit the record to the stream, preceded by its substatements.
     98   uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) {
     99     FlushSubStmts();
    100     PrepareToEmit(Writer->Stream.GetCurrentBitNo());
    101     Writer->Stream.EmitRecord(Code, *Record, Abbrev);
    102     return Writer->Stream.GetCurrentBitNo();
    103   }
    104 
    105   /// Add a bit offset into the record. This will be converted into an
    106   /// offset relative to the current record when emitted.
    107   void AddOffset(uint64_t BitOffset) {
    108     OffsetIndices.push_back(Record->size());
    109     Record->push_back(BitOffset);
    110   }
    111 
    112   /// Add the given statement or expression to the queue of
    113   /// statements to emit.
    114   ///
    115   /// This routine should be used when emitting types and declarations
    116   /// that have expressions as part of their formulation. Once the
    117   /// type or declaration has been written, Emit() will write
    118   /// the corresponding statements just after the record.
    119   void AddStmt(Stmt *S) {
    120     StmtsToEmit.push_back(S);
    121   }
    122   void writeStmtRef(const Stmt *S) {
    123     AddStmt(const_cast<Stmt*>(S));
    124   }
    125 
    126   /// Add a definition for the given function to the queue of statements
    127   /// to emit.
    128   void AddFunctionDefinition(const FunctionDecl *FD);
    129 
    130   /// Emit a source location.
    131   void AddSourceLocation(SourceLocation Loc) {
    132     return Writer->AddSourceLocation(Loc, *Record);
    133   }
    134   void writeSourceLocation(SourceLocation Loc) {
    135     AddSourceLocation(Loc);
    136   }
    137 
    138   /// Emit a source range.
    139   void AddSourceRange(SourceRange Range) {
    140     return Writer->AddSourceRange(Range, *Record);
    141   }
    142 
    143   void writeBool(bool Value) {
    144     Record->push_back(Value);
    145   }
    146 
    147   void writeUInt32(uint32_t Value) {
    148     Record->push_back(Value);
    149   }
    150 
    151   void writeUInt64(uint64_t Value) {
    152     Record->push_back(Value);
    153   }
    154 
    155   /// Emit an integral value.
    156   void AddAPInt(const llvm::APInt &Value) {
    157     writeAPInt(Value);
    158   }
    159 
    160   /// Emit a signed integral value.
    161   void AddAPSInt(const llvm::APSInt &Value) {
    162     writeAPSInt(Value);
    163   }
    164 
    165   /// Emit a floating-point value.
    166   void AddAPFloat(const llvm::APFloat &Value);
    167 
    168   /// Emit an APvalue.
    169   void AddAPValue(const APValue &Value) { writeAPValue(Value); }
    170 
    171   /// Emit a reference to an identifier.
    172   void AddIdentifierRef(const IdentifierInfo *II) {
    173     return Writer->AddIdentifierRef(II, *Record);
    174   }
    175   void writeIdentifier(const IdentifierInfo *II) {
    176     AddIdentifierRef(II);
    177   }
    178 
    179   /// Emit a Selector (which is a smart pointer reference).
    180   void AddSelectorRef(Selector S);
    181   void writeSelector(Selector sel) {
    182     AddSelectorRef(sel);
    183   }
    184 
    185   /// Emit a CXXTemporary.
    186   void AddCXXTemporary(const CXXTemporary *Temp);
    187 
    188   /// Emit a C++ base specifier.
    189   void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);
    190 
    191   /// Emit a set of C++ base specifiers.
    192   void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases);
    193 
    194   /// Emit a reference to a type.
    195   void AddTypeRef(QualType T) {
    196     return Writer->AddTypeRef(T, *Record);
    197   }
    198   void writeQualType(QualType T) {
    199     AddTypeRef(T);
    200   }
    201 
    202   /// Emits a reference to a declarator info.
    203   void AddTypeSourceInfo(TypeSourceInfo *TInfo);
    204 
    205   /// Emits source location information for a type. Does not emit the type.
    206   void AddTypeLoc(TypeLoc TL);
    207 
    208   /// Emits a template argument location info.
    209   void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
    210                                   const TemplateArgumentLocInfo &Arg);
    211 
    212   /// Emits a template argument location.
    213   void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);
    214 
    215   /// Emits an AST template argument list info.
    216   void AddASTTemplateArgumentListInfo(
    217       const ASTTemplateArgumentListInfo *ASTTemplArgList);
    218 
    219   /// Emit a reference to a declaration.
    220   void AddDeclRef(const Decl *D) {
    221     return Writer->AddDeclRef(D, *Record);
    222   }
    223   void writeDeclRef(const Decl *D) {
    224     AddDeclRef(D);
    225   }
    226 
    227   /// Emit a declaration name.
    228   void AddDeclarationName(DeclarationName Name) {
    229     writeDeclarationName(Name);
    230   }
    231 
    232   void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
    233                              DeclarationName Name);
    234   void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
    235 
    236   void AddQualifierInfo(const QualifierInfo &Info);
    237 
    238   /// Emit a nested name specifier.
    239   void AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
    240     writeNestedNameSpecifier(NNS);
    241   }
    242 
    243   /// Emit a nested name specifier with source-location information.
    244   void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
    245 
    246   /// Emit a template name.
    247   void AddTemplateName(TemplateName Name) {
    248     writeTemplateName(Name);
    249   }
    250 
    251   /// Emit a template argument.
    252   void AddTemplateArgument(const TemplateArgument &Arg) {
    253     writeTemplateArgument(Arg);
    254   }
    255 
    256   /// Emit a template parameter list.
    257   void AddTemplateParameterList(const TemplateParameterList *TemplateParams);
    258 
    259   /// Emit a template argument list.
    260   void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs);
    261 
    262   /// Emit a UnresolvedSet structure.
    263   void AddUnresolvedSet(const ASTUnresolvedSet &Set);
    264 
    265   /// Emit a CXXCtorInitializer array.
    266   void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits);
    267 
    268   void AddCXXDefinitionData(const CXXRecordDecl *D);
    269 
    270   /// Emit information about the initializer of a VarDecl.
    271   void AddVarDeclInit(const VarDecl *VD);
    272 
    273   /// Write an OMPTraitInfo object.
    274   void writeOMPTraitInfo(const OMPTraitInfo *TI);
    275 
    276   void writeOMPClause(OMPClause *C);
    277 
    278   /// Writes data related to the OpenMP directives.
    279   void writeOMPChildren(OMPChildren *Data);
    280 
    281   /// Emit a string.
    282   void AddString(StringRef Str) {
    283     return Writer->AddString(Str, *Record);
    284   }
    285 
    286   /// Emit a path.
    287   void AddPath(StringRef Path) {
    288     return Writer->AddPath(Path, *Record);
    289   }
    290 
    291   /// Emit a version tuple.
    292   void AddVersionTuple(const VersionTuple &Version) {
    293     return Writer->AddVersionTuple(Version, *Record);
    294   }
    295 
    296   // Emit an attribute.
    297   void AddAttr(const Attr *A);
    298 
    299   /// Emit a list of attributes.
    300   void AddAttributes(ArrayRef<const Attr*> Attrs);
    301 };
    302 
    303 } // end namespace clang
    304 
    305 #endif
    306