diff options
author | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-21 17:53:59 +0000 |
commit | 9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch) | |
tree | c978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/tools/clang/lib/Serialization | |
parent | 03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff) | |
download | FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz |
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports
all of the features in the current working draft of the upcoming C++
standard, provisionally named C++1y.
The code generator's performance is greatly increased, and the loop
auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The
PowerPC backend has made several major improvements to code generation
quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ
backends have all seen major feature work.
Release notes for llvm and clang can be found here:
<http://llvm.org/releases/3.4/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html>
MFC 262121 (by emaste):
Update lldb for clang/llvm 3.4 import
This commit largely restores the lldb source to the upstream r196259
snapshot with the addition of threaded inferior support and a few bug
fixes.
Specific upstream lldb revisions restored include:
SVN git
181387 779e6ac
181703 7bef4e2
182099 b31044e
182650 f2dcf35
182683 0d91b80
183862 15c1774
183929 99447a6
184177 0b2934b
184948 4dc3761
184954 007e7bc
186990 eebd175
Sponsored by: DARPA, AFRL
MFC 262186 (by emaste):
Fix mismerge in r262121
A break statement was lost in the merge. The error had no functional
impact, but restore it to reduce the diff against upstream.
MFC 262303:
Pull in r197521 from upstream clang trunk (by rdivacky):
Use the integrated assembler by default on FreeBSD/ppc and ppc64.
Requested by: jhibbits
MFC 262611:
Pull in r196874 from upstream llvm trunk:
Fix a crash that occurs when PWD is invalid.
MCJIT needs to be able to run in hostile environments, even when PWD
is invalid. There's no need to crash MCJIT in this case.
The obvious fix is to simply leave MCContext's CompilationDir empty
when PWD can't be determined. This way, MCJIT clients,
and other clients that link with LLVM don't need a valid working directory.
If we do want to guarantee valid CompilationDir, that should be done
only for clients of getCompilationDir(). This is as simple as checking
for an empty string.
The only current use of getCompilationDir is EmitGenDwarfInfo, which
won't conceivably run with an invalid working dir. However, in the
purely hypothetically and untestable case that this happens, the
AT_comp_dir will be omitted from the compilation_unit DIE.
This should help fix assertions occurring with ports-mgmt/tinderbox,
when it is using jails, and sometimes invalidates clang's current
working directory.
Reported by: decke
MFC 262809:
Pull in r203007 from upstream clang trunk:
Don't produce an alias between destructors with different calling conventions.
Fixes pr19007.
(Please note that is an LLVM PR identifier, not a FreeBSD one.)
This should fix Firefox and/or libxul crashes (due to problems with
regparm/stdcall calling conventions) on i386.
Reported by: multiple users on freebsd-current
PR: bin/187103
MFC 263048:
Repair recognition of "CC" as an alias for the C++ compiler, since it
was silently broken by upstream for a Windows-specific use-case.
Apparently some versions of CMake still rely on this archaic feature...
Reported by: rakuco
MFC 263049:
Garbage collect the old way of adding the libstdc++ include directories
in clang's InitHeaderSearch.cpp. This has been superseded by David
Chisnall's commit in r255321.
Moreover, if libc++ is used, the libstdc++ include directories should
not be in the search path at all. These directories are now only used
if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization')
11 files changed, 1412 insertions, 354 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp index 24b268f..a817687 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.cpp @@ -158,14 +158,18 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::CXXRecord: case Decl::ClassTemplateSpecialization: case Decl::ClassTemplatePartialSpecialization: + case Decl::VarTemplateSpecialization: + case Decl::VarTemplatePartialSpecialization: case Decl::Function: case Decl::CXXMethod: case Decl::CXXConstructor: case Decl::CXXDestructor: case Decl::CXXConversion: + case Decl::UsingShadow: case Decl::Var: case Decl::FunctionTemplate: case Decl::ClassTemplate: + case Decl::VarTemplate: case Decl::TypeAliasTemplate: case Decl::ObjCProtocol: case Decl::ObjCInterface: @@ -189,7 +193,6 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::NonTypeTemplateParm: case Decl::TemplateTemplateParm: case Decl::Using: - case Decl::UsingShadow: case Decl::ObjCMethod: case Decl::ObjCCategory: case Decl::ObjCCategoryImpl: diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h index 76ef904..ef81e69 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTCommon.h @@ -25,7 +25,9 @@ enum DeclUpdateKind { UPD_CXX_ADDED_IMPLICIT_MEMBER, UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, - UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER + UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER, + UPD_CXX_DEDUCED_RETURN_TYPE, + UPD_DECL_MARKED_USED }; TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT); diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp index 22caeb8..4d1b4b9 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp @@ -210,6 +210,8 @@ bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts, namespace { typedef llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> > MacroDefinitionsMap; + typedef llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > + DeclsMap; } /// \brief Collect the macro definitions provided by the given preprocessor @@ -377,12 +379,6 @@ bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, PP.getLangOpts()); } -void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI, - unsigned ID) { - PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, ID); - ++NumHeaderInfos; -} - void PCHValidator::ReadCounter(const ModuleFile &M, unsigned Value) { PP.setCounterValue(Value); } @@ -765,6 +761,10 @@ bool ASTReader::ReadDeclContextStorage(ModuleFile &M, void ASTReader::Error(StringRef Msg) { Error(diag::err_fe_pch_malformed, Msg); + if (Context.getLangOpts().Modules && !Diags.isDiagnosticInFlight()) { + Diag(diag::note_module_cache_path) + << PP.getHeaderSearchInfo().getModuleCachePath(); + } } void ASTReader::Error(unsigned DiagID, @@ -1103,7 +1103,7 @@ bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) { } } -Token ASTReader::ReadToken(ModuleFile &F, const RecordData &Record, +Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record, unsigned &Idx) { Token Tok; Tok.startToken(); @@ -1283,6 +1283,8 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, using namespace clang::io; HeaderFileInfo HFI; unsigned Flags = *d++; + HFI.HeaderRole = static_cast<ModuleMap::ModuleHeaderRole> + ((Flags >> 6) & 0x03); HFI.isImport = (Flags >> 5) & 0x01; HFI.isPragmaOnce = (Flags >> 4) & 0x01; HFI.DirInfo = (Flags >> 2) & 0x03; @@ -1309,7 +1311,7 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, FileManager &FileMgr = Reader.getFileManager(); ModuleMap &ModMap = Reader.getPreprocessor().getHeaderSearchInfo().getModuleMap(); - ModMap.addHeader(Mod, FileMgr.getFile(key.Filename), /*Excluded=*/false); + ModMap.addHeader(Mod, FileMgr.getFile(key.Filename), HFI.getHeaderRole()); } } @@ -1587,18 +1589,21 @@ void ASTReader::installPCHMacroDirectives(IdentifierInfo *II, /// \brief For the given macro definitions, check if they are both in system /// modules. static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI, - Module *NewOwner, ASTReader &Reader) { + Module *NewOwner, ASTReader &Reader) { assert(PrevMI && NewMI); - if (!NewOwner) - return false; Module *PrevOwner = 0; if (SubmoduleID PrevModID = PrevMI->getOwningModuleID()) PrevOwner = Reader.getSubmodule(PrevModID); - if (!PrevOwner) - return false; - if (PrevOwner == NewOwner) + SourceManager &SrcMgr = Reader.getSourceManager(); + bool PrevInSystem + = PrevOwner? PrevOwner->IsSystem + : SrcMgr.isInSystemHeader(PrevMI->getDefinitionLoc()); + bool NewInSystem + = NewOwner? NewOwner->IsSystem + : SrcMgr.isInSystemHeader(NewMI->getDefinitionLoc()); + if (PrevOwner && PrevOwner == NewOwner) return false; - return PrevOwner->IsSystem && NewOwner->IsSystem; + return PrevInSystem && NewInSystem; } void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD, @@ -1721,6 +1726,10 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { )) { if (Complain) { Error(diag::err_fe_pch_file_modified, Filename, F.FileName); + if (Context.getLangOpts().Modules && !Diags.isDiagnosticInFlight()) { + Diag(diag::note_module_cache_path) + << PP.getHeaderSearchInfo().getModuleCachePath(); + } } IsOutOfDate = true; @@ -2515,9 +2524,10 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) { break; case SEMA_DECL_REFS: - // Later tables overwrite earlier ones. - // FIXME: Modules will have some trouble with this. - SemaDeclRefs.clear(); + if (Record.size() != 2) { + Error("Invalid SEMA_DECL_REFS block"); + return true; + } for (unsigned I = 0, N = Record.size(); I != N; ++I) SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I])); break; @@ -2742,6 +2752,11 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) { // FIXME: Not used yet. break; } + + case LATE_PARSED_TEMPLATE: { + LateParsedTemplates.append(Record.begin(), Record.end()); + break; + } } } } @@ -2805,13 +2820,12 @@ void ASTReader::makeModuleVisible(Module *Mod, bool Complain) { llvm::SmallPtrSet<Module *, 4> Visited; SmallVector<Module *, 4> Stack; - Stack.push_back(Mod); + Stack.push_back(Mod); while (!Stack.empty()) { - Mod = Stack.back(); - Stack.pop_back(); + Mod = Stack.pop_back_val(); if (NameVisibility <= Mod->NameVisibility) { - // This module already has this level of visibility (or greater), so + // This module already has this level of visibility (or greater), so // there is nothing more to do. continue; } @@ -2831,16 +2845,7 @@ void ASTReader::makeModuleVisible(Module *Mod, makeNamesVisible(Hidden->second, Hidden->first); HiddenNamesMap.erase(Hidden); } - - // Push any non-explicit submodules onto the stack to be marked as - // visible. - for (Module::submodule_iterator Sub = Mod->submodule_begin(), - SubEnd = Mod->submodule_end(); - Sub != SubEnd; ++Sub) { - if (!(*Sub)->IsExplicit && Visited.insert(*Sub)) - Stack.push_back(*Sub); - } - + // Push any exported modules onto the stack to be marked as visible. SmallVector<Module *, 16> Exports; Mod->getExportedModules(Exports); @@ -2898,6 +2903,9 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, ModuleKind Type, SourceLocation ImportLoc, unsigned ClientLoadCapabilities) { + llvm::SaveAndRestore<SourceLocation> + SetCurImportLocRAII(CurrentImportLoc, ImportLoc); + // Bump the generation number. unsigned PreviousGeneration = CurrentGeneration++; @@ -3012,9 +3020,16 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, } } UnresolvedModuleRefs.clear(); + + // FIXME: How do we load the 'use'd modules? They may not be submodules. + // Might be unnecessary as use declarations are only used to build the + // module itself. InitializeContext(); + if (SemaObj) + UpdateSema(); + if (DeserializationListener) DeserializationListener->ReaderInitialized(this); @@ -3759,6 +3774,21 @@ bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) { break; } + case SUBMODULE_PRIVATE_HEADER: { + if (First) { + Error("missing submodule metadata record at beginning of block"); + return true; + } + + if (!CurrentModule) + break; + + // We lazily associate headers with their modules via the HeaderInfoTable. + // FIXME: Re-evaluate this section; maybe only store InputFile IDs instead + // of complete filenames or remove it entirely. + break; + } + case SUBMODULE_TOPHEADER: { if (First) { Error("missing submodule metadata record at beginning of block"); @@ -3873,7 +3903,7 @@ bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) { if (!CurrentModule) break; - CurrentModule->addRequirement(Blob, Context.getLangOpts(), + CurrentModule->addRequirement(Blob, Record[0], Context.getLangOpts(), Context.getTargetInfo()); break; } @@ -4394,11 +4424,8 @@ namespace { HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { HeaderFileInfoVisitor Visitor(FE); ModuleMgr.visit(&HeaderFileInfoVisitor::visit, &Visitor); - if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo()) { - if (Listener) - Listener->ReadHeaderFileInfo(*HFI, FE->getUID()); + if (Optional<HeaderFileInfo> HFI = Visitor.getHeaderFileInfo()) return *HFI; - } return HeaderFileInfo(); } @@ -4509,6 +4536,18 @@ QualType ASTReader::readTypeRecord(unsigned Index) { return Context.getPointerType(PointeeType); } + case TYPE_DECAYED: { + if (Record.size() != 1) { + Error("Incorrect encoding of decayed type"); + return QualType(); + } + QualType OriginalType = readType(*Loc.F, Record, Idx); + QualType DT = Context.getAdjustedParameterType(OriginalType); + if (!isa<DecayedType>(DT)) + Error("Decayed type does not decay"); + return DT; + } + case TYPE_BLOCK_POINTER: { if (Record.size() != 1) { Error("Incorrect encoding of block pointer type"); @@ -4955,6 +4994,9 @@ void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) { void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) { TL.setStarLoc(ReadSourceLocation(Record, Idx)); } +void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) { + // nothing to do +} void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { TL.setCaretLoc(ReadSourceLocation(Record, Idx)); } @@ -5315,6 +5357,19 @@ ASTReader::ReadTemplateArgumentLoc(ModuleFile &F, Record, Index)); } +const ASTTemplateArgumentListInfo* +ASTReader::ReadASTTemplateArgumentListInfo(ModuleFile &F, + const RecordData &Record, + unsigned &Index) { + SourceLocation LAngleLoc = ReadSourceLocation(F, Record, Index); + SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Index); + unsigned NumArgsAsWritten = Record[Index++]; + TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc); + for (unsigned i = 0; i != NumArgsAsWritten; ++i) + TemplArgsInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Index)); + return ASTTemplateArgumentListInfo::Create(getContext(), TemplArgsInfo); +} + Decl *ASTReader::GetExternalDecl(uint32_t ID) { return GetDecl(ID); } @@ -5775,15 +5830,13 @@ namespace { class DeclContextAllNamesVisitor { ASTReader &Reader; SmallVectorImpl<const DeclContext *> &Contexts; - llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > &Decls; + DeclsMap &Decls; bool VisitAll; public: DeclContextAllNamesVisitor(ASTReader &Reader, SmallVectorImpl<const DeclContext *> &Contexts, - llvm::DenseMap<DeclarationName, - SmallVector<NamedDecl *, 8> > &Decls, - bool VisitAll) + DeclsMap &Decls, bool VisitAll) : Reader(Reader), Contexts(Contexts), Decls(Decls), VisitAll(VisitAll) { } static bool visit(ModuleFile &M, void *UserData) { @@ -5834,7 +5887,7 @@ namespace { void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) { if (!DC->hasExternalVisibleStorage()) return; - llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > Decls; + DeclsMap Decls; // Compute the declaration contexts we need to look into. Multiple such // declaration contexts occur when two declaration contexts from disjoint @@ -5857,9 +5910,7 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) { ModuleMgr.visit(&DeclContextAllNamesVisitor::visit, &Visitor); ++NumVisibleDeclContextsRead; - for (llvm::DenseMap<DeclarationName, - SmallVector<NamedDecl *, 8> >::iterator - I = Decls.begin(), E = Decls.end(); I != E; ++I) { + for (DeclsMap::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) { SetExternalVisibleDeclsForName(DC, I->first, I->second); } const_cast<DeclContext *>(DC)->setHasExternalVisibleStorage(false); @@ -6080,21 +6131,13 @@ void ASTReader::InitializeSema(Sema &S) { } PreloadedDecls.clear(); - // Load the offsets of the declarations that Sema references. - // They will be lazily deserialized when needed. - if (!SemaDeclRefs.empty()) { - assert(SemaDeclRefs.size() == 2 && "More decl refs than expected!"); - if (!SemaObj->StdNamespace) - SemaObj->StdNamespace = SemaDeclRefs[0]; - if (!SemaObj->StdBadAlloc) - SemaObj->StdBadAlloc = SemaDeclRefs[1]; - } - + // FIXME: What happens if these are changed by a module import? if (!FPPragmaOptions.empty()) { assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS"); SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0]; } + // FIXME: What happens if these are changed by a module import? if (!OpenCLExtensions.empty()) { unsigned I = 0; #define OPENCLEXT(nm) SemaObj->OpenCLFeatures.nm = OpenCLExtensions[I++]; @@ -6102,6 +6145,25 @@ void ASTReader::InitializeSema(Sema &S) { assert(OpenCLExtensions.size() == I && "Wrong number of OPENCL_EXTENSIONS"); } + + UpdateSema(); +} + +void ASTReader::UpdateSema() { + assert(SemaObj && "no Sema to update"); + + // Load the offsets of the declarations that Sema references. + // They will be lazily deserialized when needed. + if (!SemaDeclRefs.empty()) { + assert(SemaDeclRefs.size() % 2 == 0); + for (unsigned I = 0; I != SemaDeclRefs.size(); I += 2) { + if (!SemaObj->StdNamespace) + SemaObj->StdNamespace = SemaDeclRefs[I]; + if (!SemaObj->StdBadAlloc) + SemaObj->StdBadAlloc = SemaDeclRefs[I+1]; + } + SemaDeclRefs.clear(); + } } IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) { @@ -6440,6 +6502,29 @@ void ASTReader::ReadPendingInstantiations( PendingInstantiations.clear(); } +void ASTReader::ReadLateParsedTemplates( + llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) { + for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N; + /* In loop */) { + FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++])); + + LateParsedTemplate *LT = new LateParsedTemplate; + LT->D = GetDecl(LateParsedTemplates[Idx++]); + + ModuleFile *F = getOwningModuleFile(LT->D); + assert(F && "No module"); + + unsigned TokN = LateParsedTemplates[Idx++]; + LT->Toks.reserve(TokN); + for (unsigned T = 0; T < TokN; ++T) + LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx)); + + LPTMap[FD] = LT; + } + + LateParsedTemplates.clear(); +} + void ASTReader::LoadSelector(Selector Sel) { // It would be complicated to avoid reading the methods anyway. So don't. ReadMethodPool(Sel); @@ -6887,7 +6972,7 @@ ASTReader::ReadTemplateParameterList(ModuleFile &F, void ASTReader:: -ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs, +ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, ModuleFile &F, const RecordData &Record, unsigned &Idx) { unsigned NumTemplateArgs = Record[Idx++]; @@ -6897,14 +6982,14 @@ ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs, } /// \brief Read a UnresolvedSet structure. -void ASTReader::ReadUnresolvedSet(ModuleFile &F, ASTUnresolvedSet &Set, +void ASTReader::ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set, const RecordData &Record, unsigned &Idx) { unsigned NumDecls = Record[Idx++]; Set.reserve(Context, NumDecls); while (NumDecls--) { - NamedDecl *D = ReadDeclAs<NamedDecl>(F, Record, Idx); + DeclID ID = ReadDeclID(F, Record, Idx); AccessSpecifier AS = (AccessSpecifier)Record[Idx++]; - Set.addDecl(Context, D, AS); + Set.addLazyDecl(Context, ID, AS); } } @@ -6991,9 +7076,16 @@ ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, MemberOrEllipsisLoc, LParenLoc, Init, RParenLoc); } else { - BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc, - LParenLoc, Init, RParenLoc, - Indices.data(), Indices.size()); + if (IndirectMember) { + assert(Indices.empty() && "Indirect field improperly initialized"); + BOMInit = new (Context) CXXCtorInitializer(Context, IndirectMember, + MemberOrEllipsisLoc, LParenLoc, + Init, RParenLoc); + } else { + BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc, + LParenLoc, Init, RParenLoc, + Indices.data(), Indices.size()); + } } if (IsWritten) @@ -7168,7 +7260,7 @@ CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F, } DiagnosticBuilder ASTReader::Diag(unsigned DiagID) { - return Diag(SourceLocation(), DiagID); + return Diag(CurrentImportLoc, DiagID); } DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) { @@ -7251,10 +7343,14 @@ void ASTReader::ReadComments() { void ASTReader::finishPendingActions() { while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() || - !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty()) { + !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() || + !PendingOdrMergeChecks.empty()) { // If any identifiers with corresponding top-level declarations have // been loaded, load those declarations now. - llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> > TopLevelDecls; + typedef llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> > + TopLevelDeclsMap; + TopLevelDeclsMap TopLevelDecls; + while (!PendingIdentifierInfos.empty()) { // FIXME: std::move IdentifierInfo *II = PendingIdentifierInfos.back().first; @@ -7272,9 +7368,8 @@ void ASTReader::finishPendingActions() { PendingDeclChains.clear(); // Make the most recent of the top-level declarations visible. - for (llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> >::iterator - TLD = TopLevelDecls.begin(), TLDEnd = TopLevelDecls.end(); - TLD != TLDEnd; ++TLD) { + for (TopLevelDeclsMap::iterator TLD = TopLevelDecls.begin(), + TLDEnd = TopLevelDecls.end(); TLD != TLDEnd; ++TLD) { IdentifierInfo *II = TLD->first; for (unsigned I = 0, N = TLD->second.size(); I != N; ++I) { pushExternalDeclIntoScope(cast<NamedDecl>(TLD->second[I]), II); @@ -7312,6 +7407,64 @@ void ASTReader::finishPendingActions() { DeclContext *LexicalDC = cast<DeclContext>(GetDecl(Info.LexicalDC)); Info.D->setDeclContextsImpl(SemaDC, LexicalDC, getContext()); } + + // For each declaration from a merged context, check that the canonical + // definition of that context also contains a declaration of the same + // entity. + while (!PendingOdrMergeChecks.empty()) { + NamedDecl *D = PendingOdrMergeChecks.pop_back_val(); + + // FIXME: Skip over implicit declarations for now. This matters for things + // like implicitly-declared special member functions. This isn't entirely + // correct; we can end up with multiple unmerged declarations of the same + // implicit entity. + if (D->isImplicit()) + continue; + + DeclContext *CanonDef = D->getDeclContext(); + DeclContext::lookup_result R = CanonDef->lookup(D->getDeclName()); + + bool Found = false; + const Decl *DCanon = D->getCanonicalDecl(); + + llvm::SmallVector<const NamedDecl*, 4> Candidates; + for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); + !Found && I != E; ++I) { + for (Decl::redecl_iterator RI = (*I)->redecls_begin(), + RE = (*I)->redecls_end(); + RI != RE; ++RI) { + if ((*RI)->getLexicalDeclContext() == CanonDef) { + // This declaration is present in the canonical definition. If it's + // in the same redecl chain, it's the one we're looking for. + if ((*RI)->getCanonicalDecl() == DCanon) + Found = true; + else + Candidates.push_back(cast<NamedDecl>(*RI)); + break; + } + } + } + + if (!Found) { + D->setInvalidDecl(); + + Module *CanonDefModule = cast<Decl>(CanonDef)->getOwningModule(); + Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl) + << D << D->getOwningModule()->getFullModuleName() + << CanonDef << !CanonDefModule + << (CanonDefModule ? CanonDefModule->getFullModuleName() : ""); + + if (Candidates.empty()) + Diag(cast<Decl>(CanonDef)->getLocation(), + diag::note_module_odr_violation_no_possible_decls) << D; + else { + for (unsigned I = 0, N = Candidates.size(); I != N; ++I) + Diag(Candidates[I]->getLocation(), + diag::note_module_odr_violation_possible_decl) + << Candidates[I]; + } + } + } } // If we deserialized any C++ or Objective-C class definitions, any @@ -7418,7 +7571,7 @@ void ASTReader::FinishedDeserializing() { } void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { - D = cast<NamedDecl>(D->getMostRecentDecl()); + D = D->getMostRecentDecl(); if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) { SemaObj->TUScope->AddDecl(D); @@ -7454,7 +7607,7 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0), TotalModulesSizeInBits(0), NumCurrentElementsDeserializing(0), PassingDeclsToConsumer(false), - NumCXXBaseSpecifiersLoaded(0) + NumCXXBaseSpecifiersLoaded(0), ReadingKind(Read_None) { SourceMgr.setExternalSLocEntrySource(this); } diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp index f7fa818..b8102d8 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderDecl.cpp @@ -223,16 +223,29 @@ namespace clang { void VisitTypedefDecl(TypedefDecl *TD); void VisitTypeAliasDecl(TypeAliasDecl *TD); void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); - void VisitTagDecl(TagDecl *TD); + RedeclarableResult VisitTagDecl(TagDecl *TD); void VisitEnumDecl(EnumDecl *ED); - void VisitRecordDecl(RecordDecl *RD); - void VisitCXXRecordDecl(CXXRecordDecl *D); - void VisitClassTemplateSpecializationDecl( + RedeclarableResult VisitRecordDeclImpl(RecordDecl *RD); + void VisitRecordDecl(RecordDecl *RD) { VisitRecordDeclImpl(RD); } + RedeclarableResult VisitCXXRecordDeclImpl(CXXRecordDecl *D); + void VisitCXXRecordDecl(CXXRecordDecl *D) { VisitCXXRecordDeclImpl(D); } + RedeclarableResult VisitClassTemplateSpecializationDeclImpl( ClassTemplateSpecializationDecl *D); + void VisitClassTemplateSpecializationDecl( + ClassTemplateSpecializationDecl *D) { + VisitClassTemplateSpecializationDeclImpl(D); + } void VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D); void VisitClassScopeFunctionSpecializationDecl( ClassScopeFunctionSpecializationDecl *D); + RedeclarableResult + VisitVarTemplateSpecializationDeclImpl(VarTemplateSpecializationDecl *D); + void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) { + VisitVarTemplateSpecializationDeclImpl(D); + } + void VisitVarTemplatePartialSpecializationDecl( + VarTemplatePartialSpecializationDecl *D); void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); void VisitValueDecl(ValueDecl *VD); void VisitEnumConstantDecl(EnumConstantDecl *ECD); @@ -246,13 +259,15 @@ namespace clang { void VisitFieldDecl(FieldDecl *FD); void VisitMSPropertyDecl(MSPropertyDecl *FD); void VisitIndirectFieldDecl(IndirectFieldDecl *FD); - void VisitVarDecl(VarDecl *VD); + RedeclarableResult VisitVarDeclImpl(VarDecl *D); + void VisitVarDecl(VarDecl *VD) { VisitVarDeclImpl(VD); } void VisitImplicitParamDecl(ImplicitParamDecl *PD); void VisitParmVarDecl(ParmVarDecl *PD); void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); void VisitTemplateDecl(TemplateDecl *D); RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); + void VisitVarTemplateDecl(VarTemplateDecl *D); void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); @@ -276,7 +291,14 @@ namespace clang { template<typename T> void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl); - + + template<typename T> + void mergeRedeclarable(Redeclarable<T> *D, T *Existing, + RedeclarableResult &Redecl); + + template<typename T> + void mergeMergeable(Mergeable<T> *D); + // FIXME: Reorder according to DeclNodes.td? void VisitObjCMethodDecl(ObjCMethodDecl *D); void VisitObjCContainerDecl(ObjCContainerDecl *D); @@ -348,9 +370,11 @@ void ASTDeclReader::VisitDecl(Decl *D) { } else { DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx); DeclContext *LexicalDC = ReadDeclAs<DeclContext>(Record, Idx); + DeclContext *MergedSemaDC = Reader.MergedDeclContexts.lookup(SemaDC); // Avoid calling setLexicalDeclContext() directly because it uses // Decl::getASTContext() internally which is unsafe during derialization. - D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext()); + D->setDeclContextsImpl(MergedSemaDC ? MergedSemaDC : SemaDC, LexicalDC, + Reader.getContext()); } D->setLocation(Reader.ReadSourceLocation(F, RawLocation)); D->setInvalidDecl(Record[Idx++]); @@ -362,7 +386,7 @@ void ASTDeclReader::VisitDecl(Decl *D) { D->setAttrsImpl(Attrs, Reader.getContext()); } D->setImplicit(Record[Idx++]); - D->setUsed(Record[Idx++]); + D->Used = Record[Idx++]; D->setReferenced(Record[Idx++]); D->setTopLevelDeclInObjCContainer(Record[Idx++]); D->setAccess((AccessSpecifier)Record[Idx++]); @@ -411,8 +435,12 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) { RedeclarableResult Redecl = VisitRedeclarable(TD); VisitTypeDecl(TD); - - TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx)); + TypeSourceInfo *TInfo = GetTypeSourceInfo(Record, Idx); + if (Record[Idx++]) { // isModed + QualType modedT = Reader.readType(F, Record, Idx); + TD->setModedTypeSourceInfo(TInfo, modedT); + } else + TD->setTypeSourceInfo(TInfo); mergeRedeclarable(TD, Redecl); } @@ -424,7 +452,7 @@ void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) { VisitTypedefNameDecl(TD); } -void ASTDeclReader::VisitTagDecl(TagDecl *TD) { +ASTDeclReader::RedeclarableResult ASTDeclReader::VisitTagDecl(TagDecl *TD) { RedeclarableResult Redecl = VisitRedeclarable(TD); VisitTypeDecl(TD); @@ -433,16 +461,18 @@ void ASTDeclReader::VisitTagDecl(TagDecl *TD) { TD->setCompleteDefinition(Record[Idx++]); TD->setEmbeddedInDeclarator(Record[Idx++]); TD->setFreeStanding(Record[Idx++]); + TD->setCompleteDefinitionRequired(Record[Idx++]); TD->setRBraceLoc(ReadSourceLocation(Record, Idx)); if (Record[Idx++]) { // hasExtInfo TagDecl::ExtInfo *Info = new (Reader.getContext()) TagDecl::ExtInfo(); ReadQualifierInfo(*Info, Record, Idx); - TD->TypedefNameDeclOrQualifier = Info; + TD->NamedDeclOrQualifier = Info; } else - TD->setTypedefNameForAnonDecl(ReadDeclAs<TypedefNameDecl>(Record, Idx)); + TD->NamedDeclOrQualifier = ReadDeclAs<NamedDecl>(Record, Idx); - mergeRedeclarable(TD, Redecl); + mergeRedeclarable(TD, Redecl); + return Redecl; } void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { @@ -458,6 +488,19 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { ED->IsScopedUsingClassTag = Record[Idx++]; ED->IsFixed = Record[Idx++]; + // If this is a definition subject to the ODR, and we already have a + // definition, merge this one into it. + if (ED->IsCompleteDefinition && + Reader.getContext().getLangOpts().Modules && + Reader.getContext().getLangOpts().CPlusPlus) { + if (EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()]) { + Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef)); + ED->IsCompleteDefinition = false; + } else { + OldDef = ED; + } + } + if (EnumDecl *InstED = ReadDeclAs<EnumDecl>(Record, Idx)) { TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; SourceLocation POI = ReadSourceLocation(Record, Idx); @@ -466,12 +509,14 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { } } -void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) { - VisitTagDecl(RD); +ASTDeclReader::RedeclarableResult +ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) { + RedeclarableResult Redecl = VisitTagDecl(RD); RD->setHasFlexibleArrayMember(Record[Idx++]); RD->setAnonymousStructOrUnion(Record[Idx++]); RD->setHasObjectMember(Record[Idx++]); RD->setHasVolatileMember(Record[Idx++]); + return Redecl; } void ASTDeclReader::VisitValueDecl(ValueDecl *VD) { @@ -484,6 +529,7 @@ void ASTDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) { if (Record[Idx++]) ECD->setInitExpr(Reader.ReadExpr(F)); ECD->setInitVal(Reader.ReadAPSInt(Record, Idx)); + mergeMergeable(ECD); } void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) { @@ -521,8 +567,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->HasImplicitReturnZero = Record[Idx++]; FD->IsConstexpr = Record[Idx++]; FD->HasSkippedBody = Record[Idx++]; - FD->HasCachedLinkage = true; - FD->CachedLinkage = Record[Idx++]; + FD->IsLateTemplateParsed = Record[Idx++]; + FD->setCachedLinkage(Linkage(Record[Idx++])); FD->EndRangeLoc = ReadSourceLocation(Record, Idx); switch ((FunctionDecl::TemplatedKind)Record[Idx++]) { @@ -594,11 +640,16 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(), TemplArgs.size(), C); void *InsertPos = 0; - CanonTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos); + FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr(); + CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos); if (InsertPos) - CanonTemplate->getSpecializations().InsertNode(FTInfo, InsertPos); - else - assert(0 && "Another specialization already inserted!"); + CommonPtr->Specializations.InsertNode(FTInfo, InsertPos); + else { + assert(Reader.getContext().getLangOpts().Modules && + "already deserialized this template specialization"); + // FIXME: This specialization is a redeclaration of one from another + // module. Merge it. + } } break; } @@ -747,6 +798,8 @@ void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) { IVD->setNextIvar(0); bool synth = Record[Idx++]; IVD->setSynthesize(synth); + bool backingIvarReferencedInAccessor = Record[Idx++]; + IVD->setBackingIvarReferencedInAccessor(backingIvarReferencedInAccessor); } void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { @@ -880,6 +933,7 @@ void ASTDeclReader::VisitFieldDecl(FieldDecl *FD) { if (FieldDecl *Tmpl = ReadDeclAs<FieldDecl>(Record, Idx)) Reader.getContext().setInstantiatedFromUnnamedFieldDecl(FD, Tmpl); } + mergeMergeable(FD); } void ASTDeclReader::VisitMSPropertyDecl(MSPropertyDecl *PD) { @@ -899,7 +953,7 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { FD->Chaining[I] = ReadDeclAs<NamedDecl>(Record, Idx); } -void ASTDeclReader::VisitVarDecl(VarDecl *VD) { +ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { RedeclarableResult Redecl = VisitRedeclarable(VD); VisitDeclaratorDecl(VD); @@ -911,11 +965,18 @@ void ASTDeclReader::VisitVarDecl(VarDecl *VD) { VD->VarDeclBits.CXXForRangeDecl = Record[Idx++]; VD->VarDeclBits.ARCPseudoStrong = Record[Idx++]; VD->VarDeclBits.IsConstexpr = Record[Idx++]; - VD->HasCachedLinkage = true; - VD->CachedLinkage = Record[Idx++]; - + VD->VarDeclBits.IsInitCapture = Record[Idx++]; + VD->VarDeclBits.PreviousDeclInSameBlockScope = Record[Idx++]; + Linkage VarLinkage = Linkage(Record[Idx++]); + VD->setCachedLinkage(VarLinkage); + + // Reconstruct the one piece of the IdentifierNamespace that we need. + if (VarLinkage != NoLinkage && + VD->getLexicalDeclContext()->isFunctionOrMethod()) + VD->setLocalExternDecl(); + // Only true variables (not parameters or implicit parameters) can be merged. - if (VD->getKind() == Decl::Var) + if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam) mergeRedeclarable(VD, Redecl); if (uint64_t Val = Record[Idx++]) { @@ -927,12 +988,25 @@ void ASTDeclReader::VisitVarDecl(VarDecl *VD) { } } - if (Record[Idx++]) { // HasMemberSpecializationInfo. + enum VarKind { + VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization + }; + switch ((VarKind)Record[Idx++]) { + case VarNotTemplate: + break; + case VarTemplate: + VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>(Record, Idx)); + break; + case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo. VarDecl *Tmpl = ReadDeclAs<VarDecl>(Record, Idx); TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; SourceLocation POI = ReadSourceLocation(Record, Idx); Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI); + break; } + } + + return Redecl; } void ASTDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) { @@ -956,6 +1030,9 @@ void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { PD->ParmVarDeclBits.HasInheritedDefaultArg = Record[Idx++]; if (Record[Idx++]) // hasUninstantiatedDefaultArg. PD->setUninstantiatedDefaultArg(Reader.ReadExpr(F)); + + // FIXME: If this is a redeclaration of a function from another module, handle + // inheritance of default arguments. } void ASTDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) { @@ -1022,6 +1099,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { D->setInline(Record[Idx++]); D->LocStart = ReadSourceLocation(Record, Idx); D->RBraceLoc = ReadSourceLocation(Record, Idx); + // FIXME: At the point of this call, D->getCanonicalDecl() returns 0. mergeRedeclarable(D, Redecl); if (Redecl.getFirstID() == ThisDeclID) { @@ -1034,7 +1112,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { } else { // Link this namespace back to the first declaration, which has already // been deserialized. - D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDeclaration()); + D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDecl()); } } @@ -1048,22 +1126,24 @@ void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { void ASTDeclReader::VisitUsingDecl(UsingDecl *D) { VisitNamedDecl(D); - D->setUsingLocation(ReadSourceLocation(Record, Idx)); + D->setUsingLoc(ReadSourceLocation(Record, Idx)); D->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); ReadDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record, Idx); D->FirstUsingShadow.setPointer(ReadDeclAs<UsingShadowDecl>(Record, Idx)); - D->setTypeName(Record[Idx++]); + D->setTypename(Record[Idx++]); if (NamedDecl *Pattern = ReadDeclAs<NamedDecl>(Record, Idx)) Reader.getContext().setInstantiatedFromUsingDecl(D, Pattern); } void ASTDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) { + RedeclarableResult Redecl = VisitRedeclarable(D); VisitNamedDecl(D); D->setTargetDecl(ReadDeclAs<NamedDecl>(Record, Idx)); D->UsingOrNextShadow = ReadDeclAs<NamedDecl>(Record, Idx); UsingShadowDecl *Pattern = ReadDeclAs<UsingShadowDecl>(Record, Idx); if (Pattern) Reader.getContext().setInstantiatedFromUsingShadowDecl(D, Pattern); + mergeRedeclarable(D, Redecl); } void ASTDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { @@ -1128,8 +1208,6 @@ void ASTDeclReader::ReadCXXDefinitionData( Data.ImplicitCopyAssignmentHasConstParam = Record[Idx++]; Data.HasDeclaredCopyConstructorWithConstParam = Record[Idx++]; Data.HasDeclaredCopyAssignmentWithConstParam = Record[Idx++]; - Data.FailedImplicitMoveConstructor = Record[Idx++]; - Data.FailedImplicitMoveAssignment = Record[Idx++]; Data.NumBases = Record[Idx++]; if (Data.NumBases) @@ -1141,13 +1219,15 @@ void ASTDeclReader::ReadCXXDefinitionData( Reader.ReadUnresolvedSet(F, Data.Conversions, Record, Idx); Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx); assert(Data.Definition && "Data.Definition should be already set!"); - Data.FirstFriend = ReadDeclAs<FriendDecl>(Record, Idx); - + Data.FirstFriend = ReadDeclID(Record, Idx); + if (Data.IsLambda) { typedef LambdaExpr::Capture Capture; CXXRecordDecl::LambdaDefinitionData &Lambda = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data); Lambda.Dependent = Record[Idx++]; + Lambda.IsGenericLambda = Record[Idx++]; + Lambda.CaptureDefault = Record[Idx++]; Lambda.NumCaptures = Record[Idx++]; Lambda.NumExplicitCaptures = Record[Idx++]; Lambda.ManglingNumber = Record[Idx++]; @@ -1160,41 +1240,65 @@ void ASTDeclReader::ReadCXXDefinitionData( SourceLocation Loc = ReadSourceLocation(Record, Idx); bool IsImplicit = Record[Idx++]; LambdaCaptureKind Kind = static_cast<LambdaCaptureKind>(Record[Idx++]); - VarDecl *Var = ReadDeclAs<VarDecl>(Record, Idx); - SourceLocation EllipsisLoc = ReadSourceLocation(Record, Idx); - *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc); + switch (Kind) { + case LCK_This: + *ToCapture++ = Capture(Loc, IsImplicit, Kind, 0, SourceLocation()); + break; + case LCK_ByCopy: + case LCK_ByRef: + VarDecl *Var = ReadDeclAs<VarDecl>(Record, Idx); + SourceLocation EllipsisLoc = ReadSourceLocation(Record, Idx); + *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc); + break; + } } } } -void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { - VisitRecordDecl(D); +ASTDeclReader::RedeclarableResult +ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) { + RedeclarableResult Redecl = VisitRecordDeclImpl(D); ASTContext &C = Reader.getContext(); - if (Record[Idx++]) { + bool WasDefinition = Record[Idx++]; + if (WasDefinition) { // Determine whether this is a lambda closure type, so that we can // allocate the appropriate DefinitionData structure. bool IsLambda = Record[Idx++]; if (IsLambda) D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D, 0, - false); + false, + false, LCD_None); else D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); - + + ReadCXXDefinitionData(*D->DefinitionData, Record, Idx); + // Propagate the DefinitionData pointer to the canonical declaration, so // that all other deserialized declarations will see it. - // FIXME: Complain if there already is a DefinitionData! - D->getCanonicalDecl()->DefinitionData = D->DefinitionData; - - ReadCXXDefinitionData(*D->DefinitionData, Record, Idx); - - // Note that we have deserialized a definition. Any declarations - // deserialized before this one will be be given the DefinitionData pointer - // at the end. - Reader.PendingDefinitions.insert(D); + CXXRecordDecl *Canon = D->getCanonicalDecl(); + if (Canon == D) { + // Nothing to do. + } else if (!Canon->DefinitionData) { + Canon->DefinitionData = D->DefinitionData; + + // Note that we have deserialized a definition. Any declarations + // deserialized before this one will be be given the DefinitionData + // pointer at the end. + Reader.PendingDefinitions.insert(D); + } else { + // We have already deserialized a definition of this record. This + // definition is no longer really a definition. Note that the pre-existing + // definition is the *real* definition. + // FIXME: Check DefinitionData for consistency with prior definition. + Reader.MergedDeclContexts.insert( + std::make_pair(D, D->getCanonicalDecl()->DefinitionData->Definition)); + D->IsCompleteDefinition = false; + D->DefinitionData = D->getCanonicalDecl()->DefinitionData; + } } else { // Propagate DefinitionData pointer from the canonical declaration. - D->DefinitionData = D->getCanonicalDecl()->DefinitionData; + D->DefinitionData = D->getCanonicalDecl()->DefinitionData; } enum CXXRecKind { @@ -1217,12 +1321,15 @@ void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { } } - // Load the key function to avoid deserializing every method so we can + // Lazily load the key function to avoid deserializing every method so we can // compute it. - if (D->IsCompleteDefinition) { - if (CXXMethodDecl *Key = ReadDeclAs<CXXMethodDecl>(Record, Idx)) - C.KeyFunctions[D] = Key; + if (WasDefinition) { + DeclID KeyFn = ReadDeclID(Record, Idx); + if (KeyFn && D->IsCompleteDefinition) + C.KeyFunctions[D] = KeyFn; } + + return Redecl; } void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { @@ -1240,7 +1347,6 @@ void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) { VisitCXXMethodDecl(D); D->IsExplicitSpecified = Record[Idx++]; - D->ImplicitlyDefined = Record[Idx++]; llvm::tie(D->CtorInitializers, D->NumCtorInitializers) = Reader.ReadCXXCtorInitializers(F, Record, Idx); } @@ -1248,7 +1354,6 @@ void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) { void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) { VisitCXXMethodDecl(D); - D->ImplicitlyDefined = Record[Idx++]; D->OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx); } @@ -1280,7 +1385,7 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) { D->Friend = GetTypeSourceInfo(Record, Idx); for (unsigned i = 0; i != D->NumTPLists; ++i) D->getTPLists()[i] = Reader.ReadTemplateParameterList(F, Record, Idx); - D->NextFriend = Record[Idx++]; + D->NextFriend = ReadDeclID(Record, Idx); D->UnsupportedFriend = (Record[Idx++] != 0); D->FriendLoc = ReadSourceLocation(Record, Idx); } @@ -1306,6 +1411,9 @@ void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) { TemplateParameterList* TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx); D->init(TemplatedDecl, TemplateParams); + + // FIXME: If this is a redeclaration of a template from another module, handle + // inheritance of default template arguments. } ASTDeclReader::RedeclarableResult @@ -1339,6 +1447,11 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { mergeRedeclarable(D, Redecl); + // If we merged the template with a prior declaration chain, merge the common + // pointer. + // FIXME: Actually merge here, don't just overwrite. + D->Common = D->getCanonicalDecl()->Common; + return Redecl; } @@ -1378,9 +1491,47 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { } } -void ASTDeclReader::VisitClassTemplateSpecializationDecl( - ClassTemplateSpecializationDecl *D) { - VisitCXXRecordDecl(D); +/// TODO: Unify with ClassTemplateDecl version? +/// May require unifying ClassTemplateDecl and +/// VarTemplateDecl beyond TemplateDecl... +void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) { + RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D); + + if (ThisDeclID == Redecl.getFirstID()) { + // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of + // the specializations. + SmallVector<serialization::DeclID, 2> SpecIDs; + SpecIDs.push_back(0); + + // Specializations. + unsigned Size = Record[Idx++]; + SpecIDs[0] += Size; + for (unsigned I = 0; I != Size; ++I) + SpecIDs.push_back(ReadDeclID(Record, Idx)); + + // Partial specializations. + Size = Record[Idx++]; + SpecIDs[0] += Size; + for (unsigned I = 0; I != Size; ++I) + SpecIDs.push_back(ReadDeclID(Record, Idx)); + + VarTemplateDecl::Common *CommonPtr = D->getCommonPtr(); + if (SpecIDs[0]) { + typedef serialization::DeclID DeclID; + + // FIXME: Append specializations! + CommonPtr->LazySpecializations = + new (Reader.getContext()) DeclID[SpecIDs.size()]; + memcpy(CommonPtr->LazySpecializations, SpecIDs.data(), + SpecIDs.size() * sizeof(DeclID)); + } + } +} + +ASTDeclReader::RedeclarableResult +ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( + ClassTemplateSpecializationDecl *D) { + RedeclarableResult Redecl = VisitCXXRecordDeclImpl(D); ASTContext &C = Reader.getContext(); if (Decl *InstD = ReadDecl(Record, Idx)) { @@ -1402,16 +1553,6 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl( } } - // Explicit info. - if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) { - ClassTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo - = new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo; - ExplicitInfo->TypeAsWritten = TyInfo; - ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx); - ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx); - D->ExplicitInfo = ExplicitInfo; - } - SmallVector<TemplateArgument, 8> TemplArgs; Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), @@ -1423,35 +1564,60 @@ void ASTDeclReader::VisitClassTemplateSpecializationDecl( if (writtenAsCanonicalDecl) { ClassTemplateDecl *CanonPattern = ReadDeclAs<ClassTemplateDecl>(Record,Idx); if (D->isCanonicalDecl()) { // It's kept in the folding set. - if (ClassTemplatePartialSpecializationDecl *Partial - = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { - CanonPattern->getCommonPtr()->PartialSpecializations.GetOrInsertNode(Partial); + // Set this as, or find, the canonical declaration for this specialization + ClassTemplateSpecializationDecl *CanonSpec; + if (ClassTemplatePartialSpecializationDecl *Partial = + dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { + CanonSpec = CanonPattern->getCommonPtr()->PartialSpecializations + .GetOrInsertNode(Partial); } else { - CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D); + CanonSpec = + CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D); + } + // If there was already a canonical specialization, merge into it. + if (CanonSpec != D) { + mergeRedeclarable<TagDecl>(D, CanonSpec, Redecl); + + // This declaration might be a definition. Merge with any existing + // definition. + if (D->DefinitionData) { + if (!CanonSpec->DefinitionData) { + CanonSpec->DefinitionData = D->DefinitionData; + } else { + // FIXME: Check DefinitionData for consistency with prior definition + Reader.PendingDefinitions.erase(D); + Reader.MergedDeclContexts.insert( + std::make_pair(D, CanonSpec->DefinitionData->Definition)); + D->IsCompleteDefinition = false; + D->DefinitionData = CanonSpec->DefinitionData; + } + } } } } + + // Explicit info. + if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) { + ClassTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo + = new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo; + ExplicitInfo->TypeAsWritten = TyInfo; + ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx); + ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx); + D->ExplicitInfo = ExplicitInfo; + } + + return Redecl; } void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D) { - VisitClassTemplateSpecializationDecl(D); + RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D); - ASTContext &C = Reader.getContext(); D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx); - - unsigned NumArgs = Record[Idx++]; - if (NumArgs) { - D->NumArgsAsWritten = NumArgs; - D->ArgsAsWritten = new (C) TemplateArgumentLoc[NumArgs]; - for (unsigned i=0; i != NumArgs; ++i) - D->ArgsAsWritten[i] = Reader.ReadTemplateArgumentLoc(F, Record, Idx); - } - - D->SequenceNumber = Record[Idx++]; + D->ArgsAsWritten = Reader.ReadASTTemplateArgumentListInfo(F, Record, Idx); // These are read/set from/to the first declaration. - if (D->getPreviousDecl() == 0) { + if (ThisDeclID == Redecl.getFirstID()) { D->InstantiatedFromMember.setPointer( ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx)); D->InstantiatedFromMember.setInt(Record[Idx++]); @@ -1470,12 +1636,100 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { if (ThisDeclID == Redecl.getFirstID()) { // This FunctionTemplateDecl owns a CommonPtr; read it. - // Read the function specialization declarations. - // FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled - // when reading the specialized FunctionDecl. - unsigned NumSpecs = Record[Idx++]; - while (NumSpecs--) - (void)ReadDecl(Record, Idx); + // Read the function specialization declaration IDs. The specializations + // themselves will be loaded if they're needed. + if (unsigned NumSpecs = Record[Idx++]) { + // FIXME: Append specializations! + FunctionTemplateDecl::Common *CommonPtr = D->getCommonPtr(); + CommonPtr->LazySpecializations = new (Reader.getContext()) + serialization::DeclID[NumSpecs + 1]; + CommonPtr->LazySpecializations[0] = NumSpecs; + for (unsigned I = 0; I != NumSpecs; ++I) + CommonPtr->LazySpecializations[I + 1] = ReadDeclID(Record, Idx); + } + } +} + +/// TODO: Unify with ClassTemplateSpecializationDecl version? +/// May require unifying ClassTemplate(Partial)SpecializationDecl and +/// VarTemplate(Partial)SpecializationDecl with a new data +/// structure Template(Partial)SpecializationDecl, and +/// using Template(Partial)SpecializationDecl as input type. +ASTDeclReader::RedeclarableResult +ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( + VarTemplateSpecializationDecl *D) { + RedeclarableResult Redecl = VisitVarDeclImpl(D); + + ASTContext &C = Reader.getContext(); + if (Decl *InstD = ReadDecl(Record, Idx)) { + if (VarTemplateDecl *VTD = dyn_cast<VarTemplateDecl>(InstD)) { + D->SpecializedTemplate = VTD; + } else { + SmallVector<TemplateArgument, 8> TemplArgs; + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + TemplateArgumentList *ArgList = TemplateArgumentList::CreateCopy( + C, TemplArgs.data(), TemplArgs.size()); + VarTemplateSpecializationDecl::SpecializedPartialSpecialization *PS = + new (C) + VarTemplateSpecializationDecl::SpecializedPartialSpecialization(); + PS->PartialSpecialization = + cast<VarTemplatePartialSpecializationDecl>(InstD); + PS->TemplateArgs = ArgList; + D->SpecializedTemplate = PS; + } + } + + // Explicit info. + if (TypeSourceInfo *TyInfo = GetTypeSourceInfo(Record, Idx)) { + VarTemplateSpecializationDecl::ExplicitSpecializationInfo *ExplicitInfo = + new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo; + ExplicitInfo->TypeAsWritten = TyInfo; + ExplicitInfo->ExternLoc = ReadSourceLocation(Record, Idx); + ExplicitInfo->TemplateKeywordLoc = ReadSourceLocation(Record, Idx); + D->ExplicitInfo = ExplicitInfo; + } + + SmallVector<TemplateArgument, 8> TemplArgs; + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + D->TemplateArgs = + TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size()); + D->PointOfInstantiation = ReadSourceLocation(Record, Idx); + D->SpecializationKind = (TemplateSpecializationKind)Record[Idx++]; + + bool writtenAsCanonicalDecl = Record[Idx++]; + if (writtenAsCanonicalDecl) { + VarTemplateDecl *CanonPattern = ReadDeclAs<VarTemplateDecl>(Record, Idx); + if (D->isCanonicalDecl()) { // It's kept in the folding set. + if (VarTemplatePartialSpecializationDecl *Partial = + dyn_cast<VarTemplatePartialSpecializationDecl>(D)) { + CanonPattern->getCommonPtr()->PartialSpecializations + .GetOrInsertNode(Partial); + } else { + CanonPattern->getCommonPtr()->Specializations.GetOrInsertNode(D); + } + } + } + + return Redecl; +} + +/// TODO: Unify with ClassTemplatePartialSpecializationDecl version? +/// May require unifying ClassTemplate(Partial)SpecializationDecl and +/// VarTemplate(Partial)SpecializationDecl with a new data +/// structure Template(Partial)SpecializationDecl, and +/// using Template(Partial)SpecializationDecl as input type. +void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl( + VarTemplatePartialSpecializationDecl *D) { + RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D); + + D->TemplateParams = Reader.ReadTemplateParameterList(F, Record, Idx); + D->ArgsAsWritten = Reader.ReadASTTemplateArgumentListInfo(F, Record, Idx); + + // These are read/set from/to the first declaration. + if (ThisDeclID == Redecl.getFirstID()) { + D->InstantiatedFromMember.setPointer( + ReadDeclAs<VarTemplatePartialSpecializationDecl>(Record, Idx)); + D->InstantiatedFromMember.setInt(Record[Idx++]); } } @@ -1584,70 +1838,98 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { /// \brief Attempts to merge the given declaration (D) with another declaration /// of the same entity. template<typename T> -void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, +void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl) { // If modules are not available, there is no reason to perform this merge. if (!Reader.getContext().getLangOpts().Modules) return; - - if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D))) { - if (T *Existing = ExistingRes) { - T *ExistingCanon = Existing->getCanonicalDecl(); - T *DCanon = static_cast<T*>(D)->getCanonicalDecl(); - if (ExistingCanon != DCanon) { - // Have our redeclaration link point back at the canonical declaration - // of the existing declaration, so that this declaration has the - // appropriate canonical declaration. - D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon); - - // When we merge a namespace, update its pointer to the first namespace. - if (NamespaceDecl *Namespace - = dyn_cast<NamespaceDecl>(static_cast<T*>(D))) { - Namespace->AnonOrFirstNamespaceAndInline.setPointer( - static_cast<NamespaceDecl *>(static_cast<void*>(ExistingCanon))); - } - - // Don't introduce DCanon into the set of pending declaration chains. - Redecl.suppress(); - - // Introduce ExistingCanon into the set of pending declaration chains, - // if in fact it came from a module file. - if (ExistingCanon->isFromASTFile()) { - GlobalDeclID ExistingCanonID = ExistingCanon->getGlobalID(); - assert(ExistingCanonID && "Unrecorded canonical declaration ID?"); - if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID)) - Reader.PendingDeclChains.push_back(ExistingCanonID); - } - - // If this declaration was the canonical declaration, make a note of - // that. We accept the linear algorithm here because the number of - // unique canonical declarations of an entity should always be tiny. - if (DCanon == static_cast<T*>(D)) { - SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon]; - if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID()) - == Merged.end()) - Merged.push_back(Redecl.getFirstID()); - - // If ExistingCanon did not come from a module file, introduce the - // first declaration that *does* come from a module file to the - // set of pending declaration chains, so that we merge this - // declaration. - if (!ExistingCanon->isFromASTFile() && - Reader.PendingDeclChainsKnown.insert(Redecl.getFirstID())) - Reader.PendingDeclChains.push_back(Merged[0]); - } - } + + if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D))) + if (T *Existing = ExistingRes) + mergeRedeclarable(D, Existing, Redecl); +} + +/// \brief Attempts to merge the given declaration (D) with another declaration +/// of the same entity. +template<typename T> +void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, T *Existing, + RedeclarableResult &Redecl) { + T *ExistingCanon = Existing->getCanonicalDecl(); + T *DCanon = static_cast<T*>(D)->getCanonicalDecl(); + if (ExistingCanon != DCanon) { + // Have our redeclaration link point back at the canonical declaration + // of the existing declaration, so that this declaration has the + // appropriate canonical declaration. + D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon); + + // When we merge a namespace, update its pointer to the first namespace. + if (NamespaceDecl *Namespace + = dyn_cast<NamespaceDecl>(static_cast<T*>(D))) { + Namespace->AnonOrFirstNamespaceAndInline.setPointer( + static_cast<NamespaceDecl *>(static_cast<void*>(ExistingCanon))); + } + + // Don't introduce DCanon into the set of pending declaration chains. + Redecl.suppress(); + + // Introduce ExistingCanon into the set of pending declaration chains, + // if in fact it came from a module file. + if (ExistingCanon->isFromASTFile()) { + GlobalDeclID ExistingCanonID = ExistingCanon->getGlobalID(); + assert(ExistingCanonID && "Unrecorded canonical declaration ID?"); + if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID)) + Reader.PendingDeclChains.push_back(ExistingCanonID); + } + + // If this declaration was the canonical declaration, make a note of + // that. We accept the linear algorithm here because the number of + // unique canonical declarations of an entity should always be tiny. + if (DCanon == static_cast<T*>(D)) { + SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon]; + if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID()) + == Merged.end()) + Merged.push_back(Redecl.getFirstID()); + + // If ExistingCanon did not come from a module file, introduce the + // first declaration that *does* come from a module file to the + // set of pending declaration chains, so that we merge this + // declaration. + if (!ExistingCanon->isFromASTFile() && + Reader.PendingDeclChainsKnown.insert(Redecl.getFirstID())) + Reader.PendingDeclChains.push_back(Merged[0]); } } } +/// \brief Attempts to merge the given declaration (D) with another declaration +/// of the same entity, for the case where the entity is not actually +/// redeclarable. This happens, for instance, when merging the fields of +/// identical class definitions from two different modules. +template<typename T> +void ASTDeclReader::mergeMergeable(Mergeable<T> *D) { + // If modules are not available, there is no reason to perform this merge. + if (!Reader.getContext().getLangOpts().Modules) + return; + + // ODR-based merging is only performed in C++. In C, identically-named things + // in different translation units are not redeclarations (but may still have + // compatible types). + if (!Reader.getContext().getLangOpts().CPlusPlus) + return; + + if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D))) + if (T *Existing = ExistingRes) + Reader.Context.setPrimaryMergedDecl(static_cast<T*>(D), + Existing->getCanonicalDecl()); +} + void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { VisitDecl(D); unsigned NumVars = D->varlist_size(); - SmallVector<DeclRefExpr *, 16> Vars; + SmallVector<Expr *, 16> Vars; Vars.reserve(NumVars); for (unsigned i = 0; i != NumVars; ++i) { - Vars.push_back(cast<DeclRefExpr>(Reader.ReadExpr(F))); + Vars.push_back(Reader.ReadExpr(F)); } D->setVars(Vars); } @@ -1741,6 +2023,48 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) { return LocalOffset + M.GlobalBitOffset; } +static bool isSameTemplateParameterList(const TemplateParameterList *X, + const TemplateParameterList *Y); + +/// \brief Determine whether two template parameters are similar enough +/// that they may be used in declarations of the same template. +static bool isSameTemplateParameter(const NamedDecl *X, + const NamedDecl *Y) { + if (X->getKind() != Y->getKind()) + return false; + + if (const TemplateTypeParmDecl *TX = dyn_cast<TemplateTypeParmDecl>(X)) { + const TemplateTypeParmDecl *TY = cast<TemplateTypeParmDecl>(Y); + return TX->isParameterPack() == TY->isParameterPack(); + } + + if (const NonTypeTemplateParmDecl *TX = dyn_cast<NonTypeTemplateParmDecl>(X)) { + const NonTypeTemplateParmDecl *TY = cast<NonTypeTemplateParmDecl>(Y); + return TX->isParameterPack() == TY->isParameterPack() && + TX->getASTContext().hasSameType(TX->getType(), TY->getType()); + } + + const TemplateTemplateParmDecl *TX = cast<TemplateTemplateParmDecl>(X); + const TemplateTemplateParmDecl *TY = cast<TemplateTemplateParmDecl>(Y); + return TX->isParameterPack() == TY->isParameterPack() && + isSameTemplateParameterList(TX->getTemplateParameters(), + TY->getTemplateParameters()); +} + +/// \brief Determine whether two template parameter lists are similar enough +/// that they may be used in declarations of the same template. +static bool isSameTemplateParameterList(const TemplateParameterList *X, + const TemplateParameterList *Y) { + if (X->size() != Y->size()) + return false; + + for (unsigned I = 0, N = X->size(); I != N; ++I) + if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I))) + return false; + + return true; +} + /// \brief Determine whether the two declarations refer to the same entity. static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!"); @@ -1767,7 +2091,13 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { // Objective-C classes and protocols with the same name always match. if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X)) return true; - + + if (isa<ClassTemplateSpecializationDecl>(X)) { + // No need to handle these here: we merge them when adding them to the + // template. + return false; + } + // Compatible tags match. if (TagDecl *TagX = dyn_cast<TagDecl>(X)) { TagDecl *TagY = cast<TagDecl>(Y); @@ -1777,48 +2107,90 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class || TagY->getTagKind() == TTK_Interface)); } - + // Functions with the same type and linkage match. - // FIXME: This needs to cope with function templates, merging of - //prototyped/non-prototyped functions, etc. + // FIXME: This needs to cope with function template specializations, + // merging of prototyped/non-prototyped functions, etc. if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) { FunctionDecl *FuncY = cast<FunctionDecl>(Y); - return (FuncX->getLinkage() == FuncY->getLinkage()) && + return (FuncX->getLinkageInternal() == FuncY->getLinkageInternal()) && FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType()); } // Variables with the same type and linkage match. if (VarDecl *VarX = dyn_cast<VarDecl>(X)) { VarDecl *VarY = cast<VarDecl>(Y); - return (VarX->getLinkage() == VarY->getLinkage()) && + return (VarX->getLinkageInternal() == VarY->getLinkageInternal()) && VarX->getASTContext().hasSameType(VarX->getType(), VarY->getType()); } - + // Namespaces with the same name and inlinedness match. if (NamespaceDecl *NamespaceX = dyn_cast<NamespaceDecl>(X)) { NamespaceDecl *NamespaceY = cast<NamespaceDecl>(Y); return NamespaceX->isInline() == NamespaceY->isInline(); } - // Identical template names and kinds match. - if (isa<TemplateDecl>(X)) + // Identical template names and kinds match if their template parameter lists + // and patterns match. + if (TemplateDecl *TemplateX = dyn_cast<TemplateDecl>(X)) { + TemplateDecl *TemplateY = cast<TemplateDecl>(Y); + return isSameEntity(TemplateX->getTemplatedDecl(), + TemplateY->getTemplatedDecl()) && + isSameTemplateParameterList(TemplateX->getTemplateParameters(), + TemplateY->getTemplateParameters()); + } + + // Fields with the same name and the same type match. + if (FieldDecl *FDX = dyn_cast<FieldDecl>(X)) { + FieldDecl *FDY = cast<FieldDecl>(Y); + // FIXME: Diagnose if the types don't match. More generally, diagnose if we + // get a declaration in a class definition that isn't in the canonical class + // definition. + // FIXME: Also check the bitwidth is odr-equivalent, if any. + return X->getASTContext().hasSameType(FDX->getType(), FDY->getType()); + } + + // Enumerators with the same name match. + if (isa<EnumConstantDecl>(X)) + // FIXME: Also check the value is odr-equivalent. return true; + // Using shadow declarations with the same target match. + if (UsingShadowDecl *USX = dyn_cast<UsingShadowDecl>(X)) { + UsingShadowDecl *USY = cast<UsingShadowDecl>(Y); + return USX->getTargetDecl() == USY->getTargetDecl(); + } + // FIXME: Many other cases to implement. return false; } +/// Find the context in which we should search for previous declarations when +/// looking for declarations to merge. +static DeclContext *getPrimaryContextForMerging(DeclContext *DC) { + if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC)) + return ND->getOriginalNamespace(); + + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) + return RD->getDefinition(); + + if (EnumDecl *ED = dyn_cast<EnumDecl>(DC)) + return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition() : 0; + + return 0; +} + ASTDeclReader::FindExistingResult::~FindExistingResult() { if (!AddResult || Existing) return; - - if (New->getDeclContext()->getRedeclContext()->isTranslationUnit() - && Reader.SemaObj) { + + DeclContext *DC = New->getDeclContext()->getRedeclContext(); + if (DC->isTranslationUnit() && Reader.SemaObj) { Reader.SemaObj->IdResolver.tryAddTopLevelDecl(New, New->getDeclName()); - } else { - DeclContext *DC = New->getLexicalDeclContext(); - if (DC->isNamespace()) - DC->addDecl(New); + } else if (DeclContext *MergeDC = getPrimaryContextForMerging(DC)) { + // Add the declaration to its redeclaration context so later merging + // lookups will find it. + MergeDC->makeDeclVisibleInContextImpl(New, /*Internal*/true); } } @@ -1830,11 +2202,11 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { Result.suppress(); return Result; } - + + // FIXME: Bail out for non-canonical declarations. We will have performed any + // necessary merging already. + DeclContext *DC = D->getDeclContext()->getRedeclContext(); - if (!DC->isFileContext()) - return FindExistingResult(Reader); - if (DC->isTranslationUnit() && Reader.SemaObj) { IdentifierResolver &IdResolver = Reader.SemaObj->IdResolver; @@ -1867,17 +2239,22 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { if (isSameEntity(*I, D)) return FindExistingResult(Reader, D, *I); } - } - - if (DC->isNamespace()) { - DeclContext::lookup_result R = DC->lookup(Name); - for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; - ++I) { + } else if (DeclContext *MergeDC = getPrimaryContextForMerging(DC)) { + DeclContext::lookup_result R = MergeDC->noload_lookup(Name); + for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) { if (isSameEntity(*I, D)) return FindExistingResult(Reader, D, *I); } + } else { + // Not in a mergeable context. + return FindExistingResult(Reader); } - + + // If this declaration is from a merged context, make a note that we need to + // check that the canonical definition of that context contains the decl. + if (Reader.MergedDeclContexts.count(D->getLexicalDeclContext())) + Reader.PendingOdrMergeChecks.push_back(D); + return FindExistingResult(Reader, D, /*Existing=*/0); } @@ -1891,6 +2268,8 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) { VD->RedeclLink.setNext(cast<VarDecl>(previous)); } else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) { TD->RedeclLink.setNext(cast<TypedefNameDecl>(previous)); + } else if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) { + USD->RedeclLink.setNext(cast<UsingShadowDecl>(previous)); } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) { ID->RedeclLink.setNext(cast<ObjCInterfaceDecl>(previous)); } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) { @@ -1901,6 +2280,15 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) { RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D); TD->RedeclLink.setNext(cast<RedeclarableTemplateDecl>(previous)); } + + // If the declaration was visible in one module, a redeclaration of it in + // another module remains visible even if it wouldn't be visible by itself. + // + // FIXME: In this case, the declaration should only be visible if a module + // that makes it visible has been imported. + D->IdentifierNamespace |= + previous->IdentifierNamespace & + (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type); } void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) { @@ -1909,7 +2297,7 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) { TD->RedeclLink = Redeclarable<TagDecl>::LatestDeclLink(cast<TagDecl>(Latest)); } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { - FD->RedeclLink + FD->RedeclLink = Redeclarable<FunctionDecl>::LatestDeclLink(cast<FunctionDecl>(Latest)); } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) { VD->RedeclLink @@ -1918,6 +2306,10 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) { TD->RedeclLink = Redeclarable<TypedefNameDecl>::LatestDeclLink( cast<TypedefNameDecl>(Latest)); + } else if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) { + USD->RedeclLink + = Redeclarable<UsingShadowDecl>::LatestDeclLink( + cast<UsingShadowDecl>(Latest)); } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) { ID->RedeclLink = Redeclarable<ObjCInterfaceDecl>::LatestDeclLink( @@ -1961,11 +2353,6 @@ ASTReader::combineStoredMergedDecls(Decl *Canon, GlobalDeclID CanonID) { return Pos; } -void ASTReader::loadAndAttachPreviousDecl(Decl *D, serialization::DeclID ID) { - Decl *previous = GetDecl(ID); - ASTDeclReader::attachPreviousDecl(D, previous); -} - /// \brief Read the declaration at the given offset from the AST file. Decl *ASTReader::ReadDeclRecord(DeclID ID) { unsigned Index = ID - NUM_PREDEF_DECL_IDS; @@ -2070,6 +2457,15 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION: D = ClassTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); break; + case DECL_VAR_TEMPLATE: + D = VarTemplateDecl::CreateDeserialized(Context, ID); + break; + case DECL_VAR_TEMPLATE_SPECIALIZATION: + D = VarTemplateSpecializationDecl::CreateDeserialized(Context, ID); + break; + case DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION: + D = VarTemplatePartialSpecializationDecl::CreateDeserialized(Context, ID); + break; case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION: D = ClassScopeFunctionSpecializationDecl::CreateDeserialized(Context, ID); break; @@ -2397,7 +2793,7 @@ void ASTReader::loadPendingDeclChain(serialization::GlobalDeclID ID) { for (unsigned I = 0, N = Chain.size(); I != N; ++I) { if (Chain[I] == CanonDecl) continue; - + ASTDeclReader::attachPreviousDecl(Chain[I], MostRecent); MostRecent = Chain[I]; } @@ -2582,6 +2978,20 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, cast<VarDecl>(D)->getMemberSpecializationInfo()->setPointOfInstantiation( Reader.ReadSourceLocation(ModuleFile, Record, Idx)); break; + + case UPD_CXX_DEDUCED_RETURN_TYPE: { + FunctionDecl *FD = cast<FunctionDecl>(D); + Reader.Context.adjustDeducedFunctionResultType( + FD, Reader.readType(ModuleFile, Record, Idx)); + break; + } + + case UPD_DECL_MARKED_USED: { + // FIXME: This doesn't send the right notifications if there are + // ASTMutationListeners other than an ASTWriter. + D->Used = true; + break; + } } } } diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp index e1357ba..1115e8f 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReaderStmt.cpp @@ -25,6 +25,7 @@ using namespace clang::serialization; namespace clang { class ASTStmtReader : public StmtVisitor<ASTStmtReader> { + friend class OMPClauseReader; typedef ASTReader::RecordData RecordData; ASTReader &Reader; @@ -382,6 +383,7 @@ void ASTStmtReader::VisitMSAsmStmt(MSAsmStmt *S) { void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) { VisitStmt(S); + ++Idx; S->setCapturedDecl(ReadDeclAs<CapturedDecl>(Record, Idx)); S->setCapturedRegionKind(static_cast<CapturedRegionKind>(Record[Idx++])); S->setCapturedRecordDecl(ReadDeclAs<RecordDecl>(Record, Idx)); @@ -723,7 +725,6 @@ void ASTStmtReader::VisitInitListExpr(InitListExpr *E) { } else E->ArrayFillerOrUnionFieldInit = ReadDeclAs<FieldDecl>(Record, Idx); E->sawArrayRangeDesignator(Record[Idx++]); - E->setInitializesStdInitializerList(Record[Idx++]); unsigned NumInits = Record[Idx++]; E->reserveInits(Reader.getContext(), NumInits); if (isArrayFiller) { @@ -834,6 +835,7 @@ void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) { E->setRHS(Reader.ReadSubExpr()); E->setBuiltinLoc(ReadSourceLocation(Record, Idx)); E->setRParenLoc(ReadSourceLocation(Record, Idx)); + E->setIsConditionTrue(Record[Idx++]); } void ASTStmtReader::VisitGNUNullExpr(GNUNullExpr *E) { @@ -847,11 +849,19 @@ void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { unsigned NumExprs = Record[Idx++]; while (NumExprs--) Exprs.push_back(Reader.ReadSubExpr()); - E->setExprs(Reader.getContext(), Exprs.data(), Exprs.size()); + E->setExprs(Reader.getContext(), Exprs); E->setBuiltinLoc(ReadSourceLocation(Record, Idx)); E->setRParenLoc(ReadSourceLocation(Record, Idx)); } +void ASTStmtReader::VisitConvertVectorExpr(ConvertVectorExpr *E) { + VisitExpr(E); + E->BuiltinLoc = ReadSourceLocation(Record, Idx); + E->RParenLoc = ReadSourceLocation(Record, Idx); + E->TInfo = GetTypeSourceInfo(Record, Idx); + E->SrcExpr = Reader.ReadSubExpr(); +} + void ASTStmtReader::VisitBlockExpr(BlockExpr *E) { VisitExpr(E); E->setBlockDecl(ReadDeclAs<BlockDecl>(Record, Idx)); @@ -1190,7 +1200,7 @@ void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) { E->setListInitialization(Record[Idx++]); E->setRequiresZeroInitialization(Record[Idx++]); E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]); - E->ParenRange = ReadSourceRange(Record, Idx); + E->ParenOrBraceRange = ReadSourceRange(Record, Idx); } void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { @@ -1205,6 +1215,7 @@ void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) { unsigned NumArrayIndexVars = Record[Idx++]; E->IntroducerRange = ReadSourceRange(Record, Idx); E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record[Idx++]); + E->CaptureDefaultLoc = ReadSourceLocation(Record, Idx); E->ExplicitParams = Record[Idx++]; E->ExplicitResultType = Record[Idx++]; E->ClosingBrace = ReadSourceLocation(Record, Idx); @@ -1227,6 +1238,12 @@ void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) { } } +void +ASTStmtReader::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { + VisitExpr(E); + E->SubExpr = Reader.ReadSubExpr(); +} + void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { VisitExplicitCastExpr(E); SourceRange R = ReadSourceRange(Record, Idx); @@ -1254,7 +1271,7 @@ void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) { void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) { VisitExplicitCastExpr(E); - E->setTypeBeginLoc(ReadSourceLocation(Record, Idx)); + E->setLParenLoc(ReadSourceLocation(Record, Idx)); E->setRParenLoc(ReadSourceLocation(Record, Idx)); } @@ -1576,6 +1593,7 @@ void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) { VisitExpr(E); E->Temporary = Reader.ReadSubExpr(); + E->ExtendingDecl = ReadDeclAs<ValueDecl>(Record, Idx); } void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { @@ -1650,11 +1668,114 @@ void ASTStmtReader::VisitAsTypeExpr(AsTypeExpr *E) { } //===----------------------------------------------------------------------===// +// OpenMP Clauses. +//===----------------------------------------------------------------------===// + +namespace clang { +class OMPClauseReader : public OMPClauseVisitor<OMPClauseReader> { + ASTStmtReader *Reader; + ASTContext &Context; + const ASTReader::RecordData &Record; + unsigned &Idx; +public: + OMPClauseReader(ASTStmtReader *R, ASTContext &C, + const ASTReader::RecordData &Record, unsigned &Idx) + : Reader(R), Context(C), Record(Record), Idx(Idx) { } +#define OPENMP_CLAUSE(Name, Class) \ + void Visit##Class(Class *S); +#include "clang/Basic/OpenMPKinds.def" + OMPClause *readClause(); +}; +} + +OMPClause *OMPClauseReader::readClause() { + OMPClause *C; + switch (Record[Idx++]) { + case OMPC_default: + C = new (Context) OMPDefaultClause(); + break; + case OMPC_private: + C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]); + break; + case OMPC_firstprivate: + C = OMPFirstprivateClause::CreateEmpty(Context, Record[Idx++]); + break; + case OMPC_shared: + C = OMPSharedClause::CreateEmpty(Context, Record[Idx++]); + break; + } + Visit(C); + C->setLocStart(Reader->ReadSourceLocation(Record, Idx)); + C->setLocEnd(Reader->ReadSourceLocation(Record, Idx)); + + return C; +} + +void OMPClauseReader::VisitOMPDefaultClause(OMPDefaultClause *C) { + C->setDefaultKind( + static_cast<OpenMPDefaultClauseKind>(Record[Idx++])); + C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); + C->setDefaultKindKwLoc(Reader->ReadSourceLocation(Record, Idx)); +} + +void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) { + C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Reader->Reader.ReadSubExpr()); + C->setVarRefs(Vars); +} + +void OMPClauseReader::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) { + C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Reader->Reader.ReadSubExpr()); + C->setVarRefs(Vars); +} + +void OMPClauseReader::VisitOMPSharedClause(OMPSharedClause *C) { + C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Reader->Reader.ReadSubExpr()); + C->setVarRefs(Vars); +} + +//===----------------------------------------------------------------------===// +// OpenMP Directives. +//===----------------------------------------------------------------------===// +void ASTStmtReader::VisitOMPExecutableDirective(OMPExecutableDirective *E) { + VisitStmt(E); + ++Idx; + E->setLocStart(ReadSourceLocation(Record, Idx)); + E->setLocEnd(ReadSourceLocation(Record, Idx)); + OMPClauseReader ClauseReader(this, Reader.getContext(), Record, Idx); + SmallVector<OMPClause *, 5> Clauses; + for (unsigned i = 0; i < E->getNumClauses(); ++i) + Clauses.push_back(ClauseReader.readClause()); + E->setClauses(Clauses); + E->setAssociatedStmt(Reader.ReadSubStmt()); +} + +void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) { + VisitOMPExecutableDirective(D); +} + +//===----------------------------------------------------------------------===// // ASTReader Implementation //===----------------------------------------------------------------------===// Stmt *ASTReader::ReadStmt(ModuleFile &F) { switch (ReadingKind) { + case Read_None: + llvm_unreachable("should not call this when not reading anything"); case Read_Decl: case Read_Type: return ReadStmtFromStream(F); @@ -1815,7 +1936,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case STMT_CAPTURED: S = CapturedStmt::CreateDeserialized(Context, - Record[ASTStmtReader::NumExprFields]); + Record[ASTStmtReader::NumStmtFields]); break; case EXPR_PREDEFINED: @@ -2004,6 +2125,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) ShuffleVectorExpr(Empty); break; + case EXPR_CONVERT_VECTOR: + S = new (Context) ConvertVectorExpr(Empty); + break; + case EXPR_BLOCK: S = new (Context) BlockExpr(Empty); break; @@ -2115,6 +2240,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { DeclarationNameInfo(), 0); break; + case STMT_OMP_PARALLEL_DIRECTIVE: + S = + OMPParallelDirective::CreateEmpty(Context, + Record[ASTStmtReader::NumStmtFields], + Empty); + break; case EXPR_CXX_OPERATOR_CALL: S = new (Context) CXXOperatorCallExpr(Context, Empty); @@ -2160,6 +2291,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) UserDefinedLiteral(Context, Empty); break; + case EXPR_CXX_STD_INITIALIZER_LIST: + S = new (Context) CXXStdInitializerListExpr(Empty); + break; + case EXPR_CXX_BOOL_LITERAL: S = new (Context) CXXBoolLiteralExpr(Empty); break; diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp index b8ada04..405488c 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriter.cpp @@ -108,6 +108,11 @@ void ASTTypeWriter::VisitPointerType(const PointerType *T) { Code = TYPE_POINTER; } +void ASTTypeWriter::VisitDecayedType(const DecayedType *T) { + Writer.AddTypeRef(T->getOriginalType(), Record); + Code = TYPE_DECAYED; +} + void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { Writer.AddTypeRef(T->getPointeeType(), Record); Code = TYPE_BLOCK_POINTER; @@ -447,6 +452,9 @@ void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { Writer.AddSourceLocation(TL.getStarLoc(), Record); } +void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) { + // nothing to do +} void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { Writer.AddSourceLocation(TL.getCaretLoc(), Record); } @@ -735,6 +743,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_CXX_CONST_CAST); RECORD(EXPR_CXX_FUNCTIONAL_CAST); RECORD(EXPR_USER_DEFINED_LITERAL); + RECORD(EXPR_CXX_STD_INITIALIZER_LIST); RECORD(EXPR_CXX_BOOL_LITERAL); RECORD(EXPR_CXX_NULL_PTR_LITERAL); RECORD(EXPR_CXX_TYPEID_EXPR); @@ -839,6 +848,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(OBJC_CATEGORIES); RECORD(MACRO_OFFSET); RECORD(MACRO_TABLE); + RECORD(LATE_PARSED_TEMPLATE); // SourceManager Block. BLOCK(SOURCE_MANAGER_BLOCK); @@ -937,6 +947,9 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_CLASS_TEMPLATE); RECORD(DECL_CLASS_TEMPLATE_SPECIALIZATION); RECORD(DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION); + RECORD(DECL_VAR_TEMPLATE); + RECORD(DECL_VAR_TEMPLATE_SPECIALIZATION); + RECORD(DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION); RECORD(DECL_FUNCTION_TEMPLATE); RECORD(DECL_TEMPLATE_TYPE_PARM); RECORD(DECL_NON_TYPE_TEMPLATE_PARM); @@ -1224,7 +1237,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, WriteInputFiles(Context.SourceMgr, PP.getHeaderSearchInfo().getHeaderSearchOpts(), - isysroot); + isysroot, + PP.getLangOpts().Modules); Stream.ExitBlock(); } @@ -1239,7 +1253,8 @@ namespace { void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, - StringRef isysroot) { + StringRef isysroot, + bool Modules) { using namespace llvm; Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4); RecordData Record; @@ -1293,6 +1308,19 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, } } + // Add the compiler's own module.map in the set of (non-system) input files. + // This is a simple heuristic for detecting whether the compiler's headers + // have changed, because we don't want to stat() all of them. + if (Modules && !Chain) { + SmallString<128> P = StringRef(HSOpts.ResourceDir); + llvm::sys::path::append(P, "include"); + llvm::sys::path::append(P, "module.map"); + if (const FileEntry *ModuleMapFile = FileMgr.getFile(P)) { + InputFileEntry Entry = { ModuleMapFile, false, false }; + SortedFiles.push_front(Entry); + } + } + unsigned UserFilesNum = 0; // Write out all of the input files. std::vector<uint32_t> InputFileOffsets; @@ -1475,7 +1503,8 @@ namespace { using namespace clang::io; uint64_t Start = Out.tell(); (void)Start; - unsigned char Flags = (Data.isImport << 5) + unsigned char Flags = (Data.HeaderRole << 6) + | (Data.isImport << 5) | (Data.isPragmaOnce << 4) | (Data.DirInfo << 2) | (Data.Resolved << 1) @@ -1506,7 +1535,7 @@ namespace { Emit32(Out, Offset); if (Data.isModuleHeader) { - Module *Mod = HS.findModuleForHeader(key.FE); + Module *Mod = HS.findModuleForHeader(key.FE).getModule(); Emit32(Out, Writer.getExistingSubmoduleID(Mod)); } @@ -1542,6 +1571,8 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) { const HeaderFileInfo &HFI = HS.getFileInfo(File); if (HFI.External && Chain) continue; + if (HFI.isModuleHeader && !HFI.isCompilingModuleHeader) + continue; // Turn the file name into an absolute path, if it isn't already. const char *Filename = File->getName(); @@ -1830,12 +1861,10 @@ public: }; } // end anonymous namespace -static int compareMacroDirectives(const void *XPtr, const void *YPtr) { - const std::pair<const IdentifierInfo *, MacroDirective *> &X = - *(const std::pair<const IdentifierInfo *, MacroDirective *>*)XPtr; - const std::pair<const IdentifierInfo *, MacroDirective *> &Y = - *(const std::pair<const IdentifierInfo *, MacroDirective *>*)YPtr; - return X.first->getName().compare(Y.first->getName()); +static int compareMacroDirectives( + const std::pair<const IdentifierInfo *, MacroDirective *> *X, + const std::pair<const IdentifierInfo *, MacroDirective *> *Y) { + return X->first->getName().compare(Y->first->getName()); } static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule, @@ -2249,7 +2278,8 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_REQUIRES)); - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Feature + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // State + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Feature unsigned RequiresAbbrev = Stream.EmitAbbrev(Abbrev); Abbrev = new BitCodeAbbrev(); @@ -2258,6 +2288,11 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(Abbrev); Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_PRIVATE_HEADER)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name + unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(Abbrev); + + Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name @@ -2308,12 +2343,12 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name); // Emit the requirements. - for (unsigned I = 0, N = Mod->Requires.size(); I != N; ++I) { + for (unsigned I = 0, N = Mod->Requirements.size(); I != N; ++I) { Record.clear(); Record.push_back(SUBMODULE_REQUIRES); + Record.push_back(Mod->Requirements[I].second); Stream.EmitRecordWithBlob(RequiresAbbrev, Record, - Mod->Requires[I].data(), - Mod->Requires[I].size()); + Mod->Requirements[I].first); } // Emit the umbrella header, if there is one. @@ -2330,11 +2365,11 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { } // Emit the headers. - for (unsigned I = 0, N = Mod->Headers.size(); I != N; ++I) { + for (unsigned I = 0, N = Mod->NormalHeaders.size(); I != N; ++I) { Record.clear(); Record.push_back(SUBMODULE_HEADER); Stream.EmitRecordWithBlob(HeaderAbbrev, Record, - Mod->Headers[I]->getName()); + Mod->NormalHeaders[I]->getName()); } // Emit the excluded headers. for (unsigned I = 0, N = Mod->ExcludedHeaders.size(); I != N; ++I) { @@ -2343,6 +2378,13 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Stream.EmitRecordWithBlob(ExcludedHeaderAbbrev, Record, Mod->ExcludedHeaders[I]->getName()); } + // Emit the private headers. + for (unsigned I = 0, N = Mod->PrivateHeaders.size(); I != N; ++I) { + Record.clear(); + Record.push_back(SUBMODULE_PRIVATE_HEADER); + Stream.EmitRecordWithBlob(PrivateHeaderAbbrev, Record, + Mod->PrivateHeaders[I]->getName()); + } ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(PP->getFileManager()); for (unsigned I = 0, N = TopHeaders.size(); I != N; ++I) { @@ -2380,6 +2422,10 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Stream.EmitRecord(SUBMODULE_EXPORTS, Record); } + //FIXME: How do we emit the 'use'd modules? They may not be submodules. + // Might be unnecessary as use declarations are only used to build the + // module itself. + // Emit the link libraries. for (unsigned I = 0, N = Mod->LinkLibraries.size(); I != N; ++I) { Record.clear(); @@ -3096,7 +3142,7 @@ public: // Only emit declarations that aren't from a chained PCH, though. SmallVector<Decl *, 16> Decls(IdResolver.begin(II), IdResolver.end()); - for (SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(), + for (SmallVectorImpl<Decl *>::reverse_iterator D = Decls.rbegin(), DEnd = Decls.rend(); D != DEnd; ++D) clang::io::Emit32(Out, Writer.getDeclID(getMostRecentLocalDecl(*D))); @@ -3486,7 +3532,7 @@ void ASTWriter::WriteRedeclarations() { for (unsigned I = 0, N = Redeclarations.size(); I != N; ++I) { Decl *First = Redeclarations[I]; - assert(First->getPreviousDecl() == 0 && "Not the first declaration?"); + assert(First->isFirstDecl() && "Not the first declaration?"); Decl *MostRecent = First->getMostRecentDecl(); @@ -3631,6 +3677,30 @@ void ASTWriter::WriteMergedDecls() { Stream.EmitRecord(MERGED_DECLARATIONS, Record); } +void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) { + Sema::LateParsedTemplateMapT &LPTMap = SemaRef.LateParsedTemplateMap; + + if (LPTMap.empty()) + return; + + RecordData Record; + for (Sema::LateParsedTemplateMapT::iterator It = LPTMap.begin(), + ItEnd = LPTMap.end(); + It != ItEnd; ++It) { + LateParsedTemplate *LPT = It->second; + AddDeclRef(It->first, Record); + AddDeclRef(LPT->D, Record); + Record.push_back(LPT->Toks.size()); + + for (CachedTokens::iterator TokIt = LPT->Toks.begin(), + TokEnd = LPT->Toks.end(); + TokIt != TokEnd; ++TokIt) { + AddToken(*TokIt, Record); + } + } + Stream.EmitRecord(LATE_PARSED_TEMPLATE, Record); +} + //===----------------------------------------------------------------------===// // General Serialization Routines //===----------------------------------------------------------------------===// @@ -3812,8 +3882,9 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, // FIXME: Modules won't like this at all. IdentifierTable &Table = PP.getIdentifierTable(); SmallVector<const char *, 32> BuiltinNames; - Context.BuiltinInfo.GetBuiltinNames(BuiltinNames, - Context.getLangOpts().NoBuiltin); + if (!Context.getLangOpts().NoBuiltin) { + Context.BuiltinInfo.GetBuiltinNames(BuiltinNames); + } for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I) getIdentifierRef(&Table.get(BuiltinNames[I])); } @@ -3998,12 +4069,27 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, // Make sure visible decls, added to DeclContexts previously loaded from // an AST file, are registered for serialization. - for (SmallVector<const Decl *, 16>::iterator + for (SmallVectorImpl<const Decl *>::iterator I = UpdatingVisibleDecls.begin(), E = UpdatingVisibleDecls.end(); I != E; ++I) { GetDeclRef(*I); } + // Make sure all decls associated with an identifier are registered for + // serialization. + for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(), + IDEnd = PP.getIdentifierTable().end(); + ID != IDEnd; ++ID) { + const IdentifierInfo *II = ID->second; + if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization()) { + for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II), + DEnd = SemaRef.IdResolver.end(); + D != DEnd; ++D) { + GetDeclRef(*D); + } + } + } + // Resolve any declaration pointers within the declaration updates block. ResolveDeclUpdatesBlocks(); @@ -4197,7 +4283,8 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, WriteRedeclarations(); WriteMergedDecls(); WriteObjCCategories(); - + WriteLateParsedTemplates(SemaRef); + // Some simple statistics Record.clear(); Record.push_back(NumStatements); @@ -4228,8 +4315,15 @@ void ASTWriter::ResolveDeclUpdatesBlocks() { URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx])); ++Idx; break; - + case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER: + case UPD_DECL_MARKED_USED: + ++Idx; + break; + + case UPD_CXX_DEDUCED_RETURN_TYPE: + URec[Idx] = GetOrCreateTypeID( + QualType::getFromOpaquePtr(reinterpret_cast<void *>(URec[Idx]))); ++Idx; break; } @@ -4266,8 +4360,8 @@ void ASTWriter::WriteDeclReplacementsBlock() { return; RecordData Record; - for (SmallVector<ReplacedDeclInfo, 16>::iterator - I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) { + for (SmallVectorImpl<ReplacedDeclInfo>::iterator + I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) { Record.push_back(I->ID); Record.push_back(I->Offset); Record.push_back(I->Loc); @@ -4446,11 +4540,13 @@ void ASTWriter::AddTypeRef(QualType T, RecordDataImpl &Record) { } TypeID ASTWriter::GetOrCreateTypeID( QualType T) { + assert(Context); return MakeTypeID(*Context, T, std::bind1st(std::mem_fun(&ASTWriter::GetOrCreateTypeIdx), this)); } TypeID ASTWriter::getTypeID(QualType T) const { + assert(Context); return MakeTypeID(*Context, T, std::bind1st(std::mem_fun(&ASTWriter::getTypeIdx), this)); } @@ -4531,11 +4627,6 @@ DeclID ASTWriter::getDeclID(const Decl *D) { return DeclIDs[D]; } -static inline bool compLocDecl(std::pair<unsigned, serialization::DeclID> L, - std::pair<unsigned, serialization::DeclID> R) { - return L.first < R.first; -} - void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { assert(ID); assert(D); @@ -4574,8 +4665,8 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { return; } - LocDeclIDsTy::iterator - I = std::upper_bound(Decls.begin(), Decls.end(), LocDecl, compLocDecl); + LocDeclIDsTy::iterator I = + std::upper_bound(Decls.begin(), Decls.end(), LocDecl, llvm::less_first()); Decls.insert(I, LocDecl); } @@ -4874,6 +4965,17 @@ ASTWriter::AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, AddTemplateArgument(TemplateArgs->get(i), Record); } +void +ASTWriter::AddASTTemplateArgumentListInfo +(const ASTTemplateArgumentListInfo *ASTTemplArgList, RecordDataImpl &Record) { + assert(ASTTemplArgList && "No ASTTemplArgList!"); + AddSourceLocation(ASTTemplArgList->LAngleLoc, Record); + AddSourceLocation(ASTTemplArgList->RAngleLoc, Record); + Record.push_back(ASTTemplArgList->NumTemplateArgs); + const TemplateArgumentLoc *TemplArgs = ASTTemplArgList->getTemplateArgs(); + for (int i=0, e = ASTTemplArgList->NumTemplateArgs; i != e; ++i) + AddTemplateArgumentLoc(TemplArgs[i], Record); +} void ASTWriter::AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record) { @@ -5004,8 +5106,6 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec Record.push_back(Data.ImplicitCopyAssignmentHasConstParam); Record.push_back(Data.HasDeclaredCopyConstructorWithConstParam); Record.push_back(Data.HasDeclaredCopyAssignmentWithConstParam); - Record.push_back(Data.FailedImplicitMoveConstructor); - Record.push_back(Data.FailedImplicitMoveAssignment); // IsLambda bit is already saved. Record.push_back(Data.NumBases); @@ -5019,15 +5119,17 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec AddCXXBaseSpecifiersRef(Data.getVBases(), Data.getVBases() + Data.NumVBases, Record); - AddUnresolvedSet(Data.Conversions, Record); - AddUnresolvedSet(Data.VisibleConversions, Record); + AddUnresolvedSet(Data.Conversions.get(*Context), Record); + AddUnresolvedSet(Data.VisibleConversions.get(*Context), Record); // Data.Definition is the owning decl, no need to write it. - AddDeclRef(Data.FirstFriend, Record); + AddDeclRef(D->getFirstFriend(), Record); // Add lambda-specific data. if (Data.IsLambda) { CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData(); Record.push_back(Lambda.Dependent); + Record.push_back(Lambda.IsGenericLambda); + Record.push_back(Lambda.CaptureDefault); Record.push_back(Lambda.NumCaptures); Record.push_back(Lambda.NumExplicitCaptures); Record.push_back(Lambda.ManglingNumber); @@ -5037,12 +5139,20 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec LambdaExpr::Capture &Capture = Lambda.Captures[I]; AddSourceLocation(Capture.getLocation(), Record); Record.push_back(Capture.isImplicit()); - Record.push_back(Capture.getCaptureKind()); // FIXME: stable! - VarDecl *Var = Capture.capturesVariable()? Capture.getCapturedVar() : 0; - AddDeclRef(Var, Record); - AddSourceLocation(Capture.isPackExpansion()? Capture.getEllipsisLoc() - : SourceLocation(), - Record); + Record.push_back(Capture.getCaptureKind()); + switch (Capture.getCaptureKind()) { + case LCK_This: + break; + case LCK_ByCopy: + case LCK_ByRef: + VarDecl *Var = + Capture.capturesVariable() ? Capture.getCapturedVar() : 0; + AddDeclRef(Var, Record); + AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc() + : SourceLocation(), + Record); + break; + } } } } @@ -5174,6 +5284,19 @@ void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, Record.push_back(reinterpret_cast<uint64_t>(D)); } +void ASTWriter::AddedCXXTemplateSpecialization( + const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) { + // The specializations set is kept in the canonical template. + assert(!WritingAST && "Already writing the AST!"); + TD = TD->getCanonicalDecl(); + if (!(!D->isFromASTFile() && TD->isFromASTFile())) + return; // Not a source specialization added to a template from PCH. + + UpdateRecord &Record = DeclUpdates[TD]; + Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION); + Record.push_back(reinterpret_cast<uint64_t>(D)); +} + void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, const FunctionDecl *D) { // The specializations set is kept in the canonical template. @@ -5187,6 +5310,17 @@ void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, Record.push_back(reinterpret_cast<uint64_t>(D)); } +void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) { + assert(!WritingAST && "Already writing the AST!"); + FD = FD->getCanonicalDecl(); + if (!FD->isFromASTFile()) + return; // Not a function declared in PCH and defined outside. + + UpdateRecord &Record = DeclUpdates[FD]; + Record.push_back(UPD_CXX_DEDUCED_RETURN_TYPE); + Record.push_back(reinterpret_cast<uint64_t>(ReturnType.getAsOpaquePtr())); +} + void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) { assert(!WritingAST && "Already writing the AST!"); if (!D->isFromASTFile()) @@ -5235,3 +5369,12 @@ void ASTWriter::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, RewriteDecl(D); } + +void ASTWriter::DeclarationMarkedUsed(const Decl *D) { + assert(!WritingAST && "Already writing the AST!"); + if (!D->isFromASTFile()) + return; + + UpdateRecord &Record = DeclUpdates[D]; + Record.push_back(UPD_DECL_MARKED_USED); +} diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp index 67349db..55f830a 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterDecl.cpp @@ -68,6 +68,9 @@ namespace clang { ClassTemplateSpecializationDecl *D); void VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D); + void VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); + void VisitVarTemplatePartialSpecializationDecl( + VarTemplatePartialSpecializationDecl *D); void VisitClassScopeFunctionSpecializationDecl( ClassScopeFunctionSpecializationDecl *D); void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); @@ -90,6 +93,7 @@ namespace clang { void VisitTemplateDecl(TemplateDecl *D); void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); + void VisitVarTemplateDecl(VarTemplateDecl *D); void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); @@ -184,7 +188,10 @@ void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) { void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) { VisitRedeclarable(D); VisitTypeDecl(D); - Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record); + Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record); + Record.push_back(D->isModed()); + if (D->isModed()) + Writer.AddTypeRef(D->getUnderlyingType(), Record); } void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { @@ -192,7 +199,7 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { if (!D->hasAttrs() && !D->isImplicit() && !D->isUsed(false) && - D->getFirstDeclaration() == D->getMostRecentDecl() && + D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && @@ -217,10 +224,13 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) { Record.push_back(D->isCompleteDefinition()); Record.push_back(D->isEmbeddedInDeclarator()); Record.push_back(D->isFreeStanding()); + Record.push_back(D->isCompleteDefinitionRequired()); Writer.AddSourceLocation(D->getRBraceLoc(), Record); Record.push_back(D->hasExtInfo()); if (D->hasExtInfo()) Writer.AddQualifierInfo(*D->getExtInfo(), Record); + else if (D->hasDeclaratorForAnonDecl()) + Writer.AddDeclRef(D->getDeclaratorForAnonDecl(), Record); else Writer.AddDeclRef(D->getTypedefNameForAnonDecl(), Record); } @@ -248,7 +258,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { !D->isImplicit() && !D->isUsed(false) && !D->hasExtInfo() && - D->getFirstDeclaration() == D->getMostRecentDecl() && + D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && @@ -274,7 +284,7 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) { !D->isImplicit() && !D->isUsed(false) && !D->hasExtInfo() && - D->getFirstDeclaration() == D->getMostRecentDecl() && + D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && @@ -334,7 +344,8 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Record.push_back(D->hasImplicitReturnZero()); Record.push_back(D->isConstexpr()); Record.push_back(D->HasSkippedBody); - Record.push_back(D->getLinkage()); + Record.push_back(D->isLateTemplateParsed()); + Record.push_back(D->getLinkageInternal()); Writer.AddSourceLocation(D->getLocEnd(), Record); Record.push_back(D->getTemplatedKind()); @@ -517,6 +528,7 @@ void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) { // FIXME: stable encoding for @public/@private/@protected/@package Record.push_back(D->getAccessControl()); Record.push_back(D->getSynthesize()); + Record.push_back(D->getBackingIvarReferencedInAccessor()); if (!D->hasAttrs() && !D->isImplicit() && @@ -694,7 +706,9 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(D->isCXXForRangeDecl()); Record.push_back(D->isARCPseudoStrong()); Record.push_back(D->isConstexpr()); - Record.push_back(D->getLinkage()); + Record.push_back(D->isInitCapture()); + Record.push_back(D->isPreviousDeclInSameBlockScope()); + Record.push_back(D->getLinkageInternal()); if (D->getInit()) { Record.push_back(!D->isInitKnownICE() ? 1 : (D->isInitICE() ? 3 : 2)); @@ -702,14 +716,21 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { } else { Record.push_back(0); } - - MemberSpecializationInfo *SpecInfo - = D->isStaticDataMember() ? D->getMemberSpecializationInfo() : 0; - Record.push_back(SpecInfo != 0); - if (SpecInfo) { + + enum { + VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization + }; + if (VarTemplateDecl *TemplD = D->getDescribedVarTemplate()) { + Record.push_back(VarTemplate); + Writer.AddDeclRef(TemplD, Record); + } else if (MemberSpecializationInfo *SpecInfo + = D->getMemberSpecializationInfo()) { + Record.push_back(StaticDataMemberSpecialization); Writer.AddDeclRef(SpecInfo->getInstantiatedFrom(), Record); Record.push_back(SpecInfo->getTemplateSpecializationKind()); Writer.AddSourceLocation(SpecInfo->getPointOfInstantiation(), Record); + } else { + Record.push_back(VarNotTemplate); } if (!D->hasAttrs() && @@ -722,12 +743,15 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { !D->isModulePrivate() && D->getDeclName().getNameKind() == DeclarationName::Identifier && !D->hasExtInfo() && - D->getFirstDeclaration() == D->getMostRecentDecl() && + D->getFirstDecl() == D->getMostRecentDecl() && D->getInitStyle() == VarDecl::CInit && D->getInit() == 0 && !isa<ParmVarDecl>(D) && + !isa<VarTemplateSpecializationDecl>(D) && !D->isConstexpr() && - !SpecInfo) + !D->isInitCapture() && + !D->isPreviousDeclInSameBlockScope() && + !D->getMemberSpecializationInfo()) AbbrevToUse = Writer.getDeclVarAbbrev(); Code = serialization::DECL_VAR; @@ -905,16 +929,17 @@ void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { void ASTDeclWriter::VisitUsingDecl(UsingDecl *D) { VisitNamedDecl(D); - Writer.AddSourceLocation(D->getUsingLocation(), Record); + Writer.AddSourceLocation(D->getUsingLoc(), Record); Writer.AddNestedNameSpecifierLoc(D->getQualifierLoc(), Record); Writer.AddDeclarationNameLoc(D->DNLoc, D->getDeclName(), Record); Writer.AddDeclRef(D->FirstUsingShadow.getPointer(), Record); - Record.push_back(D->isTypeName()); + Record.push_back(D->hasTypename()); Writer.AddDeclRef(Context.getInstantiatedFromUsingDecl(D), Record); Code = serialization::DECL_USING; } void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) { + VisitRedeclarable(D); VisitNamedDecl(D); Writer.AddDeclRef(D->getTargetDecl(), Record); Writer.AddDeclRef(D->UsingOrNextShadow, Record); @@ -997,7 +1022,6 @@ void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { VisitCXXMethodDecl(D); Record.push_back(D->IsExplicitSpecified); - Record.push_back(D->ImplicitlyDefined); Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers, Record); @@ -1007,7 +1031,6 @@ void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) { VisitCXXMethodDecl(D); - Record.push_back(D->ImplicitlyDefined); Writer.AddDeclRef(D->OperatorDelete, Record); Code = serialization::DECL_CXX_DESTRUCTOR; @@ -1089,7 +1112,7 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that // getCommonPtr() can be used while this is still initializing. - if (D->isFirstDeclaration()) { + if (D->isFirstDecl()) { // This declaration owns the 'common' pointer, so serialize that data now. Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record); if (D->getInstantiatedFromMemberTemplate()) @@ -1103,7 +1126,7 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->isFirstDeclaration()) { + if (D->isFirstDecl()) { typedef llvm::FoldingSetVector<ClassTemplateSpecializationDecl> CTSDSetTy; CTSDSetTy &CTSDSet = D->getSpecializations(); Record.push_back(CTSDSet.size()); @@ -1141,13 +1164,6 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl( Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record); } - // Explicit info. - Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record); - if (D->getTypeAsWritten()) { - Writer.AddSourceLocation(D->getExternLoc(), Record); - Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record); - } - Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record); Writer.AddSourceLocation(D->getPointOfInstantiation(), Record); Record.push_back(D->getSpecializationKind()); @@ -1158,6 +1174,13 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl( Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record); } + // Explicit info. + Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record); + if (D->getTypeAsWritten()) { + Writer.AddSourceLocation(D->getExternLoc(), Record); + Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record); + } + Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION; } @@ -1166,12 +1189,83 @@ void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl( VisitClassTemplateSpecializationDecl(D); Writer.AddTemplateParameterList(D->getTemplateParameters(), Record); + Writer.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten(), Record); + + // These are read/set from/to the first declaration. + if (D->getPreviousDecl() == 0) { + Writer.AddDeclRef(D->getInstantiatedFromMember(), Record); + Record.push_back(D->isMemberSpecialization()); + } + + Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION; +} + +void ASTDeclWriter::VisitVarTemplateDecl(VarTemplateDecl *D) { + VisitRedeclarableTemplateDecl(D); + + if (D->isFirstDecl()) { + typedef llvm::FoldingSetVector<VarTemplateSpecializationDecl> VTSDSetTy; + VTSDSetTy &VTSDSet = D->getSpecializations(); + Record.push_back(VTSDSet.size()); + for (VTSDSetTy::iterator I = VTSDSet.begin(), E = VTSDSet.end(); I != E; + ++I) { + assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); + Writer.AddDeclRef(&*I, Record); + } - Record.push_back(D->getNumTemplateArgsAsWritten()); - for (int i = 0, e = D->getNumTemplateArgsAsWritten(); i != e; ++i) - Writer.AddTemplateArgumentLoc(D->getTemplateArgsAsWritten()[i], Record); + typedef llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> + VTPSDSetTy; + VTPSDSetTy &VTPSDSet = D->getPartialSpecializations(); + Record.push_back(VTPSDSet.size()); + for (VTPSDSetTy::iterator I = VTPSDSet.begin(), E = VTPSDSet.end(); I != E; + ++I) { + assert(I->isCanonicalDecl() && "Expected only canonical decls in set"); + Writer.AddDeclRef(&*I, Record); + } + } + Code = serialization::DECL_VAR_TEMPLATE; +} - Record.push_back(D->getSequenceNumber()); +void ASTDeclWriter::VisitVarTemplateSpecializationDecl( + VarTemplateSpecializationDecl *D) { + VisitVarDecl(D); + + llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> + InstFrom = D->getSpecializedTemplateOrPartial(); + if (Decl *InstFromD = InstFrom.dyn_cast<VarTemplateDecl *>()) { + Writer.AddDeclRef(InstFromD, Record); + } else { + Writer.AddDeclRef(InstFrom.get<VarTemplatePartialSpecializationDecl *>(), + Record); + Writer.AddTemplateArgumentList(&D->getTemplateInstantiationArgs(), Record); + } + + // Explicit info. + Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record); + if (D->getTypeAsWritten()) { + Writer.AddSourceLocation(D->getExternLoc(), Record); + Writer.AddSourceLocation(D->getTemplateKeywordLoc(), Record); + } + + Writer.AddTemplateArgumentList(&D->getTemplateArgs(), Record); + Writer.AddSourceLocation(D->getPointOfInstantiation(), Record); + Record.push_back(D->getSpecializationKind()); + Record.push_back(D->isCanonicalDecl()); + + if (D->isCanonicalDecl()) { + // When reading, we'll add it to the folding set of the following template. + Writer.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl(), Record); + } + + Code = serialization::DECL_VAR_TEMPLATE_SPECIALIZATION; +} + +void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl( + VarTemplatePartialSpecializationDecl *D) { + VisitVarTemplateSpecializationDecl(D); + + Writer.AddTemplateParameterList(D->getTemplateParameters(), Record); + Writer.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten(), Record); // These are read/set from/to the first declaration. if (D->getPreviousDecl() == 0) { @@ -1179,7 +1273,7 @@ void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl( Record.push_back(D->isMemberSpecialization()); } - Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION; + Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION; } void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl( @@ -1193,7 +1287,7 @@ void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl( void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { VisitRedeclarableTemplateDecl(D); - if (D->isFirstDeclaration()) { + if (D->isFirstDecl()) { // This FunctionTemplateDecl owns the CommonPtr; write it. // Write the function specialization declarations. @@ -1310,7 +1404,7 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, template <typename T> void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) { - T *First = D->getFirstDeclaration(); + T *First = D->getFirstDecl(); if (First->getMostRecentDecl() != First) { assert(isRedeclarableDeclKind(static_cast<T *>(D)->getKind()) && "Not considered redeclarable?"); @@ -1412,6 +1506,8 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { // ObjC Ivar Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize + // getBackingIvarReferencedInAccessor + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Source Info Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); @@ -1447,6 +1543,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypedefNameAnonDecl @@ -1494,6 +1591,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCompleteDefinition Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // EmbeddedInDeclarator Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFreeStanding + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsCompleteDefinitionRequired Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation Abv->Add(BitCodeAbbrevOp(0)); // hasExtInfo Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TypedefNameAnonDecl @@ -1541,6 +1639,8 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(0)); // isCXXForRangeDecl Abv->Add(BitCodeAbbrevOp(0)); // isARCPseudoStrong Abv->Add(BitCodeAbbrevOp(0)); // isConstexpr + Abv->Add(BitCodeAbbrevOp(0)); // isInitCapture + Abv->Add(BitCodeAbbrevOp(0)); // isPrevDeclInSameScope Abv->Add(BitCodeAbbrevOp(0)); // Linkage Abv->Add(BitCodeAbbrevOp(0)); // HasInit Abv->Add(BitCodeAbbrevOp(0)); // HasMemberSpecializationInfo @@ -1620,7 +1720,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isCXXForRangeDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isARCPseudoStrong Abv->Add(BitCodeAbbrevOp(0)); // isConstexpr - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Linkage + Abv->Add(BitCodeAbbrevOp(0)); // isInitCapture + Abv->Add(BitCodeAbbrevOp(0)); // isPrevDeclInSameScope + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasInit Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasMemberSpecInfo // Type Source Info diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp index 5f7ac01..072fc98 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp @@ -6,9 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file implements serialization for Statements and Expressions. -// +/// +/// \file +/// \brief Implements serialization for Statements and Expressions. +/// //===----------------------------------------------------------------------===// #include "clang/Serialization/ASTWriter.h" @@ -26,7 +27,9 @@ using namespace clang; //===----------------------------------------------------------------------===// namespace clang { + class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> { + friend class OMPClauseWriter; ASTWriter &Writer; ASTWriter::RecordData &Record; @@ -683,7 +686,6 @@ void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) { else Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record); Record.push_back(E->hadArrayRangeDesignator()); - Record.push_back(E->initializesStdInitializerList()); Record.push_back(E->getNumInits()); if (isArrayFiller) { // ArrayFiller may have filled "holes" due to designated initializer. @@ -772,6 +774,7 @@ void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) { Writer.AddStmt(E->getRHS()); Writer.AddSourceLocation(E->getBuiltinLoc(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record); + Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue()); Code = serialization::EXPR_CHOOSE; } @@ -791,6 +794,15 @@ void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { Code = serialization::EXPR_SHUFFLE_VECTOR; } +void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) { + VisitExpr(E); + Writer.AddSourceLocation(E->getBuiltinLoc(), Record); + Writer.AddSourceLocation(E->getRParenLoc(), Record); + Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record); + Writer.AddStmt(E->getSrcExpr()); + Code = serialization::EXPR_CONVERT_VECTOR; +} + void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) { VisitExpr(E); Writer.AddDeclRef(E->getBlockDecl(), Record); @@ -1145,7 +1157,7 @@ void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) { Record.push_back(E->isListInitialization()); Record.push_back(E->requiresZeroInitialization()); Record.push_back(E->getConstructionKind()); // FIXME: stable encoding - Writer.AddSourceRange(E->getParenRange(), Record); + Writer.AddSourceRange(E->getParenOrBraceRange(), Record); Code = serialization::EXPR_CXX_CONSTRUCT; } @@ -1164,6 +1176,7 @@ void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) { Record.push_back(NumArrayIndexVars); Writer.AddSourceRange(E->IntroducerRange, Record); Record.push_back(E->CaptureDefault); // FIXME: stable encoding + Writer.AddSourceLocation(E->CaptureDefaultLoc, Record); Record.push_back(E->ExplicitParams); Record.push_back(E->ExplicitResultType); Writer.AddSourceLocation(E->ClosingBrace, Record); @@ -1187,6 +1200,12 @@ void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) { Code = serialization::EXPR_LAMBDA; } +void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { + VisitExpr(E); + Writer.AddStmt(E->getSubExpr()); + Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST; +} + void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { VisitExplicitCastExpr(E); Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()), @@ -1216,7 +1235,7 @@ void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) { void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) { VisitExplicitCastExpr(E); - Writer.AddSourceLocation(E->getTypeBeginLoc(), Record); + Writer.AddSourceLocation(E->getLParenLoc(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record); Code = serialization::EXPR_CXX_FUNCTIONAL_CAST; } @@ -1572,6 +1591,7 @@ void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) { VisitExpr(E); Writer.AddStmt(E->Temporary); + Writer.AddDeclRef(E->ExtendingDecl, Record); Code = serialization::EXPR_MATERIALIZE_TEMPORARY; } @@ -1653,6 +1673,84 @@ void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) { } //===----------------------------------------------------------------------===// +// OpenMP Clauses. +//===----------------------------------------------------------------------===// + +namespace clang { +class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> { + ASTStmtWriter *Writer; + ASTWriter::RecordData &Record; +public: + OMPClauseWriter(ASTStmtWriter *W, ASTWriter::RecordData &Record) + : Writer(W), Record(Record) { } +#define OPENMP_CLAUSE(Name, Class) \ + void Visit##Class(Class *S); +#include "clang/Basic/OpenMPKinds.def" + void writeClause(OMPClause *C); +}; +} + +void OMPClauseWriter::writeClause(OMPClause *C) { + Record.push_back(C->getClauseKind()); + Visit(C); + Writer->Writer.AddSourceLocation(C->getLocStart(), Record); + Writer->Writer.AddSourceLocation(C->getLocEnd(), Record); +} + +void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) { + Record.push_back(C->getDefaultKind()); + Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); + Writer->Writer.AddSourceLocation(C->getDefaultKindKwLoc(), Record); +} + +void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { + Record.push_back(C->varlist_size()); + Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); + for (OMPPrivateClause::varlist_iterator I = C->varlist_begin(), + E = C->varlist_end(); + I != E; ++I) + Writer->Writer.AddStmt(*I); +} + +void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) { + Record.push_back(C->varlist_size()); + Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); + for (OMPFirstprivateClause::varlist_iterator I = C->varlist_begin(), + E = C->varlist_end(); + I != E; ++I) + Writer->Writer.AddStmt(*I); +} + +void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) { + Record.push_back(C->varlist_size()); + Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); + for (OMPSharedClause::varlist_iterator I = C->varlist_begin(), + E = C->varlist_end(); + I != E; ++I) + Writer->Writer.AddStmt(*I); +} + +//===----------------------------------------------------------------------===// +// OpenMP Directives. +//===----------------------------------------------------------------------===// +void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) { + VisitStmt(E); + Record.push_back(E->getNumClauses()); + Writer.AddSourceLocation(E->getLocStart(), Record); + Writer.AddSourceLocation(E->getLocEnd(), Record); + OMPClauseWriter ClauseWriter(this, Record); + for (unsigned i = 0; i < E->getNumClauses(); ++i) { + ClauseWriter.writeClause(E->getClause(i)); + } + Writer.AddStmt(E->getAssociatedStmt()); +} + +void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) { + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE; +} + +//===----------------------------------------------------------------------===// // ASTWriter Implementation //===----------------------------------------------------------------------===// diff --git a/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp b/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp index 32c2df3..7e8baa2 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/GeneratePCH.cpp @@ -28,22 +28,29 @@ PCHGenerator::PCHGenerator(const Preprocessor &PP, StringRef OutputFile, clang::Module *Module, StringRef isysroot, - raw_ostream *OS) + raw_ostream *OS, bool AllowASTWithErrors) : PP(PP), OutputFile(OutputFile), Module(Module), isysroot(isysroot.str()), Out(OS), - SemaPtr(0), Stream(Buffer), Writer(Stream) { + SemaPtr(0), Stream(Buffer), Writer(Stream), + AllowASTWithErrors(AllowASTWithErrors), + HasEmittedPCH(false) { } PCHGenerator::~PCHGenerator() { } void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { - if (PP.getDiagnostics().hasErrorOccurred()) + // Don't create a PCH if there were fatal failures during module loading. + if (PP.getModuleLoader().HadFatalFailure) + return; + + bool hasErrors = PP.getDiagnostics().hasErrorOccurred(); + if (hasErrors && !AllowASTWithErrors) return; // Emit the PCH file assert(SemaPtr && "No Sema?"); - Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot); + Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot, hasErrors); // Write the generated bitstream to "Out". Out->write((char *)&Buffer.front(), Buffer.size()); @@ -53,6 +60,8 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { // Free up some memory, in case the process is kept alive. Buffer.clear(); + + HasEmittedPCH = true; } ASTMutationListener *PCHGenerator::GetASTMutationListener() { diff --git a/contrib/llvm/tools/clang/lib/Serialization/GlobalModuleIndex.cpp b/contrib/llvm/tools/clang/lib/Serialization/GlobalModuleIndex.cpp index b6693e4..fb647b0 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/GlobalModuleIndex.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/GlobalModuleIndex.cpp @@ -26,7 +26,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/LockFileManager.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PathV2.h" +#include "llvm/Support/Path.h" #include <cstdio> using namespace clang; using namespace serialization; @@ -229,7 +229,8 @@ GlobalModuleIndex::readIndex(StringRef Path) { llvm::sys::path::append(IndexPath, IndexFileName); llvm::OwningPtr<llvm::MemoryBuffer> Buffer; - if (llvm::MemoryBuffer::getFile(IndexPath, Buffer) != llvm::errc::success) + if (llvm::MemoryBuffer::getFile(IndexPath.c_str(), Buffer) != + llvm::errc::success) return std::make_pair((GlobalModuleIndex *)0, EC_NotFound); /// \brief The bitstream reader from which we'll read the AST file. @@ -790,7 +791,8 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, StringRef Path) { // Write the global index file to a temporary file. llvm::SmallString<128> IndexTmpPath; int TmpFD; - if (llvm::sys::fs::unique_file(IndexPath + "-%%%%%%%%", TmpFD, IndexTmpPath)) + if (llvm::sys::fs::createUniqueFile(IndexPath + "-%%%%%%%%", TmpFD, + IndexTmpPath)) return EC_IOError; // Open the temporary global index file for output. diff --git a/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp b/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp index f3d53ad..9c4b3d9 100644 --- a/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp +++ b/contrib/llvm/tools/clang/lib/Serialization/ModuleManager.cpp @@ -12,10 +12,10 @@ // //===----------------------------------------------------------------------===// #include "clang/Lex/ModuleMap.h" -#include "clang/Serialization/ModuleManager.h" #include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Serialization/ModuleManager.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PathV2.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" @@ -62,11 +62,13 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, // Look for the file entry. This only fails if the expected size or // modification time differ. const FileEntry *Entry; - if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) + if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) { + ErrorStr = "module file out of date"; return OutOfDate; + } if (!Entry && FileName != "-") { - ErrorStr = "file not found"; + ErrorStr = "module file not found"; return Missing; } @@ -332,8 +334,7 @@ ModuleManager::visit(bool (*Visitor)(ModuleFile &M, void *UserData), break; // Pop the next module off the stack. - NextModule = State->Stack.back(); - State->Stack.pop_back(); + NextModule = State->Stack.pop_back_val(); } while (true); } |