summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/ASTImporter.h9
-rw-r--r--clang/lib/AST/ASTImporter.cpp82
-rw-r--r--clang/test/ASTMerge/Inputs/init-ctors-classes.cpp17
-rw-r--r--clang/test/ASTMerge/init-ctors.cpp10
4 files changed, 118 insertions, 0 deletions
diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h
index ee48955ca63..e116abaef79 100644
--- a/clang/include/clang/AST/ASTImporter.h
+++ b/clang/include/clang/AST/ASTImporter.h
@@ -23,6 +23,7 @@
namespace clang {
class ASTContext;
+ class CXXCtorInitializer;
class Decl;
class DeclContext;
class DiagnosticsEngine;
@@ -204,6 +205,14 @@ namespace clang {
/// \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(CXXCtorInitializer *FromInit);
+
+
/// \brief Import the definition of the given declaration, including all of
/// the declarations it contains.
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index ec6655391e9..3598dccf0a1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -3020,6 +3020,22 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
D->isInlineSpecified(),
D->isImplicit(),
D->isConstexpr());
+ if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
+ SmallVector<CXXCtorInitializer *, 4> CtorInitializers;
+ for (CXXCtorInitializer *I : FromConstructor->inits()) {
+ CXXCtorInitializer *ToI =
+ cast_or_null<CXXCtorInitializer>(Importer.Import(I));
+ if (!ToI && I)
+ return nullptr;
+ CtorInitializers.push_back(ToI);
+ }
+ CXXCtorInitializer **Memory =
+ new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
+ std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
+ CXXConstructorDecl *ToCtor = llvm::cast<CXXConstructorDecl>(ToFunction);
+ ToCtor->setCtorInitializers(Memory);
+ ToCtor->setNumCtorInitializers(NumInitializers);
+ }
} else if (isa<CXXDestructorDecl>(D)) {
ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
cast<CXXRecordDecl>(DC),
@@ -6351,6 +6367,72 @@ FileID ASTImporter::Import(FileID FromID) {
return ToID;
}
+CXXCtorInitializer *ASTImporter::Import(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 if (unsigned NumArrayIndices = From->getNumArrayIndices()) {
+ FieldDecl *ToField =
+ llvm::cast_or_null<FieldDecl>(Import(From->getMember()));
+ if (!ToField && From->getMember())
+ return nullptr;
+
+ SmallVector<VarDecl *, 4> ToAIs(NumArrayIndices);
+
+ for (unsigned AII = 0; AII < NumArrayIndices; ++AII) {
+ VarDecl *ToArrayIndex =
+ dyn_cast_or_null<VarDecl>(Import(From->getArrayIndex(AII)));
+ if (!ToArrayIndex && From->getArrayIndex(AII))
+ return nullptr;
+ }
+
+ return CXXCtorInitializer::Create(
+ ToContext, ToField, Import(From->getMemberLocation()),
+ Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()),
+ ToAIs.data(), NumArrayIndices);
+ } else {
+ return nullptr;
+ }
+}
+
+
void ASTImporter::ImportDefinition(Decl *From) {
Decl *To = Import(From);
if (!To)
diff --git a/clang/test/ASTMerge/Inputs/init-ctors-classes.cpp b/clang/test/ASTMerge/Inputs/init-ctors-classes.cpp
new file mode 100644
index 00000000000..616e5dfebcc
--- /dev/null
+++ b/clang/test/ASTMerge/Inputs/init-ctors-classes.cpp
@@ -0,0 +1,17 @@
+class A_base
+{
+public:
+ int x;
+ A_base(int _x) : x(_x) {
+ }
+};
+
+class A : public A_base
+{
+public:
+ int y;
+ struct { int z; };
+ int array[2];
+ A(int _x) : A_base(_x), y(0), z(1), array{{2},{3}} {
+ }
+};
diff --git a/clang/test/ASTMerge/init-ctors.cpp b/clang/test/ASTMerge/init-ctors.cpp
new file mode 100644
index 00000000000..5f0ba4decd9
--- /dev/null
+++ b/clang/test/ASTMerge/init-ctors.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/init-ctors-classes.cpp
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+class B {
+ int method_1() {
+ A a(0);
+ return a.x;
+ }
+};
OpenPOWER on IntegriCloud