diff options
-rw-r--r-- | include/clang/AST/Decl.h | 30 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 25 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 30 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 10 |
4 files changed, 66 insertions, 29 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 3de01f3bae..e976d833ac 100644 --- a/include/clang/AST/Decl.h +++ b/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<FunctionTemplateDecl*, FunctionDecl*, - TemplateSpecializationInfo*> 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<TemplateSpecializationInfo*>()) { - 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<TemplateSpecializationInfo*>()) { - return Info->TemplateArguments; - } - return 0; - } - + const TemplateArgumentList *getTemplateSpecializationArgs() const; /// \brief Specify that this function declaration is actually a function /// template specialization. diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index aad19a63ef..9a633ef73e 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/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<ClassTemplateSpecializationDecl> Specializations; + + /// \brief The class template partial specializations for this class + /// template. + llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> + 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/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 5382ab52ab..94a02f418e 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -372,8 +372,9 @@ void FunctionDecl::Destroy(ASTContext& C) { C.Deallocate(ParamInfo); - if (TemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>()) + if (FunctionTemplateSpecializationInfo *Info + = TemplateOrSpecialization + .dyn_cast<FunctionTemplateSpecializationInfo*>()) 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<FunctionTemplateSpecializationInfo*>()) { + return Info->Template; + } + return 0; +} + +const TemplateArgumentList * +FunctionDecl::getTemplateSpecializationArgs() const { + if (FunctionTemplateSpecializationInfo *Info + = TemplateOrSpecialization + .dyn_cast<FunctionTemplateSpecializationInfo*>()) { + return Info->TemplateArguments; + } + return 0; +} + void FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context, FunctionTemplateDecl *Template, const TemplateArgumentList *TemplateArgs) { - TemplateSpecializationInfo *Info - = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>(); + FunctionTemplateSpecializationInfo *Info + = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); if (!Info) - Info = new (Context) TemplateSpecializationInfo; + Info = new (Context) FunctionTemplateSpecializationInfo; Info->Template = Template; Info->TemplateArguments = TemplateArgs; diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 0a531e9b21..a82324834b 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/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<FunctionDecl>(D)->getDescribedFunctionTemplate()) + return; + + // Fall through + case Decl::Var: EmitGlobal(GlobalDecl(cast<ValueDecl>(D))); break; |