354 changes: 2 additions & 352 deletions clang/include/clang/Serialization/ASTReader.h

Large diffs are not rendered by default.

351 changes: 351 additions & 0 deletions clang/include/clang/Serialization/ASTRecordReader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,351 @@
//===- ASTRecordReader.h - Helper classes for reading AST -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines classes that are useful in the implementation of
// the ASTReader.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H
#define LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H

#include "clang/AST/AbstractBasicReader.h"
#include "clang/Lex/Token.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"

namespace clang {

/// An object for streaming information from a record.
class ASTRecordReader
: public serialization::DataStreamBasicReader<ASTRecordReader> {
using ModuleFile = serialization::ModuleFile;

ASTReader *Reader;
ModuleFile *F;
unsigned Idx = 0;
ASTReader::RecordData Record;

using RecordData = ASTReader::RecordData;
using RecordDataImpl = ASTReader::RecordDataImpl;

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

/// Reads a record with id AbbrevID from Cursor, resetting the
/// internal state.
Expected<unsigned> readRecord(llvm::BitstreamCursor &Cursor,
unsigned AbbrevID);

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

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

/// The current position in this record.
unsigned getIdx() const { return Idx; }

/// The length of this record.
size_t size() const { return Record.size(); }

/// An arbitrary index in this record.
const uint64_t &operator[](size_t N) { return Record[N]; }

/// Returns the last value in this record.
uint64_t back() { return Record.back(); }

/// Returns the current value in this record, and advances to the
/// next value.
uint64_t readInt() { return Record[Idx++]; }

ArrayRef<uint64_t> readIntArray(unsigned Len) {
auto Array = llvm::makeArrayRef(Record).slice(Idx, Len);
Idx += Len;
return Array;
}

/// Returns the current value in this record, without advancing.
uint64_t peekInt() { return Record[Idx]; }

/// Skips the specified number of values.
void skipInts(unsigned N) { Idx += N; }

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

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

/// 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);
}

/// 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);
}

ExplicitSpecifier readExplicitSpec() {
uint64_t Kind = readInt();
bool HasExpr = Kind & 0x1;
Kind = Kind >> 1;
return ExplicitSpecifier(HasExpr ? readExpr() : nullptr,
static_cast<ExplicitSpecKind>(Kind));
}

/// Read information about an exception specification (inherited).
//FunctionProtoType::ExceptionSpecInfo
//readExceptionSpecInfo(SmallVectorImpl<QualType> &ExceptionStorage);

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

/// Reads a statement.
Stmt *readStmt() { return Reader->ReadStmt(*F); }
Stmt *readStmtRef() { return readStmt(); /* FIXME: readSubStmt? */ }

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

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

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

/// Reads a declaration with the given local ID in the given module.
///
/// \returns The requested declaration, casted to the given return type.
template<typename T>
T *GetLocalDeclAs(uint32_t LocalID) {
return cast_or_null<T>(Reader->GetLocalDecl(*F, LocalID));
}

/// Reads a TemplateArgumentLocInfo appropriate for the
/// given TemplateArgument kind, advancing Idx.
TemplateArgumentLocInfo
readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind);

/// Reads a TemplateArgumentLoc, advancing Idx.
TemplateArgumentLoc readTemplateArgumentLoc();

const ASTTemplateArgumentListInfo*
readASTTemplateArgumentListInfo();

/// Reads a declarator info from the given record, advancing Idx.
TypeSourceInfo *readTypeSourceInfo();

/// Reads the location information for a type.
void readTypeLoc(TypeLoc TL);


/// 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);
}

Qualifiers readQualifiers() {
return Qualifiers::fromOpaqueValue(readInt());
}

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

/// 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() {
return Reader->ReadDeclID(*F, Record, Idx);
}

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

/// 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() {
return Reader->ReadDeclAs<T>(*F, Record, Idx);
}

IdentifierInfo *readIdentifier() {
return Reader->readIdentifier(*F, Record, Idx);
}

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

