Implement function template specialization at class scope extension in Microsoft mode. A new AST node is introduced: ClassScopeFunctionSpecialization. This node holds a FunctionDecl that is not yet specialized; then during the class template instantiation the ClassScopeFunctionSpecialization will spawn the actual function specialization.
Example:
template <class T>
class A {
public:
template <class U> void f(U p) { }
template <> void f(int p) { } // <== class scope specialization
};
This extension is necessary to parse MSVC standard C++ headers, MFC and ATL code.
BTW, with this feature in, clang can parse (-fsyntax-only) all the MSVC 2010 standard header files without any error.
llvm-svn: 137573
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 7acc22a..d01e2a1 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -518,6 +518,24 @@
= new (*this) MemberSpecializationInfo(Tmpl, TSK, PointOfInstantiation);
}
+FunctionDecl *ASTContext::getClassScopeSpecializationPattern(
+ const FunctionDecl *FD){
+ assert(FD && "Specialization is 0");
+ llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos
+ = ClassScopeSpecilizationPattern.find(FD);
+ if (Pos == ClassScopeSpecilizationPattern.end())
+ return 0;
+
+ return Pos->second;
+}
+
+void ASTContext::setClassScopeSpecializationPattern(FunctionDecl *FD,
+ FunctionDecl *Pattern) {
+ assert(FD && "Specialization is 0");
+ assert(Pattern && "Class scope specialization pattern is 0");
+ ClassScopeSpecilizationPattern[FD] = Pattern;
+}
+
NamedDecl *
ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) {
llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
@@ -6439,5 +6457,6 @@
+ llvm::capacity_in_bytes(InstantiatedFromUnnamedFieldDecl)
+ llvm::capacity_in_bytes(OverriddenMethods)
+ llvm::capacity_in_bytes(Types)
- + llvm::capacity_in_bytes(VariableArrayTypes);
+ + llvm::capacity_in_bytes(VariableArrayTypes)
+ + llvm::capacity_in_bytes(ClassScopeSpecilizationPattern);
}