@@ -134,12 +134,17 @@ namespace clang {
134
134
bool ImportTemplateArguments (const TemplateArgument *FromArgs,
135
135
unsigned NumFromArgs,
136
136
SmallVectorImpl<TemplateArgument> &ToArgs);
137
+ template <typename InContainerTy>
138
+ bool ImportTemplateArgumentListInfo (const InContainerTy &Container,
139
+ TemplateArgumentListInfo &ToTAInfo);
137
140
bool IsStructuralMatch (RecordDecl *FromRecord, RecordDecl *ToRecord,
138
141
bool Complain = true );
139
142
bool IsStructuralMatch (VarDecl *FromVar, VarDecl *ToVar,
140
143
bool Complain = true );
141
144
bool IsStructuralMatch (EnumDecl *FromEnum, EnumDecl *ToRecord);
142
145
bool IsStructuralMatch (EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
146
+ bool IsStructuralMatch (FunctionTemplateDecl *From,
147
+ FunctionTemplateDecl *To);
143
148
bool IsStructuralMatch (ClassTemplateDecl *From, ClassTemplateDecl *To);
144
149
bool IsStructuralMatch (VarTemplateDecl *From, VarTemplateDecl *To);
145
150
Decl *VisitDecl (Decl *D);
@@ -195,6 +200,7 @@ namespace clang {
195
200
ClassTemplateSpecializationDecl *D);
196
201
Decl *VisitVarTemplateDecl (VarTemplateDecl *D);
197
202
Decl *VisitVarTemplateSpecializationDecl (VarTemplateSpecializationDecl *D);
203
+ Decl *VisitFunctionTemplateDecl (FunctionTemplateDecl *D);
198
204
199
205
// Importing statements
200
206
DeclGroupRef ImportDeclGroup (DeclGroupRef DG);
@@ -280,6 +286,7 @@ namespace clang {
280
286
Expr *VisitCXXDeleteExpr (CXXDeleteExpr *E);
281
287
Expr *VisitCXXConstructExpr (CXXConstructExpr *E);
282
288
Expr *VisitCXXMemberCallExpr (CXXMemberCallExpr *E);
289
+ Expr *VisitCXXDependentScopeMemberExpr (CXXDependentScopeMemberExpr *E);
283
290
Expr *VisitExprWithCleanups (ExprWithCleanups *EWC);
284
291
Expr *VisitCXXThisExpr (CXXThisExpr *E);
285
292
Expr *VisitCXXBoolLiteralExpr (CXXBoolLiteralExpr *E);
@@ -1247,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
1247
1254
return false ;
1248
1255
}
1249
1256
1257
+ template <typename InContainerTy>
1258
+ bool ASTNodeImporter::ImportTemplateArgumentListInfo (
1259
+ const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) {
1260
+ for (const auto &FromLoc : Container) {
1261
+ if (auto ToLoc = ImportTemplateArgumentLoc (FromLoc))
1262
+ ToTAInfo.addArgument (*ToLoc);
1263
+ else
1264
+ return true ;
1265
+ }
1266
+ return false ;
1267
+ }
1268
+
1250
1269
bool ASTNodeImporter::IsStructuralMatch (RecordDecl *FromRecord,
1251
1270
RecordDecl *ToRecord, bool Complain) {
1252
1271
// Eliminate a potential failure point where we attempt to re-import
@@ -1280,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
1280
1299
return Ctx.IsStructurallyEquivalent (FromEnum, ToEnum);
1281
1300
}
1282
1301
1302
+ bool ASTNodeImporter::IsStructuralMatch (FunctionTemplateDecl *From,
1303
+ FunctionTemplateDecl *To) {
1304
+ StructuralEquivalenceContext Ctx (
1305
+ Importer.getFromContext (), Importer.getToContext (),
1306
+ Importer.getNonEquivalentDecls (), false , false );
1307
+ return Ctx.IsStructurallyEquivalent (From, To);
1308
+ }
1309
+
1283
1310
bool ASTNodeImporter::IsStructuralMatch (EnumConstantDecl *FromEC,
1284
1311
EnumConstantDecl *ToEC)
1285
1312
{
@@ -4197,6 +4224,64 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
4197
4224
return D2;
4198
4225
}
4199
4226
4227
+ Decl *ASTNodeImporter::VisitFunctionTemplateDecl (FunctionTemplateDecl *D) {
4228
+ DeclContext *DC, *LexicalDC;
4229
+ DeclarationName Name;
4230
+ SourceLocation Loc;
4231
+ NamedDecl *ToD;
4232
+
4233
+ if (ImportDeclParts (D, DC, LexicalDC, Name, ToD, Loc))
4234
+ return nullptr ;
4235
+
4236
+ if (ToD)
4237
+ return ToD;
4238
+
4239
+ // Try to find a function in our own ("to") context with the same name, same
4240
+ // type, and in the same context as the function we're importing.
4241
+ if (!LexicalDC->isFunctionOrMethod ()) {
4242
+ unsigned IDNS = Decl::IDNS_Ordinary;
4243
+ SmallVector<NamedDecl *, 2 > FoundDecls;
4244
+ DC->getRedeclContext ()->localUncachedLookup (Name, FoundDecls);
4245
+ for (unsigned I = 0 , N = FoundDecls.size (); I != N; ++I) {
4246
+ if (!FoundDecls[I]->isInIdentifierNamespace (IDNS))
4247
+ continue ;
4248
+
4249
+ if (FunctionTemplateDecl *FoundFunction =
4250
+ dyn_cast<FunctionTemplateDecl>(FoundDecls[I])) {
4251
+ if (FoundFunction->hasExternalFormalLinkage () &&
4252
+ D->hasExternalFormalLinkage ()) {
4253
+ if (IsStructuralMatch (D, FoundFunction)) {
4254
+ Importer.Imported (D, FoundFunction);
4255
+ // FIXME: Actually try to merge the body and other attributes.
4256
+ return FoundFunction;
4257
+ }
4258
+ }
4259
+ }
4260
+ }
4261
+ }
4262
+
4263
+ TemplateParameterList *Params =
4264
+ ImportTemplateParameterList (D->getTemplateParameters ());
4265
+ if (!Params)
4266
+ return nullptr ;
4267
+
4268
+ FunctionDecl *TemplatedFD =
4269
+ cast_or_null<FunctionDecl>(Importer.Import (D->getTemplatedDecl ()));
4270
+ if (!TemplatedFD)
4271
+ return nullptr ;
4272
+
4273
+ FunctionTemplateDecl *ToFunc = FunctionTemplateDecl::Create (
4274
+ Importer.getToContext (), DC, Loc, Name, Params, TemplatedFD);
4275
+
4276
+ TemplatedFD->setDescribedFunctionTemplate (ToFunc);
4277
+ ToFunc->setAccess (D->getAccess ());
4278
+ ToFunc->setLexicalDeclContext (LexicalDC);
4279
+ Importer.Imported (D, ToFunc);
4280
+
4281
+ LexicalDC->addDeclInternal (ToFunc);
4282
+ return ToFunc;
4283
+ }
4284
+
4200
4285
// ----------------------------------------------------------------------------
4201
4286
// Import Statements
4202
4287
// ----------------------------------------------------------------------------
@@ -5758,6 +5843,47 @@ Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr(
5758
5843
Importer.Import (E->getTildeLoc ()), Storage);
5759
5844
}
5760
5845
5846
+ Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr (
5847
+ CXXDependentScopeMemberExpr *E) {
5848
+ Expr *Base = nullptr ;
5849
+ if (!E->isImplicitAccess ()) {
5850
+ Base = Importer.Import (E->getBase ());
5851
+ if (!Base)
5852
+ return nullptr ;
5853
+ }
5854
+
5855
+ QualType BaseType = Importer.Import (E->getBaseType ());
5856
+ if (BaseType.isNull ())
5857
+ return nullptr ;
5858
+
5859
+ TemplateArgumentListInfo ToTAInfo (Importer.Import (E->getLAngleLoc ()),
5860
+ Importer.Import (E->getRAngleLoc ()));
5861
+ TemplateArgumentListInfo *ResInfo = nullptr ;
5862
+ if (E->hasExplicitTemplateArgs ()) {
5863
+ if (ImportTemplateArgumentListInfo (E->template_arguments (), ToTAInfo))
5864
+ return nullptr ;
5865
+ ResInfo = &ToTAInfo;
5866
+ }
5867
+
5868
+ DeclarationName Name = Importer.Import (E->getMember ());
5869
+ if (!E->getMember ().isEmpty () && Name.isEmpty ())
5870
+ return nullptr ;
5871
+
5872
+ DeclarationNameInfo MemberNameInfo (Name, Importer.Import (E->getMemberLoc ()));
5873
+ // Import additional name location/type info.
5874
+ ImportDeclarationNameLoc (E->getMemberNameInfo (), MemberNameInfo);
5875
+ auto ToFQ = Importer.Import (E->getFirstQualifierFoundInScope ());
5876
+ if (!ToFQ && E->getFirstQualifierFoundInScope ())
5877
+ return nullptr ;
5878
+
5879
+ return CXXDependentScopeMemberExpr::Create (
5880
+ Importer.getToContext (), Base, BaseType, E->isArrow (),
5881
+ Importer.Import (E->getOperatorLoc ()),
5882
+ Importer.Import (E->getQualifierLoc ()),
5883
+ Importer.Import (E->getTemplateKeywordLoc ()),
5884
+ cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo);
5885
+ }
5886
+
5761
5887
Expr *ASTNodeImporter::VisitCallExpr (CallExpr *E) {
5762
5888
QualType T = Importer.Import (E->getType ());
5763
5889
if (T.isNull ())
0 commit comments