Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- ASTRecordReader.h - Helper classes for reading 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 classes that are useful in the implementation of |
||
| 10 | // the ASTReader. |
||
| 11 | // |
||
| 12 | //===----------------------------------------------------------------------===// |
||
| 13 | |||
| 14 | #ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H |
||
| 15 | #define LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H |
||
| 16 | |||
| 17 | #include "clang/AST/ASTContext.h" |
||
| 18 | #include "clang/AST/AbstractBasicReader.h" |
||
| 19 | #include "clang/Lex/Token.h" |
||
| 20 | #include "clang/Serialization/ASTReader.h" |
||
| 21 | #include "clang/Serialization/SourceLocationEncoding.h" |
||
| 22 | #include "llvm/ADT/APFloat.h" |
||
| 23 | #include "llvm/ADT/APInt.h" |
||
| 24 | #include "llvm/ADT/APSInt.h" |
||
| 25 | |||
| 26 | namespace clang { |
||
| 27 | class OMPTraitInfo; |
||
| 28 | class OMPChildren; |
||
| 29 | |||
| 30 | /// An object for streaming information from a record. |
||
| 31 | class ASTRecordReader |
||
| 32 | : public serialization::DataStreamBasicReader<ASTRecordReader> { |
||
| 33 | using ModuleFile = serialization::ModuleFile; |
||
| 34 | using LocSeq = SourceLocationSequence; |
||
| 35 | |||
| 36 | ASTReader *Reader; |
||
| 37 | ModuleFile *F; |
||
| 38 | unsigned Idx = 0; |
||
| 39 | ASTReader::RecordData Record; |
||
| 40 | |||
| 41 | using RecordData = ASTReader::RecordData; |
||
| 42 | using RecordDataImpl = ASTReader::RecordDataImpl; |
||
| 43 | |||
| 44 | public: |
||
| 45 | /// Construct an ASTRecordReader that uses the default encoding scheme. |
||
| 46 | ASTRecordReader(ASTReader &Reader, ModuleFile &F) |
||
| 47 | : DataStreamBasicReader(Reader.getContext()), Reader(&Reader), F(&F) {} |
||
| 48 | |||
| 49 | /// Reads a record with id AbbrevID from Cursor, resetting the |
||
| 50 | /// internal state. |
||
| 51 | Expected<unsigned> readRecord(llvm::BitstreamCursor &Cursor, |
||
| 52 | unsigned AbbrevID); |
||
| 53 | |||
| 54 | /// Is this a module file for a module (rather than a PCH or similar). |
||
| 55 | bool isModule() const { return F->isModule(); } |
||
| 56 | |||
| 57 | /// Retrieve the AST context that this AST reader supplements. |
||
| 58 | ASTContext &getContext() { return Reader->getContext(); } |
||
| 59 | |||
| 60 | /// The current position in this record. |
||
| 61 | unsigned getIdx() const { return Idx; } |
||
| 62 | |||
| 63 | /// The length of this record. |
||
| 64 | size_t size() const { return Record.size(); } |
||
| 65 | |||
| 66 | /// An arbitrary index in this record. |
||
| 67 | const uint64_t &operator[](size_t N) { return Record[N]; } |
||
| 68 | |||
| 69 | /// Returns the last value in this record. |
||
| 70 | uint64_t back() { return Record.back(); } |
||
| 71 | |||
| 72 | /// Returns the current value in this record, and advances to the |
||
| 73 | /// next value. |
||
| 74 | uint64_t readInt() { return Record[Idx++]; } |
||
| 75 | |||
| 76 | ArrayRef<uint64_t> readIntArray(unsigned Len) { |
||
| 77 | auto Array = llvm::ArrayRef(Record).slice(Idx, Len); |
||
| 78 | Idx += Len; |
||
| 79 | return Array; |
||
| 80 | } |
||
| 81 | |||
| 82 | /// Returns the current value in this record, without advancing. |
||
| 83 | uint64_t peekInt() { return Record[Idx]; } |
||
| 84 | |||
| 85 | /// Skips the specified number of values. |
||
| 86 | void skipInts(unsigned N) { Idx += N; } |
||
| 87 | |||
| 88 | /// Retrieve the global submodule ID its local ID number. |
||
| 89 | serialization::SubmoduleID |
||
| 90 | getGlobalSubmoduleID(unsigned LocalID) { |
||
| 91 | return Reader->getGlobalSubmoduleID(*F, LocalID); |
||
| 92 | } |
||
| 93 | |||
| 94 | /// Retrieve the submodule that corresponds to a global submodule ID. |
||
| 95 | Module *getSubmodule(serialization::SubmoduleID GlobalID) { |
||
| 96 | return Reader->getSubmodule(GlobalID); |
||
| 97 | } |
||
| 98 | |||
| 99 | /// Read the record that describes the lexical contents of a DC. |
||
| 100 | bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) { |
||
| 101 | return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset, |
||
| 102 | DC); |
||
| 103 | } |
||
| 104 | |||
| 105 | /// Read the record that describes the visible contents of a DC. |
||
| 106 | bool readVisibleDeclContextStorage(uint64_t Offset, |
||
| 107 | serialization::DeclID ID) { |
||
| 108 | return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset, |
||
| 109 | ID); |
||
| 110 | } |
||
| 111 | |||
| 112 | ExplicitSpecifier readExplicitSpec() { |
||
| 113 | uint64_t Kind = readInt(); |
||
| 114 | bool HasExpr = Kind & 0x1; |
||
| 115 | Kind = Kind >> 1; |
||
| 116 | return ExplicitSpecifier(HasExpr ? readExpr() : nullptr, |
||
| 117 | static_cast<ExplicitSpecKind>(Kind)); |
||
| 118 | } |
||
| 119 | |||
| 120 | /// Read information about an exception specification (inherited). |
||
| 121 | //FunctionProtoType::ExceptionSpecInfo |
||
| 122 | //readExceptionSpecInfo(SmallVectorImpl<QualType> &ExceptionStorage); |
||
| 123 | |||
| 124 | /// Get the global offset corresponding to a local offset. |
||
| 125 | uint64_t getGlobalBitOffset(uint64_t LocalOffset) { |
||
| 126 | return Reader->getGlobalBitOffset(*F, LocalOffset); |
||
| 127 | } |
||
| 128 | |||
| 129 | /// Reads a statement. |
||
| 130 | Stmt *readStmt() { return Reader->ReadStmt(*F); } |
||
| 131 | Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ } |
||
| 132 | |||
| 133 | /// Reads an expression. |
||
| 134 | Expr *readExpr() { return Reader->ReadExpr(*F); } |
||
| 135 | |||
| 136 | /// Reads a sub-statement operand during statement reading. |
||
| 137 | Stmt *readSubStmt() { return Reader->ReadSubStmt(); } |
||
| 138 | |||
| 139 | /// Reads a sub-expression operand during statement reading. |
||
| 140 | Expr *readSubExpr() { return Reader->ReadSubExpr(); } |
||
| 141 | |||
| 142 | /// Reads a declaration with the given local ID in the given module. |
||
| 143 | /// |
||
| 144 | /// \returns The requested declaration, casted to the given return type. |
||
| 145 | template<typename T> |
||
| 146 | T *GetLocalDeclAs(uint32_t LocalID) { |
||
| 147 | return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID)); |
||
| 148 | } |
||
| 149 | |||
| 150 | /// Reads a TemplateArgumentLocInfo appropriate for the |
||
| 151 | /// given TemplateArgument kind, advancing Idx. |
||
| 152 | TemplateArgumentLocInfo |
||
| 153 | readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind); |
||
| 154 | |||
| 155 | /// Reads a TemplateArgumentLoc, advancing Idx. |
||
| 156 | TemplateArgumentLoc readTemplateArgumentLoc(); |
||
| 157 | |||
| 158 | const ASTTemplateArgumentListInfo* |
||
| 159 | readASTTemplateArgumentListInfo(); |
||
| 160 | |||
| 161 | /// Reads a declarator info from the given record, advancing Idx. |
||
| 162 | TypeSourceInfo *readTypeSourceInfo(); |
||
| 163 | |||
| 164 | /// Reads the location information for a type. |
||
| 165 | void readTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr); |
||
| 166 | |||
| 167 | /// Map a local type ID within a given AST file to a global type ID. |
||
| 168 | serialization::TypeID getGlobalTypeID(unsigned LocalID) const { |
||
| 169 | return Reader->getGlobalTypeID(*F, LocalID); |
||
| 170 | } |
||
| 171 | |||
| 172 | Qualifiers readQualifiers() { |
||
| 173 | return Qualifiers::fromOpaqueValue(readInt()); |
||
| 174 | } |
||
| 175 | |||
| 176 | /// Read a type from the current position in the record. |
||
| 177 | QualType readType() { |
||
| 178 | return Reader->readType(*F, Record, Idx); |
||
| 179 | } |
||
| 180 | QualType readQualType() { |
||
| 181 | return readType(); |
||
| 182 | } |
||
| 183 | |||
| 184 | /// Reads a declaration ID from the given position in this record. |
||
| 185 | /// |
||
| 186 | /// \returns The declaration ID read from the record, adjusted to a global ID. |
||
| 187 | serialization::DeclID readDeclID() { |
||
| 188 | return Reader->ReadDeclID(*F, Record, Idx); |
||
| 189 | } |
||
| 190 | |||
| 191 | /// Reads a declaration from the given position in a record in the |
||
| 192 | /// given module, advancing Idx. |
||
| 193 | Decl *readDecl() { |
||
| 194 | return Reader->ReadDecl(*F, Record, Idx); |
||
| 195 | } |
||
| 196 | Decl *readDeclRef() { |
||
| 197 | return readDecl(); |
||
| 198 | } |
||
| 199 | |||
| 200 | /// Reads a declaration from the given position in the record, |
||
| 201 | /// advancing Idx. |
||
| 202 | /// |
||
| 203 | /// \returns The declaration read from this location, casted to the given |
||
| 204 | /// result type. |
||
| 205 | template<typename T> |
||
| 206 | T *readDeclAs() { |
||
| 207 | return Reader->ReadDeclAs<T>(*F, Record, Idx); |
||
| 208 | } |
||
| 209 | |||
| 210 | IdentifierInfo *readIdentifier() { |
||
| 211 | return Reader->readIdentifier(*F, Record, Idx); |
||
| 212 | } |
||
| 213 | |||
| 214 | /// Read a selector from the Record, advancing Idx. |
||
| 215 | Selector readSelector() { |
||
| 216 | return Reader->ReadSelector(*F, Record, Idx); |
||
| 217 | } |
||
| 218 | |||
| 219 | /// Read a declaration name, advancing Idx. |
||
| 220 | // DeclarationName readDeclarationName(); (inherited) |
||
| 221 | DeclarationNameLoc readDeclarationNameLoc(DeclarationName Name); |
||
| 222 | DeclarationNameInfo readDeclarationNameInfo(); |
||
| 223 | |||
| 224 | void readQualifierInfo(QualifierInfo &Info); |
||
| 225 | |||
| 226 | /// Return a nested name specifier, advancing Idx. |
||
| 227 | // NestedNameSpecifier *readNestedNameSpecifier(); (inherited) |
||
| 228 | |||
| 229 | NestedNameSpecifierLoc readNestedNameSpecifierLoc(); |
||
| 230 | |||
| 231 | /// Read a template name, advancing Idx. |
||
| 232 | // TemplateName readTemplateName(); (inherited) |
||
| 233 | |||
| 234 | /// Read a template argument, advancing Idx. (inherited) |
||
| 235 | // TemplateArgument readTemplateArgument(); |
||
| 236 | using DataStreamBasicReader::readTemplateArgument; |
||
| 237 | TemplateArgument readTemplateArgument(bool Canonicalize) { |
||
| 238 | TemplateArgument Arg = readTemplateArgument(); |
||
| 239 | if (Canonicalize) { |
||
| 240 | Arg = getContext().getCanonicalTemplateArgument(Arg); |
||
| 241 | } |
||
| 242 | return Arg; |
||
| 243 | } |
||
| 244 | |||
| 245 | /// Read a template parameter list, advancing Idx. |
||
| 246 | TemplateParameterList *readTemplateParameterList(); |
||
| 247 | |||
| 248 | /// Read a template argument array, advancing Idx. |
||
| 249 | void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, |
||
| 250 | bool Canonicalize = false); |
||
| 251 | |||
| 252 | /// Read a UnresolvedSet structure, advancing Idx. |
||
| 253 | void readUnresolvedSet(LazyASTUnresolvedSet &Set); |
||
| 254 | |||
| 255 | /// Read a C++ base specifier, advancing Idx. |
||
| 256 | CXXBaseSpecifier readCXXBaseSpecifier(); |
||
| 257 | |||
| 258 | /// Read a CXXCtorInitializer array, advancing Idx. |
||
| 259 | CXXCtorInitializer **readCXXCtorInitializers(); |
||
| 260 | |||
| 261 | CXXTemporary *readCXXTemporary() { |
||
| 262 | return Reader->ReadCXXTemporary(*F, Record, Idx); |
||
| 263 | } |
||
| 264 | |||
| 265 | /// Read an OMPTraitInfo object, advancing Idx. |
||
| 266 | OMPTraitInfo *readOMPTraitInfo(); |
||
| 267 | |||
| 268 | /// Read an OpenMP clause, advancing Idx. |
||
| 269 | OMPClause *readOMPClause(); |
||
| 270 | |||
| 271 | /// Read an OpenMP children, advancing Idx. |
||
| 272 | void readOMPChildren(OMPChildren *Data); |
||
| 273 | |||
| 274 | /// Read a source location, advancing Idx. |
||
| 275 | SourceLocation readSourceLocation(LocSeq *Seq = nullptr) { |
||
| 276 | return Reader->ReadSourceLocation(*F, Record, Idx, Seq); |
||
| 277 | } |
||
| 278 | |||
| 279 | /// Read a source range, advancing Idx. |
||
| 280 | SourceRange readSourceRange(LocSeq *Seq = nullptr) { |
||
| 281 | return Reader->ReadSourceRange(*F, Record, Idx, Seq); |
||
| 282 | } |
||
| 283 | |||
| 284 | /// Read an arbitrary constant value, advancing Idx. |
||
| 285 | // APValue readAPValue(); (inherited) |
||
| 286 | |||
| 287 | /// Read an integral value, advancing Idx. |
||
| 288 | // llvm::APInt readAPInt(); (inherited) |
||
| 289 | |||
| 290 | /// Read a signed integral value, advancing Idx. |
||
| 291 | // llvm::APSInt readAPSInt(); (inherited) |
||
| 292 | |||
| 293 | /// Read a floating-point value, advancing Idx. |
||
| 294 | llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem); |
||
| 295 | |||
| 296 | /// Read a boolean value, advancing Idx. |
||
| 297 | bool readBool() { return readInt() != 0; } |
||
| 298 | |||
| 299 | /// Read a 32-bit unsigned value; required to satisfy BasicReader. |
||
| 300 | uint32_t readUInt32() { |
||
| 301 | return uint32_t(readInt()); |
||
| 302 | } |
||
| 303 | |||
| 304 | /// Read a 64-bit unsigned value; required to satisfy BasicReader. |
||
| 305 | uint64_t readUInt64() { |
||
| 306 | return readInt(); |
||
| 307 | } |
||
| 308 | |||
| 309 | /// Read a string, advancing Idx. |
||
| 310 | std::string readString() { |
||
| 311 | return Reader->ReadString(Record, Idx); |
||
| 312 | } |
||
| 313 | |||
| 314 | /// Read a path, advancing Idx. |
||
| 315 | std::string readPath() { |
||
| 316 | return Reader->ReadPath(*F, Record, Idx); |
||
| 317 | } |
||
| 318 | |||
| 319 | /// Read a version tuple, advancing Idx. |
||
| 320 | VersionTuple readVersionTuple() { |
||
| 321 | return ASTReader::ReadVersionTuple(Record, Idx); |
||
| 322 | } |
||
| 323 | |||
| 324 | /// Reads one attribute from the current stream position, advancing Idx. |
||
| 325 | Attr *readAttr(); |
||
| 326 | |||
| 327 | /// Reads attributes from the current stream position, advancing Idx. |
||
| 328 | void readAttributes(AttrVec &Attrs); |
||
| 329 | |||
| 330 | /// Read an BTFTypeTagAttr object. |
||
| 331 | BTFTypeTagAttr *readBTFTypeTagAttr() { |
||
| 332 | return cast<BTFTypeTagAttr>(readAttr()); |
||
| 333 | } |
||
| 334 | |||
| 335 | /// Reads a token out of a record, advancing Idx. |
||
| 336 | Token readToken() { |
||
| 337 | return Reader->ReadToken(*F, Record, Idx); |
||
| 338 | } |
||
| 339 | |||
| 340 | void recordSwitchCaseID(SwitchCase *SC, unsigned ID) { |
||
| 341 | Reader->RecordSwitchCaseID(SC, ID); |
||
| 342 | } |
||
| 343 | |||
| 344 | /// Retrieve the switch-case statement with the given ID. |
||
| 345 | SwitchCase *getSwitchCaseWithID(unsigned ID) { |
||
| 346 | return Reader->getSwitchCaseWithID(ID); |
||
| 347 | } |
||
| 348 | }; |
||
| 349 | |||
| 350 | /// Helper class that saves the current stream position and |
||
| 351 | /// then restores it when destroyed. |
||
| 352 | struct SavedStreamPosition { |
||
| 353 | explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor) |
||
| 354 | : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {} |
||
| 355 | |||
| 356 | ~SavedStreamPosition() { |
||
| 357 | if (llvm::Error Err = Cursor.JumpToBit(Offset)) |
||
| 358 | llvm::report_fatal_error( |
||
| 359 | llvm::Twine("Cursor should always be able to go back, failed: ") + |
||
| 360 | toString(std::move(Err))); |
||
| 361 | } |
||
| 362 | |||
| 363 | private: |
||
| 364 | llvm::BitstreamCursor &Cursor; |
||
| 365 | uint64_t Offset; |
||
| 366 | }; |
||
| 367 | |||
| 368 | inline void PCHValidator::Error(const char *Msg) { |
||
| 369 | Reader.Error(Msg); |
||
| 370 | } |
||
| 371 | |||
| 372 | } // namespace clang |
||
| 373 | |||
| 374 | #endif |