r264669 - Improvements to the ASTImporter to support LLDB top-level Clang expressions.

Sean Callanan via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 28 14:43:01 PDT 2016


Author: spyffe
Date: Mon Mar 28 16:43:01 2016
New Revision: 264669

URL: http://llvm.org/viewvc/llvm-project?rev=264669&view=rev
Log:
Improvements to the ASTImporter to support LLDB top-level Clang expressions.

The testcase for this is in LLDB, adeed by r264662.

This patch adds support for a variety of new expression types to the AST
importer, mostly related to C++.  It also adds support for importing lambdas
correctly, and adds support for importing the attributes attached to any Decl.

Finally, the patch adds a new templated function to ASTNodeImporter that imports
arbitrary arrays of importable things into a bump-allocated array attached to
getToContext().  This is a pattern we see at many places in ASTNodeImporter;
rather than do it slightly differently at each point, this function does it one
way.

<rdar://problem/22864976>

Modified:
    cfe/trunk/lib/AST/ASTImporter.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=264669&r1=264668&r2=264669&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Mar 28 16:43:01 2016
@@ -224,8 +224,36 @@ namespace clang {
     Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
     Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
     Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
+    Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
+    Expr *VisitCXXThisExpr(CXXThisExpr *E);
+    Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
     Expr *VisitMemberExpr(MemberExpr *E);
     Expr *VisitCallExpr(CallExpr *E);
+    Expr *VisitInitListExpr(InitListExpr *E);
+                            
+    template <typename T, typename Iter> bool ImportArray(Iter B, Iter E, llvm::ArrayRef<T*> &ToArray) {
+      size_t NumElements = E - B;
+      SmallVector<T *, 1> ImportedElements(NumElements);
+      ASTImporter &_Importer = Importer;
+      
+      bool Failed = false;
+      std::transform(B, E, ImportedElements.begin(),
+                     [&_Importer, &Failed](T *Element) -> T* {
+                       T *ToElement = _Importer.Import(Element);
+                       if (Element && !ToElement)
+                         Failed = true;
+                       return ToElement;
+                     });
+      
+      if (Failed)
+        return false;
+      
+      T **CopiedElements = new (Importer.getToContext()) T*[NumElements];
+      std::copy(ImportedElements.begin(), ImportedElements.end(), &CopiedElements[0]);
+      ToArray = llvm::ArrayRef<T*>(CopiedElements, NumElements);
+      
+      return true;
+    }
   };
 }
 using namespace clang;
