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