summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-04-01 16:23:44 +0000
committerReid Kleckner <reid@kleckner.net>2015-04-01 16:23:44 +0000
commit0a33e615f31ca2882893cf16f619e21632fbad66 (patch)
tree55a4b6073ca47a680457226a513fee3f092cfc0f /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
parentba7c3ff32f7564b4503e5245a09052b4d0c23291 (diff)
downloadbcm5719-llvm-0a33e615f31ca2882893cf16f619e21632fbad66.tar.gz
bcm5719-llvm-0a33e615f31ca2882893cf16f619e21632fbad66.zip
Mark instantiated function decls as inline specified if any pattern is
A function template pattern can be declared without the 'inline' specifier and defined later with the 'inline' specifier. However, during instantiation, we were only looking at the canonical decl to see if we should mark the instantiated decl as inline specified. Since the instantiated decl actually represents many pattern declarations, put the inline specifier on the instantiation decl if any of the pattern decls have it. llvm-svn: 233817
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 6936539f1ca..677c3b8bb1d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1304,6 +1304,15 @@ static QualType adjustFunctionTypeForInstantiation(ASTContext &Context,
NewFunc->getParamTypes(), NewEPI);
}
+/// Return true if any redeclaration of FD was inline specified. Useful for
+/// propagating the 'inline' specifier onto function template instantiations.
+static bool isAnyRedeclInlineSpecified(const FunctionDecl *FD) {
+ for (const auto *R : FD->redecls())
+ if (R->isInlineSpecified())
+ return true;
+ return false;
+}
+
/// Normal class members are of more specific types and therefore
/// don't make it here. This function serves two purposes:
/// 1) instantiating function templates
@@ -1372,7 +1381,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),
D->getNameInfo(), T, TInfo,
D->getCanonicalDecl()->getStorageClass(),
- D->isInlineSpecified(), D->hasWrittenPrototype(),
+ isAnyRedeclInlineSpecified(D),
+ D->hasWrittenPrototype(),
D->isConstexpr());
Function->setRangeEnd(D->getSourceRange().getEnd());
@@ -1669,7 +1679,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Method = CXXConstructorDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
Constructor->isExplicit(),
- Constructor->isInlineSpecified(),
+ isAnyRedeclInlineSpecified(Constructor),
false, Constructor->isConstexpr());
// Claim that the instantiation of a constructor or constructor template
@@ -1704,12 +1714,12 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
- Destructor->isInlineSpecified(),
+ isAnyRedeclInlineSpecified(Destructor),
false);
} else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
Method = CXXConversionDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
- Conversion->isInlineSpecified(),
+ isAnyRedeclInlineSpecified(Conversion),
Conversion->isExplicit(),
Conversion->isConstexpr(),
Conversion->getLocEnd());
@@ -1717,7 +1727,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
StorageClass SC = D->isStatic() ? SC_Static : SC_None;
Method = CXXMethodDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
- SC, D->isInlineSpecified(),
+ SC, isAnyRedeclInlineSpecified(D),
D->isConstexpr(), D->getLocEnd());
}
OpenPOWER on IntegriCloud