diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-03 22:46:00 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-03 22:46:00 +0000 |
commit | 2009ceed8233a5d8cb979fd34c75714011a4ea01 (patch) | |
tree | 607773bb46da368289cda730d788244e6a74a14b /clang/lib/Serialization/ASTReaderDecl.cpp | |
parent | 1b7f2a7638b9e0e25fd7e05831f22935de059171 (diff) | |
download | bcm5719-llvm-2009ceed8233a5d8cb979fd34c75714011a4ea01.tar.gz bcm5719-llvm-2009ceed8233a5d8cb979fd34c75714011a4ea01.zip |
Implement cross-module declaration merging for tag declarations, so
that if two modules A and B both contain a declaration of a tag such
as
struct X;
and those two modules are unrelated, the two declarations of X will be
merged into a single redeclaration chain.
llvm-svn: 147488
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 82f6fae4a03..4871a3049ab 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -182,6 +182,10 @@ namespace clang { ~FindExistingResult(); + /// \brief Suppress the addition of this result into the known set of + /// names. + void suppress() { AddResult = false; } + operator NamedDecl*() const { return Existing; } template<typename T> @@ -412,20 +416,27 @@ void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) { } void ASTDeclReader::VisitTagDecl(TagDecl *TD) { - VisitRedeclarable(TD); + // Record the declaration -> global ID mapping. + Reader.DeclToID[TD] = ThisDeclID; + + RedeclarableResult Redecl = VisitRedeclarable(TD); VisitTypeDecl(TD); + TD->IdentifierNamespace = Record[Idx++]; TD->setTagKind((TagDecl::TagKind)Record[Idx++]); TD->setCompleteDefinition(Record[Idx++]); TD->setEmbeddedInDeclarator(Record[Idx++]); TD->setFreeStanding(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; } else TD->setTypedefNameForAnonDecl(ReadDeclAs<TypedefNameDecl>(Record, Idx)); + + mergeRedeclarable(TD, Redecl); } void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) { @@ -1547,6 +1558,14 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, 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 is in 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]); } } } @@ -1662,6 +1681,15 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X)) return true; + // Compatible tags match. + if (TagDecl *TagX = dyn_cast<TagDecl>(X)) { + TagDecl *TagY = cast<TagDecl>(Y); + if ((TagX->getTagKind() == TagY->getTagKind()) || + ((TagX->getTagKind() == TTK_Struct || TagX->getTagKind() == TTK_Class)&& + (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class))) + return true; + } + // FIXME: Many other cases to implement. return false; } @@ -1679,13 +1707,21 @@ ASTDeclReader::FindExistingResult::~FindExistingResult() { } ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) { + DeclarationName Name = D->getDeclName(); + if (!Name) { + // Don't bother trying to find unnamed declarations. + FindExistingResult Result(Reader, D, /*Existing=*/0); + Result.suppress(); + return Result; + } + DeclContext *DC = D->getDeclContext()->getRedeclContext(); if (!DC->isFileContext()) return FindExistingResult(Reader); if (DC->isTranslationUnit() && Reader.SemaObj) { IdentifierResolver &IdResolver = Reader.SemaObj->IdResolver; - for (IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()), + for (IdentifierResolver::iterator I = IdResolver.begin(Name), IEnd = IdResolver.end(); I != IEnd; ++I) { if (isSameEntity(*I, D)) |