diff options
author | Axel Naumann <Axel.Naumann@cern.ch> | 2012-10-02 09:09:43 +0000 |
---|---|---|
committer | Axel Naumann <Axel.Naumann@cern.ch> | 2012-10-02 09:09:43 +0000 |
commit | 63469422c403a866157a612f2f7f97c72dcd6de3 (patch) | |
tree | b0de9df3ca42503f4a5b52ba5483b03a5a8f6126 /clang/lib/Serialization/ASTReaderDecl.cpp | |
parent | 7e5ef83cdb85e1335b77af11b1ec5a56c148c8ef (diff) | |
download | bcm5719-llvm-63469422c403a866157a612f2f7f97c72dcd6de3.tar.gz bcm5719-llvm-63469422c403a866157a612f2f7f97c72dcd6de3.zip |
Merge pending instantiations instead of overwriting existing ones.
Check whether a pending instantiation needs to be instantiated (or whether an instantiation already exists).
Verify the size of the PendingInstantiations record (was only checking size of existing PendingInstantiations).
Migrate Obj-C++ part of redecl-merge into separate test, now that this is growing.
templates.mm: test that CodeGen has seen exactly one definition of template instantiations.
redecl-merge.m: use "@" specifier for expected-diagnostics.
llvm-svn: 164993
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index fb4192f86a7..85740de15b5 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2156,7 +2156,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { // loading, and some declarations may still be initializing. if (isConsumerInterestedIn(D)) InterestingDecls.push_back(D); - + return D; } @@ -2504,3 +2504,60 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, } } } + +/// \brief Return a template specialization of ND (should be a TemplateDecl) +/// that matches FD or TD. +static NamedDecl* findMatchingSpecialization(FunctionDecl* FD, + ClassTemplateSpecializationDecl*TD, + NamedDecl* ND) { + TemplateDecl* Templt = dyn_cast<TemplateDecl>(ND); + if (!Templt) return 0; + if (FD) { + FunctionTemplateDecl* FTD = dyn_cast<FunctionTemplateDecl>(Templt); + if (!FTD) return 0; + const TemplateArgumentList* TmpltArgs = FD->getTemplateSpecializationArgs(); + assert(TmpltArgs || "Template without arguments"); + void* InsertionPoint; + return FTD->findSpecialization(TmpltArgs->data(), TmpltArgs->size(), + InsertionPoint); + } else { + ClassTemplateDecl* CTD = dyn_cast<ClassTemplateDecl>(Templt); + if (!CTD) return 0; + const TemplateArgumentList& TmpltArgs = TD->getTemplateArgs(); + void* InsertionPoint; + return CTD->findSpecialization(TmpltArgs.data(), TmpltArgs.size(), + InsertionPoint); + } + return 0; +} + +/// \brief Find out whether an instantiation (outside the module) already exists +bool ASTReader::needPendingInstantiation(ValueDecl* D) const { + DeclContext *DC = D->getDeclContext()->getRedeclContext(); + DeclarationName Name = D->getDeclName(); + assert(Name && "unnamed template"); + + FunctionDecl* FD = dyn_cast<FunctionDecl>(D); + ClassTemplateSpecializationDecl* CD + = FD ? 0 : dyn_cast<ClassTemplateSpecializationDecl>(D); + + NamedDecl* FoundSpecialization = 0; + if (DC->isTranslationUnit() && SemaObj) { + IdentifierResolver &IdResolver = SemaObj->IdResolver; + for (IdentifierResolver::iterator I = IdResolver.begin(Name), + IEnd = IdResolver.end(); + I != IEnd && !FoundSpecialization; ++I) + FoundSpecialization = findMatchingSpecialization(FD, CD, *I); + } else { + // templates are redeclarables, i.e. they must have been merged into + // the primary context. Use localUncachedLookup to not pick up template + // decls from modules again. + llvm::SmallVector<NamedDecl*, 6> Results; + DC->getPrimaryContext()->localUncachedLookup(Name, Results); + for (llvm::SmallVector<NamedDecl *, 6>::const_iterator + I = Results.begin(), E = Results.end(); + I != E && FoundSpecialization; ++I) + FoundSpecialization = findMatchingSpecialization(FD, CD, *I); + } + return FoundSpecialization && isSameEntity(FoundSpecialization, D); +} |