aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/DeclBase.h30
-rw-r--r--include/clang/Frontend/PCHBitCodes.h9
-rw-r--r--include/clang/Frontend/PCHReader.h7
-rw-r--r--include/clang/Frontend/PCHWriter.h11
4 files changed, 46 insertions, 11 deletions
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 8a07475800..3ff38dc0d5 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -222,11 +222,14 @@ protected:
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
unsigned Access : 2;
friend class CXXClassMemberWrapper;
-
- // PCHLevel - the "level" of precompiled header/AST file from which this
- // declaration was built.
- unsigned PCHLevel : 3;
-
+
+ /// PCHLevel - the "level" of precompiled header/AST file from which this
+ /// declaration was built.
+ unsigned PCHLevel : 2;
+
+ /// PCHChanged - if this declaration has changed since being deserialized
+ bool PCHChanged : 1;
+
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
unsigned IdentifierNamespace : 15;
@@ -243,7 +246,7 @@ protected:
: NextDeclInContext(0), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
- Access(AS_none), PCHLevel(0),
+ Access(AS_none), PCHLevel(0), PCHChanged(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
if (Decl::CollectingStats()) add(DK);
}
@@ -251,7 +254,7 @@ protected:
Decl(Kind DK, EmptyShell Empty)
: NextDeclInContext(0), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
- Access(AS_none), PCHLevel(0),
+ Access(AS_none), PCHLevel(0), PCHChanged(false),
IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
if (Decl::CollectingStats()) add(DK);
}
@@ -358,7 +361,7 @@ public:
unsigned getPCHLevel() const { return PCHLevel; }
/// \brief The maximum PCH level that any declaration may have.
- static const unsigned MaxPCHLevel = 7;
+ static const unsigned MaxPCHLevel = 3;
/// \brief Set the PCH level of this declaration.
void setPCHLevel(unsigned Level) {
@@ -366,6 +369,17 @@ public:
PCHLevel = Level;
}
+ /// \brief Query whether this declaration was changed in a significant way
+ /// since being loaded from a PCH file.
+ ///
+ /// In an epic violation of layering, what is "significant" is entirely
+ /// up to the PCH system, but implemented in AST and Sema.
+ bool isChangedSinceDeserialization() const { return PCHChanged; }
+
+ /// \brief Mark this declaration as having changed since deserialization, or
+ /// reset the flag.
+ void setChangedSinceDeserialization(bool Changed) { PCHChanged = Changed; }
+
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 7605670f0e..bce5c287e7 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -256,7 +256,14 @@ namespace clang {
WEAK_UNDECLARED_IDENTIFIERS = 31,
/// \brief Record code for pending implicit instantiations.
- PENDING_IMPLICIT_INSTANTIATIONS = 32
+ PENDING_IMPLICIT_INSTANTIATIONS = 32,
+
+ /// \brief Record code for a decl replacement block.
+ ///
+ /// If a declaration is modified after having been deserialized, and then
+ /// written to a dependent PCH file, its ID and offset must be added to
+ /// the replacement block.
+ DECL_REPLACEMENTS = 33
};
/// \brief Record types used within a source manager block.
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index 7be86050ab..906e3e1b22 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -321,6 +321,11 @@ private:
/// = I + 1 has already been loaded.
std::vector<Decl *> DeclsLoaded;
+ typedef llvm::DenseMap<pch::DeclID, std::pair<PerFileData *, uint64_t> >
+ DeclReplacementMap;
+ /// \brief Declarations that have been replaced in a later file in the chain.
+ DeclReplacementMap ReplacedDecls;
+
/// \brief Information about the contents of a DeclContext.
struct DeclContextInfo {
llvm::BitstreamCursor *Stream;
@@ -577,7 +582,7 @@ private:
RecordLocation TypeCursorForIndex(unsigned Index);
void LoadedDecl(unsigned Index, Decl *D);
Decl *ReadDeclRecord(unsigned Index, pch::DeclID ID);
- RecordLocation DeclCursorForIndex(unsigned Index);
+ RecordLocation DeclCursorForIndex(unsigned Index, pch::DeclID ID);
void PassInterestingDeclsToConsumer();
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index 11422b4ba2..bb083eaf8f 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -227,10 +227,18 @@ private:
/// to this set, so that we can write out lexical content updates for it.
llvm::SmallPtrSet<const NamespaceDecl *, 16> UpdatedNamespaces;
+ /// \brief Decls that have been replaced in the current dependent PCH.
+ ///
+ /// When a decl changes fundamentally after being deserialized (this shouldn't
+ /// happen, but the ObjC AST nodes are designed this way), it will be
+ /// serialized again. In this case, it is registered here, so that the reader
+ /// knows to read the updated version.
+ llvm::SmallVector<std::pair<pch::DeclID, uint64_t>, 16> ReplacedDecls;
+
/// \brief Statements that we've encountered while serializing a
/// declaration or type.
llvm::SmallVector<Stmt *, 16> StmtsToEmit;
-
+
/// \brief Statements collection to use for PCHWriter::AddStmt().
/// It will point to StmtsToEmit unless it is overriden.
llvm::SmallVector<Stmt *, 16> *CollectedStmts;
@@ -274,6 +282,7 @@ private:
void WriteReferencedSelectorsPool(Sema &SemaRef);
void WriteIdentifierTable(Preprocessor &PP);
void WriteAttributeRecord(const Attr *Attr);
+ void WriteDeclUpdateBlock();
unsigned ParmVarDeclAbbrev;
unsigned DeclContextLexicalAbbrev;