/// Read a declaration name, advancing Idx.
// DeclarationName readDeclarationName(); (inherited)
DeclarationNameLoc readDeclarationNameLoc(DeclarationName Name);
DeclarationNameInfo readDeclarationNameInfo();

void readQualifierInfo(QualifierInfo &Info);

/// Return a nested name specifier, advancing Idx.
// NestedNameSpecifier *readNestedNameSpecifier(); (inherited)

NestedNameSpecifierLoc readNestedNameSpecifierLoc();

/// Read a template name, advancing Idx.
// TemplateName readTemplateName(); (inherited)

/// Read a template argument, advancing Idx. (inherited)
// TemplateArgument readTemplateArgument(bool Canonicalize = false);

/// Read a template parameter list, advancing Idx.
TemplateParameterList *readTemplateParameterList();

/// Read a template argument array, advancing Idx.
void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs,
bool Canonicalize = false);

/// Read a UnresolvedSet structure, advancing Idx.
void readUnresolvedSet(LazyASTUnresolvedSet &Set);

/// Read a C++ base specifier, advancing Idx.
CXXBaseSpecifier readCXXBaseSpecifier();

/// Read a CXXCtorInitializer array, advancing Idx.
CXXCtorInitializer **readCXXCtorInitializers();

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

/// Read an OpenMP clause, advancing Idx.
OMPClause *readOMPClause();

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

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

/// Read an arbitrary constant value, advancing Idx.
APValue readAPValue();

/// Read an integral value, advancing Idx.
// llvm::APInt readAPInt(); (inherited)

/// Read a signed integral value, advancing Idx.
// llvm::APSInt readAPSInt(); (inherited)

/// Read a floating-point value, advancing Idx.
llvm::APFloat readAPFloat(const llvm::fltSemantics &Sem);

/// Read a boolean value, advancing Idx.
bool readBool() { return readInt() != 0; }

/// Read a 32-bit unsigned value; required to satisfy BasicReader.
uint32_t readUInt32() {
return uint32_t(readInt());
}

/// Read a 64-bit unsigned value; required to satisfy BasicReader.
uint64_t readUInt64() {
return readInt();
}

/// Read a string, advancing Idx.
std::string readString() {
return Reader->ReadString(Record, Idx);
}

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

/// Read a version tuple, advancing Idx.
VersionTuple readVersionTuple() {
return ASTReader::ReadVersionTuple(Record, Idx);
}

/// Reads one attribute from the current stream position, advancing Idx.
Attr *readAttr();

/// Reads attributes from the current stream position, advancing Idx.
void readAttributes(AttrVec &Attrs);

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

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

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

/// Helper class that saves the current stream position and
/// then restores it when destroyed.
struct SavedStreamPosition {
explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
: Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {}

~SavedStreamPosition() {
if (llvm::Error Err = Cursor.JumpToBit(Offset))
llvm::report_fatal_error(
"Cursor should always be able to go back, failed: " +
toString(std::move(Err)));
}

private:
llvm::BitstreamCursor &Cursor;
uint64_t Offset;
};

inline void PCHValidator::Error(const char *Msg) {
Reader.Error(Msg);
}

} // namespace clang

#endif
295 changes: 295 additions & 0 deletions clang/include/clang/Serialization/ASTRecordWriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
//===- ASTRecordWriter.h - Helper classes for writing AST -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the ASTRecordWriter class, a helper class useful
// when serializing AST.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H
#define LLVM_CLANG_SERIALIZATION_ASTRECORDWRITER_H

#include "clang/AST/AbstractBasicWriter.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/Serialization/ASTWriter.h"

