[cfe-commits] r84293 - in /cfe/trunk: include/clang/Frontend/PCHBitCodes.h include/clang/Frontend/PCHWriter.h lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp lib/Frontend/PCHWriterDecl.cpp
Douglas Gregor
dgregor at apple.com
Fri Oct 16 17:13:20 PDT 2009
Author: dgregor
Date: Fri Oct 16 19:13:19 2009
New Revision: 84293
URL: http://llvm.org/viewvc/llvm-project?rev=84293&view=rev
Log:
Merge the "types" and "declarations" blocks in the precompiled header
format, so that we don't end up with multiple declaration and types
blocks. Also, fix a few obscure bugs with PCH loading and generation:
- If the DeclIDs DenseMap reallocates while we are writing a
declaration (due to recursively writing other declarations), we
could end up writing a bad ID to ExternalDefinitions.
- When loading an ArrayLoc (part of DeclaratorInfo), we need to set
the size expression to NULL if no size expression was provided.
PCH -> AST rewriting is still partly broken, unfortunately.
Modified:
cfe/trunk/include/clang/Frontend/PCHBitCodes.h
cfe/trunk/include/clang/Frontend/PCHWriter.h
cfe/trunk/lib/Frontend/PCHReader.cpp
cfe/trunk/lib/Frontend/PCHWriter.cpp
cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=84293&r1=84292&r2=84293&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Fri Oct 16 19:13:19 2009
@@ -86,38 +86,33 @@
PREPROCESSOR_BLOCK_ID,
/// \brief The block containing the definitions of all of the
- /// types used within the PCH file.
- TYPES_BLOCK_ID,
-
- /// \brief The block containing the definitions of all of the
- /// declarations stored in the PCH file.
- DECLS_BLOCK_ID
+ /// types and decls used within the PCH file.
+ DECLTYPES_BLOCK_ID
};
/// \brief Record types that occur within the PCH block itself.
enum PCHRecordTypes {
- /// \brief Offset of each type within the types block.
+ /// \brief Record code for the offsets of each type.
///
/// The TYPE_OFFSET constant describes the record that occurs
- /// within the block identified by TYPE_OFFSETS_BLOCK_ID within
- /// the PCH file. The record itself is an array of offsets that
- /// point into the types block (identified by TYPES_BLOCK_ID in
- /// the PCH file). The index into the array is based on the ID
+ /// within the PCH block. The record itself is an array of offsets that
+ /// point into the declarations and types block (identified by
+ /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
/// of a type. For a given type ID @c T, the lower three bits of
/// @c T are its qualifiers (const, volatile, restrict), as in
/// the QualType class. The upper bits, after being shifted and
/// subtracting NUM_PREDEF_TYPE_IDS, are used to index into the
/// TYPE_OFFSET block to determine the offset of that type's
- /// corresponding record within the TYPES_BLOCK_ID block.
+ /// corresponding record within the DECLTYPES_BLOCK_ID block.
TYPE_OFFSET = 1,
/// \brief Record code for the offsets of each decl.
///
/// The DECL_OFFSET constant describes the record that occurs
- /// within the block identifier by DECL_OFFSETS_BLOCK_ID within
- /// the PCH file. The record itself is an array of offsets that
- /// point into the declarations block (identified by
- /// DECLS_BLOCK_ID). The declaration ID is an index into this
+ /// within the block identified by DECL_OFFSETS_BLOCK_ID within
+ /// the PCH block. The record itself is an array of offsets that
+ /// point into the declarations and types block (identified by
+ /// DECLTYPES_BLOCK_ID). The declaration ID is an index into this
/// record, after subtracting one to account for the use of
/// declaration ID 0 for a NULL declaration pointer. Index 0 is
/// reserved for the translation unit declaration.
@@ -353,8 +348,8 @@
/// \brief Record codes for each kind of type.
///
- /// These constants describe the records that can occur within a
- /// block identified by TYPES_BLOCK_ID in the PCH file. Each
+ /// These constants describe the type records that can occur within a
+ /// block identified by DECLTYPES_BLOCK_ID in the PCH file. Each
/// constant describes a record for a specific type class in the
/// AST.
enum TypeCode {
@@ -444,13 +439,13 @@
/// \brief Record codes for each kind of declaration.
///
- /// These constants describe the records that can occur within a
- /// declarations block (identified by DECLS_BLOCK_ID). Each
+ /// These constants describe the declaration records that can occur within
+ /// a declarations block (identified by DECLS_BLOCK_ID). Each
/// constant describes a record for a specific declaration class
/// in the AST.
enum DeclCode {
/// \brief Attributes attached to a declaration.
- DECL_ATTR = 1,
+ DECL_ATTR = 50,
/// \brief A TranslationUnitDecl record.
DECL_TRANSLATION_UNIT,
/// \brief A TypedefDecl record.
@@ -525,14 +520,14 @@
/// \brief Record codes for each kind of statement or expression.
///
/// These constants describe the records that describe statements
- /// or expressions. These records can occur within either the type
- /// or declaration blocks, so they begin with record values of
- /// 50. Each constant describes a record for a specific
- /// statement or expression class in the AST.
+ /// or expressions. These records occur within type and declarations
+ /// block, so they begin with record values of 100. Each constant
+ /// describes a record for a specific statement or expression class in the
+ /// AST.
enum StmtCode {
/// \brief A marker record that indicates that we are at the end
/// of an expression.
- STMT_STOP = 50,
+ STMT_STOP = 100,
/// \brief A NULL expression.
STMT_NULL_PTR,
/// \brief A NullStmt record.
Modified: cfe/trunk/include/clang/Frontend/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHWriter.h?rev=84293&r1=84292&r2=84293&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHWriter.h Fri Oct 16 19:13:19 2009
@@ -73,6 +73,33 @@
/// \brief The bitstream writer used to emit this precompiled header.
llvm::BitstreamWriter &Stream;
+ /// \brief Stores a declaration or a type to be written to the PCH file.
+ class DeclOrType {
+ public:
+ DeclOrType(Decl *D) : Stored(D), IsType(false) { }
+ DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) { }
+
+ bool isType() const { return IsType; }
+ bool isDecl() const { return !IsType; }
+
+ QualType getType() const {
+ assert(isType() && "Not a type!");
+ return QualType::getFromOpaquePtr(Stored);
+ }
+
+ Decl *getDecl() const {
+ assert(isDecl() && "Not a decl!");
+ return static_cast<Decl *>(Stored);
+ }
+
+ private:
+ void *Stored;
+ bool IsType;
+ };
+
+ /// \brief The declarations and types to emit.
+ std::queue<DeclOrType> DeclTypesToEmit;
+
/// \brief Map that provides the ID numbers of each declaration within
/// the output stream.
///
@@ -85,10 +112,6 @@
/// the declaration's ID.
std::vector<uint32_t> DeclOffsets;
- /// \brief Queue containing the declarations that we still need to
- /// emit.
- std::queue<Decl *> DeclsToEmit;
-
/// \brief Map that provides the ID numbers of each type within the
/// output stream.
///
@@ -107,10 +130,6 @@
/// \brief The type ID that will be assigned to the next new type.
pch::TypeID NextTypeID;
- /// \brief Queue containing the types that we still need to
- /// emit.
- std::queue<QualType> TypesToEmit;
-
/// \brief Map that provides the ID numbers of each identifier in
/// the output stream.
///
@@ -189,18 +208,17 @@
void WritePreprocessor(const Preprocessor &PP);
void WriteComments(ASTContext &Context);
void WriteType(QualType T);
- void WriteTypesBlock(ASTContext &Context);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
- void WriteDeclsBlock(ASTContext &Context);
void WriteMethodPool(Sema &SemaRef);
void WriteIdentifierTable(Preprocessor &PP);
void WriteAttributeRecord(const Attr *Attr);
unsigned ParmVarDeclAbbrev;
void WriteDeclsBlockAbbrevs();
-
+ void WriteDecl(ASTContext &Context, Decl *D);
+
public:
/// \brief Create a new precompiled header writer that outputs to
/// the given bitstream.
Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=84293&r1=84292&r2=84293&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Fri Oct 16 19:13:19 2009
@@ -382,7 +382,7 @@
}
Expr *PCHReader::ReadTypeExpr() {
- return dyn_cast_or_null<Expr>(ReadStmt(Stream));
+ return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));
}
@@ -1157,15 +1157,7 @@
if (Code == llvm::bitc::ENTER_SUBBLOCK) {
switch (Stream.ReadSubBlockID()) {
- case pch::TYPES_BLOCK_ID: // Skip types block (lazily loaded)
- default: // Skip unknown content.
- if (Stream.SkipBlock()) {
- Error("malformed block record in PCH file");
- return Failure;
- }
- break;
-
- case pch::DECLS_BLOCK_ID:
+ case pch::DECLTYPES_BLOCK_ID:
// We lazily load the decls block, but we want to set up the
// DeclsCursor cursor to point into it. Clone our current bitcode
// cursor to it, enter the block and read the abbrevs in that block.
@@ -1173,7 +1165,7 @@
DeclsCursor = Stream;
if (Stream.SkipBlock() || // Skip with the main cursor.
// Read the abbrevs.
- ReadBlockAbbrevs(DeclsCursor, pch::DECLS_BLOCK_ID)) {
+ ReadBlockAbbrevs(DeclsCursor, pch::DECLTYPES_BLOCK_ID)) {
Error("malformed block record in PCH file");
return Failure;
}
@@ -1773,15 +1765,15 @@
QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
// Keep track of where we are in the stream, then jump back there
// after reading this type.
- SavedStreamPosition SavedPosition(Stream);
+ SavedStreamPosition SavedPosition(DeclsCursor);
// Note that we are loading a type record.
LoadingTypeOrDecl Loading(*this);
- Stream.JumpToBit(Offset);
+ DeclsCursor.JumpToBit(Offset);
RecordData Record;
- unsigned Code = Stream.ReadCode();
- switch ((pch::TypeCode)Stream.ReadRecord(Code, Record)) {
+ unsigned Code = DeclsCursor.ReadCode();
+ switch ((pch::TypeCode)DeclsCursor.ReadRecord(Code, Record)) {
case pch::TYPE_EXT_QUAL: {
assert(Record.size() == 2 &&
"Incorrect encoding of extended qualifier type");
@@ -2045,6 +2037,8 @@
TyLoc.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
if (Record[Idx++])
TyLoc.setSizeExpr(Reader.ReadDeclExpr());
+ else
+ TyLoc.setSizeExpr(0);
}
DeclaratorInfo *PCHReader::GetDeclaratorInfo(const RecordData &Record,
Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=84293&r1=84292&r2=84293&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Fri Oct 16 19:13:19 2009
@@ -461,8 +461,8 @@
RECORD(PP_MACRO_FUNCTION_LIKE);
RECORD(PP_TOKEN);
- // Types block.
- BLOCK(TYPES_BLOCK);
+ // Decls and Types block.
+ BLOCK(DECLTYPES_BLOCK);
RECORD(TYPE_EXT_QUAL);
RECORD(TYPE_FIXED_WIDTH_INT);
RECORD(TYPE_COMPLEX);
@@ -486,11 +486,6 @@
RECORD(TYPE_OBJC_INTERFACE);
RECORD(TYPE_OBJC_OBJECT_POINTER);
RECORD(TYPE_OBJC_PROTOCOL_LIST);
- // Statements and Exprs can occur in the Types block.
- AddStmtsExprs(Stream, Record);
-
- // Decls block.
- BLOCK(DECLS_BLOCK);
RECORD(DECL_ATTR);
RECORD(DECL_TRANSLATION_UNIT);
RECORD(DECL_TYPEDEF);
@@ -520,7 +515,7 @@
RECORD(DECL_BLOCK);
RECORD(DECL_CONTEXT_LEXICAL);
RECORD(DECL_CONTEXT_VISIBLE);
- // Statements and Exprs can occur in the Decls block.
+ // Statements and Exprs can occur in the Decls and Types block.
AddStmtsExprs(Stream, Record);
#undef RECORD
#undef BLOCK
@@ -1201,22 +1196,6 @@
FlushStmts();
}
-/// \brief Write a block containing all of the types.
-void PCHWriter::WriteTypesBlock(ASTContext &Context) {
- // Enter the types block.
- Stream.EnterSubblock(pch::TYPES_BLOCK_ID, 2);
-
- // Emit all of the types that need to be emitted (so far).
- while (!TypesToEmit.empty()) {
- QualType T = TypesToEmit.front();
- TypesToEmit.pop();
- WriteType(T);
- }
-
- // Exit the types block
- Stream.ExitBlock();
-}
-
//===----------------------------------------------------------------------===//
// Declaration Serialization
//===----------------------------------------------------------------------===//
@@ -1859,7 +1838,7 @@
// The translation unit is the first declaration we'll emit.
DeclIDs[Context.getTranslationUnitDecl()] = 1;
- DeclsToEmit.push(Context.getTranslationUnitDecl());
+ DeclTypesToEmit.push(Context.getTranslationUnitDecl());
// Make sure that we emit IdentifierInfos (and any attached
// declarations) for builtins.
@@ -1928,13 +1907,18 @@
// Keep writing types and declarations until all types and
// declarations have been written.
- do {
- if (!DeclsToEmit.empty())
- WriteDeclsBlock(Context);
- if (!TypesToEmit.empty())
- WriteTypesBlock(Context);
- } while (!(DeclsToEmit.empty() && TypesToEmit.empty()));
-
+ Stream.EnterSubblock(pch::DECLTYPES_BLOCK_ID, 3);
+ WriteDeclsBlockAbbrevs();
+ while (!DeclTypesToEmit.empty()) {
+ DeclOrType DOT = DeclTypesToEmit.front();
+ DeclTypesToEmit.pop();
+ if (DOT.isType())
+ WriteType(DOT.getType());
+ else
+ WriteDecl(Context, DOT.getDecl());
+ }
+ Stream.ExitBlock();
+
WriteMethodPool(SemaRef);
WriteIdentifierTable(PP);
@@ -2068,7 +2052,7 @@
// Assign it a new ID. This is the only time we enqueue a
// qualified type, and it has no CV qualifiers.
ID = NextTypeID++;
- TypesToEmit.push(T);
+ DeclTypesToEmit.push(T);
}
// Encode the type qualifiers in the type reference.
@@ -2122,7 +2106,7 @@
// We haven't seen this type before. Assign it a new ID and put it
// into the queue of types to emit.
ID = NextTypeID++;
- TypesToEmit.push(T);
+ DeclTypesToEmit.push(T);
}
// Encode the type qualifiers in the type reference.
@@ -2140,7 +2124,7 @@
// We haven't seen this declaration before. Give it a new ID and
// enqueue it in the list of declarations to emit.
ID = DeclIDs.size();
- DeclsToEmit.push(const_cast<Decl *>(D));
+ DeclTypesToEmit.push(const_cast<Decl *>(D));
}
Record.push_back(ID);
Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=84293&r1=84292&r2=84293&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Fri Oct 16 19:13:19 2009
@@ -535,80 +535,64 @@
}
}
-/// \brief Write a block containing all of the declarations.
-void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
- // Enter the declarations block.
- Stream.EnterSubblock(pch::DECLS_BLOCK_ID, 3);
-
- // Output the abbreviations that we will use in this block.
- WriteDeclsBlockAbbrevs();
-
- // Emit all of the declarations.
+void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {
RecordData Record;
PCHDeclWriter W(*this, Context, Record);
- while (!DeclsToEmit.empty()) {
- // Pull the next declaration off the queue
- Decl *D = DeclsToEmit.front();
- DeclsToEmit.pop();
-
- // If this declaration is also a DeclContext, write blocks for the
- // declarations that lexically stored inside its context and those
- // declarations that are visible from its context. These blocks
- // are written before the declaration itself so that we can put
- // their offsets into the record for the declaration.
- uint64_t LexicalOffset = 0;
- uint64_t VisibleOffset = 0;
- DeclContext *DC = dyn_cast<DeclContext>(D);
- if (DC) {
- LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
- VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
- }
-
- // Determine the ID for this declaration
- pch::DeclID &ID = DeclIDs[D];
- if (ID == 0)
- ID = DeclIDs.size();
-
- unsigned Index = ID - 1;
-
- // Record the offset for this declaration
- if (DeclOffsets.size() == Index)
- DeclOffsets.push_back(Stream.GetCurrentBitNo());
- else if (DeclOffsets.size() < Index) {
- DeclOffsets.resize(Index+1);
- DeclOffsets[Index] = Stream.GetCurrentBitNo();
- }
-
- // Build and emit a record for this declaration
- Record.clear();
- W.Code = (pch::DeclCode)0;
- W.AbbrevToUse = 0;
- W.Visit(D);
- if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
-
- if (!W.Code) {
- fprintf(stderr, "Cannot serialize declaration of kind %s\n",
- D->getDeclKindName());
- assert(false && "Unhandled declaration kind while generating PCH");
- exit(-1);
- }
- Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
-
- // If the declaration had any attributes, write them now.
- if (D->hasAttrs())
- WriteAttributeRecord(D->getAttrs());
-
- // Flush any expressions that were written as part of this declaration.
- FlushStmts();
-
- // Note "external" declarations so that we can add them to a record in the
- // PCH file later.
- //
- // FIXME: This should be renamed, the predicate is much more complicated.
- if (isRequiredDecl(D, Context))
- ExternalDefinitions.push_back(ID);
+
+ // If this declaration is also a DeclContext, write blocks for the
+ // declarations that lexically stored inside its context and those
+ // declarations that are visible from its context. These blocks
+ // are written before the declaration itself so that we can put
+ // their offsets into the record for the declaration.
+ uint64_t LexicalOffset = 0;
+ uint64_t VisibleOffset = 0;
+ DeclContext *DC = dyn_cast<DeclContext>(D);
+ if (DC) {
+ LexicalOffset = WriteDeclContextLexicalBlock(Context, DC);
+ VisibleOffset = WriteDeclContextVisibleBlock(Context, DC);
+ }
+
+ // Determine the ID for this declaration
+ pch::DeclID &ID = DeclIDs[D];
+ if (ID == 0)
+ ID = DeclIDs.size();
+
+ unsigned Index = ID - 1;
+
+ // Record the offset for this declaration
+ if (DeclOffsets.size() == Index)
+ DeclOffsets.push_back(Stream.GetCurrentBitNo());
+ else if (DeclOffsets.size() < Index) {
+ DeclOffsets.resize(Index+1);
+ DeclOffsets[Index] = Stream.GetCurrentBitNo();
+ }
+
+ // Build and emit a record for this declaration
+ Record.clear();
+ W.Code = (pch::DeclCode)0;
+ W.AbbrevToUse = 0;
+ W.Visit(D);
+ if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
+
+ if (!W.Code) {
+ fprintf(stderr, "Cannot serialize declaration of kind %s\n",
+ D->getDeclKindName());
+ assert(false && "Unhandled declaration kind while generating PCH");
+ exit(-1);
}
+ Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
- // Exit the declarations block
- Stream.ExitBlock();
+ // If the declaration had any attributes, write them now.
+ if (D->hasAttrs())
+ WriteAttributeRecord(D->getAttrs());
+
+ // Flush any expressions that were written as part of this declaration.
+ FlushStmts();
+
+ // Note "external" declarations so that we can add them to a record in the
+ // PCH file later.
+ //
+ // FIXME: This should be renamed, the predicate is much more complicated.
+ if (isRequiredDecl(D, Context))
+ ExternalDefinitions.push_back(Index + 1);
}
More information about the cfe-commits
mailing list