Given Decl::isUsed() a flag indicating when to consider the "used"
attribute as part of the calculation. Sema::MarkDeclReferenced(), and
a few other places, want only to consider the "used" bit to determine,
e.g, whether to perform template instantiation. Fixes a linkage issue
with Boost.Serialization.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106252 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index f1b78e4..104df7a 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -212,17 +212,17 @@
   return getTranslationUnitDecl()->getASTContext();
 }
 
-bool Decl::isUsed() const { 
+bool Decl::isUsed(bool CheckUsedAttr) const { 
   if (Used)
     return true;
   
   // Check for used attribute.
-  if (hasAttr<UsedAttr>())
+  if (CheckUsedAttr && hasAttr<UsedAttr>())
     return true;
   
   // Check redeclarations for used attribute.
   for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
-    if (I->hasAttr<UsedAttr>() || I->Used)
+    if ((CheckUsedAttr && I->hasAttr<UsedAttr>()) || I->Used)
       return true;
   }
   
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 6b88dfc..36ce5c0 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -118,7 +118,7 @@
   Record.push_back(D->isInvalidDecl());
   Record.push_back(D->hasAttrs());
   Record.push_back(D->isImplicit());
-  Record.push_back(D->isUsed());
+  Record.push_back(D->isUsed(false));
   Record.push_back(D->getAccess());
   Record.push_back(D->getPCHLevel());
 }
@@ -443,7 +443,7 @@
   if (!D->getTypeSourceInfo() &&
       !D->hasAttrs() &&
       !D->isImplicit() &&
-      !D->isUsed() &&
+      !D->isUsed(false) &&
       D->getAccess() == AS_none &&
       D->getPCHLevel() == 0 &&
       D->getStorageClass() == 0 &&
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 8bdf971..eadc2ad 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -226,7 +226,8 @@
   // Remove functions that turned out to be used.
   UnusedStaticFuncs.erase(std::remove_if(UnusedStaticFuncs.begin(), 
                                          UnusedStaticFuncs.end(), 
-                                         std::mem_fun(&FunctionDecl::isUsed)), 
+                             std::bind2nd(std::mem_fun(&FunctionDecl::isUsed),
+                                          true)), 
                           UnusedStaticFuncs.end());
 
   // Check for #pragma weak identifiers that were never declared
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 2a881ff..c6f149e 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4216,7 +4216,7 @@
 void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
                                             CXXConstructorDecl *Constructor) {
   assert((Constructor->isImplicit() && Constructor->isDefaultConstructor() &&
-          !Constructor->isUsed()) &&
+          !Constructor->isUsed(false)) &&
     "DefineImplicitDefaultConstructor - call it for implicit default ctor");
 
   CXXRecordDecl *ClassDecl = Constructor->getParent();
@@ -4237,7 +4237,7 @@
 
 void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
                                     CXXDestructorDecl *Destructor) {
-  assert((Destructor->isImplicit() && !Destructor->isUsed()) &&
+  assert((Destructor->isImplicit() && !Destructor->isUsed(false)) &&
          "DefineImplicitDestructor - call it for implicit default dtor");
   CXXRecordDecl *ClassDecl = Destructor->getParent();
   assert(ClassDecl && "DefineImplicitDestructor - invalid destructor");
@@ -4466,7 +4466,7 @@
   assert((CopyAssignOperator->isImplicit() && 
           CopyAssignOperator->isOverloadedOperator() &&
           CopyAssignOperator->getOverloadedOperator() == OO_Equal &&
-          !CopyAssignOperator->isUsed()) &&
+          !CopyAssignOperator->isUsed(false)) &&
          "DefineImplicitCopyAssignment called for wrong function");
 
   CXXRecordDecl *ClassDecl = CopyAssignOperator->getParent();
@@ -4766,7 +4766,7 @@
                                    unsigned TypeQuals) {
   assert((CopyConstructor->isImplicit() &&
           CopyConstructor->isCopyConstructor(TypeQuals) &&
-          !CopyConstructor->isUsed()) &&
+          !CopyConstructor->isUsed(false)) &&
          "DefineImplicitCopyConstructor - call it for implicit copy ctor");
 
   CXXRecordDecl *ClassDecl = CopyConstructor->getParent();
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index fa403c7..5882381 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -7500,7 +7500,7 @@
 void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
   assert(D && "No declaration?");
 
-  if (D->isUsed())
+  if (D->isUsed(false))
     return;
 
   // Mark a parameter or variable declaration "used", regardless of whether we're in a
@@ -7543,24 +7543,24 @@
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
     unsigned TypeQuals;
     if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) {
-        if (!Constructor->isUsed())
+        if (!Constructor->isUsed(false))
           DefineImplicitDefaultConstructor(Loc, Constructor);
     } else if (Constructor->isImplicit() &&
                Constructor->isCopyConstructor(TypeQuals)) {
-      if (!Constructor->isUsed())
+      if (!Constructor->isUsed(false))
         DefineImplicitCopyConstructor(Loc, Constructor, TypeQuals);
     }
 
     MarkVTableUsed(Loc, Constructor->getParent());
   } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
-    if (Destructor->isImplicit() && !Destructor->isUsed())
+    if (Destructor->isImplicit() && !Destructor->isUsed(false))
       DefineImplicitDestructor(Loc, Destructor);
     if (Destructor->isVirtual())
       MarkVTableUsed(Loc, Destructor->getParent());
   } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
     if (MethodDecl->isImplicit() && MethodDecl->isOverloadedOperator() &&
         MethodDecl->getOverloadedOperator() == OO_Equal) {
-      if (!MethodDecl->isUsed())
+      if (!MethodDecl->isUsed(false))
         DefineImplicitCopyAssignment(Loc, MethodDecl);
     } else if (MethodDecl->isVirtual())
       MarkVTableUsed(Loc, MethodDecl->getParent());
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b7059e5..1b28579 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -361,7 +361,9 @@
     Var->setLexicalDeclContext(D->getLexicalDeclContext());
 
   Var->setAccess(D->getAccess());
-  Var->setUsed(D->isUsed());
+  
+  if (!D->isStaticDataMember())
+    Var->setUsed(D->isUsed(false));
   
   // FIXME: In theory, we could have a previous declaration for variables that
   // are not static data members.