aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Serialization/ASTWriter.cpp34
1 files changed, 27 insertions, 7 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index e4fe99cde3..b6789687d7 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1498,6 +1498,14 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// 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;
+ return X.first->getName().compare(Y.first->getName());
+}
+
/// \brief Writes the block containing the serialized form of the
/// preprocessor.
///
@@ -1524,12 +1532,24 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
// emitting each to the PP section.
PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
- // FIXME: If we are chaining, don't visit all of the macros!
+ // Construct the list of macro definitions that need to be serialized.
+ llvm::SmallVector<std::pair<const IdentifierInfo *, MacroInfo *>, 2>
+ MacrosToEmit;
+ llvm::SmallPtrSet<const IdentifierInfo*, 4> MacroDefinitionsSeen;
for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
I != E; ++I) {
- // FIXME: This emits macros in hash table order, we should do it in a stable
- // order so that output is reproducible.
- MacroInfo *MI = I->second;
+ MacroDefinitionsSeen.insert(I->first);
+ MacrosToEmit.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);
+
+ for (unsigned I = 0, N = MacrosToEmit.size(); I != N; ++I) {
+ const IdentifierInfo *Name = MacrosToEmit[I].first;
+ MacroInfo *MI = MacrosToEmit[I].second;
// 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).
@@ -1540,11 +1560,11 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) {
// chained PCH, by storing the offset into the original PCH rather than
// writing the macro definition a second time.
if (MI->isBuiltinMacro() ||
- (Chain && I->first->isFromAST() && MI->isFromAST()))
+ (Chain && Name->isFromAST() && MI->isFromAST()))
continue;
- AddIdentifierRef(I->first, Record);
- MacroOffsets[I->first] = Stream.GetCurrentBitNo();
+ AddIdentifierRef(Name, Record);
+ MacroOffsets[Name] = Stream.GetCurrentBitNo();
Record.push_back(MI->getDefinitionLoc().getRawEncoding());
Record.push_back(MI->isUsed());