[cfe-commits] r95783 - in /cfe/trunk: lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/typedef1.c test/ASTMerge/Inputs/typedef2.c test/ASTMerge/typedef.c test/ASTMerge/var.c

Douglas Gregor dgregor at apple.com
Wed Feb 10 09:47:21 PST 2010


Author: dgregor
Date: Wed Feb 10 11:47:19 2010
New Revision: 95783

URL: http://llvm.org/viewvc/llvm-project?rev=95783&view=rev
Log:
Implement AST importing and merging for typedefs. As part of this, provide a lame implementation for importing TypeSourceInfos.

Added:
    cfe/trunk/test/ASTMerge/Inputs/typedef1.c   (with props)
    cfe/trunk/test/ASTMerge/Inputs/typedef2.c   (with props)
    cfe/trunk/test/ASTMerge/typedef.c   (with props)
Modified:
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/test/ASTMerge/var.c

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

==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Feb 10 11:47:19 2010
@@ -17,6 +17,7 @@
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclVisitor.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeVisitor.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
@@ -74,6 +75,7 @@
     // Importing declarations
     Decl *VisitDecl(Decl *D);
     Decl *VisitVarDecl(VarDecl *D);
+    Decl *VisitTypedefDecl(TypedefDecl *D);
   };
 }
 
@@ -565,19 +567,9 @@
         return 0;
     }
   }
-  
-  TypeSourceInfo *TInfo = 0;
-  if (TypeSourceInfo *FromTInfo = D->getTypeSourceInfo()) {
-    TInfo = Importer.Import(FromTInfo);
-#if 0
-    // FIXME: Tolerate failures in translation type source
-    // information, at least until it is implemented.
-    if (!TInfo)
-      return 0;
-#endif
-  }
-  
+    
   // Create the imported variable.
+  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC, Loc, 
                                    Name.getAsIdentifierInfo(), T, TInfo,
                                    D->getStorageClass());
@@ -597,6 +589,74 @@
   return ToVar;
 }
 
+Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
+  // Import the context of this declaration.
+  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
+  if (!DC)
+    return 0;
+    
+  DeclContext *LexicalDC = DC;
+  if (D->getDeclContext() != D->getLexicalDeclContext()) {
+    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+    if (!LexicalDC)
+      return 0;
+  }
+
+  // Import the name of this declaration.
+  DeclarationName Name = Importer.Import(D->getDeclName());
+  if (D->getDeclName() && !Name)
+    return 0;
+  
+  // Import the type of this declaration.
+  QualType T = Importer.Import(D->getUnderlyingType());
+  if (T.isNull())
+    return 0;
+  
+  // Import the location of this declaration.
+  SourceLocation Loc = Importer.Import(D->getLocation());
+
+  // If this typedef is not in block scope, determine whether we've
+  // seen a typedef with the same name (that we can merge with) or any
+  // other entity by that name (which name lookup could conflict with).
+  if (!DC->isFunctionOrMethod()) {
+    llvm::SmallVector<NamedDecl *, 4> ConflictingDecls;
+    unsigned IDNS = Decl::IDNS_Ordinary;
+    for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+         Lookup.first != Lookup.second; 
+         ++Lookup.first) {
+      if (!(*Lookup.first)->isInIdentifierNamespace(IDNS))
+        continue;
+      if (TypedefDecl *FoundTypedef = dyn_cast<TypedefDecl>(*Lookup.first)) {
+        if (Importer.getToContext().typesAreCompatible(T, 
+                                         FoundTypedef->getUnderlyingType())) {
+          Importer.getImportedDecls()[D] = FoundTypedef;
+          return FoundTypedef;
+        }
+      }
+
+      ConflictingDecls.push_back(*Lookup.first);
+    }
+
+    if (!ConflictingDecls.empty()) {
+      Name = Importer.HandleNameConflict(Name, DC, IDNS,
+                                         ConflictingDecls.data(), 
+                                         ConflictingDecls.size());
+      if (!Name)
+        return 0;
+    }
+  }
+
+  // Create the new typedef node.
+  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+  TypedefDecl *ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
+                                               Loc, Name.getAsIdentifierInfo(),
+                                               TInfo);
+  ToTypedef->setLexicalDeclContext(LexicalDC);
+  Importer.getImportedDecls()[D] = ToTypedef;
+  LexicalDC->addDecl(ToTypedef);
+  return ToTypedef;
+}
+
 ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                          Diagnostic &ToDiags,
                          ASTContext &FromContext, FileManager &FromFileManager,
