From 70d83e27a42d6498e2c30d38762710ae803bf7ae Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 29 Jun 2009 17:30:29 +0000 Subject: [PATCH] Move FunctionDecl::TemplateSpecializationInfo out into its own class, FunctionTemplateSpecializationInfo, in DeclTemplate.h. No functionality change. llvm-svn: 74431 --- clang/include/clang/AST/Decl.h | 30 ++++++-------------------- clang/include/clang/AST/DeclTemplate.h | 25 +++++++++++++++++++++ clang/lib/AST/Decl.cpp | 30 +++++++++++++++++++++----- clang/lib/CodeGen/CodeGenModule.cpp | 10 +++++++++ 4 files changed, 66 insertions(+), 29 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 3de01f3baeb5..e976d833acae 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -26,6 +26,7 @@ class Stmt; class CompoundStmt; class StringLiteral; class TemplateArgumentList; +class FunctionTemplateSpecializationInfo; /// TranslationUnitDecl - The top declaration context. class TranslationUnitDecl : public Decl, public DeclContext { @@ -621,15 +622,8 @@ public: enum StorageClass { None, Extern, Static, PrivateExtern }; -private: - /// \brief Provides information about a function template specialization, - /// which is a FunctionDecl that has been explicitly specialization or - /// instantiated from a function template. - struct TemplateSpecializationInfo { - FunctionTemplateDecl *Template; - const TemplateArgumentList *TemplateArguments; - }; +private: /// ParamInfo - new[]'d array of pointers to VarDecls for the formal /// parameters of this function. This is null if a prototype or if there are /// no formals. @@ -684,7 +678,8 @@ private: /// the template being specialized and the template arguments involved in /// that specialization. llvm::PointerUnion3 TemplateOrSpecialization; + FunctionTemplateSpecializationInfo*> + TemplateOrSpecialization; protected: FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -940,27 +935,14 @@ public: /// /// If this function declaration is not a function template specialization, /// returns NULL. - FunctionTemplateDecl *getPrimaryTemplate() const { - if (TemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast()) { - return Info->Template; - } - return 0; - } + FunctionTemplateDecl *getPrimaryTemplate() const; /// \brief Retrieve the template arguments used to produce this function /// template specialization from the primary template. /// /// If this function declaration is not a function template specialization, /// returns NULL. - const TemplateArgumentList *getTemplateSpecializationArgs() const { - if (TemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast()) { - return Info->TemplateArguments; - } - return 0; - } - + const TemplateArgumentList *getTemplateSpecializationArgs() const; /// \brief Specify that this function declaration is actually a function /// template specialization. diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index aad19a63ef0f..9a633ef73ef5 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -154,9 +154,34 @@ protected: TemplateParameterList* TemplateParams; }; +/// \brief Provides information about a function template specialization, +/// which is a FunctionDecl that has been explicitly specialization or +/// instantiated from a function template. +class FunctionTemplateSpecializationInfo { +public: + FunctionTemplateDecl *Template; + const TemplateArgumentList *TemplateArguments; +}; + /// Declaration of a template function. class FunctionTemplateDecl : public TemplateDecl { protected: + /// \brief Data that is common to all of the declarations of a given + /// class template. + struct Common { + /// \brief The class template specializations for this class + /// template, including explicit specializations and instantiations. + llvm::FoldingSet Specializations; + + /// \brief The class template partial specializations for this class + /// template. + llvm::FoldingSet + PartialSpecializations; + + /// \brief The injected-class-name type for this class template. + QualType InjectedClassNameType; + }; + FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl) : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { } diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 5382ab52ab5b..94a02f418ef9 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -372,8 +372,9 @@ void FunctionDecl::Destroy(ASTContext& C) { C.Deallocate(ParamInfo); - if (TemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast()) + if (FunctionTemplateSpecializationInfo *Info + = TemplateOrSpecialization + .dyn_cast()) C.Deallocate(Info); Decl::Destroy(C); @@ -572,14 +573,33 @@ OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { return OO_None; } +FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { + if (FunctionTemplateSpecializationInfo *Info + = TemplateOrSpecialization + .dyn_cast()) { + return Info->Template; + } + return 0; +} + +const TemplateArgumentList * +FunctionDecl::getTemplateSpecializationArgs() const { + if (FunctionTemplateSpecializationInfo *Info + = TemplateOrSpecialization + .dyn_cast()) { + return Info->TemplateArguments; + } + return 0; +} + void FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context, FunctionTemplateDecl *Template, const TemplateArgumentList *TemplateArgs) { - TemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast(); + FunctionTemplateSpecializationInfo *Info + = TemplateOrSpecialization.dyn_cast(); if (!Info) - Info = new (Context) TemplateSpecializationInfo; + Info = new (Context) FunctionTemplateSpecializationInfo; Info->Template = Template; Info->TemplateArguments = TemplateArgs; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0a531e9b21a6..a82324834b8d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1477,9 +1477,19 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { if (Diags.hasErrorOccurred()) return; + // Ignore dependent declarations. + if (D->getDeclContext() && D->getDeclContext()->isDependentContext()) + return; + switch (D->getKind()) { case Decl::CXXMethod: case Decl::Function: + // Skip function templates + if (cast(D)->getDescribedFunctionTemplate()) + return; + + // Fall through + case Decl::Var: EmitGlobal(GlobalDecl(cast(D))); break;