summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/MultiplexExternalSemaSource.cpp6
-rw-r--r--clang/lib/Sema/Sema.cpp18
-rw-r--r--clang/lib/Sema/SemaDecl.cpp50
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp3
-rw-r--r--clang/lib/Serialization/ASTReader.cpp15
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp8
6 files changed, 29 insertions, 71 deletions
diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp
index 449ddf43114..a0315777675 100644
--- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp
+++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp
@@ -236,12 +236,6 @@ void MultiplexExternalSemaSource::ReadExtVectorDecls(
Sources[i]->ReadExtVectorDecls(Decls);
}
-void MultiplexExternalSemaSource::ReadDynamicClasses(
- SmallVectorImpl<CXXRecordDecl*> &Decls) {
- for(size_t i = 0; i < Sources.size(); ++i)
- Sources[i]->ReadDynamicClasses(Decls);
-}
-
void MultiplexExternalSemaSource::ReadUnusedLocalTypedefNameCandidates(
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
for(size_t i = 0; i < Sources.size(); ++i)
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 5170c244bbf..a851ce14556 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -621,22 +621,6 @@ void Sema::ActOnEndOfTranslationUnit() {
if (TUKind != TU_Prefix) {
DiagnoseUseOfUnimplementedSelectors();
- // If any dynamic classes have their key function defined within
- // this translation unit, then those vtables are considered "used" and must
- // be emitted.
- for (DynamicClassesType::iterator I = DynamicClasses.begin(ExternalSource),
- E = DynamicClasses.end();
- I != E; ++I) {
- assert(!(*I)->isDependentType() &&
- "Should not see dependent types here!");
- if (const CXXMethodDecl *KeyFunction =
- Context.getCurrentKeyFunction(*I)) {
- const FunctionDecl *Definition = nullptr;
- if (KeyFunction->hasBody(Definition))
- MarkVTableUsed(Definition->getLocation(), *I, true);
- }
- }
-
// If DefinedUsedVTables ends up marking any virtual member functions it
// might lead to more pending template instantiations, which we then need
// to instantiate.
@@ -668,6 +652,8 @@ void Sema::ActOnEndOfTranslationUnit() {
// All delayed member exception specs should be checked or we end up accepting
// incompatible declarations.
+ // FIXME: This is wrong for TUKind == TU_Prefix. In that case, we need to
+ // write out the lists to the AST file (if any).
assert(DelayedDefaultedMemberExceptionSpecs.empty());
assert(DelayedExceptionSpecChecks.empty());
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index e2547739f43..eb5b7154936 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8011,28 +8011,8 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// This needs to happen first so that 'inline' propagates.
NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl));
- if (isa<CXXMethodDecl>(NewFD)) {
- // A valid redeclaration of a C++ method must be out-of-line,
- // but (unfortunately) it's not necessarily a definition
- // because of templates, which means that the previous
- // declaration is not necessarily from the class definition.
-
- // For just setting the access, that doesn't matter.
- CXXMethodDecl *oldMethod = cast<CXXMethodDecl>(OldDecl);
- NewFD->setAccess(oldMethod->getAccess());
-
- // Update the key-function state if necessary for this ABI.
- if (NewFD->isInlined() &&
- !Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline()) {
- // setNonKeyFunction needs to work with the original
- // declaration from the class definition, and isVirtual() is
- // just faster in that case, so map back to that now.
- oldMethod = cast<CXXMethodDecl>(oldMethod->getFirstDecl());
- if (oldMethod->isVirtual()) {
- Context.setNonKeyFunction(oldMethod);
- }
- }
- }
+ if (isa<CXXMethodDecl>(NewFD))
+ NewFD->setAccess(OldDecl->getAccess());
}
}
@@ -10559,7 +10539,31 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
!FD->isDependentContext())
computeNRVO(Body, getCurFunction());
}
-
+
+ if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ const CXXMethodDecl *KeyFunction;
+ if (MD->isOutOfLine() && (MD = MD->getCanonicalDecl()) &&
+ MD->isVirtual() &&
+ (KeyFunction = Context.getCurrentKeyFunction(MD->getParent())) &&
+ MD == KeyFunction->getCanonicalDecl()) {
+ // Update the key-function state if necessary for this ABI.
+ if (FD->isInlined() &&
+ !Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline()) {
+ Context.setNonKeyFunction(MD);
+
+ // If the newly-chosen key function is already defined, then we
+ // need to mark the vtable as used retroactively.
+ KeyFunction = Context.getCurrentKeyFunction(MD->getParent());
+ const FunctionDecl *Definition;
+ if (KeyFunction && KeyFunction->isDefined(Definition))
+ MarkVTableUsed(Definition->getLocation(), MD->getParent(), true);
+ } else {
+ // We just defined they key function; mark the vtable as used.
+ MarkVTableUsed(FD->getLocation(), MD->getParent(), true);
+ }
+ }
+ }
+
assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) &&
"Function parsing confused");
} else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) {
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c41dc3309a5..c78f214fbca 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -4875,9 +4875,6 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
}
}
- if (Record->isDynamicClass() && !Record->isDependentType())
- DynamicClasses.push_back(Record);
-
if (Record->getIdentifier()) {
// C++ [class.mem]p13:
// If T is the name of a class, then each of the following shall have a
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 9d9885b7930..78c44d17887 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3099,11 +3099,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
}
break;
- case DYNAMIC_CLASSES:
- for (unsigned I = 0, N = Record.size(); I != N; ++I)
- DynamicClasses.push_back(getGlobalDeclID(F, Record[I]));
- break;
-
case PENDING_IMPLICIT_INSTANTIATIONS:
if (PendingInstantiations.size() % 2 != 0) {
Error("Invalid existing PendingInstantiations");
@@ -7312,16 +7307,6 @@ void ASTReader::ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {
ExtVectorDecls.clear();
}
-void ASTReader::ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {
- for (unsigned I = 0, N = DynamicClasses.size(); I != N; ++I) {
- CXXRecordDecl *D
- = dyn_cast_or_null<CXXRecordDecl>(GetDecl(DynamicClasses[I]));
- if (D)
- Decls.push_back(D);
- }
- DynamicClasses.clear();
-}
-
void ASTReader::ReadUnusedLocalTypedefNameCandidates(
llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {
for (unsigned I = 0, N = UnusedLocalTypedefNameCandidates.size(); I != N;
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index c70935c0c7d..e04c46ed982 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4344,10 +4344,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
AddDeclRef(TD, UnusedLocalTypedefNameCandidates);
- // Build a record containing all of dynamic classes declarations.
- RecordData DynamicClasses;
- AddLazyVectorDecls(*this, SemaRef.DynamicClasses, DynamicClasses);
-
// Build a record containing all of pending implicit instantiations.
RecordData PendingInstantiations;
for (std::deque<Sema::PendingImplicitInstantiation>::iterator
@@ -4628,10 +4624,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
if (!VTableUses.empty())
Stream.EmitRecord(VTABLE_USES, VTableUses);
- // Write the record containing dynamic classes declarations.
- if (!DynamicClasses.empty())
- Stream.EmitRecord(DYNAMIC_CLASSES, DynamicClasses);
-
// Write the record containing potentially unused local typedefs.
if (!UnusedLocalTypedefNameCandidates.empty())
Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
OpenPOWER on IntegriCloud