namespace clang {

class TypeLoc;

/// An object for streaming information to a record.
class ASTRecordWriter
: public serialization::DataStreamBasicWriter<ASTRecordWriter> {
ASTWriter *Writer;
ASTWriter::RecordDataImpl *Record;

/// Statements that we've encountered while serializing a
/// declaration or type.
SmallVector<Stmt *, 16> StmtsToEmit;

/// Indices of record elements that describe offsets within the
/// bitcode. These will be converted to offsets relative to the current
/// record when emitted.
SmallVector<unsigned, 8> OffsetIndices;

/// Flush all of the statements and expressions that have
/// been added to the queue via AddStmt().
void FlushStmts();
void FlushSubStmts();

void PrepareToEmit(uint64_t MyOffset) {
// Convert offsets into relative form.
for (unsigned I : OffsetIndices) {
auto &StoredOffset = (*Record)[I];
assert(StoredOffset < MyOffset && "invalid offset");
if (StoredOffset)
StoredOffset = MyOffset - StoredOffset;
}
OffsetIndices.clear();
}

public:
/// Construct a ASTRecordWriter that uses the default encoding scheme.
ASTRecordWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
: Writer(&Writer), Record(&Record) {}

/// Construct a ASTRecordWriter that uses the same encoding scheme as another
/// ASTRecordWriter.
ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record)
: Writer(Parent.Writer), Record(&Record) {}

/// Copying an ASTRecordWriter is almost certainly a bug.
ASTRecordWriter(const ASTRecordWriter &) = delete;
ASTRecordWriter &operator=(const ASTRecordWriter &) = delete;

/// Extract the underlying record storage.
ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }

/// Minimal vector-like interface.
/// @{
void push_back(uint64_t N) { Record->push_back(N); }
template<typename InputIterator>
void append(InputIterator begin, InputIterator end) {
Record->append(begin, end);
}
bool empty() const { return Record->empty(); }
size_t size() const { return Record->size(); }
uint64_t &operator[](size_t N) { return (*Record)[N]; }
/// @}

/// Emit the record to the stream, followed by its substatements, and
/// return its offset.
// FIXME: Allow record producers to suggest Abbrevs.
uint64_t Emit(unsigned Code, unsigned Abbrev = 0) {
uint64_t Offset = Writer->Stream.GetCurrentBitNo();
PrepareToEmit(Offset);
Writer->Stream.EmitRecord(Code, *Record, Abbrev);
FlushStmts();
return Offset;
}

/// Emit the record to the stream, preceded by its substatements.
uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) {
FlushSubStmts();
PrepareToEmit(Writer->Stream.GetCurrentBitNo());
Writer->Stream.EmitRecord(Code, *Record, Abbrev);
return Writer->Stream.GetCurrentBitNo();
}

/// Add a bit offset into the record. This will be converted into an
/// offset relative to the current record when emitted.
void AddOffset(uint64_t BitOffset) {
OffsetIndices.push_back(Record->size());
Record->push_back(BitOffset);
}

/// Add the given statement or expression to the queue of
/// statements to emit.
///
/// This routine should be used when emitting types and declarations
/// that have expressions as part of their formulation. Once the
/// type or declaration has been written, Emit() will write
/// the corresponding statements just after the record.
void AddStmt(Stmt *S) {
StmtsToEmit.push_back(S);
}
void writeStmtRef(const Stmt *S) {
AddStmt(const_cast<Stmt*>(S));
}

/// Add a definition for the given function to the queue of statements
/// to emit.
void AddFunctionDefinition(const FunctionDecl *FD);

/// Emit a source location.
void AddSourceLocation(SourceLocation Loc) {
return Writer->AddSourceLocation(Loc, *Record);
}
void writeSourceLocation(SourceLocation Loc) {
AddSourceLocation(Loc);
}

/// Emit a source range.
void AddSourceRange(SourceRange Range) {
return Writer->AddSourceRange(Range, *Record);
}

void writeBool(bool Value) {
Record->push_back(Value);
}

void writeUInt32(uint32_t Value) {
Record->push_back(Value);
}

void writeUInt64(uint64_t Value) {
Record->push_back(Value);
}

/// Emit an integral value.
void AddAPInt(const llvm::APInt &Value) {
writeAPInt(Value);
}

