summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-02-12 00:09:27 +0000
committerDouglas Gregor <dgregor@apple.com>2010-02-12 00:09:27 +0000
commit2579105c4e4057b18ac78f5b9fd546e7350f1ec4 (patch)
treedc58f74f29ceeb7cde04486d97aab7dbec66c7cc /clang/lib/AST
parent90073804fb1cf6e6273bce41ecaaa9e1a0c33b8f (diff)
downloadbcm5719-llvm-2579105c4e4057b18ac78f5b9fd546e7350f1ec4.tar.gz
bcm5719-llvm-2579105c4e4057b18ac78f5b9fd546e7350f1ec4.zip
Handle AST merges of incomplete class types.
llvm-svn: 95941
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTImporter.cpp90
1 files changed, 50 insertions, 40 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index a7a76532cab..5993e9ac34e 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -789,6 +789,7 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
IDNS |= Decl::IDNS_Ordinary;
// We may already have a record of the same name; try to find and match it.
+ RecordDecl *AdoptDecl = 0;
if (!DC->isFunctionOrMethod() && SearchName) {
llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
for (DeclContext::lookup_result Lookup = DC->lookup(Name);
@@ -804,15 +805,21 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
}
if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
- RecordDecl *FoundDef = FoundRecord->getDefinition();
- // FIXME: If we found something but there is no definition,
- // assume the types are the same and fill in the gaps.
- if (FoundDef && IsStructuralMatch(D, FoundDef)) {
- // The record types structurally match.
- // FIXME: For C++, we should also merge methods here.
- Importer.getImportedDecls()[D] = FoundDef;
- return FoundDef;
- }
+ if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
+ if (!D->isDefinition() || IsStructuralMatch(D, FoundDef)) {
+ // The record types structurally match, or the "from" translation
+ // unit only had a forward declaration anyway; call it the same
+ // function.
+ // FIXME: For C++, we should also merge methods here.
+ Importer.getImportedDecls()[D] = FoundDef;
+ return FoundDef;
+ }
+ } else {
+ // We have a forward declaration of this type, so adopt that forward
+ // declaration rather than building a new one.
+ AdoptDecl = FoundRecord;
+ continue;
+ }
}
ConflictingDecls.push_back(*Lookup.first);
@@ -826,47 +833,50 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
}
// Create the record declaration.
- RecordDecl *ToRecord = 0;
- if (CXXRecordDecl *FromCXX = dyn_cast<CXXRecordDecl>(D)) {
- CXXRecordDecl *ToCXX = CXXRecordDecl::Create(Importer.getToContext(),
- D->getTagKind(),
- DC, Loc,
- Name.getAsIdentifierInfo(),
+ RecordDecl *ToRecord = AdoptDecl;
+ if (!ToRecord) {
+ if (CXXRecordDecl *FromCXX = dyn_cast<CXXRecordDecl>(D)) {
+ CXXRecordDecl *ToCXX = CXXRecordDecl::Create(Importer.getToContext(),
+ D->getTagKind(),
+ DC, Loc,
+ Name.getAsIdentifierInfo(),
Importer.Import(D->getTagKeywordLoc()));
- ToRecord = ToCXX;
-
- if (D->isDefinition()) {
- // Add base classes.
- llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
- for (CXXRecordDecl::base_class_iterator FromBase = FromCXX->bases_begin(),
- FromBaseEnd = FromCXX->bases_end();
- FromBase != FromBaseEnd;
- ++FromBase) {
- QualType T = Importer.Import(FromBase->getType());
- if (T.isNull())
- return 0;
-
- Bases.push_back(
- new (Importer.getToContext())
+ ToRecord = ToCXX;
+
+ if (D->isDefinition()) {
+ // Add base classes.
+ llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
+ for (CXXRecordDecl::base_class_iterator
+ FromBase = FromCXX->bases_begin(),
+ FromBaseEnd = FromCXX->bases_end();
+ FromBase != FromBaseEnd;
+ ++FromBase) {
+ QualType T = Importer.Import(FromBase->getType());
+ if (T.isNull())
+ return 0;
+
+ Bases.push_back(
+ new (Importer.getToContext())
CXXBaseSpecifier(Importer.Import(FromBase->getSourceRange()),
FromBase->isVirtual(),
FromBase->isBaseOfClass(),
FromBase->getAccessSpecifierAsWritten(),
T));
+ }
+ if (!Bases.empty())
+ ToCXX->setBases(Bases.data(), Bases.size());
}
- if (!Bases.empty())
- ToCXX->setBases(Bases.data(), Bases.size());
+ } else {
+ ToRecord = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
+ DC, Loc,
+ Name.getAsIdentifierInfo(),
+ Importer.Import(D->getTagKeywordLoc()));
}
- } else {
- ToRecord = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
- DC, Loc,
- Name.getAsIdentifierInfo(),
- Importer.Import(D->getTagKeywordLoc()));
+ ToRecord->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDecl(ToRecord);
}
- ToRecord->setLexicalDeclContext(LexicalDC);
Importer.getImportedDecls()[D] = ToRecord;
- LexicalDC->addDecl(ToRecord);
-
+
if (D->isDefinition()) {
ToRecord->startDefinition();
for (DeclContext::decl_iterator FromMem = D->decls_begin(),
OpenPOWER on IntegriCloud