On Mar 5, 2012, at 2:54 AM, Rafael Espindola wrote: > Author: rafael > Date: Mon Mar 5 04:54:55 2012 > New Revision: 152024 > > URL: http://llvm.org/viewvc/llvm-project?rev=152024&view=rev > Log: > Fix a small difference in sema and codegen views of what needs to be output. > > In the included testcase, soma thinks that we already have a definition after > we > see the out of line decl. Codegen puts it in a deferred list, to be output if > a use is seen. This would break when we saw an explicit template instantiation > definition, since codegen would not be notified. > > This patch adds a method to the consumer interface so that soma can notify > codegen that this decl is now required.
"void MarkVarRequired(VarDecl *VD);" seems like a too codegen-specific callback to put in ASTConsumer; how about notifying the ASTConsumer that a static member variable was instantiated ? Something like: "virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD)" then have codegen do the right thing ? Also could you add a test to make sure the related test case works fine through a PCH ? -Argyrios > > Added: > cfe/trunk/test/CodeGenCXX/pr12104.cpp > Modified: > cfe/trunk/include/clang/AST/ASTConsumer.h > cfe/trunk/include/clang/Frontend/MultiplexConsumer.h > cfe/trunk/lib/CodeGen/CodeGenAction.cpp > cfe/trunk/lib/CodeGen/CodeGenModule.cpp > cfe/trunk/lib/CodeGen/CodeGenModule.h > cfe/trunk/lib/CodeGen/ModuleBuilder.cpp > cfe/trunk/lib/Frontend/MultiplexConsumer.cpp > cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp > > Modified: cfe/trunk/include/clang/AST/ASTConsumer.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTConsumer.h?rev=152024&r1=152023&r2=152024&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/ASTConsumer.h (original) > +++ cfe/trunk/include/clang/AST/ASTConsumer.h Mon Mar 5 04:54:55 2012 > @@ -90,6 +90,11 @@ > /// modified by the introduction of an implicit zero initializer. > virtual void CompleteTentativeDefinition(VarDecl *D) {} > > + /// MarkVarRequired - Tell the consumer that this variable must be output. > + /// This is needed when the definition is initially one that can be > deferred, > + /// but we then see an explicit template instantiation definition. > + virtual void MarkVarRequired(VarDecl *D) {} > + > /// \brief Callback involved at the end of a translation unit to > /// notify the consumer that a vtable for the given C++ class is > /// required. > > Modified: cfe/trunk/include/clang/Frontend/MultiplexConsumer.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/MultiplexConsumer.h?rev=152024&r1=152023&r2=152024&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Frontend/MultiplexConsumer.h (original) > +++ cfe/trunk/include/clang/Frontend/MultiplexConsumer.h Mon Mar 5 04:54:55 > 2012 > @@ -35,6 +35,7 @@ > > // ASTConsumer > virtual void Initialize(ASTContext &Context); > + virtual void MarkVarRequired(VarDecl *VD); > virtual bool HandleTopLevelDecl(DeclGroupRef D); > virtual void HandleInterestingDecl(DeclGroupRef D); > virtual void HandleTranslationUnit(ASTContext &Ctx); > > Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=152024&r1=152023&r2=152024&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Mon Mar 5 04:54:55 2012 > @@ -73,6 +73,10 @@ > llvm::Module *takeModule() { return TheModule.take(); } > llvm::Module *takeLinkModule() { return LinkModule.take(); } > > + virtual void MarkVarRequired(VarDecl *VD) { > + Gen->MarkVarRequired(VD); > + } > + > virtual void Initialize(ASTContext &Ctx) { > Context = &Ctx; > > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=152024&r1=152023&r2=152024&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Mar 5 04:54:55 2012 > @@ -1722,6 +1722,9 @@ > } > } > > +void CodeGenModule::MarkVarRequired(VarDecl *VD) { > + GetAddrOfGlobalVar(VD); > +} > > void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { > const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl()); > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=152024&r1=152023&r2=152024&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original) > +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Mar 5 04:54:55 2012 > @@ -658,6 +658,11 @@ > /// EmitTopLevelDecl - Emit code for a single top level declaration. > void EmitTopLevelDecl(Decl *D); > > + /// MarkVarRequired - Tell the consumer that this variable must be output. > + /// This is needed when the definition is initially one that can be > deferred, > + /// but we then see an explicit template instantiation definition. > + void MarkVarRequired(VarDecl *VD); > + > /// AddUsedGlobal - Add a global which should be forced to be > /// present in the object file; these are emitted to the llvm.used > /// metadata global. > > Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=152024&r1=152023&r2=152024&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original) > +++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Mon Mar 5 04:54:55 2012 > @@ -59,6 +59,10 @@ > *M, *TD, Diags)); > } > > + virtual void MarkVarRequired(VarDecl *VD) { > + Builder->MarkVarRequired(VD); > + } > + > virtual bool HandleTopLevelDecl(DeclGroupRef DG) { > // Make sure to emit all elements of a Decl. > for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) > > Modified: cfe/trunk/lib/Frontend/MultiplexConsumer.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=152024&r1=152023&r2=152024&view=diff > ============================================================================== > --- cfe/trunk/lib/Frontend/MultiplexConsumer.cpp (original) > +++ cfe/trunk/lib/Frontend/MultiplexConsumer.cpp Mon Mar 5 04:54:55 2012 > @@ -209,6 +209,11 @@ > return Continue; > } > > +void MultiplexConsumer::MarkVarRequired(VarDecl *VD) { > + for (size_t i = 0, e = Consumers.size(); i != e; ++i) > + Consumers[i]->MarkVarRequired(VD); > +} > + > void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) { > for (size_t i = 0, e = Consumers.size(); i != e; ++i) > Consumers[i]->HandleInterestingDecl(D); > > Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=152024&r1=152023&r2=152024&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Mar 5 04:54:55 > 2012 > @@ -2596,21 +2596,25 @@ > return; > } > > + TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); > + > // Never instantiate an explicit specialization. > - if (Var->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) > + if (TSK == TSK_ExplicitSpecialization) > return; > > // C++0x [temp.explicit]p9: > // Except for inline functions, other explicit instantiation declarations > // have the effect of suppressing the implicit instantiation of the entity > // to which they refer. > - if (Var->getTemplateSpecializationKind() > - == TSK_ExplicitInstantiationDeclaration) > + if (TSK == TSK_ExplicitInstantiationDeclaration) > return; > > // If we already have a definition, we're done. > - if (Var->getDefinition()) > + if (Var->getDefinition()) { > + if (TSK == TSK_ExplicitInstantiationDefinition) > + Consumer.MarkVarRequired(Var); > return; > + } > > InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); > if (Inst) > > Added: cfe/trunk/test/CodeGenCXX/pr12104.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pr12104.cpp?rev=152024&view=auto > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/pr12104.cpp (added) > +++ cfe/trunk/test/CodeGenCXX/pr12104.cpp Mon Mar 5 04:54:55 2012 > @@ -0,0 +1,14 @@ > +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s > + > +template <int dimm> struct Patch { > + static const unsigned int no_neighbor = 1; > +}; > +template <int dim> > +const unsigned int Patch<dim>::no_neighbor; > +void f(const unsigned int); > +void g() { > + f(Patch<1>::no_neighbor); > +} > +template struct Patch<1>; > + > +// CHECK: _ZN5PatchILi1EE11no_neighborE > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