/// Emit a signed integral value.
void AddAPSInt(const llvm::APSInt &Value) {
writeAPSInt(Value);
}

/// Emit a floating-point value.
void AddAPFloat(const llvm::APFloat &Value);

/// Emit an APvalue.
void AddAPValue(const APValue &Value);

/// Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II) {
return Writer->AddIdentifierRef(II, *Record);
}
void writeIdentifier(const IdentifierInfo *II) {
AddIdentifierRef(II);
}

/// Emit a Selector (which is a smart pointer reference).
void AddSelectorRef(Selector S);
void writeSelector(Selector sel) {
AddSelectorRef(sel);
}

/// Emit a CXXTemporary.
void AddCXXTemporary(const CXXTemporary *Temp);

/// Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);

/// Emit a set of C++ base specifiers.
void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases);

/// Emit a reference to a type.
void AddTypeRef(QualType T) {
return Writer->AddTypeRef(T, *Record);
}
void writeQualType(QualType T) {
AddTypeRef(T);
}

/// Emits a reference to a declarator info.
void AddTypeSourceInfo(TypeSourceInfo *TInfo);

/// Emits source location information for a type. Does not emit the type.
void AddTypeLoc(TypeLoc TL);

/// Emits a template argument location info.
void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const TemplateArgumentLocInfo &Arg);

/// Emits a template argument location.
void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);

/// Emits an AST template argument list info.
void AddASTTemplateArgumentListInfo(
const ASTTemplateArgumentListInfo *ASTTemplArgList);

/// Emit a reference to a declaration.
void AddDeclRef(const Decl *D) {
return Writer->AddDeclRef(D, *Record);
}
void writeDeclRef(const Decl *D) {
AddDeclRef(D);
}

/// Emit a declaration name.
void AddDeclarationName(DeclarationName Name) {
writeDeclarationName(Name);
}

void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
DeclarationName Name);
void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo);

void AddQualifierInfo(const QualifierInfo &Info);

/// Emit a nested name specifier.
void AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
writeNestedNameSpecifier(NNS);
}

/// Emit a nested name specifier with source-location information.
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);

/// Emit a template name.
void AddTemplateName(TemplateName Name) {
writeTemplateName(Name);
}

/// Emit a template argument.
void AddTemplateArgument(const TemplateArgument &Arg) {
writeTemplateArgument(Arg);
}

/// Emit a template parameter list.
void AddTemplateParameterList(const TemplateParameterList *TemplateParams);

/// Emit a template argument list.
void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs);

/// Emit a UnresolvedSet structure.
void AddUnresolvedSet(const ASTUnresolvedSet &Set);

/// Emit a CXXCtorInitializer array.
void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits);

void AddCXXDefinitionData(const CXXRecordDecl *D);

void writeOMPClause(OMPClause *C);

/// Emit a string.
void AddString(StringRef Str) {
return Writer->AddString(Str, *Record);
}

/// Emit a path.
void AddPath(StringRef Path) {
return Writer->AddPath(Path, *Record);
}

/// Emit a version tuple.
void AddVersionTuple(const VersionTuple &Version) {
return Writer->AddVersionTuple(Version, *Record);
}

// Emit an attribute.
void AddAttr(const Attr *A);

/// Emit a list of attributes.
void AddAttributes(ArrayRef<const Attr*> Attrs);
};

} // end namespace clang

#endif
286 changes: 0 additions & 286 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,9 @@
#ifndef LLVM_CLANG_SERIALIZATION_ASTWRITER_H
#define LLVM_CLANG_SERIALIZATION_ASTWRITER_H

#include "clang/AST/AbstractBasicWriter.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaConsumer.h"
Expand Down Expand Up @@ -80,7 +73,6 @@ class InMemoryModuleCache;
class ModuleFileExtension;
class ModuleFileExtensionWriter;
class NamedDecl;
class NestedNameSpecifier;
class ObjCInterfaceDecl;
class PreprocessingRecord;
class Preprocessor;
Expand Down Expand Up @@ -743,272 +735,6 @@ class ASTWriter : public ASTDeserializationListener,
const RecordDecl *Record) override;
};

