[cfe-commits] r95941 - in /cfe/trunk: lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/struct1.c test/ASTMerge/Inputs/struct2.c

Douglas Gregor dgregor at apple.com
Thu Feb 11 16:09:27 PST 2010


Author: dgregor
Date: Thu Feb 11 18:09:27 2010
New Revision: 95941

URL: http://llvm.org/viewvc/llvm-project?rev=95941&view=rev
Log:
Handle AST merges of incomplete class types. 

Modified:
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/test/ASTMerge/Inputs/struct1.c
    cfe/trunk/test/ASTMerge/Inputs/struct2.c

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=95941&r1=95940&r2=95941&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Feb 11 18:09:27 2010
@@ -789,6 +789,7 @@
     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 @@
       }
       
       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 @@
   }
   
   // 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(), 

Modified: cfe/trunk/test/ASTMerge/Inputs/struct1.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/struct1.c?rev=95941&r1=95940&r2=95941&view=diff

==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/struct1.c (original)
+++ cfe/trunk/test/ASTMerge/Inputs/struct1.c Thu Feb 11 18:09:27 2010
@@ -34,3 +34,13 @@
 
 // Bit-field mismatch
 struct S7 { int i : 8; unsigned j : 8; } x7;
+
+// Incomplete type
+struct S8 *x8;
+
+// Incomplete type
+struct S9 { int i; float f; } *x9;
+
+// Incomplete type
+struct S10 *x10;
+

Modified: cfe/trunk/test/ASTMerge/Inputs/struct2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/struct2.c?rev=95941&r1=95940&r2=95941&view=diff

==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/struct2.c (original)
+++ cfe/trunk/test/ASTMerge/Inputs/struct2.c Thu Feb 11 18:09:27 2010
@@ -31,3 +31,12 @@
 
 // Bit-field mismatch
 struct S7 { int i : 8; unsigned j : 16; } x7;
+
+// Incomplete type
+struct S8 { int i; float f; } *x8;
+
+// Incomplete type
+struct S9 *x9;
+
+// Incomplete type
+struct S10 *x10;





More information about the cfe-commits mailing list