spyffe created this revision.
spyffe added reviewers: sepavloff, a.sidorin.
spyffe added a subscriber: cfe-commits.
spyffe set the repository for this revision to rL LLVM.
spyffe added a project: clang-c.

The AST importer currently does not handle injected class names properly (it 
does not bind their types to the type of the parent as the parser would) and it 
doesn't handle constructor initializers at all.

This patch adds support for both of those, and also forwards the `isImplicit()` 
and `isReferenced()` flags for *all* declarations as is done for `isUsed()`.

Repository:
  rL LLVM

http://reviews.llvm.org/D20118

Files:
  include/clang/AST/ASTImporter.h
  lib/AST/ASTImporter.cpp

Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -2820,6 +2820,18 @@
           return nullptr;
         D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(),
                                  CDecl);
+      } else if (DCXX->isInjectedClassName()) {
+        // We have to be careful to do a similar dance to the one in
+        // Sema::ActOnStartCXXMemberDeclarations
+        CXXRecordDecl * const PrevDecl = nullptr;
+        const bool DelayTypeCreation = true;
+        D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
+                                      D->getTagKind(),
+                                      DC, StartLoc, Loc,
+                                      Name.getAsIdentifierInfo(),
+                                      PrevDecl, DelayTypeCreation);
+        Importer.getToContext().getTypeDeclType(
+            D2CXX, llvm::dyn_cast<CXXRecordDecl>(DC));
       } else {
         D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
                                       D->getTagKind(),
@@ -3018,6 +3030,22 @@
                                             D->isInlineSpecified(), 
                                             D->isImplicit(),
                                             D->isConstexpr());
+    SmallVector<CXXCtorInitializer *, 4> CtorInitializers;
+    for (const CXXCtorInitializer *I : FromConstructor->inits()) {
+      CXXCtorInitializer *ToI =cast_or_null<CXXCtorInitializer>(
+          Importer.Import(I));
+      if (!ToI && I)
+        return nullptr;
+      CtorInitializers.push_back(ToI);
+    }
+    if (unsigned NumInitializers = CtorInitializers.size()) {
+      CXXCtorInitializer **Memory = new (Importer.getToContext())
+                                         CXXCtorInitializer*[NumInitializers];
+      std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
+      llvm::cast<CXXConstructorDecl>(ToFunction)->setCtorInitializers(Memory);
+      llvm::cast<CXXConstructorDecl>(ToFunction)->setNumCtorInitializers(
+          NumInitializers);
+    }
   } else if (isa<CXXDestructorDecl>(D)) {
     ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
                                            cast<CXXRecordDecl>(DC),
@@ -6344,6 +6372,58 @@
   return ToID;
 }
 
+CXXCtorInitializer *ASTImporter::Import(const CXXCtorInitializer *From) {
+  Expr *ToExpr = Import(From->getInit());
+  if (!ToExpr && From->getInit())
+    return nullptr;
+
+  if (From->isBaseInitializer()) {
+    TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo());
+    if (!ToTInfo && From->getTypeSourceInfo())
+      return nullptr;
+    
+    return new (ToContext)
+      CXXCtorInitializer(ToContext, ToTInfo, From->isBaseVirtual(),
+                         Import(From->getLParenLoc()), ToExpr, 
+                         Import(From->getRParenLoc()),
+                         From->isPackExpansion() ?
+                         Import(From->getEllipsisLoc()) : SourceLocation());
+  } else if (From->isMemberInitializer()) {
+    FieldDecl *ToField = llvm::cast_or_null<FieldDecl>(Import(
+        From->getMember()));
+    if (!ToField && From->getMember())
+      return nullptr;
+    
+    return new (ToContext)
+        CXXCtorInitializer(ToContext, ToField,
+                           Import(From->getMemberLocation()),
+                           Import(From->getLParenLoc()), ToExpr, 
+                           Import(From->getRParenLoc()));
+  } else if (From->isIndirectMemberInitializer()) {
+    IndirectFieldDecl *ToIField = llvm::cast_or_null<IndirectFieldDecl>(Import(
+        From->getIndirectMember()));
+    if (!ToIField && From->getIndirectMember())
+      return nullptr;
+
+    return new (ToContext)
+        CXXCtorInitializer(ToContext, ToIField,
+                           Import(From->getMemberLocation()),
+                           Import(From->getLParenLoc()), ToExpr, 
+                           Import(From->getRParenLoc()));
+  } else if (From->isDelegatingInitializer()) {
+    TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo());
+    if (!ToTInfo && From->getTypeSourceInfo())
+      return nullptr;
+
+    return new (ToContext)
+        CXXCtorInitializer(ToContext, ToTInfo,
+                           Import(From->getLParenLoc()), ToExpr,
+                           Import(From->getRParenLoc()));
+  } else {
+    return nullptr;
+  }
+}
+
 void ASTImporter::ImportDefinition(Decl *From) {
   Decl *To = Import(From);
   if (!To)
@@ -6514,6 +6594,12 @@
   if (From->isUsed()) {
     To->setIsUsed();
   }
+  if (From->isImplicit()) {
+    To->setImplicit();
+  }
+  if (From->isReferenced()) { 
+    To->setReferenced();
+  }
   ImportedDecls[From] = To;
   return To;
 }
Index: include/clang/AST/ASTImporter.h
===================================================================
--- include/clang/AST/ASTImporter.h
+++ include/clang/AST/ASTImporter.h
@@ -23,6 +23,7 @@
 
 namespace clang {
   class ASTContext;
+  class CXXCtorInitializer;
   class Decl;
   class DeclContext;
   class DiagnosticsEngine;
@@ -204,6 +205,12 @@
     /// \returns the equivalent file ID in the source manager of the "to"
     /// context.
     FileID Import(FileID);
+
+    /// \brief Import the given C++ constructor initializer from the "from"
+    /// context into the "to" context.
+    ///
+    /// \returns the equivalent initializer in the "to" context.
+    CXXCtorInitializer *Import(const CXXCtorInitializer *FromInit);
     
     /// \brief Import the definition of the given declaration, including all of
     /// the declarations it contains.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to