summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-01-25 00:08:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-01-25 00:08:28 +0000
commitf3814ad4268d6b4c206fb6f7d4b3460de485add2 (patch)
tree6ba6838a660432d097c50659c0482e34cb55452d
parente29dadb6403c8b0d3658f9bbbe2f5fbde5431fdb (diff)
downloadbcm5719-llvm-f3814ad4268d6b4c206fb6f7d4b3460de485add2.tar.gz
bcm5719-llvm-f3814ad4268d6b4c206fb6f7d4b3460de485add2.zip
Clean up: since we have FunctionDecl::IsInline, make it store the right value
for template instantiations, and use it to simplify the implementation of FunctionDecl::isInlined(). This incidentally changes the result of isInlined on a declared-but-not-defined non-inline member function from true to false. This is sort of a bug fix, but currently isInlined is only called on function definitions, so it has no visible effects. llvm-svn: 173397
-rw-r--r--clang/include/clang/AST/Decl.h2
-rw-r--r--clang/lib/AST/Decl.cpp40
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp9
3 files changed, 16 insertions, 35 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 3cca66f0683..8b9688baead 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -1887,7 +1887,7 @@ public:
/// \brief Determine whether this function should be inlined, because it is
/// either marked "inline" or "constexpr" or is a member function of a class
/// that was defined in the class body.
- bool isInlined() const;
+ bool isInlined() const { return IsInline; }
bool isInlineDefinitionExternallyVisible() const;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 7a518143251..6ecc2cce53c 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1962,38 +1962,6 @@ unsigned FunctionDecl::getMinRequiredArguments() const {
return NumRequiredArgs;
}
-bool FunctionDecl::isInlined() const {
- if (IsInline)
- return true;
-
- if (isa<CXXMethodDecl>(this)) {
- if (!isOutOfLine() || getCanonicalDecl()->isInlineSpecified())
- return true;
- }
-
- switch (getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ExplicitSpecialization:
- return false;
-
- case TSK_ImplicitInstantiation:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- // Handle below.
- break;
- }
-
- const FunctionDecl *PatternDecl = getTemplateInstantiationPattern();
- bool HasPattern = false;
- if (PatternDecl)
- HasPattern = PatternDecl->hasBody(PatternDecl);
-
- if (HasPattern && PatternDecl)
- return PatternDecl->isInlined();
-
- return false;
-}
-
static bool RedeclForcesDefC99(const FunctionDecl *Redecl) {
// Only consider file-scope declarations in this test.
if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
@@ -2069,8 +2037,8 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
return FoundBody;
}
-/// \brief For an inline function definition in C or C++, determine whether the
-/// definition will be externally visible.
+/// \brief For an inline function definition in C, or for a gnu_inline function
+/// in C++, determine whether the definition will be externally visible.
///
/// Inline function definitions are always available for inlining optimizations.
/// However, depending on the language dialect, declaration specifiers, and
@@ -2114,6 +2082,10 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
return false;
}
+ // The rest of this function is C-only.
+ assert(!Context.getLangOpts().CPlusPlus &&
+ "should not use C inline rules in C++");
+
// C99 6.7.4p6:
// [...] If all of the file scope declarations for a function in a
// translation unit include the inline function specifier without extern,
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b0935a54ac5..b679d49215b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1120,6 +1120,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
D->isInlineSpecified(), D->hasWrittenPrototype(),
D->isConstexpr());
+ if (D->isInlined())
+ Function->setImplicitlyInline();
+
if (QualifierLoc)
Function->setQualifierInfo(QualifierLoc);
@@ -1485,6 +1488,9 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
D->isConstexpr(), D->getLocEnd());
}
+ if (D->isInlined())
+ Method->setImplicitlyInline();
+
if (QualifierLoc)
Method->setQualifierInfo(QualifierLoc);
@@ -2763,6 +2769,9 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
!PatternDecl->isInlined())
return;
+ if (PatternDecl->isInlined())
+ Function->setImplicitlyInline();
+
InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
if (Inst)
return;
OpenPOWER on IntegriCloud