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 void readTemplateArgumentListInfo(TemplateArgumentListInfo &Result); 159 160 const ASTTemplateArgumentListInfo* 161 readASTTemplateArgumentListInfo(); 162 163 // Reads a concept reference from the given record. 164 ConceptReference *readConceptReference(); 165 166 /// Reads a declarator info from the given record, advancing Idx. 167 TypeSourceInfo *readTypeSourceInfo(); 168 169 /// Reads the location information for a type. 170 void readTypeLoc(TypeLoc TL, LocSeq *Seq = nullptr); 171 172 /// Map a local type ID within a given AST file to a global type ID. 173 serialization::TypeID getGlobalTypeID(unsigned LocalID) const { 174 return Reader->getGlobalTypeID(*F, LocalID); 175 } 176 177 Qualifiers readQualifiers() { 178 return Qualifiers::fromOpaqueValue(readInt()); 179 } 180 181 /// Read a type from the current position in the record. 182 QualType readType() { 183 return Reader->readType(*F, Record, Idx); 184 } 185 QualType readQualType() { 186 return readType(); 187 } 188 189 /// Reads a declaration ID from the given position in this record. 190 /// 191 /// \returns The declaration ID read from the record, adjusted to a global ID. 192 serialization::DeclID readDeclID() { 193 return Reader->ReadDeclID(*F, Record, Idx); 194 } 195 196 /// Reads a declaration from the given position in a record in the 197 /// given module, advancing Idx. 198 Decl *readDecl() { 199 return Reader->ReadDecl(*F, Record, Idx); 200 } 201 Decl *readDeclRef() { 202 return readDecl(); 203 } 204 205 /// Reads a declaration from the given position in the record, 206 /// advancing Idx. 207 /// 208 /// \returns The declaration read from this location, casted to the given 209 /// result type. 210 template<typename T> 211 T *readDeclAs() { 212 return Reader->ReadDeclAs<T>(*F, Record, Idx); 213 } 214 215 IdentifierInfo *readIdentifier() { 216 return Reader->readIdentifier(*F, Record, Idx); 217 } 218 219 /// Read a selector from the Record, advancing Idx. 220 Selector readSelector() { 221 return Reader->ReadSelector(*F, Record, Idx); 222 } 223 224 /// Read a declaration name, advancing Idx. 225 // DeclarationName readDeclarationName(); (inherited) 226 DeclarationNameLoc readDeclarationNameLoc(DeclarationName Name); 227 DeclarationNameInfo readDeclarationNameInfo(); 228 229 void readQualifierInfo(QualifierInfo &Info); 230 231 /// Return a nested name specifier, advancing Idx. 232 // NestedNameSpecifier *readNestedNameSpecifier(); (inherited) 233 234 NestedNameSpecifierLoc readNestedNameSpecifierLoc(); 235 236 /// Read a template name, advancing Idx. 237 // TemplateName readTemplateName(); (inherited) 238 239 /// Read a template argument, advancing Idx. (inherited) 240 // TemplateArgument readTemplateArgument(); 241 using DataStreamBasicReader::readTemplateArgument; 242 TemplateArgument readTemplateArgument(bool Canonicalize) { 243 TemplateArgument Arg = readTemplateArgument(); 244 if (Canonicalize) { 245 Arg = getContext().getCanonicalTemplateArgument(Arg); 246 } 247 return Arg; 248 } 249 250 /// Read a template parameter list, advancing Idx. 251 TemplateParameterList *readTemplateParameterList(); 252 253 /// Read a template argument array, advancing Idx. 254 void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, 255 bool Canonicalize = false); 256 257 /// Read a UnresolvedSet structure, advancing Idx. 258 void readUnresolvedSet(LazyASTUnresolvedSet &Set); 259 260 /// Read a C++ base specifier, advancing Idx. 261 CXXBaseSpecifier readCXXBaseSpecifier(); 262 263 /// Read a CXXCtorInitializer array, advancing Idx. 264 CXXCtorInitializer **readCXXCtorInitializers(); 265 266 CXXTemporary *readCXXTemporary() { 267 return Reader->ReadCXXTemporary(*F, Record, Idx); 268 } 269 270 /// Read an OMPTraitInfo object, advancing Idx. 271 OMPTraitInfo *readOMPTraitInfo(); 272 273 /// Read an OpenMP clause, advancing Idx. 274 OMPClause *readOMPClause(); 275 276 /// Read an OpenMP children, advancing Idx. 277 void readOMPChildren(OMPChildren *Data); 278 279 /// Read a source location, advancing Idx. 280 SourceLocation readSourceLocation(LocSeq *Seq = nullptr) { 281 return Reader->ReadSourceLocation(*F, Record, Idx, Seq); 282 } 283 284 /// Read a source range, advancing Idx. 285 SourceRange readSourceRange(LocSeq *Seq = nullptr) { 286 return Reader->ReadSourceRange(*F, Record, Idx, Seq); 287 } 288 289 /// Read an arbitrary constant value, advancing Idx. 290 // APValue readAPValue(); (inherited) 291 292 /// Read an integral value, advancing Idx. 293 // llvm::APInt readAPInt(); (inherited) 294 295 /// Read a signed integral value, advancing Idx. 296 // llvm::APSInt readAPSInt(); (inherited) 297 298 /// Read a floating-point value, advancing Idx. 299 llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem); 300 301 /// Read a boolean value, advancing Idx. 302 bool readBool() { return readInt() != 0; } 303 304 /// Read a 32-bit unsigned value; required to satisfy BasicReader. 305 uint32_t readUInt32() { 306 return uint32_t(readInt()); 307 } 308 309 /// Read a 64-bit unsigned value; required to satisfy BasicReader. 310 uint64_t readUInt64() { 311 return readInt(); 312 } 313 314 /// Read a string, advancing Idx. 315 std::string readString() { 316 return Reader->ReadString(Record, Idx); 317 } 318 319 /// Read a path, advancing Idx. 320 std::string readPath() { 321 return Reader->ReadPath(*F, Record, Idx); 322 } 323 324 /// Read a version tuple, advancing Idx. 325 VersionTuple readVersionTuple() { 326 return ASTReader::ReadVersionTuple(Record, Idx); 327 } 328 329 /// Reads one attribute from the current stream position, advancing Idx. 330 Attr *readAttr(); 331 332 /// Reads attributes from the current stream position, advancing Idx. 333 void readAttributes(AttrVec &Attrs); 334 335 /// Read an BTFTypeTagAttr object. 336 BTFTypeTagAttr *readBTFTypeTagAttr() { 337 return cast<BTFTypeTagAttr>(readAttr()); 338 } 339 340 /// Reads a token out of a record, advancing Idx. 341 Token readToken() { 342 return Reader->ReadToken(*F, Record, Idx); 343 } 344 345 void recordSwitchCaseID(SwitchCase *SC, unsigned ID) { 346 Reader->RecordSwitchCaseID(SC, ID); 347 } 348 349 /// Retrieve the switch-case statement with the given ID. 350 SwitchCase *getSwitchCaseWithID(unsigned ID) { 351 return Reader->getSwitchCaseWithID(ID); 352 } 353 }; 354 355 /// Helper class that saves the current stream position and 356 /// then restores it when destroyed. 357 struct SavedStreamPosition { 358 explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor) 359 : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {} 360 361 ~SavedStreamPosition() { 362 if (llvm::Error Err = Cursor.JumpToBit(Offset)) 363 llvm::report_fatal_error( 364 llvm::Twine("Cursor should always be able to go back, failed: ") + 365 toString(std::move(Err))); 366 } 367 368 private: 369 llvm::BitstreamCursor &Cursor; 370 uint64_t Offset; 371 }; 372 373 } // namespace clang 374 375 #endif 376