aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-25 21:45:23 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-25 21:45:23 +0000
commitdb422dffb720ff41d0b60e228f45c685600ffa9e (patch)
tree347abefb53d70d332ac3bdf0fe1097a4c69137a0 /lib
parent699a07d8a0b1579c5178b3baf4bcf9edb6b38108 (diff)
Declarators can now properly represent template-ids, e.g., for
template void f<int>(int); ~~~~~~ Previously, we silently dropped the template arguments. With this change, we now use the template arguments (when available) as the explicitly-specified template arguments used to aid template argument deduction for explicit template instantiations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82806 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/ParseDecl.cpp14
-rw-r--r--lib/Sema/SemaDecl.cpp11
-rw-r--r--lib/Sema/SemaTemplate.cpp34
-rw-r--r--lib/Sema/SemaType.cpp3
4 files changed, 41 insertions, 21 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 9525eb364c..2dac473cc6 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2210,12 +2210,12 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
///
/// id-expression: [C++ 5.1]
/// unqualified-id
-/// qualified-id [TODO]
+/// qualified-id
///
/// unqualified-id: [C++ 5.1]
/// identifier
/// operator-function-id
-/// conversion-function-id [TODO]
+/// conversion-function-id
/// '~' class-name
/// template-id
///
@@ -2254,15 +2254,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
TemplateIdAnnotation *TemplateId
= static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
- // FIXME: Could this template-id name a constructor?
-
- // FIXME: This is an egregious hack, where we silently ignore
- // the specialization (which should be a function template
- // specialization name) and use the name instead. This hack
- // will go away when we have support for function
- // specializations.
- D.SetIdentifier(TemplateId->Name, Tok.getLocation());
- TemplateId->Destroy();
+ D.setTemplateId(TemplateId);
ConsumeToken();
goto PastIdentifier;
} else if (Tok.is(tok::kw_operator)) {
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c9983a8f73..074eb6e149 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1587,6 +1587,17 @@ DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
assert(D.getIdentifier() == 0 && "operator names have no identifier");
return Context.DeclarationNames.getCXXOperatorName(
D.getOverloadedOperator());
+
+ case Declarator::DK_TemplateId: {
+ TemplateName Name
+ = TemplateName::getFromVoidPointer(D.getTemplateId()->Template);
+ if (TemplateDecl *Template = Name.getAsTemplateDecl())
+ return Template->getDeclName();
+ if (OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl())
+ return Ovl->getDeclName();
+
+ return DeclarationName();
+ }
}
assert(false && "Unknown name kind");
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 37fbf45374..27e8edd962 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3409,23 +3409,38 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
return DeclPtrTy();
}
+ // Translate the parser's template argument list in our AST format.
+ bool HasExplicitTemplateArgs = false;
+ llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ if (D.getKind() == Declarator::DK_TemplateId) {
+ TemplateIdAnnotation *TemplateId = D.getTemplateId();
+ ASTTemplateArgsPtr TemplateArgsPtr(*this,
+ TemplateId->getTemplateArgs(),
+ TemplateId->getTemplateArgIsType(),
+ TemplateId->NumArgs);
+ translateTemplateArguments(TemplateArgsPtr,
+ TemplateId->getTemplateArgLocations(),
+ TemplateArgs);
+ HasExplicitTemplateArgs = true;
+ }
+
+
// C++ [temp.explicit]p1:
// A [...] function [...] can be explicitly instantiated from its template.
// A member function [...] of a class template can be explicitly
// instantiated from the member definition associated with its class
// template.
- // FIXME: Implement this!
llvm::SmallVector<FunctionDecl *, 8> Matches;
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
P != PEnd; ++P) {
NamedDecl *Prev = *P;
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) {
- // FIXME: If there were any explicitly-specified template arguments,
- // don't look for Method declarations.
- if (Context.hasSameUnqualifiedType(Method->getType(), R)) {
- Matches.clear();
- Matches.push_back(Method);
- break;
+ if (!HasExplicitTemplateArgs) {
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) {
+ if (Context.hasSameUnqualifiedType(Method->getType(), R)) {
+ Matches.clear();
+ Matches.push_back(Method);
+ break;
+ }
}
}
@@ -3436,7 +3451,8 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult TDK
- = DeduceTemplateArguments(FunTmpl, /*FIXME:*/false, 0, 0,
+ = DeduceTemplateArguments(FunTmpl, HasExplicitTemplateArgs,
+ TemplateArgs.data(), TemplateArgs.size(),
R, Specialization, Info)) {
// FIXME: Keep track of almost-matches?
(void)TDK;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index c297694b9f..d064e3c3ce 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -842,7 +842,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
switch (D.getKind()) {
case Declarator::DK_Abstract:
case Declarator::DK_Normal:
- case Declarator::DK_Operator: {
+ case Declarator::DK_Operator:
+ case Declarator::DK_TemplateId: {
const DeclSpec &DS = D.getDeclSpec();
if (OmittedReturnType) {
// We default to a dependent type initially. Can be modified by