Clean up: since we have FunctionDecl::IsInline, make it store the right value
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 25 Jan 2013 00:08:28 +0000 (00:08 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 25 Jan 2013 00:08:28 +0000 (00:08 +0000)
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

clang/include/clang/AST/Decl.h
clang/lib/AST/Decl.cpp
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

index 3cca66f..8b9688b 100644 (file)
@@ -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;
 
index 7a51814..6ecc2cc 100644 (file)
@@ -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, 
index b0935a5..b679d49 100644 (file)
@@ -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;