aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-09 18:46:07 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-09 18:46:07 +0000
commit55f6b14230c94272efbbcdd89a92224c8db9f225 (patch)
tree988ae940f14f93aac610fbc36d89766e539eab6c /lib/Sema/SemaTemplate.cpp
parent00e68e2cc5ce37cb95beb801cae73c0d1e9dda37 (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.cpp88
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.
///