summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorShafik Yaghmour <syaghmour@apple.com>2019-01-28 21:55:33 +0000
committerShafik Yaghmour <syaghmour@apple.com>2019-01-28 21:55:33 +0000
commit96b3d2094f9db5f9f64dec3e0c432bedb787d5eb (patch)
tree0a1fcdc8683d97ef7ec135daf0adacae5093dddc /clang/lib
parent0068d223eefa9cbff19831a16f6e80393df5156b (diff)
downloadbcm5719-llvm-96b3d2094f9db5f9f64dec3e0c432bedb787d5eb.tar.gz
bcm5719-llvm-96b3d2094f9db5f9f64dec3e0c432bedb787d5eb.zip
[ASTImporter] Fix handling of overriden methods during ASTImport
Summary: When importing classes we may add a CXXMethodDecl more than once to a CXXRecordDecl when handling overrides. This patch will fix the cases we currently know about and handle the case where we are only dealing with declarations. Differential Revision: https://reviews.llvm.org/D56936 llvm-svn: 352436
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTImporter.cpp44
1 files changed, 37 insertions, 7 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index f24a5698f58..68da18aface 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -437,6 +437,8 @@ namespace clang {
Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
+ Error ImportFunctionDeclBody(FunctionDecl *FromFD, FunctionDecl *ToFD);
+
bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
@@ -2944,6 +2946,17 @@ ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD) {
return FoundSpec;
}
+Error ASTNodeImporter::ImportFunctionDeclBody(FunctionDecl *FromFD,
+ FunctionDecl *ToFD) {
+ if (Stmt *FromBody = FromFD->getBody()) {
+ if (ExpectedStmt ToBodyOrErr = import(FromBody))
+ ToFD->setBody(*ToBodyOrErr);
+ else
+ return ToBodyOrErr.takeError();
+ }
+ return Error::success();
+}
+
ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
SmallVector<Decl *, 2> Redecls = getCanonicalForwardRedeclChain(D);
@@ -2967,7 +2980,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (ToD)
return ToD;
- const FunctionDecl *FoundByLookup = nullptr;
+ FunctionDecl *FoundByLookup = nullptr;
FunctionTemplateDecl *FromFT = D->getDescribedFunctionTemplate();
// If this is a function template specialization, then try to find the same
@@ -3038,6 +3051,25 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
}
+ // We do not allow more than one in-class declaration of a function. This is
+ // because AST clients like VTableBuilder asserts on this. VTableBuilder
+ // assumes there is only one in-class declaration. Building a redecl
+ // chain would result in more than one in-class declaration for
+ // overrides (even if they are part of the same redecl chain inside the
+ // derived class.)
+ if (FoundByLookup) {
+ if (auto *MD = dyn_cast<CXXMethodDecl>(FoundByLookup)) {
+ if (D->getLexicalDeclContext() == D->getDeclContext()) {
+ if (!D->doesThisDeclarationHaveABody())
+ return Importer.MapImported(D, FoundByLookup);
+ else {
+ // Let's continue and build up the redecl chain in this case.
+ // FIXME Merge the functions into one decl.
+ }
+ }
+ }
+ }
+
DeclarationNameInfo NameInfo(Name, Loc);
// Import additional name location/type info.
if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
@@ -3199,12 +3231,10 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
if (D->doesThisDeclarationHaveABody()) {
- if (Stmt *FromBody = D->getBody()) {
- if (ExpectedStmt ToBodyOrErr = import(FromBody))
- ToFunction->setBody(*ToBodyOrErr);
- else
- return ToBodyOrErr.takeError();
- }
+ Error Err = ImportFunctionDeclBody(D, ToFunction);
+
+ if (Err)
+ return std::move(Err);
}
// FIXME: Other bits to merge?
OpenPOWER on IntegriCloud