summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp17
-rw-r--r--clang/test/Modules/Inputs/cxx-decls-imported.h7
-rw-r--r--clang/test/Modules/Inputs/cxx-decls-merged.h8
-rw-r--r--clang/test/Modules/cxx-decls.cpp3
4 files changed, 30 insertions, 5 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 5f7a93f1320..0aa29239915 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1504,12 +1504,19 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
VisitFunctionDecl(D);
+
unsigned NumOverridenMethods = Record[Idx++];
- while (NumOverridenMethods--) {
- // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
- // MD may be initializing.
- if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx))
- Reader.getContext().addOverriddenMethod(D, MD);
+ if (D->isCanonicalDecl()) {
+ while (NumOverridenMethods--) {
+ // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
+ // MD may be initializing.
+ if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx))
+ Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl());
+ }
+ } else {
+ // We don't care about which declarations this used to override; we get
+ // the relevant information from the canonical declaration.
+ Idx += NumOverridenMethods;
}
}
diff --git a/clang/test/Modules/Inputs/cxx-decls-imported.h b/clang/test/Modules/Inputs/cxx-decls-imported.h
index a30db940a19..ccf1cb2b359 100644
--- a/clang/test/Modules/Inputs/cxx-decls-imported.h
+++ b/clang/test/Modules/Inputs/cxx-decls-imported.h
@@ -28,3 +28,10 @@ typedef struct {
int n;
int m;
} NameForLinkage;
+
+struct HasVirtualFunctions {
+ virtual void f();
+};
+struct OverridesVirtualFunctions : HasVirtualFunctions {
+ void f();
+};
diff --git a/clang/test/Modules/Inputs/cxx-decls-merged.h b/clang/test/Modules/Inputs/cxx-decls-merged.h
index b1ed2a0d932..3f9da1a55ee 100644
--- a/clang/test/Modules/Inputs/cxx-decls-merged.h
+++ b/clang/test/Modules/Inputs/cxx-decls-merged.h
@@ -5,3 +5,11 @@ typedef struct {
int m;
} NameForLinkage;
extern NameForLinkage name_for_linkage;
+
+struct HasVirtualFunctions {
+ virtual void f();
+};
+struct OverridesVirtualFunctions : HasVirtualFunctions {
+ void f();
+};
+extern OverridesVirtualFunctions overrides_virtual_functions;
diff --git a/clang/test/Modules/cxx-decls.cpp b/clang/test/Modules/cxx-decls.cpp
index 678f245ed10..ee196cfc33b 100644
--- a/clang/test/Modules/cxx-decls.cpp
+++ b/clang/test/Modules/cxx-decls.cpp
@@ -33,10 +33,13 @@ int importMergeUsedFlag = getMergeUsedFlag();
int use_name_for_linkage(NameForLinkage &nfl) {
return nfl.n + nfl.m;
}
+int use_overrides_virtual_functions(OverridesVirtualFunctions ovf) { return 0; }
@import cxx_decls_merged;
int name_for_linkage_test = use_name_for_linkage(name_for_linkage);
+int overrides_virtual_functions_test =
+ use_overrides_virtual_functions(overrides_virtual_functions);
// CHECK: VarDecl [[mergeUsedFlag:0x[0-9a-f]*]] {{.*}} in cxx_decls.imported used mergeUsedFlag
// CHECK: VarDecl {{0x[0-9a-f]*}} prev [[mergeUsedFlag]] {{.*}} in cxx_decls_merged used mergeUsedFlag
OpenPOWER on IntegriCloud