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