diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-09 18:46:07 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-09 18:46:07 +0000 |
commit | 55f6b14230c94272efbbcdd89a92224c8db9f225 (patch) | |
tree | 988ae940f14f93aac610fbc36d89766e539eab6c /lib/Sema/SemaTemplate.cpp | |
parent | 00e68e2cc5ce37cb95beb801cae73c0d1e9dda37 (diff) |
Start processing template-ids as types when the template-name refers
to a class template. For example, the template-id 'vector<int>' now
has a nice, sugary type in the type system. What we can do now:
- Parse template-ids like 'vector<int>' (where 'vector' names a
class template) and form proper types for them in the type system.
- Parse icky template-ids like 'A<5>' and 'A<(5 > 0)>' properly,
using (sadly) a bool in the parser to tell it whether '>' should
be treated as an operator or not.
This is a baby-step, with major problems and limitations:
- There are currently two ways that we handle template arguments
(whether they are types or expressions). These will be merged, and,
most likely, TemplateArg will disappear.
- We don't have any notion of the declaration of class template
specializations or of template instantiations, so all template-ids
are fancy names for 'int' :)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64153 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 88 |
1 files changed, 69 insertions, 19 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 6c5f90afa5..6b6a50130a 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -25,38 +25,43 @@ using namespace clang; /// declaration if II names a template. An optional CXXScope can be /// passed to indicate the C++ scope in which the identifier will be /// found. -Sema::DeclTy *Sema::isTemplateName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS) { - DeclContext *DC = 0; - - if (SS) { - if (SS->isInvalid()) - return 0; - DC = static_cast<DeclContext*>(SS->getScopeRep()); - } +Sema::TemplateNameKind Sema::isTemplateName(IdentifierInfo &II, Scope *S, + DeclTy *&Template, + const CXXScopeSpec *SS) { NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName); if (IIDecl) { - // FIXME: We need to represent templates via some kind of - // TemplateDecl, because what follows is a hack that only works in - // one specific case. - if (isa<TemplateDecl>(IIDecl)) - return IIDecl; + if (isa<TemplateDecl>(IIDecl)) { + Template = IIDecl; + if (isa<FunctionTemplateDecl>(IIDecl)) + return TNK_Function_template; + else if (isa<ClassTemplateDecl>(IIDecl)) + return TNK_Class_template; + else if (isa<TemplateTemplateParmDecl>(IIDecl)) + return TNK_Template_template_parm; + else + assert(false && "Unknown TemplateDecl"); + } + // FIXME: What follows is a gross hack. if (FunctionDecl *FD = dyn_cast<FunctionDecl>(IIDecl)) { - if (FD->getType()->isDependentType()) - return FD; + if (FD->getType()->isDependentType()) { + Template = FD; + return TNK_Function_template; + } } else if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(IIDecl)) { for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(), FEnd = Ovl->function_end(); F != FEnd; ++F) { - if ((*F)->getType()->isDependentType()) - return Ovl; + if ((*F)->getType()->isDependentType()) { + Template = Ovl; + return TNK_Function_template; + } } } } - return 0; + return TNK_Non_template; } /// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining @@ -226,6 +231,15 @@ Sema::ActOnTemplateParameterList(unsigned Depth, (Decl**)Params, NumParams, RAngleLoc); } +Sema::OwningTemplateArgResult Sema::ActOnTypeTemplateArgument(TypeTy *Type) { + return Owned(new (Context) TemplateArg(QualType::getFromOpaquePtr(Type))); +} + +Sema::OwningTemplateArgResult +Sema::ActOnExprTemplateArgument(ExprArg Value) { + return Owned(new (Context) TemplateArg(static_cast<Expr *>(Value.release()))); +} + Sema::DeclTy * Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, SourceLocation KWLoc, const CXXScopeSpec &SS, @@ -351,6 +365,42 @@ Sema::ActOnClassTemplate(Scope *S, unsigned TagSpec, TagKind TK, return NewTemplate; } +Action::TypeTy * +Sema::ActOnClassTemplateSpecialization(DeclTy *TemplateD, + SourceLocation LAngleLoc, + MultiTemplateArgsArg TemplateArgsIn, + SourceLocation RAngleLoc, + const CXXScopeSpec *SS) { + TemplateDecl *Template = cast<TemplateDecl>(static_cast<Decl *>(TemplateD)); + + // FIXME: Not happy about this. We should teach the parser to pass + // us opaque pointers + bools for template argument lists. + // FIXME: Also not happy about the fact that we leak these + // TemplateArg structures. Fixing the above will fix this, too. + llvm::SmallVector<uintptr_t, 16> Args; + llvm::SmallVector<bool, 16> ArgIsType; + unsigned NumArgs = TemplateArgsIn.size(); + TemplateArg **TemplateArgs + = reinterpret_cast<TemplateArg **>(TemplateArgsIn.release()); + for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { + if (Expr *ExprArg = TemplateArgs[Arg]->getAsExpr()) { + Args.push_back(reinterpret_cast<uintptr_t>(ExprArg)); + ArgIsType.push_back(false); + } else { + QualType T = TemplateArgs[Arg]->getAsType(); + Args.push_back(reinterpret_cast<uintptr_t>(T.getAsOpaquePtr())); + ArgIsType.push_back(true); + } + } + + // Yes, all class template specializations are just silly sugar for + // 'int'. Gotta problem wit dat? + return Context.getClassTemplateSpecializationType(Template, NumArgs, + &Args[0], &ArgIsType[0], + Context.IntTy) + .getAsOpaquePtr(); +} + /// \brief Determine whether the given template parameter lists are /// equivalent. /// |