diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-09-01 17:04:32 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-09-01 17:04:32 +0000 |
commit | 7143aab97c6e849a5a5005b7853b8c7d5af008ed (patch) | |
tree | 1d717dfe03b6e8ad673920a17b021fb3faf6912d /lib/Serialization/ASTWriter.cpp | |
parent | 8efcc0184a6dfe1ea799d3a6b9c1312ef1fac11d (diff) |
Modules hide macro definitions by default, so that silly things like
include guards don't show up as macro definitions in every translation
unit that imports a module. Macro definitions can, however, be
exported with the intentionally-ugly #__export_macro__
directive. Implement this feature by not even bothering to serialize
non-exported macros to a module, because clients of that module need
not (should not) know that these macros even exist.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138943 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 83 |
1 files changed, 51 insertions, 32 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index a57f3a1388..f2ff332de1 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1667,7 +1667,7 @@ static int compareMacroDefinitions(const void *XPtr, const void *YPtr) { /// \brief Writes the block containing the serialized form of the /// preprocessor. /// -void ASTWriter::WritePreprocessor(const Preprocessor &PP) { +void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { RecordData Record; // If the preprocessor __COUNTER__ value has been bumped, remember it. @@ -1697,8 +1697,10 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP) { for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0), E = PP.macro_end(Chain == 0); I != E; ++I) { - MacroDefinitionsSeen.insert(I->first); - MacrosToEmit.push_back(std::make_pair(I->first, I->second)); + if (!IsModule || I->second->isExported()) { + 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 @@ -1730,14 +1732,15 @@ 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 && Name->isFromAST() && MI->isFromAST())) + (Chain && Name->isFromAST() && MI->isFromAST() && + !MI->hasChangedAfterLoad())) continue; AddIdentifierRef(Name, Record); MacroOffsets[Name] = Stream.GetCurrentBitNo(); Record.push_back(MI->getDefinitionLoc().getRawEncoding()); Record.push_back(MI->isUsed()); - + AddSourceLocation(MI->getExportLocation(), Record); unsigned Code; if (MI->isObjectLike()) { Code = PP_MACRO_OBJECT_LIKE; @@ -2293,38 +2296,52 @@ namespace { class ASTIdentifierTableTrait { ASTWriter &Writer; Preprocessor &PP; - + bool IsModule; + /// \brief Determines whether this is an "interesting" identifier /// that needs a full IdentifierInfo structure written into the hash /// table. - static bool isInterestingIdentifier(const IdentifierInfo *II) { - return II->isPoisoned() || - II->isExtensionToken() || - II->hasMacroDefinition() || - II->getObjCOrBuiltinID() || - II->getFETokenInfo<void>(); + bool isInterestingIdentifier(IdentifierInfo *II, MacroInfo *&Macro) { + Macro = 0; + + if (II->isPoisoned() || + II->isExtensionToken() || + II->getObjCOrBuiltinID() || + II->getFETokenInfo<void>()) + return true; + + if (!II->hasMacroDefinition()) + return false; + + if (!IsModule) + return true; + + if ((Macro = PP.getMacroInfo(II))) + return Macro->isExported(); + + return false; } public: - typedef const IdentifierInfo* key_type; + typedef IdentifierInfo* key_type; typedef key_type key_type_ref; typedef IdentID data_type; typedef data_type data_type_ref; - ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP) - : Writer(Writer), PP(PP) { } + ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP, bool IsModule) + : Writer(Writer), PP(PP), IsModule(IsModule) { } static unsigned ComputeHash(const IdentifierInfo* II) { return llvm::HashString(II->getName()); } std::pair<unsigned,unsigned> - EmitKeyDataLength(raw_ostream& Out, const IdentifierInfo* II, - IdentID ID) { + EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) { unsigned KeyLen = II->getLength() + 1; unsigned DataLen = 4; // 4 bytes for the persistent ID << 1 - if (isInterestingIdentifier(II)) { + MacroInfo *Macro; + if (isInterestingIdentifier(II, Macro)) { DataLen += 2; // 2 bytes for builtin ID, flags if (II->hasMacroDefinition() && !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro()) @@ -2350,18 +2367,19 @@ public: Out.write(II->getNameStart(), KeyLen); } - void EmitData(raw_ostream& Out, const IdentifierInfo* II, + void EmitData(raw_ostream& Out, IdentifierInfo* II, IdentID ID, unsigned) { - if (!isInterestingIdentifier(II)) { + MacroInfo *Macro; + if (!isInterestingIdentifier(II, Macro)) { clang::io::Emit32(Out, ID << 1); return; } clang::io::Emit32(Out, (ID << 1) | 0x01); uint32_t Bits = 0; - bool hasMacroDefinition = - II->hasMacroDefinition() && - !PP.getMacroInfo(const_cast<IdentifierInfo *>(II))->isBuiltinMacro(); + bool hasMacroDefinition + = II->hasMacroDefinition() && + (Macro || (Macro = PP.getMacroInfo(II))) && !Macro->isBuiltinMacro(); Bits = (uint32_t)II->getObjCOrBuiltinID(); Bits = (Bits << 1) | unsigned(hasMacroDefinition); Bits = (Bits << 1) | unsigned(II->isExtensionToken()); @@ -2395,14 +2413,14 @@ public: /// The identifier table consists of a blob containing string data /// (the actual identifiers themselves) and a separate "offsets" index /// that maps identifier IDs to locations within the blob. -void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { +void ASTWriter::WriteIdentifierTable(Preprocessor &PP, bool IsModule) { using namespace llvm; // Create and write out the blob that contains the identifier // strings. { OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator; - ASTIdentifierTableTrait Trait(*this, PP); + ASTIdentifierTableTrait Trait(*this, PP, IsModule); // Look for any identifiers that were named while processing the // headers, but are otherwise not needed. We add these to the hash @@ -2422,14 +2440,15 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { ID != IDEnd; ++ID) { assert(ID->first && "NULL identifier in identifier table"); if (!Chain || !ID->first->isFromAST()) - Generator.insert(ID->first, ID->second, Trait); + Generator.insert(const_cast<IdentifierInfo *>(ID->first), ID->second, + Trait); } // Create the on-disk hash table in a buffer. llvm::SmallString<4096> IdentifierTable; uint32_t BucketOffset; { - ASTIdentifierTableTrait Trait(*this, PP); + ASTIdentifierTableTrait Trait(*this, PP, IsModule); llvm::raw_svector_ostream Out(IdentifierTable); // Make sure that no bucket is at offset 0 clang::io::Emit32(Out, 0); @@ -2818,7 +2837,7 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, const std::string &OutputFile, - StringRef isysroot) { + bool IsModule, StringRef isysroot) { // Emit the file header. Stream.Emit((unsigned)'C', 8); Stream.Emit((unsigned)'P', 8); @@ -2828,7 +2847,7 @@ void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls, WriteBlockInfoBlock(); Context = &SemaRef.Context; - WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile); + WriteASTCore(SemaRef, StatCalls, isysroot, OutputFile, IsModule); Context = 0; } @@ -2843,7 +2862,7 @@ static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec, void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, StringRef isysroot, - const std::string &OutputFile) { + const std::string &OutputFile, bool IsModule) { using namespace llvm; ASTContext &Context = SemaRef.Context; @@ -3095,11 +3114,11 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, } Stream.ExitBlock(); - WritePreprocessor(PP); + WritePreprocessor(PP, IsModule); WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot); WriteSelectors(SemaRef); WriteReferencedSelectorsPool(SemaRef); - WriteIdentifierTable(PP); + WriteIdentifierTable(PP, IsModule); WriteFPPragmaOptions(SemaRef.getFPOptions()); WriteOpenCLExtensions(SemaRef); |