aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-09-13 21:56:43 +0000
committerDouglas Gregor <dgregor@apple.com>2012-09-13 21:56:43 +0000
commit71074fdf40a8f5b53810712102b58c27efc30759 (patch)
tree6b74f9bc0f5e961271586b2d10c9df45381b08c8 /lib/Sema/SemaTemplateInstantiateDecl.cpp
parent7b4362ec118bb69d0d2aaee01941cb85a36efa79 (diff)
When we substitute into the type of a function based on the
TypeSourceInfo, we may have lost some adjustments made to the type of that function due to declaration merging. Adjust the resulting type correspondingly. Fixes PR12948 / <rdar://problem/11552434>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163845 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp19
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 15afd1f6c9..858aabf8a8 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1008,6 +1008,21 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
return Record;
}
+/// \brief Adjust the given function type for an instantiation of the
+/// given declaration, to cope with modifications to the function's type that
+/// aren't reflected in the type-source information.
+///
+/// \param D The declaration we're instantiating.
+/// \param TInfo The already-instantiated type.
+static QualType adjustFunctionTypeForInstantiation(ASTContext &Context,
+ FunctionDecl *D,
+ TypeSourceInfo *TInfo) {
+ const FunctionType *OrigFunc = D->getType()->castAs<FunctionType>();
+ const FunctionType *NewFunc = TInfo->getType()->castAs<FunctionType>();
+ return QualType(Context.adjustFunctionType(NewFunc, OrigFunc->getExtInfo()),
+ 0);
+}
+
/// Normal class members are of more specific types and therefore
/// don't make it here. This function serves two purposes:
/// 1) instantiating function templates
@@ -1048,7 +1063,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
if (!TInfo)
return 0;
- QualType T = TInfo->getType();
+ QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
if (QualifierLoc) {
@@ -1366,7 +1381,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
if (!TInfo)
return 0;
- QualType T = TInfo->getType();
+ QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
// \brief If the type of this function, after ignoring parentheses,
// is not *directly* a function type, then we're instantiating a function