@@ -2683,11 +2711,26 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
   RecordDecl *D2 = AdoptDecl;
   SourceLocation StartLoc = Importer.Import(D->getLocStart());
   if (!D2) {
-    if (isa<CXXRecordDecl>(D)) {
-      CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(), 
-                                                   D->getTagKind(),
-                                                   DC, StartLoc, Loc,
-                                                   Name.getAsIdentifierInfo());
+    CXXRecordDecl *D2CXX = nullptr;
+    if (CXXRecordDecl *DCXX = llvm::dyn_cast<CXXRecordDecl>(D)) {
+      if (DCXX->isLambda()) {
+        TypeSourceInfo *TInfo = Importer.Import(DCXX->getLambdaTypeInfo());
+        D2CXX = CXXRecordDecl::CreateLambda(Importer.getToContext(),
+                                            DC, TInfo, Loc,
+                                            DCXX->isDependentLambda(),
+                                            DCXX->isGenericLambda(),
+                                            DCXX->getLambdaCaptureDefault());
+        Decl *CDecl = Importer.Import(DCXX->getLambdaContextDecl());
+        if (DCXX->getLambdaContextDecl() && !CDecl)
+          return nullptr;
+        D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(),
+                                 CDecl);
+      } else {
+        D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
+                                      D->getTagKind(),
+                                      DC, StartLoc, Loc,
+                                      Name.getAsIdentifierInfo());
+      }
       D2 = D2CXX;
       D2->setAccess(D->getAccess());
     } else {
@@ -4653,16 +4696,11 @@ Stmt *ASTNodeImporter::VisitNullStmt(Nul
 }
 
 Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
-  SmallVector<Stmt *, 4> ToStmts(S->size());
-  auto &_Importer = this->Importer;
-  std::transform(S->body_begin(), S->body_end(), ToStmts.begin(),
-    [&_Importer](Stmt *CS) -> Stmt * {
-      return _Importer.Import(CS);
-    });
-  for (Stmt *ToS : ToStmts) {
-    if (!ToS)
-      return nullptr;
-  }
+  llvm::ArrayRef<Stmt *> ToStmts;
+    
+  if (!ImportArray(S->body_begin(), S->body_end(), ToStmts))
+    return nullptr;
+
   SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
   SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc());
   return new (Importer.getToContext()) CompoundStmt(Importer.getToContext(),
@@ -5290,17 +5328,10 @@ Expr *ASTNodeImporter::VisitCXXConstruct
   if (!ToCCD && E->getConstructor())
     return nullptr;
 
-  size_t NumArgs = E->getNumArgs();
-  SmallVector<Expr *, 1> ToArgs(NumArgs);
-  ASTImporter &_Importer = Importer;
-  std::transform(E->arg_begin(), E->arg_end(), ToArgs.begin(),
-    [&_Importer](Expr *AE) -> Expr * {
-      return _Importer.Import(AE);
-    });
-  for (Expr *ToA : ToArgs) {
-    if (!ToA)
-      return nullptr;
-  }
+  ArrayRef<Expr *> ToArgs;
+  
+  if (!ImportArray(E->arg_begin(), E->arg_end(), ToArgs))
+    return nullptr;
 
   return CXXConstructExpr::Create(Importer.getToContext(), T,
                                   Importer.Import(E->getLocation()),
@@ -5313,6 +5344,44 @@ Expr *ASTNodeImporter::VisitCXXConstruct
                                   Importer.Import(E->getParenOrBraceRange()));
 }
 
+Expr *ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+  
+  Expr *ToFn = Importer.Import(E->getCallee());
+  if (!ToFn)
+    return nullptr;
+  
+  ArrayRef<Expr *> ToArgs;
+  
+  if (!ImportArray(E->arg_begin(), E->arg_end(), ToArgs))
+    return nullptr;
+
+  return new (Importer.getToContext()) CXXMemberCallExpr(Importer.getToContext(), ToFn,
+                                                         ToArgs, T, E->getValueKind(),
+                                                         Importer.Import(E->getRParenLoc()));
+}
+
+Expr *ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+  
+  return new (Importer.getToContext())
+  CXXThisExpr(Importer.Import(E->getLocation()), T, E->isImplicit());
+}
+
+Expr *ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+  
+  return new (Importer.getToContext())
+  CXXBoolLiteralExpr(E->getValue(), T, Importer.Import(E->getLocation()));
+}
+
+
 Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
@@ -5381,6 +5450,28 @@ Expr *ASTNodeImporter::VisitCallExpr(Cal
              Importer.Import(E->getRParenLoc()));
 }
 
+Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+    return nullptr;
+    
+  ArrayRef<Expr *> ToInits;
+
+  if (!ImportArray(E->inits().begin(), E->inits().end(), ToInits))
+    return nullptr;
+    
+  InitListExpr *ToE = new (Importer.getToContext())
+    InitListExpr(Importer.getToContext(),
+                 Importer.Import(E->getLBraceLoc()),
+                 ToInits,
+                 Importer.Import(E->getRBraceLoc()));
+  
+  if (ToE)
+    ToE->setType(T);
+
+  return ToE;
+}
+
 ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
                          ASTContext &FromContext, FileManager &FromFileManager,
                          bool MinimalImport)
@@ -5949,6 +6040,13 @@ void ASTImporter::CompleteDecl (Decl *D)
 }
 
 Decl *ASTImporter::Imported(Decl *From, Decl *To) {
+  if (From->hasAttrs()) {
+    for (Attr *FromAttr : From->getAttrs())
+      To->addAttr(FromAttr->clone(To->getASTContext()));
+  }
+  if (From->isUsed()) {
+    To->setIsUsed();
+  }
   ImportedDecls[From] = To;
   return To;
 }




More information about the cfe-commits mailing list