Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:06

0001 //===- ASTRecordWriter.h - Helper classes for writing AST -------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the ASTRecordWriter class, a helper class useful
0010 //  when serializing AST.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H
0015 #define LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H
0016 
0017 #include "clang/AST/AbstractBasicWriter.h"
0018 #include "clang/AST/OpenACCClause.h"
0019 #include "clang/AST/OpenMPClause.h"
0020 #include "clang/Serialization/ASTWriter.h"
0021 #include "clang/Serialization/SourceLocationEncoding.h"
0022 
0023 namespace clang {
0024 
0025 class OpenACCClause;
0026 class TypeLoc;
0027 
0028 /// An object for streaming information to a record.
0029 class ASTRecordWriter
0030     : public serialization::DataStreamBasicWriter<ASTRecordWriter> {
0031   using LocSeq = SourceLocationSequence;
0032 
0033   ASTWriter *Writer;
0034   ASTWriter::RecordDataImpl *Record;
0035 
0036   /// Statements that we've encountered while serializing a
0037   /// declaration or type.
0038   SmallVector<Stmt *, 16> StmtsToEmit;
0039 
0040   /// Indices of record elements that describe offsets within the
0041   /// bitcode. These will be converted to offsets relative to the current
0042   /// record when emitted.
0043   SmallVector<unsigned, 8> OffsetIndices;
0044 
0045   /// Flush all of the statements and expressions that have
0046   /// been added to the queue via AddStmt().
0047   void FlushStmts();
0048   void FlushSubStmts();
0049 
0050   void PrepareToEmit(uint64_t MyOffset) {
0051     // Convert offsets into relative form.
0052     for (unsigned I : OffsetIndices) {
0053       auto &StoredOffset = (*Record)[I];
0054       assert(StoredOffset < MyOffset && "invalid offset");
0055       if (StoredOffset)
0056         StoredOffset = MyOffset - StoredOffset;
0057     }
0058     OffsetIndices.clear();
0059   }
0060 
0061 public:
0062   /// Construct a ASTRecordWriter that uses the default encoding scheme.
0063   ASTRecordWriter(ASTContext &Context, ASTWriter &W,
0064                   ASTWriter::RecordDataImpl &Record)
0065       : DataStreamBasicWriter(Context), Writer(&W), Record(&Record) {}
0066 
0067   /// Construct a ASTRecordWriter that uses the same encoding scheme as another
0068   /// ASTRecordWriter.
0069   ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record)
0070       : DataStreamBasicWriter(Parent.getASTContext()), Writer(Parent.Writer),
0071         Record(&Record) {}
0072 
0073   /// Copying an ASTRecordWriter is almost certainly a bug.
0074   ASTRecordWriter(const ASTRecordWriter &) = delete;
0075   ASTRecordWriter &operator=(const ASTRecordWriter &) = delete;
0076 
0077   /// Extract the underlying record storage.
0078   ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }
0079 
0080   /// Minimal vector-like interface.
0081   /// @{
0082   void push_back(uint64_t N) { Record->push_back(N); }
0083   template<typename InputIterator>
0084   void append(InputIterator begin, InputIterator end) {
0085     Record->append(begin, end);
0086   }
0087   bool empty() const { return Record->empty(); }
0088   size_t size() const { return Record->size(); }
0089   uint64_t &operator[](size_t N) { return (*Record)[N]; }
0090   /// @}
0091 
0092   /// Emit the record to the stream, followed by its substatements, and
0093   /// return its offset.
0094   // FIXME: Allow record producers to suggest Abbrevs.
0095   uint64_t Emit(unsigned Code, unsigned Abbrev = 0) {
0096     uint64_t Offset = Writer->Stream.GetCurrentBitNo();
0097     PrepareToEmit(Offset);
0098     Writer->Stream.EmitRecord(Code, *Record, Abbrev);
0099     FlushStmts();
0100     return Offset;
0101   }
0102 
0103   /// Emit the record to the stream, preceded by its substatements.
0104   uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) {
0105     FlushSubStmts();
0106     PrepareToEmit(Writer->Stream.GetCurrentBitNo());
0107     Writer->Stream.EmitRecord(Code, *Record, Abbrev);
0108     return Writer->Stream.GetCurrentBitNo();
0109   }
0110 
0111   /// Add a bit offset into the record. This will be converted into an
0112   /// offset relative to the current record when emitted.
0113   void AddOffset(uint64_t BitOffset) {
0114     OffsetIndices.push_back(Record->size());
0115     Record->push_back(BitOffset);
0116   }
0117 
0118   /// Add the given statement or expression to the queue of
0119   /// statements to emit.
0120   ///
0121   /// This routine should be used when emitting types and declarations
0122   /// that have expressions as part of their formulation. Once the
0123   /// type or declaration has been written, Emit() will write
0124   /// the corresponding statements just after the record.
0125   void AddStmt(Stmt *S) {
0126     StmtsToEmit.push_back(S);
0127   }
0128   void writeStmtRef(const Stmt *S) {
0129     AddStmt(const_cast<Stmt*>(S));
0130   }
0131 
0132   void writeAttr(const Attr *A) { AddAttr(A); }
0133 
0134   /// Write an BTFTypeTagAttr object.
0135   void writeBTFTypeTagAttr(const BTFTypeTagAttr *A) { AddAttr(A); }
0136 
0137   /// Add a definition for the given function to the queue of statements
0138   /// to emit.
0139   void AddFunctionDefinition(const FunctionDecl *FD);
0140 
0141   /// Emit a source location.
0142   void AddSourceLocation(SourceLocation Loc, LocSeq *Seq = nullptr) {
0143     return Writer->AddSourceLocation(Loc, *Record, Seq);
0144   }
0145   void writeSourceLocation(SourceLocation Loc) {
0146     AddSourceLocation(Loc);
0147   }
0148 
0149   void writeTypeCoupledDeclRefInfo(TypeCoupledDeclRefInfo Info) {
0150     writeDeclRef(Info.getDecl());
0151     writeBool(Info.isDeref());
0152   }
0153 
0154   /// Emit a source range.
0155   void AddSourceRange(SourceRange Range, LocSeq *Seq = nullptr) {
0156     return Writer->AddSourceRange(Range, *Record, Seq);
0157   }
0158 
0159   void writeBool(bool Value) {
0160     Record->push_back(Value);
0161   }
0162 
0163   void writeUInt32(uint32_t Value) {
0164     Record->push_back(Value);
0165   }
0166 
0167   void writeUInt64(uint64_t Value) {
0168     Record->push_back(Value);
0169   }
0170 
0171   /// Emit an integral value.
0172   void AddAPInt(const llvm::APInt &Value) {
0173     writeAPInt(Value);
0174   }
0175 
0176   /// Emit a signed integral value.
0177   void AddAPSInt(const llvm::APSInt &Value) {
0178     writeAPSInt(Value);
0179   }
0180 
0181   /// Emit a floating-point value.
0182   void AddAPFloat(const llvm::APFloat &Value);
0183 
0184   /// Emit an APvalue.
0185   void AddAPValue(const APValue &Value) { writeAPValue(Value); }
0186 
0187   /// Emit a reference to an identifier.
0188   void AddIdentifierRef(const IdentifierInfo *II) {
0189     return Writer->AddIdentifierRef(II, *Record);
0190   }
0191   void writeIdentifier(const IdentifierInfo *II) {
0192     AddIdentifierRef(II);
0193   }
0194 
0195   /// Emit a Selector (which is a smart pointer reference).
0196   void AddSelectorRef(Selector S);
0197   void writeSelector(Selector sel) {
0198     AddSelectorRef(sel);
0199   }
0200 
0201   /// Emit a CXXTemporary.
0202   void AddCXXTemporary(const CXXTemporary *Temp);
0203 
0204   /// Emit a C++ base specifier.
0205   void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);
0206 
0207   /// Emit a set of C++ base specifiers.
0208   void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases);
0209 
0210   /// Emit a reference to a type.
0211   void AddTypeRef(QualType T) {
0212     return Writer->AddTypeRef(getASTContext(), T, *Record);
0213   }
0214   void writeQualType(QualType T) {
0215     AddTypeRef(T);
0216   }
0217 
0218   /// Emits a reference to a declarator info.
0219   void AddTypeSourceInfo(TypeSourceInfo *TInfo);
0220 
0221   /// Emits source location information for a type. Does not emit the type.
0222   void AddTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr);
0223 
0224   /// Emits a template argument location info.
0225   void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
0226                                   const TemplateArgumentLocInfo &Arg);
0227 
0228   /// Emits a template argument location.
0229   void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);
0230 
0231   /// Emits an AST template argument list info.
0232   void AddASTTemplateArgumentListInfo(
0233       const ASTTemplateArgumentListInfo *ASTTemplArgList);
0234 
0235   // Emits a concept reference.
0236   void AddConceptReference(const ConceptReference *CR);
0237 
0238   /// Emit a reference to a declaration.
0239   void AddDeclRef(const Decl *D) {
0240     return Writer->AddDeclRef(D, *Record);
0241   }
0242   void writeDeclRef(const Decl *D) {
0243     AddDeclRef(D);
0244   }
0245 
0246   /// Emit a declaration name.
0247   void AddDeclarationName(DeclarationName Name) {
0248     writeDeclarationName(Name);
0249   }
0250 
0251   void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
0252                              DeclarationName Name);
0253   void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
0254 
0255   void AddQualifierInfo(const QualifierInfo &Info);
0256 
0257   /// Emit a nested name specifier.
0258   void AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
0259     writeNestedNameSpecifier(NNS);
0260   }
0261 
0262   /// Emit a nested name specifier with source-location information.
0263   void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
0264 
0265   /// Emit a template name.
0266   void AddTemplateName(TemplateName Name) {
0267     writeTemplateName(Name);
0268   }
0269 
0270   /// Emit a template argument.
0271   void AddTemplateArgument(const TemplateArgument &Arg) {
0272     writeTemplateArgument(Arg);
0273   }
0274 
0275   /// Emit a template parameter list.
0276   void AddTemplateParameterList(const TemplateParameterList *TemplateParams);
0277 
0278   /// Emit a template argument list.
0279   void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs);
0280 
0281   /// Emit a UnresolvedSet structure.
0282   void AddUnresolvedSet(const ASTUnresolvedSet &Set);
0283 
0284   /// Emit a CXXCtorInitializer array.
0285   void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits);
0286 
0287   void AddCXXDefinitionData(const CXXRecordDecl *D);
0288 
0289   /// Emit information about the initializer of a VarDecl.
0290   void AddVarDeclInit(const VarDecl *VD);
0291 
0292   /// Write an OMPTraitInfo object.
0293   void writeOMPTraitInfo(const OMPTraitInfo *TI);
0294 
0295   void writeOMPClause(OMPClause *C);
0296 
0297   /// Writes data related to the OpenMP directives.
0298   void writeOMPChildren(OMPChildren *Data);
0299 
0300   void writeOpenACCVarList(const OpenACCClauseWithVarList *C);
0301 
0302   void writeOpenACCIntExprList(ArrayRef<Expr *> Exprs);
0303 
0304   /// Writes out a single OpenACC Clause.
0305   void writeOpenACCClause(const OpenACCClause *C);
0306 
0307   /// Writes out a list of OpenACC clauses.
0308   void writeOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses);
0309 
0310   /// Emit a string.
0311   void AddString(StringRef Str) {
0312     return Writer->AddString(Str, *Record);
0313   }
0314 
0315   /// Emit a path.
0316   void AddPath(StringRef Path) {
0317     return Writer->AddPath(Path, *Record);
0318   }
0319 
0320   /// Emit a version tuple.
0321   void AddVersionTuple(const VersionTuple &Version) {
0322     return Writer->AddVersionTuple(Version, *Record);
0323   }
0324 
0325   // Emit an attribute.
0326   void AddAttr(const Attr *A);
0327 
0328   /// Emit a list of attributes.
0329   void AddAttributes(ArrayRef<const Attr*> Attrs);
0330 };
0331 
0332 } // end namespace clang
0333 
0334 #endif