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 OpenACCClause; 28 class OMPTraitInfo; 29 class OMPChildren; 30 31 /// An object for streaming information from a record. 32 class ASTRecordReader 33 : public serialization::DataStreamBasicReader<ASTRecordReader> { 34 using ModuleFile = serialization::ModuleFile; 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. ASTRecordReader(ASTReader & Reader,ModuleFile & F)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). isModule()55 bool isModule() const { return F->isModule(); } 56 57 /// Retrieve the AST context that this AST reader supplements. getContext()58 ASTContext &getContext() { return Reader->getContext(); } 59 60 /// The current position in this record. getIdx()61 unsigned getIdx() const { return Idx; } 62 63 /// The length of this record. size()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. back()70 uint64_t back() { return Record.back(); } 71 72 /// Returns the current value in this record, and advances to the 73 /// next value. readInt()74 uint64_t readInt() { return Record[Idx++]; } 75 readIntArray(unsigned Len)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. peekInt()83 uint64_t peekInt() { return Record[Idx]; } 84 85 /// Skips the specified number of values. skipInts(unsigned N)86 void skipInts(unsigned N) { Idx += N; } 87 88 /// Retrieve the global submodule ID its local ID number. 89 serialization::SubmoduleID getGlobalSubmoduleID(unsigned LocalID)90 getGlobalSubmoduleID(unsigned LocalID) { 91 return Reader->getGlobalSubmoduleID(*F, LocalID); 92 } 93 94 /// Retrieve the submodule that corresponds to a global submodule ID. getSubmodule(serialization::SubmoduleID GlobalID)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. readLexicalDeclContextStorage(uint64_t Offset,DeclContext * DC)100 bool readLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) { 101 return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset, 102 DC); 103 } 104 readExplicitSpec()105 ExplicitSpecifier readExplicitSpec() { 106 uint64_t Kind = readInt(); 107 bool HasExpr = Kind & 0x1; 108 Kind = Kind >> 1; 109 return ExplicitSpecifier(HasExpr ? readExpr() : nullptr, 110 static_cast<ExplicitSpecKind>(Kind)); 111 } 112 113 /// Read information about an exception specification (inherited). 114 //FunctionProtoType::ExceptionSpecInfo 115 //readExceptionSpecInfo(SmallVectorImpl<QualType> &ExceptionStorage); 116 117 /// Get the global offset corresponding to a local offset. getGlobalBitOffset(uint64_t LocalOffset)118 uint64_t getGlobalBitOffset(uint64_t LocalOffset) { 119 return Reader->getGlobalBitOffset(*F, LocalOffset); 120 } 121 122 /// Reads a statement. readStmt()123 Stmt *readStmt() { return Reader->ReadStmt(*F); } readStmtRef()124 Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ } 125 126 /// Reads an expression. readExpr()127 Expr *readExpr() { return Reader->ReadExpr(*F); } 128 129 /// Reads a sub-statement operand during statement reading. readSubStmt()130 Stmt *readSubStmt() { return Reader->ReadSubStmt(); } 131 132 /// Reads a sub-expression operand during statement reading. readSubExpr()133 Expr *readSubExpr() { return Reader->ReadSubExpr(); } 134 135 /// Reads a declaration with the given local ID in the given module. 136 /// 137 /// \returns The requested declaration, casted to the given return type. GetLocalDeclAs(LocalDeclID LocalID)138 template <typename T> T *GetLocalDeclAs(LocalDeclID LocalID) { 139 return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID)); 140 } 141 142 /// Reads a TemplateArgumentLocInfo appropriate for the 143 /// given TemplateArgument kind, advancing Idx. 144 TemplateArgumentLocInfo 145 readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind); 146 147 /// Reads a TemplateArgumentLoc, advancing Idx. 148 TemplateArgumentLoc readTemplateArgumentLoc(); 149 150 void readTemplateArgumentListInfo(TemplateArgumentListInfo &Result); 151 152 const ASTTemplateArgumentListInfo* 153 readASTTemplateArgumentListInfo(); 154 155 // Reads a concept reference from the given record. 156 ConceptReference *readConceptReference(); 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 /// Map a local type ID within a given AST file to a global type ID. getGlobalTypeID(serialization::TypeID LocalID)165 serialization::TypeID getGlobalTypeID(serialization::TypeID LocalID) const { 166 return Reader->getGlobalTypeID(*F, LocalID); 167 } 168 readQualifiers()169 Qualifiers readQualifiers() { 170 return Qualifiers::fromOpaqueValue(readInt()); 171 } 172 173 /// Read a type from the current position in the record. readType()174 QualType readType() { 175 return Reader->readType(*F, Record, Idx); 176 } readQualType()177 QualType readQualType() { 178 return readType(); 179 } 180 181 /// Reads a declaration ID from the given position in this record. 182 /// 183 /// \returns The declaration ID read from the record, adjusted to a global ID. readDeclID()184 GlobalDeclID readDeclID() { return Reader->ReadDeclID(*F, Record, Idx); } 185 186 /// Reads a declaration from the given position in a record in the 187 /// given module, advancing Idx. readDecl()188 Decl *readDecl() { 189 return Reader->ReadDecl(*F, Record, Idx); 190 } readDeclRef()191 Decl *readDeclRef() { 192 return readDecl(); 193 } 194 195 /// Reads a declaration from the given position in the record, 196 /// advancing Idx. 197 /// 198 /// \returns The declaration read from this location, casted to the given 199 /// result type. 200 template<typename T> readDeclAs()201 T *readDeclAs() { 202 return Reader->ReadDeclAs<T>(*F, Record, Idx); 203 } 204 readIdentifier()205 IdentifierInfo *readIdentifier() { 206 return Reader->readIdentifier(*F, Record, Idx); 207 } 208 209 /// Read a selector from the Record, advancing Idx. readSelector()210 Selector readSelector() { 211 return Reader->ReadSelector(*F, Record, Idx); 212 } 213 214 TypeCoupledDeclRefInfo readTypeCoupledDeclRefInfo(); 215 216 SpirvOperand readHLSLSpirvOperand(); 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; readTemplateArgument(bool Canonicalize)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 readCXXTemporary()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 list of Exprs used for a var-list. 274 llvm::SmallVector<Expr *> readOpenACCVarList(); 275 276 /// Read a list of Exprs used for a int-expr-list. 277 llvm::SmallVector<Expr *> readOpenACCIntExprList(); 278 279 /// Read an OpenACC clause, advancing Idx. 280 OpenACCClause *readOpenACCClause(); 281 282 /// Read a list of OpenACC clauses into the passed SmallVector, during 283 /// statement reading. 284 void readOpenACCClauseList(MutableArrayRef<const OpenACCClause *> Clauses); 285 286 void readOpenACCRoutineDeclAttr(OpenACCRoutineDeclAttr *A); 287 288 /// Read a source location, advancing Idx. readSourceLocation()289 SourceLocation readSourceLocation() { 290 return Reader->ReadSourceLocation(*F, Record, Idx); 291 } 292 293 /// Read a source range, advancing Idx. readSourceRange()294 SourceRange readSourceRange() { 295 return Reader->ReadSourceRange(*F, Record, Idx); 296 } 297 298 /// Read an arbitrary constant value, advancing Idx. 299 // APValue readAPValue(); (inherited) 300 301 /// Read an integral value, advancing Idx. 302 // llvm::APInt readAPInt(); (inherited) 303 304 /// Read a signed integral value, advancing Idx. 305 // llvm::APSInt readAPSInt(); (inherited) 306 307 /// Read a floating-point value, advancing Idx. 308 llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem); 309 310 /// Read a boolean value, advancing Idx. readBool()311 bool readBool() { return readInt() != 0; } 312 313 /// Read a 32-bit unsigned value; required to satisfy BasicReader. readUInt32()314 uint32_t readUInt32() { 315 return uint32_t(readInt()); 316 } 317 318 /// Read a 64-bit unsigned value; required to satisfy BasicReader. readUInt64()319 uint64_t readUInt64() { 320 return readInt(); 321 } 322 readUnsignedOrNone()323 UnsignedOrNone readUnsignedOrNone() { 324 return UnsignedOrNone::fromInternalRepresentation(unsigned(readInt())); 325 } 326 327 /// Read a string, advancing Idx. readString()328 std::string readString() { 329 return Reader->ReadString(Record, Idx); 330 } 331 332 /// Read a path, advancing Idx. readPath()333 std::string readPath() { 334 return Reader->ReadPath(*F, Record, Idx); 335 } 336 337 /// Read a version tuple, advancing Idx. readVersionTuple()338 VersionTuple readVersionTuple() { 339 return ASTReader::ReadVersionTuple(Record, Idx); 340 } 341 342 /// Reads one attribute from the current stream position, advancing Idx. 343 Attr *readAttr(); 344 345 /// Reads attributes from the current stream position, advancing Idx. 346 void readAttributes(AttrVec &Attrs); 347 348 /// Read an BTFTypeTagAttr object. readBTFTypeTagAttr()349 BTFTypeTagAttr *readBTFTypeTagAttr() { 350 return cast<BTFTypeTagAttr>(readAttr()); 351 } 352 353 /// Reads a token out of a record, advancing Idx. readToken()354 Token readToken() { 355 return Reader->ReadToken(*F, Record, Idx); 356 } 357 recordSwitchCaseID(SwitchCase * SC,unsigned ID)358 void recordSwitchCaseID(SwitchCase *SC, unsigned ID) { 359 Reader->RecordSwitchCaseID(SC, ID); 360 } 361 362 /// Retrieve the switch-case statement with the given ID. getSwitchCaseWithID(unsigned ID)363 SwitchCase *getSwitchCaseWithID(unsigned ID) { 364 return Reader->getSwitchCaseWithID(ID); 365 } 366 }; 367 368 /// Helper class that saves the current stream position and 369 /// then restores it when destroyed. 370 struct SavedStreamPosition { SavedStreamPositionSavedStreamPosition371 explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor) 372 : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {} 373 ~SavedStreamPositionSavedStreamPosition374 ~SavedStreamPosition() { 375 if (llvm::Error Err = Cursor.JumpToBit(Offset)) 376 llvm::report_fatal_error( 377 llvm::Twine("Cursor should always be able to go back, failed: ") + 378 toString(std::move(Err))); 379 } 380 381 private: 382 llvm::BitstreamCursor &Cursor; 383 uint64_t Offset; 384 }; 385 386 } // namespace clang 387 388 #endif 389