diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 34 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 3 |
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 |