r177761 - [PCH/Modules] De/Serialize MacroInfos separately than MacroDirectives.
Argyrios Kyrtzidis
akyrtzi at gmail.com
Fri Mar 22 14:12:58 PDT 2013
Author: akirtzidis
Date: Fri Mar 22 16:12:57 2013
New Revision: 177761
URL: http://llvm.org/viewvc/llvm-project?rev=177761&view=rev
Log:
[PCH/Modules] De/Serialize MacroInfos separately than MacroDirectives.
-Serialize the macro directives history into its own section
-Get rid of the macro updates section
-When de/serializing an identifier from a module, associate only one macro per
submodule that defined+exported it.
Modified:
cfe/trunk/include/clang/Lex/MacroInfo.h
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/include/clang/Serialization/ASTBitCodes.h
cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/include/clang/Serialization/ASTWriter.h
cfe/trunk/lib/Lex/PPDirectives.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Fri Mar 22 16:12:57 2013
@@ -332,7 +332,10 @@ class MacroDirective {
/// If invalid, this macro has not been explicitly given any visibility.
SourceLocation VisibilityLocation;
- /// \brief True if this macro was loaded from an AST file.
+ /// \brief True if the macro directive was loaded from a PCH file.
+ bool IsFromPCH : 1;
+
+ /// \brief True if this macro was imported from a module.
bool IsImported : 1;
/// \brief Whether the macro has public (when described in a module).
@@ -354,14 +357,14 @@ class MacroDirective {
public:
explicit MacroDirective(MacroInfo *MI)
: Info(MI), Previous(0), Loc(MI->getDefinitionLoc()),
- IsImported(false), IsPublic(true), IsHidden(false), IsAmbiguous(false),
- ChangedAfterLoad(false) {
+ IsFromPCH(false), IsImported(false), IsPublic(true), IsHidden(false),
+ IsAmbiguous(false), ChangedAfterLoad(false) {
assert(MI && "MacroInfo is null");
}
MacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported)
: Info(MI), Previous(0), Loc(Loc),
- IsImported(isImported), IsPublic(true), IsHidden(false),
+ IsFromPCH(false), IsImported(isImported), IsPublic(true), IsHidden(false),
IsAmbiguous(false), ChangedAfterLoad(false) {
assert(MI && "MacroInfo is null");
}
@@ -412,7 +415,12 @@ public:
/// public or private within its module.
SourceLocation getVisibilityLocation() const { return VisibilityLocation; }
- /// \brief True if this macro was loaded from an AST file.
+ /// \brief Return true if the macro directive was loaded from a PCH file.
+ bool isFromPCH() const { return IsFromPCH; }
+
+ void setIsFromPCH() { IsFromPCH = true; }
+
+ /// \brief True if this macro was imported from a module.
bool isImported() const { return IsImported; }
/// \brief Determine whether this macro is currently defined (and has not
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Mar 22 16:12:57 2013
@@ -560,11 +560,18 @@ public:
MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
/// \brief Specify a macro for this identifier.
+ void setMacroDirective(IdentifierInfo *II, MacroDirective *MD);
MacroDirective *setMacroDirective(IdentifierInfo *II, MacroInfo *MI,
- SourceLocation Loc, bool isImported);
+ SourceLocation Loc, bool isImported) {
+ MacroDirective *MD = AllocateMacroDirective(MI, Loc, isImported);
+ setMacroDirective(II, MD);
+ return MD;
+ }
MacroDirective *setMacroDirective(IdentifierInfo *II, MacroInfo *MI) {
return setMacroDirective(II, MI, MI->getDefinitionLoc(), false);
}
+ /// \brief Set a MacroDirective that was loaded from a PCH file.
+ void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
/// \brief Add a MacroInfo that was loaded from an AST file.
void addLoadedMacroInfo(IdentifierInfo *II, MacroDirective *MD,
MacroDirective *Hint = 0);
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Mar 22 16:12:57 2013
@@ -129,7 +129,14 @@ namespace clang {
/// \brief An ID number that refers to a macro in an AST file.
typedef uint32_t MacroID;
-
+
+ /// \brief A global ID number that refers to a macro in an AST file.
+ typedef uint32_t GlobalMacroID;
+
+ /// \brief A local to a module ID number that refers to a macro in an
+ /// AST file.
+ typedef uint32_t LocalMacroID;
+
/// \brief The number of predefined macro IDs.
const unsigned int NUM_PREDEF_MACRO_IDS = 1;
@@ -522,9 +529,9 @@ namespace clang {
/// macro definition.
MACRO_OFFSET = 47,
- /// \brief Record of updates for a macro that was modified after
- /// being deserialized.
- MACRO_UPDATES = 48,
+ /// \brief Mapping table from the identifier ID to the offset of the
+ /// macro directive history for the identifier.
+ MACRO_TABLE = 48,
/// \brief Record code for undefined but used functions and variables that
/// need a definition in this TU.
@@ -565,7 +572,10 @@ namespace clang {
/// \brief Describes one token.
/// [PP_TOKEN, SLoc, Length, IdentInfoID, Kind, Flags]
- PP_TOKEN = 3
+ PP_TOKEN = 3,
+
+ /// \brief The macro directives history for a particular identifier.
+ PP_MACRO_DIRECTIVE_HISTORY = 4
};
/// \brief Record types used within a preprocessor detail block.
Modified: cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTDeserializationListener.h Fri Mar 22 16:12:57 2013
@@ -23,7 +23,7 @@ class Decl;
class ASTReader;
class QualType;
class MacroDefinition;
-class MacroDirective;
+class MacroInfo;
class Module;
class ASTDeserializationListener {
@@ -39,7 +39,7 @@ public:
virtual void IdentifierRead(serialization::IdentID ID,
IdentifierInfo *II) { }
/// \brief A macro was read from the AST file.
- virtual void MacroRead(serialization::MacroID ID, MacroDirective *MD) { }
+ virtual void MacroRead(serialization::MacroID ID, MacroInfo *MI) { }
/// \brief A type was deserialized from the AST file. The ID here has the
/// qualifier bits already removed, and T is guaranteed to be locally
/// unqualified.
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Mar 22 16:12:57 2013
@@ -430,7 +430,7 @@ private:
/// If the pointer at index I is non-NULL, then it refers to the
/// MacroInfo for the identifier with ID=I+1 that has already
/// been loaded.
- std::vector<MacroDirective *> MacrosLoaded;
+ std::vector<MacroInfo *> MacrosLoaded;
typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>
GlobalMacroMapType;
@@ -564,8 +564,35 @@ private:
/// global method pool for this selector.
llvm::DenseMap<Selector, unsigned> SelectorGeneration;
- typedef llvm::MapVector<IdentifierInfo *,
- SmallVector<serialization::MacroID, 2> >
+ struct PendingMacroInfo {
+ ModuleFile *M;
+
+ struct ModuleMacroDataTy {
+ serialization::GlobalMacroID GMacID;
+ unsigned ImportLoc;
+ };
+ struct PCHMacroDataTy {
+ uint64_t MacroDirectivesOffset;
+ };
+
+ union {
+ ModuleMacroDataTy ModuleMacroData;
+ PCHMacroDataTy PCHMacroData;
+ };
+
+ PendingMacroInfo(ModuleFile *M,
+ serialization::GlobalMacroID GMacID,
+ SourceLocation ImportLoc) : M(M) {
+ ModuleMacroData.GMacID = GMacID;
+ ModuleMacroData.ImportLoc = ImportLoc.getRawEncoding();
+ }
+
+ PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) : M(M) {
+ PCHMacroData.MacroDirectivesOffset = MacroDirectivesOffset;
+ }
+ };
+
+ typedef llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2> >
PendingMacroIDsMap;
/// \brief Mapping from identifiers that have a macro history to the global
@@ -1619,8 +1646,15 @@ public:
serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
unsigned LocalID);
+ void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
+
+ void installPCHMacroDirectives(IdentifierInfo *II,
+ ModuleFile &M, uint64_t Offset);
+
+ void installImportedMacro(IdentifierInfo *II, MacroDirective *MD);
+
/// \brief Retrieve the macro with the given ID.
- MacroDirective *getMacro(serialization::MacroID ID, MacroDirective *Hint = 0);
+ MacroInfo *getMacro(serialization::MacroID ID);
/// \brief Retrieve the global macro ID corresponding to the given local
/// ID within the given module file.
@@ -1779,20 +1813,32 @@ public:
Expr *ReadSubExpr();
/// \brief Reads the macro record located at the given offset.
- void ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroDirective *Hint = 0);
+ MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset);
/// \brief Determine the global preprocessed entity ID that corresponds to
/// the given local ID within the given module.
serialization::PreprocessedEntityID
getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const;
- /// \brief Note that the identifier has a macro history.
+ /// \brief Add a macro to resolve imported from a module.
///
/// \param II The name of the macro.
+ /// \param M The module file.
+ /// \param GMacID The global macro ID that is associated with this identifier.
+ /// \param ImportLoc The location where the module is imported.
+ void addPendingMacroFromModule(IdentifierInfo *II,
+ ModuleFile *M,
+ serialization::GlobalMacroID GMacID,
+ SourceLocation ImportLoc);
+
+ /// \brief Add a macro to deserialize its macro directive history from a PCH.
///
- /// \param IDs The global macro IDs that are associated with this identifier.
- void setIdentifierIsMacro(IdentifierInfo *II,
- ArrayRef<serialization::MacroID> IDs);
+ /// \param II The name of the macro.
+ /// \param M The module file.
+ /// \param MacroDirectivesOffset Offset of the serialized macro directive
+ /// history.
+ void addPendingMacroFromPCH(IdentifierInfo *II,
+ ModuleFile *M, uint64_t MacroDirectivesOffset);
/// \brief Read the set of macros defined by this external macro source.
virtual void ReadDefinedMacros();
Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri Mar 22 16:12:57 2013
@@ -51,10 +51,11 @@ class HeaderSearch;
class HeaderSearchOptions;
class IdentifierResolver;
class MacroDefinition;
+class MacroDirective;
+class MacroInfo;
class OpaqueValueExpr;
class OpenCLOptions;
class ASTReader;
-class MacroDirective;
class Module;
class PreprocessedEntity;
class PreprocessingRecord;
@@ -231,7 +232,17 @@ private:
serialization::MacroID NextMacroID;
/// \brief Map that provides the ID numbers of each macro.
- llvm::DenseMap<MacroDirective *, serialization::MacroID> MacroIDs;
+ llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
+
+ struct MacroInfoToEmitData {
+ const IdentifierInfo *Name;
+ MacroInfo *MI;
+ serialization::MacroID ID;
+ };
+ /// \brief The macro infos to emit.
+ std::vector<MacroInfoToEmitData> MacroInfosToEmit;
+
+ llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap;
/// @name FlushStmt Caches
/// @{
@@ -268,11 +279,6 @@ private:
/// table, indexed by the Selector ID (-1).
std::vector<uint32_t> SelectorOffsets;
- typedef llvm::MapVector<MacroDirective *, MacroUpdate> MacroUpdatesMap;
-
- /// \brief Updates to macro definitions that were loaded from an AST file.
- MacroUpdatesMap MacroUpdates;
-
/// \brief Mapping from macro definitions (as they occur in the preprocessing
/// record) to the macro IDs.
llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID>
@@ -441,7 +447,6 @@ private:
void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
bool IsModule);
void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
- void WriteMacroUpdates();
void ResolveDeclUpdatesBlocks();
void WriteDeclUpdatesBlocks();
void WriteDeclReplacementsBlock();
@@ -512,9 +517,6 @@ public:
/// \brief Emit a reference to an identifier.
void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
- /// \brief Emit a reference to a macro.
- void addMacroRef(MacroDirective *MI, RecordDataImpl &Record);
-
/// \brief Emit a Selector (which is a smart pointer reference).
void AddSelectorRef(Selector, RecordDataImpl &Record);
@@ -533,7 +535,12 @@ public:
serialization::IdentID getIdentifierRef(const IdentifierInfo *II);
/// \brief Get the unique number used to refer to the given macro.
- serialization::MacroID getMacroRef(MacroDirective *MI);
+ serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name);
+
+ /// \brief Determine the ID of an already-emitted macro.
+ serialization::MacroID getMacroID(MacroInfo *MI);
+
+ uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name);
/// \brief Emit a reference to a type.
void AddTypeRef(QualType T, RecordDataImpl &Record);
@@ -700,16 +707,13 @@ public:
// ASTDeserializationListener implementation
void ReaderInitialized(ASTReader *Reader);
void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II);
- void MacroRead(serialization::MacroID ID, MacroDirective *MI);
+ void MacroRead(serialization::MacroID ID, MacroInfo *MI);
void TypeRead(serialization::TypeIdx Idx, QualType T);
void SelectorRead(serialization::SelectorID ID, Selector Sel);
void MacroDefinitionRead(serialization::PreprocessedEntityID ID,
MacroDefinition *MD);
void ModuleRead(serialization::SubmoduleID ID, Module *Mod);
- // PPMutationListener implementation.
- virtual void UndefinedMacro(MacroDirective *MD);
-
// ASTMutationListener implementation.
virtual void CompletedTagDefinition(const TagDecl *D);
virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Mar 22 16:12:57 2013
@@ -1119,23 +1119,26 @@ void Preprocessor::HandleMacroPublicDire
// Check to see if this is the last token on the #__public_macro line.
CheckEndOfDirective("__public_macro");
+ IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
// Okay, we finally have a valid identifier to undef.
- MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo());
+ MacroDirective *MD = getMacroDirective(II);
// If the macro is not defined, this is an error.
if (MD == 0) {
- Diag(MacroNameTok, diag::err_pp_visibility_non_macro)
- << MacroNameTok.getIdentifierInfo();
+ Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
return;
}
// Note that this macro has now been exported.
MD->setVisibility(/*IsPublic=*/true, MacroNameTok.getLocation());
- // If this macro definition came from a PCH file, mark it
- // as having changed since serialization.
- if (MD->isImported())
+ // If this macro directive came from a PCH file, mark it as having changed
+ // since serialization.
+ if (MD->isFromPCH()) {
MD->setChangedAfterLoad();
+ assert(II->isFromAST());
+ II->setChangedSinceDeserialization();
+ }
}
/// \brief Handle a #private directive.
@@ -1150,23 +1153,26 @@ void Preprocessor::HandleMacroPrivateDir
// Check to see if this is the last token on the #__private_macro line.
CheckEndOfDirective("__private_macro");
+ IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
// Okay, we finally have a valid identifier to undef.
- MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo());
+ MacroDirective *MD = getMacroDirective(II);
// If the macro is not defined, this is an error.
if (MD == 0) {
- Diag(MacroNameTok, diag::err_pp_visibility_non_macro)
- << MacroNameTok.getIdentifierInfo();
+ Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
return;
}
// Note that this macro has now been marked private.
MD->setVisibility(/*IsPublic=*/false, MacroNameTok.getLocation());
- // If this macro definition came from a PCH file, mark it
- // as having changed since serialization.
- if (MD->isImported())
+ // If this macro directive came from a PCH file, mark it as having changed
+ // since serialization.
+ if (MD->isFromPCH()) {
MD->setChangedAfterLoad();
+ assert(II->isFromAST());
+ II->setChangedSinceDeserialization();
+ }
}
//===----------------------------------------------------------------------===//
@@ -2011,7 +2017,7 @@ void Preprocessor::HandleUndefDirective(
void Preprocessor::UndefineMacro(IdentifierInfo *II, MacroDirective *MD,
SourceLocation UndefLoc) {
MD->setUndefLoc(UndefLoc);
- if (MD->isImported()) {
+ if (MD->isFromPCH()) {
MD->setChangedAfterLoad();
if (Listener)
Listener->UndefinedMacro(MD);
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Mar 22 16:12:57 2013
@@ -42,20 +42,28 @@ Preprocessor::getMacroDirectiveHistory(c
}
/// \brief Specify a macro for this identifier.
-MacroDirective *
-Preprocessor::setMacroDirective(IdentifierInfo *II, MacroInfo *MI,
- SourceLocation Loc, bool isImported) {
- assert(MI && "MacroInfo should be non-zero!");
+void Preprocessor::setMacroDirective(IdentifierInfo *II, MacroDirective *MD) {
+ assert(MD && "MacroDirective should be non-zero!");
- MacroDirective *MD = AllocateMacroDirective(MI, Loc, isImported);
MacroDirective *&StoredMD = Macros[II];
MD->setPrevious(StoredMD);
StoredMD = MD;
II->setHasMacroDefinition(true);
if (II->isFromAST())
II->setChangedSinceDeserialization();
+}
- return MD;
+void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
+ MacroDirective *MD) {
+ assert(II && MD);
+ MacroDirective *&StoredMD = Macros[II];
+ assert(!StoredMD &&
+ "the macro history was modified before initializing it from a pch");
+ StoredMD = MD;
+ // Setup the identifier as having associated macro history.
+ II->setHasMacroDefinition(true);
+ if (!MD->isDefined())
+ II->setHasMacroDefinition(false);
}
void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroDirective *MD,
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Mar 22 16:12:57 2013
@@ -516,6 +516,8 @@ IdentifierInfo *ASTIdentifierLookupTrait
Bits >>= 1;
bool ExtensionToken = Bits & 0x01;
Bits >>= 1;
+ bool hasSubmoduleMacros = Bits & 0x01;
+ Bits >>= 1;
bool hadMacroDefinition = Bits & 0x01;
Bits >>= 1;
@@ -554,13 +556,26 @@ IdentifierInfo *ASTIdentifierLookupTrait
// If this identifier is a macro, deserialize the macro
// definition.
if (hadMacroDefinition) {
- SmallVector<MacroID, 4> MacroIDs;
- while (uint32_t LocalID = ReadUnalignedLE32(d)) {
- MacroIDs.push_back(Reader.getGlobalMacroID(F, LocalID));
+ uint32_t MacroDirectivesOffset = ReadUnalignedLE32(d);
+ DataLen -= 4;
+ SmallVector<uint32_t, 8> LocalMacroIDs;
+ if (hasSubmoduleMacros) {
+ while (uint32_t LocalMacroID = ReadUnalignedLE32(d)) {
+ DataLen -= 4;
+ LocalMacroIDs.push_back(LocalMacroID);
+ }
DataLen -= 4;
}
- DataLen -= 4;
- Reader.setIdentifierIsMacro(II, MacroIDs);
+
+ if (F.Kind == MK_Module) {
+ for (SmallVectorImpl<uint32_t>::iterator
+ I = LocalMacroIDs.begin(), E = LocalMacroIDs.end(); I != E; ++I) {
+ MacroID MacID = Reader.getGlobalMacroID(F, *I);
+ Reader.addPendingMacroFromModule(II, &F, MacID, F.DirectImportLoc);
+ }
+ } else {
+ Reader.addPendingMacroFromPCH(II, &F, MacroDirectivesOffset);
+ }
}
Reader.SetIdentifierInfo(ID, II);
@@ -1073,8 +1088,7 @@ bool ASTReader::ReadBlockAbbrevs(Bitstre
}
}
-void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset,
- MacroDirective *Hint) {
+MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
BitstreamCursor &Stream = F.MacroCursor;
// Keep track of where we are in the stream, then jump back there
@@ -1086,24 +1100,6 @@ void ASTReader::ReadMacroRecord(ModuleFi
SmallVector<IdentifierInfo*, 16> MacroArgs;
MacroInfo *Macro = 0;
- // RAII object to add the loaded macro information once we're done
- // adding tokens.
- struct AddLoadedMacroInfoRAII {
- Preprocessor &PP;
- MacroDirective *Hint;
- MacroDirective *MD;
- IdentifierInfo *II;
-
- AddLoadedMacroInfoRAII(Preprocessor &PP, MacroDirective *Hint)
- : PP(PP), Hint(Hint), MD(), II() { }
- ~AddLoadedMacroInfoRAII( ) {
- if (MD) {
- // Finally, install the macro.
- PP.addLoadedMacroInfo(II, MD, Hint);
- }
- }
- } AddLoadedMacroInfo(PP, Hint);
-
while (true) {
// Advance to the next record, but if we get to the end of the block, don't
// pop it (removing all the abbreviations from the cursor) since we want to
@@ -1115,9 +1111,9 @@ void ASTReader::ReadMacroRecord(ModuleFi
case llvm::BitstreamEntry::SubBlock: // Handled for us already.
case llvm::BitstreamEntry::Error:
Error("malformed block record in AST file");
- return;
+ return Macro;
case llvm::BitstreamEntry::EndBlock:
- return;
+ return Macro;
case llvm::BitstreamEntry::Record:
// The interesting case.
break;
@@ -1128,47 +1124,24 @@ void ASTReader::ReadMacroRecord(ModuleFi
PreprocessorRecordTypes RecType =
(PreprocessorRecordTypes)Stream.readRecord(Entry.ID, Record);
switch (RecType) {
+ case PP_MACRO_DIRECTIVE_HISTORY:
+ return Macro;
+
case PP_MACRO_OBJECT_LIKE:
case PP_MACRO_FUNCTION_LIKE: {
// If we already have a macro, that means that we've hit the end
// of the definition of the macro we were looking for. We're
// done.
if (Macro)
- return;
-
- IdentifierInfo *II = getLocalIdentifier(F, Record[0]);
- if (II == 0) {
- Error("macro must have a name in AST file");
- return;
- }
+ return Macro;
- unsigned GlobalID = getGlobalMacroID(F, Record[1]);
-
- // If this macro has already been loaded, don't do so again.
- if (MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS])
- return;
-
- SubmoduleID GlobalSubmoduleID = getGlobalSubmoduleID(F, Record[2]);
- unsigned NextIndex = 3;
+ unsigned NextIndex = 1; // Skip identifier ID.
+ SubmoduleID SubModID = getGlobalSubmoduleID(F, Record[NextIndex++]);
SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex);
- MacroInfo *MI = PP.AllocateDeserializedMacroInfo(Loc, GlobalSubmoduleID);
- // FIXME: Location should be import location in case of module.
- MacroDirective *MD = PP.AllocateMacroDirective(MI, Loc,
- /*isImported=*/true);
+ MacroInfo *MI = PP.AllocateDeserializedMacroInfo(Loc, SubModID);
MI->setDefinitionEndLoc(ReadSourceLocation(F, Record, NextIndex));
-
- // Record this macro.
- MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS] = MD;
-
- SourceLocation UndefLoc = ReadSourceLocation(F, Record, NextIndex);
- if (UndefLoc.isValid())
- MD->setUndefLoc(UndefLoc);
-
MI->setIsUsed(Record[NextIndex++]);
- bool IsPublic = Record[NextIndex++];
- MD->setVisibility(IsPublic, ReadSourceLocation(F, Record, NextIndex));
-
if (RecType == PP_MACRO_FUNCTION_LIKE) {
// Decode function-like macro info.
bool isC99VarArgs = Record[NextIndex++];
@@ -1188,61 +1161,6 @@ void ASTReader::ReadMacroRecord(ModuleFi
PP.getPreprocessorAllocator());
}
- if (DeserializationListener)
- DeserializationListener->MacroRead(GlobalID, MD);
-
- // If an update record marked this as undefined, do so now.
- // FIXME: Only if the submodule this update came from is visible?
- MacroUpdatesMap::iterator Update = MacroUpdates.find(GlobalID);
- if (Update != MacroUpdates.end()) {
- if (MD->getUndefLoc().isInvalid()) {
- for (unsigned I = 0, N = Update->second.size(); I != N; ++I) {
- bool Hidden = false;
- if (unsigned SubmoduleID = Update->second[I].first) {
- if (Module *Owner = getSubmodule(SubmoduleID)) {
- if (Owner->NameVisibility == Module::Hidden) {
- // Note that this #undef is hidden.
- Hidden = true;
-
- // Record this hiding for later.
- HiddenNamesMap[Owner].push_back(
- HiddenName(II, MD, Update->second[I].second.UndefLoc));
- }
- }
- }
-
- if (!Hidden) {
- MD->setUndefLoc(Update->second[I].second.UndefLoc);
- if (PPMutationListener *Listener = PP.getPPMutationListener())
- Listener->UndefinedMacro(MD);
- break;
- }
- }
- }
- MacroUpdates.erase(Update);
- }
-
- // Determine whether this macro definition is visible.
- bool Hidden = !MD->isPublic();
- if (!Hidden && GlobalSubmoduleID) {
- if (Module *Owner = getSubmodule(GlobalSubmoduleID)) {
- if (Owner->NameVisibility == Module::Hidden) {
- // The owning module is not visible, and this macro definition
- // should not be, either.
- Hidden = true;
-
- // Note that this macro definition was hidden because its owning
- // module is not yet visible.
- HiddenNamesMap[Owner].push_back(HiddenName(II, MD));
- }
- }
- }
- MD->setHidden(Hidden);
-
- // Make sure we install the macro once we're done.
- AddLoadedMacroInfo.MD = MD;
- AddLoadedMacroInfo.II = II;
-
// Remember that we saw this macro last so that we add the tokens that
// form its body to it.
Macro = MI;
@@ -1381,10 +1299,19 @@ HeaderFileInfoTrait::ReadData(internal_k
return HFI;
}
-void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, ArrayRef<MacroID> IDs){
- II->setHadMacroDefinition(true);
+void ASTReader::addPendingMacroFromModule(IdentifierInfo *II,
+ ModuleFile *M,
+ GlobalMacroID GMacID,
+ SourceLocation ImportLoc) {
assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
- PendingMacroIDs[II].append(IDs.begin(), IDs.end());
+ PendingMacroIDs[II].push_back(PendingMacroInfo(M, GMacID, ImportLoc));
+}
+
+void ASTReader::addPendingMacroFromPCH(IdentifierInfo *II,
+ ModuleFile *M,
+ uint64_t MacroDirectivesOffset) {
+ assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
+ PendingMacroIDs[II].push_back(PendingMacroInfo(M, MacroDirectivesOffset));
}
void ASTReader::ReadDefinedMacros() {
@@ -1526,6 +1453,119 @@ void ASTReader::markIdentifierUpToDate(I
IdentifierGeneration[II] = CurrentGeneration;
}
+void ASTReader::resolvePendingMacro(IdentifierInfo *II,
+ const PendingMacroInfo &PMInfo) {
+ assert(II);
+
+ if (PMInfo.M->Kind != MK_Module) {
+ installPCHMacroDirectives(II, *PMInfo.M,
+ PMInfo.PCHMacroData.MacroDirectivesOffset);
+ return;
+ }
+
+ // Module Macro.
+
+ GlobalMacroID GMacID = PMInfo.ModuleMacroData.GMacID;
+ SourceLocation ImportLoc =
+ SourceLocation::getFromRawEncoding(PMInfo.ModuleMacroData.ImportLoc);
+
+ assert(GMacID);
+ // If this macro has already been loaded, don't do so again.
+ if (MacrosLoaded[GMacID - NUM_PREDEF_MACRO_IDS])
+ return;
+
+ MacroInfo *MI = getMacro(GMacID);
+ SubmoduleID SubModID = MI->getOwningModuleID();
+ MacroDirective *MD = PP.AllocateMacroDirective(MI, ImportLoc,
+ /*isImported=*/true);
+
+ // Determine whether this macro definition is visible.
+ bool Hidden = false;
+ if (SubModID) {
+ if (Module *Owner = getSubmodule(SubModID)) {
+ if (Owner->NameVisibility == Module::Hidden) {
+ // The owning module is not visible, and this macro definition
+ // should not be, either.
+ Hidden = true;
+
+ // Note that this macro definition was hidden because its owning
+ // module is not yet visible.
+ HiddenNamesMap[Owner].push_back(HiddenName(II, MD));
+ }
+ }
+ }
+ MD->setHidden(Hidden);
+
+ if (!Hidden)
+ installImportedMacro(II, MD);
+}
+
+void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,
+ ModuleFile &M, uint64_t Offset) {
+ assert(M.Kind != MK_Module);
+
+ BitstreamCursor &Cursor = M.MacroCursor;
+ SavedStreamPosition SavedPosition(Cursor);
+ Cursor.JumpToBit(Offset);
+
+ llvm::BitstreamEntry Entry =
+ Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
+ if (Entry.Kind != llvm::BitstreamEntry::Record) {
+ Error("malformed block record in AST file");
+ return;
+ }
+
+ RecordData Record;
+ PreprocessorRecordTypes RecType =
+ (PreprocessorRecordTypes)Cursor.readRecord(Entry.ID, Record);
+ if (RecType != PP_MACRO_DIRECTIVE_HISTORY) {
+ Error("malformed block record in AST file");
+ return;
+ }
+
+ // Deserialize the macro directives history in reverse source-order.
+ MacroDirective *Latest = 0, *Earliest = 0;
+ unsigned Idx = 0, N = Record.size();
+ while (Idx < N) {
+ GlobalMacroID GMacID = getGlobalMacroID(M, Record[Idx++]);
+ MacroInfo *MI = getMacro(GMacID);
+ SourceLocation Loc = ReadSourceLocation(M, Record, Idx);
+ SourceLocation UndefLoc = ReadSourceLocation(M, Record, Idx);
+ SourceLocation VisibilityLoc = ReadSourceLocation(M, Record, Idx);
+ bool isImported = Record[Idx++];
+ bool isPublic = Record[Idx++];
+ bool isAmbiguous = Record[Idx++];
+
+ MacroDirective *MD = PP.AllocateMacroDirective(MI, Loc, isImported);
+ if (UndefLoc.isValid())
+ MD->setUndefLoc(UndefLoc);
+ if (VisibilityLoc.isValid())
+ MD->setVisibility(isPublic, VisibilityLoc);
+ MD->setAmbiguous(isAmbiguous);
+ MD->setIsFromPCH();
+
+ if (!Latest)
+ Latest = MD;
+ if (Earliest)
+ Earliest->setPrevious(MD);
+ Earliest = MD;
+ }
+
+ PP.setLoadedMacroDirective(II, Latest);
+}
+
+void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD) {
+ assert(II && MD);
+
+ MacroDirective *Prev = PP.getMacroDirective(II);
+ if (Prev && !Prev->getInfo()->isIdenticalTo(*MD->getInfo(), PP)) {
+ Prev->setAmbiguous(true);
+ MD->setAmbiguous(true);
+ }
+
+ PP.setMacroDirective(II, MD);
+}
+
InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
// If this ID is bogus, just return an empty input file.
if (ID == 0 || ID > F.InputFilesLoaded.size())
@@ -2629,18 +2669,8 @@ bool ASTReader::ReadASTBlock(ModuleFile
break;
}
- case MACRO_UPDATES: {
- for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
- MacroID ID = getGlobalMacroID(F, Record[I++]);
- if (I == N)
- break;
-
- SourceLocation UndefLoc = ReadSourceLocation(F, Record, I);
- SubmoduleID SubmoduleID = getGlobalSubmoduleID(F, Record[I++]);;
- MacroUpdate Update;
- Update.UndefLoc = UndefLoc;
- MacroUpdates[ID].push_back(std::make_pair(SubmoduleID, Update));
- }
+ case MACRO_TABLE: {
+ // FIXME: Not used yet.
break;
}
}
@@ -2695,7 +2725,7 @@ void ASTReader::makeNamesVisible(const H
std::pair<IdentifierInfo *, MacroDirective *> Macro = Names[I].getMacro();
Macro.second->setHidden(!Macro.second->isPublic());
if (Macro.second->isDefined()) {
- PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second);
+ installImportedMacro(Macro.first, Macro.second);
}
break;
}
@@ -5789,7 +5819,7 @@ void ASTReader::PrintStats() {
unsigned NumMacrosLoaded
= MacrosLoaded.size() - std::count(MacrosLoaded.begin(),
MacrosLoaded.end(),
- (MacroDirective *)0);
+ (MacroInfo *)0);
unsigned NumSelectorsLoaded
= SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
SelectorsLoaded.end(),
@@ -6398,7 +6428,7 @@ IdentifierID ASTReader::getGlobalIdentif
return LocalID + I->second;
}
-MacroDirective *ASTReader::getMacro(MacroID ID, MacroDirective *Hint) {
+MacroInfo *ASTReader::getMacro(MacroID ID) {
if (ID == 0)
return 0;
@@ -6414,7 +6444,11 @@ MacroDirective *ASTReader::getMacro(Macr
assert(I != GlobalMacroMap.end() && "Corrupted global macro map");
ModuleFile *M = I->second;
unsigned Index = ID - M->BaseMacroID;
- ReadMacroRecord(*M, M->MacroOffsets[Index], Hint);
+ MacrosLoaded[ID] = ReadMacroRecord(*M, M->MacroOffsets[Index]);
+
+ if (DeserializationListener)
+ DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS,
+ MacrosLoaded[ID]);
}
return MacrosLoaded[ID];
@@ -7128,12 +7162,22 @@ void ASTReader::finishPendingActions() {
// Load any pending macro definitions.
for (unsigned I = 0; I != PendingMacroIDs.size(); ++I) {
- // FIXME: std::move here
- SmallVector<MacroID, 2> GlobalIDs = PendingMacroIDs.begin()[I].second;
- MacroDirective *Hint = 0;
+ IdentifierInfo *II = PendingMacroIDs.begin()[I].first;
+ SmallVector<PendingMacroInfo, 2> GlobalIDs;
+ GlobalIDs.swap(PendingMacroIDs.begin()[I].second);
+ // Initialize the macro history from chained-PCHs ahead of module imports.
+ for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
+ ++IDIdx) {
+ const PendingMacroInfo &Info = GlobalIDs[IDIdx];
+ if (Info.M->Kind != MK_Module)
+ resolvePendingMacro(II, Info);
+ }
+ // Handle module imports.
for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
++IDIdx) {
- Hint = getMacro(GlobalIDs[IDIdx], Hint);
+ const PendingMacroInfo &Info = GlobalIDs[IDIdx];
+ if (Info.M->Kind == MK_Module)
+ resolvePendingMacro(II, Info);
}
}
PendingMacroIDs.clear();
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=177761&r1=177760&r2=177761&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Mar 22 16:12:57 2013
@@ -835,7 +835,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(LOCAL_REDECLARATIONS);
RECORD(OBJC_CATEGORIES);
RECORD(MACRO_OFFSET);
- RECORD(MACRO_UPDATES);
+ RECORD(MACRO_TABLE);
// SourceManager Block.
BLOCK(SOURCE_MANAGER_BLOCK);
@@ -1787,11 +1787,47 @@ void ASTWriter::WriteSourceManagerBlock(
// Preprocessor Serialization
//===----------------------------------------------------------------------===//
-static int compareMacroDefinitions(const void *XPtr, const void *YPtr) {
- const std::pair<const IdentifierInfo *, MacroInfo *> &X =
- *(const std::pair<const IdentifierInfo *, MacroInfo *>*)XPtr;
- const std::pair<const IdentifierInfo *, MacroInfo *> &Y =
- *(const std::pair<const IdentifierInfo *, MacroInfo *>*)YPtr;
+namespace {
+class ASTMacroTableTrait {
+public:
+ typedef IdentID key_type;
+ typedef key_type key_type_ref;
+
+ struct Data {
+ uint32_t MacroDirectivesOffset;
+ };
+
+ typedef Data data_type;
+ typedef const data_type &data_type_ref;
+
+ static unsigned ComputeHash(IdentID IdID) {
+ return llvm::hash_value(IdID);
+ }
+
+ std::pair<unsigned,unsigned>
+ static EmitKeyDataLength(raw_ostream& Out,
+ key_type_ref Key, data_type_ref Data) {
+ unsigned KeyLen = 4; // IdentID.
+ unsigned DataLen = 4; // MacroDirectivesOffset.
+ return std::make_pair(KeyLen, DataLen);
+ }
+
+ static void EmitKey(raw_ostream& Out, key_type_ref Key, unsigned KeyLen) {
+ clang::io::Emit32(Out, Key);
+ }
+
+ static void EmitData(raw_ostream& Out, key_type_ref Key, data_type_ref Data,
+ unsigned) {
+ clang::io::Emit32(Out, Data.MacroDirectivesOffset);
+ }
+};
+} // end anonymous namespace
+
+static int compareMacroDirectives(const void *XPtr, const void *YPtr) {
+ const std::pair<const IdentifierInfo *, MacroDirective *> &X =
+ *(const std::pair<const IdentifierInfo *, MacroDirective *>*)XPtr;
+ const std::pair<const IdentifierInfo *, MacroDirective *> &Y =
+ *(const std::pair<const IdentifierInfo *, MacroDirective *>*)YPtr;
return X.first->getName().compare(Y.first->getName());
}
@@ -1837,24 +1873,68 @@ void ASTWriter::WritePreprocessor(const
fprintf(stderr, "warning: precompiled header used __DATE__ or __TIME__.\n");
- // Loop over all the macro definitions that are live at the end of the file,
+ // Loop over all the macro directives that are live at the end of the file,
// emitting each to the PP section.
- // Construct the list of macro definitions that need to be serialized.
+ // Construct the list of macro directives that need to be serialized.
SmallVector<std::pair<const IdentifierInfo *, MacroDirective *>, 2>
- MacrosToEmit;
- for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0),
- E = PP.macro_end(Chain == 0);
+ MacroDirectives;
+ for (Preprocessor::macro_iterator
+ I = PP.macro_begin(/*IncludeExternalMacros=*/false),
+ E = PP.macro_end(/*IncludeExternalMacros=*/false);
I != E; ++I) {
- if (!IsModule || I->second->isPublic()) {
- MacrosToEmit.push_back(std::make_pair(I->first, I->second));
- }
+ MacroDirectives.push_back(std::make_pair(I->first, I->second));
}
// Sort the set of macro definitions that need to be serialized by the
// name of the macro, to provide a stable ordering.
- llvm::array_pod_sort(MacrosToEmit.begin(), MacrosToEmit.end(),
- &compareMacroDefinitions);
+ llvm::array_pod_sort(MacroDirectives.begin(), MacroDirectives.end(),
+ &compareMacroDirectives);
+
+ OnDiskChainedHashTableGenerator<ASTMacroTableTrait> Generator;
+
+ // Emit the macro directives as a list and associate the offset with the
+ // identifier they belong to.
+ for (unsigned I = 0, N = MacroDirectives.size(); I != N; ++I) {
+ const IdentifierInfo *Name = MacroDirectives[I].first;
+ uint64_t MacroDirectiveOffset = Stream.GetCurrentBitNo();
+ MacroDirective *MD = MacroDirectives[I].second;
+
+ // If the macro or identifier need no updates, don't write the macro history
+ // for this one.
+ if (MD->isFromPCH() && !MD->hasChangedAfterLoad() &&
+ Name->isFromAST() && !Name->hasChangedSinceDeserialization())
+ continue;
+
+ // Emit the macro directives in reverse source order.
+ for (; MD; MD = MD->getPrevious()) {
+ if (shouldIgnoreMacro(MD, IsModule, PP))
+ continue;
+ MacroID InfoID = getMacroRef(MD->getInfo(), Name);
+ if (InfoID == 0)
+ continue;
+
+ Record.push_back(InfoID);
+ AddSourceLocation(MD->getLocation(), Record);
+ AddSourceLocation(MD->getUndefLoc(), Record);
+ AddSourceLocation(MD->getVisibilityLocation(), Record);
+ Record.push_back(MD->isImported());
+ Record.push_back(MD->isPublic());
+ Record.push_back(MD->isAmbiguous());
+ }
+ if (Record.empty())
+ continue;
+
+ Stream.EmitRecord(PP_MACRO_DIRECTIVE_HISTORY, Record);
+ Record.clear();
+
+ IdentMacroDirectivesOffsetMap[Name] = MacroDirectiveOffset;
+
+ IdentID NameID = getIdentifierRef(Name);
+ ASTMacroTableTrait::Data data;
+ data.MacroDirectivesOffset = MacroDirectiveOffset;
+ Generator.insert(NameID, data);
+ }
/// \brief Offsets of each of the macros into the bitstream, indexed by
/// the local macro ID
@@ -1864,101 +1944,107 @@ void ASTWriter::WritePreprocessor(const
/// defined.
std::vector<uint32_t> MacroOffsets;
- for (unsigned I = 0, N = MacrosToEmit.size(); I != N; ++I) {
- const IdentifierInfo *Name = MacrosToEmit[I].first;
-
- for (MacroDirective *MD = MacrosToEmit[I].second; MD;
- MD = MD->getPrevious()) {
- if (shouldIgnoreMacro(MD, IsModule, PP))
- continue;
+ for (unsigned I = 0, N = MacroInfosToEmit.size(); I != N; ++I) {
+ const IdentifierInfo *Name = MacroInfosToEmit[I].Name;
+ MacroInfo *MI = MacroInfosToEmit[I].MI;
+ MacroID ID = MacroInfosToEmit[I].ID;
- MacroID ID = getMacroRef(MD);
- if (!ID)
- continue;
+ if (ID < FirstMacroID) {
+ assert(0 && "Loaded MacroInfo entered MacroInfosToEmit ?");
+ continue;
+ }
- // Skip macros from a AST file if we're chaining.
- if (Chain && MD->isImported() && !MD->hasChangedAfterLoad())
- continue;
+ // Record the local offset of this macro.
+ unsigned Index = ID - FirstMacroID;
+ if (Index == MacroOffsets.size())
+ MacroOffsets.push_back(Stream.GetCurrentBitNo());
+ else {
+ if (Index > MacroOffsets.size())
+ MacroOffsets.resize(Index + 1);
- if (ID < FirstMacroID) {
- // This will have been dealt with via an update record.
- assert(MacroUpdates.count(MD) > 0 && "Missing macro update");
- continue;
- }
+ MacroOffsets[Index] = Stream.GetCurrentBitNo();
+ }
- // Record the local offset of this macro.
- unsigned Index = ID - FirstMacroID;
- if (Index == MacroOffsets.size())
- MacroOffsets.push_back(Stream.GetCurrentBitNo());
- else {
- if (Index > MacroOffsets.size())
- MacroOffsets.resize(Index + 1);
+ AddIdentifierRef(Name, Record);
+ Record.push_back(inferSubmoduleIDFromLocation(MI->getDefinitionLoc()));
+ AddSourceLocation(MI->getDefinitionLoc(), Record);
+ AddSourceLocation(MI->getDefinitionEndLoc(), Record);
+ Record.push_back(MI->isUsed());
+ unsigned Code;
+ if (MI->isObjectLike()) {
+ Code = PP_MACRO_OBJECT_LIKE;
+ } else {
+ Code = PP_MACRO_FUNCTION_LIKE;
- MacroOffsets[Index] = Stream.GetCurrentBitNo();
- }
+ Record.push_back(MI->isC99Varargs());
+ Record.push_back(MI->isGNUVarargs());
+ Record.push_back(MI->hasCommaPasting());
+ Record.push_back(MI->getNumArgs());
+ for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
+ I != E; ++I)
+ AddIdentifierRef(*I, Record);
+ }
- AddIdentifierRef(Name, Record);
- addMacroRef(MD, Record);
- const MacroInfo *MI = MD->getInfo();
- Record.push_back(inferSubmoduleIDFromLocation(MI->getDefinitionLoc()));
- AddSourceLocation(MI->getDefinitionLoc(), Record);
- AddSourceLocation(MI->getDefinitionEndLoc(), Record);
- AddSourceLocation(MD->getUndefLoc(), Record);
- Record.push_back(MI->isUsed());
- Record.push_back(MD->isPublic());
- AddSourceLocation(MD->getVisibilityLocation(), Record);
- unsigned Code;
- if (MI->isObjectLike()) {
- Code = PP_MACRO_OBJECT_LIKE;
- } else {
- Code = PP_MACRO_FUNCTION_LIKE;
+ // If we have a detailed preprocessing record, record the macro definition
+ // ID that corresponds to this macro.
+ if (PPRec)
+ Record.push_back(MacroDefinitions[PPRec->findMacroDefinition(MI)]);
- Record.push_back(MI->isC99Varargs());
- Record.push_back(MI->isGNUVarargs());
- Record.push_back(MI->hasCommaPasting());
- Record.push_back(MI->getNumArgs());
- for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
- I != E; ++I)
- AddIdentifierRef(*I, Record);
- }
+ Stream.EmitRecord(Code, Record);
+ Record.clear();
- // If we have a detailed preprocessing record, record the macro definition
- // ID that corresponds to this macro.
- if (PPRec)
- Record.push_back(MacroDefinitions[PPRec->findMacroDefinition(MI)]);
+ // Emit the tokens array.
+ for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
+ // Note that we know that the preprocessor does not have any annotation
+ // tokens in it because they are created by the parser, and thus can't
+ // be in a macro definition.
+ const Token &Tok = MI->getReplacementToken(TokNo);
+
+ Record.push_back(Tok.getLocation().getRawEncoding());
+ Record.push_back(Tok.getLength());
+
+ // FIXME: When reading literal tokens, reconstruct the literal pointer
+ // if it is needed.
+ AddIdentifierRef(Tok.getIdentifierInfo(), Record);
+ // FIXME: Should translate token kind to a stable encoding.
+ Record.push_back(Tok.getKind());
+ // FIXME: Should translate token flags to a stable encoding.
+ Record.push_back(Tok.getFlags());
- Stream.EmitRecord(Code, Record);
+ Stream.EmitRecord(PP_TOKEN, Record);
Record.clear();
-
- // Emit the tokens array.
- for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
- // Note that we know that the preprocessor does not have any annotation
- // tokens in it because they are created by the parser, and thus can't
- // be in a macro definition.
- const Token &Tok = MI->getReplacementToken(TokNo);
-
- Record.push_back(Tok.getLocation().getRawEncoding());
- Record.push_back(Tok.getLength());
-
- // FIXME: When reading literal tokens, reconstruct the literal pointer
- // if it is needed.
- AddIdentifierRef(Tok.getIdentifierInfo(), Record);
- // FIXME: Should translate token kind to a stable encoding.
- Record.push_back(Tok.getKind());
- // FIXME: Should translate token flags to a stable encoding.
- Record.push_back(Tok.getFlags());
-
- Stream.EmitRecord(PP_TOKEN, Record);
- Record.clear();
- }
- ++NumMacros;
}
+ ++NumMacros;
}
+
Stream.ExitBlock();
- // Write the offsets table for macro IDs.
+ // Create the on-disk hash table in a buffer.
+ SmallString<4096> MacroTable;
+ uint32_t BucketOffset;
+ {
+ llvm::raw_svector_ostream Out(MacroTable);
+ // Make sure that no bucket is at offset 0
+ clang::io::Emit32(Out, 0);
+ BucketOffset = Generator.Emit(Out);
+ }
+
+ // Write the macro table
using namespace llvm;
BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+ Abbrev->Add(BitCodeAbbrevOp(MACRO_TABLE));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ unsigned MacroTableAbbrev = Stream.EmitAbbrev(Abbrev);
+
+ Record.push_back(MACRO_TABLE);
+ Record.push_back(BucketOffset);
+ Stream.EmitRecordWithBlob(MacroTableAbbrev, Record, MacroTable.str());
+ Record.clear();
+
+ // Write the offsets table for macro IDs.
+ using namespace llvm;
+ Abbrev = new BitCodeAbbrev();
Abbrev->Add(BitCodeAbbrevOp(MACRO_OFFSET));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macros
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
@@ -2801,13 +2887,61 @@ class ASTIdentifierTableTrait {
if (!II->hadMacroDefinition())
return false;
- if (Macro || (Macro = PP.getMacroDirectiveHistory(II)))
- return !shouldIgnoreMacro(Macro, IsModule, PP) &&
- (!IsModule || Macro->isPublic());
+ if (Macro || (Macro = PP.getMacroDirectiveHistory(II))) {
+ if (!IsModule)
+ return !shouldIgnoreMacro(Macro, IsModule, PP);
+ SubmoduleID ModID;
+ if (getFirstPublicSubmoduleMacro(Macro, ModID))
+ return true;
+ }
return false;
}
+ MacroDirective *getFirstPublicSubmoduleMacro(MacroDirective *MD,
+ SubmoduleID &ModID) {
+ if (shouldIgnoreMacro(MD, IsModule, PP))
+ return 0;
+ ModID = getSubmoduleID(MD);
+ if (ModID == 0)
+ return 0;
+ if (MD->isDefined() && MD->isPublic())
+ return MD;
+ return getNextPublicSubmoduleMacro(MD, ModID);
+ }
+
+ MacroDirective *getNextPublicSubmoduleMacro(MacroDirective *MD,
+ SubmoduleID &ModID) {
+ while (MD) {
+ MD = getNextSubmoduleMacro(MD, ModID);
+ if (MD && MD->isDefined() && MD->isPublic())
+ return MD;
+ }
+ return 0;
+ }
+
+ MacroDirective *getNextSubmoduleMacro(MacroDirective *CurrMD,
+ SubmoduleID &CurrModID) {
+ SubmoduleID OrigID = CurrModID;
+ while ((CurrMD = CurrMD->getPrevious())) {
+ if (shouldIgnoreMacro(CurrMD, IsModule, PP))
+ return 0;
+ CurrModID = getSubmoduleID(CurrMD);
+ if (CurrModID == 0)
+ return 0;
+ if (CurrModID != OrigID)
+ return CurrMD;
+ }
+ return 0;
+ }
+
+ SubmoduleID getSubmoduleID(MacroDirective *MD) {
+ MacroInfo *MI = MD->getInfo();
+ if (unsigned ID = MI->getOwningModuleID())
+ return ID;
+ return Writer.inferSubmoduleIDFromLocation(MI->getDefinitionLoc());
+ }
+
public:
typedef IdentifierInfo* key_type;
typedef key_type key_type_ref;
@@ -2832,14 +2966,15 @@ public:
DataLen += 2; // 2 bytes for builtin ID
DataLen += 2; // 2 bytes for flags
if (hadMacroDefinition(II, Macro)) {
- for (MacroDirective *M = Macro; M; M = M->getPrevious()) {
- if (shouldIgnoreMacro(M, IsModule, PP))
- continue;
- if (Writer.getMacroRef(M) != 0)
- DataLen += 4;
+ DataLen += 4; // MacroDirectives offset.
+ if (IsModule) {
+ SubmoduleID ModID;
+ for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, ModID);
+ MD; MD = getNextPublicSubmoduleMacro(MD, ModID)) {
+ DataLen += 4; // MacroInfo ID.
+ }
+ DataLen += 4;
}
-
- DataLen += 4;
}
for (IdentifierResolver::iterator D = IdResolver.begin(II),
@@ -2878,6 +3013,7 @@ public:
Bits = 0;
bool HadMacroDefinition = hadMacroDefinition(II, Macro);
Bits = (Bits << 1) | unsigned(HadMacroDefinition);
+ Bits = (Bits << 1) | unsigned(IsModule);
Bits = (Bits << 1) | unsigned(II->isExtensionToken());
Bits = (Bits << 1) | unsigned(II->isPoisoned());
Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());
@@ -2885,15 +3021,18 @@ public:
clang::io::Emit16(Out, Bits);
if (HadMacroDefinition) {
- // Write all of the macro IDs associated with this identifier.
- for (MacroDirective *M = Macro; M; M = M->getPrevious()) {
- if (shouldIgnoreMacro(M, IsModule, PP))
- continue;
- if (MacroID ID = Writer.getMacroRef(M))
- clang::io::Emit32(Out, ID);
+ clang::io::Emit32(Out, Writer.getMacroDirectivesOffset(II));
+ if (IsModule) {
+ // Write the IDs of macros coming from different submodules.
+ SubmoduleID ModID;
+ for (MacroDirective *MD = getFirstPublicSubmoduleMacro(Macro, ModID);
+ MD; MD = getNextPublicSubmoduleMacro(MD, ModID)) {
+ MacroID InfoID = Writer.getMacroID(MD->getInfo());
+ assert(InfoID);
+ clang::io::Emit32(Out, InfoID);
+ }
+ clang::io::Emit32(Out, 0);
}
-
- clang::io::Emit32(Out, 0);
}
// Emit the declaration IDs in reverse order, because the
@@ -3968,7 +4107,6 @@ void ASTWriter::WriteASTCore(Sema &SemaR
}
}
- WriteMacroUpdates();
WriteDeclUpdatesBlocks();
WriteDeclReplacementsBlock();
WriteRedeclarations();
@@ -3985,21 +4123,6 @@ void ASTWriter::WriteASTCore(Sema &SemaR
Stream.ExitBlock();
}
-void ASTWriter::WriteMacroUpdates() {
- if (MacroUpdates.empty())
- return;
-
- RecordData Record;
- for (MacroUpdatesMap::iterator I = MacroUpdates.begin(),
- E = MacroUpdates.end();
- I != E; ++I) {
- addMacroRef(I->first, Record);
- AddSourceLocation(I->second.UndefLoc, Record);
- Record.push_back(inferSubmoduleIDFromLocation(I->second.UndefLoc));
- }
- Stream.EmitRecord(MACRO_UPDATES, Record);
-}
-
/// \brief Go through the declaration update blocks and resolve declaration
/// pointers into declaration IDs.
void ASTWriter::ResolveDeclUpdatesBlocks() {
@@ -4095,10 +4218,6 @@ void ASTWriter::AddIdentifierRef(const I
Record.push_back(getIdentifierRef(II));
}
-void ASTWriter::addMacroRef(MacroDirective *MD, RecordDataImpl &Record) {
- Record.push_back(getMacroRef(MD));
-}
-
IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
if (II == 0)
return 0;
@@ -4109,19 +4228,35 @@ IdentID ASTWriter::getIdentifierRef(cons
return ID;
}
-MacroID ASTWriter::getMacroRef(MacroDirective *MD) {
+MacroID ASTWriter::getMacroRef(MacroInfo *MI, const IdentifierInfo *Name) {
// Don't emit builtin macros like __LINE__ to the AST file unless they
// have been redefined by the header (in which case they are not
// isBuiltinMacro).
- if (MD == 0 || MD->getInfo()->isBuiltinMacro())
+ if (MI == 0 || MI->isBuiltinMacro())
return 0;
- MacroID &ID = MacroIDs[MD];
- if (ID == 0)
+ MacroID &ID = MacroIDs[MI];
+ if (ID == 0) {
ID = NextMacroID++;
+ MacroInfoToEmitData Info = { Name, MI, ID };
+ MacroInfosToEmit.push_back(Info);
+ }
return ID;
}
+MacroID ASTWriter::getMacroID(MacroInfo *MI) {
+ if (MI == 0 || MI->isBuiltinMacro())
+ return 0;
+
+ assert(MacroIDs.find(MI) != MacroIDs.end() && "Macro not emitted!");
+ return MacroIDs[MI];
+}
+
+uint64_t ASTWriter::getMacroDirectivesOffset(const IdentifierInfo *Name) {
+ assert(IdentMacroDirectivesOffsetMap[Name] && "not set!");
+ return IdentMacroDirectivesOffsetMap[Name];
+}
+
void ASTWriter::AddSelectorRef(const Selector SelRef, RecordDataImpl &Record) {
Record.push_back(getSelectorRef(SelRef));
}
@@ -4861,9 +4996,9 @@ void ASTWriter::IdentifierRead(IdentID I
StoredID = ID;
}
-void ASTWriter::MacroRead(serialization::MacroID ID, MacroDirective *MD) {
+void ASTWriter::MacroRead(serialization::MacroID ID, MacroInfo *MI) {
// Always keep the highest ID. See \p TypeRead() for more information.
- MacroID &StoredID = MacroIDs[MD];
+ MacroID &StoredID = MacroIDs[MI];
if (ID > StoredID)
StoredID = ID;
}
@@ -4897,10 +5032,6 @@ void ASTWriter::ModuleRead(serialization
SubmoduleIDs[Mod] = ID;
}
-void ASTWriter::UndefinedMacro(MacroDirective *MD) {
- MacroUpdates[MD].UndefLoc = MD->getUndefLoc();
-}
-
void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
assert(D->isCompleteDefinition());
assert(!WritingAST && "Already writing the AST!");
More information about the cfe-commits
mailing list