]> granicus.if.org Git - clang/commitdiff
Given Decl::isUsed() a flag indicating when to consider the "used"
authorDouglas Gregor <dgregor@apple.com>
Thu, 17 Jun 2010 23:14:26 +0000 (23:14 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 17 Jun 2010 23:14:26 +0000 (23:14 +0000)
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

include/clang/AST/DeclBase.h
lib/AST/DeclBase.cpp
lib/Frontend/PCHWriterDecl.cpp
lib/Sema/Sema.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-function-2.cpp

index f6478d9ea6695d5e88a473bbfc3fe63d5f0e1284..fe091ad17bc4e143095a1d89935b6b7e9f4017cb 100644 (file)
@@ -330,7 +330,11 @@ public:
 
   /// \brief Whether this declaration was used, meaning that a definition
   /// is required.
-  bool isUsed() const;
+  ///
+  /// \param CheckUsedAttr When true, also consider the "used" attribute
+  /// (in addition to the "used" bit set by \c setUsed()) when determining
+  /// whether the function is used.
+  bool isUsed(bool CheckUsedAttr = true) const;
   
   void setUsed(bool U = true) { Used = U; }
 
index f1b78e40fc807d88c03b6a119429466841acab1a..104df7ae84f3372fa26af5b3e32205ef96e29afd 100644 (file)
@@ -212,17 +212,17 @@ ASTContext &Decl::getASTContext() const {
   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;
   }
   
index 6b88dfcae416239d251f904a1f0cc2ae50185e19..36ce5c047fe922420b900823613beb02fb325df2 100644 (file)
@@ -118,7 +118,7 @@ void PCHDeclWriter::VisitDecl(Decl *D) {
   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 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
   if (!D->getTypeSourceInfo() &&
       !D->hasAttrs() &&
       !D->isImplicit() &&
-      !D->isUsed() &&
+      !D->isUsed(false) &&
       D->getAccess() == AS_none &&
       D->getPCHLevel() == 0 &&
       D->getStorageClass() == 0 &&
index 8bdf971d9657ed9b41daafbfc66b769441b725d2..eadc2ad253d82a8f62241a05e57bc8d210a79215 100644 (file)
@@ -226,7 +226,8 @@ void Sema::ActOnEndOfTranslationUnit() {
   // 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
index 2a881ff4348e7e095e2df17684a9f80c77b75355..c6f149e8fed6f50fb44873b3892799dc99264bcf 100644 (file)
@@ -4216,7 +4216,7 @@ namespace {
 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::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
 
 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 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
   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 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
                                    unsigned TypeQuals) {
   assert((CopyConstructor->isImplicit() &&
           CopyConstructor->isCopyConstructor(TypeQuals) &&
-          !CopyConstructor->isUsed()) &&
+          !CopyConstructor->isUsed(false)) &&
          "DefineImplicitCopyConstructor - call it for implicit copy ctor");
 
   CXXRecordDecl *ClassDecl = CopyConstructor->getParent();
index fa403c78d06642f8a72750f78adea6a628b17678..5882381e222b7e4d10d3029de48383a20789fe4b 100644 (file)
@@ -7500,7 +7500,7 @@ Sema::PopExpressionEvaluationContext() {
 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 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
   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());
index b7059e5752389adc9f4f79fa93df590ea658f6e7..1b28579e61d45f703582217047a4de2c8231268d 100644 (file)
@@ -361,7 +361,9 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
     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.
index afca358784442fb39baf31736aa2f352c1d9c18f..ebc0ef3a9f9616c26973bb2760ffca460fe9c99a 100644 (file)
@@ -20,3 +20,14 @@ namespace PR7184 {
 
   template void f<int>();
 }
+
+namespace UsedAttr {
+  template<typename T>
+  void __attribute__((used)) foo() {
+    T *x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+  }
+
+  void bar() {
+    foo<int>(); // expected-note{{instantiation of}}
+  }
+}