aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-07-30 00:29:29 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-07-30 00:29:29 +0000
commitffaab3e2bb13991bb3357e80f14bcae3745b2347 (patch)
treeaba453c66d76494ce04b5495d76ac38b68e2af5c /include/clang
parent3ce9e7d270e7df86c09c8126b4412d55be7c123b (diff)
Make macro weirdness in chained PCH work. This required changing the way PCHReader and PCHWriter are initialized to correctly pick up all initializer. On the upside, this means that there is far less repetition in the dependent PCH now.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109823 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTConsumer.h9
-rw-r--r--include/clang/Basic/IdentifierTable.h48
-rw-r--r--include/clang/Frontend/ASTConsumers.h3
-rw-r--r--include/clang/Frontend/CompilerInstance.h12
-rw-r--r--include/clang/Frontend/PCHDeserializationListener.h4
-rw-r--r--include/clang/Frontend/PCHReader.h11
-rw-r--r--include/clang/Frontend/PCHWriter.h3
7 files changed, 55 insertions, 35 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 06113954fc..b01f6c6001 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -18,9 +18,10 @@ namespace clang {
class ASTContext;
class CXXRecordDecl;
class DeclGroupRef;
- class TagDecl;
class HandleTagDeclDefinition;
+ class PCHDeserializationListener; // layering violation because void* is ugly
class SemaConsumer; // layering violation required for safe SemaConsumer
+ class TagDecl;
class VarDecl;
/// ASTConsumer - This is an abstract interface that should be implemented by
@@ -80,6 +81,12 @@ public:
/// it was actually used.
virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {}
+ /// \brief If the consumer is interested in entities being deserialized from
+ /// PCH, it should return a pointer to a PCHDeserializationListener here.
+ ///
+ /// The return type is void* because PCHDS lives in Frontend.
+ virtual PCHDeserializationListener *GetPCHDeserializationListener() { return 0; }
+
/// PrintStats - If desired, print any statistics.
virtual void PrintStats() {}
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 6b8bcdc52f..c8642a1ac5 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -59,7 +59,9 @@ class IdentifierInfo {
bool IsPoisoned : 1; // True if identifier is poisoned.
bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier".
- // 9 bits left in 32-bit word.
+ bool IsFromPCH : 1; // True if identfier first appeared in a PCH
+ // and wasn't modified since.
+ // 8 bits left in 32-bit word.
void *FETokenInfo; // Managed by the language front-end.
llvm::StringMapEntry<IdentifierInfo*> *Entry;
@@ -125,6 +127,7 @@ public:
NeedsHandleIdentifier = 1;
else
RecomputeNeedsHandleIdentifier();
+ IsFromPCH = false;
}
/// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
@@ -186,6 +189,7 @@ public:
NeedsHandleIdentifier = 1;
else
RecomputeNeedsHandleIdentifier();
+ IsFromPCH = false;
}
/// isPoisoned - Return true if this token has been poisoned.
@@ -213,6 +217,12 @@ public:
/// know that HandleIdentifier will not affect the token.
bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
+ /// isFromPCH - Return true if the identifier in its current state was loaded
+ /// from a PCH file.
+ bool isFromPCH() const { return IsFromPCH; }
+
+ void setIsFromPCH(bool FromPCH = true) { IsFromPCH = FromPCH; }
+
private:
/// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
/// several special (but rare) things to identifiers of various sorts. For
@@ -321,35 +331,33 @@ public:
return get(llvm::StringRef(Name, NameLen));
}
- /// \brief Creates a new IdentifierInfo from the given string.
+ /// \brief Gets an IdentifierInfo for the given name without consulting
+ /// external sources.
///
- /// This is a lower-level version of get() that requires that this
- /// identifier not be known previously and that does not consult an
- /// external source for identifiers. In particular, external
- /// identifier sources can use this routine to build IdentifierInfo
- /// nodes and then introduce additional information about those
- /// identifiers.
- IdentifierInfo &CreateIdentifierInfo(const char *NameStart,
- const char *NameEnd) {
+ /// This is a version of get() meant for external sources that want to
+ /// introduce or modify an identifier. If they called get(), they would
+ /// likely end up in a recursion.
+ IdentifierInfo &getOwn(const char *NameStart, const char *NameEnd) {
llvm::StringMapEntry<IdentifierInfo*> &Entry =
HashTable.GetOrCreateValue(NameStart, NameEnd);
IdentifierInfo *II = Entry.getValue();
- assert(!II && "IdentifierInfo already exists");
+ if (!II) {
- // Lookups failed, make a new IdentifierInfo.
- void *Mem = getAllocator().Allocate<IdentifierInfo>();
- II = new (Mem) IdentifierInfo();
- Entry.setValue(II);
+ // Lookups failed, make a new IdentifierInfo.
+ void *Mem = getAllocator().Allocate<IdentifierInfo>();
+ II = new (Mem) IdentifierInfo();
+ Entry.setValue(II);
- // Make sure getName() knows how to find the IdentifierInfo
- // contents.
- II->Entry = &Entry;
+ // Make sure getName() knows how to find the IdentifierInfo
+ // contents.
+ II->Entry = &Entry;
+ }
return *II;
}
- IdentifierInfo &CreateIdentifierInfo(llvm::StringRef Name) {
- return CreateIdentifierInfo(Name.begin(), Name.end());
+ IdentifierInfo &getOwn(llvm::StringRef Name) {
+ return getOwn(Name.begin(), Name.end());
}
typedef HashTableTy::const_iterator iterator;
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index 2d1df44cc9..0747290358 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -29,7 +29,6 @@ class CodeGenOptions;
class Diagnostic;
class FileManager;
class LangOptions;
-class PCHReader;
class Preprocessor;
class TargetOptions;
@@ -63,7 +62,7 @@ ASTConsumer *CreateDeclContextPrinter();
// times.
ASTConsumer *CreatePCHGenerator(const Preprocessor &PP,
llvm::raw_ostream *OS,
- PCHReader *Chain,
+ bool Chaining,
const char *isysroot = 0);
// Inheritance viewer: for C++ code, creates a graph of the inheritance
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 89df8f584b..4a4d5ae1d4 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -97,9 +97,6 @@ class CompilerInstance {
/// The list of active output files.
std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
- /// The PCH reader. Not owned; the ASTContext owns this.
- PCHReader *Reader;
-
void operator=(const CompilerInstance &); // DO NOT IMPLEMENT
CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT
public:
@@ -503,7 +500,8 @@ public:
/// Create an external AST source to read a PCH file and attach it to the AST
/// context.
void createPCHExternalASTSource(llvm::StringRef Path,
- bool DisablePCHValidation);
+ bool DisablePCHValidation,
+ void *DeserializationListener);
/// Create an external AST source to read a PCH file.
///
@@ -511,10 +509,8 @@ public:
static ExternalASTSource *
createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
bool DisablePCHValidation,
- Preprocessor &PP, ASTContext &Context);
-
- /// Get the PCH reader, if any.
- PCHReader *getPCHReader() { return Reader; }
+ Preprocessor &PP, ASTContext &Context,
+ void *DeserializationListener);
/// Create a code completion consumer using the invocation; note that this
/// will cause the source manager to truncate the input source file at the
diff --git a/include/clang/Frontend/PCHDeserializationListener.h b/include/clang/Frontend/PCHDeserializationListener.h
index fe9c755605..52adda9f3f 100644
--- a/include/clang/Frontend/PCHDeserializationListener.h
+++ b/include/clang/Frontend/PCHDeserializationListener.h
@@ -20,6 +20,7 @@
namespace clang {
class Decl;
+class PCHReader;
class QualType;
class PCHDeserializationListener {
@@ -27,6 +28,9 @@ protected:
virtual ~PCHDeserializationListener() {}
public:
+ /// \brief Tell the listener about the reader.
+ virtual void SetReader(PCHReader *Reader) = 0;
+
/// \brief An identifier was deserialized from the PCH.
virtual void IdentifierRead(pch::IdentID ID, IdentifierInfo *II) = 0;
/// \brief A type was deserialized from the PCH. The ID here has the qualifier
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index 49579dc1b1..8e8cf25fb9 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -645,9 +645,8 @@ public:
Listener.reset(listener);
}
- void setDeserializationListener(PCHDeserializationListener *Listener) {
- DeserializationListener = Listener;
- }
+ /// \brief Set the PCH deserialization listener.
+ void setDeserializationListener(PCHDeserializationListener *Listener);
/// \brief Set the Preprocessor to use.
void setPreprocessor(Preprocessor &pp);
@@ -911,6 +910,12 @@ public:
/// \brief Retrieve the macro definition with the given ID.
MacroDefinition *getMacroDefinition(pch::IdentID ID);
+
+ /// \brief Erase the macro that's bound to the given IdentifierInfo.
+ void EraseMacro(IdentifierInfo *II);
+
+ /// \brief Check if the given macro identifier is built-in.
+ bool isBuiltinMacro(IdentifierInfo *II);
/// \brief Retrieve the AST context that this PCH reader
/// supplements.
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index 90f59cfad9..c143cefccf 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -268,7 +268,7 @@ private:
public:
/// \brief Create a new precompiled header writer that outputs to
/// the given bitstream.
- PCHWriter(llvm::BitstreamWriter &Stream, PCHReader *Chain);
+ PCHWriter(llvm::BitstreamWriter &Stream);
/// \brief Write a precompiled header for the given semantic analysis.
///
@@ -421,6 +421,7 @@ public:
bool hasChain() const { return Chain; }
// PCHDeserializationListener implementation
+ void SetReader(PCHReader *Reader);
void IdentifierRead(pch::IdentID ID, IdentifierInfo *II);
void TypeRead(pch::TypeID ID, QualType T);
void DeclRead(pch::DeclID ID, const Decl *D);