Skip to content

Commit

Permalink
Add a class ASTRecordReader which wraps an ASTReader, a RecordData, a…
Browse files Browse the repository at this point in the history
…nd ModuleFile.

Summary:
When reading an ASTRecord, each RecordData is logically contained within a
single ModuleFile, and global(er) state is contained by a single ASTReader. This
means that any operations that read from a RecordData and reference an ASTReader
or a ModuleFile, will always reference the same ASTReader or ModuleFile.
ASTRecordReader groups these together so that parameters don't need to be
duplicated ad infinitum. Most uses of the Idx variable seem to be redunant
aliases as well, but I'll leave that for now.

Reviewers: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D27784

llvm-svn: 289870
  • Loading branch information
dlj-NaN committed Dec 15, 2016
1 parent 1aa3ef9 commit c4808b9
Show file tree
Hide file tree
Showing 4 changed files with 1,655 additions and 1,449 deletions.
279 changes: 277 additions & 2 deletions clang/include/clang/Serialization/ASTReader.h
Expand Up @@ -356,14 +356,15 @@ class ASTReader
/// \brief The AST file has errors.
HadErrors
};

/// \brief Types of AST files.
friend class PCHValidator;
friend class ASTDeclReader;
friend class ASTStmtReader;
friend class ASTIdentifierIterator;
friend class serialization::reader::ASTIdentifierLookupTrait;
friend class TypeLocReader;
friend class ASTRecordReader;
friend class ASTWriter;
friend class ASTUnit; // ASTUnit needs to remap source locations.
friend class serialization::ReadMethodPoolVisitor;
Expand Down Expand Up @@ -1939,7 +1940,7 @@ class ASTReader
/// number.
serialization::SubmoduleID
getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID);

/// \brief Retrieve the submodule that corresponds to a global submodule ID.
///
Module *getSubmodule(serialization::SubmoduleID GlobalID);
Expand Down Expand Up @@ -2183,6 +2184,280 @@ class ASTReader
bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
};

/// \brief An object for streaming information from a record.
class ASTRecordReader {
typedef serialization::ModuleFile ModuleFile;

ASTReader *Reader;
const ASTReader::RecordData *Record;
ModuleFile *F;

typedef ASTReader::RecordData RecordData;
typedef ASTReader::RecordDataImpl RecordDataImpl;

public:
/// Construct an ASTRecordReader that uses the default encoding scheme.
ASTRecordReader(ASTReader &Reader, const ASTReader::RecordData &Record,
ModuleFile& F)
: Reader(&Reader), Record(&Record), F(&F) {}

/// Construct an ASTRecordReader that uses the same encoding scheme as another
/// ASTRecordReader.
ASTRecordReader(ASTRecordReader &Parent)
: Reader(Parent.Reader), Record(Parent.Record), F(Parent.F) {}

/// \brief The length of this record.
size_t size() const { return Record->size(); }
/// \brief An arbitrary index in this record.
const uint64_t &operator[](size_t N) { return (*Record)[N]; }
/// \brief The last element in this record.
const uint64_t &back() const { return Record->back(); }

/// \brief Is this a module file for a module (rather than a PCH or similar).
bool isModule() const { return F->isModule(); }

/// \brief Retrieve the AST context that this AST reader supplements.
ASTContext &getContext() { return Reader->getContext(); }

/// \brief Retrieve the global submodule ID its local ID number.
serialization::SubmoduleID
getGlobalSubmoduleID(unsigned LocalID) {
return Reader->getGlobalSubmoduleID(*F, LocalID);
}

/// \brief Retrieve the submodule that corresponds to a global submodule ID.
Module *getSubmodule(serialization::SubmoduleID GlobalID) {
return Reader->getSubmodule(GlobalID);
}

/// \brief Read the record that describes the lexical contents of a DC.
bool ReadLexicalDeclContextStorage(uint64_t Offset, DeclContext *DC) {
return Reader->ReadLexicalDeclContextStorage(*F, F->DeclsCursor, Offset,
DC);
}

/// \brief Read the record that describes the visible contents of a DC.
bool ReadVisibleDeclContextStorage(uint64_t Offset,
serialization::DeclID ID) {
return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset,
ID);
}