@@ -633,8 +693,18 @@
 }
 
 TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
-  // FIXME: Implement!
-  return 0;
+  if (!FromTSI)
+    return FromTSI;
+
+  // FIXME: For now we just create a "trivial" type source info based
+  // on the type and a seingle location. Implement a real version of
+  // this.
+  QualType T = Import(FromTSI->getType());
+  if (T.isNull())
+    return 0;
+
+  return ToContext.getTrivialTypeSourceInfo(T, 
+                        FromTSI->getTypeLoc().getFullSourceRange().getBegin());
 }
 
 Decl *ASTImporter::Import(Decl *FromD) {

Added: cfe/trunk/test/ASTMerge/Inputs/typedef1.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/typedef1.c?rev=95783&view=auto

==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/typedef1.c (added)
+++ cfe/trunk/test/ASTMerge/Inputs/typedef1.c Wed Feb 10 11:47:19 2010
@@ -0,0 +1,4 @@
+typedef int Typedef1;
+typedef int Typedef2;
+Typedef1 x1;
+Typedef2 x2;

Propchange: cfe/trunk/test/ASTMerge/Inputs/typedef1.c

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/ASTMerge/Inputs/typedef1.c

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/ASTMerge/Inputs/typedef1.c

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/ASTMerge/Inputs/typedef2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/typedef2.c?rev=95783&view=auto

==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/typedef2.c (added)
+++ cfe/trunk/test/ASTMerge/Inputs/typedef2.c Wed Feb 10 11:47:19 2010
@@ -0,0 +1,4 @@
+typedef int Typedef1;
+typedef double Typedef2;
+Typedef1 x1;
+Typedef2 x2;

Propchange: cfe/trunk/test/ASTMerge/Inputs/typedef2.c

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/ASTMerge/Inputs/typedef2.c

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/ASTMerge/Inputs/typedef2.c

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cfe/trunk/test/ASTMerge/typedef.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/typedef.c?rev=95783&view=auto

==============================================================================
--- cfe/trunk/test/ASTMerge/typedef.c (added)
+++ cfe/trunk/test/ASTMerge/typedef.c Wed Feb 10 11:47:19 2010
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/typedef1.c
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/typedef2.c
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: typedef2.c:4:10: error: external variable 'x2' declared with incompatible types in different translation units ('Typedef2' (aka 'double') vs. 'Typedef2' (aka 'int'))
+// CHECK: typedef1.c:4:10: note: declared here with type 'Typedef2' (aka 'int')
+// CHECK: 2 diagnostics

Propchange: cfe/trunk/test/ASTMerge/typedef.c

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/ASTMerge/typedef.c

------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/ASTMerge/typedef.c

------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cfe/trunk/test/ASTMerge/var.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/var.c?rev=95783&r1=95782&r2=95783&view=diff

==============================================================================
--- cfe/trunk/test/ASTMerge/var.c (original)
+++ cfe/trunk/test/ASTMerge/var.c Wed Feb 10 11:47:19 2010
@@ -9,3 +9,4 @@
 // CHECK: var1.h:1:8: note: declared here with type 'double'
 // CHECK: error: external variable 'xarray3' declared with incompatible types in different translation units ('int [17]' vs. 'int [18]')
 // CHECK: var1.c:7:5: note: declared here with type 'int [18]'
+// CHECK: 6 diagnostics





More information about the cfe-commits mailing list