return ToD;
}
-// Returns the definition for a (forward) declaration of a ClassTemplateDecl, if
+// Returns the definition for a (forward) declaration of a TemplateDecl, if
// it has any definition in the redecl chain.
-static ClassTemplateDecl *getDefinition(ClassTemplateDecl *D) {
- CXXRecordDecl *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
+template <typename T> static auto getTemplateDefinition(T *D) -> T * {
+ assert(D->getTemplatedDecl() && "Should be called on templates only");
+ auto *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
if (!ToTemplatedDef)
return nullptr;
- ClassTemplateDecl *TemplateWithDef =
- ToTemplatedDef->getDescribedClassTemplate();
- return TemplateWithDef;
+ auto *TemplateWithDef = ToTemplatedDef->getDescribedTemplate();
+ return cast_or_null<T>(TemplateWithDef);
}
ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (FoundTemplate) {
if (IsStructuralMatch(D, FoundTemplate)) {
- ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
+ ClassTemplateDecl *TemplateWithDef =
+ getTemplateDefinition(FoundTemplate);
if (D->isThisDeclarationADefinition() && TemplateWithDef) {
return Importer.MapImported(D, TemplateWithDef);
}
// and this time the lookup finds the previous fwd friend class template.
// In this case we must set up the previous decl for the templated decl.
if (!ToTemplated->getPreviousDecl()) {
+ assert(FoundByLookup->getTemplatedDecl() &&
+ "Found decl must have its templated decl set");
CXXRecordDecl *PrevTemplated =
FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
if (ToTemplated != PrevTemplated)
if (ToD)
return ToD;
+ const FunctionTemplateDecl *FoundByLookup = nullptr;
+
// Try to find a function in our own ("to") context with the same name, same
// type, and in the same context as the function we're importing.
+ // FIXME Split this into a separate function.
if (!LexicalDC->isFunctionOrMethod()) {
unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (auto *FoundFunction =
- dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
- if (FoundFunction->hasExternalFormalLinkage() &&
+ if (auto *FoundTemplate = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
+ if (FoundTemplate->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
- if (IsStructuralMatch(D, FoundFunction)) {
- Importer.MapImported(D, FoundFunction);
- // FIXME: Actually try to merge the body and other attributes.
- return FoundFunction;
+ if (IsStructuralMatch(D, FoundTemplate)) {
+ FunctionTemplateDecl *TemplateWithDef =
+ getTemplateDefinition(FoundTemplate);
+ if (D->isThisDeclarationADefinition() && TemplateWithDef) {
+ return Importer.MapImported(D, TemplateWithDef);
+ }
+ FoundByLookup = FoundTemplate;
+ break;
}
+ // TODO: handle conflicting names
}
}
- // TODO: handle conflicting names
}
}
return ToFunc;
TemplatedFD->setDescribedFunctionTemplate(ToFunc);
+
ToFunc->setAccess(D->getAccess());
ToFunc->setLexicalDeclContext(LexicalDC);
-
LexicalDC->addDeclInternal(ToFunc);
+
+ if (FoundByLookup) {
+ auto *Recent =
+ const_cast<FunctionTemplateDecl *>(FoundByLookup->getMostRecentDecl());
+ if (!TemplatedFD->getPreviousDecl()) {
+ assert(FoundByLookup->getTemplatedDecl() &&
+ "Found decl must have its templated decl set");
+ auto *PrevTemplated =
+ FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
+ if (TemplatedFD != PrevTemplated)
+ TemplatedFD->setPreviousDecl(PrevTemplated);
+ }
+ ToFunc->setPreviousDecl(Recent);
+ }
+
return ToFunc;
}
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
RedeclChain, Variable, ,
PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
-// FIXME Enable this test, once we import function templates chains correctly.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
- RedeclChain, FunctionTemplate, DISABLED_,
+ RedeclChain, FunctionTemplate, ,
PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
RedeclChain, ClassTemplate, ,
RedeclChain, Class, , DefinitionShouldBeImportedAsADefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
RedeclChain, Variable, , DefinitionShouldBeImportedAsADefinition)
-// FIXME Enable this test, once we import function templates chains correctly.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
- RedeclChain, FunctionTemplate, DISABLED_,
+ RedeclChain, FunctionTemplate, ,
DefinitionShouldBeImportedAsADefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
RedeclChain, ClassTemplate, , DefinitionShouldBeImportedAsADefinition)
ImportPrototypeAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeAfterImportedPrototype)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportPrototypeAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportPrototypeAfterImportedPrototype)
ImportDefinitionAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportDefinitionAfterImportedPrototype)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportDefinitionAfterImportedPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportDefinitionAfterImportedPrototype)
ImportPrototypeAfterImportedDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeAfterImportedDefinition)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportPrototypeAfterImportedDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportPrototypeAfterImportedDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, , ImportPrototypes)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypes)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_, ImportPrototypes)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportPrototypes)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportPrototypes)
// FIXME This does not pass, possible error with Spec import.
ImportDefinitions)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportDefinitions)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_, ImportDefinitions)
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
+ ImportDefinitions)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportDefinitions)
// FIXME This does not pass, possible error with Spec import.
ImportDefinitionThenPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportDefinitionThenPrototype)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportDefinitionThenPrototype)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportDefinitionThenPrototype)
ImportPrototypeThenDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeThenDefinition)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportPrototypeThenDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
ImportPrototypeThenDefinition)
WholeRedeclChainIsImportedAtOnce)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
WholeRedeclChainIsImportedAtOnce)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
WholeRedeclChainIsImportedAtOnce)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
WholeRedeclChainIsImportedAtOnce)
ImportPrototypeThenProtoAndDefinition)
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
ImportPrototypeThenProtoAndDefinition)
-// FIXME Enable this test, once we import function templates chains correctly.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
- DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate, ,
ImportPrototypeThenProtoAndDefinition)
// FIXME This does not pass, possible error with Spec import.
ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec,
FromTU, functionTemplateDecl(hasName("foo")));
auto *Imported = Import(FromFoo, Lang_CXX);
- // FIXME Currently chains of FunctionTemplateDecls are not implemented.
- //EXPECT_EQ(Imported->getPreviousDecl(), Friend);
- EXPECT_EQ(Imported, Friend);
+ EXPECT_EQ(Imported->getPreviousDecl(), Friend);
}
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,