From f40f67af436c33a0c76ead87d23f77d186abd8e4 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 16 Jan 2013 16:19:38 +0000 Subject: [PCH/Modules] Change how macro [re]definitions are de/serialized. Previously we would serialize the macro redefinitions as a list, part of the identifier, and try to chain them together across modules individually without having the info that they were already chained at definition time. Change this by serializing the macro redefinition chain and then try to synthesize the chain parts across modules. This allows us to correctly pinpoint when 2 different definitions are ambiguous because they came from unrelated modules. Fixes bogus "ambiguous expansion of macro" warning when a macro in a PCH is redefined without undef'ing it first. rdar://13016031 llvm-svn: 172620 --- clang/lib/Serialization/ASTWriter.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'clang/lib/Serialization/ASTWriter.cpp') diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index af736a4048a..67e03c23346 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1796,12 +1796,10 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { // Construct the list of macro definitions that need to be serialized. SmallVector, 2> MacrosToEmit; - llvm::SmallPtrSet MacroDefinitionsSeen; for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0), E = PP.macro_end(Chain == 0); I != E; ++I) { if (!IsModule || I->second->isPublic()) { - MacroDefinitionsSeen.insert(I->first); MacrosToEmit.push_back(std::make_pair(I->first, I->second)); } } @@ -1854,6 +1852,12 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { Record.push_back(inferSubmoduleIDFromLocation(MI->getDefinitionLoc())); AddSourceLocation(MI->getDefinitionLoc(), Record); AddSourceLocation(MI->getDefinitionEndLoc(), Record); + MacroInfo *PrevMI = MI->getPreviousDefinition(); + // Serialize only the part of the definition chain that is local. + // The chain will be synthesized across modules by the ASTReader. + if (Chain && PrevMI && PrevMI->isFromAST()) + PrevMI = 0; + addMacroRef(PrevMI, Record); AddSourceLocation(MI->getUndefLoc(), Record); Record.push_back(MI->isUsed()); Record.push_back(MI->isPublic()); @@ -2735,14 +2739,8 @@ public: if (isInterestingIdentifier(II, Macro)) { DataLen += 2; // 2 bytes for builtin ID DataLen += 2; // 2 bytes for flags - if (hadMacroDefinition(II, Macro)) { - for (MacroInfo *M = Macro; M; M = M->getPreviousDefinition()) { - if (Writer.getMacroRef(M) != 0) - DataLen += 4; - } - + if (hadMacroDefinition(II, Macro)) DataLen += 4; - } for (IdentifierResolver::iterator D = IdResolver.begin(II), DEnd = IdResolver.end(); @@ -2787,13 +2785,8 @@ public: clang::io::Emit16(Out, Bits); if (HadMacroDefinition) { - // Write all of the macro IDs associated with this identifier. - for (MacroInfo *M = Macro; M; M = M->getPreviousDefinition()) { - if (MacroID ID = Writer.getMacroRef(M)) - clang::io::Emit32(Out, ID); - } - - clang::io::Emit32(Out, 0); + // Write the macro ID associated with this identifier. + clang::io::Emit32(Out, Writer.getMacroRef(Macro)); } // Emit the declaration IDs in reverse order, because the -- cgit v1.2.3