void readExceptionSpec(SmallVectorImpl<QualType> &ExceptionStorage,
FunctionProtoType::ExceptionSpecInfo &ESI,
unsigned &Index) {
return Reader->readExceptionSpec(*F, ExceptionStorage, ESI, *Record, Index);
}

/// \brief Get the global offset corresponding to a local offset.
uint64_t getGlobalBitOffset(uint32_t LocalOffset) {
return Reader->getGlobalBitOffset(*F, LocalOffset);
}

/// \brief Reads a statement.
Stmt *ReadStmt() { return Reader->ReadStmt(*F); }

/// \brief Reads an expression.
Expr *ReadExpr() { return Reader->ReadExpr(*F); }

/// \brief Reads a sub-statement operand during statement reading.
Stmt *ReadSubStmt() { return Reader->ReadSubStmt(); }

/// \brief Reads a sub-expression operand during statement reading.
Expr *ReadSubExpr() { return Reader->ReadSubExpr(); }

/// \brief Reads a TemplateArgumentLocInfo appropriate for the
/// given TemplateArgument kind, advancing Idx.
TemplateArgumentLocInfo
GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, unsigned &Idx) {
return Reader->GetTemplateArgumentLocInfo(*F, Kind, *Record, Idx);
}

/// \brief Reads a TemplateArgumentLoc, advancing Idx.
TemplateArgumentLoc
ReadTemplateArgumentLoc(unsigned &Idx) {
return Reader->ReadTemplateArgumentLoc(*F, *Record, Idx);
}

const ASTTemplateArgumentListInfo*
ReadASTTemplateArgumentListInfo(unsigned &Idx) {
return Reader->ReadASTTemplateArgumentListInfo(*F, *Record, Idx);
}

/// \brief Reads a declarator info from the given record, advancing Idx.
TypeSourceInfo *GetTypeSourceInfo(unsigned &Idx) {
return Reader->GetTypeSourceInfo(*F, *Record, Idx);
}

/// \brief Map a local type ID within a given AST file to a global type ID.
serialization::TypeID getGlobalTypeID(unsigned LocalID) const {
return Reader->getGlobalTypeID(*F, LocalID);
}

/// \brief Read a type from the current position in the record.
QualType readType(unsigned &Idx) {
return Reader->readType(*F, *Record, Idx);
}

/// \brief Reads a declaration ID from the given position in this record.
///
/// \returns The declaration ID read from the record, adjusted to a global ID.
serialization::DeclID ReadDeclID(unsigned &Idx) {
return Reader->ReadDeclID(*F, *Record, Idx);
}

/// \brief Reads a declaration from the given position in a record in the
/// given module, advancing Idx.
Decl *ReadDecl(unsigned &Idx) {
return Reader->ReadDecl(*F, *Record, Idx);
}

/// \brief Reads a declaration from the given position in the record,
/// advancing Idx.
///
/// \returns The declaration read from this location, casted to the given
/// result type.
template<typename T>
T *ReadDeclAs(unsigned &Idx) {
return Reader->ReadDeclAs<T>(*F, *Record, Idx);
}

IdentifierInfo *GetIdentifierInfo(unsigned &Idx) {
return Reader->GetIdentifierInfo(*F, *Record, Idx);
}

/// \brief Read a selector from the Record, advancing Idx.
Selector ReadSelector(unsigned &Idx) {
return Reader->ReadSelector(*F, *Record, Idx);
}

/// \brief Read a declaration name, advancing Idx.
DeclarationName ReadDeclarationName(unsigned &Idx) {
return Reader->ReadDeclarationName(*F, *Record, Idx);
}
void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name,
unsigned &Idx) {
return Reader->ReadDeclarationNameLoc(*F, DNLoc, Name, *Record, Idx);
}
void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo, unsigned &Idx) {
return Reader->ReadDeclarationNameInfo(*F, NameInfo, *Record, Idx);
}

void ReadQualifierInfo(QualifierInfo &Info, unsigned &Idx) {
return Reader->ReadQualifierInfo(*F, Info, *Record, Idx);
}

NestedNameSpecifier *ReadNestedNameSpecifier(unsigned &Idx) {
return Reader->ReadNestedNameSpecifier(*F, *Record, Idx);
}

