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