diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 8 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 10 |
5 files changed, 40 insertions, 9 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 385b805113f..c82f6a41147 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -638,6 +638,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // This is an explicit instantiation of a class template. TagOrTempResult = Actions.ActOnExplicitInstantiation(CurScope, + TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, TagType, StartLoc, @@ -734,6 +735,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // TagOrTempResult = Actions.ActOnExplicitInstantiation(CurScope, + TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, TagType, StartLoc, SS, Name, NameLoc, Attr); diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 34cabfd7ade..40de81a883f 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -25,7 +25,8 @@ Parser::ParseDeclarationStartingWithTemplate(unsigned Context, SourceLocation &DeclEnd, AccessSpecifier AS) { if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) - return ParseExplicitInstantiation(ConsumeToken(), DeclEnd); + return ParseExplicitInstantiation(SourceLocation(), ConsumeToken(), + DeclEnd); return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS); } @@ -186,7 +187,6 @@ Parser::ParseSingleDeclarationAfterTemplate( // Parse the declaration specifiers. DeclSpec DS; - // FIXME: Pass TemplateLoc through for explicit template instantiations ParseDeclarationSpecifiers(DS, TemplateInfo, AS); if (Tok.is(tok::semi)) { @@ -871,11 +871,15 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs, /// (C++ [temp.explicit]). /// /// explicit-instantiation: -/// 'template' declaration +/// 'extern' [opt] 'template' declaration +/// +/// Note that the 'extern' is a GNU extension and C++0x feature. Parser::DeclPtrTy -Parser::ParseExplicitInstantiation(SourceLocation TemplateLoc, +Parser::ParseExplicitInstantiation(SourceLocation ExternLoc, + SourceLocation TemplateLoc, SourceLocation &DeclEnd) { return ParseSingleDeclarationAfterTemplate(Declarator::FileContext, - ParsedTemplateInfo(TemplateLoc), + ParsedTemplateInfo(ExternLoc, + TemplateLoc), DeclEnd, AS_none); } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 36d5db599d4..8572d326866 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -391,6 +391,7 @@ void Parser::ParseTranslationUnit() { /// [C++0x] empty-declaration: /// ';' /// +/// [C++0x/GNU] 'extern' 'template' declaration Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration() { DeclPtrTy SingleDecl; switch (Tok.getKind()) { @@ -452,6 +453,20 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration() { SourceLocation DeclEnd; return ParseDeclaration(Declarator::FileContext, DeclEnd); } + case tok::kw_extern: + if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) { + // Extern templates + SourceLocation ExternLoc = ConsumeToken(); + SourceLocation TemplateLoc = ConsumeToken(); + SourceLocation DeclEnd; + return Actions.ConvertDeclToDeclGroup( + ParseExplicitInstantiation(ExternLoc, TemplateLoc, DeclEnd)); + } + + // FIXME: Detect C++ linkage specifications here? + + // Fall through to handle other declarations or function definitions. + default: // We can't tell whether this is a function-definition or declaration yet. return ParseDeclarationOrFunctionDefinition(); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index f1e4968fd2d..78e71bcab8e 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -2454,7 +2454,9 @@ public: Declarator &D); virtual DeclResult - ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, + ActOnExplicitInstantiation(Scope *S, + SourceLocation ExternLoc, + SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, @@ -2467,7 +2469,9 @@ public: AttributeList *Attr); virtual DeclResult - ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, + ActOnExplicitInstantiation(Scope *S, + SourceLocation ExternLoc, + SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 8eaa9fb3975..76b6d7ecaa9 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2849,8 +2849,11 @@ Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, } // Explicit instantiation of a class template specialization +// FIXME: Implement extern template semantics Sema::DeclResult -Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, +Sema::ActOnExplicitInstantiation(Scope *S, + SourceLocation ExternLoc, + SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, @@ -3034,8 +3037,11 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, } // Explicit instantiation of a member class of a class template. +// FIXME: Implement extern template semantics. Sema::DeclResult -Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc, +Sema::ActOnExplicitInstantiation(Scope *S, + SourceLocation ExternLoc, + SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, |