summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-03 22:46:00 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-03 22:46:00 +0000
commit2009ceed8233a5d8cb979fd34c75714011a4ea01 (patch)
tree607773bb46da368289cda730d788244e6a74a14b /clang/lib/Serialization/ASTReaderDecl.cpp
parent1b7f2a7638b9e0e25fd7e05831f22935de059171 (diff)
downloadbcm5719-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.cpp40
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))
OpenPOWER on IntegriCloud