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