forked from OSchip/llvm-project
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> llvm-svn: 264669
This commit is contained in:
parent
cc1ac8d125
commit
8bca996651
|
@ -224,8 +224,36 @@ namespace clang {
|
||||||
Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
|
Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
|
||||||
Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
|
Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
|
||||||
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
|
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
|
||||||
|
Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
|
||||||
|
Expr *VisitCXXThisExpr(CXXThisExpr *E);
|
||||||
|
Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
|
||||||
Expr *VisitMemberExpr(MemberExpr *E);
|
Expr *VisitMemberExpr(MemberExpr *E);
|
||||||
Expr *VisitCallExpr(CallExpr *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;
|
using namespace clang;
|
||||||
|
@ -2683,11 +2711,26 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
|
||||||
RecordDecl *D2 = AdoptDecl;
|
RecordDecl *D2 = AdoptDecl;
|
||||||
SourceLocation StartLoc = Importer.Import(D->getLocStart());
|
SourceLocation StartLoc = Importer.Import(D->getLocStart());
|
||||||
if (!D2) {
|
if (!D2) {
|
||||||
if (isa<CXXRecordDecl>(D)) {
|
CXXRecordDecl *D2CXX = nullptr;
|
||||||
CXXRecordDecl *D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
|
if (CXXRecordDecl *DCXX = llvm::dyn_cast<CXXRecordDecl>(D)) {
|
||||||
D->getTagKind(),
|
if (DCXX->isLambda()) {
|
||||||
DC, StartLoc, Loc,
|
TypeSourceInfo *TInfo = Importer.Import(DCXX->getLambdaTypeInfo());
|
||||||
Name.getAsIdentifierInfo());
|
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 = D2CXX;
|
||||||
D2->setAccess(D->getAccess());
|
D2->setAccess(D->getAccess());
|
||||||
} else {
|
} else {
|
||||||
|
@ -4653,16 +4696,11 @@ Stmt *ASTNodeImporter::VisitNullStmt(NullStmt *S) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
|
Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
|
||||||
SmallVector<Stmt *, 4> ToStmts(S->size());
|
llvm::ArrayRef<Stmt *> ToStmts;
|
||||||
auto &_Importer = this->Importer;
|
|
||||||
std::transform(S->body_begin(), S->body_end(), ToStmts.begin(),
|
if (!ImportArray(S->body_begin(), S->body_end(), ToStmts))
|
||||||
[&_Importer](Stmt *CS) -> Stmt * {
|
return nullptr;
|
||||||
return _Importer.Import(CS);
|
|
||||||
});
|
|
||||||
for (Stmt *ToS : ToStmts) {
|
|
||||||
if (!ToS)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
|
SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
|
||||||
SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc());
|
SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc());
|
||||||
return new (Importer.getToContext()) CompoundStmt(Importer.getToContext(),
|
return new (Importer.getToContext()) CompoundStmt(Importer.getToContext(),
|
||||||
|
@ -5290,17 +5328,10 @@ Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
||||||
if (!ToCCD && E->getConstructor())
|
if (!ToCCD && E->getConstructor())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
size_t NumArgs = E->getNumArgs();
|
ArrayRef<Expr *> ToArgs;
|
||||||
SmallVector<Expr *, 1> ToArgs(NumArgs);
|
|
||||||
ASTImporter &_Importer = Importer;
|
if (!ImportArray(E->arg_begin(), E->arg_end(), ToArgs))
|
||||||
std::transform(E->arg_begin(), E->arg_end(), ToArgs.begin(),
|
return nullptr;
|
||||||
[&_Importer](Expr *AE) -> Expr * {
|
|
||||||
return _Importer.Import(AE);
|
|
||||||
});
|
|
||||||
for (Expr *ToA : ToArgs) {
|
|
||||||
if (!ToA)
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CXXConstructExpr::Create(Importer.getToContext(), T,
|
return CXXConstructExpr::Create(Importer.getToContext(), T,
|
||||||
Importer.Import(E->getLocation()),
|
Importer.Import(E->getLocation()),
|
||||||
|
@ -5313,6 +5344,44 @@ Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
||||||
Importer.Import(E->getParenOrBraceRange()));
|
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) {
|
Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
|
||||||
QualType T = Importer.Import(E->getType());
|
QualType T = Importer.Import(E->getType());
|
||||||
if (T.isNull())
|
if (T.isNull())
|
||||||
|
@ -5381,6 +5450,28 @@ Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
|
||||||
Importer.Import(E->getRParenLoc()));
|
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,
|
ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
|
||||||
ASTContext &FromContext, FileManager &FromFileManager,
|
ASTContext &FromContext, FileManager &FromFileManager,
|
||||||
bool MinimalImport)
|
bool MinimalImport)
|
||||||
|
@ -5949,6 +6040,13 @@ void ASTImporter::CompleteDecl (Decl *D) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Decl *ASTImporter::Imported(Decl *From, Decl *To) {
|
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;
|
ImportedDecls[From] = To;
|
||||||
return To;
|
return To;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue