diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Basic/IdentifierTable.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 5 | ||||
-rw-r--r-- | lib/Frontend/FrontendActions.cpp | 3 | ||||
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 34 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 11 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 83 | ||||
-rw-r--r-- | lib/Serialization/ChainedIncludesSource.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/GeneratePCH.cpp | 6 |
9 files changed, 104 insertions, 43 deletions
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index 792b0c9c61..0103318405 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -217,6 +217,7 @@ tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const { CASE(12, 'i', 'c', include_next); CASE(16, '_', 'i', __include_macros); + CASE(16, '_', 'e', __export_macro__); #undef CASE #undef HASH } diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index cc96d486b1..eee5b1a7cc 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -771,7 +771,7 @@ class PrecompilePreambleConsumer : public PCHGenerator, public: PrecompilePreambleConsumer(ASTUnit &Unit, const Preprocessor &PP, StringRef isysroot, raw_ostream *Out) - : PCHGenerator(PP, "", isysroot, Out), Unit(Unit), + : PCHGenerator(PP, "", /*IsModule=*/false, isysroot, Out), Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()) { Hash = 0; } @@ -2324,7 +2324,8 @@ bool ASTUnit::serialize(raw_ostream &OS) { std::vector<unsigned char> Buffer; llvm::BitstreamWriter Stream(Buffer); ASTWriter Writer(Stream); - Writer.WriteAST(getSema(), 0, std::string(), ""); + // FIXME: Handle modules + Writer.WriteAST(getSema(), 0, std::string(), /*IsModule=*/false, ""); // Write the generated bitstream to "Out". if (!Buffer.empty()) diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index e05d5767ea..c80802e353 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -83,7 +83,8 @@ ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, if (!CI.getFrontendOpts().RelocatablePCH) Sysroot.clear(); - return new PCHGenerator(CI.getPreprocessor(), OutputFile, Sysroot, OS); + return new PCHGenerator(CI.getPreprocessor(), OutputFile, MakeModule, + Sysroot, OS); } bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI, diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp index 9e682ce306..5a7af56398 100644 --- a/lib/Lex/MacroInfo.cpp +++ b/lib/Lex/MacroInfo.cpp @@ -21,6 +21,7 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) { IsGNUVarargs = false; IsBuiltinMacro = false; IsFromAST = false; + ChangedAfterLoad = false; IsDisabled = false; IsUsed = false; IsAllowRedefinitionsWithoutWarning = false; @@ -40,6 +41,7 @@ MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator) { IsGNUVarargs = MI.IsGNUVarargs; IsBuiltinMacro = MI.IsBuiltinMacro; IsFromAST = MI.IsFromAST; + ChangedAfterLoad = MI.ChangedAfterLoad; IsDisabled = MI.IsDisabled; IsUsed = MI.IsUsed; IsAllowRedefinitionsWithoutWarning = MI.IsAllowRedefinitionsWithoutWarning; diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 99383e4791..c8fcc3e37d 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -652,6 +652,9 @@ TryAgain: case tok::pp_unassert: //isExtension = true; // FIXME: implement #unassert break; + + case tok::pp___export_macro__: + return HandleMacroExportDirective(Result); } break; } @@ -1000,6 +1003,37 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) { } } +/// \brief Handle a #__export_macro__ directive. +void Preprocessor::HandleMacroExportDirective(Token &Tok) { + Token MacroNameTok; + ReadMacroName(MacroNameTok, 2); + + // Error reading macro name? If so, diagnostic already issued. + if (MacroNameTok.is(tok::eod)) + return; + + // Check to see if this is the last token on the #__export_macro__ line. + CheckEndOfDirective("__export_macro__"); + + // Okay, we finally have a valid identifier to undef. + MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo()); + + // If the macro is not defined, this is an error. + if (MI == 0) { + Diag(MacroNameTok, diag::err_pp_export_non_macro) + << MacroNameTok.getIdentifierInfo(); + return; + } + + // Note that this macro has now been exported. + MI->setExportLocation(MacroNameTok.getLocation()); + + // If this macro definition came from a PCH file, mark it + // as having changed since serialization. + if (MI->isFromAST()) + MI->setChangedAfterLoad(); +} + //===----------------------------------------------------------------------===// // Preprocessor Include Directive Handling. //===----------------------------------------------------------------------===// diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index bc022f5721..10b01d8c9f 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1352,15 +1352,16 @@ void ASTReader::ReadMacroRecord(Module &F, uint64_t Offset) { MI->setIsFromAST(); unsigned NextIndex = 3; + MI->setExportLocation(ReadSourceLocation(F, Record, NextIndex)); + if (RecType == PP_MACRO_FUNCTION_LIKE) { // Decode function-like macro info. - bool isC99VarArgs = Record[3]; - bool isGNUVarArgs = Record[4]; + bool isC99VarArgs = Record[NextIndex++]; + bool isGNUVarArgs = Record[NextIndex++]; MacroArgs.clear(); - unsigned NumArgs = Record[5]; - NextIndex = 6 + NumArgs; + unsigned NumArgs = Record[NextIndex++]; for (unsigned i = 0; i != NumArgs; ++i) - MacroArgs.push_back(getLocalIdentifier(F, Record[6+i])); + MacroArgs.push_back(getLocalIdentifier(F, Record[NextIndex++])); // Install function-like macro info. MI->setIsFunctionLike(); 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); diff --git a/lib/Serialization/ChainedIncludesSource.cpp b/lib/Serialization/ChainedIncludesSource.cpp index 56dc07f4cb..e354054fb1 100644 --- a/lib/Serialization/ChainedIncludesSource.cpp +++ b/lib/Serialization/ChainedIncludesSource.cpp @@ -106,7 +106,7 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) { llvm::raw_svector_ostream OS(serialAST); llvm::OwningPtr<ASTConsumer> consumer; consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", - /*isysroot=*/"", &OS)); + /*IsModule=*/false, /*isysroot=*/"", &OS)); Clang->getASTContext().setASTMutationListener( consumer->GetASTMutationListener()); Clang->setASTConsumer(consumer.take()); diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp index 358954ed19..25fac8b7a8 100644 --- a/lib/Serialization/GeneratePCH.cpp +++ b/lib/Serialization/GeneratePCH.cpp @@ -28,9 +28,11 @@ using namespace clang; PCHGenerator::PCHGenerator(const Preprocessor &PP, StringRef OutputFile, + bool IsModule, StringRef isysroot, raw_ostream *OS) - : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()), Out(OS), + : PP(PP), OutputFile(OutputFile), IsModule(IsModule), + isysroot(isysroot.str()), Out(OS), SemaPtr(0), StatCalls(0), Stream(Buffer), Writer(Stream) { // Install a stat() listener to keep track of all of the stat() // calls. @@ -50,7 +52,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { // Emit the PCH file assert(SemaPtr && "No Sema?"); - Writer.WriteAST(*SemaPtr, StatCalls, OutputFile, isysroot); + Writer.WriteAST(*SemaPtr, StatCalls, OutputFile, IsModule, isysroot); // Write the generated bitstream to "Out". Out->write((char *)&Buffer.front(), Buffer.size()); |