diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-09-13 21:56:43 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-09-13 21:56:43 +0000 |
commit | 89f593a14c0b37250749d9b5e96c8f926a409475 (patch) | |
tree | b5ee40d45779c2229e8590f1a554ab32b06df02b /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 3f553c21eb5abef5413ec188c76390f2de61da85 (diff) | |
download | bcm5719-llvm-89f593a14c0b37250749d9b5e96c8f926a409475.tar.gz bcm5719-llvm-89f593a14c0b37250749d9b5e96c8f926a409475.zip |
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>.
llvm-svn: 163845
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 15afd1f6c99..858aabf8a8b 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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 |