diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-10-07 08:02:11 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-10-07 08:02:11 +0000 |
| commit | 0b87e0739e02b839ab80bf06ce89aab5cbf57bc5 (patch) | |
| tree | 1d276238b170c13a7e362357dac517fdd049a57c /clang/lib/Serialization | |
| parent | 3f8f8c9dbd23e0da6e5d81a1ee957c1209ab0234 (diff) | |
| download | bcm5719-llvm-0b87e0739e02b839ab80bf06ce89aab5cbf57bc5.tar.gz bcm5719-llvm-0b87e0739e02b839ab80bf06ce89aab5cbf57bc5.zip | |
When merging class definitions across modules in C++, merge together fields.
This change doesn't go all the way to making fields redeclarable; instead, it
makes them 'mergeable', which means we can find the canonical declaration, but
not much else (and for a declaration that's not from a module, the canonical
declaration is always that declaration).
llvm-svn: 192092
Diffstat (limited to 'clang/lib/Serialization')
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index a5fb21cb66c..341f8eb068d 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -296,6 +296,9 @@ namespace clang { 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); @@ -914,6 +917,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) { @@ -1874,6 +1878,22 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, T *Existing, } } +/// \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; + + 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(); @@ -2091,6 +2111,15 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { 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. + return X->getASTContext().hasSameType(FDX->getType(), FDY->getType()); + } + // FIXME: Many other cases to implement. return false; } |

