summaryrefslogtreecommitdiffstats
path: root/lib/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTCommon.cpp5
-rw-r--r--lib/Serialization/ASTCommon.h4
-rw-r--r--lib/Serialization/ASTReader.cpp293
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp772
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp145
-rw-r--r--lib/Serialization/ASTWriter.cpp229
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp170
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp110
-rw-r--r--lib/Serialization/GeneratePCH.cpp17
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp8
-rw-r--r--lib/Serialization/ModuleManager.cpp13
11 files changed, 1412 insertions, 354 deletions
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index 24b268f..a817687 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/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/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index 76ef904..ef81e69 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/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/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 22caeb8..4d1b4b9 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/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/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index f7fa818..b8102d8 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/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/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index e1357ba..1115e8f 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/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/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index b8ada04..405488c 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/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/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 67349db..55f830a 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/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/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 5f7ac01..072fc98 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/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/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index 32c2df3..7e8baa2 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/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/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index b6693e4..fb647b0 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/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/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index f3d53ad..9c4b3d9 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/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);
}
OpenPOWER on IntegriCloud