diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 135 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 57 |
11 files changed, 157 insertions, 93 deletions
diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index 0a4e036e439..f00f33fcb94 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/lib/Parse/DeclSpec.cpp @@ -13,6 +13,7 @@ #include "clang/Parse/DeclSpec.h" #include "clang/Parse/ParseDiagnostic.h" +#include "clang/Parse/Template.h" #include "clang/Lex/Preprocessor.h" #include "clang/Basic/LangOptions.h" #include "llvm/ADT/STLExtras.h" @@ -26,6 +27,15 @@ static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc, return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID); } + +void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { + assert(TemplateId && "NULL template-id annotation?"); + Kind = IK_TemplateId; + this->TemplateId = TemplateId; + StartLocation = TemplateId->TemplateNameLoc; + EndLocation = TemplateId->RAngleLoc; +} + /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. /// "TheDeclarator" is the declarator that this will be added to. DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 99752b59507..2bfda30a951 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -14,6 +14,7 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Scope.h" +#include "clang/Parse/Template.h" #include "ExtensionRAIIObject.h" #include "llvm/ADT/SmallSet.h" using namespace clang; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index c006f8bc803..baf9e4ba599 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -16,6 +16,7 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" +#include "clang/Parse/Template.h" #include "ExtensionRAIIObject.h" using namespace clang; @@ -586,13 +587,10 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // Eat the template argument list and try to continue parsing this as // a class (or template thereof). TemplateArgList TemplateArgs; - TemplateArgIsTypeList TemplateArgIsType; - TemplateArgLocationList TemplateArgLocations; SourceLocation LAngleLoc, RAngleLoc; if (ParseTemplateIdAfterTemplateName(TemplateTy(), NameLoc, &SS, true, LAngleLoc, - TemplateArgs, TemplateArgIsType, - TemplateArgLocations, RAngleLoc)) { + TemplateArgs, RAngleLoc)) { // We couldn't parse the template argument list at all, so don't // try to give any location information for the list. LAngleLoc = RAngleLoc = SourceLocation(); @@ -704,7 +702,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // or explicit instantiation. ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateId->getTemplateArgs(), - TemplateId->getTemplateArgIsType(), TemplateId->NumArgs); if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && TUK == Action::TUK_Declaration) { @@ -720,7 +717,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, - TemplateId->getTemplateArgLocations(), TemplateId->RAngleLoc, Attr); } else if (TUK == Action::TUK_Reference) { @@ -729,7 +725,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, - TemplateId->getTemplateArgLocations(), TemplateId->RAngleLoc); TypeResult = Actions.ActOnTagTemplateIdType(TypeResult, TUK, @@ -777,7 +772,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, - TemplateId->getTemplateArgLocations(), TemplateId->RAngleLoc, Attr, Action::MultiTemplateParamsArg(Actions, diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index fa8e64dc125..a7e7648c1f5 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -14,6 +14,7 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" #include "clang/Parse/DeclSpec.h" +#include "clang/Parse/Template.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -814,13 +815,9 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, // Parse the enclosed template argument list. SourceLocation LAngleLoc, RAngleLoc; TemplateArgList TemplateArgs; - TemplateArgIsTypeList TemplateArgIsType; - TemplateArgLocationList TemplateArgLocations; if (ParseTemplateIdAfterTemplateName(Template, Id.StartLocation, &SS, true, LAngleLoc, TemplateArgs, - TemplateArgIsType, - TemplateArgLocations, RAngleLoc)) return true; @@ -845,15 +842,10 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, TemplateId->Kind = TNK; TemplateId->LAngleLoc = LAngleLoc; TemplateId->RAngleLoc = RAngleLoc; - void **Args = TemplateId->getTemplateArgs(); - bool *ArgIsType = TemplateId->getTemplateArgIsType(); - SourceLocation *ArgLocs = TemplateId->getTemplateArgLocations(); + ParsedTemplateArgument *Args = TemplateId->getTemplateArgs(); for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); - Arg != ArgEnd; ++Arg) { + Arg != ArgEnd; ++Arg) Args[Arg] = TemplateArgs[Arg]; - ArgIsType[Arg] = TemplateArgIsType[Arg]; - ArgLocs[Arg] = TemplateArgLocations[Arg]; - } Id.setTemplateId(TemplateId); return false; @@ -861,14 +853,12 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, // Bundle the template arguments together. ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), - TemplateArgIsType.data(), TemplateArgs.size()); // Constructor and destructor names. Action::TypeResult Type = Actions.ActOnTemplateIdType(Template, NameLoc, LAngleLoc, TemplateArgsPtr, - &TemplateArgLocations[0], RAngleLoc); if (Type.isInvalid()) return true; diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 99578837c21..4e7ceaa7c14 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -15,6 +15,7 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" +#include "clang/Parse/Template.h" #include "llvm/Support/Compiler.h" using namespace clang; @@ -582,8 +583,6 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template, bool ConsumeLastToken, SourceLocation &LAngleLoc, TemplateArgList &TemplateArgs, - TemplateArgIsTypeList &TemplateArgIsType, - TemplateArgLocationList &TemplateArgLocations, SourceLocation &RAngleLoc) { assert(Tok.is(tok::less) && "Must have already parsed the template-name"); @@ -595,8 +594,7 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template, { GreaterThanIsOperatorScope G(GreaterThanIsOperator, false); if (Tok.isNot(tok::greater)) - Invalid = ParseTemplateArgumentList(TemplateArgs, TemplateArgIsType, - TemplateArgLocations); + Invalid = ParseTemplateArgumentList(TemplateArgs); if (Invalid) { // Try to find the closing '>'. @@ -688,14 +686,10 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, // Parse the enclosed template argument list. SourceLocation LAngleLoc, RAngleLoc; TemplateArgList TemplateArgs; - TemplateArgIsTypeList TemplateArgIsType; - TemplateArgLocationList TemplateArgLocations; bool Invalid = ParseTemplateIdAfterTemplateName(Template, TemplateNameLoc, SS, false, LAngleLoc, TemplateArgs, - TemplateArgIsType, - TemplateArgLocations, RAngleLoc); if (Invalid) { @@ -707,7 +701,6 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, } ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), - TemplateArgIsType.data(), TemplateArgs.size()); // Build the annotation token. @@ -715,7 +708,6 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, Action::TypeResult Type = Actions.ActOnTemplateIdType(Template, TemplateNameLoc, LAngleLoc, TemplateArgsPtr, - &TemplateArgLocations[0], RAngleLoc); if (Type.isInvalid()) { // If we failed to parse the template ID but skipped ahead to a >, we're not @@ -751,14 +743,9 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, TemplateId->Kind = TNK; TemplateId->LAngleLoc = LAngleLoc; TemplateId->RAngleLoc = RAngleLoc; - void **Args = TemplateId->getTemplateArgs(); - bool *ArgIsType = TemplateId->getTemplateArgIsType(); - SourceLocation *ArgLocs = TemplateId->getTemplateArgLocations(); - for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg) { + ParsedTemplateArgument *Args = TemplateId->getTemplateArgs(); + for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg) Args[Arg] = TemplateArgs[Arg]; - ArgIsType[Arg] = TemplateArgIsType[Arg]; - ArgLocs[Arg] = TemplateArgLocations[Arg]; - } Tok.setAnnotationValue(TemplateId); if (TemplateKWLoc.isValid()) Tok.setLocation(TemplateKWLoc); @@ -794,7 +781,6 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) { ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateId->getTemplateArgs(), - TemplateId->getTemplateArgIsType(), TemplateId->NumArgs); Action::TypeResult Type @@ -802,7 +788,6 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) { TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, - TemplateId->getTemplateArgLocations(), TemplateId->RAngleLoc); // Create the new "type" annotation token. Tok.setKind(tok::annot_typename); @@ -817,33 +802,112 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) { TemplateId->Destroy(); } +/// \brief Determine whether the given token can end a template argument. +static const bool isEndOfTemplateArgument(Token Tok) { + return Tok.is(tok::comma) || Tok.is(tok::greater) || + Tok.is(tok::greatergreater); +} + /// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]). /// /// template-argument: [C++ 14.2] /// constant-expression /// type-id /// id-expression -void *Parser::ParseTemplateArgument(bool &ArgIsType) { +ParsedTemplateArgument Parser::ParseTemplateArgument() { // C++ [temp.arg]p2: // In a template-argument, an ambiguity between a type-id and an // expression is resolved to a type-id, regardless of the form of // the corresponding template-parameter. // - // Therefore, we initially try to parse a type-id. + // Therefore, we initially try to parse a type-id. if (isCXXTypeId(TypeIdAsTemplateArgument)) { - ArgIsType = true; + SourceLocation Loc = Tok.getLocation(); TypeResult TypeArg = ParseTypeName(); if (TypeArg.isInvalid()) - return 0; - return TypeArg.get(); + return ParsedTemplateArgument(); + + return ParsedTemplateArgument(ParsedTemplateArgument::Type, TypeArg.get(), + Loc); } + // C++0x [temp.arg.template]p1: + // A template-argument for a template template-parameter shall be the name + // of a class template or a template alias, expressed as id-expression. + // + // We perform some tentative parsing at this point, to determine whether + // we have an id-expression that refers to a class template or template + // alias. The grammar we tentatively parse is: + // + // nested-name-specifier[opt] template[opt] identifier + // + // followed by a token that terminates a template argument, such as ',', + // '>', or (in some cases) '>>'. + if (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || + Tok.is(tok::annot_cxxscope)) { + TentativeParsingAction TPA(*this); + CXXScopeSpec SS; // nested-name-specifier, if present + ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, + /*EnteringContext=*/false); + + if (SS.isSet() && Tok.is(tok::kw_template)) { + // Parse the optional 'template' keyword following the + // nested-name-specifier. + SourceLocation TemplateLoc = ConsumeToken(); + + if (Tok.is(tok::identifier)) { + // We appear to have a dependent template name. + UnqualifiedId Name; + Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); + ConsumeToken(); // the identifier + + // If the next token signals the end of a template argument, + // then we have a dependent template name that could be a template + // template argument. + if (isEndOfTemplateArgument(Tok)) { + TemplateTy Template + = Actions.ActOnDependentTemplateName(TemplateLoc, SS, Name, + /*ObjectType=*/0); + if (Template.get()) { + TPA.Commit(); + return ParsedTemplateArgument(SS, Template, Name.StartLocation); + } + } + } + } else if (Tok.is(tok::identifier)) { + // We may have a (non-dependent) template name. + TemplateTy Template; + UnqualifiedId Name; + Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); + ConsumeToken(); // the identifier + + if (isEndOfTemplateArgument(Tok)) { + TemplateNameKind TNK = Actions.isTemplateName(CurScope, SS, Name, + /*ObjectType=*/0, + /*EnteringContext=*/false, + Template); + if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) { + // We have an id-expression that refers to a class template or + // (C++0x) template alias. + TPA.Commit(); + return ParsedTemplateArgument(SS, Template, Name.StartLocation); + } + } + } + + // We don't have a template template argument; revert everything we have + // tentatively parsed. + TPA.Revert(); + } + + // Parse a non-type template argument. + SourceLocation Loc = Tok.getLocation(); OwningExprResult ExprArg = ParseConstantExpression(); if (ExprArg.isInvalid() || !ExprArg.get()) - return 0; + return ParsedTemplateArgument(); - ArgIsType = false; - return ExprArg.release(); + return ParsedTemplateArgument(ParsedTemplateArgument::NonType, + ExprArg.release(), Loc); } /// ParseTemplateArgumentList - Parse a C++ template-argument-list @@ -853,22 +917,17 @@ void *Parser::ParseTemplateArgument(bool &ArgIsType) { /// template-argument /// template-argument-list ',' template-argument bool -Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, - TemplateArgIsTypeList &TemplateArgIsType, - TemplateArgLocationList &TemplateArgLocations) { +Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { while (true) { - bool IsType = false; - SourceLocation Loc = Tok.getLocation(); - void *Arg = ParseTemplateArgument(IsType); - if (Arg) { - TemplateArgs.push_back(Arg); - TemplateArgIsType.push_back(IsType); - TemplateArgLocations.push_back(Loc); - } else { + ParsedTemplateArgument Arg = ParseTemplateArgument(); + if (Arg.isInvalid()) { SkipUntil(tok::comma, tok::greater, true, true); return true; } + // Save this template argument. + TemplateArgs.push_back(Arg); + // If the next token is a comma, consume it and keep reading // arguments. if (Tok.isNot(tok::comma)) break; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 335a6cf3625..a9152745b3f 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -15,6 +15,7 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" +#include "clang/Parse/Template.h" #include "llvm/Support/raw_ostream.h" #include "ExtensionRAIIObject.h" #include "ParsePragma.h" diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index b9e8473105f..90f580618a2 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -2472,8 +2472,7 @@ public: AccessSpecifier AS); void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn, - SourceLocation *TemplateArgLocsIn, - llvm::SmallVector<TemplateArgumentLoc, 16> &TempArgs); + llvm::SmallVectorImpl<TemplateArgumentLoc> &TempArgs); QualType CheckTemplateIdType(TemplateName Template, SourceLocation TemplateLoc, @@ -2486,7 +2485,6 @@ public: ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc); virtual TypeResult ActOnTagTemplateIdType(TypeResult Type, @@ -2508,7 +2506,6 @@ public: SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc); virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc, @@ -2529,7 +2526,6 @@ public: SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc, AttributeList *Attr, MultiTemplateParamsArg TemplateParameterLists); @@ -2570,7 +2566,6 @@ public: SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc, AttributeList *Attr); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 8bd934a561f..d1eaa6bb60b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -24,6 +24,7 @@ #include "clang/AST/StmtObjC.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/ParseDiagnostic.h" +#include "clang/Parse/Template.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -1669,7 +1670,7 @@ DeclarationName Sema::GetNameFromUnqualifiedId(UnqualifiedId &Name) { case UnqualifiedId::IK_TemplateId: { TemplateName TName - = TemplateName::getFromVoidPointer(Name.TemplateId->Template); + = TemplateName::getFromVoidPointer(Name.TemplateId->Template); if (TemplateDecl *Template = TName.getAsTemplateDecl()) return Template->getDeclName(); if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl()) @@ -2835,10 +2836,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, TemplateIdAnnotation *TemplateId = D.getName().TemplateId; ASTTemplateArgsPtr TemplateArgsPtr(*this, TemplateId->getTemplateArgs(), - TemplateId->getTemplateArgIsType(), TemplateId->NumArgs); translateTemplateArguments(TemplateArgsPtr, - TemplateId->getTemplateArgLocations(), TemplateArgs); TemplateArgsPtr.release(); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 36f2734a1ad..25d14a70be2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -18,9 +18,10 @@ #include "clang/AST/DeclVisitor.h" #include "clang/AST/TypeOrdering.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Parse/DeclSpec.h" +#include "clang/Parse/Template.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Parse/DeclSpec.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" #include <algorithm> // for std::equal diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ec6ca2a9ac0..c29cfb7c5d2 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -25,6 +25,7 @@ #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Designator.h" #include "clang/Parse/Scope.h" +#include "clang/Parse/Template.h" using namespace clang; @@ -622,14 +623,12 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, if (Name.getKind() == UnqualifiedId::IK_TemplateId) { ASTTemplateArgsPtr TemplateArgsPtr(*this, Name.TemplateId->getTemplateArgs(), - Name.TemplateId->getTemplateArgIsType(), Name.TemplateId->NumArgs); return ActOnTemplateIdExpr(SS, TemplateTy::make(Name.TemplateId->Template), Name.TemplateId->TemplateNameLoc, Name.TemplateId->LAngleLoc, TemplateArgsPtr, - Name.TemplateId->getTemplateArgLocations(), Name.TemplateId->RAngleLoc); } @@ -2501,12 +2500,10 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg Base, // Translate the parser's template argument list in our AST format. ASTTemplateArgsPtr TemplateArgsPtr(*this, Member.TemplateId->getTemplateArgs(), - Member.TemplateId->getTemplateArgIsType(), Member.TemplateId->NumArgs); llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; translateTemplateArguments(TemplateArgsPtr, - Member.TemplateId->getTemplateArgLocations(), TemplateArgs); TemplateArgsPtr.release(); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 0f7106135b2..32a6d6c2438 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -16,6 +16,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/Parse/DeclSpec.h" +#include "clang/Parse/Template.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/PartialDiagnostic.h" #include "llvm/Support/Compiler.h" @@ -1121,22 +1122,44 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, /// \brief Translates template arguments as provided by the parser /// into template arguments used by semantic analysis. void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn, - SourceLocation *TemplateArgLocs, - llvm::SmallVector<TemplateArgumentLoc, 16> &TemplateArgs) { + llvm::SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) { TemplateArgs.reserve(TemplateArgsIn.size()); - void **Args = TemplateArgsIn.getArgs(); - bool *ArgIsType = TemplateArgsIn.getArgIsType(); - for (unsigned Arg = 0, Last = TemplateArgsIn.size(); Arg != Last; ++Arg) { - if (ArgIsType[Arg]) { + for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I) { + const ParsedTemplateArgument &Arg = TemplateArgsIn[I]; + switch (Arg.getKind()) { + case ParsedTemplateArgument::Type: { DeclaratorInfo *DI; - QualType T = Sema::GetTypeFromParser(Args[Arg], &DI); - if (!DI) DI = Context.getTrivialDeclaratorInfo(T, TemplateArgLocs[Arg]); + QualType T = Sema::GetTypeFromParser(Arg.getAsType(), &DI); + if (!DI) DI = Context.getTrivialDeclaratorInfo(T, Arg.getLocation()); TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(T), DI)); - } else { - Expr *E = reinterpret_cast<Expr *>(Args[Arg]); + break; + } + + case ParsedTemplateArgument::NonType: { + Expr *E = static_cast<Expr *>(Arg.getAsExpr()); + TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(E), E)); + break; + } + + case ParsedTemplateArgument::Template: { + TemplateName Template + = TemplateName::getFromVoidPointer(Arg.getAsTemplate().get()); + + // FIXME: This is an egregious hack. We turn a nicely-parsed template name + // into a DeclRefExpr, because that's how we previously parsed template + // template parameters. This will disappear as part of the upcoming + // implementation of template template parameters. + const CXXScopeSpec &SS = Arg.getScopeSpec(); + Expr *E = DeclRefExpr::Create(Context, + (NestedNameSpecifier *)SS.getScopeRep(), + SS.getRange(), + Template.getAsTemplateDecl(), + Arg.getLocation(), + Context.DependentTy, false, false); TemplateArgs.push_back(TemplateArgumentLoc(TemplateArgument(E), E)); } + } } } @@ -1228,13 +1251,12 @@ Action::TypeResult Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, - SourceLocation *TemplateArgLocsIn, SourceLocation RAngleLoc) { TemplateName Template = TemplateD.getAsVal<TemplateName>(); // Translate the parser's template argument list in our AST format. llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; - translateTemplateArguments(TemplateArgsIn, TemplateArgLocsIn, TemplateArgs); + translateTemplateArguments(TemplateArgsIn, TemplateArgs); QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc, TemplateArgs.data(), @@ -1336,13 +1358,12 @@ Sema::OwningExprResult Sema::ActOnTemplateIdExpr(const CXXScopeSpec &SS, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, - SourceLocation *TemplateArgSLs, SourceLocation RAngleLoc) { TemplateName Template = TemplateD.getAsVal<TemplateName>(); // Translate the parser's template argument list in our AST format. llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; - translateTemplateArguments(TemplateArgsIn, TemplateArgSLs, TemplateArgs); + translateTemplateArguments(TemplateArgsIn, TemplateArgs); TemplateArgsIn.release(); return BuildTemplateIdExpr((NestedNameSpecifier *)SS.getScopeRep(), @@ -2803,7 +2824,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc, AttributeList *Attr, MultiTemplateParamsArg TemplateParameterLists) { @@ -2898,7 +2918,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // Translate the parser's template argument list in our AST format. llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; - translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs); + translateTemplateArguments(TemplateArgsIn, TemplateArgs); // Check that the template argument list is well-formed for this // template. @@ -3704,7 +3724,6 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, - SourceLocation *TemplateArgLocs, SourceLocation RAngleLoc, AttributeList *Attr) { // Find the class template we're specializing @@ -3743,7 +3762,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, // Translate the parser's template argument list in our AST format. llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs; - translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs); + translateTemplateArguments(TemplateArgsIn, TemplateArgs); // Check that the template argument list is well-formed for this // template. @@ -4126,10 +4145,8 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S, TemplateIdAnnotation *TemplateId = D.getName().TemplateId; ASTTemplateArgsPtr TemplateArgsPtr(*this, TemplateId->getTemplateArgs(), - TemplateId->getTemplateArgIsType(), TemplateId->NumArgs); translateTemplateArguments(TemplateArgsPtr, - TemplateId->getTemplateArgLocations(), TemplateArgs); HasExplicitTemplateArgs = true; TemplateArgsPtr.release(); |