diff options
author | John McCall <rjmccall@apple.com> | 2013-01-25 22:31:03 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2013-01-25 22:31:03 +0000 |
commit | 6bd2a89d5ae990135b6d400982c2004ad72b9f15 (patch) | |
tree | d9cb85b4d58dd1c58f178e799bb1691b97d72a9f /clang/lib/Sema/SemaDecl.cpp | |
parent | 359b885e12815e8d63adcfb5760696bad82c6908 (diff) | |
download | bcm5719-llvm-6bd2a89d5ae990135b6d400982c2004ad72b9f15.tar.gz bcm5719-llvm-6bd2a89d5ae990135b6d400982c2004ad72b9f15.zip |
The standard ARM C++ ABI dictates that inline functions are
never key functions. We did not implement that rule for the
iOS ABI, which was driven by what was implemented in gcc-4.2.
However, implement it now for other ARM-based platforms.
llvm-svn: 173515
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9efcb52d148..d584ed85710 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6362,9 +6362,31 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } } else { - if (isa<CXXMethodDecl>(NewFD)) // Set access for out-of-line definitions - NewFD->setAccess(OldDecl->getAccess()); + // 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->getFirstDeclaration()); + if (oldMethod->isVirtual()) { + Context.setNonKeyFunction(oldMethod); + } + } + } } } |