diff options
author | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
commit | ea266cad53e3d49771fa38103913d3ec7a166694 (patch) | |
tree | 8f7776b7310bebaf415ac5b69e46e9f928c37144 /lib/Serialization | |
parent | c72c57c9e9b69944e3e009cd5e209634839581d3 (diff) | |
download | FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.zip FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.tar.gz |
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
release):
http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502
Diffstat (limited to 'lib/Serialization')
-rw-r--r-- | lib/Serialization/ASTCommon.cpp | 3 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 212 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 24 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderInternals.h | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 125 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 83 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 27 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 90 | ||||
-rw-r--r-- | lib/Serialization/GlobalModuleIndex.cpp | 31 |
9 files changed, 494 insertions, 103 deletions
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index 7bbe6b1..24b268f 100644 --- a/lib/Serialization/ASTCommon.cpp +++ b/lib/Serialization/ASTCommon.cpp @@ -119,6 +119,7 @@ serialization::getDefinitiveDeclContext(const DeclContext *DC) { case Decl::CXXConversion: case Decl::ObjCMethod: case Decl::Block: + case Decl::Captured: // Objective C categories, category implementations, and class // implementations can only be defined in one place. case Decl::ObjCCategory: @@ -180,6 +181,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::UnresolvedUsingValue: case Decl::IndirectField: case Decl::Field: + case Decl::MSProperty: case Decl::ObjCIvar: case Decl::ObjCAtDefsField: case Decl::ImplicitParam: @@ -202,6 +204,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::FriendTemplate: case Decl::StaticAssert: case Decl::Block: + case Decl::Captured: case Decl::ClassScopeFunctionSpecialization: case Decl::Import: case Decl::OMPThreadPrivate: diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index d984415..22caeb8 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -257,7 +257,8 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts, const PreprocessorOptions &ExistingPPOpts, DiagnosticsEngine *Diags, FileManager &FileMgr, - std::string &SuggestedPredefines) { + std::string &SuggestedPredefines, + const LangOptions &LangOpts) { // Check macro definitions. MacroDefinitionsMap ASTFileMacros; collectMacroDefinitions(PPOpts, ASTFileMacros); @@ -323,6 +324,15 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts, return true; } + // Detailed record is important since it is used for the module cache hash. + if (LangOpts.Modules && + PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord) { + if (Diags) { + Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord; + } + return true; + } + // Compute the #include and #include_macros lines we need. for (unsigned I = 0, N = ExistingPPOpts.Includes.size(); I != N; ++I) { StringRef File = ExistingPPOpts.Includes[I]; @@ -363,7 +373,8 @@ bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, return checkPreprocessorOptions(PPOpts, ExistingPPOpts, Complain? &Reader.Diags : 0, PP.getFileManager(), - SuggestedPredefines); + SuggestedPredefines, + PP.getLangOpts()); } void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI, @@ -428,8 +439,12 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, data_type Result; Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d)); - unsigned NumInstanceMethods = ReadUnalignedLE16(d); - unsigned NumFactoryMethods = ReadUnalignedLE16(d); + unsigned NumInstanceMethodsAndBits = ReadUnalignedLE16(d); + unsigned NumFactoryMethodsAndBits = ReadUnalignedLE16(d); + Result.InstanceBits = NumInstanceMethodsAndBits & 0x3; + Result.FactoryBits = NumFactoryMethodsAndBits & 0x3; + unsigned NumInstanceMethods = NumInstanceMethodsAndBits >> 2; + unsigned NumFactoryMethods = NumFactoryMethodsAndBits >> 2; // Load instance methods for (unsigned I = 0; I != NumInstanceMethods; ++I) { @@ -1088,6 +1103,19 @@ bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) { } } +Token ASTReader::ReadToken(ModuleFile &F, const RecordData &Record, + unsigned &Idx) { + Token Tok; + Tok.startToken(); + Tok.setLocation(ReadSourceLocation(F, Record, Idx)); + Tok.setLength(Record[Idx++]); + if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++])) + Tok.setIdentifierInfo(II); + Tok.setKind((tok::TokenKind)Record[Idx++]); + Tok.setFlag((Token::TokenFlags)Record[Idx++]); + return Tok; +} + MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { BitstreamCursor &Stream = F.MacroCursor; @@ -1188,14 +1216,8 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { // erroneous, just pretend we didn't see this. if (Macro == 0) break; - Token Tok; - Tok.startToken(); - Tok.setLocation(ReadSourceLocation(F, Record[0])); - Tok.setLength(Record[1]); - if (IdentifierInfo *II = getLocalIdentifier(F, Record[2])) - Tok.setIdentifierInfo(II); - Tok.setKind((tok::TokenKind)Record[3]); - Tok.setFlag((Token::TokenFlags)Record[4]); + unsigned Idx = 0; + Token Tok = ReadToken(F, Record, Idx); Macro->AddTokenToBody(Tok); break; } @@ -1563,9 +1585,9 @@ void ASTReader::installPCHMacroDirectives(IdentifierInfo *II, } /// \brief For the given macro definitions, check if they are both in system -/// modules and if one of the two is in the clang builtin headers. -static bool isSystemAndClangMacro(MacroInfo *PrevMI, MacroInfo *NewMI, - Module *NewOwner, ASTReader &Reader) { +/// modules. +static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI, + Module *NewOwner, ASTReader &Reader) { assert(PrevMI && NewMI); if (!NewOwner) return false; @@ -1576,22 +1598,7 @@ static bool isSystemAndClangMacro(MacroInfo *PrevMI, MacroInfo *NewMI, return false; if (PrevOwner == NewOwner) return false; - if (!PrevOwner->IsSystem || !NewOwner->IsSystem) - return false; - - SourceManager &SM = Reader.getSourceManager(); - FileID PrevFID = SM.getFileID(PrevMI->getDefinitionLoc()); - FileID NewFID = SM.getFileID(NewMI->getDefinitionLoc()); - const FileEntry *PrevFE = SM.getFileEntryForID(PrevFID); - const FileEntry *NewFE = SM.getFileEntryForID(NewFID); - if (PrevFE == 0 || NewFE == 0) - return false; - - Preprocessor &PP = Reader.getPreprocessor(); - ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap(); - const DirectoryEntry *BuiltinDir = ModMap.getBuiltinIncludeDir(); - - return (PrevFE->getDir() == BuiltinDir) != (NewFE->getDir() == BuiltinDir); + return PrevOwner->IsSystem && NewOwner->IsSystem; } void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD, @@ -1607,15 +1614,12 @@ void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD, if (NewMI != PrevMI && !PrevMI->isIdenticalTo(*NewMI, PP, /*Syntactically=*/true)) { // Before marking the macros as ambiguous, check if this is a case where - // the system macro uses a not identical definition compared to a macro - // from the clang headers. For example: + // both macros are in system headers. If so, we trust that the system + // did not get it wrong. This also handles cases where Clang's own + // headers have a different spelling of certain system macros: // #define LONG_MAX __LONG_MAX__ (clang's limits.h) // #define LONG_MAX 0x7fffffffffffffffL (system's limits.h) - // in which case don't mark them to avoid the "ambiguous macro expansion" - // warning. - // FIXME: This should go away if the system headers get "fixed" to use - // identical definitions. - if (!isSystemAndClangMacro(PrevMI, NewMI, Owner, *this)) { + if (!areDefinedInSystemModules(PrevMI, NewMI, Owner, *this)) { PrevDef.getDirective()->setAmbiguous(true); DefMD->setAmbiguous(true); } @@ -2754,7 +2758,7 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { ObjCMethodList &Start = Method->isInstanceMethod()? Known->second.first : Known->second.second; bool Found = false; - for (ObjCMethodList *List = &Start; List; List = List->Next) { + for (ObjCMethodList *List = &Start; List; List = List->getNext()) { if (!Found) { if (List->Method == Method) { Found = true; @@ -2764,8 +2768,8 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { } } - if (List->Next) - List->Method = List->Next->Method; + if (List->getNext()) + List->Method = List->getNext()->Method; else List->Method = Method; } @@ -3324,10 +3328,10 @@ void ASTReader::finalizeForWriting() { HiddenNamesMap.clear(); } -/// SkipCursorToControlBlock - Given a cursor at the start of an AST file, scan -/// ahead and drop the cursor into the start of the CONTROL_BLOCK, returning -/// false on success and true on failure. -static bool SkipCursorToControlBlock(BitstreamCursor &Cursor) { +/// \brief Given a cursor at the start of an AST file, scan ahead and drop the +/// cursor into the start of the given block ID, returning false on success and +/// true on failure. +static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) { while (1) { llvm::BitstreamEntry Entry = Cursor.advance(); switch (Entry.Kind) { @@ -3341,8 +3345,8 @@ static bool SkipCursorToControlBlock(BitstreamCursor &Cursor) { break; case llvm::BitstreamEntry::SubBlock: - if (Entry.ID == CONTROL_BLOCK_ID) { - if (Cursor.EnterSubBlock(CONTROL_BLOCK_ID)) + if (Entry.ID == BlockID) { + if (Cursor.EnterSubBlock(BlockID)) return true; // Found it! return false; @@ -3386,7 +3390,7 @@ std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName, } // Scan for the CONTROL_BLOCK_ID block. - if (SkipCursorToControlBlock(Stream)) { + if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) { Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName; return std::string(); } @@ -3441,7 +3445,7 @@ namespace { bool Complain, std::string &SuggestedPredefines) { return checkPreprocessorOptions(ExistingPPOpts, PPOpts, 0, FileMgr, - SuggestedPredefines); + SuggestedPredefines, ExistingLangOpts); } }; } @@ -3473,8 +3477,29 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, } // Scan for the CONTROL_BLOCK_ID block. - if (SkipCursorToControlBlock(Stream)) + if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) return true; + + bool NeedsInputFiles = Listener.needsInputFileVisitation(); + BitstreamCursor InputFilesCursor; + if (NeedsInputFiles) { + InputFilesCursor = Stream; + if (SkipCursorToBlock(InputFilesCursor, INPUT_FILES_BLOCK_ID)) + return true; + + // Read the abbreviations + while (true) { + uint64_t Offset = InputFilesCursor.GetCurrentBitNo(); + unsigned Code = InputFilesCursor.ReadCode(); + + // We expect all abbrevs to be at the start of the block. + if (Code != llvm::bitc::DEFINE_ABBREV) { + InputFilesCursor.JumpToBit(Offset); + break; + } + InputFilesCursor.ReadAbbrevRecord(); + } + } // Scan for ORIGINAL_FILE inside the control block. RecordData Record; @@ -3532,6 +3557,35 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename, break; } + case INPUT_FILE_OFFSETS: { + if (!NeedsInputFiles) + break; + + unsigned NumInputFiles = Record[0]; + unsigned NumUserFiles = Record[1]; + const uint32_t *InputFileOffs = (const uint32_t *)Blob.data(); + for (unsigned I = 0; I != NumInputFiles; ++I) { + // Go find this input file. + bool isSystemFile = I >= NumUserFiles; + BitstreamCursor &Cursor = InputFilesCursor; + SavedStreamPosition SavedPosition(Cursor); + Cursor.JumpToBit(InputFileOffs[I]); + + unsigned Code = Cursor.ReadCode(); + RecordData Record; + StringRef Blob; + bool shouldContinue = false; + switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) { + case INPUT_FILE: + shouldContinue = Listener.visitInputFile(Blob, isSystemFile); + break; + } + if (!shouldContinue) + break; + } + break; + } + default: // No other validation to perform. break; @@ -3907,6 +3961,7 @@ bool ASTReader::ParseLanguageOptions(const RecordData &Record, LangOpts.CommentOpts.BlockCommandNames.push_back( ReadString(Record, Idx)); } + LangOpts.CommentOpts.ParseAllComments = Record[Idx++]; return Listener.ReadLanguageOptions(LangOpts, Complain); } @@ -4017,6 +4072,7 @@ bool ASTReader::ParsePreprocessorOptions(const RecordData &Record, } PPOpts.UsePredefines = Record[Idx++]; + PPOpts.DetailedRecord = Record[Idx++]; PPOpts.ImplicitPCHInclude = ReadString(Record, Idx); PPOpts.ImplicitPTHInclude = ReadString(Record, Idx); PPOpts.ObjCXXARCStandardLibrary = @@ -4639,8 +4695,12 @@ QualType ASTReader::readTypeRecord(unsigned Index) { return Context.getUnaryTransformType(BaseType, UnderlyingType, UKind); } - case TYPE_AUTO: - return Context.getAutoType(readType(*Loc.F, Record, Idx)); + case TYPE_AUTO: { + QualType Deduced = readType(*Loc.F, Record, Idx); + bool IsDecltypeAuto = Record[Idx++]; + bool IsDependent = Deduced.isNull() ? Record[Idx++] : false; + return Context.getAutoType(Deduced, IsDecltypeAuto, IsDependent); + } case TYPE_RECORD: { if (Record.size() != 2) { @@ -6015,8 +6075,8 @@ void ASTReader::InitializeSema(Sema &S) { // Makes sure any declarations that were deserialized "too early" // still get added to the identifier's declaration chains. for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) { - NamedDecl *ND = cast<NamedDecl>(PreloadedDecls[I]->getMostRecentDecl()); - SemaObj->pushExternalDeclIntoScope(ND, PreloadedDecls[I]->getDeclName()); + pushExternalDeclIntoScope(PreloadedDecls[I], + PreloadedDecls[I]->getDeclName()); } PreloadedDecls.clear(); @@ -6122,7 +6182,10 @@ StringRef ASTIdentifierIterator::Next() { return Result; } -IdentifierIterator *ASTReader::getIdentifiers() const { +IdentifierIterator *ASTReader::getIdentifiers() { + if (!loadGlobalIndex()) + return GlobalIndex->createIdentifierIterator(); + return new ASTIdentifierIterator(*this); } @@ -6131,13 +6194,16 @@ namespace clang { namespace serialization { ASTReader &Reader; Selector Sel; unsigned PriorGeneration; + unsigned InstanceBits; + unsigned FactoryBits; SmallVector<ObjCMethodDecl *, 4> InstanceMethods; SmallVector<ObjCMethodDecl *, 4> FactoryMethods; public: ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel, unsigned PriorGeneration) - : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration) { } + : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration), + InstanceBits(0), FactoryBits(0) { } static bool visit(ModuleFile &M, void *UserData) { ReadMethodPoolVisitor *This @@ -6170,6 +6236,8 @@ namespace clang { namespace serialization { This->InstanceMethods.append(Data.Instance.begin(), Data.Instance.end()); This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end()); + This->InstanceBits = Data.InstanceBits; + This->FactoryBits = Data.FactoryBits; return true; } @@ -6182,6 +6250,9 @@ namespace clang { namespace serialization { ArrayRef<ObjCMethodDecl *> getFactoryMethods() const { return FactoryMethods; } + + unsigned getInstanceBits() const { return InstanceBits; } + unsigned getFactoryBits() const { return FactoryBits; } }; } } // end namespace clang::serialization @@ -6219,6 +6290,8 @@ void ASTReader::ReadMethodPool(Selector Sel) { addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first); addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second); + Pos->second.first.setBits(Visitor.getInstanceBits()); + Pos->second.second.setBits(Visitor.getFactoryBits()); } void ASTReader::ReadKnownNamespaces( @@ -6417,8 +6490,7 @@ ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II, // Introduce this declaration into the translation-unit scope // and add it to the declaration chain for this identifier, so // that (unqualified) name lookup will find it. - NamedDecl *ND = cast<NamedDecl>(D->getMostRecentDecl()); - SemaObj->pushExternalDeclIntoScope(ND, II); + pushExternalDeclIntoScope(D, II); } else { // Queue this declaration so that it will be added to the // translation unit scope and identifier's declaration chain @@ -7165,9 +7237,9 @@ void ASTReader::ReadComments() { (RawComment::CommentKind) Record[Idx++]; bool IsTrailingComment = Record[Idx++]; bool IsAlmostTrailingComment = Record[Idx++]; - Comments.push_back(new (Context) RawComment(SR, Kind, - IsTrailingComment, - IsAlmostTrailingComment)); + Comments.push_back(new (Context) RawComment( + SR, Kind, IsTrailingComment, IsAlmostTrailingComment, + Context.getLangOpts().CommentOpts.ParseAllComments)); break; } } @@ -7205,8 +7277,7 @@ void ASTReader::finishPendingActions() { TLD != TLDEnd; ++TLD) { IdentifierInfo *II = TLD->first; for (unsigned I = 0, N = TLD->second.size(); I != N; ++I) { - NamedDecl *ND = cast<NamedDecl>(TLD->second[I]->getMostRecentDecl()); - SemaObj->pushExternalDeclIntoScope(ND, II); + pushExternalDeclIntoScope(cast<NamedDecl>(TLD->second[I]), II); } } @@ -7346,6 +7417,21 @@ void ASTReader::FinishedDeserializing() { } } +void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { + D = cast<NamedDecl>(D->getMostRecentDecl()); + + if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) { + SemaObj->TUScope->AddDecl(D); + } else if (SemaObj->TUScope) { + // Adding the decl to IdResolver may have failed because it was already in + // (even though it was not added in scope). If it is already in, make sure + // it gets in the scope as well. + if (std::find(SemaObj->IdResolver.begin(Name), + SemaObj->IdResolver.end(), D) != SemaObj->IdResolver.end()) + SemaObj->TUScope->AddDecl(D); + } +} + ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot, bool DisableValidation, bool AllowASTWithCompilerErrors, bool UseGlobalIndex) diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 0fbdd7e..f7fa818 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -244,6 +244,7 @@ namespace clang { void VisitCXXDestructorDecl(CXXDestructorDecl *D); void VisitCXXConversionDecl(CXXConversionDecl *D); void VisitFieldDecl(FieldDecl *FD); + void VisitMSPropertyDecl(MSPropertyDecl *FD); void VisitIndirectFieldDecl(IndirectFieldDecl *FD); void VisitVarDecl(VarDecl *VD); void VisitImplicitParamDecl(ImplicitParamDecl *PD); @@ -265,6 +266,7 @@ namespace clang { void VisitFriendTemplateDecl(FriendTemplateDecl *D); void VisitStaticAssertDecl(StaticAssertDecl *D); void VisitBlockDecl(BlockDecl *BD); + void VisitCapturedDecl(CapturedDecl *CD); void VisitEmptyDecl(EmptyDecl *D); std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC); @@ -847,6 +849,7 @@ void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { void ASTDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { VisitObjCImplDecl(D); D->setSuperClass(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx)); + D->SuperLoc = ReadSourceLocation(Record, Idx); D->setIvarLBraceLoc(ReadSourceLocation(Record, Idx)); D->setIvarRBraceLoc(ReadSourceLocation(Record, Idx)); D->setHasNonZeroConstructors(Record[Idx++]); @@ -879,6 +882,12 @@ void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) { } } +void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) { + VisitDeclaratorDecl(PD); + PD->GetterId = Reader.GetIdentifierInfo(F, Record, Idx); + PD->SetterId = Reader.GetIdentifierInfo(F, Record, Idx); +} + void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { VisitValueDecl(FD); @@ -895,7 +904,7 @@ void ASTDeclReader::VisitVarDecl(VarDecl *VD) { VisitDeclaratorDecl(VD); VD->VarDeclBits.SClass = (StorageClass)Record[Idx++]; - VD->VarDeclBits.ThreadSpecified = Record[Idx++]; + VD->VarDeclBits.TSCSpec = Record[Idx++]; VD->VarDeclBits.InitStyle = Record[Idx++]; VD->VarDeclBits.ExceptionVar = Record[Idx++]; VD->VarDeclBits.NRVOVariable = Record[Idx++]; @@ -987,6 +996,13 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { captures.end(), capturesCXXThis); } +void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) { + VisitDecl(CD); + // Body is set by VisitCapturedStmt. + for (unsigned i = 0; i < CD->NumParams; ++i) + CD->setParam(i, ReadDeclAs<ImplicitParamDecl>(Record, Idx)); +} + void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) { VisitDecl(D); D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]); @@ -2136,6 +2152,12 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_BLOCK: D = BlockDecl::CreateDeserialized(Context, ID); break; + case DECL_MS_PROPERTY: + D = MSPropertyDecl::CreateDeserialized(Context, ID); + break; + case DECL_CAPTURED: + D = CapturedDecl::CreateDeserialized(Context, ID, Record[Idx++]); + break; case DECL_CXX_BASE_SPECIFIERS: Error("attempt to read a C++ base-specifier record as a declaration"); return 0; diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h index 327da44..9149b18 100644 --- a/lib/Serialization/ASTReaderInternals.h +++ b/lib/Serialization/ASTReaderInternals.h @@ -152,6 +152,8 @@ class ASTSelectorLookupTrait { public: struct data_type { SelectorID ID; + unsigned InstanceBits; + unsigned FactoryBits; SmallVector<ObjCMethodDecl *, 2> Instance; SmallVector<ObjCMethodDecl *, 2> Factory; }; diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 078ecb7..e1357ba 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Lex/Token.h" #include "llvm/ADT/SmallString.h" using namespace clang; using namespace clang::serialization; @@ -32,14 +33,22 @@ namespace clang { const ASTReader::RecordData &Record; unsigned &Idx; + Token ReadToken(const RecordData &R, unsigned &I) { + return Reader.ReadToken(F, R, I); + } + SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) { return Reader.ReadSourceLocation(F, R, I); } - + SourceRange ReadSourceRange(const RecordData &R, unsigned &I) { return Reader.ReadSourceRange(F, R, I); } - + + std::string ReadString(const RecordData &R, unsigned &I) { + return Reader.ReadString(R, I); + } + TypeSourceInfo *GetTypeSourceInfo(const RecordData &R, unsigned &I) { return Reader.GetTypeSourceInfo(F, R, I); } @@ -286,18 +295,25 @@ void ASTStmtReader::VisitDeclStmt(DeclStmt *S) { } } -void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) { +void ASTStmtReader::VisitAsmStmt(AsmStmt *S) { VisitStmt(S); - unsigned NumOutputs = Record[Idx++]; - unsigned NumInputs = Record[Idx++]; - unsigned NumClobbers = Record[Idx++]; + S->NumOutputs = Record[Idx++]; + S->NumInputs = Record[Idx++]; + S->NumClobbers = Record[Idx++]; S->setAsmLoc(ReadSourceLocation(Record, Idx)); - S->setRParenLoc(ReadSourceLocation(Record, Idx)); S->setVolatile(Record[Idx++]); S->setSimple(Record[Idx++]); +} +void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) { + VisitAsmStmt(S); + S->setRParenLoc(ReadSourceLocation(Record, Idx)); S->setAsmString(cast_or_null<StringLiteral>(Reader.ReadSubStmt())); + unsigned NumOutputs = S->getNumOutputs(); + unsigned NumInputs = S->getNumInputs(); + unsigned NumClobbers = S->getNumClobbers(); + // Outputs and inputs SmallVector<IdentifierInfo *, 16> Names; SmallVector<StringLiteral*, 16> Constraints; @@ -320,8 +336,75 @@ void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) { } void ASTStmtReader::VisitMSAsmStmt(MSAsmStmt *S) { - // FIXME: Statement reader not yet implemented for MS style inline asm. + VisitAsmStmt(S); + S->LBraceLoc = ReadSourceLocation(Record, Idx); + S->EndLoc = ReadSourceLocation(Record, Idx); + S->NumAsmToks = Record[Idx++]; + std::string AsmStr = ReadString(Record, Idx); + + // Read the tokens. + SmallVector<Token, 16> AsmToks; + AsmToks.reserve(S->NumAsmToks); + for (unsigned i = 0, e = S->NumAsmToks; i != e; ++i) { + AsmToks.push_back(ReadToken(Record, Idx)); + } + + // The calls to reserve() for the FooData vectors are mandatory to + // prevent dead StringRefs in the Foo vectors. + + // Read the clobbers. + SmallVector<std::string, 16> ClobbersData; + SmallVector<StringRef, 16> Clobbers; + ClobbersData.reserve(S->NumClobbers); + Clobbers.reserve(S->NumClobbers); + for (unsigned i = 0, e = S->NumClobbers; i != e; ++i) { + ClobbersData.push_back(ReadString(Record, Idx)); + Clobbers.push_back(ClobbersData.back()); + } + + // Read the operands. + unsigned NumOperands = S->NumOutputs + S->NumInputs; + SmallVector<Expr*, 16> Exprs; + SmallVector<std::string, 16> ConstraintsData; + SmallVector<StringRef, 16> Constraints; + Exprs.reserve(NumOperands); + ConstraintsData.reserve(NumOperands); + Constraints.reserve(NumOperands); + for (unsigned i = 0; i != NumOperands; ++i) { + Exprs.push_back(cast<Expr>(Reader.ReadSubStmt())); + ConstraintsData.push_back(ReadString(Record, Idx)); + Constraints.push_back(ConstraintsData.back()); + } + + S->initialize(Reader.getContext(), AsmStr, AsmToks, + Constraints, Exprs, Clobbers); +} + +void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) { VisitStmt(S); + S->setCapturedDecl(ReadDeclAs<CapturedDecl>(Record, Idx)); + S->setCapturedRegionKind(static_cast<CapturedRegionKind>(Record[Idx++])); + S->setCapturedRecordDecl(ReadDeclAs<RecordDecl>(Record, Idx)); + + // Capture inits + for (CapturedStmt::capture_init_iterator I = S->capture_init_begin(), + E = S->capture_init_end(); + I != E; ++I) + *I = Reader.ReadSubExpr(); + + // Body + S->setCapturedStmt(Reader.ReadSubStmt()); + S->getCapturedDecl()->setBody(S->getCapturedStmt()); + + // Captures + for (CapturedStmt::capture_iterator I = S->capture_begin(), + E = S->capture_end(); + I != E; ++I) { + I->VarAndKind.setPointer(ReadDeclAs<VarDecl>(Record, Idx)); + I->VarAndKind + .setInt(static_cast<CapturedStmt::VariableCaptureKind>(Record[Idx++])); + I->Loc = ReadSourceLocation(Record, Idx); + } } void ASTStmtReader::VisitExpr(Expr *E) { @@ -1226,6 +1309,12 @@ void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { E->Loc = ReadSourceLocation(Record, Idx); } +void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { + VisitExpr(E); + E->Field = ReadDeclAs<FieldDecl>(Record, Idx); + E->Loc = ReadSourceLocation(Record, Idx); +} + void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { VisitExpr(E); E->setTemporary(Reader.ReadCXXTemporary(F, Record, Idx)); @@ -1498,6 +1587,15 @@ void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { //===----------------------------------------------------------------------===// // Microsoft Expressions and Statements //===----------------------------------------------------------------------===// +void ASTStmtReader::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) { + VisitExpr(E); + E->IsArrow = (Record[Idx++] != 0); + E->BaseExpr = Reader.ReadSubExpr(); + E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); + E->MemberLoc = ReadSourceLocation(Record, Idx); + E->TheDecl = ReadDeclAs<MSPropertyDecl>(Record, Idx); +} + void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) { VisitExpr(E); E->setSourceRange(ReadSourceRange(Record, Idx)); @@ -1715,6 +1813,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) MSAsmStmt(Empty); break; + case STMT_CAPTURED: + S = CapturedStmt::CreateDeserialized(Context, + Record[ASTStmtReader::NumExprFields]); + break; + case EXPR_PREDEFINED: S = new (Context) PredefinedExpr(Empty); break; @@ -2073,6 +2176,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case EXPR_CXX_UUIDOF_EXPR: S = new (Context) CXXUuidofExpr(Empty, true); break; + case EXPR_CXX_PROPERTY_REF_EXPR: + S = new (Context) MSPropertyRefExpr(Empty); + break; case EXPR_CXX_UUIDOF_TYPE: S = new (Context) CXXUuidofExpr(Empty, false); break; @@ -2091,6 +2197,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) CXXDefaultArgExpr(Empty); break; } + case EXPR_CXX_DEFAULT_INIT: + S = new (Context) CXXDefaultInitExpr(Empty); + break; case EXPR_CXX_BIND_TEMPORARY: S = new (Context) CXXBindTemporaryExpr(Empty); break; diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index cf93d1c..b8ada04 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -245,6 +245,9 @@ void ASTTypeWriter::VisitUnaryTransformType(const UnaryTransformType *T) { void ASTTypeWriter::VisitAutoType(const AutoType *T) { Writer.AddTypeRef(T->getDeducedType(), Record); + Record.push_back(T->isDecltypeAuto()); + if (T->getDeducedType().isNull()) + Record.push_back(T->isDependentType()); Code = TYPE_AUTO; } @@ -907,6 +910,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_OBJC_PROPERTY); RECORD(DECL_OBJC_PROPERTY_IMPL); RECORD(DECL_FIELD); + RECORD(DECL_MS_PROPERTY); RECORD(DECL_VAR); RECORD(DECL_IMPLICIT_PARAM); RECORD(DECL_PARM_VAR); @@ -1069,6 +1073,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, I != IEnd; ++I) { AddString(*I, Record); } + Record.push_back(LangOpts.CommentOpts.ParseAllComments); Stream.EmitRecord(LANGUAGE_OPTIONS, Record); @@ -1167,6 +1172,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, AddString(PPOpts.MacroIncludes[I], Record); Record.push_back(PPOpts.UsePredefines); + // Detailed record is important since it is used for the module cache hash. + Record.push_back(PPOpts.DetailedRecord); AddString(PPOpts.ImplicitPCHInclude, Record); AddString(PPOpts.ImplicitPTHInclude, Record); Record.push_back(static_cast<unsigned>(PPOpts.ObjCXXARCStandardLibrary)); @@ -2005,18 +2012,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { // 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()); - + AddToken(Tok, Record); Stream.EmitRecord(PP_TOKEN, Record); Record.clear(); } @@ -2690,11 +2686,11 @@ public: clang::io::Emit16(Out, KeyLen); unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts for (const ObjCMethodList *Method = &Methods.Instance; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) DataLen += 4; for (const ObjCMethodList *Method = &Methods.Factory; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) DataLen += 4; clang::io::Emit16(Out, DataLen); @@ -2720,24 +2716,31 @@ public: clang::io::Emit32(Out, Methods.ID); unsigned NumInstanceMethods = 0; for (const ObjCMethodList *Method = &Methods.Instance; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) ++NumInstanceMethods; unsigned NumFactoryMethods = 0; for (const ObjCMethodList *Method = &Methods.Factory; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) ++NumFactoryMethods; - clang::io::Emit16(Out, NumInstanceMethods); - clang::io::Emit16(Out, NumFactoryMethods); + unsigned InstanceBits = Methods.Instance.getBits(); + assert(InstanceBits < 4); + unsigned NumInstanceMethodsAndBits = + (NumInstanceMethods << 2) | InstanceBits; + unsigned FactoryBits = Methods.Factory.getBits(); + assert(FactoryBits < 4); + unsigned NumFactoryMethodsAndBits = (NumFactoryMethods << 2) | FactoryBits; + clang::io::Emit16(Out, NumInstanceMethodsAndBits); + clang::io::Emit16(Out, NumFactoryMethodsAndBits); for (const ObjCMethodList *Method = &Methods.Instance; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); for (const ObjCMethodList *Method = &Methods.Factory; Method; - Method = Method->Next) + Method = Method->getNext()) if (Method->Method) clang::io::Emit32(Out, Writer.getDeclID(Method->Method)); @@ -2786,12 +2789,12 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { // Selector already exists. Did it change? bool changed = false; for (ObjCMethodList *M = &Data.Instance; !changed && M && M->Method; - M = M->Next) { + M = M->getNext()) { if (!M->Method->isFromASTFile()) changed = true; } for (ObjCMethodList *M = &Data.Factory; !changed && M && M->Method; - M = M->Next) { + M = M->getNext()) { if (!M->Method->isFromASTFile()) changed = true; } @@ -3096,7 +3099,28 @@ public: for (SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(), DEnd = Decls.rend(); D != DEnd; ++D) - clang::io::Emit32(Out, Writer.getDeclID(*D)); + clang::io::Emit32(Out, Writer.getDeclID(getMostRecentLocalDecl(*D))); + } + + /// \brief Returns the most recent local decl or the given decl if there are + /// no local ones. The given decl is assumed to be the most recent one. + Decl *getMostRecentLocalDecl(Decl *Orig) { + // The only way a "from AST file" decl would be more recent from a local one + // is if it came from a module. + if (!PP.getLangOpts().Modules) + return Orig; + + // Look for a local in the decl chain. + for (Decl *D = Orig; D; D = D->getPreviousDecl()) { + if (!D->isFromASTFile()) + return D; + // If we come up a decl from a (chained-)PCH stop since we won't find a + // local one. + if (D->getOwningModuleID() == 0) + break; + } + + return Orig; } }; } // end anonymous namespace @@ -3626,6 +3650,19 @@ void ASTWriter::WriteAttributes(ArrayRef<const Attr*> Attrs, } } +void ASTWriter::AddToken(const Token &Tok, RecordDataImpl &Record) { + AddSourceLocation(Tok.getLocation(), Record); + 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()); +} + void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) { Record.push_back(Str.size()); Record.insert(Record.end(), Str.begin(), Str.end()); diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 023599d..67349db 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -81,6 +81,7 @@ namespace clang { void VisitCXXDestructorDecl(CXXDestructorDecl *D); void VisitCXXConversionDecl(CXXConversionDecl *D); void VisitFieldDecl(FieldDecl *D); + void VisitMSPropertyDecl(MSPropertyDecl *D); void VisitIndirectFieldDecl(IndirectFieldDecl *D); void VisitVarDecl(VarDecl *D); void VisitImplicitParamDecl(ImplicitParamDecl *D); @@ -102,6 +103,7 @@ namespace clang { void VisitFriendTemplateDecl(FriendTemplateDecl *D); void VisitStaticAssertDecl(StaticAssertDecl *D); void VisitBlockDecl(BlockDecl *D); + void VisitCapturedDecl(CapturedDecl *D); void VisitEmptyDecl(EmptyDecl *D); void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, @@ -611,6 +613,7 @@ void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { void ASTDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { VisitObjCImplDecl(D); Writer.AddDeclRef(D->getSuperClass(), Record); + Writer.AddSourceLocation(D->getSuperClassLoc(), Record); Writer.AddSourceLocation(D->getIvarLBraceLoc(), Record); Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record); Record.push_back(D->hasNonZeroConstructors()); @@ -662,6 +665,13 @@ void ASTDeclWriter::VisitFieldDecl(FieldDecl *D) { Code = serialization::DECL_FIELD; } +void ASTDeclWriter::VisitMSPropertyDecl(MSPropertyDecl *D) { + VisitDeclaratorDecl(D); + Writer.AddIdentifierRef(D->getGetterId(), Record); + Writer.AddIdentifierRef(D->getSetterId(), Record); + Code = serialization::DECL_MS_PROPERTY; +} + void ASTDeclWriter::VisitIndirectFieldDecl(IndirectFieldDecl *D) { VisitValueDecl(D); Record.push_back(D->getChainingSize()); @@ -677,7 +687,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { VisitRedeclarable(D); VisitDeclaratorDecl(D); Record.push_back(D->getStorageClass()); - Record.push_back(D->isThreadSpecified()); + Record.push_back(D->getTSCSpec()); Record.push_back(D->getInitStyle()); Record.push_back(D->isExceptionVariable()); Record.push_back(D->isNRVOVariable()); @@ -766,7 +776,7 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { // Check things we know are true of *every* PARM_VAR_DECL, which is more than // just us assuming it. - assert(!D->isThreadSpecified() && "PARM_VAR_DECL can't be __thread"); + assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS"); assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private"); assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var"); assert(D->getPreviousDecl() == 0 && "PARM_VAR_DECL can't be redecl"); @@ -816,6 +826,15 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) { Code = serialization::DECL_BLOCK; } +void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) { + Record.push_back(CD->getNumParams()); + VisitDecl(CD); + // Body is stored by VisitCapturedStmt. + for (unsigned i = 0; i < CD->getNumParams(); ++i) + Writer.AddDeclRef(CD->getParam(i), Record); + Code = serialization::DECL_CAPTURED; +} + void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { VisitDecl(D); Record.push_back(D->getLanguage()); @@ -1515,7 +1534,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo // VarDecl Abv->Add(BitCodeAbbrevOp(0)); // StorageClass - Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified + Abv->Add(BitCodeAbbrevOp(0)); // getTSCSpec Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer Abv->Add(BitCodeAbbrevOp(0)); // isExceptionVariable Abv->Add(BitCodeAbbrevOp(0)); // isNRVOVariable @@ -1594,7 +1613,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo // VarDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // StorageClass - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isThreadSpecified + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // getTSCSpec Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // CXXDirectInitializer Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isExceptionVariable Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNRVOVariable diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index b6f1d54..5f7ac01 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Lex/Token.h" #include "llvm/Bitcode/BitstreamWriter.h" using namespace clang; @@ -216,15 +217,19 @@ void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) { Code = serialization::STMT_DECL; } -void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) { +void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) { VisitStmt(S); Record.push_back(S->getNumOutputs()); Record.push_back(S->getNumInputs()); Record.push_back(S->getNumClobbers()); Writer.AddSourceLocation(S->getAsmLoc(), Record); - Writer.AddSourceLocation(S->getRParenLoc(), Record); Record.push_back(S->isVolatile()); Record.push_back(S->isSimple()); +} + +void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) { + VisitAsmStmt(S); + Writer.AddSourceLocation(S->getRParenLoc(), Record); Writer.AddStmt(S->getAsmString()); // Outputs @@ -249,12 +254,72 @@ void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) { } void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) { - // FIXME: Statement writer not yet implemented for MS style inline asm. - VisitStmt(S); + VisitAsmStmt(S); + Writer.AddSourceLocation(S->getLBraceLoc(), Record); + Writer.AddSourceLocation(S->getEndLoc(), Record); + Record.push_back(S->getNumAsmToks()); + Writer.AddString(S->getAsmString(), Record); + + // Tokens + for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) { + Writer.AddToken(S->getAsmToks()[I], Record); + } + + // Clobbers + for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) { + Writer.AddString(S->getClobber(I), Record); + } + + // Outputs + for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) { + Writer.AddStmt(S->getOutputExpr(I)); + Writer.AddString(S->getOutputConstraint(I), Record); + } + + // Inputs + for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) { + Writer.AddStmt(S->getInputExpr(I)); + Writer.AddString(S->getInputConstraint(I), Record); + } Code = serialization::STMT_MSASM; } +void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) { + VisitStmt(S); + // NumCaptures + Record.push_back(std::distance(S->capture_begin(), S->capture_end())); + + // CapturedDecl and captured region kind + Writer.AddDeclRef(S->getCapturedDecl(), Record); + Record.push_back(S->getCapturedRegionKind()); + + Writer.AddDeclRef(S->getCapturedRecordDecl(), Record); + + // Capture inits + for (CapturedStmt::capture_init_iterator I = S->capture_init_begin(), + E = S->capture_init_end(); + I != E; ++I) + Writer.AddStmt(*I); + + // Body + Writer.AddStmt(S->getCapturedStmt()); + + // Captures + for (CapturedStmt::capture_iterator I = S->capture_begin(), + E = S->capture_end(); + I != E; ++I) { + if (I->capturesThis()) + Writer.AddDeclRef(0, Record); + else + Writer.AddDeclRef(I->getCapturedVar(), Record); + Record.push_back(I->getCaptureKind()); + Writer.AddSourceLocation(I->getLocation(), Record); + } + + Code = serialization::STMT_CAPTURED; +} + void ASTStmtWriter::VisitExpr(Expr *E) { VisitStmt(E); Writer.AddTypeRef(E->getType(), Record); @@ -1216,6 +1281,13 @@ void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { Code = serialization::EXPR_CXX_DEFAULT_ARG; } +void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { + VisitExpr(E); + Writer.AddDeclRef(E->getField(), Record); + Writer.AddSourceLocation(E->getExprLoc(), Record); + Code = serialization::EXPR_CXX_DEFAULT_INIT; +} + void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { VisitExpr(E); Writer.AddCXXTemporary(E->getTemporary(), Record); @@ -1534,6 +1606,16 @@ void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) { //===----------------------------------------------------------------------===// // Microsoft Expressions and Statements. //===----------------------------------------------------------------------===// +void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) { + VisitExpr(E); + Record.push_back(E->isArrow()); + Writer.AddStmt(E->getBaseExpr()); + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); + Writer.AddSourceLocation(E->getMemberLoc(), Record); + Writer.AddDeclRef(E->getPropertyDecl(), Record); + Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR; +} + void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) { VisitExpr(E); Writer.AddSourceRange(E->getSourceRange(), Record); diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp index f9acb84..b6693e4 100644 --- a/lib/Serialization/GlobalModuleIndex.cpp +++ b/lib/Serialization/GlobalModuleIndex.cpp @@ -818,3 +818,34 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, StringRef Path) { // We're done. return EC_None; } + +namespace { + class GlobalIndexIdentifierIterator : public IdentifierIterator { + /// \brief The current position within the identifier lookup table. + IdentifierIndexTable::key_iterator Current; + + /// \brief The end position within the identifier lookup table. + IdentifierIndexTable::key_iterator End; + + public: + explicit GlobalIndexIdentifierIterator(IdentifierIndexTable &Idx) { + Current = Idx.key_begin(); + End = Idx.key_end(); + } + + virtual StringRef Next() { + if (Current == End) + return StringRef(); + + StringRef Result = *Current; + ++Current; + return Result; + } + }; +} + +IdentifierIterator *GlobalModuleIndex::createIdentifierIterator() const { + IdentifierIndexTable &Table = + *static_cast<IdentifierIndexTable *>(IdentifierIndex); + return new GlobalIndexIdentifierIterator(Table); +} |