/// An object for streaming information to a record.
class ASTRecordWriter
: public serialization::DataStreamBasicWriter<ASTRecordWriter> {
ASTWriter *Writer;
ASTWriter::RecordDataImpl *Record;

/// Statements that we've encountered while serializing a
/// declaration or type.
SmallVector<Stmt *, 16> StmtsToEmit;

/// Indices of record elements that describe offsets within the
/// bitcode. These will be converted to offsets relative to the current
/// record when emitted.
SmallVector<unsigned, 8> OffsetIndices;

/// Flush all of the statements and expressions that have
/// been added to the queue via AddStmt().
void FlushStmts();
void FlushSubStmts();

void PrepareToEmit(uint64_t MyOffset) {
// Convert offsets into relative form.
for (unsigned I : OffsetIndices) {
auto &StoredOffset = (*Record)[I];
assert(StoredOffset < MyOffset && "invalid offset");
if (StoredOffset)
StoredOffset = MyOffset - StoredOffset;
}
OffsetIndices.clear();
}

public:
/// Construct a ASTRecordWriter that uses the default encoding scheme.
ASTRecordWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
: Writer(&Writer), Record(&Record) {}

/// Construct a ASTRecordWriter that uses the same encoding scheme as another
/// ASTRecordWriter.
ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record)
: Writer(Parent.Writer), Record(&Record) {}

/// Copying an ASTRecordWriter is almost certainly a bug.
ASTRecordWriter(const ASTRecordWriter &) = delete;
ASTRecordWriter &operator=(const ASTRecordWriter &) = delete;

/// Extract the underlying record storage.
ASTWriter::RecordDataImpl &getRecordData() const { return *Record; }

/// Minimal vector-like interface.
/// @{
void push_back(uint64_t N) { Record->push_back(N); }
template<typename InputIterator>
void append(InputIterator begin, InputIterator end) {
Record->append(begin, end);
}
bool empty() const { return Record->empty(); }
size_t size() const { return Record->size(); }
uint64_t &operator[](size_t N) { return (*Record)[N]; }
/// @}

/// Emit the record to the stream, followed by its substatements, and
/// return its offset.
// FIXME: Allow record producers to suggest Abbrevs.
uint64_t Emit(unsigned Code, unsigned Abbrev = 0) {
uint64_t Offset = Writer->Stream.GetCurrentBitNo();
PrepareToEmit(Offset);
Writer->Stream.EmitRecord(Code, *Record, Abbrev);
FlushStmts();
return Offset;
}

/// Emit the record to the stream, preceded by its substatements.
uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) {
FlushSubStmts();
PrepareToEmit(Writer->Stream.GetCurrentBitNo());
Writer->Stream.EmitRecord(Code, *Record, Abbrev);
return Writer->Stream.GetCurrentBitNo();
}

/// Add a bit offset into the record. This will be converted into an
/// offset relative to the current record when emitted.
void AddOffset(uint64_t BitOffset) {
OffsetIndices.push_back(Record->size());
Record->push_back(BitOffset);
}

/// Add the given statement or expression to the queue of
/// statements to emit.
///
/// This routine should be used when emitting types and declarations
/// that have expressions as part of their formulation. Once the
/// type or declaration has been written, Emit() will write
/// the corresponding statements just after the record.
void AddStmt(Stmt *S) {
StmtsToEmit.push_back(S);
}
void writeStmtRef(const Stmt *S) {
AddStmt(const_cast<Stmt*>(S));
}

/// Add a definition for the given function to the queue of statements
/// to emit.
void AddFunctionDefinition(const FunctionDecl *FD);

/// Emit a source location.
void AddSourceLocation(SourceLocation Loc) {
return Writer->AddSourceLocation(Loc, *Record);
}
void writeSourceLocation(SourceLocation Loc) {
AddSourceLocation(Loc);
}

