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