[cfe-commits] r80425 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclCXX.h lib/Sema/SemaTemplateInstantiateDecl.cpp
John McCall
rjmccall at apple.com
Sat Aug 29 01:11:14 PDT 2009
Author: rjmccall
Date: Sat Aug 29 03:11:13 2009
New Revision: 80425
URL: http://llvm.org/viewvc/llvm-project?rev=80425&view=rev
Log:
Fix the breakage by handling indirect instantiations. This would be much
improved if there were a consistent name for getInstantiatedFromMemberX()
across all classes. Cheap refactor if someone wants to do it, but let's get the
buildbots happy first.
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=80425&r1=80424&r2=80425&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Aug 29 03:11:13 2009
@@ -1379,6 +1379,10 @@
IntegerType = QualType();
}
public:
+ EnumDecl *getCanonicalDecl() {
+ return cast<EnumDecl>(TagDecl::getCanonicalDecl());
+ }
+
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL, EnumDecl *PrevDecl);
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=80425&r1=80424&r2=80425&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sat Aug 29 03:11:13 2009
@@ -405,8 +405,12 @@
/// reverse_base_class_iterator = Iterator that traverses the base classes
/// of a class in reverse order.
- typedef std::reverse_iterator<base_class_const_iterator>
- reverse_base_class_const_iterator;
+ typedef std::reverse_iterator<base_class_const_iterator>
+ reverse_base_class_const_iterator;
+
+ virtual CXXRecordDecl *getCanonicalDecl() {
+ return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
+ }
static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -712,7 +716,7 @@
return dyn_cast<FunctionDecl>(getDeclContext());
}
-
+
/// viewInheritance - Renders and displays an inheritance diagram
/// for this C++ class and all of its base classes (transitively) using
/// GraphViz.
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80425&r1=80424&r2=80425&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Aug 29 03:11:13 2009
@@ -1166,38 +1166,94 @@
NewInits.data(), NewInits.size());
}
+// TODO: this could be templated if the various decl types used the
+// same method name.
+static bool isInstantiationOf(ClassTemplateDecl *Pattern,
+ ClassTemplateDecl *Instance) {
+ Pattern = Pattern->getCanonicalDecl();
+
+ do {
+ Instance = Instance->getCanonicalDecl();
+ if (Pattern == Instance) return true;
+ Instance = Instance->getInstantiatedFromMemberTemplate();
+ } while (Instance);
+
+ return false;
+}
+
+static bool isInstantiationOf(CXXRecordDecl *Pattern,
+ CXXRecordDecl *Instance) {
+ Pattern = Pattern->getCanonicalDecl();
+
+ do {
+ Instance = Instance->getCanonicalDecl();
+ if (Pattern == Instance) return true;
+ Instance = Instance->getInstantiatedFromMemberClass();
+ } while (Instance);
+
+ return false;
+}
+
+static bool isInstantiationOf(FunctionDecl *Pattern,
+ FunctionDecl *Instance) {
+ Pattern = Pattern->getCanonicalDecl();
+
+ do {
+ Instance = Instance->getCanonicalDecl();
+ if (Pattern == Instance) return true;
+ Instance = Instance->getInstantiatedFromMemberFunction();
+ } while (Instance);
+
+ return false;
+}
+
+static bool isInstantiationOf(EnumDecl *Pattern,
+ EnumDecl *Instance) {
+ Pattern = Pattern->getCanonicalDecl();
+
+ do {
+ Instance = Instance->getCanonicalDecl();
+ if (Pattern == Instance) return true;
+ Instance = Instance->getInstantiatedFromMemberEnum();
+ } while (Instance);
+
+ return false;
+}
+
+static bool isInstantiationOfStaticDataMember(VarDecl *Pattern,
+ VarDecl *Instance) {
+ assert(Instance->isStaticDataMember());
+
+ Pattern = Pattern->getCanonicalDecl();
+
+ do {
+ Instance = Instance->getCanonicalDecl();
+ if (Pattern == Instance) return true;
+ Instance = Instance->getInstantiatedFromStaticDataMember();
+ } while (Instance);
+
+ return false;
+}
+
static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
if (D->getKind() != Other->getKind())
return false;
- if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other)) {
- if (CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass())
- return Pattern->getCanonicalDecl() == D->getCanonicalDecl();
- else
- return false;
- }
+ if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other))
+ return isInstantiationOf(cast<CXXRecordDecl>(D), Record);
- if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Other)) {
- if (FunctionDecl *Pattern = Function->getInstantiatedFromMemberFunction())
- return Pattern->getCanonicalDecl() == D->getCanonicalDecl();
- else
- return false;
- }
+ if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Other))
+ return isInstantiationOf(cast<FunctionDecl>(D), Function);
- if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other)) {
- if (EnumDecl *Pattern = Enum->getInstantiatedFromMemberEnum())
- return Pattern->getCanonicalDecl() == D->getCanonicalDecl();
- else
- return false;
- }
+ if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other))
+ return isInstantiationOf(cast<EnumDecl>(D), Enum);
if (VarDecl *Var = dyn_cast<VarDecl>(Other))
- if (Var->isStaticDataMember()) {
- if (VarDecl *Pattern = Var->getInstantiatedFromStaticDataMember())
- return Pattern->getCanonicalDecl() == D->getCanonicalDecl();
- else
- return false;
- }
+ if (Var->isStaticDataMember())
+ return isInstantiationOfStaticDataMember(cast<VarDecl>(D), Var);
+
+ if (ClassTemplateDecl *Temp = dyn_cast<ClassTemplateDecl>(Other))
+ return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp);
// FIXME: How can we find instantiations of anonymous unions?
@@ -1262,6 +1318,28 @@
return cast<NamedDecl>(CurrentInstantiationScope->getInstantiationOf(D));
}
+ if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D))
+ if (ClassTemplateDecl *ClassTemplate
+ = Record->getDescribedClassTemplate()) {
+ // When the declaration D was parsed, it referred to the current
+ // instantiation. Therefore, look through the current context,
+ // which contains actual instantiations, to find the
+ // instantiation of the "current instantiation" that D refers
+ // to. Alternatively, we could just instantiate the
+ // injected-class-name with the current template arguments, but
+ // such an instantiation is far more expensive.
+ for (DeclContext *DC = CurContext; !DC->isFileContext();
+ DC = DC->getParent()) {
+ if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(DC))
+ if (isInstantiationOf(ClassTemplate, Spec->getSpecializedTemplate()))
+ return Spec;
+ }
+
+ assert(false &&
+ "Unable to find declaration for the current instantiation");
+ }
+
ParentDC = FindInstantiatedContext(ParentDC);
if (!ParentDC) return 0;
@@ -1286,33 +1364,11 @@
ParentDC->decls_begin(),
ParentDC->decls_end());
}
+
assert(Result && "Unable to find instantiation of declaration!");
D = Result;
}
- if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D))
- if (ClassTemplateDecl *ClassTemplate
- = Record->getDescribedClassTemplate()) {
- // When the declaration D was parsed, it referred to the current
- // instantiation. Therefore, look through the current context,
- // which contains actual instantiations, to find the
- // instantiation of the "current instantiation" that D refers
- // to. Alternatively, we could just instantiate the
- // injected-class-name with the current template arguments, but
- // such an instantiation is far more expensive.
- for (DeclContext *DC = CurContext; !DC->isFileContext();
- DC = DC->getParent()) {
- if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(DC))
- if (Spec->getSpecializedTemplate()->getCanonicalDecl()
- == ClassTemplate->getCanonicalDecl())
- return Spec;
- }
-
- assert(false &&
- "Unable to find declaration for the current instantiation");
- }
-
return D;
}
More information about the cfe-commits
mailing list