NestedNameSpecifierLoc ReadNestedNameSpecifierLoc(unsigned &Idx) {
return Reader->ReadNestedNameSpecifierLoc(*F, *Record, Idx);
}

/// \brief Read a template name, advancing Idx.
TemplateName ReadTemplateName(unsigned &Idx) {
return Reader->ReadTemplateName(*F, *Record, Idx);
}

/// \brief Read a template argument, advancing Idx.
TemplateArgument ReadTemplateArgument(unsigned &Idx,
bool Canonicalize = false) {
return Reader->ReadTemplateArgument(*F, *Record, Idx, Canonicalize);
}

/// \brief Read a template parameter list, advancing Idx.
TemplateParameterList *ReadTemplateParameterList(unsigned &Idx) {
return Reader->ReadTemplateParameterList(*F, *Record, Idx);
}

/// \brief Read a template argument array, advancing Idx.
void ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
unsigned &Idx, bool Canonicalize = false) {
return Reader->ReadTemplateArgumentList(TemplArgs, *F, *Record, Idx,
Canonicalize);
}

/// \brief Read a UnresolvedSet structure, advancing Idx.
void ReadUnresolvedSet(LazyASTUnresolvedSet &Set, unsigned &Idx) {
return Reader->ReadUnresolvedSet(*F, Set, *Record, Idx);
}

/// \brief Read a C++ base specifier, advancing Idx.
CXXBaseSpecifier ReadCXXBaseSpecifier(unsigned &Idx) {
return Reader->ReadCXXBaseSpecifier(*F, *Record, Idx);
}

/// \brief Read a CXXCtorInitializer array, advancing Idx.
CXXCtorInitializer **ReadCXXCtorInitializers(unsigned &Idx) {
return Reader->ReadCXXCtorInitializers(*F, *Record, Idx);
}

CXXTemporary *ReadCXXTemporary(unsigned &Idx) {
return Reader->ReadCXXTemporary(*F, *Record, Idx);
}

/// \brief Read a source location, advancing Idx.
SourceLocation ReadSourceLocation(unsigned &Idx) {
return Reader->ReadSourceLocation(*F, *Record, Idx);
}

/// \brief Read a source range, advancing Idx.
SourceRange ReadSourceRange(unsigned &Idx) {
return Reader->ReadSourceRange(*F, *Record, Idx);
}

/// \brief Read an integral value, advancing Idx.
llvm::APInt ReadAPInt(unsigned &Idx) {
return Reader->ReadAPInt(*Record, Idx);
}

/// \brief Read a signed integral value, advancing Idx.
llvm::APSInt ReadAPSInt(unsigned &Idx) {
return Reader->ReadAPSInt(*Record, Idx);
}

/// \brief Read a floating-point value, advancing Idx.
llvm::APFloat ReadAPFloat(const llvm::fltSemantics &Sem, unsigned &Idx) {
return Reader->ReadAPFloat(*Record, Sem,Idx);
}

/// \brief Read a string, advancing Idx.
std::string ReadString(unsigned &Idx) {
return Reader->ReadString(*Record, Idx);
}

/// \brief Read a path, advancing Idx.
std::string ReadPath(unsigned &Idx) {
return Reader->ReadPath(*F, *Record, Idx);
}

/// \brief Read a version tuple, advancing Idx.
VersionTuple ReadVersionTuple(unsigned &Idx) {
return ASTReader::ReadVersionTuple(*Record, Idx);
}

/// \brief Reads attributes from the current stream position, advancing Idx.
void ReadAttributes(AttrVec &Attrs, unsigned &Idx) {
return Reader->ReadAttributes(*F, Attrs, *Record, Idx);
}

/// \brief Reads a token out of a record, advancing Idx.
Token ReadToken(unsigned &Idx) {
return Reader->ReadToken(*F, *Record, Idx);
}

void RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
Reader->RecordSwitchCaseID(SC, ID);
}

/// \brief Retrieve the switch-case statement with the given ID.
SwitchCase *getSwitchCaseWithID(unsigned ID) {
return Reader->getSwitchCaseWithID(ID);
}

};

/// \brief Helper class that saves the current stream position and
/// then restores it when destroyed.
struct SavedStreamPosition {
Expand Down

0 comments on commit c4808b9

Please sign in to comment.