From: Sean Callanan Date: Sat, 14 May 2016 05:43:57 +0000 (+0000) Subject: Handle injected class names in the ASTImporter. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d944e0ebaf7d183c01510e16dd61791ce608d23f;p=clang Handle injected class names in the ASTImporter. Every class as parsed by Clang has a forward declaration of itself as a member: class A { class A; ... } but when the parser generates this it ensures that the RecordTypes for the two are the same. This makes (among other things) inheritance work. This patch fixes a bug where the ASTImporter generated two separate RecordTypes when importing the class and the contained forward declaration, and adds a test case. Thanks to Doug Gregor for advice on this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269551 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 3598dccf0a..c1dda3fcf6 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -2820,8 +2820,17 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) { Decl *CDecl = Importer.Import(DCXX->getLambdaContextDecl()); if (DCXX->getLambdaContextDecl() && !CDecl) return nullptr; - D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), - CDecl); + 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(DC)); } else { D2CXX = CXXRecordDecl::Create(Importer.getToContext(), D->getTagKind(), diff --git a/test/ASTMerge/Inputs/inheritance-base.cpp b/test/ASTMerge/Inputs/inheritance-base.cpp new file mode 100644 index 0000000000..26fe42eb64 --- /dev/null +++ b/test/ASTMerge/Inputs/inheritance-base.cpp @@ -0,0 +1,7 @@ +class A +{ +public: + int x; + A(int _x) : x(_x) { + } +}; diff --git a/test/ASTMerge/inheritance.cpp b/test/ASTMerge/inheritance.cpp new file mode 100644 index 0000000000..7fce82a736 --- /dev/null +++ b/test/ASTMerge/inheritance.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/inheritance-base.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 : public A { + B(int _a) : A(_a) { + } +};