/// Emit a source range.
void AddSourceRange(SourceRange Range) {
return Writer->AddSourceRange(Range, *Record);
}

void writeBool(bool Value) {
Record->push_back(Value);
}

void writeUInt32(uint32_t Value) {
Record->push_back(Value);
}

void writeUInt64(uint64_t Value) {
Record->push_back(Value);
}

/// Emit an integral value.
void AddAPInt(const llvm::APInt &Value) {
writeAPInt(Value);
}

/// Emit a signed integral value.
void AddAPSInt(const llvm::APSInt &Value) {
writeAPSInt(Value);
}

/// Emit a floating-point value.
void AddAPFloat(const llvm::APFloat &Value);

/// Emit an APvalue.
void AddAPValue(const APValue &Value);

/// Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II) {
return Writer->AddIdentifierRef(II, *Record);
}
void writeIdentifier(const IdentifierInfo *II) {
AddIdentifierRef(II);
}

/// Emit a Selector (which is a smart pointer reference).
void AddSelectorRef(Selector S);
void writeSelector(Selector sel) {
AddSelectorRef(sel);
}

/// Emit a CXXTemporary.
void AddCXXTemporary(const CXXTemporary *Temp);

/// Emit a C++ base specifier.
void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base);

/// Emit a set of C++ base specifiers.
void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases);

/// Emit a reference to a type.
void AddTypeRef(QualType T) {
return Writer->AddTypeRef(T, *Record);
}
void writeQualType(QualType T) {
AddTypeRef(T);
}

/// Emits a reference to a declarator info.
void AddTypeSourceInfo(TypeSourceInfo *TInfo);

/// Emits source location information for a type. Does not emit the type.
void AddTypeLoc(TypeLoc TL);

/// Emits a template argument location info.
void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
const TemplateArgumentLocInfo &Arg);

/// Emits a template argument location.
void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);

/// Emits an AST template argument list info.
void AddASTTemplateArgumentListInfo(
const ASTTemplateArgumentListInfo *ASTTemplArgList);

/// Emit a reference to a declaration.
void AddDeclRef(const Decl *D) {
return Writer->AddDeclRef(D, *Record);
}
void writeDeclRef(const Decl *D) {
AddDeclRef(D);
}

/// Emit a declaration name.
void AddDeclarationName(DeclarationName Name) {
writeDeclarationName(Name);
}

void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
DeclarationName Name);
void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo);

void AddQualifierInfo(const QualifierInfo &Info);

/// Emit a nested name specifier.
void AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
writeNestedNameSpecifier(NNS);
}

/// Emit a nested name specifier with source-location information.
void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);

/// Emit a template name.
void AddTemplateName(TemplateName Name) {
writeTemplateName(Name);
}

/// Emit a template argument.
void AddTemplateArgument(const TemplateArgument &Arg) {
writeTemplateArgument(Arg);
}

/// Emit a template parameter list.
void AddTemplateParameterList(const TemplateParameterList *TemplateParams);

/// Emit a template argument list.
void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs);

/// Emit a UnresolvedSet structure.
void AddUnresolvedSet(const ASTUnresolvedSet &Set);

/// Emit a CXXCtorInitializer array.
void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer *> CtorInits);

void AddCXXDefinitionData(const CXXRecordDecl *D);

/// Emit a string.
void AddString(StringRef Str) {
return Writer->AddString(Str, *Record);
}

/// Emit a path.
void AddPath(StringRef Path) {
return Writer->AddPath(Path, *Record);
}

/// Emit a version tuple.
void AddVersionTuple(const VersionTuple &Version) {
return Writer->AddVersionTuple(Version, *Record);
}

// Emit an attribute.
void AddAttr(const Attr *A);

/// Emit a list of attributes.
void AddAttributes(ArrayRef<const Attr*> Attrs);
};

/// AST and semantic-analysis consumer that generates a
/// precompiled header from the parsed source code.
class PCHGenerator : public SemaConsumer {
Expand Down Expand Up @@ -1043,18 +769,6 @@ class PCHGenerator : public SemaConsumer {
bool hasEmittedPCH() const { return Buffer->IsComplete; }
};

class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
ASTRecordWriter &Record;

public:
OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {}
#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S);
#include "clang/Basic/OpenMPKinds.def"
void writeClause(OMPClause *C);
void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C);
void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C);
};

} // namespace clang

#endif // LLVM_CLANG_SERIALIZATION_ASTWRITER_H
28 changes: 27 additions & 1 deletion clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTRecordReader.h"
#include "ASTCommon.h"
#include "ASTReaderInternals.h"
#include "clang/AST/AbstractTypeReader.h"
Expand All @@ -30,6 +30,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/ODRHash.h"
#include "clang/AST/RawCommentList.h"
#include "clang/AST/TemplateBase.h"
Expand Down Expand Up @@ -11471,6 +11472,31 @@ Expected<unsigned> ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor,
//// OMPClauseReader implementation
////===----------------------------------------------------------------------===//

// This has to be in namespace clang because it's friended by all
// of the OMP clauses.
namespace clang {

class OMPClauseReader : public OMPClauseVisitor<OMPClauseReader> {
ASTRecordReader &Record;
ASTContext &Context;

public:
OMPClauseReader(ASTRecordReader &Record)
: Record(Record), Context(Record.getContext()) {}

#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C);
#include "clang/Basic/OpenMPKinds.def"
OMPClause *readClause();
void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C);
void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C);
};

} // end namespace clang

OMPClause *ASTRecordReader::readOMPClause() {
return OMPClauseReader(*this).readClause();
}

OMPClause *OMPClauseReader::readClause() {
OMPClause *C = nullptr;
switch (Record.readInt()) {
Expand Down
11 changes: 4 additions & 7 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/IdentifierResolver.h"
#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTRecordReader.h"
#include "clang/Serialization/ContinuousRangeMap.h"
#include "clang/Serialization/ModuleFile.h"
#include "llvm/ADT/DenseMap.h"
Expand Down Expand Up @@ -2630,9 +2630,8 @@ void ASTDeclReader::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
D->setVars(Vars);
SmallVector<OMPClause *, 8> Clauses;
Clauses.reserve(NumClauses);
OMPClauseReader ClauseReader(Record);
for (unsigned I = 0; I != NumClauses; ++I)
Clauses.push_back(ClauseReader.readClause());
Clauses.push_back(Record.readOMPClause());
D->setClauses(Clauses);
}

Expand All @@ -2641,9 +2640,8 @@ void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) {
unsigned NumClauses = D->clauselist_size();
SmallVector<OMPClause *, 8> Clauses;
Clauses.reserve(NumClauses);
OMPClauseReader ClauseReader(Record);
for (unsigned I = 0; I != NumClauses; ++I)
Clauses.push_back(ClauseReader.readClause());
Clauses.push_back(Record.readOMPClause());
D->setClauses(Clauses);
}

Expand Down Expand Up @@ -2674,9 +2672,8 @@ void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
unsigned NumClauses = D->clauselist_size();
SmallVector<OMPClause *, 8> Clauses;
Clauses.reserve(NumClauses);
OMPClauseReader ClauseReader(Record);
for (unsigned I = 0; I != NumClauses; ++I)
Clauses.push_back(ClauseReader.readClause());
Clauses.push_back(Record.readOMPClause());
D->setClauses(Clauses);
}

Expand Down
7 changes: 2 additions & 5 deletions clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//

#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTRecordReader.h"
#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/AttrIterator.h"
Expand Down Expand Up @@ -67,8 +67,6 @@ using namespace serialization;
namespace clang {

class ASTStmtReader : public StmtVisitor<ASTStmtReader> {
friend class OMPClauseReader;

ASTRecordReader &Record;
llvm::BitstreamCursor &DeclsCursor;

Expand Down Expand Up @@ -2026,10 +2024,9 @@ void ASTStmtReader::VisitAsTypeExpr(AsTypeExpr *E) {
void ASTStmtReader::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
E->setLocStart(readSourceLocation());
E->setLocEnd(readSourceLocation());
OMPClauseReader ClauseReader(Record);
SmallVector<OMPClause *, 5> Clauses;
for (unsigned i = 0; i < E->getNumClauses(); ++i)
Clauses.push_back(ClauseReader.readClause());
Clauses.push_back(Record.readOMPClause());
E->setClauses(Clauses);
if (E->hasAssociatedStmt())
E->setAssociatedStmt(Record.readSubStmt());
Expand Down
22 changes: 21 additions & 1 deletion clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

#include "clang/Serialization/ASTWriter.h"
#include "clang/Serialization/ASTRecordWriter.h"
#include "ASTCommon.h"
#include "ASTReaderInternals.h"
#include "MultiOnDiskHashTable.h"
Expand Down Expand Up @@ -6004,6 +6004,26 @@ void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
//// OMPClause Serialization
////===----------------------------------------------------------------------===//

namespace {

class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
ASTRecordWriter &Record;

public:
OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {}
#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S);
#include "clang/Basic/OpenMPKinds.def"
void writeClause(OMPClause *C);
void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C);
void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C);
};

}

void ASTRecordWriter::writeOMPClause(OMPClause *C) {
OMPClauseWriter(*this).writeClause(C);
}

void OMPClauseWriter::writeClause(OMPClause *C) {
Record.push_back(C->getClauseKind());
Visit(C);
Expand Down
11 changes: 4 additions & 7 deletions clang/lib/Serialization/ASTWriterDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "clang/Serialization/ASTRecordWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
Expand Down Expand Up @@ -1818,18 +1818,16 @@ void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
VisitDecl(D);
for (auto *I : D->varlists())
Record.AddStmt(I);
OMPClauseWriter ClauseWriter(Record);
for (OMPClause *C : D->clauselists())
ClauseWriter.writeClause(C);
Record.writeOMPClause(C);
Code = serialization::DECL_OMP_ALLOCATE;
}

void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
Record.push_back(D->clauselist_size());
VisitDecl(D);
OMPClauseWriter ClauseWriter(Record);
for (OMPClause *C : D->clauselists())
ClauseWriter.writeClause(C);
Record.writeOMPClause(C);
Code = serialization::DECL_OMP_REQUIRES;
}

Expand All @@ -1854,9 +1852,8 @@ void ASTDeclWriter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
Record.AddStmt(D->getMapperVarRef());
Record.AddDeclarationName(D->getVarName());
Record.AddDeclRef(D->getPrevDeclInScope());
OMPClauseWriter ClauseWriter(Record);
for (OMPClause *C : D->clauselists())
ClauseWriter.writeClause(C);
Record.writeOMPClause(C);
Code = serialization::DECL_OMP_DECLARE_MAPPER;
}

Expand Down
5 changes: 2 additions & 3 deletions clang/lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
///
//===----------------------------------------------------------------------===//

#include "clang/Serialization/ASTWriter.h"
#include "clang/Serialization/ASTRecordWriter.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
Expand Down Expand Up @@ -1978,9 +1978,8 @@ void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
Record.AddSourceLocation(E->getBeginLoc());
Record.AddSourceLocation(E->getEndLoc());
OMPClauseWriter ClauseWriter(Record);
for (unsigned i = 0; i < E->getNumClauses(); ++i) {
ClauseWriter.writeClause(E->getClause(i));
Record.writeOMPClause(E->getClause(i));
}
if (E->hasAssociatedStmt())
Record.AddStmt(E->getAssociatedStmt());
Expand Down
1 change: 1 addition & 0 deletions clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangStandard.h"
#include "clang/Basic/Stack.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
Expand Down