r339018 - [ASTmporter] SourceRange-free function parameter checking for declarations

2018-08-06 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Aug  6 07:38:37 2018
New Revision: 339018

URL: http://llvm.org/viewvc/llvm-project?rev=339018&view=rev
Log:
[ASTmporter] SourceRange-free function parameter checking for declarations

Summary: The previous code which avoided infinite recursion (because of 
reparsing declarations in function parameter lists) contained SourceRange 
dependent code which had some problems when parameter types were coming from 
macros. The new solution is not using macros and therefore much safer. A couple 
of importer problems are fixed in redis and tmux by this fix. Various unittests 
are included.

Reviewers: a.sidorin, r.stahl, a_sidorin

Reviewed By: a_sidorin

Subscribers: cfe-commits, dkrupp, balazske, martong

Differential Revision: https://reviews.llvm.org/D49792

Patch by Zoltan Gera!

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=339018&r1=339017&r2=339018&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Aug  6 07:38:37 2018
@@ -1147,15 +1147,21 @@ bool ASTNodeImporter::ImportDeclParts(Na
   FunctionDecl *FunDecl;
   if (isa(D) && (FunDecl = dyn_cast(OrigDC)) &&
   FunDecl->hasBody()) {
-SourceRange RecR = D->getSourceRange();
-SourceRange BodyR = FunDecl->getBody()->getSourceRange();
-// If RecordDecl is not in Body (it is a param), we bail out.
-if (RecR.isValid() && BodyR.isValid() &&
-(RecR.getBegin() < BodyR.getBegin() ||
- BodyR.getEnd() < RecR.getEnd())) {
-  Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
-  << D->getDeclKindName();
-  return true;
+auto getLeafPointeeType = [](const Type *T) {
+  while (T->isPointerType() || T->isArrayType()) {
+T = T->getPointeeOrArrayElementType();
+  }
+  return T;
+};
+for (const ParmVarDecl *P : FunDecl->parameters()) {
+  const Type *LeafT =
+  getLeafPointeeType(P->getType().getCanonicalType().getTypePtr());
+  auto *RT = dyn_cast(LeafT);
+  if (RT && RT->getDecl() == D) {
+Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
+<< D->getDeclKindName();
+return true;
+  }
 }
   }
 

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=339018&r1=339017&r2=339018&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Aug  6 07:38:37 2018
@@ -989,7 +989,7 @@ TEST_P(ASTImporterTestBase, ImportRecord
"  return 0;"
"}",
Lang_C, "input.c");
-  auto FromVar =
+  auto *FromVar =
   FirstDeclMatcher().match(FromTU, varDecl(hasName("d")));
   ASSERT_TRUE(FromVar);
   auto ToType =
@@ -999,12 +999,41 @@ TEST_P(ASTImporterTestBase, ImportRecord
 
 TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncParams) {
   // This construct is not supported by ASTImporter.
-  Decl *FromTU =
-  getTuDecl("int declToImport(struct data_t{int a;int b;} *d){ return 0; 
}",
-Lang_C, "input.c");
-  auto From = FirstDeclMatcher().match(FromTU, functionDecl());
+  Decl *FromTU = getTuDecl(
+  "int declToImport(struct data_t{int a;int b;} ***d){ return 0; }",
+  Lang_C, "input.c");
+  auto *From = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasName("declToImport")));
   ASSERT_TRUE(From);
-  auto To = Import(From, Lang_C);
+  auto *To = Import(From, Lang_C);
+  EXPECT_EQ(To, nullptr);
+}
+
+TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncFromMacro) {
+  Decl *FromTU = getTuDecl(
+  "#define NONAME_SIZEOF(type) sizeof(struct{type *dummy;}) \n"
+  "int declToImport(){ return NONAME_SIZEOF(int); }",
+  Lang_C, "input.c");
+  auto *From = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasName("declToImport")));
+  ASSERT_TRUE(From);
+  auto *To = Import(From, Lang_C);
+  ASSERT_TRUE(To);
+  EXPECT_TRUE(MatchVerifier().match(
+  To, functionDecl(hasName("declToImport"),
+   hasDescendant(unaryExprOrTypeTraitExpr();
+}
+
+TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncParamsFromMacro) {
+  // This construct is not supported by ASTImporter.
+  Decl *FromTU = getTuDecl(
+  "#define PAIR_STRUCT(type) struct data_t{type a;type b;} \n"
+  "int declToImport(PAIR_STRUCT(int) ***d){ return 0; }",
+  Lang_C, "input.c");
+  auto *From = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasName("declToImport")));
+  ASSERT_TRUE(From);
+  auto *To = Import(From, Lang_C);
   EXPECT_EQ(To, nullptr);
 }
 


r339334 - Add support for importing imaginary literals

2018-08-09 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Aug  9 05:18:07 2018
New Revision: 339334

URL: http://llvm.org/viewvc/llvm-project?rev=339334&view=rev
Log:
Add support for importing imaginary literals

Reviewers: a_sidorin, r.stahl, xazax.hun

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D50428

Modified:
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=339334&r1=339333&r2=339334&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Thu Aug  9 05:18:07 2018
@@ -1975,6 +1975,11 @@ extern const internal::VariadicDynCastAl
 extern const internal::VariadicDynCastAllOfMatcher
 floatLiteral;
 
+/// Matches imaginary literals, which are based on integer and floating
+/// point literals e.g.: 1i, 1.0i
+extern const internal::VariadicDynCastAllOfMatcher
+imaginaryLiteral;
+
 /// Matches user defined literal operator call.
 ///
 /// Example match: "foo"_suffix

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=339334&r1=339333&r2=339334&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Aug  9 05:18:07 2018
@@ -434,6 +434,7 @@ namespace clang {
 Expr *VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
 Expr *VisitIntegerLiteral(IntegerLiteral *E);
 Expr *VisitFloatingLiteral(FloatingLiteral *E);
+Expr *VisitImaginaryLiteral(ImaginaryLiteral *E);
 Expr *VisitCharacterLiteral(CharacterLiteral *E);
 Expr *VisitStringLiteral(StringLiteral *E);
 Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
@@ -5613,6 +5614,18 @@ Expr *ASTNodeImporter::VisitFloatingLite
 Importer.Import(E->getLocation()));
 }
 
+Expr *ASTNodeImporter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+return nullptr;
+
+  Expr *SubE = Importer.Import(E->getSubExpr());
+  if (!SubE)
+return nullptr;
+
+  return new (Importer.getToContext()) ImaginaryLiteral(SubE, T);
+}
+
 Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())

Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=339334&r1=339333&r2=339334&view=diff
==
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Thu Aug  9 05:18:07 2018
@@ -710,6 +710,7 @@ const internal::VariadicDynCastAllOfMatc
 const internal::VariadicDynCastAllOfMatcher
 integerLiteral;
 const internal::VariadicDynCastAllOfMatcher 
floatLiteral;
+const internal::VariadicDynCastAllOfMatcher 
imaginaryLiteral;
 const internal::VariadicDynCastAllOfMatcher
 userDefinedLiteral;
 const internal::VariadicDynCastAllOfMatcher

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=339334&r1=339333&r2=339334&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu Aug  9 05:18:07 2018
@@ -553,6 +553,14 @@ TEST_P(ImportExpr, ImportFloatinglLitera
   floatLiteral(equals(1.0e-5f), hasType(asString("float"));
 }
 
+TEST_P(ImportExpr, ImportImaginaryLiteralExpr) {
+  MatchVerifier Verifier;
+  testImport(
+  "void declToImport() { (void)1.0i; }",
+  Lang_CXX14, "", Lang_CXX14, Verifier,
+  functionDecl(hasDescendant(imaginaryLiteral(;
+}
+
 TEST_P(ImportExpr, ImportCompoundLiteralExpr) {
   MatchVerifier Verifier;
   testImport(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r339336 - Fix structural inequivalency of forward EnumDecl

2018-08-09 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Aug  9 05:36:25 2018
New Revision: 339336

URL: http://llvm.org/viewvc/llvm-project?rev=339336&view=rev
Log:
Fix structural inequivalency of forward EnumDecl

Summary:
Currently we consider one forward declared RecordDecl and another with a
definition equal. We have to do the same in case of enums.

Reviewers: a_sidorin, r.stahl, xazax.hun

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D50444

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=339336&r1=339335&r2=339336&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Thu Aug  9 05:36:25 2018
@@ -1178,6 +1178,14 @@ static bool IsStructurallyEquivalent(Str
 /// Determine structural equivalence of two enums.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  EnumDecl *D1, EnumDecl *D2) {
+
+  // Compare the definitions of these two enums. If either or both are
+  // incomplete (i.e. forward declared), we assume that they are equivalent.
+  D1 = D1->getDefinition();
+  D2 = D2->getDefinition();
+  if (!D1 || !D2)
+return true;
+
   EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
 EC2End = D2->enumerator_end();
   for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=339336&r1=339335&r2=339336&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Thu Aug  9 05:36:25 
2018
@@ -642,6 +642,32 @@ TEST_F(StructuralEquivalenceRecordTest,
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceRecordTest,
+FwdDeclRecordShouldBeEqualWithFwdDeclRecord) {
+  auto t = makeNamedDecls("class foo;", "class foo;", Lang_CXX11);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceRecordTest,
+   FwdDeclRecordShouldBeEqualWithRecordWhichHasDefinition) {
+  auto t =
+  makeNamedDecls("class foo;", "class foo { int A; };", Lang_CXX11);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceRecordTest,
+   RecordShouldBeEqualWithRecordWhichHasDefinition) {
+  auto t = makeNamedDecls("class foo { int A; };", "class foo { int A; };",
+  Lang_CXX11);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceRecordTest, RecordsWithDifferentBody) {
+  auto t = makeNamedDecls("class foo { int B; };", "class foo { int A; };",
+  Lang_CXX11);
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 TEST_F(StructuralEquivalenceTest, CompareSameDeclWithMultiple) {
   auto t = makeNamedDecls(
   "struct A{ }; struct B{ }; void foo(A a, A b);",
@@ -650,5 +676,33 @@ TEST_F(StructuralEquivalenceTest, Compar
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+struct StructuralEquivalenceEnumTest : StructuralEquivalenceTest {};
+
+TEST_F(StructuralEquivalenceEnumTest, FwdDeclEnumShouldBeEqualWithFwdDeclEnum) 
{
+  auto t = makeNamedDecls("enum class foo;", "enum class foo;", Lang_CXX11);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceEnumTest,
+   FwdDeclEnumShouldBeEqualWithEnumWhichHasDefinition) {
+  auto t =
+  makeNamedDecls("enum class foo;", "enum class foo { A };", Lang_CXX11);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceEnumTest,
+   EnumShouldBeEqualWithEnumWhichHasDefinition) {
+  auto t = makeNamedDecls("enum class foo { A };", "enum class foo { A };",
+  Lang_CXX11);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceEnumTest, EnumsWithDifferentBody) {
+  auto t = makeNamedDecls("enum class foo { B };", "enum class foo { A };",
+  Lang_CXX11);
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+
 } // end namespace ast_matchers
 } // end namespace clang


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r340402 - Fix import of class templates partial specialization

2018-08-22 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Aug 22 04:52:14 2018
New Revision: 340402

URL: http://llvm.org/viewvc/llvm-project?rev=340402&view=rev
Log:
Fix import of class templates partial specialization

Summary:
Currently there are several issues with the import of class template
specializations.  (1) Different TUs may have class template specializations
with the same template arguments, but with different set of instantiated
MethodDecls and FieldDecls.  In this patch we provide a fix to merge these
methods and fields.  (2) Currently, we search the partial template
specializations in the set of simple specializations and we add partial
specializations as simple specializations. This is bad, this patch fixes it.

Reviewers: a_sidorin, xazax.hun, r.stahl

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D50451

Modified:
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=340402&r1=340401&r2=340402&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Wed Aug 22 04:52:14 2018
@@ -420,6 +420,25 @@ extern const internal::VariadicDynCastAl
 Decl, ClassTemplateSpecializationDecl>
 classTemplateSpecializationDecl;
 
+/// Matches C++ class template partial specializations.
+///
+/// Given
+/// \code
+///   template
+///   class A {};
+///
+///   template
+///   class A {};
+///
+///   template<>
+///   class A {};
+/// \endcode
+/// classTemplatePartialSpecializationDecl()
+///   matches the specialization \c A but not \c A
+extern const internal::VariadicDynCastAllOfMatcher<
+Decl, ClassTemplatePartialSpecializationDecl>
+classTemplatePartialSpecializationDecl;
+
 /// Matches declarator declarations (field, variable, function
 /// and non-type template parameter declarations).
 ///

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=340402&r1=340401&r2=340402&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Aug 22 04:52:14 2018
@@ -2890,6 +2890,22 @@ Decl *ASTNodeImporter::VisitFieldDecl(Fi
   if (Importer.IsStructurallyEquivalent(D->getType(),
 FoundField->getType())) {
 Importer.MapImported(D, FoundField);
+// In case of a FieldDecl of a ClassTemplateSpecializationDecl, the
+// initializer of a FieldDecl might not had been instantiated in the
+// "To" context.  However, the "From" context might instantiated that,
+// thus we have to merge that.
+if (Expr *FromInitializer = D->getInClassInitializer()) {
+  // We don't have yet the initializer set.
+  if (FoundField->hasInClassInitializer() &&
+  !FoundField->getInClassInitializer()) {
+Expr *ToInitializer = Importer.Import(FromInitializer);
+if (!ToInitializer)
+  // We can't return a nullptr here,
+  // since we already mapped D as imported.
+  return FoundField;
+FoundField->setInClassInitializer(ToInitializer);
+  }
+}
 return FoundField;
   }
 
@@ -4544,27 +4560,50 @@ Decl *ASTNodeImporter::VisitClassTemplat
 
   // Try to find an existing specialization with these template arguments.
   void *InsertPos = nullptr;
-  ClassTemplateSpecializationDecl *D2
-= ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
-  if (D2) {
-// We already have a class template specialization with these template
-// arguments.
-
-// FIXME: Check for specialization vs. instantiation errors.
-
-if (RecordDecl *FoundDef = D2->getDefinition()) {
-  if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) {
-// The record types structurally match, or the "from" translation
-// unit only had a forward declaration anyway; call it the same
-// function.
-return Importer.MapImported(D, FoundDef);
-  }
-}
-  } else {
-// Create a new specialization.
-if (auto *PartialSpec =
-dyn_cast(D)) {
-  // Import TemplateArgumentListInfo
+  ClassTemplateSpecializationDecl *D2 = nullptr;
+  ClassTemplatePartialSpecializationDecl *PartialSpec =
+dyn_cast(D);
+  if (PartialSpec)
+D2 = ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
+  else
+D2 = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
+  ClassTemplateSpecializationDecl * const PrevDecl

r332454 - Test commit access: remove superflous spaces

2018-05-16 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed May 16 04:48:11 2018
New Revision: 332454

URL: http://llvm.org/viewvc/llvm-project?rev=332454&view=rev
Log:
Test commit access: remove superflous spaces

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=332454&r1=332453&r2=332454&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed May 16 04:48:11 2018
@@ -78,7 +78,7 @@ namespace clang {
 
   public:
 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
-
+
 using TypeVisitor::Visit;
 using DeclVisitor::Visit;
 using StmtVisitor::Visit;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r332588 - [ASTImporter] Fix missing implict CXXRecordDecl

2018-05-17 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu May 17 02:46:07 2018
New Revision: 332588

URL: http://llvm.org/viewvc/llvm-project?rev=332588&view=rev
Log:
[ASTImporter] Fix missing implict CXXRecordDecl

Summary:
Implicit CXXRecordDecl is not added to its DeclContext during import, but in
the original AST it is. This patch fixes this.

Reviewers: xazax.hun, a.sidorin, szepet

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D46958

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=332588&r1=332587&r2=332588&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu May 17 02:46:07 2018
@@ -2110,7 +2110,7 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
   D2 = D2CXX;
   D2->setAccess(D->getAccess());
   D2->setLexicalDeclContext(LexicalDC);
-  if (!DCXX->getDescribedClassTemplate())
+  if (!DCXX->getDescribedClassTemplate() || DCXX->isImplicit())
 LexicalDC->addDeclInternal(D2);
 
   Importer.Imported(D, D2);

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=332588&r1=332587&r2=332588&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu May 17 02:46:07 2018
@@ -1348,7 +1348,7 @@ TEST_P(ASTImporterTestBase,
   Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"};
 }
 
-TEST_P(ASTImporterTestBase, DISABLED_ShouldImportImplicitCXXRecordDecl) {
+TEST_P(ASTImporterTestBase, ShouldImportImplicitCXXRecordDecl) {
   Decl *From, *To;
   std::tie(From, To) = getImportedDecl(
   R"(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r332699 - Do not try to remove invisible Decls from DeclContext

2018-05-18 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri May 18 02:08:47 2018
New Revision: 332699

URL: http://llvm.org/viewvc/llvm-project?rev=332699&view=rev
Log:
Do not try to remove invisible Decls from DeclContext

Modified:
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=332699&r1=332698&r2=332699&view=diff
==
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri May 18 02:08:47 2018
@@ -1347,6 +1347,32 @@ bool DeclContext::containsDecl(Decl *D)
   (D->NextInContextAndBits.getPointer() || D == LastDecl));
 }
 
+/// shouldBeHidden - Determine whether a declaration which was declared
+/// within its semantic context should be invisible to qualified name lookup.
+static bool shouldBeHidden(NamedDecl *D) {
+  // Skip unnamed declarations.
+  if (!D->getDeclName())
+return true;
+
+  // Skip entities that can't be found by name lookup into a particular
+  // context.
+  if ((D->getIdentifierNamespace() == 0 && !isa(D)) ||
+  D->isTemplateParameter())
+return true;
+
+  // Skip template specializations.
+  // FIXME: This feels like a hack. Should DeclarationName support
+  // template-ids, or is there a better way to keep specializations
+  // from being visible?
+  if (isa(D))
+return true;
+  if (auto *FD = dyn_cast(D))
+if (FD->isFunctionTemplateSpecialization())
+  return true;
+
+  return false;
+}
+
 void DeclContext::removeDecl(Decl *D) {
   assert(D->getLexicalDeclContext() == this &&
  "decl being removed from non-lexical context");
@@ -1369,7 +1395,7 @@ void DeclContext::removeDecl(Decl *D) {
   }
 }
   }
-  
+
   // Mark that D is no longer in the decl chain.
   D->NextInContextAndBits.setPointer(nullptr);
 
@@ -1377,8 +1403,14 @@ void DeclContext::removeDecl(Decl *D) {
   if (isa(D)) {
 auto *ND = cast(D);
 
+// Do not try to remove the declaration if that is invisible to qualified
+// lookup.  E.g. template specializations are skipped.
+if (shouldBeHidden(ND))
+  return;
+
 // Remove only decls that have a name
-if (!ND->getDeclName()) return;
+if (!ND->getDeclName())
+  return;
 
 auto *DC = D->getDeclContext();
 do {
@@ -1435,32 +1467,6 @@ void DeclContext::addDeclInternal(Decl *
 makeDeclVisibleInContextWithFlags(ND, true, true);
 }
 
-/// shouldBeHidden - Determine whether a declaration which was declared
-/// within its semantic context should be invisible to qualified name lookup.
-static bool shouldBeHidden(NamedDecl *D) {
-  // Skip unnamed declarations.
-  if (!D->getDeclName())
-return true;
-
-  // Skip entities that can't be found by name lookup into a particular
-  // context.
-  if ((D->getIdentifierNamespace() == 0 && !isa(D)) ||
-  D->isTemplateParameter())
-return true;
-
-  // Skip template specializations.
-  // FIXME: This feels like a hack. Should DeclarationName support
-  // template-ids, or is there a better way to keep specializations
-  // from being visible?
-  if (isa(D))
-return true;
-  if (auto *FD = dyn_cast(D))
-if (FD->isFunctionTemplateSpecialization())
-  return true;
-
-  return false;
-}
-
 /// buildLookup - Build the lookup data structure with all of the
 /// declarations in this DeclContext (and any other contexts linked
 /// to it or transparent contexts nested within it) and return it.

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=332699&r1=332698&r2=332699&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Fri May 18 02:08:47 2018
@@ -1797,5 +1797,38 @@ TEST(ImportExpr, UnresolvedMemberExpr) {
  compoundStmt(has(callExpr(has(unresolvedMemberExpr());
 }
 
+struct DeclContextTest : ASTImporterTestBase {};
+
+TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
+  Decl *TU = getTuDecl(
+  R"(
+  namespace NS {
+
+  template 
+  struct S {};
+  template struct S;
+
+  inline namespace INS {
+template 
+struct S {};
+template struct S;
+  }
+
+  }
+  )", Lang_CXX11, "input0.cc");
+  auto *NS = FirstDeclMatcher().match(
+  TU, namespaceDecl());
+  auto *Spec = FirstDeclMatcher().match(
+  TU, classTemplateSpecializationDecl());
+  ASSERT_TRUE(NS->containsDecl(Spec));
+
+  NS->removeDecl(Spec);
+  EXPECT_FALSE(NS->containsDecl(Spec));
+}
+
+INSTANTIATE_TEST_CASE_P(
+ParameterizedTests, DeclContextTest,
+::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),);
+
 } // end namespace ast_matchers
 } // end namespace clang



r332728 - [ASTImporter] Enable disabled but passing test

2018-05-18 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri May 18 08:46:18 2018
New Revision: 332728

URL: http://llvm.org/viewvc/llvm-project?rev=332728&view=rev
Log:
[ASTImporter] Enable disabled but passing test

Summary:
There is a test which passes since D32947, but it was forgotten to be enabled.
This patch enables that disabled test.

Reviewers: a.sidorin, r.stahl, xazax.hun

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D47069

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=332728&r1=332727&r2=332728&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Fri May 18 08:46:18 2018
@@ -1399,7 +1399,7 @@ TEST_P(ASTImporterTestBase, IDNSOrdinary
   EXPECT_EQ(From->getIdentifierNamespace(), To->getIdentifierNamespace());
 }
 
-TEST_P(ASTImporterTestBase, DISABLED_IDNSOfNonmemberOperator) {
+TEST_P(ASTImporterTestBase, IDNSOfNonmemberOperator) {
   Decl *FromTU = getTuDecl(
   R"(
   struct X {};


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r333086 - [ASTImporter] Fix missing implict CXXRecordDecl in ClassTemplateSpecializationDecl

2018-05-23 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed May 23 07:24:02 2018
New Revision: 333086

URL: http://llvm.org/viewvc/llvm-project?rev=333086&view=rev
Log:
[ASTImporter] Fix missing implict CXXRecordDecl in 
ClassTemplateSpecializationDecl

Summary:
Currently we do not import the implicit CXXRecordDecl of a
ClassTemplateSpecializationDecl. This patch fixes it.

Reviewers: a.sidorin, xazax.hun, r.stahl

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D47057

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=333086&r1=333085&r2=333086&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed May 23 07:24:02 2018
@@ -1959,14 +1959,20 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
   // but this particular declaration is not that definition, import the
   // definition and map to that.
   TagDecl *Definition = D->getDefinition();
-  if (Definition && Definition != D) {
+  if (Definition && Definition != D &&
+  // In contrast to a normal CXXRecordDecl, the implicit
+  // CXXRecordDecl of ClassTemplateSpecializationDecl is its redeclaration.
+  // The definition of the implicit CXXRecordDecl in this case is the
+  // ClassTemplateSpecializationDecl itself. Thus, we start with an extra
+  // condition in order to be able to import the implict Decl.
+  !D->isImplicit()) {
 Decl *ImportedDef = Importer.Import(Definition);
 if (!ImportedDef)
   return nullptr;
 
 return Importer.Imported(D, ImportedDef);
   }
-  
+
   // Import the major distinguishing characteristics of this record.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=333086&r1=333085&r2=333086&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Wed May 23 07:24:02 2018
@@ -1363,6 +1363,22 @@ TEST_P(ASTImporterTestBase, ShouldImport
   Decl *From, *To;
   std::tie(From, To) = getImportedDecl(
   R"(
+  struct declToImport {
+  };
+  )",
+  Lang_CXX, "", Lang_CXX);
+
+  MatchVerifier Verifier;
+  // Match the implicit Decl.
+  auto Matcher = cxxRecordDecl(has(cxxRecordDecl()));
+  ASSERT_TRUE(Verifier.match(From, Matcher));
+  EXPECT_TRUE(Verifier.match(To, Matcher));
+}
+
+TEST_P(ASTImporterTestBase, ShouldImportImplicitCXXRecordDeclOfClassTemplate) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+  R"(
   template 
   struct declToImport {
   };
@@ -1378,7 +1394,7 @@ TEST_P(ASTImporterTestBase, ShouldImport
 
 TEST_P(
 ASTImporterTestBase,
-
DISABLED_ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) {
+ShouldImportImplicitCXXRecordDeclOfClassTemplateSpecializationDecl) {
   Decl *From, *To;
   std::tie(From, To) = getImportedDecl(
   R"(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r333082 - Fix duplicate class template definitions problem

2018-05-23 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed May 23 06:53:36 2018
New Revision: 333082

URL: http://llvm.org/viewvc/llvm-project?rev=333082&view=rev
Log:
Fix duplicate class template definitions problem

Summary:
We fail to import a `ClassTemplateDecl` if the "To" context already
contains a definition and then a forward decl.  This is because
`localUncachedLookup` does not find the definition.  This is not a
lookup error, the parser behaves differently than assumed in the
importer code.  A `DeclContext` contains one DenseMap (`LookupPtr`)
which maps names to lists.  The list is a special list `StoredDeclsList`
which is optimized to have one element.  During building the initial
AST, the parser first adds the definition to the `DeclContext`.  Then
during parsing the second declaration (the forward decl) the parser
again calls `DeclContext::addDecl` but that will not add a new element
to the `StoredDeclsList` rarther it simply overwrites the old element
with the most recent one.  This patch fixes the error by finding the
definition in the redecl chain.  Added tests for the same issue with
`CXXRecordDecl` and with `ClassTemplateSpecializationDecl`.  These tests
pass and they pass because in `VisitRecordDecl` and in
`VisitClassTemplateSpecializationDecl` we already use
`D->getDefinition()` after the lookup.

Reviewers: a.sidorin, xazax.hun, szepet

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D46950

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/DeclMatcher.h

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=333082&r1=333081&r2=333082&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed May 23 06:53:36 2018
@@ -4070,6 +4070,17 @@ ASTNodeImporter::VisitTemplateTemplatePa
   TemplateParams);
 }
 
+// Returns the definition for a (forward) declaration of a ClassTemplateDecl, 
if
+// it has any definition in the redecl chain.
+static ClassTemplateDecl *getDefinition(ClassTemplateDecl *D) {
+  CXXRecordDecl *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
+  if (!ToTemplatedDef)
+return nullptr;
+  ClassTemplateDecl *TemplateWithDef =
+  ToTemplatedDef->getDescribedClassTemplate();
+  return TemplateWithDef;
+}
+
 Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   // If this record has a definition in the translation unit we're coming from,
   // but this particular declaration is not that definition, import the
@@ -4084,7 +4095,7 @@ Decl *ASTNodeImporter::VisitClassTemplat
 
 return Importer.Imported(D, ImportedDef);
   }
-  
+
   // Import the major distinguishing characteristics of this class template.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
@@ -4103,34 +4114,39 @@ Decl *ASTNodeImporter::VisitClassTemplat
 for (auto *FoundDecl : FoundDecls) {
   if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
 continue;
-  
+
   Decl *Found = FoundDecl;
   if (auto *FoundTemplate = dyn_cast(Found)) {
-if (IsStructuralMatch(D, FoundTemplate)) {
-  // The class templates structurally match; call it the same template.
 
-  // We found a forward declaration but the class to be imported has a
-  // definition.
-  // FIXME Add this forward declaration to the redeclaration chain.
-  if (D->isThisDeclarationADefinition() &&
-  !FoundTemplate->isThisDeclarationADefinition())
+// The class to be imported is a definition.
+if (D->isThisDeclarationADefinition()) {
+  // Lookup will find the fwd decl only if that is more recent than the
+  // definition. So, try to get the definition if that is available in
+  // the redecl chain.
+  ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
+  if (!TemplateWithDef)
 continue;
+  FoundTemplate = TemplateWithDef; // Continue with the definition.
+}
 
-  Importer.Imported(D->getTemplatedDecl(), 
+if (IsStructuralMatch(D, FoundTemplate)) {
+  // The class templates structurally match; call it the same template.
+
+  Importer.Imported(D->getTemplatedDecl(),
 FoundTemplate->getTemplatedDecl());
   return Importer.Imported(D, FoundTemplate);
-} 
+}
   }
-  
+
   ConflictingDecls.push_back(FoundDecl);
 }
-
+
 if (!ConflictingDecls.empty()) {
   Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
- ConflictingDecls.data(), 
+ ConflictingDecls.data(),
  Conflic

r333166 - [ASTImporter] Add unit tests for structural equivalence

2018-05-24 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu May 24 01:41:07 2018
New Revision: 333166

URL: http://llvm.org/viewvc/llvm-project?rev=333166&view=rev
Log:
[ASTImporter] Add unit tests for structural equivalence

Summary:
This patch add new tests for structural equivalence. For that a new
common header is created which holds the test related language specific
types and functions.

Reviewers: a.sidorin, xazax.hun, szepet

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D46867

Added:
cfe/trunk/unittests/AST/Language.cpp
cfe/trunk/unittests/AST/Language.h
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/CMakeLists.txt
cfe/trunk/unittests/AST/MatchVerifier.h

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=333166&r1=333165&r2=333166&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu May 24 01:41:07 2018
@@ -19,6 +19,7 @@
 #include "clang/Tooling/Tooling.h"
 
 #include "DeclMatcher.h"
+#include "Language.h"
 #include "gtest/gtest.h"
 #include "llvm/ADT/StringMap.h"
 
@@ -29,50 +30,6 @@ using internal::Matcher;
 using internal::BindableMatcher;
 using llvm::StringMap;
 
-typedef std::vector ArgVector;
-typedef std::vector RunOptions;
-
-static bool isCXX(Language Lang) {
-  return Lang == Lang_CXX || Lang == Lang_CXX11;
-}
-
-static ArgVector getBasicRunOptionsForLanguage(Language Lang) {
-  ArgVector BasicArgs;
-  // Test with basic arguments.
-  switch (Lang) {
-  case Lang_C:
-BasicArgs = {"-x", "c", "-std=c99"};
-break;
-  case Lang_C89:
-BasicArgs = {"-x", "c", "-std=c89"};
-break;
-  case Lang_CXX:
-BasicArgs = {"-std=c++98", "-frtti"};
-break;
-  case Lang_CXX11:
-BasicArgs = {"-std=c++11", "-frtti"};
-break;
-  case Lang_OpenCL:
-  case Lang_OBJCXX:
-llvm_unreachable("Not implemented yet!");
-  }
-  return BasicArgs;
-}
-
-static RunOptions getRunOptionsForLanguage(Language Lang) {
-  ArgVector BasicArgs = getBasicRunOptionsForLanguage(Lang);
-
-  // For C++, test with "-fdelayed-template-parsing" enabled to handle MSVC
-  // default behaviour.
-  if (isCXX(Lang)) {
-ArgVector ArgsForDelayedTemplateParse = BasicArgs;
-ArgsForDelayedTemplateParse.emplace_back("-fdelayed-template-parsing");
-return {BasicArgs, ArgsForDelayedTemplateParse};
-  }
-
-  return {BasicArgs};
-}
-
 // Creates a virtual file and assigns that to the context of given AST. If the
 // file already exists then the file will not be created again as a duplicate.
 static void

Modified: cfe/trunk/unittests/AST/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CMakeLists.txt?rev=333166&r1=333165&r2=333166&view=diff
==
--- cfe/trunk/unittests/AST/CMakeLists.txt (original)
+++ cfe/trunk/unittests/AST/CMakeLists.txt Thu May 24 01:41:07 2018
@@ -15,9 +15,11 @@ add_clang_unittest(ASTTests
   DeclTest.cpp
   EvaluateAsRValueTest.cpp
   ExternalASTSourceTest.cpp
+  Language.cpp
   NamedDeclPrinterTest.cpp
   SourceLocationTest.cpp
   StmtPrinterTest.cpp
+  StructuralEquivalenceTest.cpp
   )
 
 target_link_libraries(ASTTests

Added: cfe/trunk/unittests/AST/Language.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/Language.cpp?rev=333166&view=auto
==
--- cfe/trunk/unittests/AST/Language.cpp (added)
+++ cfe/trunk/unittests/AST/Language.cpp Thu May 24 01:41:07 2018
@@ -0,0 +1,60 @@
+//===-- unittest/AST/Language.cpp - AST unit test support 
-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+//  This file defines language options for AST unittests.
+//
+//===--===//
+
+#include "Language.h"
+
+namespace clang {
+namespace ast_matchers {
+
+ArgVector getBasicRunOptionsForLanguage(Language Lang) {
+  ArgVector BasicArgs;
+  // Test with basic arguments.
+  switch (Lang) {
+  case Lang_C:
+BasicArgs = {"-x", "c", "-std=c99"};
+break;
+  case Lang_C89:
+BasicArgs = {"-x", "c", "-std=c89"};
+break;
+  case Lang_CXX:
+BasicArgs = {"-std=c++98", "-frtti"};
+break;
+  case Lang_CXX11:
+BasicArgs = {"-std=c++11", "-frtti"};
+break;
+  case Lang_CXX14:
+BasicArgs = {"-std=c++14", "-frtti"};
+break;
+  case Lang_OpenCL:
+  case Lang_OBJCXX:
+llvm_unreachable("Not implemented yet!");
+  }
+  return

r333269 - [ASTImporter] Fix ClassTemplateSpecialization in wrong DC

2018-05-25 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri May 25 04:21:24 2018
New Revision: 333269

URL: http://llvm.org/viewvc/llvm-project?rev=333269&view=rev
Log:
[ASTImporter] Fix ClassTemplateSpecialization in wrong DC

Summary:
ClassTemplateSpecialization is put in the wrong DeclContex if implicitly
instantiated. This patch fixes it.

Reviewers: a.sidorin, r.stahl, xazax.hun

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D47058

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=333269&r1=333268&r2=333269&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Fri May 25 04:21:24 2018
@@ -4320,9 +4320,13 @@ Decl *ASTNodeImporter::VisitClassTemplat
 
 D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
 
-// Add the specialization to this context.
+// Set the context of this specialization/instantiation.
 D2->setLexicalDeclContext(LexicalDC);
-LexicalDC->addDeclInternal(D2);
+
+// Add to the DC only if it was an explicit specialization/instantiation.
+if (D2->isExplicitInstantiationOrSpecialization()) {
+  LexicalDC->addDeclInternal(D2);
+}
   }
   Importer.Imported(D, D2);
   if (D->isCompleteDefinition() && ImportDefinition(D, D2))

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=333269&r1=333268&r2=333269&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Fri May 25 04:21:24 2018
@@ -1214,7 +1214,7 @@ TEST_P(ASTImporterTestBase, TUshouldNotC
 
 TEST_P(
 ASTImporterTestBase,
-
DISABLED_TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {
+TUshouldNotContainClassTemplateSpecializationOfImplicitInstantiation) {
 
   Decl *From, *To;
   std::tie(From, To) = getImportedDecl(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r333522 - [ASTImporter] Corrected lookup at import of templated record decl

2018-05-30 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed May 30 02:19:26 2018
New Revision: 333522

URL: http://llvm.org/viewvc/llvm-project?rev=333522&view=rev
Log:
[ASTImporter] Corrected lookup at import of templated record decl

Summary:
When a CXXRecordDecl under ClassTemplateDecl is imported, check
the templated record decl for similarity instead of the template.

Reviewers: a.sidorin

Reviewed By: a.sidorin

Subscribers: martong, cfe-commits

Differential Revision: https://reviews.llvm.org/D47313

Patch by Balazs Keri!

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=333522&r1=333521&r2=333522&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed May 30 02:19:26 2018
@@ -2015,7 +2015,14 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
 if (const auto *Tag = Typedef->getUnderlyingType()->getAs())
   Found = Tag->getDecl();
   }
-  
+
+  if (D->getDescribedTemplate()) {
+if (auto *Template = dyn_cast(Found))
+  Found = Template->getTemplatedDecl();
+else
+  continue;
+  }
+
   if (auto *FoundRecord = dyn_cast(Found)) {
 if (!SearchName) {
   // If both unnamed structs/unions are in a record context, make sure

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=333522&r1=333521&r2=333522&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Wed May 30 02:19:26 2018
@@ -1107,6 +1107,50 @@ TEST(ImportExpr, DependentSizedArrayType
  has(fieldDecl(hasType(dependentSizedArrayType(;
 }
 
+TEST_P(ASTImporterTestBase, ImportOfTemplatedDeclOfClassTemplateDecl) {
+  Decl *FromTU = getTuDecl("template struct S{};", Lang_CXX);
+  auto From =
+  FirstDeclMatcher().match(FromTU, classTemplateDecl());
+  ASSERT_TRUE(From);
+  auto To = cast(Import(From, Lang_CXX));
+  ASSERT_TRUE(To);
+  Decl *ToTemplated = To->getTemplatedDecl();
+  Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX);
+  EXPECT_TRUE(ToTemplated1);
+  EXPECT_EQ(ToTemplated1, ToTemplated);
+}
+
+TEST_P(ASTImporterTestBase, ImportCorrectTemplatedDecl) {
+  auto Code =
+R"(
+namespace x {
+  template struct S1{};
+  template struct S2{};
+  template struct S3{};
+}
+)";
+  Decl *FromTU = getTuDecl(Code, Lang_CXX);
+  auto FromNs =
+  FirstDeclMatcher().match(FromTU, namespaceDecl());
+  auto ToNs = cast(Import(FromNs, Lang_CXX));
+  ASSERT_TRUE(ToNs);
+  auto From =
+  FirstDeclMatcher().match(FromTU,
+  classTemplateDecl(
+  hasName("S2")));
+  auto To =
+  FirstDeclMatcher().match(ToNs,
+  classTemplateDecl(
+  hasName("S2")));
+  ASSERT_TRUE(From);
+  ASSERT_TRUE(To);
+  auto ToTemplated = To->getTemplatedDecl();
+  auto ToTemplated1 =
+  cast(Import(From->getTemplatedDecl(), Lang_CXX));
+  EXPECT_TRUE(ToTemplated1);
+  ASSERT_EQ(ToTemplated1, ToTemplated);
+}
+
 TEST_P(ASTImporterTestBase, DISABLED_ImportFunctionWithBackReferringParameter) 
{
   Decl *From, *To;
   std::tie(From, To) = getImportedDecl(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r341316 - [ASTImporter] Merge ExprBits

2018-09-03 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Sep  3 06:10:53 2018
New Revision: 341316

URL: http://llvm.org/viewvc/llvm-project?rev=341316&view=rev
Log:
[ASTImporter] Merge ExprBits

Summary:
Some `Expr` classes set up default values for the `ExprBits` of `Stmt`.  These
default values are then overwritten by the parser sometimes.  One example is
`InitListExpr` which sets the value kind to be an rvalue in the ctor.  However,
this bit may change after the `InitListExpr` is created.  There may be other
expressions similar to `InitListExpr` in this sense, thus the safest solution
is to copy the expression bits.

The lack of copying `ExprBits` causes an assertion in the analyzer engine in a
specific case: Since the value kind is not imported, the analyzer engine
believes that the given InitListExpr is an rvalue, thus it creates a
nonloc::CompoundVal instead of creating memory region (as in case of an lvalue
reference).

Reviewers: a_sidorin, r.stahl, xazax.hun, a.sidorin

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D51533

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=341316&r1=341315&r2=341316&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Sep  3 06:10:53 2018
@@ -6817,9 +6817,9 @@ Expr *ASTNodeImporter::VisitInitListExpr
 To->setSyntacticForm(ToSyntForm);
   }
 
+  // Copy InitListExprBitfields, which are not handled in the ctor of
+  // InitListExpr.
   To->sawArrayRangeDesignator(ILE->hadArrayRangeDesignator());
-  To->setValueDependent(ILE->isValueDependent());
-  To->setInstantiationDependent(ILE->isInstantiationDependent());
 
   return To;
 }
@@ -7164,6 +7164,19 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
   if (!ToS)
 return nullptr;
 
+  if (auto *ToE = dyn_cast(ToS)) {
+auto *FromE = cast(FromS);
+// Copy ExprBitfields, which may not be handled in Expr subclasses
+// constructors.
+ToE->setValueKind(FromE->getValueKind());
+ToE->setObjectKind(FromE->getObjectKind());
+ToE->setTypeDependent(FromE->isTypeDependent());
+ToE->setValueDependent(FromE->isValueDependent());
+ToE->setInstantiationDependent(FromE->isInstantiationDependent());
+ToE->setContainsUnexpandedParameterPack(
+FromE->containsUnexpandedParameterPack());
+  }
+
   // Record the imported declaration.
   ImportedStmts[FromS] = ToS;
   return ToS;

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=341316&r1=341315&r2=341316&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Sep  3 06:10:53 2018
@@ -3225,6 +3225,25 @@ TEST_P(ASTImporterTestBase, ClassTemplat
   
unless(classTemplatePartialSpecializationDecl();
 }
 
+TEST_P(ASTImporterTestBase, InitListExprValueKindShouldBeImported) {
+  Decl *TU = getTuDecl(
+  R"(
+  const int &init();
+  void foo() { const int &a{init()}; }
+  )", Lang_CXX11, "input0.cc");
+  auto *FromD = FirstDeclMatcher().match(TU, varDecl(hasName("a")));
+  ASSERT_TRUE(FromD->getAnyInitializer());
+  auto *InitExpr = FromD->getAnyInitializer();
+  ASSERT_TRUE(InitExpr);
+  ASSERT_TRUE(InitExpr->isGLValue());
+
+  auto *ToD = Import(FromD, Lang_CXX11);
+  EXPECT_TRUE(ToD);
+  auto *ToInitExpr = cast(ToD)->getAnyInitializer();
+  EXPECT_TRUE(ToInitExpr);
+  EXPECT_TRUE(ToInitExpr->isGLValue());
+}
+
 struct DeclContextTest : ASTImporterTestBase {};
 
 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r345496 - [ASTImporter] Import overrides before importing the rest of the chain

2018-10-29 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Oct 29 03:18:28 2018
New Revision: 345496

URL: http://llvm.org/viewvc/llvm-project?rev=345496&view=rev
Log:
[ASTImporter] Import overrides before importing the rest of the chain

Summary:
During method import we check for structural eq of two methods.
In the structural eq check we check for their isVirtual() flag. That
flag, however, may depend on the number of overrides. Before this
change we imported the overrides *after* we had imported the rest of the
redecl chain.  So, during the import of another decl from the chain
IsVirtual() gave false result.

Writing tests for this is not really possible, because there is no way
to remove an overridden method via the AST API.
(We should access the private ASTContext::OverriddenMethods container.)
Also, we should do the remove in the middle of the import process.

Reviewers: a_sidorin, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53704

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=345496&r1=345495&r2=345496&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Oct 29 03:18:28 2018
@@ -3258,6 +3258,9 @@ ExpectedDecl ASTNodeImporter::VisitFunct
 DC->makeDeclVisibleInContext(ToFunction);
   }
 
+  if (auto *FromCXXMethod = dyn_cast(D))
+ImportOverrides(cast(ToFunction), FromCXXMethod);
+
   // Import the rest of the chain. I.e. import all subsequent declarations.
   for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt) {
 ExpectedDecl ToRedeclOrErr = import(*RedeclIt);
@@ -3265,9 +3268,6 @@ ExpectedDecl ASTNodeImporter::VisitFunct
   return ToRedeclOrErr.takeError();
   }
 
-  if (auto *FromCXXMethod = dyn_cast(D))
-ImportOverrides(cast(ToFunction), FromCXXMethod);
-
   return ToFunction;
 }
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r352050 - [ASTImporter] Fix inequality of functions with different attributes

2019-01-24 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jan 24 06:47:44 2019
New Revision: 352050

URL: http://llvm.org/viewvc/llvm-project?rev=352050&view=rev
Log:
[ASTImporter] Fix inequality of functions with different attributes

Summary:
FunctionType::ExtInfo holds such properties of a function which are needed
mostly for code gen. We should not compare these bits when checking for
structural equivalency.
Checking ExtInfo caused false ODR errors during CTU analysis (of tmux).

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53699

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=352050&r1=352049&r2=352050&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Thu Jan 24 06:47:44 2019
@@ -296,6 +296,32 @@ static bool IsArrayStructurallyEquivalen
   return true;
 }
 
+/// Determine structural equivalence based on the ExtInfo of functions. This
+/// is inspired by ASTContext::mergeFunctionTypes(), we compare calling
+/// conventions bits but must not compare some other bits.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ FunctionType::ExtInfo EI1,
+ FunctionType::ExtInfo EI2) {
+  // Compatible functions must have compatible calling conventions.
+  if (EI1.getCC() != EI2.getCC())
+return false;
+
+  // Regparm is part of the calling convention.
+  if (EI1.getHasRegParm() != EI2.getHasRegParm())
+return false;
+  if (EI1.getRegParm() != EI2.getRegParm())
+return false;
+
+  if (EI1.getProducesResult() != EI2.getProducesResult())
+return false;
+  if (EI1.getNoCallerSavedRegs() != EI2.getNoCallerSavedRegs())
+return false;
+  if (EI1.getNoCfCheck() != EI2.getNoCfCheck())
+return false;
+
+  return true;
+}
+
 /// Determine structural equivalence of two types.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  QualType T1, QualType T2) {
@@ -539,7 +565,8 @@ static bool IsStructurallyEquivalent(Str
 if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
   Function2->getReturnType()))
   return false;
-if (Function1->getExtInfo() != Function2->getExtInfo())
+if (!IsStructurallyEquivalent(Context, Function1->getExtInfo(),
+  Function2->getExtInfo()))
   return false;
 break;
   }

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=352050&r1=352049&r2=352050&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Thu Jan 24 06:47:44 
2019
@@ -370,6 +370,31 @@ TEST_F(StructuralEquivalenceFunctionTest
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentNoreturnAttr) {
+  auto t = makeNamedDecls(
+  "__attribute__((noreturn)) void foo();",
+  "  void foo();",
+  Lang_C);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceFunctionTest,
+FunctionsWithDifferentCallingConventions) {
+  auto t = makeNamedDecls(
+  "__attribute__((fastcall)) void foo();",
+  "__attribute__((ms_abi))   void foo();",
+  Lang_C);
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) 
{
+  auto t = makeNamedDecls(
+  "__attribute__((no_caller_saved_registers)) void foo();",
+  "   void foo();",
+  Lang_C);
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
 };
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r352055 - Fix failing buildbots

2019-01-24 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jan 24 07:42:20 2019
New Revision: 352055

URL: http://llvm.org/viewvc/llvm-project?rev=352055&view=rev
Log:
Fix failing buildbots

Related commit which caused the buildbots to fail:
rL352050

Modified:
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=352055&r1=352054&r2=352055&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Thu Jan 24 07:42:20 
2019
@@ -378,14 +378,17 @@ TEST_F(StructuralEquivalenceFunctionTest
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
+// These calling conventions may not be available on certain platforms.
+#if defined(__x86_64__) && defined(__linux__)
 TEST_F(StructuralEquivalenceFunctionTest,
 FunctionsWithDifferentCallingConventions) {
   auto t = makeNamedDecls(
-  "__attribute__((fastcall)) void foo();",
+  "__attribute__((preserve_all)) void foo();",
   "__attribute__((ms_abi))   void foo();",
   Lang_C);
   EXPECT_FALSE(testStructuralMatch(t));
 }
+#endif
 
 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) 
{
   auto t = makeNamedDecls(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r352060 - Fix failing buildbots

2019-01-24 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jan 24 08:27:21 2019
New Revision: 352060

URL: http://llvm.org/viewvc/llvm-project?rev=352060&view=rev
Log:
Fix failing buildbots

Fix remaining unittest errors caused by
__attribute__((no_caller_saved_registers))
Related commit which caused the buildbots to fail:
rL352050

Modified:
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=352060&r1=352059&r2=352060&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Thu Jan 24 08:27:21 
2019
@@ -378,7 +378,7 @@ TEST_F(StructuralEquivalenceFunctionTest
   EXPECT_TRUE(testStructuralMatch(t));
 }
 
-// These calling conventions may not be available on certain platforms.
+// These attributes may not be available on certain platforms.
 #if defined(__x86_64__) && defined(__linux__)
 TEST_F(StructuralEquivalenceFunctionTest,
 FunctionsWithDifferentCallingConventions) {
@@ -388,7 +388,6 @@ TEST_F(StructuralEquivalenceFunctionTest
   Lang_C);
   EXPECT_FALSE(testStructuralMatch(t));
 }
-#endif
 
 TEST_F(StructuralEquivalenceFunctionTest, FunctionsWithDifferentSavedRegsAttr) 
{
   auto t = makeNamedDecls(
@@ -397,6 +396,7 @@ TEST_F(StructuralEquivalenceFunctionTest
   Lang_C);
   EXPECT_FALSE(testStructuralMatch(t));
 }
+#endif
 
 struct StructuralEquivalenceCXXMethodTest : StructuralEquivalenceTest {
 };


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r352345 - [AST] Add structural eq tests for template args

2019-01-28 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jan 28 02:01:11 2019
New Revision: 352345

URL: http://llvm.org/viewvc/llvm-project?rev=352345&view=rev
Log:
[AST] Add structural eq tests for template args

Summary:
New tests added to verify equivalency of templates when their
parameters are different.

Reviewers: a_sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D57235

Modified:
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=352345&r1=352344&r2=352345&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Mon Jan 28 02:01:11 
2019
@@ -802,6 +802,25 @@ TEST_F(StructuralEquivalenceEnumTest, En
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+struct StructuralEquivalenceTemplateTest : StructuralEquivalenceTest {};
+
+TEST_F(StructuralEquivalenceTemplateTest, ExactlySameTemplates) {
+  auto t = makeNamedDecls("template  struct foo;",
+  "template  struct foo;", Lang_CXX);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgName) {
+  auto t = makeNamedDecls("template  struct foo;",
+  "template  struct foo;", Lang_CXX);
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
+  auto t = makeNamedDecls("template  struct foo;",
+  "template  struct foo;", Lang_CXX);
+  EXPECT_FALSE(testStructuralMatch(t));
+}
 
 } // end namespace ast_matchers
 } // end namespace clang


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r345760 - [ASTImporter][Structural Eq] Check for isBeingDefined

2018-10-31 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Oct 31 11:46:13 2018
New Revision: 345760

URL: http://llvm.org/viewvc/llvm-project?rev=345760&view=rev
Log:
[ASTImporter][Structural Eq] Check for isBeingDefined

Summary:
If one definition is currently being defined, we do not compare for
equality and we assume that the decls are equal.

Reviewers: a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53697

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=345760&r1=345759&r2=345760&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Wed Oct 31 11:46:13 2018
@@ -1016,7 +1016,8 @@ static bool IsStructurallyEquivalent(Str
 return false;
 
   // Compare the definitions of these two records. If either or both are
-  // incomplete, we assume that they are equivalent.
+  // incomplete (i.e. it is a forward decl), we assume that they are
+  // equivalent.
   D1 = D1->getDefinition();
   D2 = D2->getDefinition();
   if (!D1 || !D2)
@@ -1031,6 +1032,11 @@ static bool IsStructurallyEquivalent(Str
 if (D1->hasExternalLexicalStorage() || D2->hasExternalLexicalStorage())
   return true;
 
+  // If one definition is currently being defined, we do not compare for
+  // equality and we assume that the decls are equal.
+  if (D1->isBeingDefined() || D2->isBeingDefined())
+return true;
+
   if (auto *D1CXX = dyn_cast(D1)) {
 if (auto *D2CXX = dyn_cast(D2)) {
   if (D1CXX->hasExternalLexicalStorage() &&

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=345760&r1=345759&r2=345760&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Wed Oct 31 11:46:13 2018
@@ -3726,6 +3726,45 @@ TEST_P(ImportFunctionTemplateSpecializat
   EXPECT_EQ(To1->getPreviousDecl(), To0);
 }
 
+TEST_P(ASTImporterTestBase,
+ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) {
+  {
+Decl *FromTU = getTuDecl(
+R"(
+template 
+struct B;
+)",
+Lang_CXX, "input0.cc");
+auto *FromD = FirstDeclMatcher().match(
+FromTU, classTemplateDecl(hasName("B")));
+
+Import(FromD, Lang_CXX);
+  }
+
+  {
+Decl *FromTU = getTuDecl(
+R"(
+template 
+struct B {
+  void f();
+  B* b;
+};
+)",
+Lang_CXX, "input1.cc");
+FunctionDecl *FromD = FirstDeclMatcher().match(
+FromTU, functionDecl(hasName("f")));
+Import(FromD, Lang_CXX);
+auto *FromCTD = FirstDeclMatcher().match(
+FromTU, classTemplateDecl(hasName("B")));
+auto *ToCTD = cast(Import(FromCTD, Lang_CXX));
+EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
+
+// We expect no (ODR) warning during the import.
+auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
+  }
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest,
 ::testing::Values(ArgVector()), );
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r347306 - [ASTImporter] Set redecl chain of functions before any other import

2018-11-20 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Nov 20 06:19:39 2018
New Revision: 347306

URL: http://llvm.org/viewvc/llvm-project?rev=347306&view=rev
Log:
[ASTImporter] Set redecl chain of functions before any other import

Summary:
FunctionDecl import starts with a lookup and then we create a new Decl.
Then in case of CXXConstructorDecl we further import other Decls
(base classes, members through CXXConstructorDecl::inits()) before connecting
the redecl chain.  During those in-between imports structural eq fails
because the canonical decl is different.  This commit fixes this.
Synthesizing a test seemed extremely hard, however, Xerces analysis
reproduces the problem.

Reviewers: a_sidorin, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53702

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=347306&r1=347305&r2=347306&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Nov 20 06:19:39 2018
@@ -3144,19 +3144,6 @@ ExpectedDecl ASTNodeImporter::VisitFunct
 FromConstructor->isExplicit(),
 D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
   return ToFunction;
-if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
-  SmallVector CtorInitializers(NumInitializers);
-  // Import first, then allocate memory and copy if there was no error.
-  if (Error Err = ImportContainerChecked(
-  FromConstructor->inits(), CtorInitializers))
-return std::move(Err);
-  auto **Memory =
-  new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
-  std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
-  auto *ToCtor = cast(ToFunction);
-  ToCtor->setCtorInitializers(Memory);
-  ToCtor->setNumCtorInitializers(NumInitializers);
-}
   } else if (isa(D)) {
 if (GetImportedOrCreateDecl(
 ToFunction, D, Importer.getToContext(), cast(DC),
@@ -3184,6 +3171,30 @@ ExpectedDecl ASTNodeImporter::VisitFunct
   return ToFunction;
   }
 
+  // Connect the redecl chain.
+  if (FoundByLookup) {
+auto *Recent = const_cast(
+  FoundByLookup->getMostRecentDecl());
+ToFunction->setPreviousDecl(Recent);
+  }
+
+  // Import Ctor initializers.
+  if (auto *FromConstructor = dyn_cast(D)) {
+if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
+  SmallVector CtorInitializers(NumInitializers);
+  // Import first, then allocate memory and copy if there was no error.
+  if (Error Err = ImportContainerChecked(
+  FromConstructor->inits(), CtorInitializers))
+return std::move(Err);
+  auto **Memory =
+  new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
+  std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
+  auto *ToCtor = cast(ToFunction);
+  ToCtor->setCtorInitializers(Memory);
+  ToCtor->setNumCtorInitializers(NumInitializers);
+}
+  }
+
   ToFunction->setQualifierInfo(ToQualifierLoc);
   ToFunction->setAccess(D->getAccess());
   ToFunction->setLexicalDeclContext(LexicalDC);
@@ -3199,12 +3210,6 @@ ExpectedDecl ASTNodeImporter::VisitFunct
   }
   ToFunction->setParams(Parameters);
 
-  if (FoundByLookup) {
-auto *Recent = const_cast(
-  FoundByLookup->getMostRecentDecl());
-ToFunction->setPreviousDecl(Recent);
-  }
-
   // We need to complete creation of FunctionProtoTypeLoc manually with setting
   // params it refers to.
   if (TInfo) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r347564 - [ASTImporter][Structural Eq] Check for isBeingDefined

2018-11-26 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Nov 26 07:54:08 2018
New Revision: 347564

URL: http://llvm.org/viewvc/llvm-project?rev=347564&view=rev
Log:
[ASTImporter][Structural Eq] Check for isBeingDefined

Summary:
If one definition is currently being defined, we do not compare for
equality and we assume that the decls are equal.

Reviewers: a_sidorin, a.sidorin, shafik

Reviewed By: a_sidorin

Subscribers: gamesh411, shafik, rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53697

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=347564&r1=347563&r2=347564&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Nov 26 07:54:08 2018
@@ -1740,8 +1740,9 @@ Error ASTNodeImporter::ImportDefinition(
 return Err;
 
   // Add base classes.
-  if (auto *ToCXX = dyn_cast(To)) {
-auto *FromCXX = cast(From);
+  auto *ToCXX = dyn_cast(To);
+  auto *FromCXX = dyn_cast(From);
+  if (ToCXX && FromCXX && ToCXX->dataPtr() && FromCXX->dataPtr()) {
 
 struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();
 struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=347564&r1=347563&r2=347564&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Mon Nov 26 07:54:08 2018
@@ -1016,7 +1016,8 @@ static bool IsStructurallyEquivalent(Str
 return false;
 
   // Compare the definitions of these two records. If either or both are
-  // incomplete, we assume that they are equivalent.
+  // incomplete (i.e. it is a forward decl), we assume that they are
+  // equivalent.
   D1 = D1->getDefinition();
   D2 = D2->getDefinition();
   if (!D1 || !D2)
@@ -1031,6 +1032,11 @@ static bool IsStructurallyEquivalent(Str
 if (D1->hasExternalLexicalStorage() || D2->hasExternalLexicalStorage())
   return true;
 
+  // If one definition is currently being defined, we do not compare for
+  // equality and we assume that the decls are equal.
+  if (D1->isBeingDefined() || D2->isBeingDefined())
+return true;
+
   if (auto *D1CXX = dyn_cast(D1)) {
 if (auto *D2CXX = dyn_cast(D2)) {
   if (D1CXX->hasExternalLexicalStorage() &&

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=347564&r1=347563&r2=347564&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Nov 26 07:54:08 2018
@@ -3725,6 +3725,45 @@ TEST_P(ImportFunctionTemplateSpecializat
   EXPECT_EQ(To1->getPreviousDecl(), To0);
 }
 
+TEST_P(ASTImporterTestBase,
+ImportShouldNotReportFalseODRErrorWhenRecordIsBeingDefined) {
+  {
+Decl *FromTU = getTuDecl(
+R"(
+template 
+struct B;
+)",
+Lang_CXX, "input0.cc");
+auto *FromD = FirstDeclMatcher().match(
+FromTU, classTemplateDecl(hasName("B")));
+
+Import(FromD, Lang_CXX);
+  }
+
+  {
+Decl *FromTU = getTuDecl(
+R"(
+template 
+struct B {
+  void f();
+  B* b;
+};
+)",
+Lang_CXX, "input1.cc");
+FunctionDecl *FromD = FirstDeclMatcher().match(
+FromTU, functionDecl(hasName("f")));
+Import(FromD, Lang_CXX);
+auto *FromCTD = FirstDeclMatcher().match(
+FromTU, classTemplateDecl(hasName("B")));
+auto *ToCTD = cast(Import(FromCTD, Lang_CXX));
+EXPECT_TRUE(ToCTD->isThisDeclarationADefinition());
+
+// We expect no (ODR) warning during the import.
+auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
+  }
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest,
 ::testing::Values(ArgVector()), );
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r347648 - [ASTImporter] Typedef import brings in the complete type

2018-11-27 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Nov 27 01:51:36 2018
New Revision: 347648

URL: http://llvm.org/viewvc/llvm-project?rev=347648&view=rev
Log:
[ASTImporter] Typedef import brings in the complete type

Summary:
When we already have an incomplete underlying type of a typedef in the
"To" context, and the "From" context has the same typedef, but the
underlying type is complete, then the imported type should be complete.

Fixes an assertion in CTU analysis of Xerces:
Assertion `DD && "queried property of class with no definition"' failed.
This assert is happening in the analyzer engine, because that attempts
to query an underlying type of a typedef, which happens to be
incomplete.

Reviewers: a_sidorin, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53693

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=347648&r1=347647&r2=347648&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Nov 27 01:51:36 2018
@@ -2311,9 +2311,16 @@ ASTNodeImporter::VisitTypedefNameDecl(Ty
   if (!FoundDecl->isInIdentifierNamespace(IDNS))
 continue;
   if (auto *FoundTypedef = dyn_cast(FoundDecl)) {
-if (Importer.IsStructurallyEquivalent(
-D->getUnderlyingType(), FoundTypedef->getUnderlyingType()))
+QualType FromUT = D->getUnderlyingType();
+QualType FoundUT = FoundTypedef->getUnderlyingType();
+if (Importer.IsStructurallyEquivalent(FromUT, FoundUT)) {
+  // If the "From" context has a complete underlying type but we
+  // already have a complete underlying type then return with that.
+  if (!FromUT->isIncompleteType() && !FoundUT->isIncompleteType())
 return Importer.MapImported(D, FoundTypedef);
+}
+// FIXME Handle redecl chain.
+break;
   }
 
   ConflictingDecls.push_back(FoundDecl);

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=347648&r1=347647&r2=347648&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Tue Nov 27 01:51:36 2018
@@ -3764,6 +3764,38 @@ TEST_P(ASTImporterTestBase,
   }
 }
 
+TEST_P(ASTImporterTestBase, ImportingTypedefShouldImportTheCompleteType) {
+  // We already have an incomplete underlying type in the "To" context.
+  auto Code =
+  R"(
+  template 
+  struct S {
+void foo();
+  };
+  using U = S;
+  )";
+  Decl *ToTU = getToTuDecl(Code, Lang_CXX11);
+  auto *ToD = FirstDeclMatcher().match(ToTU,
+  typedefNameDecl(hasName("U")));
+  ASSERT_TRUE(ToD->getUnderlyingType()->isIncompleteType());
+
+  // The "From" context has the same typedef, but the underlying type is
+  // complete this time.
+  Decl *FromTU = getTuDecl(std::string(Code) +
+  R"(
+  void foo(U* u) {
+u->foo();
+  }
+  )", Lang_CXX11);
+  auto *FromD = FirstDeclMatcher().match(FromTU,
+  typedefNameDecl(hasName("U")));
+  ASSERT_FALSE(FromD->getUnderlyingType()->isIncompleteType());
+
+  // The imported type should be complete.
+  auto *ImportedD = cast(Import(FromD, Lang_CXX11));
+  EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType());
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, DeclContextTest,
 ::testing::Values(ArgVector()), );
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r348584 - [CTU] Add statistics

2018-12-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Dec  7 03:55:22 2018
New Revision: 348584

URL: http://llvm.org/viewvc/llvm-project?rev=348584&view=rev
Log:
[CTU] Add statistics

Reviewers: xazax.hun, a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D55133

Modified:
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp

Modified: cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp?rev=348584&r1=348583&r2=348584&view=diff
==
--- cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp (original)
+++ cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp Fri Dec  7 03:55:22 2018
@@ -21,6 +21,7 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Index/USRGeneration.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Path.h"
@@ -32,6 +33,15 @@ namespace clang {
 namespace cross_tu {
 
 namespace {
+#define DEBUG_TYPE "CrossTranslationUnit"
+STATISTIC(NumGetCTUCalled, "The # of getCTUDefinition function called");
+STATISTIC(
+NumNotInOtherTU,
+"The # of getCTUDefinition called but the function is not in any other 
TU");
+STATISTIC(NumGetCTUSuccess,
+  "The # of getCTUDefinition successfully returned the "
+  "requested function's body");
+
 // FIXME: This class is will be removed after the transition to llvm::Error.
 class IndexErrorCategory : public std::error_category {
 public:
@@ -151,6 +161,7 @@ CrossTranslationUnitContext::getCrossTUD
   StringRef CrossTUDir,
   StringRef IndexName) {
   assert(!FD->hasBody() && "FD has a definition in current translation unit!");
+  ++NumGetCTUCalled;
   const std::string LookupFnName = getLookupName(FD);
   if (LookupFnName.empty())
 return llvm::make_error(
@@ -216,8 +227,10 @@ llvm::Expected CrossTranslati
 }
 
 auto It = FunctionFileMap.find(LookupName);
-if (It == FunctionFileMap.end())
+if (It == FunctionFileMap.end()) {
+  ++NumNotInOtherTU;
   return 
llvm::make_error(index_error_code::missing_definition);
+}
 StringRef ASTFileName = It->second;
 auto ASTCacheEntry = FileASTUnitMap.find(ASTFileName);
 if (ASTCacheEntry == FileASTUnitMap.end()) {
@@ -250,6 +263,7 @@ CrossTranslationUnitContext::importDefin
   cast(Importer.Import(const_cast(FD)));
   assert(ToDecl->hasBody());
   assert(FD->hasBody() && "Functions already imported should have body.");
+  ++NumGetCTUSuccess;
   return ToDecl;
 }
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r348586 - [CTU] Add asserts to protect invariants

2018-12-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Dec  7 04:21:43 2018
New Revision: 348586

URL: http://llvm.org/viewvc/llvm-project?rev=348586&view=rev
Log:
[CTU] Add asserts to protect invariants

Reviewers: xazax.hun, a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D55132

Modified:
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp

Modified: cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp?rev=348586&r1=348585&r2=348586&view=diff
==
--- cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp (original)
+++ cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp Fri Dec  7 04:21:43 2018
@@ -160,6 +160,7 @@ llvm::Expected
 CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
   StringRef CrossTUDir,
   StringRef IndexName) {
+  assert(FD && "FD is missing, bad call to this function!");
   assert(!FD->hasBody() && "FD has a definition in current translation unit!");
   ++NumGetCTUCalled;
   const std::string LookupFnName = getLookupName(FD);
@@ -258,6 +259,8 @@ llvm::Expected CrossTranslati
 
 llvm::Expected
 CrossTranslationUnitContext::importDefinition(const FunctionDecl *FD) {
+  assert(FD->hasBody() && "Functions to be imported should have body.");
+
   ASTImporter &Importer = getOrCreateASTImporter(FD->getASTContext());
   auto *ToDecl =
   cast(Importer.Import(const_cast(FD)));


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r348587 - [CTU] Eliminate race condition in CTU lit tests

2018-12-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Dec  7 04:29:02 2018
New Revision: 348587

URL: http://llvm.org/viewvc/llvm-project?rev=348587&view=rev
Log:
[CTU] Eliminate race condition in CTU lit tests

Summary:
We plan to introduce additional CTU related lit test. Since lit may run the
tests in parallel, it is not safe to use the same directory (%T) for these
tests. It is safe to use however test case specific directories (%t).

Reviewers: xazax.hun, a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D55129

Modified:
cfe/trunk/test/Analysis/ctu-main.cpp

Modified: cfe/trunk/test/Analysis/ctu-main.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctu-main.cpp?rev=348587&r1=348586&r2=348587&view=diff
==
--- cfe/trunk/test/Analysis/ctu-main.cpp (original)
+++ cfe/trunk/test/Analysis/ctu-main.cpp Fri Dec  7 04:29:02 2018
@@ -1,8 +1,15 @@
-// RUN: mkdir -p %T/ctudir
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-pch -o 
%T/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-pch -o 
%T/ctudir/ctu-chain.cpp.ast %S/Inputs/ctu-chain.cpp
-// RUN: cp %S/Inputs/externalFnMap.txt %T/ctudir/
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -analyze 
-analyzer-checker=core,debug.ExprInspection -analyzer-config 
experimental-enable-naive-ctu-analysis=true -analyzer-config ctu-dir=%T/ctudir 
-verify %s
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-chain.cpp.ast %S/Inputs/ctu-chain.cpp
+// RUN: cp %S/Inputs/externalFnMap.txt %t/ctudir/
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -verify %s
 
 #include "ctu-hdr.h"
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r348594 - [CTU] Add DisplayCTUProgress analyzer switch

2018-12-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Dec  7 06:56:02 2018
New Revision: 348594

URL: http://llvm.org/viewvc/llvm-project?rev=348594&view=rev
Log:
[CTU] Add DisplayCTUProgress analyzer switch

Summary:
With a new switch we may be able to print to stderr if a new TU is being loaded
during CTU.  This is very important for higher level scripts (like CodeChecker)
to be able to parse this output so they can create e.g. a zip file in case of
a Clang crash which contains all the related TU files.

Reviewers: xazax.hun, Szelethus, a_sidorin, george.karpenkov

Subscribers: whisperity, baloghadamsoftware, szepet, rnkovacs, a.sidorin, 
mikhail.ramalho, donat.nagy, dkrupp,

Differential Revision: https://reviews.llvm.org/D55135

Modified:
cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/test/Analysis/analyzer-config.c
cfe/trunk/test/Analysis/ctu-main.cpp

Modified: cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h?rev=348594&r1=348593&r2=348594&view=diff
==
--- cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h (original)
+++ cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h Fri Dec  7 06:56:02 
2018
@@ -108,7 +108,7 @@ public:
   /// Note that the AST files should also be in the \p CrossTUDir.
   llvm::Expected
   getCrossTUDefinition(const FunctionDecl *FD, StringRef CrossTUDir,
-   StringRef IndexName);
+   StringRef IndexName, bool DisplayCTUProgress = false);
 
   /// This function loads a function definition from an external AST
   ///file.
@@ -124,7 +124,8 @@ public:
   /// Note that the AST files should also be in the \p CrossTUDir.
   llvm::Expected loadExternalAST(StringRef LookupName,
 StringRef CrossTUDir,
-StringRef IndexName);
+StringRef IndexName,
+bool DisplayCTUProgress = false);
 
   /// This function merges a definition from a separate AST Unit into
   ///the current one which was created by the compiler instance that

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def?rev=348594&r1=348593&r2=348594&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def Fri Dec  7 
06:56:02 2018
@@ -283,6 +283,11 @@ ANALYZER_OPTION(bool, ShouldDisplayMacro
 "expanded and included in the plist output.",
 false)
 
+ANALYZER_OPTION(bool, DisplayCTUProgress, "display-ctu-progress",
+"Whether to emit verbose output about "
+"the analyzer's progress related to ctu.",
+false)
+
 
//===--===//
 // Unsinged analyzer options.
 
//===--===//

Modified: cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp?rev=348594&r1=348593&r2=348594&view=diff
==
--- cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp (original)
+++ cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp Fri Dec  7 06:56:02 2018
@@ -159,7 +159,8 @@ CrossTranslationUnitContext::findFunctio
 llvm::Expected
 CrossTranslationUnitContext::getCrossTUDefinition(const FunctionDecl *FD,
   StringRef CrossTUDir,
-  StringRef IndexName) {
+  StringRef IndexName,
+  bool DisplayCTUProgress) {
   assert(FD && "FD is missing, bad call to this function!");
   assert(!FD->hasBody() && "FD has a definition in current translation unit!");
   ++NumGetCTUCalled;
@@ -168,7 +169,7 @@ CrossTranslationUnitContext::getCrossTUD
 return llvm::make_error(
 index_error_code::failed_to_generate_usr);
   llvm::Expected ASTUnitOrError =
-  loadExternalAST(LookupFnName, CrossTUDir, IndexName);
+  loadExternalAST(LookupFnName, CrossTUDir, IndexName, DisplayCTUProgress);
   if (!ASTUnitOrError)
 return ASTUnitOrError.takeError();
   ASTUnit *Unit = *ASTUnitOrError;
@@ -205,7 +206,8 @@ void CrossTranslationUnitContext::emitCr
 }
 

r348605 - [CTU] Add more lit tests and better error handling

2018-12-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Dec  7 08:05:58 2018
New Revision: 348605

URL: http://llvm.org/viewvc/llvm-project?rev=348605&view=rev
Log:
[CTU] Add more lit tests and better error handling

Summary:
Adding some more CTU list tests. E.g. to check if a construct is unsupported.
We also slightly modify the handling of the return value of the `Import`
function from ASTImporter.

Reviewers: xazax.hun, balazske, a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D55131

Added:
cfe/trunk/test/Analysis/Inputs/ctu-other.c
cfe/trunk/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt
cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt
  - copied, changed from r348594, 
cfe/trunk/test/Analysis/Inputs/externalFnMap.txt
cfe/trunk/test/Analysis/ctu-main.c
Removed:
cfe/trunk/test/Analysis/Inputs/externalFnMap.txt
Modified:
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
cfe/trunk/test/Analysis/ctu-main.cpp

Modified: cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp?rev=348605&r1=348604&r2=348605&view=diff
==
--- cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp (original)
+++ cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp Fri Dec  7 08:05:58 2018
@@ -269,7 +269,9 @@ CrossTranslationUnitContext::importDefin
 
   ASTImporter &Importer = getOrCreateASTImporter(FD->getASTContext());
   auto *ToDecl =
-  cast(Importer.Import(const_cast(FD)));
+  cast_or_null(Importer.Import(const_cast(FD)));
+  if (!ToDecl)
+return llvm::make_error(index_error_code::failed_import);
   assert(ToDecl->hasBody());
   assert(FD->hasBody() && "Functions already imported should have body.");
   ++NumGetCTUSuccess;

Added: cfe/trunk/test/Analysis/Inputs/ctu-other.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/ctu-other.c?rev=348605&view=auto
==
--- cfe/trunk/test/Analysis/Inputs/ctu-other.c (added)
+++ cfe/trunk/test/Analysis/Inputs/ctu-other.c Fri Dec  7 08:05:58 2018
@@ -0,0 +1,49 @@
+// Test typedef and global variable in function.
+typedef struct {
+  int a;
+  int b;
+} FooBar;
+FooBar fb;
+int f(int i) {
+  if (fb.a) {
+fb.b = i;
+  }
+  return 1;
+}
+
+// Test enums.
+enum B { x = 42,
+ l,
+ s };
+int enumCheck(void) {
+  return x;
+}
+
+// Test reporting an error in macro definition
+#define MYMACRO(ctx) \
+  ctx->a;
+struct S {
+  int a;
+};
+int g(struct S *ctx) {
+  MYMACRO(ctx);
+  return 0;
+}
+
+// Test that asm import does not fail.
+int inlineAsm() {
+  int res;
+  asm("mov $42, %0"
+  : "=r"(res));
+  return res;
+}
+
+// Implicit function.
+int identImplicit(int in) {
+  return in;
+}
+
+// ASTImporter doesn't support this construct.
+int structInProto(struct DataType {int a;int b; } * d) {
+  return 0;
+}

Added: cfe/trunk/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt?rev=348605&view=auto
==
--- cfe/trunk/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt (added)
+++ cfe/trunk/test/Analysis/Inputs/ctu-other.c.externalFnMap.txt Fri Dec  7 
08:05:58 2018
@@ -0,0 +1,6 @@
+c:@F@inlineAsm ctu-other.c.ast
+c:@F@g ctu-other.c.ast
+c:@F@f ctu-other.c.ast
+c:@F@enumCheck ctu-other.c.ast
+c:@F@identImplicit ctu-other.c.ast
+c:@F@structInProto ctu-other.c.ast

Copied: cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt (from 
r348594, cfe/trunk/test/Analysis/Inputs/externalFnMap.txt)
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt?p2=cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalFnMap.txt&p1=cfe/trunk/test/Analysis/Inputs/externalFnMap.txt&r1=348594&r2=348605&rev=348605&view=diff
==
(empty)

Removed: cfe/trunk/test/Analysis/Inputs/externalFnMap.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/externalFnMap.txt?rev=348604&view=auto
==
--- cfe/trunk/test/Analysis/Inputs/externalFnMap.txt (original)
+++ cfe/trunk/test/Analysis/Inputs/externalFnMap.txt (removed)
@@ -1,15 +0,0 @@
-c:@N@chns@F@chf1#I# ctu-other.cpp.ast
-c:@N@myns@N@embed_ns@F@fens#I# ctu-other.cpp.ast
-c:@F@g#I# ctu-other.cpp.ast
-c:@S@mycls@F@fscl#I#S ctu-other.cpp.ast
-c:@S@mycls@F@fcl#I# ctu-other.cpp.ast
-c:@N@myns@S@embed_cls@F@fecl#I# ctu-other.cpp.ast
-c:@S@mycls@S@embed_cls2@F@fecl2#I# ctu-other.cpp.ast
-c:@F@f#I# ctu-other.cpp.ast
-c:@N@myns@F@fns#I# ctu-other.cpp.ast
-c:@F@h#I# ctu-other.cpp.ast
-c:@F@h_chain#I# ctu-chain.cpp.ast
-c

r348609 - [CTU] test/Analysis/ctu-main.cpp Attempt to fix failing windows bot

2018-12-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Dec  7 08:27:31 2018
New Revision: 348609

URL: http://llvm.org/viewvc/llvm-project?rev=348609&view=rev
Log:
[CTU] test/Analysis/ctu-main.cpp Attempt to fix failing windows bot

Modified:
cfe/trunk/test/Analysis/ctu-main.cpp

Modified: cfe/trunk/test/Analysis/ctu-main.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctu-main.cpp?rev=348609&r1=348608&r2=348609&view=diff
==
--- cfe/trunk/test/Analysis/ctu-main.cpp (original)
+++ cfe/trunk/test/Analysis/ctu-main.cpp Fri Dec  7 08:27:31 2018
@@ -16,8 +16,8 @@
 // RUN:   -analyzer-config ctu-dir=%t/ctudir \
 // RUN:   -analyzer-config display-ctu-progress=true 2>&1 %s | FileCheck %s
 
-// CHECK: CTU loaded AST file: {{.*}}/ctu-other.cpp
-// CHECK: CTU loaded AST file: {{.*}}/ctu-chain.cpp
+// CHECK: CTU loaded AST file: {{.*}}/ctu-other.cpp.ast
+// CHECK: CTU loaded AST file: {{.*}}/ctu-chain.cpp.ast
 
 #include "ctu-hdr.h"
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r348610 - [CTU] Add triple/lang mismatch handling

2018-12-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Dec  7 08:32:43 2018
New Revision: 348610

URL: http://llvm.org/viewvc/llvm-project?rev=348610&view=rev
Log:
[CTU] Add triple/lang mismatch handling

Summary:
We introduce a strict policy for C++ CTU. It can work across TUs only if
the C++ dialects are the same. We neither allow C vs C++ CTU.  We do this
because the same constructs might be represented with different properties in
the corresponding AST nodes or even the nodes might be completely different (a
struct will be RecordDecl in C, but it will be a CXXRectordDecl in C++, thus it
may cause certain assertions during cast operations).

Reviewers: xazax.hun, a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D55134

Added:
cfe/trunk/test/Analysis/ctu-different-triples.cpp
cfe/trunk/test/Analysis/ctu-unknown-parts-in-triples.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticCrossTUKinds.td
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticCrossTUKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCrossTUKinds.td?rev=348610&r1=348609&r2=348610&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticCrossTUKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCrossTUKinds.td Fri Dec  7 08:32:43 
2018
@@ -15,4 +15,8 @@ def err_fnmap_parsing : Error<
 
 def err_multiple_def_index : Error<
   "multiple definitions are found for the same key in index ">;
+
+def warn_ctu_incompat_triple : Warning<
+  "imported AST from '%0' had been generated for a different target, "
+  "current: %1, imported: %2">, InGroup;
 }

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=348610&r1=348609&r2=348610&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Dec  7 08:32:43 2018
@@ -1041,3 +1041,6 @@ def ExperimentalISel : DiagGroup<"experi
 def FunctionMultiVersioning : DiagGroup<"function-multiversion">;
 
 def NoDeref : DiagGroup<"noderef">;
+
+// A group for cross translation unit static analysis related warnings.
+def CrossTU : DiagGroup<"ctu">;

Modified: cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h?rev=348610&r1=348609&r2=348610&view=diff
==
--- cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h (original)
+++ cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h Fri Dec  7 08:32:43 
2018
@@ -41,7 +41,9 @@ enum class index_error_code {
   missing_definition,
   failed_import,
   failed_to_get_external_ast,
-  failed_to_generate_usr
+  failed_to_generate_usr,
+  triple_mismatch,
+  lang_mismatch
 };
 
 class IndexError : public llvm::ErrorInfo {
@@ -50,16 +52,25 @@ public:
   IndexError(index_error_code C) : Code(C), LineNo(0) {}
   IndexError(index_error_code C, std::string FileName, int LineNo = 0)
   : Code(C), FileName(std::move(FileName)), LineNo(LineNo) {}
+  IndexError(index_error_code C, std::string FileName, std::string 
TripleToName,
+ std::string TripleFromName)
+  : Code(C), FileName(std::move(FileName)),
+TripleToName(std::move(TripleToName)),
+TripleFromName(std::move(TripleFromName)) {}
   void log(raw_ostream &OS) const override;
   std::error_code convertToErrorCode() const override;
   index_error_code getCode() const { return Code; }
   int getLineNum() const { return LineNo; }
   std::string getFileName() const { return FileName; }
+  std::string getTripleToName() const { return TripleToName; }
+  std::string getTripleFromName() const { return TripleFromName; }
 
 private:
   index_error_code Code;
   std::string FileName;
   int LineNo;
+  std::string TripleToName;
+  std::string TripleFromName;
 };
 
 /// This function parses an index file that determines which

Modified: cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp?rev=348610&r1=348609&r2=348610&view=diff
==
--- cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp (original)
+++ cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp Fri Dec  7 08:32:43 2018
@@ -33,6 +33,7 @@ namespace clang {
 namespace cross_tu {
 
 namespace {
+
 #define DEBUG_TYPE "CrossTranslationUnit"
 STATISTIC(NumGetCTUCalled, "The # of getCTUDefinition function called");
 STATISTIC(
@@ -41,6 +42,

r348614 - [CTU] test/Analysis/ctu-main.cpp Attempt to fix failing windows bot

2018-12-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Dec  7 09:36:44 2018
New Revision: 348614

URL: http://llvm.org/viewvc/llvm-project?rev=348614&view=rev
Log:
[CTU] test/Analysis/ctu-main.cpp Attempt to fix failing windows bot

Modified:
cfe/trunk/test/Analysis/ctu-main.cpp

Modified: cfe/trunk/test/Analysis/ctu-main.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctu-main.cpp?rev=348614&r1=348613&r2=348614&view=diff
==
--- cfe/trunk/test/Analysis/ctu-main.cpp (original)
+++ cfe/trunk/test/Analysis/ctu-main.cpp Fri Dec  7 09:36:44 2018
@@ -16,8 +16,8 @@
 // RUN:   -analyzer-config ctu-dir=%t/ctudir \
 // RUN:   -analyzer-config display-ctu-progress=true 2>&1 %s | FileCheck %s
 
-// CHECK: CTU loaded AST file: {{.*}}/ctu-other.cpp.ast
-// CHECK: CTU loaded AST file: {{.*}}/ctu-chain.cpp.ast
+// CHECK: CTU loaded AST file: {{.*}}ctu-other.cpp.ast
+// CHECK: CTU loaded AST file: {{.*}}ctu-chain.cpp.ast
 
 #include "ctu-hdr.h"
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r355096 - [CTU] Do not allow different CPP dialects in CTU

2019-02-28 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Feb 28 07:24:59 2019
New Revision: 355096

URL: http://llvm.org/viewvc/llvm-project?rev=355096&view=rev
Log:
[CTU] Do not allow different CPP dialects in CTU

Summary:
If CPP dialects are different then return with error.

Consider this STL code:
  template
struct __alloc_traits
  #if __cplusplus >= 201103L
: std::allocator_traits<_Alloc>
  #endif
{ // ...
};
This class template would create ODR errors during merging the two units,
since in one translation unit the class template has a base class, however
in the other unit it has none.

Reviewers: xazax.hun, a_sidorin, r.stahl

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57906

Modified:
cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp

Modified: cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h?rev=355096&r1=355095&r2=355096&view=diff
==
--- cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h (original)
+++ cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h Thu Feb 28 07:24:59 
2019
@@ -43,7 +43,8 @@ enum class index_error_code {
   failed_to_get_external_ast,
   failed_to_generate_usr,
   triple_mismatch,
-  lang_mismatch
+  lang_mismatch,
+  lang_dialect_mismatch
 };
 
 class IndexError : public llvm::ErrorInfo {

Modified: cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp?rev=355096&r1=355095&r2=355096&view=diff
==
--- cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp (original)
+++ cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp Thu Feb 28 07:24:59 2019
@@ -42,6 +42,7 @@ STATISTIC(NumGetCTUSuccess,
   "requested function's body");
 STATISTIC(NumTripleMismatch, "The # of triple mismatches");
 STATISTIC(NumLangMismatch, "The # of language mismatches");
+STATISTIC(NumLangDialectMismatch, "The # of language dialect mismatches");
 
 // Same as Triple's equality operator, but we check a field only if that is
 // known in both instances.
@@ -99,6 +100,8 @@ public:
   return "Triple mismatch";
 case index_error_code::lang_mismatch:
   return "Language mismatch";
+case index_error_code::lang_dialect_mismatch:
+  return "Language dialect mismatch";
 }
 llvm_unreachable("Unrecognized index_error_code.");
   }
@@ -228,6 +231,7 @@ CrossTranslationUnitContext::getCrossTUD
 
   const auto &LangTo = Context.getLangOpts();
   const auto &LangFrom = Unit->getASTContext().getLangOpts();
+
   // FIXME: Currenty we do not support CTU across C++ and C and across
   // different dialects of C++.
   if (LangTo.CPlusPlus != LangFrom.CPlusPlus) {
@@ -235,6 +239,28 @@ CrossTranslationUnitContext::getCrossTUD
 return llvm::make_error(index_error_code::lang_mismatch);
   }
 
+  // If CPP dialects are different then return with error.
+  //
+  // Consider this STL code:
+  //   template
+  // struct __alloc_traits
+  //   #if __cplusplus >= 201103L
+  // : std::allocator_traits<_Alloc>
+  //   #endif
+  // { // ...
+  // };
+  // This class template would create ODR errors during merging the two units,
+  // since in one translation unit the class template has a base class, however
+  // in the other unit it has none.
+  if (LangTo.CPlusPlus11 != LangFrom.CPlusPlus11 ||
+  LangTo.CPlusPlus14 != LangFrom.CPlusPlus14 ||
+  LangTo.CPlusPlus17 != LangFrom.CPlusPlus17 ||
+  LangTo.CPlusPlus2a != LangFrom.CPlusPlus2a) {
+++NumLangDialectMismatch;
+return llvm::make_error(
+index_error_code::lang_dialect_mismatch);
+  }
+
   TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
   if (const FunctionDecl *ResultDecl =
   findFunctionInDeclContext(TU, LookupFnName))


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r355390 - [ASTImporter] Fix redecl failures of Class and ClassTemplate

2019-03-05 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Mar  5 03:23:24 2019
New Revision: 355390

URL: http://llvm.org/viewvc/llvm-project?rev=355390&view=rev
Log:
[ASTImporter] Fix redecl failures of Class and ClassTemplate

Summary:
Redecl chains of classes and class templates are not handled well
currently. We want to handle them similarly to functions, i.e. try to
keep the structure of the original AST as much as possible. The aim is
to not squash a prototype with a definition, rather we create both and
put them in a redecl chain.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58502

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=355390&r1=355389&r2=355390&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Mar  5 03:23:24 2019
@@ -2553,26 +2553,6 @@ ExpectedDecl ASTNodeImporter::VisitRecor
 Decl::FOK_None;
   }
 
-  // If this record has a definition in the translation unit we're coming from,
-  // but this particular declaration is not that definition, import the
-  // definition and map to that.
-  TagDecl *Definition = D->getDefinition();
-  if (Definition && Definition != D &&
-  // Friend template declaration must be imported on its own.
-  !IsFriendTemplate &&
-  // In contrast to a normal CXXRecordDecl, the implicit
-  // CXXRecordDecl of ClassTemplateSpecializationDecl is its redeclaration.
-  // The definition of the implicit CXXRecordDecl in this case is the
-  // ClassTemplateSpecializationDecl itself. Thus, we start with an extra
-  // condition in order to be able to import the implict Decl.
-  !D->isImplicit()) {
-ExpectedDecl ImportedDefOrErr = import(Definition);
-if (!ImportedDefOrErr)
-  return ImportedDefOrErr.takeError();
-
-return Importer.MapImported(D, *ImportedDefOrErr);
-  }
-
   // Import the major distinguishing characteristics of this record.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
@@ -2601,7 +2581,8 @@ ExpectedDecl ASTNodeImporter::VisitRecor
 auto FoundDecls =
 Importer.findDeclsInToCtx(DC, SearchName);
 if (!FoundDecls.empty()) {
-  // We're going to have to compare D against potentially conflicting 
Decls, so complete it.
+  // We're going to have to compare D against potentially conflicting 
Decls,
+  // so complete it.
   if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
 D->getASTContext().getExternalSource()->CompleteType(D);
 }
@@ -4976,17 +4957,6 @@ static ClassTemplateDecl *getDefinition(
 ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   bool IsFriend = D->getFriendObjectKind() != Decl::FOK_None;
 
-  // If this template has a definition in the translation unit we're coming
-  // from, but this particular declaration is not that definition, import the
-  // definition and map to that.
-  ClassTemplateDecl *Definition = getDefinition(D);
-  if (Definition && Definition != D && !IsFriend) {
-if (ExpectedDecl ImportedDefOrErr = import(Definition))
-  return Importer.MapImported(D, *ImportedDefOrErr);
-else
-  return ImportedDefOrErr.takeError();
-  }
-
   // Import the major distinguishing characteristics of this class template.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=355390&r1=355389&r2=355390&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Tue Mar  5 03:23:24 2019
@@ -4241,8 +4241,7 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
 ImportDefinitionAfterImportedPrototype)
-// FIXME This does not pass, possible error with Class import.
-ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, DISABLED_,
+ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
 ImportDefinitionAfterImportedPrototype)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
 ImportDefinitionAfterImportedPrototype)
@@ -4250,16 +4249,14 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
 DISABLED_,
 ImportDefinitionAfterImportedPrototype)
-// FIXME This does not 

r355593 - [ASTImporter] Handle redecl chain of FunctionTemplateDecls

2019-03-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Mar  7 05:01:51 2019
New Revision: 355593

URL: http://llvm.org/viewvc/llvm-project?rev=355593&view=rev
Log:
[ASTImporter] Handle redecl chain of FunctionTemplateDecls

Summary:
Redecl chains of function templates are not handled well currently. We
want to handle them similarly to functions, i.e. try to keep the
structure of the original AST as much as possible. The aim is to not
squash a prototype with a definition, rather we create both and put them
in a redecl chain.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58494

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=355593&r1=355592&r2=355593&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Mar  7 05:01:51 2019
@@ -4943,15 +4943,15 @@ ASTNodeImporter::VisitTemplateTemplatePa
   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  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(TemplateWithDef);
 }
 
 ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
@@ -4983,7 +4983,8 @@ ExpectedDecl ASTNodeImporter::VisitClass
   if (FoundTemplate) {
 
 if (IsStructuralMatch(D, FoundTemplate)) {
-  ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
+  ClassTemplateDecl *TemplateWithDef =
+  getTemplateDefinition(FoundTemplate);
   if (D->isThisDeclarationADefinition() && TemplateWithDef) {
 return Importer.MapImported(D, TemplateWithDef);
   }
@@ -5046,6 +5047,8 @@ ExpectedDecl ASTNodeImporter::VisitClass
 // 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)
@@ -5508,8 +5511,11 @@ ASTNodeImporter::VisitFunctionTemplateDe
   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);
@@ -5517,18 +5523,21 @@ ASTNodeImporter::VisitFunctionTemplateDe
   if (!FoundDecl->isInIdentifierNamespace(IDNS))
 continue;
 
-  if (auto *FoundFunction =
-  dyn_cast(FoundDecl)) {
-if (FoundFunction->hasExternalFormalLinkage() &&
+  if (auto *FoundTemplate = dyn_cast(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
 }
   }
 
@@ -5547,10 +5556,25 @@ ASTNodeImporter::VisitFunctionTemplateDe
 return ToFunc;
 
   TemplatedFD->setDescribedFunctionTemplate(ToFunc);
+
   ToFunc->setAccess(D->getAccess());
   ToFunc->setLexicalDeclContext

r355596 - [ASTImporter] Import member expr with explicit template args

2019-03-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Mar  7 05:38:20 2019
New Revision: 355596

URL: http://llvm.org/viewvc/llvm-project?rev=355596&view=rev
Log:
[ASTImporter] Import member expr with explicit template args

Summary:
Member expressions with explicit template arguments were not imported
correctly: the DeclRefExpr was missing. This patch fixes.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58830

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=355596&r1=355595&r2=355596&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Mar  7 05:38:20 2019
@@ -7129,15 +7129,19 @@ ExpectedStmt ASTNodeImporter::VisitMembe
 
   DeclarationNameInfo ToMemberNameInfo(ToName, ToLoc);
 
+  TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
   if (E->hasExplicitTemplateArgs()) {
-// FIXME: handle template arguments
-return make_error(ImportError::UnsupportedConstruct);
+if (Error Err =
+ImportTemplateArgumentListInfo(E->getLAngleLoc(), 
E->getRAngleLoc(),
+   E->template_arguments(), ToTAInfo))
+  return std::move(Err);
+ResInfo = &ToTAInfo;
   }
 
   return MemberExpr::Create(
   Importer.getToContext(), ToBase, E->isArrow(), ToOperatorLoc,
   ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl, ToFoundDecl,
-  ToMemberNameInfo, nullptr, ToType, E->getValueKind(), 
E->getObjectKind());
+  ToMemberNameInfo, ResInfo, ToType, E->getValueKind(), 
E->getObjectKind());
 }
 
 ExpectedStmt

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=355596&r1=355595&r2=355596&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu Mar  7 05:38:20 2019
@@ -2604,6 +2604,56 @@ TEST_P(ImportFunctions, ImportImplicitFu
   EXPECT_TRUE(LambdaRec->getDestructor());
 }
 
+TEST_P(ImportFunctions,
+   CallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  struct X {
+template 
+void foo(){}
+  };
+  void f() {
+X x;
+x.foo();
+  }
+  )",
+  Lang_CXX);
+  auto *FromD = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasName("f")));
+  auto *ToD = Import(FromD, Lang_CXX);
+  EXPECT_TRUE(ToD);
+  EXPECT_TRUE(MatchVerifier().match(
+  ToD, functionDecl(hasName("f"), hasDescendant(declRefExpr();
+}
+
+TEST_P(ImportFunctions,
+   DependentCallExprOfMemberFunctionTemplateWithExplicitTemplateArgs) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  struct X {
+template 
+void foo(){}
+  };
+  template 
+  void f() {
+X x;
+x.foo();
+  }
+  void g() {
+f();
+  }
+  )",
+  Lang_CXX);
+  auto *FromD = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasName("g")));
+  auto *ToD = Import(FromD, Lang_CXX);
+  EXPECT_TRUE(ToD);
+  Decl *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+  EXPECT_TRUE(MatchVerifier().match(
+  ToTU, translationUnitDecl(hasDescendant(
+functionDecl(hasName("f"), hasDescendant(declRefExpr()));
+}
+
 struct ImportFriendFunctions : ImportFunctions {};
 
 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r356452 - [ASTImporter] Fix redecl failures of ClassTemplateSpec

2019-03-19 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Mar 19 06:34:10 2019
New Revision: 356452

URL: http://llvm.org/viewvc/llvm-project?rev=356452&view=rev
Log:
[ASTImporter] Fix redecl failures of ClassTemplateSpec

Summary:
Redecl chains of class template specializations are not handled well
currently. We want to handle them similarly to functions, i.e. try to
keep the structure of the original AST as much as possible. The aim is
to not squash a prototype with a definition, rather we create both and
put them in a redecl chain.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58673

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=356452&r1=356451&r2=356452&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Mar 19 06:34:10 2019
@@ -5052,17 +5052,6 @@ ExpectedDecl ASTNodeImporter::VisitClass
 
 ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
   ClassTemplateSpecializationDecl *D) {
-  // If this record has a definition in the translation unit we're coming from,
-  // but this particular declaration is not that definition, import the
-  // definition and map to that.
-  TagDecl *Definition = D->getDefinition();
-  if (Definition && Definition != D) {
-if (ExpectedDecl ImportedDefOrErr = import(Definition))
-  return Importer.MapImported(D, *ImportedDefOrErr);
-else
-  return ImportedDefOrErr.takeError();
-  }
-
   ClassTemplateDecl *ClassTemplate;
   if (Error Err = importInto(ClassTemplate, D->getSpecializedTemplate()))
 return std::move(Err);
@@ -5080,154 +5069,141 @@ ExpectedDecl ASTNodeImporter::VisitClass
 
   // Try to find an existing specialization with these template arguments.
   void *InsertPos = nullptr;
-  ClassTemplateSpecializationDecl *D2 = nullptr;
+  ClassTemplateSpecializationDecl *PrevDecl = nullptr;
   ClassTemplatePartialSpecializationDecl *PartialSpec =
 dyn_cast(D);
   if (PartialSpec)
-D2 = ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
+PrevDecl =
+ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
   else
-D2 = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
-  ClassTemplateSpecializationDecl * const PrevDecl = D2;
-  RecordDecl *FoundDef = D2 ? D2->getDefinition() : nullptr;
-  if (FoundDef) {
-if (!D->isCompleteDefinition()) {
-  // The "From" translation unit only had a forward declaration; call it
-  // the same declaration.
-  // TODO Handle the redecl chain properly!
-  return Importer.MapImported(D, FoundDef);
-}
-
-if (IsStructuralMatch(D, FoundDef)) {
-
-  Importer.MapImported(D, FoundDef);
+PrevDecl = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
 
-  // Import those those default field initializers which have been
-  // instantiated in the "From" context, but not in the "To" context.
-  for (auto *FromField : D->fields()) {
-auto ToOrErr = import(FromField);
-if (!ToOrErr)
-  // FIXME: return the error?
-  consumeError(ToOrErr.takeError());
+  if (PrevDecl) {
+if (IsStructuralMatch(D, PrevDecl)) {
+  if (D->isThisDeclarationADefinition() && PrevDecl->getDefinition()) {
+Importer.MapImported(D, PrevDecl->getDefinition());
+// Import those default field initializers which have been
+// instantiated in the "From" context, but not in the "To" context.
+for (auto *FromField : D->fields())
+  Importer.Import(FromField);
+
+// Import those methods which have been instantiated in the
+// "From" context, but not in the "To" context.
+for (CXXMethodDecl *FromM : D->methods())
+  Importer.Import(FromM);
+
+// TODO Import instantiated default arguments.
+// TODO Import instantiated exception specifications.
+//
+// Generally, ASTCommon.h/DeclUpdateKind enum gives a very good hint
+// what else could be fused during an AST merge.
+return PrevDecl;
   }
+} else { // ODR violation.
+  // FIXME HandleNameConflict
+  return nullptr;
+}
+  }
 
-  // Import those methods which have been instantiated in the
-  // "From" context, but not in the "To" context.
-  for (CXXMethodDecl *FromM : D->methods()) {
-auto ToOrErr = import(FromM);
-if (!ToOrErr)
-  // FIXME: return the error?
-  consumeError(ToOrErr.takeError());
-  }
+  // Import the location of this declaration.
+  ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+  if (!BeginLocOrErr)
+

r356455 - [ASTImporter] Fix redecl failures of FunctionTemplateSpec

2019-03-19 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Mar 19 07:04:50 2019
New Revision: 356455

URL: http://llvm.org/viewvc/llvm-project?rev=356455&view=rev
Log:
[ASTImporter] Fix redecl failures of FunctionTemplateSpec

Summary:
Redecl chains of function template specializations are not handled well
currently. We want to handle them similarly to functions, i.e. try to
keep the structure of the original AST as much as possible. The aim is
to not squash a prototype with a definition, rather we create both and
put them in a redecl chain.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58668

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=356455&r1=356454&r2=356455&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Mar 19 07:04:50 2019
@@ -290,6 +290,16 @@ namespace clang {
 ToD->setImplicit();
 }
 
+// Check if we have found an existing definition.  Returns with that
+// definition if yes, otherwise returns null.
+Decl *FindAndMapDefinition(FunctionDecl *D, FunctionDecl *FoundFunction) {
+  const FunctionDecl *Definition = nullptr;
+  if (D->doesThisDeclarationHaveABody() &&
+  FoundFunction->hasBody(Definition))
+return Importer.MapImported(D, const_cast(Definition));
+  return nullptr;
+}
+
   public:
 explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
 
@@ -2973,8 +2983,8 @@ ExpectedDecl ASTNodeImporter::VisitFunct
 if (!FoundFunctionOrErr)
   return FoundFunctionOrErr.takeError();
 if (FunctionDecl *FoundFunction = *FoundFunctionOrErr) {
-  if (D->doesThisDeclarationHaveABody() && FoundFunction->hasBody())
-return Importer.MapImported(D, FoundFunction);
+  if (Decl *Def = FindAndMapDefinition(D, FoundFunction))
+return Def;
   FoundByLookup = FoundFunction;
 }
   }
@@ -2993,11 +3003,8 @@ ExpectedDecl ASTNodeImporter::VisitFunct
   continue;
 
 if (IsStructuralMatch(D, FoundFunction)) {
-  const FunctionDecl *Definition = nullptr;
-  if (D->doesThisDeclarationHaveABody() &&
-  FoundFunction->hasBody(Definition))
-return Importer.MapImported(D,
-const_cast(Definition));
+  if (Decl *Def = FindAndMapDefinition(D, FoundFunction))
+return Def;
   FoundByLookup = FoundFunction;
   break;
 }

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=356455&r1=356454&r2=356455&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Tue Mar 19 07:04:50 2019
@@ -3978,6 +3978,45 @@ struct RedeclChain : ASTImporterOptionSp
   std::string getDefinition() { return TypeParam::Definition; }
   BindableMatcher getPattern() const { return TypeParam().getPattern(); }
 
+  void CheckPreviousDecl(Decl *Prev, Decl *Current) {
+ASSERT_NE(Prev, Current);
+ASSERT_EQ(&Prev->getASTContext(), &Current->getASTContext());
+EXPECT_EQ(Prev->getCanonicalDecl(), Current->getCanonicalDecl());
+
+// Templates.
+if (auto *PrevT = dyn_cast(Prev)) {
+  EXPECT_EQ(Current->getPreviousDecl(), Prev);
+  auto *CurrentT = cast(Current);
+  ASSERT_TRUE(PrevT->getTemplatedDecl());
+  ASSERT_TRUE(CurrentT->getTemplatedDecl());
+  EXPECT_EQ(CurrentT->getTemplatedDecl()->getPreviousDecl(),
+PrevT->getTemplatedDecl());
+  return;
+}
+
+// Specializations.
+if (auto *PrevF = dyn_cast(Prev)) {
+  if (PrevF->getTemplatedKind() ==
+  FunctionDecl::TK_FunctionTemplateSpecialization) {
+// There may be a hidden fwd spec decl before a spec decl.
+// In that case the previous visible decl can be reached through that
+// invisible one.
+EXPECT_THAT(Prev, testing::AnyOf(
+  Current->getPreviousDecl(),
+  Current->getPreviousDecl()->getPreviousDecl()));
+auto *ToTU = Prev->getTranslationUnitDecl();
+auto *TemplateD = FirstDeclMatcher().match(
+ToTU, functionTemplateDecl());
+auto *FirstSpecD = *(TemplateD->spec_begin());
+EXPECT_EQ(FirstSpecD->getCanonicalDecl(), PrevF->getCanonicalDecl());
+return;
+  }
+}
+
+// The rest: Classes, Functions, etc.
+EXPECT_EQ(Current->getPreviousDecl(), Prev);
+  }
+
   void
   TypedTest_PrototypeShouldBeImportedAsAPrototype

r357394 - [ASTImporter] Make ODR error handling configurable

2019-04-01 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Apr  1 07:46:53 2019
New Revision: 357394

URL: http://llvm.org/viewvc/llvm-project?rev=357394&view=rev
Log:
[ASTImporter] Make ODR error handling configurable

Summary:
ODR errors are not necessarily true errors during the import of ASTs.
ASTMerge and CrossTU should use the warning equivalent of every CTU error,
while Sema should emit errors as before.

Reviewers: martong, a_sidorin, shafik, a.sidorin

Reviewed By: a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D58897

Patch by Endre Fulop!

Modified:
cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h
cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp

Modified: cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h?rev=357394&r1=357393&r2=357394&view=diff
==
--- cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h (original)
+++ cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h Mon Apr  1 07:46:53 
2019
@@ -111,6 +111,10 @@ struct StructuralEquivalenceContext {
   static llvm::Optional
   findUntaggedStructOrUnionIndex(RecordDecl *Anon);
 
+  // If ErrorOnTagTypeMismatch is set, return the the error, otherwise get the
+  // relevant warning for the input error diagnostic.
+  unsigned getApplicableDiagnostic(unsigned ErrorDiagnostic);
+
 private:
   /// Finish checking all of the structural equivalences.
   ///

Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=357394&r1=357393&r2=357394&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Mon Apr  1 07:46:53 2019
@@ -224,20 +224,31 @@ let CategoryName = "VTable ABI Issue" in
 def err_odr_variable_type_inconsistent : Error<
   "external variable %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
+def warn_odr_variable_type_inconsistent : Warning<
+  "external variable %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup;
 def err_odr_variable_multiple_def : Error<
   "external variable %0 defined in multiple translation units">;
+def warn_odr_variable_multiple_def : Warning<
+  "external variable %0 defined in multiple translation units">,
+  InGroup;
 def note_odr_value_here : Note<"declared here with type %0">;
 def note_odr_defined_here : Note<"also defined here">;
 def err_odr_function_type_inconsistent : Error<
   "external function %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
-def warn_odr_tag_type_inconsistent
-: Warning<"type %0 has incompatible definitions in different translation "
-  "units">,
-  InGroup>;
+def warn_odr_function_type_inconsistent : Warning<
+  "external function %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup;
 def err_odr_tag_type_inconsistent
 : Error<"type %0 has incompatible definitions in different translation "
 "units">;
+def warn_odr_tag_type_inconsistent
+: Warning<"type %0 has incompatible definitions in different translation "
+  "units">,
+  InGroup;
 def note_odr_tag_kind_here: Note<
   "%0 is a %select{struct|interface|union|class|enum}1 here">;
 def note_odr_field : Note<"field %0 has type %1 here">;
@@ -253,44 +264,82 @@ def note_odr_number_of_bases : Note<
   "class has %0 base %plural{1:class|:classes}0">;
 def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
 def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
-
 def err_odr_field_type_inconsistent : Error<
   "field %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
+def warn_odr_field_type_inconsistent : Warning<
+  "field %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup;
 
 // Importing Objective-C ASTs
 def err_odr_ivar_type_inconsistent : Error<
   "instance variable %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
+def warn_odr_ivar_type_inconsistent : Warning<
+  "instance variable %0 declared with incompatible types in different "
+  "translation units (%1 vs. %2)">,
+  InGroup;
 def err_odr_objc_superclass_inconsistent : Error<
   "class %0 has incompatible superclasses">;
+def warn_odr_objc_superclass_inconsistent : Warning<
+  "class %0 has incompatible superclasses">,
+  InGroup;
 def note_odr_objc_superclass : Note<"inherits from supe

r357402 - [ASTImporter] Convert ODR diagnostics inside ASTImporter implementation

2019-04-01 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Apr  1 08:29:55 2019
New Revision: 357402

URL: http://llvm.org/viewvc/llvm-project?rev=357402&view=rev
Log:
[ASTImporter] Convert ODR diagnostics inside ASTImporter implementation

Summary:
ASTStructuralEquivalence uses a flag to indicate whether ODR diagnostics
should be considered errors or warnings as module Sema is more strict than
ASTMerge. The implementation of ASTImporter should allso follow
along the same lines.

Reviewers: martong, a.sidorin, shafik, a_sidorin

Reviewed By: shafik, a_sidorin

Subscribers: rnkovacs, martong, dkrupp, Szelethus, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D59761

Patch by Endre Fulop!

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=357402&r1=357401&r2=357402&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Apr  1 08:29:55 2019
@@ -2961,7 +2961,7 @@ ExpectedDecl ASTNodeImporter::VisitFunct
   continue;
 
 // Complain about inconsistent function types.
-Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
+Importer.ToDiag(Loc, diag::warn_odr_function_type_inconsistent)
 << Name << D->getType() << FoundFunction->getType();
 Importer.ToDiag(FoundFunction->getLocation(), 
diag::note_odr_value_here)
 << FoundFunction->getType();
@@ -3265,7 +3265,7 @@ ExpectedDecl ASTNodeImporter::VisitField
   }
 
   // FIXME: Why is this case not handled with calling HandleNameConflict?
-  Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
+  Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
 << Name << D->getType() << FoundField->getType();
   Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
 << FoundField->getType();
@@ -3336,7 +3336,7 @@ ExpectedDecl ASTNodeImporter::VisitIndir
 continue;
 
   // FIXME: Why is this case not handled with calling HandleNameConflict?
-  Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
+  Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
 << Name << D->getType() << FoundField->getType();
   Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
 << FoundField->getType();
@@ -3467,7 +3467,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCI
 return FoundIvar;
   }
 
-  Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
+  Importer.ToDiag(Loc, diag::warn_odr_ivar_type_inconsistent)
 << Name << D->getType() << FoundIvar->getType();
   Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
 << FoundIvar->getType();
@@ -3580,7 +3580,7 @@ ExpectedDecl ASTNodeImporter::VisitVarDe
   }
 }
 
-Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
+Importer.ToDiag(Loc, diag::warn_odr_variable_type_inconsistent)
   << Name << D->getType() << FoundVar->getType();
 Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
   << FoundVar->getType();
@@ -3745,7 +3745,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCM
   // Check return types.
   if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
  FoundMethod->getReturnType())) {
-Importer.ToDiag(Loc, 
diag::err_odr_objc_method_result_type_inconsistent)
+Importer.ToDiag(Loc, 
diag::warn_odr_objc_method_result_type_inconsistent)
 << D->isInstanceMethod() << Name << D->getReturnType()
 << FoundMethod->getReturnType();
 Importer.ToDiag(FoundMethod->getLocation(),
@@ -3757,7 +3757,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCM
 
   // Check the number of parameters.
   if (D->param_size() != FoundMethod->param_size()) {
-Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
+Importer.ToDiag(Loc, 
diag::warn_odr_objc_method_num_params_inconsistent)
   << D->isInstanceMethod() << Name
   << D->param_size() << FoundMethod->param_size();
 Importer.ToDiag(FoundMethod->getLocation(),
@@ -3774,7 +3774,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCM
 if (!Importer.IsStructurallyEquivalent((*P)->getType(),
(*FoundP)->getType())) {
   Importer.FromDiag((*P)->getLocation(),
-diag::err_odr_objc_method_param_type_inconsistent)
+diag::warn_odr_objc_method_param_type_inconsistent)
 << D->isInstanceMethod() << Name
 << (*P)->getType() << (*FoundP)->getType();
   Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
@@ -3787,7 +3787,7 @@ ExpectedDecl ASTNo

r357405 - Attempt to fix failing buildbot (ppc64le)

2019-04-01 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Apr  1 08:48:29 2019
New Revision: 357405

URL: http://llvm.org/viewvc/llvm-project?rev=357405&view=rev
Log:
Attempt to fix failing buildbot (ppc64le)

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=357405&r1=357404&r2=357405&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Mon Apr  1 08:48:29 2019
@@ -1561,6 +1561,7 @@ unsigned StructuralEquivalenceContext::g
   case diag::err_odr_non_type_parameter_type_inconsistent:
 return diag::warn_odr_non_type_parameter_type_inconsistent;
   }
+  llvm_unreachable("Diagnostic kind not handled in preceding switch");
 }
 
 bool StructuralEquivalenceContext::IsEquivalent(Decl *D1, Decl *D2) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r360261 - [ASTImporter] Fix inequivalence of unresolved exception spec

2019-05-08 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed May  8 08:23:48 2019
New Revision: 360261

URL: http://llvm.org/viewvc/llvm-project?rev=360261&view=rev
Log:
[ASTImporter] Fix inequivalence of unresolved exception spec

Summary:
Structural equivalence of methods can falsely report false when the
exception specifier is unresolved (i.e unevaluated or not instantiated).

(This caused one assertion during bitcoin ctu-analysis.)

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61424

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=360261&r1=360260&r2=360261&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed May  8 08:23:48 2019
@@ -3130,6 +3130,11 @@ ExpectedDecl ASTNodeImporter::VisitFunct
 auto *Recent = const_cast(
   FoundByLookup->getMostRecentDecl());
 ToFunction->setPreviousDecl(Recent);
+// FIXME Probably we should merge exception specifications.  E.g. In the
+// "To" context the existing function may have exception specification with
+// noexcept-unevaluated, while the newly imported function may have an
+// evaluated noexcept.  A call to adjustExceptionSpec() on the imported
+// decl and its redeclarations may be required.
   }
 
   // Import Ctor initializers.

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=360261&r1=360260&r2=360261&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Wed May  8 08:23:48 2019
@@ -322,6 +322,36 @@ static bool IsStructurallyEquivalent(Str
   return true;
 }
 
+/// Check the equivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context,
+  const FunctionProtoType *Proto1,
+  const FunctionProtoType *Proto2) {
+
+  auto Spec1 = Proto1->getExceptionSpecType();
+  auto Spec2 = Proto2->getExceptionSpecType();
+
+  if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
+return true;
+
+  if (Spec1 != Spec2)
+return false;
+  if (Spec1 == EST_Dynamic) {
+if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+  return false;
+for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+  if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+Proto2->getExceptionType(I)))
+return false;
+}
+  } else if (isComputedNoexcept(Spec1)) {
+if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
+  Proto2->getNoexceptExpr()))
+  return false;
+  }
+
+  return true;
+}
+
 /// Determine structural equivalence of two types.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  QualType T1, QualType T2) {
@@ -536,24 +566,8 @@ static bool IsStructurallyEquivalent(Str
 cast(OrigT1.getDesugaredType(Context.FromCtx));
 const auto *OrigProto2 =
 cast(OrigT2.getDesugaredType(Context.ToCtx));
-auto Spec1 = OrigProto1->getExceptionSpecType();
-auto Spec2 = OrigProto2->getExceptionSpecType();
-
-if (Spec1 != Spec2)
+if (!IsEquivalentExceptionSpec(Context, OrigProto1, OrigProto2))
   return false;
-if (Spec1 == EST_Dynamic) {
-  if (OrigProto1->getNumExceptions() != OrigProto2->getNumExceptions())
-return false;
-  for (unsigned I = 0, N = OrigProto1->getNumExceptions(); I != N; ++I) {
-if (!IsStructurallyEquivalent(Context, OrigProto1->getExceptionType(I),
-  OrigProto2->getExceptionType(I)))
-  return false;
-  }
-} else if (isComputedNoexcept(Spec1)) {
-  if (!IsStructurallyEquivalent(Context, OrigProto1->getNoexceptExpr(),
-OrigProto2->getNoexceptExpr()))
-return false;
-}
 
 // Fall through to check the bits common with FunctionNoProtoType.
 LLVM_FALLTHROUGH;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342384 - [ASTImporter] Fix import of VarDecl init

2018-09-17 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Sep 17 05:04:52 2018
New Revision: 342384

URL: http://llvm.org/viewvc/llvm-project?rev=342384&view=rev
Log:
[ASTImporter] Fix import of VarDecl init

Summary:
The init expression of a VarDecl is overwritten in the "To" context if we
import a VarDecl without an init expression (and with a definition).  Please
refer to the added tests, especially InitAndDefinitionAreInDifferentTUs.  This
patch fixes the malfunction by importing the whole Decl chain similarly as we
did that in case of FunctionDecls.  We handle the init expression similarly to
a  definition, alas only one init expression will be in the merged ast.

Reviewers: a_sidorin, xazax.hun, r.stahl, a.sidorin

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D51597

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=342384&r1=342383&r2=342384&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Sep 17 05:04:52 2018
@@ -107,9 +107,11 @@ namespace clang {
   }
 
   SmallVector getCanonicalForwardRedeclChain(Decl* D) {
-// Currently only FunctionDecl is supported
-auto FD = cast(D);
-return getCanonicalForwardRedeclChain(FD);
+if (auto *FD = dyn_cast(D))
+  return getCanonicalForwardRedeclChain(FD);
+if (auto *VD = dyn_cast(D))
+  return getCanonicalForwardRedeclChain(VD);
+llvm_unreachable("Bad declaration kind");
   }
 
   void updateFlags(const Decl *From, Decl *To) {
@@ -280,10 +282,9 @@ namespace clang {
  (IDK == IDK_Default && !Importer.isMinimalImport());
 }
 
+bool ImportInitializer(VarDecl *From, VarDecl *To);
 bool ImportDefinition(RecordDecl *From, RecordDecl *To,
   ImportDefinitionKind Kind = IDK_Default);
-bool ImportDefinition(VarDecl *From, VarDecl *To,
-  ImportDefinitionKind Kind = IDK_Default);
 bool ImportDefinition(EnumDecl *From, EnumDecl *To,
   ImportDefinitionKind Kind = IDK_Default);
 bool ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
@@ -1424,18 +1425,26 @@ bool ASTNodeImporter::ImportDefinition(R
   return false;
 }
 
-bool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To,
-   ImportDefinitionKind Kind) {
+bool ASTNodeImporter::ImportInitializer(VarDecl *From, VarDecl *To) {
   if (To->getAnyInitializer())
 return false;
 
-  // FIXME: Can we really import any initializer? Alternatively, we could force
-  // ourselves to import every declaration of a variable and then only use
-  // getInit() here.
-  To->setInit(Importer.Import(const_cast(From->getAnyInitializer(;
+  Expr *FromInit = From->getInit();
+  if (!FromInit)
+return false;
 
-  // FIXME: Other bits to merge?
+  Expr *ToInit = Importer.Import(const_cast(FromInit));
+  if (!ToInit)
+return true;
 
+  To->setInit(ToInit);
+  if (From->isInitKnownICE()) {
+EvaluatedStmt *Eval = To->ensureEvaluatedStmt();
+Eval->CheckedICE = true;
+Eval->IsICE = From->isInitICE();
+  }
+
+  // FIXME: Other bits to merge?
   return false;
 }
 
@@ -3138,6 +3147,16 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl
 }
 
 Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
+
+  SmallVector Redecls = getCanonicalForwardRedeclChain(D);
+  auto RedeclIt = Redecls.begin();
+  // Import the first part of the decl chain. I.e. import all previous
+  // declarations starting from the canonical decl.
+  for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt)
+if (!Importer.Import(*RedeclIt))
+  return nullptr;
+  assert(*RedeclIt == D);
+
   // Import the major distinguishing characteristics of a variable.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
@@ -3150,8 +3169,8 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
 
   // Try to find a variable in our own ("to") context with the same name and
   // in the same context as the variable we're importing.
+  VarDecl *FoundByLookup = nullptr;
   if (D->isFileVarDecl()) {
-VarDecl *MergeWithVar = nullptr;
 SmallVector ConflictingDecls;
 unsigned IDNS = Decl::IDNS_Ordinary;
 SmallVector FoundDecls;
@@ -3166,7 +3185,23 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
 D->hasExternalFormalLinkage()) {
   if (Importer.IsStructurallyEquivalent(D->getType(),
 FoundVar->getType())) {
-MergeWithVar = FoundVar;
+
+// The VarDecl in the "From" context has a definition, but in the
+// "To" context we already have a definition.
+VarDecl *FoundDef = FoundVar->getDefinition();
+if (D->isThisDeclarationADefinition() && FoundDef)

r353425 - [ASTImporter] Refactor unittests to be able to parameterize them in a more flexible way

2019-02-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Feb  7 08:52:48 2019
New Revision: 353425

URL: http://llvm.org/viewvc/llvm-project?rev=353425&view=rev
Log:
[ASTImporter] Refactor unittests to be able to parameterize them in a more 
flexible way

Summary:
Currently `TestImportBase` is derived from `ParameterizedTestsFixture`
which explicitly states that the gtest parameter can be only an
`ArgVector`. This is a limitation when we want to create tests which may
have different parameters.
E.g. we would like to create tests where we can combine different test
parameters. So, for example we'd like gtest to be able to provide
parameters of `` instead of a simple
`ArgVector`.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D57322

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=353425&r1=353424&r2=353425&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu Feb  7 08:52:48 2019
@@ -58,23 +58,31 @@ const StringRef DeclToVerifyID = "declTo
 // Common base for the different families of ASTImporter tests that are
 // parameterized on the compiler options which may result a different AST. E.g.
 // -fms-compatibility or -fdelayed-template-parsing.
-struct ParameterizedTestsFixture : ::testing::TestWithParam {
+class CompilerOptionSpecificTest : public ::testing::Test {
+protected:
+  // Return the extra arguments appended to runtime options at compilation.
+  virtual ArgVector getExtraArgs() const { return ArgVector(); }
 
   // Returns the argument vector used for a specific language option, this set
   // can be tweaked by the test parameters.
   ArgVector getArgVectorForLanguage(Language Lang) const {
 ArgVector Args = getBasicRunOptionsForLanguage(Lang);
-ArgVector ExtraArgs = GetParam();
+ArgVector ExtraArgs = getExtraArgs();
 for (const auto &Arg : ExtraArgs) {
   Args.push_back(Arg);
 }
 return Args;
   }
-
 };
 
+auto DefaultTestValuesForRunOptions = ::testing::Values(
+ArgVector(), ArgVector{"-fdelayed-template-parsing"},
+ArgVector{"-fms-compatibility"},
+ArgVector{"-fdelayed-template-parsing", "-fms-compatibility"});
+
 // Base class for those tests which use the family of `testImport` functions.
-class TestImportBase : public ParameterizedTestsFixture {
+class TestImportBase : public CompilerOptionSpecificTest,
+   public ::testing::WithParamInterface {
 
   template 
   NodeType importNode(ASTUnit *From, ASTUnit *To, ASTImporter &Importer,
@@ -159,6 +167,9 @@ class TestImportBase : public Parameteri
 VerificationMatcher);
   }
 
+protected:
+  ArgVector getExtraArgs() const override { return GetParam(); }
+
 public:
 
   /// Test how AST node named "declToImport" located in the translation unit
@@ -284,7 +295,7 @@ template  RecordDecl *getRec
 // This class provides generic methods to write tests which can check internal
 // attributes of AST nodes like getPreviousDecl(), isVirtual(), etc. Also,
 // this fixture makes it possible to import from several "From" contexts.
-class ASTImporterTestBase : public ParameterizedTestsFixture {
+class ASTImporterTestBase : public CompilerOptionSpecificTest {
 
   const char *const InputFileName = "input.cc";
   const char *const OutputFileName = "output.cc";
@@ -473,11 +484,18 @@ public:
   }
 };
 
+class ASTImporterOptionSpecificTestBase
+: public ASTImporterTestBase,
+  public ::testing::WithParamInterface {
+protected:
+  ArgVector getExtraArgs() const override { return GetParam(); }
+};
+
 struct ImportExpr : TestImportBase {};
 struct ImportType : TestImportBase {};
 struct ImportDecl : TestImportBase {};
 
-struct CanonicalRedeclChain : ASTImporterTestBase {};
+struct CanonicalRedeclChain : ASTImporterOptionSpecificTestBase {};
 
 TEST_P(CanonicalRedeclChain, ShouldBeConsequentWithMatchers) {
   Decl *FromTU = getTuDecl("void f();", Lang_CXX);
@@ -1000,7 +1018,7 @@ TEST_P(ImportDecl, ImportRecordDeclInFun
  has(declStmt(hasSingleDecl(varDecl(hasName("d");
 }
 
-TEST_P(ASTImporterTestBase, ImportRecordTypeInFunc) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordTypeInFunc) {
   Decl *FromTU = getTuDecl("int declToImport() { "
"  struct data_t {int a;int b;};"
"  struct data_t d;"
@@ -1015,7 +1033,7 @@ TEST_P(ASTImporterTestBase, ImportRecord
   EXPECT_FALSE(ToType.isNull());
 }
 
-TEST_P(ASTImporterTestBase, ImportRecordDeclInFuncParams) {
+TEST_P(ASTImporterOptionSpecificTestBase, ImportRecordDeclInFuncParams) {
   // This construct is not supported by ASTImporter.
   Decl *FromTU = getTuDecl(
   "int declToImport(stru

r353504 - [AST] Fix structural inequivalence of operators

2019-02-08 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Feb  8 00:55:32 2019
New Revision: 353504

URL: http://llvm.org/viewvc/llvm-project?rev=353504&view=rev
Log:
[AST] Fix structural inequivalence of operators

Summary: Operators kind was not checked, so we reported e.g. op- to be equal 
with op+

Reviewers: shafik, a_sidorin, aaron.ballman

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57902

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=353504&r1=353503&r2=353504&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Fri Feb  8 00:55:32 2019
@@ -1650,6 +1650,12 @@ bool StructuralEquivalenceContext::Check
 }
   } else if (FunctionDecl *FD1 = dyn_cast(D1)) {
 if (FunctionDecl *FD2 = dyn_cast(D2)) {
+  if (FD1->isOverloadedOperator()) {
+if (!FD2->isOverloadedOperator())
+  return false;
+if (FD1->getOverloadedOperator() != FD2->getOverloadedOperator())
+  return false;
+  }
   if (!::IsStructurallyEquivalent(FD1->getIdentifier(),
   FD2->getIdentifier()))
 return false;

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=353504&r1=353503&r2=353504&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Fri Feb  8 00:55:32 
2019
@@ -230,6 +230,33 @@ TEST_F(StructuralEquivalenceFunctionTest
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+TEST_F(StructuralEquivalenceFunctionTest, DifferentOperators) {
+  auto t = makeDecls(
+  "struct X{}; bool operator<(X, X);",
+  "struct X{}; bool operator==(X, X);", Lang_CXX,
+  functionDecl(hasOverloadedOperatorName("<")),
+  functionDecl(hasOverloadedOperatorName("==")));
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceFunctionTest, SameOperators) {
+  auto t = makeDecls(
+  "struct X{}; bool operator<(X, X);",
+  "struct X{}; bool operator<(X, X);", Lang_CXX,
+  functionDecl(hasOverloadedOperatorName("<")),
+  functionDecl(hasOverloadedOperatorName("<")));
+  EXPECT_TRUE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceFunctionTest, CtorVsDtor) {
+  auto t = makeDecls(
+  "struct X{ X(); };",
+  "struct X{ ~X(); };", Lang_CXX,
+  cxxConstructorDecl(),
+  cxxDestructorDecl());
+  EXPECT_FALSE(testStructuralMatch(t));
+}
+
 TEST_F(StructuralEquivalenceFunctionTest, ParamConstWithRef) {
   auto t = makeNamedDecls("void foo(int&);",
   "void foo(const int&);", Lang_CXX);


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r353505 - [ASTImporter][ASTImporterSpecificLookup] Add test for different operators

2019-02-08 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Feb  8 01:19:34 2019
New Revision: 353505

URL: http://llvm.org/viewvc/llvm-project?rev=353505&view=rev
Log:
[ASTImporter][ASTImporterSpecificLookup] Add test for different operators

Summary:
This is to check that operators are handled properly in
`ASTImporterSpecificLookup`.  Note, this lookup table is not used in LLDB, only
in CTU.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57905

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=353505&r1=353504&r2=353505&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Fri Feb  8 01:19:34 2019
@@ -4812,6 +4812,66 @@ TEST_P(ASTImporterLookupTableTest, Looku
   EXPECT_EQ(Res.count(F2), 1u);
 }
 
+TEST_P(ASTImporterLookupTableTest,
+   DifferentOperatorsShouldHaveDifferentResultSet) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+  R"(
+  struct X{};
+  void operator+(X, X);
+  void operator-(X, X);
+  )",
+  Lang_CXX);
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto *FPlus = FirstDeclMatcher().match(
+  ToTU, functionDecl(hasOverloadedOperatorName("+")));
+  auto *FMinus = FirstDeclMatcher().match(
+  ToTU, functionDecl(hasOverloadedOperatorName("-")));
+  DeclarationName NamePlus = FPlus->getDeclName();
+  auto ResPlus = LT.lookup(ToTU, NamePlus);
+  EXPECT_EQ(ResPlus.size(), 1u);
+  EXPECT_EQ(ResPlus.count(FPlus), 1u);
+  EXPECT_EQ(ResPlus.count(FMinus), 0u);
+  DeclarationName NameMinus = FMinus->getDeclName();
+  auto ResMinus = LT.lookup(ToTU, NameMinus);
+  EXPECT_EQ(ResMinus.size(), 1u);
+  EXPECT_EQ(ResMinus.count(FMinus), 1u);
+  EXPECT_EQ(ResMinus.count(FPlus), 0u);
+  EXPECT_NE(*ResMinus.begin(), *ResPlus.begin());
+}
+
+TEST_P(ASTImporterLookupTableTest, LookupDeclNamesFromDifferentTUs) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+  R"(
+  struct X {};
+  void operator+(X, X);
+  )",
+  Lang_CXX);
+  auto *ToPlus = FirstDeclMatcher().match(
+  ToTU, functionDecl(hasOverloadedOperatorName("+")));
+
+  Decl *FromTU = getTuDecl(
+  R"(
+  struct X {};
+  void operator+(X, X);
+  )",
+  Lang_CXX);
+  auto *FromPlus = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasOverloadedOperatorName("+")));
+
+  // FromPlus have a different TU, thus its DeclarationName is different too.
+  ASSERT_NE(ToPlus->getDeclName(), FromPlus->getDeclName());
+
+  ASTImporterLookupTable LT(*ToTU);
+  auto Res = LT.lookup(ToTU, ToPlus->getDeclName());
+  ASSERT_EQ(Res.size(), 1u);
+  EXPECT_EQ(*Res.begin(), ToPlus);
+
+  // FromPlus have a different TU, thus its DeclarationName is different too.
+  Res = LT.lookup(ToTU, FromPlus->getDeclName());
+  ASSERT_EQ(Res.size(), 0u);
+}
+
 static const RecordDecl * getRecordDeclOfFriend(FriendDecl *FD) {
   QualType Ty = FD->getFriendType()->getType();
   QualType NamedTy = cast(Ty)->getNamedType();


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r353684 - [ASTImporter] Add test RedeclChainShouldBeCorrectAmongstNamespaces

2019-02-11 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Feb 11 02:27:58 2019
New Revision: 353684

URL: http://llvm.org/viewvc/llvm-project?rev=353684&view=rev
Log:
[ASTImporter] Add test RedeclChainShouldBeCorrectAmongstNamespaces

Summary:
We add a new test to show that redecl chains are not handled properly
amongst namespaces. We cannot pass this test now, so this is disabled.
Subsequent patches will make this test pass.

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57901

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=353684&r1=353683&r2=353684&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Feb 11 02:27:58 2019
@@ -5143,6 +5143,47 @@ INSTANTIATE_TEST_CASE_P(
 ParameterizedTests, CanonicalRedeclChain,
 ::testing::Values(ArgVector()),);
 
+// FIXME This test is disabled currently, upcoming patches will make it
+// possible to enable.
+TEST_P(ASTImporterOptionSpecificTestBase,
+   DISABLED_RedeclChainShouldBeCorrectAmongstNamespaces) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  namespace NS {
+struct X;
+struct Y {
+  static const int I = 3;
+};
+  }
+  namespace NS {
+struct X {  // <--- To be imported
+  void method(int i = Y::I) {}
+  int f;
+};
+  }
+  )",
+  Lang_CXX);
+  auto *FromFwd = FirstDeclMatcher().match(
+  FromTU, cxxRecordDecl(hasName("X"), unless(isImplicit(;
+  auto *FromDef = LastDeclMatcher().match(
+  FromTU,
+  cxxRecordDecl(hasName("X"), isDefinition(), unless(isImplicit(;
+  ASSERT_NE(FromFwd, FromDef);
+  ASSERT_FALSE(FromFwd->isThisDeclarationADefinition());
+  ASSERT_TRUE(FromDef->isThisDeclarationADefinition());
+  ASSERT_EQ(FromFwd->getCanonicalDecl(), FromDef->getCanonicalDecl());
+
+  auto *ToDef = cast_or_null(Import(FromDef, Lang_CXX));
+  auto *ToFwd = cast_or_null(Import(FromFwd, Lang_CXX));
+  EXPECT_NE(ToFwd, ToDef);
+  EXPECT_FALSE(ToFwd->isThisDeclarationADefinition());
+  EXPECT_TRUE(ToDef->isThisDeclarationADefinition());
+  EXPECT_EQ(ToFwd->getCanonicalDecl(), ToDef->getCanonicalDecl());
+  auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+  // We expect no (ODR) warning during the import.
+  EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
 DefaultTestValuesForRunOptions, );
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r354027 - [ASTImporter] Check visibility/linkage of functions and variables

2019-02-14 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Feb 14 05:07:03 2019
New Revision: 354027

URL: http://llvm.org/viewvc/llvm-project?rev=354027&view=rev
Log:
[ASTImporter] Check visibility/linkage of functions and variables

Summary:
During import of a global variable with external visibility the lookup
will find variables (with the same name) but with static visibility.
Clearly, we cannot put them into the same redecl chain.  The same is
true in case of functions.  In this fix we filter the lookup results and
consider only those which have the same visibility as the decl we
currently import.

We consider two decls in two anonymous namsepaces to have the same
visibility only if they are imported from the very same translation
unit.

Reviewers: a_sidorin, shafik, a.sidorin

Reviewed By: shafik

Subscribers: jdoerfert, balazske, rnkovacs, dkrupp, Szelethus, gamesh411, 
cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57232

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=354027&r1=354026&r2=354027&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Thu Feb 14 05:07:03 2019
@@ -32,6 +32,7 @@
 namespace clang {
 
 class ASTContext;
+class Attr;
 class ASTImporterLookupTable;
 class CXXBaseSpecifier;
 class CXXCtorInitializer;
@@ -42,8 +43,8 @@ class FileManager;
 class NamedDecl;
 class Stmt;
 class TagDecl;
+class TranslationUnitDecl;
 class TypeSourceInfo;
-class Attr;
 
   class ImportError : public llvm::ErrorInfo {
   public:
@@ -115,6 +116,10 @@ class Attr;
 /// context to the corresponding declarations in the "to" context.
 llvm::DenseMap ImportedDecls;
 
+/// Mapping from the already-imported declarations in the "to"
+/// context to the corresponding declarations in the "from" context.
+llvm::DenseMap ImportedFromDecls;
+
 /// Mapping from the already-imported statements in the "from"
 /// context to the corresponding statements in the "to" context.
 llvm::DenseMap ImportedStmts;
@@ -226,9 +231,13 @@ class Attr;
 
 /// Return the copy of the given declaration in the "to" context if
 /// it has already been imported from the "from" context.  Otherwise return
-/// NULL.
+/// nullptr.
 Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;
 
+/// Return the translation unit from where the declaration was
+/// imported. If it does not exist nullptr is returned.
+TranslationUnitDecl *GetFromTU(Decl *ToD);
+
 /// Import the given declaration context from the "from"
 /// AST context into the "to" AST context.
 ///

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=354027&r1=354026&r2=354027&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Feb 14 05:07:03 2019
@@ -439,6 +439,9 @@ namespace clang {
 
 Error ImportFunctionDeclBody(FunctionDecl *FromFD, FunctionDecl *ToFD);
 
+template 
+bool hasSameVisibilityContext(T *Found, T *From);
+
 bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
@@ -2957,6 +2960,19 @@ Error ASTNodeImporter::ImportFunctionDec
   return Error::success();
 }
 
+template 
+bool ASTNodeImporter::hasSameVisibilityContext(T *Found, T *From) {
+  if (From->hasExternalFormalLinkage())
+return Found->hasExternalFormalLinkage();
+  if (Importer.GetFromTU(Found) != From->getTranslationUnitDecl())
+return false;
+  if (From->isInAnonymousNamespace())
+return Found->isInAnonymousNamespace();
+  else
+return !Found->isInAnonymousNamespace() &&
+   !Found->hasExternalFormalLinkage();
+}
+
 ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 
   SmallVector Redecls = getCanonicalForwardRedeclChain(D);
@@ -3010,33 +3026,30 @@ ExpectedDecl ASTNodeImporter::VisitFunct
 continue;
 
   if (auto *FoundFunction = dyn_cast(FoundDecl)) {
-if (FoundFunction->hasExternalFormalLinkage() &&
-D->hasExternalFormalLinkage()) {
-  if (IsStructuralMatch(D, FoundFunction)) {
-const FunctionDecl *Definition = nullptr;
-if (D->doesThisDeclarationHaveABody() &&
-FoundFunction->hasBody(Definition)) {
-  return Importer.MapImported(
-  D, const_cast(Definition));
-}
-FoundByLookup = FoundFunction;
-break;
-  }
+if (!hasSameVisibilit

r354120 - [ASTImporter] Import every Decl in lambda record

2019-02-15 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Feb 15 04:04:05 2019
New Revision: 354120

URL: http://llvm.org/viewvc/llvm-project?rev=354120&view=rev
Log:
[ASTImporter] Import every Decl in lambda record

Summary:
Previously only the fields were imported. Now every Decl is imported.
This way the destructor decl is not missing after import.

Patch by balazske (Balázs Kéri)

Reviewers: a.sidorin, shafik

Reviewed By: shafik

Subscribers: balazske, cfe-commits, Szelethus, martong, dkrupp

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57740

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=354120&r1=354119&r2=354120&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Fri Feb 15 04:04:05 2019
@@ -7393,13 +7393,9 @@ ExpectedStmt ASTNodeImporter::VisitLambd
   // NOTE: lambda classes are created with BeingDefined flag set up.
   // It means that ImportDefinition doesn't work for them and we should fill it
   // manually.
-  if (ToClass->isBeingDefined()) {
-for (auto FromField : FromClass->fields()) {
-  auto ToFieldOrErr = import(FromField);
-  if (!ToFieldOrErr)
-return ToFieldOrErr.takeError();
-}
-  }
+  if (ToClass->isBeingDefined())
+if (Error Err = ImportDeclContext(FromClass, /*ForceImport = */ true))
+  return std::move(Err);
 
   auto ToCallOpOrErr = import(E->getCallOperator());
   if (!ToCallOpOrErr)

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=354120&r1=354119&r2=354120&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Fri Feb 15 04:04:05 2019
@@ -2709,6 +2709,26 @@ TEST_P(ImportFunctions, ImportFunctionFr
 2u);
 }
 
+TEST_P(ImportFunctions, ImportImplicitFunctionsInLambda) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  void foo() {
+(void)[]() { ; };
+  }
+  )",
+  Lang_CXX11);
+  auto *FromD = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasName("foo")));
+  auto *ToD = Import(FromD, Lang_CXX);
+  EXPECT_TRUE(ToD);
+  CXXRecordDecl *LambdaRec =
+  cast(cast(
+   *cast(ToD->getBody())->body_begin())
+   ->getSubExpr())
+  ->getLambdaClass();
+  EXPECT_TRUE(LambdaRec->getDestructor());
+}
+
 struct ImportFriendFunctions : ImportFunctions {};
 
 TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainProto) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r354259 - [ASTImporter] Unify redecl chain tests as type parameterized tests

2019-02-18 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Feb 18 03:09:56 2019
New Revision: 354259

URL: http://llvm.org/viewvc/llvm-project?rev=354259&view=rev
Log:
[ASTImporter] Unify redecl chain tests as type parameterized tests

Summary:
This patch unifies all those tests which check the correctness of the
redecl chains. Previously we had several structurally very similar test
cases for each language construct (class, function, variable, function
template, ...).

We still use value-parameterized tests for the different AST
compatibility switches (-fdelayed-template-parsing, -fms-compatibility).
Gtest makes it possible to have either value-parameterized or
type-parameterized fixtures. However, we cannot have both value- and
type-parameterized test fixtures. So we use a value-parameterized test
fixture in the gtest sense. We intend to mimic gtest's type-parameters
via the type template parameter. We manually instantiate the different
tests with the each types.

After this patch I am planning to put the "generic redecl chain" related
tests into their own separate test file (in another patch).

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D57236

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=354259&r1=354258&r2=354259&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Feb 18 03:09:56 2019
@@ -2008,33 +2008,6 @@ TEST_P(ASTImporterOptionSpecificTestBase
 
 struct ImportFunctions : ASTImporterOptionSpecificTestBase {};
 
-TEST_P(ImportFunctions,
-   DefinitionShouldBeImportedAsDefintionWhenThereIsAPrototype) {
-  Decl *FromTU = getTuDecl("void f(); void f() {}", Lang_CXX);
-  auto Pattern = functionDecl(hasName("f"));
-  FunctionDecl *FromD = // Definition
-  LastDeclMatcher().match(FromTU, Pattern);
-
-  Decl *ImportedD = Import(FromD, Lang_CXX);
-  Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
-  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
-  EXPECT_TRUE(cast(ImportedD)->doesThisDeclarationHaveABody());
-}
-
-TEST_P(ImportFunctions, DefinitionShouldBeImportedAsADefinition) {
-  Decl *FromTU = getTuDecl("void f() {}", Lang_CXX);
-  auto Pattern = functionDecl(hasName("f"));
-  FunctionDecl *FromD =
-  FirstDeclMatcher().match(FromTU, Pattern);
-
-  Decl *ImportedD = Import(FromD, Lang_CXX);
-  Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
-  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u);
-  EXPECT_TRUE(cast(ImportedD)->doesThisDeclarationHaveABody());
-}
-
 TEST_P(ImportFunctions, ImportPrototypeOfRecursiveFunction) {
   Decl *FromTU = getTuDecl("void f(); void f() { f(); }", Lang_CXX);
   auto Pattern = functionDecl(hasName("f"));
@@ -2071,138 +2044,6 @@ TEST_P(ImportFunctions, ImportDefinition
   EXPECT_EQ(To1->getPreviousDecl(), To0);
 }
 
-TEST_P(ImportFunctions, ImportPrototypes) {
-  auto Pattern = functionDecl(hasName("f"));
-
-  Decl *ImportedD;
-  {
-Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input0.cc");
-auto *FromD = FirstDeclMatcher().match(FromTU, Pattern);
-
-ImportedD = Import(FromD, Lang_CXX);
-  }
-  {
-Decl *FromTU = getTuDecl("void f();", Lang_CXX, "input1.cc");
-auto *FromD = FirstDeclMatcher().match(FromTU, Pattern);
-Import(FromD, Lang_CXX);
-  }
-
-  Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
-  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 2u);
-  auto *To0 = FirstDeclMatcher().match(ToTU, Pattern);
-  auto *To1 = LastDeclMatcher().match(ToTU, Pattern);
-  EXPECT_TRUE(ImportedD == To0);
-  EXPECT_FALSE(To0->doesThisDeclarationHaveABody());
-  EXPECT_FALSE(To1->doesThisDeclarationHaveABody());
-  EXPECT_EQ(To1->getPreviousDecl(), To0);
-}
-
-TEST_P(ImportFunctions, ImportDefinitions) {
-  auto Pattern = functionDecl(hasName("f"));
-
-  Decl *ImportedD;
-  {
-Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input0.cc");
-auto *FromD = FirstDeclMatcher().match(FromTU, Pattern);
-ImportedD = Import(FromD, Lang_CXX);
-  }
-  {
-Decl *FromTU = getTuDecl("void f(){};", Lang_CXX, "input1.cc");
-auto *FromD = FirstDeclMatcher().match(FromTU, Pattern);
-Import(FromD, Lang_CXX);
-  }
-
-  Decl *ToTU = ImportedD->getTranslationUnitDecl();
-
-  EXPECT_EQ(DeclCounter().match(ToTU, Pattern), 1u);
-  auto *To0 = FirstDeclMatcher().match(ToTU, Pattern);
-  EXPECT_TRUE(ImportedD == To0);
-  EXPECT_TRUE(To0->doesThisDeclarationHaveABody());
-}
-
-TEST_P(ImportFunctions, ImportDefinitionThenPrototype) {
-  auto Pattern = functionDecl(hasName("f"));
-
-  Decl *ImportedD;
-  {
-Decl *FromTU = getTuDecl("void f(){}", Lang_CXX, "input0.cc");
-auto *FromD = FirstDeclMatcher().match(FromTU, Pattern);
-ImportedD = Import(F

r354267 - [ASTImporter] Find previous friend function template

2019-02-18 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Feb 18 05:09:27 2019
New Revision: 354267

URL: http://llvm.org/viewvc/llvm-project?rev=354267&view=rev
Log:
[ASTImporter] Find previous friend function template

Reviewers: a_sidorin, shafik, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57910

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=354267&r1=354266&r2=354267&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Feb 18 05:09:27 2019
@@ -5540,7 +5540,7 @@ ASTNodeImporter::VisitFunctionTemplateDe
   // 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.
   if (!LexicalDC->isFunctionOrMethod()) {
-unsigned IDNS = Decl::IDNS_Ordinary;
+unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
 auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
 for (auto *FoundDecl : FoundDecls) {
   if (!FoundDecl->isInIdentifierNamespace(IDNS))

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=354267&r1=354266&r2=354267&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Feb 18 05:09:27 2019
@@ -5390,6 +5390,33 @@ TEST_P(ASTImporterOptionSpecificTestBase
   EXPECT_EQ(0u, ToTU->getASTContext().getDiagnostics().getNumWarnings());
 }
 
+struct ImportFriendFunctionTemplates : ASTImporterOptionSpecificTestBase {};
+
+TEST_P(ImportFriendFunctionTemplates, LookupShouldFindPreviousFriend) {
+  Decl *ToTU = getToTuDecl(
+  R"(
+  class X {
+template  friend void foo();
+  };
+  )",
+  Lang_CXX);
+  auto *Friend = FirstDeclMatcher().match(
+  ToTU, functionTemplateDecl(hasName("foo")));
+
+  Decl *FromTU = getTuDecl(
+  R"(
+  template  void foo();
+  )",
+  Lang_CXX);
+  auto *FromFoo = FirstDeclMatcher().match(
+  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);
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
 DefaultTestValuesForRunOptions, );
 
@@ -5408,6 +5435,9 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTes
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFunctions,
 DefaultTestValuesForRunOptions, );
 
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportFriendFunctionTemplates,
+DefaultTestValuesForRunOptions, );
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClasses,
 DefaultTestValuesForRunOptions, );
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r354482 - Fix compile error with Intel's compiler (-Werror=pedantic)

2019-02-20 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Feb 20 08:57:41 2019
New Revision: 354482

URL: http://llvm.org/viewvc/llvm-project?rev=354482&view=rev
Log:
Fix compile error with Intel's compiler (-Werror=pedantic)

An extra semicolon at the end of macro invocations caused a build bot
failure for Intel's compiler when pedantic is turned on.

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=354482&r1=354481&r2=354482&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Wed Feb 20 08:57:41 2019
@@ -4156,175 +4156,175 @@ struct RedeclChain : ASTImporterOptionSp
 
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 RedeclChain, Function, ,
-PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 RedeclChain, Class, ,
-PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 RedeclChain, Variable, ,
-PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
 // FIXME Enable this test, once we import function templates chains correctly.
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 RedeclChain, FunctionTemplate, DISABLED_,
-PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 RedeclChain, ClassTemplate, ,
-PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 RedeclChain, FunctionTemplateSpec, ,
-PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition);
+PrototypeShouldBeImportedAsAPrototypeWhenThereIsNoDefinition)
 
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
-RedeclChain, Function, , DefinitionShouldBeImportedAsADefinition);
+RedeclChain, Function, , DefinitionShouldBeImportedAsADefinition)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
-RedeclChain, Class, , DefinitionShouldBeImportedAsADefinition);
+RedeclChain, Class, , DefinitionShouldBeImportedAsADefinition)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
-RedeclChain, Variable, , DefinitionShouldBeImportedAsADefinition);
+RedeclChain, Variable, , DefinitionShouldBeImportedAsADefinition)
 // FIXME Enable this test, once we import function templates chains correctly.
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 RedeclChain, FunctionTemplate, DISABLED_,
-DefinitionShouldBeImportedAsADefinition);
+DefinitionShouldBeImportedAsADefinition)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
-RedeclChain, ClassTemplate, , DefinitionShouldBeImportedAsADefinition);
+RedeclChain, ClassTemplate, , DefinitionShouldBeImportedAsADefinition)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 RedeclChain, FunctionTemplateSpec, ,
-DefinitionShouldBeImportedAsADefinition);
+DefinitionShouldBeImportedAsADefinition)
 
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
-ImportPrototypeAfterImportedPrototype);
+ImportPrototypeAfterImportedPrototype)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, ,
-ImportPrototypeAfterImportedPrototype);
+ImportPrototypeAfterImportedPrototype)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
-ImportPrototypeAfterImportedPrototype);
+ImportPrototypeAfterImportedPrototype)
 // FIXME Enable this test, once we import function templates chains correctly.
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
 DISABLED_,
-ImportPrototypeAfterImportedPrototype);
+ImportPrototypeAfterImportedPrototype)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, ClassTemplate, ,
-ImportPrototypeAfterImportedPrototype);
+ImportPrototypeAfterImportedPrototype)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplateSpec, ,
-ImportPrototypeAfterImportedPrototype);
+ImportPrototypeAfterImportedPrototype)
 
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
- 

r354503 - Fix remaining semicolon pedantic errors for intel

2019-02-20 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Feb 20 11:07:36 2019
New Revision: 354503

URL: http://llvm.org/viewvc/llvm-project?rev=354503&view=rev
Log:
Fix remaining semicolon pedantic errors for intel

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=354503&r1=354502&r2=354503&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Wed Feb 20 11:07:36 2019
@@ -4240,10 +4240,10 @@ ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(
 ImportPrototypeAfterImportedDefinition)
 
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Function, ,
-ImportPrototypes);
+ImportPrototypes)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Class, , ImportPrototypes)
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, Variable, ,
-ImportPrototypes);
+ImportPrototypes)
 // FIXME Enable this test, once we import function templates chains correctly.
 ASTIMPORTER_INSTANTIATE_TYPED_TEST_CASE(RedeclChain, FunctionTemplate,
 DISABLED_, ImportPrototypes)


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r363062 - [ASTImporter] Fix unhandled cases in ASTImporterLookupTable

2019-06-11 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Jun 11 06:35:25 2019
New Revision: 363062

URL: http://llvm.org/viewvc/llvm-project?rev=363062&view=rev
Log:
[ASTImporter] Fix unhandled cases in ASTImporterLookupTable

Summary:
In most cases the FriendDecl contains the declaration of the befriended
class as a child node, so it is discovered during the recursive
visitation. However, there are cases when the befriended class is not a
child, thus it must be fetched explicitly from the FriendDecl, and only
then can we add it to the lookup table.
(Note, this does affect only CTU and does not affect LLDB, because we
cannot and do not use the ASTImporterLookupTable in LLDB.)

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62064

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/ASTImporterLookupTable.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=363062&r1=363061&r2=363062&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Jun 11 06:35:25 2019
@@ -2256,7 +2256,8 @@ ASTNodeImporter::VisitTypedefNameDecl(Ty
   if (!FromUT->isIncompleteType() && !FoundUT->isIncompleteType())
 return Importer.MapImported(D, FoundTypedef);
 }
-// FIXME Handle redecl chain.
+// FIXME Handle redecl chain. When you do that make consistent changes
+// in ASTImporterLookupTable too.
 break;
   }
 

Modified: cfe/trunk/lib/AST/ASTImporterLookupTable.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporterLookupTable.cpp?rev=363062&r1=363061&r2=363062&view=diff
==
--- cfe/trunk/lib/AST/ASTImporterLookupTable.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporterLookupTable.cpp Tue Jun 11 06:35:25 2019
@@ -26,17 +26,30 @@ struct Builder : RecursiveASTVisitorgetFriendType()) {
   QualType Ty = D->getFriendType()->getType();
-  // FIXME Can this be other than elaborated?
-  QualType NamedTy = cast(Ty)->getNamedType();
-  if (!NamedTy->isDependentType()) {
-if (const auto *RTy = dyn_cast(NamedTy))
+  if (isa(Ty))
+Ty = cast(Ty)->getNamedType();
+  // A FriendDecl with a dependent type (e.g. ClassTemplateSpecialization)
+  // always has that decl as child node.
+  // However, there are non-dependent cases which does not have the
+  // type as a child node. We have to dig up that type now.
+  if (!Ty->isDependentType()) {
+if (const auto *RTy = dyn_cast(Ty))
   LT.add(RTy->getAsCXXRecordDecl());
-else if (const auto *SpecTy =
- dyn_cast(NamedTy)) {
+else if (const auto *SpecTy = dyn_cast(Ty))
   LT.add(SpecTy->getAsCXXRecordDecl());
+else if (isa(Ty)) {
+  // We do not put friend typedefs to the lookup table because
+  // ASTImporter does not organize typedefs into redecl chains.
+} else {
+  llvm_unreachable("Unhandled type of friend class");
 }
   }
 }

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=363062&r1=363061&r2=363062&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Tue Jun 11 06:35:25 2019
@@ -4237,13 +4237,13 @@ TEST_P(ASTImporterLookupTableTest, Looku
   ASSERT_EQ(Res.size(), 0u);
 }
 
-static const RecordDecl * getRecordDeclOfFriend(FriendDecl *FD) {
-  QualType Ty = FD->getFriendType()->getType();
-  QualType NamedTy = cast(Ty)->getNamedType();
-  return cast(NamedTy)->getDecl();
+static const RecordDecl *getRecordDeclOfFriend(FriendDecl *FD) {
+  QualType Ty = FD->getFriendType()->getType().getCanonicalType();
+  return cast(Ty)->getDecl();
 }
 
-TEST_P(ASTImporterLookupTableTest, LookupFindsFwdFriendClassDecl) {
+TEST_P(ASTImporterLookupTableTest,
+   LookupFindsFwdFriendClassDeclWithElaboratedType) {
   TranslationUnitDecl *ToTU = getToTuDecl(
   R"(
   class Y { friend class F; };
@@ -4267,6 +4267,52 @@ TEST_P(ASTImporterLookupTableTest, Looku
   EXPECT_EQ(Res.size(), 0u);
 }
 
+TEST_P(ASTImporterLookupTableTest,
+   LookupFindsFwdFriendClassDeclWithUnelaboratedType) {
+  TranslationUnitDecl *ToTU = getToTuDecl(
+  R"(
+  class F;
+  class Y { friend F; };
+  )",
+  Lang_CXX11);
+
+  // In this case, the CXXRecordDecl is hidden, the FriendDecl is not a parent.
+  // So we must dig up the underlying CXXRecordDecl.
+  ASTImporterLookupTable LT(*ToTU);
+  auto *Frien

r366325 - [ASTImporter] Fix LLDB lookup in transparent ctx and with ext src

2019-07-17 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Jul 17 06:47:46 2019
New Revision: 366325

URL: http://llvm.org/viewvc/llvm-project?rev=366325&view=rev
Log:
[ASTImporter] Fix LLDB lookup in transparent ctx and with ext src

Summary:
With LLDB we use localUncachedLookup(), however, that fails to find
Decls when a transparent context is involved and the given DC has
external lexical storage.  The solution is to use noload_lookup, which
works well with transparent contexts.  But, we cannot use only the
noload_lookup since the slow case of localUncachedLookup is still needed
in some other cases.

These other cases are handled in ASTImporterLookupTable, but we cannot
use that with LLDB since that traverses through the AST which initiates
the load of external decls again via DC::decls().

We must avoid loading external decls during the import becuase
ExternalASTSource is implemented with ASTImporter, so external loads
during import results in uncontrolled and faulty import.

Reviewers: shafik, teemperor, jingham, clayborg, a_sidorin, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits

Tags: #clang, #lldb

Differential Revision: https://reviews.llvm.org/D61333

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=366325&r1=366324&r2=366325&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Jul 17 06:47:46 2019
@@ -1707,6 +1707,17 @@ static Error setTypedefNameForAnonDecl(T
 
 Error ASTNodeImporter::ImportDefinition(
 RecordDecl *From, RecordDecl *To, ImportDefinitionKind Kind) {
+  auto DefinitionCompleter = [To]() {
+// There are cases in LLDB when we first import a class without its
+// members. The class will have DefinitionData, but no members. Then,
+// importDefinition is called from LLDB, which tries to get the members, so
+// when we get here, the class already has the DefinitionData set, so we
+// must unset the CompleteDefinition here to be able to complete again the
+// definition.
+To->setCompleteDefinition(false);
+To->completeDefinition();
+  };
+
   if (To->getDefinition() || To->isBeingDefined()) {
 if (Kind == IDK_Everything ||
 // In case of lambdas, the class already has a definition ptr set, but
@@ -1717,7 +1728,7 @@ Error ASTNodeImporter::ImportDefinition(
   Error Result = ImportDeclContext(From, /*ForceImport=*/true);
   // Finish the definition of the lambda, set isBeingDefined to false.
   if (To->isLambda())
-To->completeDefinition();
+DefinitionCompleter();
   return Result;
 }
 
@@ -1728,8 +1739,8 @@ Error ASTNodeImporter::ImportDefinition(
   // Complete the definition even if error is returned.
   // The RecordDecl may be already part of the AST so it is better to
   // have it in complete state even if something is wrong with it.
-  auto DefinitionCompleter =
-  llvm::make_scope_exit([To]() { To->completeDefinition(); });
+  auto DefinitionCompleterScopeExit =
+  llvm::make_scope_exit(DefinitionCompleter);
 
   if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
 return Err;
@@ -7757,10 +7768,20 @@ ASTImporter::findDeclsInToCtx(DeclContex
 SharedState->getLookupTable()->lookup(ReDC, Name);
 return FoundDeclsTy(LookupResult.begin(), LookupResult.end());
   } else {
-// FIXME Can we remove this kind of lookup?
-// Or lldb really needs this C/C++ lookup?
-FoundDeclsTy Result;
-ReDC->localUncachedLookup(Name, Result);
+DeclContext::lookup_result NoloadLookupResult = ReDC->noload_lookup(Name);
+FoundDeclsTy Result(NoloadLookupResult.begin(), NoloadLookupResult.end());
+// We must search by the slow case of localUncachedLookup because that is
+// working even if there is no LookupPtr for the DC. We could use
+// DC::buildLookup() to create the LookupPtr, but that would load external
+// decls again, we must avoid that case.
+// Also, even if we had the LookupPtr, we must find Decls which are not
+// in the LookupPtr, so we need the slow case.
+// These cases are handled in ASTImporterLookupTable, but we cannot use
+// that with LLDB since that traverses through the AST which initiates the
+// load of external decls again via DC::decls().  And again, we must avoid
+// loading external decls during the import.
+if (Result.empty())
+  ReDC->localUncachedLookup(Name, Result);
 return Result;
   }
 }

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=366325&r1=366324&r2=366325&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporte

r366332 - [ASTImporter] Fix structural eq of lambdas

2019-07-17 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Jul 17 07:40:09 2019
New Revision: 366332

URL: http://llvm.org/viewvc/llvm-project?rev=366332&view=rev
Log:
[ASTImporter] Fix structural eq of lambdas

Summary:
The structural equivalence check reported false eq between lambda classes
with different parameters in their call signature.
The solution is to check the methods for equality too in case of lambda
classes.

Reviewers: a_sidorin, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64075

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=366332&r1=366331&r2=366332&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Wed Jul 17 07:40:09 2019
@@ -1085,6 +1085,19 @@ static bool IsStructurallyEquivalent(Str
   return true;
 }
 
+/// Determine structural equivalence of two lambda classes.
+static bool
+IsStructurallyEquivalentLambdas(StructuralEquivalenceContext &Context,
+CXXRecordDecl *D1, CXXRecordDecl *D2) {
+  assert(D1->isLambda() && D2->isLambda() &&
+ "Must be called on lambda classes");
+  if (!IsStructurallyEquivalent(Context, D1->getLambdaCallOperator(),
+D2->getLambdaCallOperator()))
+return false;
+
+  return true;
+}
+
 /// Determine structural equivalence of two records.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  RecordDecl *D1, RecordDecl *D2) {
@@ -1166,6 +1179,13 @@ static bool IsStructurallyEquivalent(Str
 D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
   }
 
+  if (D1CXX->isLambda() != D2CXX->isLambda())
+return false;
+  if (D1CXX->isLambda()) {
+if (!IsStructurallyEquivalentLambdas(Context, D1CXX, D2CXX))
+  return false;
+  }
+
   if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
 if (Context.Complain) {
   Context.Diag2(D2->getLocation(),

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=366332&r1=366331&r2=366332&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Wed Jul 17 07:40:09 2019
@@ -5122,6 +5122,22 @@ TEST_P(ASTImporterOptionSpecificTestBase
   EXPECT_EQ(ToLSize, FromLSize);
 }
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaInGlobalScope) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  auto l1 = [](unsigned lp) { return 1; };
+  auto l2 = [](int lp) { return 2; };
+  int f(int p) {
+return l1(p) + l2(p);
+  }
+  )",
+  Lang_CXX11, "input0.cc");
+  FunctionDecl *FromF = FirstDeclMatcher().match(
+  FromTU, functionDecl(hasName("f")));
+  FunctionDecl *ToF = Import(FromF, Lang_CXX11);
+  EXPECT_TRUE(ToF);
+}
+
 struct LLDBLookupTest : ASTImporterOptionSpecificTestBase {
   LLDBLookupTest() {
 Creator = [](ASTContext &ToContext, FileManager &ToFileManager,

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=366332&r1=366331&r2=366332&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Wed Jul 17 07:40:09 
2019
@@ -797,6 +797,58 @@ TEST_F(StructuralEquivalenceRecordTest,
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
+struct StructuralEquivalenceLambdaTest : StructuralEquivalenceTest {};
+
+TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithDifferentMethods) {
+  // Get the LambdaExprs, unfortunately we can't match directly the underlying
+  // implicit CXXRecordDecl of the Lambda classes.
+  auto t = makeDecls(
+  "void f() { auto L0 = [](int){}; }",
+  "void f() { auto L1 = [](){}; }",
+  Lang_CXX11,
+  lambdaExpr(),
+  lambdaExpr());
+  CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
+  CXXRecordDecl *L1 = get<1>(t)->getLambdaClass();
+  EXPECT_FALSE(testStructuralMatch(L0, L1));
+}
+
+TEST_F(StructuralEquivalenceLambdaTest, LambdaClassesWithEqMethods) {
+  auto t = makeDecls(
+  "void f() { auto L0 = [](int){}; }",
+  "void f() { auto L1 = [](int){}; }",
+  Lang_CXX11,
+  lambdaExpr(),
+  lambdaExpr());
+  CXXRecordDecl *L0 = get<0>(t)->getLambdaClass();
+  CXXRecordDecl *L1 =

r366439 - [analyzer] Add CTU user docs

2019-07-18 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jul 18 07:03:25 2019
New Revision: 366439

URL: http://llvm.org/viewvc/llvm-project?rev=366439&view=rev
Log:
[analyzer] Add CTU user docs

Reviewers: dkrupp, a_sidorin, Szelethus, NoQ

Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, 
a.sidorin, mikhail.ramalho, donat.nagy, gamesh411, Charusso, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64801

Added:
cfe/trunk/docs/analyzer/user-docs/
cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst
Modified:
cfe/trunk/docs/analyzer/user-docs.rst

Modified: cfe/trunk/docs/analyzer/user-docs.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/user-docs.rst?rev=366439&r1=366438&r2=366439&view=diff
==
--- cfe/trunk/docs/analyzer/user-docs.rst (original)
+++ cfe/trunk/docs/analyzer/user-docs.rst Thu Jul 18 07:03:25 2019
@@ -2,3 +2,8 @@ User Docs
 =
 
 Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   user-docs/CrossTranslationUnit

Added: cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst?rev=366439&view=auto
==
--- cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst (added)
+++ cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst Thu Jul 18 
07:03:25 2019
@@ -0,0 +1,202 @@
+=
+Cross Translation Unit (CTU) Analysis
+=
+
+Normally, static analysis works in the boundary of one translation unit (TU).
+However, with additional steps and configuration we can enable the analysis to 
inline the definition of a function from another TU.
+
+.. contents::
+   :local:
+
+Manual CTU Analysis
+---
+
+Let's consider these source files in our minimal example:
+
+.. code-block:: cpp
+
+  // main.cpp
+  int foo();
+
+  int main() {
+return 3 / foo();
+  }
+
+.. code-block:: cpp
+
+  // foo.cpp
+  int foo() {
+return 0;
+  }
+
+And a compilation database:
+
+.. code-block:: bash
+
+  [
+{
+  "directory": "/path/to/your/project",
+  "command": "clang++ -c foo.cpp -o foo.o",
+  "file": "foo.cpp"
+},
+{
+  "directory": "/path/to/your/project",
+  "command": "clang++ -c main.cpp -o main.o",
+  "file": "main.cpp"
+}
+  ]
+
+We'd like to analyze `main.cpp` and discover the division by zero bug.
+In order to be able to inline the definition of `foo` from `foo.cpp` first we 
have to generate the `AST` (or `PCH`) file of `foo.cpp`:
+
+.. code-block:: bash
+
+  $ pwd $ /path/to/your/project
+  $ clang++ -emit-ast -o foo.cpp.ast foo.cpp
+  $ # Check that the .ast file is generated:
+  $ ls
+  compile_commands.json  foo.cpp.ast  foo.cpp  main.cpp
+  $
+
+The next step is to create a CTU index file which holds the `USR` name and 
location of external definitions in the source files:
+
+.. code-block:: bash
+
+  $ clang-extdef-mapping -p . foo.cpp
+  c:@F@foo# /path/to/your/project/foo.cpp
+  $ clang-extdef-mapping -p . foo.cpp > externalDefMap.txt
+
+We have to modify `externalDefMap.txt` to contain the name of the `.ast` files 
instead of the source files:
+
+.. code-block:: bash
+
+  $ sed -i -e "s/.cpp/.cpp.ast/g" externalDefMap.txt
+
+We still have to further modify the `externalDefMap.txt` file to contain 
relative paths:
+
+.. code-block:: bash
+
+  $ sed -i -e "s|$(pwd)/||g" externalDefMap.txt
+
+Now everything is available for the CTU analysis.
+We have to feed Clang with CTU specific extra arguments:
+
+.. code-block:: bash
+
+  $ pwd
+  /path/to/your/project
+  $ clang++ --analyze -Xclang -analyzer-config -Xclang 
experimental-enable-naive-ctu-analysis=true -Xclang -analyzer-config -Xclang 
ctu-dir=. -Xclang -analyzer-output=plist-multi-file main.cpp
+  main.cpp:5:12: warning: Division by zero
+return 3 / foo();
+   ~~^~~
+  1 warning generated.
+  $ # The plist file with the result is generated.
+  $ ls
+  compile_commands.json  externalDefMap.txt  foo.ast  foo.cpp  foo.cpp.ast  
main.cpp  main.plist
+  $
+
+This manual procedure is error-prone and not scalable, therefore to analyze 
real projects it is recommended to use `CodeChecker` or `scan-build-py`.
+
+Automated CTU Analysis with CodeChecker
+---
+The `CodeChecker `_ project fully 
supports automated CTU analysis with Clang.
+Once we have set up the `PATH` environment variable and we activated the 
python `venv` then it is all it takes:
+
+.. code-block:: bash
+
+  $ CodeChecker analyze --ctu compile_commands.json -o reports
+  [INFO 2019-07-16 17:21] - Pre-analysis started.
+  [INFO 2019-07-16 17:21] - Collecting data for ctu analysis.
+  [INFO 2019-07-16 17:21] - [1/2] foo.cpp
+  [INFO 2019-07-16 17:21] - [2/2] main.

r366818 - [ASTImporter] Fix inequivalence of ClassTemplateInstantiations

2019-07-23 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Jul 23 08:46:38 2019
New Revision: 366818

URL: http://llvm.org/viewvc/llvm-project?rev=366818&view=rev
Log:
[ASTImporter] Fix inequivalence of ClassTemplateInstantiations

Summary:
We falsely state inequivalence if the template parameter is a
qualified/nonquialified template in the first/second instantiation.
Also, different kinds of TemplateName should be equal if the template
decl (if available) is equal (even if the name kind is different).

Reviewers: a_sidorin, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64241

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=366818&r1=366817&r2=366818&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Tue Jul 23 08:46:38 2019
@@ -235,12 +235,21 @@ static bool IsStructurallyEquivalent(Str
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  const TemplateName &N1,
  const TemplateName &N2) {
-  if (N1.getKind() != N2.getKind())
+  TemplateDecl *TemplateDeclN1 = N1.getAsTemplateDecl();
+  TemplateDecl *TemplateDeclN2 = N2.getAsTemplateDecl();
+  if (TemplateDeclN1 && TemplateDeclN2) {
+if (!IsStructurallyEquivalent(Context, TemplateDeclN1, TemplateDeclN2))
+  return false;
+// If the kind is different we compare only the template decl.
+if (N1.getKind() != N2.getKind())
+  return true;
+  } else if (TemplateDeclN1 || TemplateDeclN2)
+return false;
+  else if (N1.getKind() != N2.getKind())
 return false;
+
+  // Check for special case incompatibilities.
   switch (N1.getKind()) {
-  case TemplateName::Template:
-return IsStructurallyEquivalent(Context, N1.getAsTemplateDecl(),
-N2.getAsTemplateDecl());
 
   case TemplateName::OverloadedTemplate: {
 OverloadedTemplateStorage *OS1 = N1.getAsOverloadedTemplate(),
@@ -259,14 +268,6 @@ static bool IsStructurallyEquivalent(Str
 return TN1->getDeclName() == TN2->getDeclName();
   }
 
-  case TemplateName::QualifiedTemplate: {
-QualifiedTemplateName *QN1 = N1.getAsQualifiedTemplateName(),
-  *QN2 = N2.getAsQualifiedTemplateName();
-return IsStructurallyEquivalent(Context, QN1->getDecl(), QN2->getDecl()) &&
-   IsStructurallyEquivalent(Context, QN1->getQualifier(),
-QN2->getQualifier());
-  }
-
   case TemplateName::DependentTemplate: {
 DependentTemplateName *DN1 = N1.getAsDependentTemplateName(),
   *DN2 = N2.getAsDependentTemplateName();
@@ -281,15 +282,6 @@ static bool IsStructurallyEquivalent(Str
 return false;
   }
 
-  case TemplateName::SubstTemplateTemplateParm: {
-SubstTemplateTemplateParmStorage *TS1 = 
N1.getAsSubstTemplateTemplateParm(),
- *TS2 = 
N2.getAsSubstTemplateTemplateParm();
-return IsStructurallyEquivalent(Context, TS1->getParameter(),
-TS2->getParameter()) &&
-   IsStructurallyEquivalent(Context, TS1->getReplacement(),
-TS2->getReplacement());
-  }
-
   case TemplateName::SubstTemplateTemplateParmPack: {
 SubstTemplateTemplateParmPackStorage
 *P1 = N1.getAsSubstTemplateTemplateParmPack(),
@@ -299,8 +291,16 @@ static bool IsStructurallyEquivalent(Str
IsStructurallyEquivalent(Context, P1->getParameterPack(),
 P2->getParameterPack());
   }
+
+   case TemplateName::Template:
+   case TemplateName::QualifiedTemplate:
+   case TemplateName::SubstTemplateTemplateParm:
+ // It is sufficient to check value of getAsTemplateDecl.
+ break;
+
   }
-  return false;
+
+  return true;
 }
 
 /// Determine whether two template arguments are equivalent.

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=366818&r1=366817&r2=366818&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Tue Jul 23 08:46:38 
2019
@@ -944,6 +944,67 @@ TEST_F(StructuralEquivalenceTemplateTest
   EXPECT_FALSE(testStructuralMatch(First, Second));
 }
 
+TEST_F(StructuralEquivalenceTemplateTest,
+   TemplateVsSubstTemplateTemplateParmInArgEq) {
+  auto t = makeDecls(
+  R"(
+template  class Arg { };
+template  class P1> cla

r366997 - [ASTImporter] Reorder fields after structure import is finished

2019-07-25 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jul 25 02:07:17 2019
New Revision: 366997

URL: http://llvm.org/viewvc/llvm-project?rev=366997&view=rev
Log:
[ASTImporter] Reorder fields after structure import is finished

We reorder declarations in RecordDecls because they may have another order
in the "to" context than they have in the "from" context. This may happen
e.g when we import a class like this:
   struct declToImport {
   int a = c + b;
   int b = 1;
   int c = 2;
   };
During the import of `a` we import first the dependencies in sequence,
thus the order would be `c`, `b`, `a`. We will get the normal order by
first removing the already imported members and then adding them in the
order as they apper in the "from" context.

Keeping field order is vital because it determines structure layout.

Reviewers: a_sidorin, shafik

Tags: #clang

Differential Revision: https://reviews.llvm.org/D44100

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=366997&r1=366996&r2=366997&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Jul 25 02:07:17 2019
@@ -1645,7 +1645,6 @@ ASTNodeImporter::ImportDeclContext(DeclC
   bool AccumulateChildErrors = isa(FromDC);
 
   Error ChildErrors = Error::success();
-  llvm::SmallVector ImportedDecls;
   for (auto *From : FromDC->decls()) {
 ExpectedDecl ImportedOrErr = import(From);
 if (!ImportedOrErr) {
@@ -1657,6 +1656,59 @@ ASTNodeImporter::ImportDeclContext(DeclC
 }
   }
 
+  // We reorder declarations in RecordDecls because they may have another order
+  // in the "to" context than they have in the "from" context. This may happen
+  // e.g when we import a class like this:
+  //struct declToImport {
+  //int a = c + b;
+  //int b = 1;
+  //int c = 2;
+  //};
+  // During the import of `a` we import first the dependencies in sequence,
+  // thus the order would be `c`, `b`, `a`. We will get the normal order by
+  // first removing the already imported members and then adding them in the
+  // order as they apper in the "from" context.
+  //
+  // Keeping field order is vital because it determines structure layout.
+  //
+  // Here and below, we cannot call field_begin() method and its callers on
+  // ToDC if it has an external storage. Calling field_begin() will
+  // automatically load all the fields by calling
+  // LoadFieldsFromExternalStorage(). LoadFieldsFromExternalStorage() would
+  // call ASTImporter::Import(). This is because the ExternalASTSource
+  // interface in LLDB is implemented by the means of the ASTImporter. However,
+  // calling an import at this point would result in an uncontrolled import, we
+  // must avoid that.
+  const auto *FromRD = dyn_cast(FromDC);
+  if (!FromRD)
+return ChildErrors;
+
+  auto ToDCOrErr = Importer.ImportContext(FromDC);
+  if (!ToDCOrErr) {
+consumeError(std::move(ChildErrors));
+return ToDCOrErr.takeError();
+  }
+
+  DeclContext *ToDC = *ToDCOrErr;
+  // Remove all declarations, which may be in wrong order in the
+  // lexical DeclContext and then add them in the proper order.
+  for (auto *D : FromRD->decls()) {
+if (isa(D) || isa(D)) {
+  assert(D && "DC contains a null decl");
+  Decl *ToD = Importer.GetAlreadyImportedOrNull(D);
+  // Remove only the decls which we successfully imported.
+  if (ToD) {
+assert(ToDC == ToD->getLexicalDeclContext() && 
ToDC->containsDecl(ToD));
+// Remove the decl from its wrong place in the linked list.
+ToDC->removeDecl(ToD);
+// Add the decl to the end of the linked list.
+// This time it will be at the proper place because the enclosing for
+// loop iterates in the original (good) order of the decls.
+ToDC->addDeclInternal(ToD);
+  }
+}
+  }
+
   return ChildErrors;
 }
 

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=366997&r1=366996&r2=366997&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu Jul 25 02:07:17 2019
@@ -1472,7 +1472,7 @@ TEST_P(ASTImporterOptionSpecificTestBase
 }
 
 TEST_P(ASTImporterOptionSpecificTestBase,
-   DISABLED_CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) {
+   CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) {
   Decl *From, *To;
   std::tie(From, To) = getImportedDecl(
   // The original recursive algorithm of ASTImporter first imports 'c' then
@@ -2795,6 +2795,16 @@ TEST_P(ImportDecl, ImportEnumSequential)
   "main.c", enumDecl(), VerificationMatcher);
 }
 
+TEST

r368009 - Add User docs for ASTImporter

2019-08-06 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Aug  6 02:52:21 2019
New Revision: 368009

URL: http://llvm.org/viewvc/llvm-project?rev=368009&view=rev
Log:
Add User docs for ASTImporter

Summary:
This document includes the description of the ASTImporter from the user/client
perspective.
A subsequent patch will describe the development internals.

Reviewers: a_sidorin, shafik, gamesh411, balazske, a.sidorin

Subscribers: rnkovacs, dkrupp, arphaman, Szelethus, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65573

Added:
cfe/trunk/docs/LibASTImporter.rst
Modified:
cfe/trunk/docs/index.rst

Added: cfe/trunk/docs/LibASTImporter.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTImporter.rst?rev=368009&view=auto
==
--- cfe/trunk/docs/LibASTImporter.rst (added)
+++ cfe/trunk/docs/LibASTImporter.rst Tue Aug  6 02:52:21 2019
@@ -0,0 +1,613 @@
+===
+ASTImporter: Merging Clang ASTs
+===
+
+The ``ASTImporter`` class is part of Clang's core library, the AST library.
+It imports nodes of an ``ASTContext`` into another ``ASTContext``.
+
+In this document, we assume basic knowledge about the Clang AST.  See the 
:doc:`Introduction
+to the Clang AST ` if you want to learn more
+about how the AST is structured.
+Knowledge about :doc:`matching the Clang AST ` and the 
`reference for the matchers 
`_ are also useful.
+
+.. contents::
+   :local:
+
+Introduction
+
+
+``ASTContext`` holds long-lived AST nodes (such as types and decls) that can 
be referred to throughout the semantic analysis of a file.
+In some cases it is preferable to work with more than one ``ASTContext``.
+For example, we'd like to parse multiple different files inside the same Clang 
tool.
+It may be convenient if we could view the set of the resulting ASTs as if they 
were one AST resulting from the parsing of each file together.
+``ASTImporter`` provides the way to copy types or declarations from one 
``ASTContext`` to another.
+We refer to the context from which we import as the **"from" context** or 
*source context*; and the context into which we import as the **"to" context** 
or *destination context*.
+
+Existing clients of the ``ASTImporter`` library are Cross Translation Unit 
(CTU) static analysis and the LLDB expression parser.
+CTU static analysis imports a definition of a function if its definition is 
found in another translation unit (TU).
+This way the analysis can breach out from the single TU limitation.
+LLDB's ``expr`` command parses a user-defined expression, creates an 
``ASTContext`` for that and then imports the missing definitions from the AST 
what we got from the debug information (DWARF, etc).
+
+Algorithm of the import
+---
+
+Importing one AST node copies that node into the destination ``ASTContext``.
+Why do we have to copy the node?
+Isn't enough to insert the pointer to that node into the destination context?
+One reason is that the "from" context may outlive the "to" context.
+Also, the Clang AST consider nodes (or certain properties of nodes) equivalent 
if they have the same address!
+
+The import algorithm has to ensure that the structurally equivalent nodes in 
the different translation units are not getting duplicated in the merged AST.
+E.g. if we include the definition of the vector template (``#include 
``) in two translation units, then their merged AST should have only 
one node which represents the template.
+Also, we have to discover *one definition rule* (ODR) violations.
+For instance, if there is a class definition with the same name in both 
translation units, but one of the definition contains a different number of 
fields.
+So, we look up existing definitions, and then we check the structural 
equivalency on those nodes.
+The following pseudo-code demonstrates the basics of the import mechanism:
+
+.. code-block:: cpp
+
+  // Pseudo-code(!) of import:
+  ErrorOrDecl Import(Decl *FromD) {
+Decl *ToDecl = nullptr;
+FoundDeclsList = Look up all Decls in the "to" Ctx with the same name of 
FromD;
+for (auto FoundDecl : FoundDeclsList) {
+  if (StructurallyEquivalentDecls(FoundDecl, FromD)) {
+ToDecl = FoundDecl;
+Mark FromD as imported;
+break;
+  } else {
+Report ODR violation;
+return error;
+  }
+}
+if (FoundDeclsList is empty) {
+  Import dependent declarations and types of ToDecl;
+  ToDecl = create a new AST node in "to" Ctx;
+  Mark FromD as imported;
+}
+return ToDecl;
+  }
+
+Two AST nodes are *structurally equivalent* if they are
+
+- builtin types and refer to the same type, e.g. ``int`` and ``int`` are 
structurally equivalent,
+- function types and all their parameters have structurally equivalent types,
+- record types and all their fields in order of thei

r368562 - [CrossTU] User docs: remove temporary limiation with macro expansion

2019-08-12 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Aug 12 05:46:28 2019
New Revision: 368562

URL: http://llvm.org/viewvc/llvm-project?rev=368562&view=rev
Log:
[CrossTU] User docs: remove temporary limiation with macro expansion

D65064, D64635, D64638 pathces solve the issue with macor expansion.

Modified:
cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst

Modified: cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst?rev=368562&r1=368561&r2=368562&view=diff
==
--- cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst (original)
+++ cfe/trunk/docs/analyzer/user-docs/CrossTranslationUnit.rst Mon Aug 12 
05:46:28 2019
@@ -173,15 +173,6 @@ Or we can use `CodeChecker parse -e html
   $ CodeChecker parse -e html -o html_out reports
   $ firefox html_out/index.html
 
-If you experience that Clang crashes during the visitation of the BugPath then 
please disable macro expansion when CTU is used:
-
-.. code-block:: bash
-
-  $ echo "-Xclang -analyzer-stats -Xclang -analyzer-config -Xclang 
expand-macros=false" >./saargs_file
-  $ CodeChecker analyze --ctu --saargs ./saargs_file compile_commands.json -o 
reports
-
-We have a patch which will solve this issue soon.
-
 Automated CTU Analysis with scan-build-py (don't do it)
 ---
 We actively develop CTU with CodeChecker as a "runner" script, `scan-build-py` 
is not actively developed for CTU.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r369099 - Fix typos in LibASTImporter.rst

2019-08-16 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Aug 16 05:21:49 2019
New Revision: 369099

URL: http://llvm.org/viewvc/llvm-project?rev=369099&view=rev
Log:
Fix typos in LibASTImporter.rst

Modified:
cfe/trunk/docs/LibASTImporter.rst

Modified: cfe/trunk/docs/LibASTImporter.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTImporter.rst?rev=369099&r1=369098&r2=369099&view=diff
==
--- cfe/trunk/docs/LibASTImporter.rst (original)
+++ cfe/trunk/docs/LibASTImporter.rst Fri Aug 16 05:21:49 2019
@@ -255,7 +255,7 @@ Putting this all together here is how th
 return 0;
   };
 
-We may extend the ``CmakeLists.txt`` under let's say ``clang/tools`` with the 
build and link instructions:
+We may extend the ``CMakeLists.txt`` under let's say ``clang/tools`` with the 
build and link instructions:
 
 .. code-block:: bash
 
@@ -554,7 +554,7 @@ What's more there is a third prototype d
 The functions are merged in a way that prototypes are added to the redecl 
chain if they refer to the same type, but we can have only one definition.
 The first two declarations are from ``bar.ast``, the third is from 
``main.ast``.
 
-Now, Let's create an object file from the merged AST:
+Now, let's create an object file from the merged AST:
 
 .. code-block:: bash
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r364279 - [ASTImporter] Store import errors for Decls

2019-06-25 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Jun 25 01:00:51 2019
New Revision: 364279

URL: http://llvm.org/viewvc/llvm-project?rev=364279&view=rev
Log:
[ASTImporter] Store import errors for Decls

Summary:
We add a new member which is a mapping from the already-imported
declarations in the "from" context to the error status of the import of
that declaration.  This map contains only the declarations that were not
correctly imported. The same declaration may or may not be included in
ImportedDecls. This map is updated continuously during imports and never
cleared (like ImportedDecls).  In Import(Decl*) we use this mapping, so
if there was a previous failed import we return with the existing error.

We add/remove from the Lookuptable in consistency with ImportedFromDecls.
When we map a decl in the 'to' context to something in the 'from'
context then and only then we add it to the lookup table. When we
remove a mapping then and only then we remove it from the lookup table.

This patch is the first in a series of patches whose aim is to further
strengthen the error handling in ASTImporter.

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62373

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp
cfe/trunk/unittests/AST/ASTImporterFixtures.cpp
cfe/trunk/unittests/AST/ASTImporterFixtures.h
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=364279&r1=364278&r2=364279&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Tue Jun 25 01:00:51 2019
@@ -116,6 +116,14 @@ class TypeSourceInfo;
 /// context to the corresponding declarations in the "to" context.
 llvm::DenseMap ImportedDecls;
 
+/// Mapping from the already-imported declarations in the "from"
+/// context to the error status of the import of that declaration.
+/// This map contains only the declarations that were not correctly
+/// imported. The same declaration may or may not be included in
+/// ImportedDecls. This map is updated continuously during imports and 
never
+/// cleared (like ImportedDecls).
+llvm::DenseMap ImportDeclErrors;
+
 /// Mapping from the already-imported declarations in the "to"
 /// context to the corresponding declarations in the "from" context.
 llvm::DenseMap ImportedFromDecls;
@@ -148,6 +156,9 @@ class TypeSourceInfo;
 /// decl on its own.
 virtual Expected ImportImpl(Decl *From);
 
+/// Used only in unittests to verify the behaviour of the error handling.
+virtual bool returnWithErrorInTest() { return false; };
+
   public:
 
 /// \param ToContext The context we'll be importing into.
@@ -394,6 +405,8 @@ class TypeSourceInfo;
 void RegisterImportedDecl(Decl *FromD, Decl *ToD);
 
 /// Store and assign the imported declaration to its counterpart.
+/// It may happen that several decls from the 'from' context are mapped to
+/// the same decl in the 'to' context.
 Decl *MapImported(Decl *From, Decl *To);
 
 /// Called by StructuralEquivalenceContext.  If a RecordDecl is
@@ -404,6 +417,14 @@ class TypeSourceInfo;
 /// importation, eliminating this loop.
 virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
 
+/// Return if import of the given declaration has failed and if yes
+/// the kind of the problem. This gives the first error encountered with
+/// the node.
+llvm::Optional getImportDeclErrorIfAny(Decl *FromD) const;
+
+/// Mark (newly) imported declaration with error.
+void setImportDeclError(Decl *From, ImportError Error);
+
 /// Determine whether the given types are structurally
 /// equivalent.
 bool IsStructurallyEquivalent(QualType From, QualType To,
@@ -414,7 +435,6 @@ class TypeSourceInfo;
 /// \returns The index of the field in its parent context (starting from 
0).
 /// On error `None` is returned (parent context is non-record).
 static llvm::Optional getFieldIndex(Decl *F);
-
   };
 
 } // namespace clang

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=364279&r1=364278&r2=364279&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Jun 25 01:00:51 2019
@@ -253,11 +253,10 @@ namespace clang {
 LLVM_NODISCARD bool
 GetImportedOrCreateSpecialDecl(ToDeclT *&ToD, CreateFunT CreateFun,
FromDeclT *FromD, Args &&... args) {
-  // FIXME: This 

r364630 - [CTU] Add missing statistics

2019-06-28 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Jun 28 01:08:51 2019
New Revision: 364630

URL: http://llvm.org/viewvc/llvm-project?rev=364630&view=rev
Log:
[CTU] Add missing statistics

Reviewers: xazax.hun

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D63878

Modified:
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp

Modified: cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp?rev=364630&r1=364629&r2=364630&view=diff
==
--- cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp (original)
+++ cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp Fri Jun 28 01:08:51 2019
@@ -40,6 +40,10 @@ STATISTIC(
 STATISTIC(NumGetCTUSuccess,
   "The # of getCTUDefinition successfully returned the "
   "requested function's body");
+STATISTIC(NumUnsupportedNodeFound, "The # of imports when the ASTImporter "
+   "encountered an unsupported AST Node");
+STATISTIC(NumNameConflicts, "The # of imports when the ASTImporter "
+"encountered an ODR error");
 STATISTIC(NumTripleMismatch, "The # of triple mismatches");
 STATISTIC(NumLangMismatch, "The # of language mismatches");
 STATISTIC(NumLangDialectMismatch, "The # of language dialect mismatches");
@@ -404,10 +408,10 @@ CrossTranslationUnitContext::importDefin
 [&](const ImportError &IE) {
   switch (IE.Error) {
   case ImportError::NameConflict:
-// FIXME: Add statistic.
+++NumNameConflicts;
  break;
   case ImportError::UnsupportedConstruct:
-// FIXME: Add statistic.
+++NumUnsupportedNodeFound;
 break;
   case ImportError::Unknown:
 llvm_unreachable("Unknown import error happened.");


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r364752 - [ASTImporter] Propagate error from ImportDeclContext

2019-07-01 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jul  1 05:44:39 2019
New Revision: 364752

URL: http://llvm.org/viewvc/llvm-project?rev=364752&view=rev
Log:
[ASTImporter] Propagate error from ImportDeclContext

Summary:
During analysis of one project we failed to import one
CXXDestructorDecl. But since we did not propagate the error in
importDeclContext we had a CXXRecordDecl without a destructor. Then the
analyzer engine had a CallEvent where the nonexistent dtor was requested
(crash).

Solution is to propagate the errors we have during importing a
DeclContext.

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D63603

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=364752&r1=364751&r2=364752&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jul  1 05:44:39 2019
@@ -57,6 +57,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
@@ -1631,16 +1632,32 @@ ASTNodeImporter::ImportDeclContext(DeclC
 auto ToDCOrErr = Importer.ImportContext(FromDC);
 return ToDCOrErr.takeError();
   }
+
+  // We use strict error handling in case of records and enums, but not
+  // with e.g. namespaces.
+  //
+  // FIXME Clients of the ASTImporter should be able to choose an
+  // appropriate error handling strategy for their needs.  For instance,
+  // they may not want to mark an entire namespace as erroneous merely
+  // because there is an ODR error with two typedefs.  As another example,
+  // the client may allow EnumConstantDecls with same names but with
+  // different values in two distinct translation units.
+  bool AccumulateChildErrors = isa(FromDC);
+
+  Error ChildErrors = Error::success();
   llvm::SmallVector ImportedDecls;
   for (auto *From : FromDC->decls()) {
 ExpectedDecl ImportedOrErr = import(From);
-if (!ImportedOrErr)
-  // Ignore the error, continue with next Decl.
-  // FIXME: Handle this case somehow better.
-  consumeError(ImportedOrErr.takeError());
+if (!ImportedOrErr) {
+  if (AccumulateChildErrors)
+ChildErrors =
+joinErrors(std::move(ChildErrors), ImportedOrErr.takeError());
+  else
+consumeError(ImportedOrErr.takeError());
+}
   }
 
-  return Error::success();
+  return ChildErrors;
 }
 
 Error ASTNodeImporter::ImportDeclContext(
@@ -1698,6 +1715,11 @@ Error ASTNodeImporter::ImportDefinition(
   }
 
   To->startDefinition();
+  // Complete the definition even if error is returned.
+  // The RecordDecl may be already part of the AST so it is better to
+  // have it in complete state even if something is wrong with it.
+  auto DefinitionCompleter =
+  llvm::make_scope_exit([To]() { To->completeDefinition(); });
 
   if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
 return Err;
@@ -1822,7 +1844,6 @@ Error ASTNodeImporter::ImportDefinition(
 if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
   return Err;
 
-  To->completeDefinition();
   return Error::success();
 }
 

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=364752&r1=364751&r2=364752&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Jul  1 05:44:39 2019
@@ -4738,6 +4738,93 @@ TEST_P(ErrorHandlingTest, ErrorHappensAf
   EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
 }
 
+// An error should be set for a class if we cannot import one member.
+TEST_P(ErrorHandlingTest, ErrorIsPropagatedFromMemberToClass) {
+  TranslationUnitDecl *FromTU = getTuDecl(
+  std::string(R"(
+  class X {
+void f() { )") + ErroneousStmt + R"( } // This member has the error
+   // during import.
+void ok();// The error should not prevent importing this.
+  };  // An error will be set for X too.
+  )",
+  Lang_CXX);
+  auto *FromX = FirstDeclMatcher().match(
+  FromTU, cxxRecordDecl(hasName("X")));
+  CXXRecordDecl *ImportedX = Import(FromX, Lang_CXX);
+
+  // An error is set for X.
+  EXPECT_FALSE(ImportedX);
+  ASTImporter *Importer = findFromTU(FromX)->Importer.get();
+  Optional OptErr = Importer->getImportDeclErrorIfAny(FromX);
+  ASSERT_TRUE(OptErr);
+  EXPECT_EQ(OptErr->Error, ImportError::UnsupportedConstruct);
+
+  // An 

r364771 - [ASTImporter] Mark erroneous nodes in from ctx

2019-07-01 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jul  1 07:19:53 2019
New Revision: 364771

URL: http://llvm.org/viewvc/llvm-project?rev=364771&view=rev
Log:
[ASTImporter] Mark erroneous nodes in from ctx

Summary:
During import of a specific Decl D, it may happen that some AST nodes
had already been created before we recognize an error. In this case we
signal back the error to the caller, but the "to" context remains
polluted with those nodes which had been created. Ideally, those nodes
should not had been created, but that time we did not know about the
error, the error happened later.  Since the AST is immutable (most of
the cases we can't remove existing nodes) we choose to mark these nodes
as erroneous.
Here are the steps of the algorithm:
1) We keep track of the nodes which we visit during the import of D: See
ImportPathTy.
2) If a Decl is already imported and it is already on the import path
(we have a cycle) then we copy/store the relevant part of the import
path. We store these cycles for each Decl.
3) When we recognize an error during the import of D then we set up this
error to all Decls in the stored cycles for D and we clear the stored
cycles.

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62375

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=364771&r1=364770&r2=364771&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Mon Jul  1 07:19:53 2019
@@ -87,6 +87,127 @@ class TypeSourceInfo;
 using ImportedCXXBaseSpecifierMap =
 llvm::DenseMap;
 
+// An ImportPath is the list of the AST nodes which we visit during an
+// Import call.
+// If node `A` depends on node `B` then the path contains an `A`->`B` edge.
+// From the call stack of the import functions we can read the very same
+// path.
+//
+// Now imagine the following AST, where the `->` represents dependency in
+// therms of the import.
+// ```
+// A->B->C->D
+//`->E
+// ```
+// We would like to import A.
+// The import behaves like a DFS, so we will visit the nodes in this order:
+// ABCDE.
+// During the visitation we will have the following ImportPaths:
+// ```
+// A
+// AB
+// ABC
+// ABCD
+// ABC
+// AB
+// ABE
+// AB
+// A
+// ```
+// If during the visit of E there is an error then we set an error for E,
+// then as the call stack shrinks for B, then for A:
+// ```
+// A
+// AB
+// ABC
+// ABCD
+// ABC
+// AB
+// ABE // Error! Set an error to E
+// AB  // Set an error to B
+// A   // Set an error to A
+// ```
+// However, during the import we could import C and D without any error and
+// they are independent from A,B and E.
+// We must not set up an error for C and D.
+// So, at the end of the import we have an entry in `ImportDeclErrors` for
+// A,B,E but not for C,D.
+//
+// Now what happens if there is a cycle in the import path?
+// Let's consider this AST:
+// ```
+// A->B->C->A
+//`->E
+// ```
+// During the visitation we will have the below ImportPaths and if during
+// the visit of E there is an error then we will set up an error for E,B,A.
+// But what's up with C?
+// ```
+// A
+// AB
+// ABC
+// ABCA
+// ABC
+// AB
+// ABE // Error! Set an error to E
+// AB  // Set an error to B
+// A   // Set an error to A
+// ```
+// This time we know that both B and C are dependent on A.
+// This means we must set up an error for C too.
+// As the call stack reverses back we get to A and we must set up an error
+// to all nodes which depend on A (this includes C).
+// But C is no longer on the import path, it just had been previously.
+// Such situation can happen only if during the visitation we had a cycle.
+// If we didn't have any cycle, then the normal way of passing an Error
+// object through the call stack could handle the situation.
+// This is why we must track cycles during the import process for each
+// visited declaration.
+class ImportPathTy {
+public:
+  using VecTy = llvm::SmallVector;
+
+  void push(Decl *D) {
+Nodes.push_back(D);
+++Aux[D];
+  }
+
+  void pop() {
+if (Nodes.empty())
+  return;
+--Aux[Nodes.back()];
+Nodes.pop_back();
+  }
+
+  /// Returns true if the last element can be found earlier in the path.
+  bool hasCycleAtBack() const {
+

r364785 - [ASTImporter] Mark erroneous nodes in shared st

2019-07-01 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jul  1 08:37:07 2019
New Revision: 364785

URL: http://llvm.org/viewvc/llvm-project?rev=364785&view=rev
Log:
[ASTImporter] Mark erroneous nodes in shared st

Summary:
Now we store the errors for the Decls in the "to" context too. For
that, however, we have to put these errors in a shared state (among all
the ASTImporter objects which handle the same "to" context but different
"from" contexts).

After a series of imports from different "from" TUs we have a "to" context
which may have erroneous nodes in it. (Remember, the AST is immutable so
there is no way to delete a node once we had created it and we realized
the error later.) All these erroneous nodes are marked in
ASTImporterSharedState::ImportErrors.  Clients of the ASTImporter may
use this as an input. E.g. the static analyzer engine may not try to
analyze a function if that is marked as erroneous (it can be queried via
ASTImporterSharedState::getImportDeclErrorIfAny()).

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62376

Added:
cfe/trunk/include/clang/AST/ASTImporterSharedState.h
Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
cfe/trunk/lib/Frontend/ASTMerge.cpp
cfe/trunk/unittests/AST/ASTImporterFixtures.cpp
cfe/trunk/unittests/AST/ASTImporterFixtures.h
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=364785&r1=364784&r2=364785&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Mon Jul  1 08:37:07 2019
@@ -32,8 +32,8 @@
 namespace clang {
 
 class ASTContext;
+class ASTImporterSharedState;
 class Attr;
-class ASTImporterLookupTable;
 class CXXBaseSpecifier;
 class CXXCtorInitializer;
 class Decl;
@@ -209,13 +209,7 @@ class TypeSourceInfo;
 };
 
   private:
-
-/// Pointer to the import specific lookup table, which may be shared
-/// amongst several ASTImporter objects.
-/// This is an externally managed resource (and should exist during the
-/// lifetime of the ASTImporter object)
-/// If not set then the original C/C++ lookup is used.
-ASTImporterLookupTable *LookupTable = nullptr;
+std::shared_ptr SharedState = nullptr;
 
 /// The path which we go through during the import of a given AST node.
 ImportPathTy ImportPath;
@@ -311,7 +305,7 @@ class TypeSourceInfo;
 ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
 ASTContext &FromContext, FileManager &FromFileManager,
 bool MinimalImport,
-ASTImporterLookupTable *LookupTable = nullptr);
+std::shared_ptr SharedState = nullptr);
 
 virtual ~ASTImporter();
 

Added: cfe/trunk/include/clang/AST/ASTImporterSharedState.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporterSharedState.h?rev=364785&view=auto
==
--- cfe/trunk/include/clang/AST/ASTImporterSharedState.h (added)
+++ cfe/trunk/include/clang/AST/ASTImporterSharedState.h Mon Jul  1 08:37:07 
2019
@@ -0,0 +1,80 @@
+//===- ASTImporterSharedState.h - ASTImporter specific state --*- C++ 
-*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+//  This file defines the ASTImporter specific state, which may be shared
+//  amongst several ASTImporter objects.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H
+#define LLVM_CLANG_AST_ASTIMPORTERSHAREDSTATE_H
+
+#include "clang/AST/ASTImporterLookupTable.h"
+#include "llvm/ADT/DenseMap.h"
+// FIXME We need this because of ImportError.
+#include "clang/AST/ASTImporter.h"
+
+namespace clang {
+
+class TranslationUnitDecl;
+
+/// Importer specific state, which may be shared amongst several ASTImporter
+/// objects.
+class ASTImporterSharedState {
+
+  /// Pointer to the import specific lookup table.
+  std::unique_ptr LookupTable;
+
+  /// Mapping from the already-imported declarations in the "to"
+  /// context to the error status of the import of that declaration.
+  /// This map contains only the declarations that were not correctly
+  /// imported. The same declaration may or may not be included in
+  /// ImportedFromDecls. This map is updated continuously during imports and
+  ///

r364889 - [ASTImporter] Structural eq: handle DependentScopeDeclRefExpr

2019-07-02 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Jul  2 00:36:39 2019
New Revision: 364889

URL: http://llvm.org/viewvc/llvm-project?rev=364889&view=rev
Log:
[ASTImporter] Structural eq: handle DependentScopeDeclRefExpr

Summary:
Structural equivalence did not handle dependent template args properly
when the arg contained a DependentScopeDeclRefExpr.

Reviewers: a_sidorin, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62329

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=364889&r1=364888&r2=364889&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Tue Jul  2 00:36:39 2019
@@ -73,6 +73,7 @@
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/TemplateName.h"
@@ -100,6 +101,59 @@ static bool IsStructurallyEquivalent(Str
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
  const TemplateArgument &Arg1,
  const TemplateArgument &Arg2);
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ NestedNameSpecifier *NNS1,
+ NestedNameSpecifier *NNS2);
+static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
+ const IdentifierInfo *Name2);
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ const DeclarationName Name1,
+ const DeclarationName Name2) {
+  if (Name1.getNameKind() != Name2.getNameKind())
+return false;
+
+  switch (Name1.getNameKind()) {
+
+  case DeclarationName::Identifier:
+return IsStructurallyEquivalent(Name1.getAsIdentifierInfo(),
+Name2.getAsIdentifierInfo());
+
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+return IsStructurallyEquivalent(Context, Name1.getCXXNameType(),
+Name2.getCXXNameType());
+
+  case DeclarationName::CXXDeductionGuideName: {
+if (!IsStructurallyEquivalent(
+Context, Name1.getCXXDeductionGuideTemplate()->getDeclName(),
+Name2.getCXXDeductionGuideTemplate()->getDeclName()))
+  return false;
+return IsStructurallyEquivalent(Context,
+Name1.getCXXDeductionGuideTemplate(),
+Name2.getCXXDeductionGuideTemplate());
+  }
+
+  case DeclarationName::CXXOperatorName:
+return Name1.getCXXOverloadedOperator() == 
Name2.getCXXOverloadedOperator();
+
+  case DeclarationName::CXXLiteralOperatorName:
+return IsStructurallyEquivalent(Name1.getCXXLiteralIdentifier(),
+Name2.getCXXLiteralIdentifier());
+
+  case DeclarationName::CXXUsingDirective:
+return true; // FIXME When do we consider two using directives equal?
+
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+return true; // FIXME
+  }
+
+  llvm_unreachable("Unhandled kind of DeclarationName");
+  return true;
+}
 
 /// Determine structural equivalence of two expressions.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
@@ -107,7 +161,26 @@ static bool IsStructurallyEquivalent(Str
   if (!E1 || !E2)
 return E1 == E2;
 
-  // FIXME: Actually perform a structural comparison!
+  if (auto *DE1 = dyn_cast(E1)) {
+auto *DE2 = dyn_cast(E2);
+if (!DE2)
+  return false;
+if (!IsStructurallyEquivalent(Context, DE1->getDeclName(),
+  DE2->getDeclName()))
+  return false;
+return IsStructurallyEquivalent(Context, DE1->getQualifier(),
+DE2->getQualifier());
+  } else if (auto CastE1 = dyn_cast(E1)) {
+auto *CastE2 = dyn_cast(E2);
+if (!CastE2)
+  return false;
+if (!IsStructurallyEquivalent(Context, CastE1->getType(),
+  CastE2->getType()))
+  return false;
+return IsStructurallyEquivalent(Context, CastE1->getSubExpr(),
+CastE2->getSubExpr());
+  }
+  // FIXME: Handle other kind of expressions!
   return true;
 }
 

Modified: cfe/trunk/unittests/AST/StructuralEqu

r365133 - [CTU] Add support for virtual functions

2019-07-04 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jul  4 04:39:00 2019
New Revision: 365133

URL: http://llvm.org/viewvc/llvm-project?rev=365133&view=rev
Log:
[CTU] Add support for virtual functions

Reviewers: Szelethus, xazax.hun

Subscribers: rnkovacs, dkrupp, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D63920

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/test/Analysis/Inputs/ctu-other.cpp
cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
cfe/trunk/test/Analysis/ctu-main.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=365133&r1=365132&r2=365133&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Thu Jul  4 04:39:00 2019
@@ -766,8 +766,11 @@ RuntimeDefinition CXXInstanceCall::getRu
 
   // Does the decl that we found have an implementation?
   const FunctionDecl *Definition;
-  if (!Result->hasBody(Definition))
+  if (!Result->hasBody(Definition)) {
+if (!DynType.canBeASubClass())
+  return AnyFunctionCall::getRuntimeDefinition();
 return {};
+  }
 
   // We found a definition. If we're not sure that this devirtualization is
   // actually what will happen at runtime, make sure to provide the region so

Modified: cfe/trunk/test/Analysis/Inputs/ctu-other.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/ctu-other.cpp?rev=365133&r1=365132&r2=365133&view=diff
==
--- cfe/trunk/test/Analysis/Inputs/ctu-other.cpp (original)
+++ cfe/trunk/test/Analysis/Inputs/ctu-other.cpp Thu Jul  4 04:39:00 2019
@@ -38,6 +38,7 @@ int embed_cls::fecl(int x) {
 class mycls {
 public:
   int fcl(int x);
+  virtual int fvcl(int x);
   static int fscl(int x);
 
   class embed_cls2 {
@@ -49,6 +50,9 @@ public:
 int mycls::fcl(int x) {
   return x + 5;
 }
+int mycls::fvcl(int x) {
+  return x + 7;
+}
 int mycls::fscl(int x) {
   return x + 6;
 }
@@ -56,6 +60,15 @@ int mycls::embed_cls2::fecl2(int x) {
   return x - 11;
 }
 
+class derived : public mycls {
+public:
+  virtual int fvcl(int x) override;
+};
+
+int derived::fvcl(int x) {
+  return x + 8;
+}
+
 namespace chns {
 int chf2(int x);
 

Modified: cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt?rev=365133&r1=365132&r2=365133&view=diff
==
--- cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt (original)
+++ cfe/trunk/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt Thu Jul  4 
04:39:00 2019
@@ -3,8 +3,10 @@ c:@N@myns@N@embed_ns@F@fens#I# ctu-other
 c:@F@g#I# ctu-other.cpp.ast
 c:@S@mycls@F@fscl#I#S ctu-other.cpp.ast
 c:@S@mycls@F@fcl#I# ctu-other.cpp.ast
+c:@S@mycls@F@fvcl#I# ctu-other.cpp.ast
 c:@N@myns@S@embed_cls@F@fecl#I# ctu-other.cpp.ast
 c:@S@mycls@S@embed_cls2@F@fecl2#I# ctu-other.cpp.ast
+c:@S@derived@F@fvcl#I# ctu-other.cpp.ast
 c:@F@f#I# ctu-other.cpp.ast
 c:@N@myns@F@fns#I# ctu-other.cpp.ast
 c:@F@h#I# ctu-other.cpp.ast

Modified: cfe/trunk/test/Analysis/ctu-main.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctu-main.cpp?rev=365133&r1=365132&r2=365133&view=diff
==
--- cfe/trunk/test/Analysis/ctu-main.cpp (original)
+++ cfe/trunk/test/Analysis/ctu-main.cpp Thu Jul  4 04:39:00 2019
@@ -45,6 +45,7 @@ public:
 class mycls {
 public:
   int fcl(int x);
+  virtual int fvcl(int x);
   static int fscl(int x);
 
   class embed_cls2 {
@@ -53,6 +54,11 @@ public:
   };
 };
 
+class derived : public mycls {
+public:
+  virtual int fvcl(int x) override;
+};
+
 namespace chns {
 int chf1(int x);
 }
@@ -98,6 +104,14 @@ union U {
 };
 extern U extU;
 
+void test_virtual_functions(mycls* obj) {
+  // The dynamic type is known.
+  clang_analyzer_eval(mycls().fvcl(1) == 8);   // expected-warning{{TRUE}}
+  clang_analyzer_eval(derived().fvcl(1) == 9); // expected-warning{{TRUE}}
+  // We cannot decide about the dynamic type.
+  clang_analyzer_eval(obj->fvcl(1) == 8);  // expected-warning{{FALSE}} 
expected-warning{{TRUE}}
+}
+
 int main() {
   clang_analyzer_eval(f(3) == 2); // expected-warning{{TRUE}}
   clang_analyzer_eval(f(4) == 3); // expected-warning{{TRUE}}
@@ -116,7 +130,7 @@ int main() {
   clang_analyzer_eval(fun_using_anon_struct(8) == 8); // 
expected-warning{{TRUE}}
 
   clang_analyzer_eval(other_macro_diag(1) == 1); // expected-warning{{TRUE}}
-  // expected-warning@Inputs/ctu-other.cpp:80{{REACHABLE}}
+  // expected-warning@Inputs/ctu-other.cpp:93{{REACHABLE}}
   MACRODIAG(); // expected-warning{{REACHABLE}}
 
   clang_a

r365315 - [ASTImporter] Fix import of lambda in function param

2019-07-08 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jul  8 05:49:13 2019
New Revision: 365315

URL: http://llvm.org/viewvc/llvm-project?rev=365315&view=rev
Log:
[ASTImporter] Fix import of lambda in function param

Summary:
The current import implementation fails to import the definition of a
lambda class if the lambda class is defined in a function param.
E.g., the lambda class below will be imported without any methods:
```
  template 
  void f(F L = [](){}) {}
```

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64073

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=365315&r1=365314&r2=365315&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jul  8 05:49:13 2019
@@ -1708,8 +1708,18 @@ static Error setTypedefNameForAnonDecl(T
 Error ASTNodeImporter::ImportDefinition(
 RecordDecl *From, RecordDecl *To, ImportDefinitionKind Kind) {
   if (To->getDefinition() || To->isBeingDefined()) {
-if (Kind == IDK_Everything)
-  return ImportDeclContext(From, /*ForceImport=*/true);
+if (Kind == IDK_Everything ||
+// In case of lambdas, the class already has a definition ptr set, but
+// the contained decls are not imported yet. Also, isBeingDefined was
+// set in CXXRecordDecl::CreateLambda.  We must import the contained
+// decls here and finish the definition.
+(To->isLambda() && shouldForceImportDeclContext(Kind))) {
+  Error Result = ImportDeclContext(From, /*ForceImport=*/true);
+  // Finish the definition of the lambda, set isBeingDefined to false.
+  if (To->isLambda())
+To->completeDefinition();
+  return Result;
+}
 
 return Error::success();
   }
@@ -7422,19 +7432,10 @@ ExpectedStmt ASTNodeImporter::VisitLambd
 return ToClassOrErr.takeError();
   CXXRecordDecl *ToClass = *ToClassOrErr;
 
-  // NOTE: lambda classes are created with BeingDefined flag set up.
-  // It means that ImportDefinition doesn't work for them and we should fill it
-  // manually.
-  if (ToClass->isBeingDefined())
-if (Error Err = ImportDeclContext(FromClass, /*ForceImport = */ true))
-  return std::move(Err);
-
   auto ToCallOpOrErr = import(E->getCallOperator());
   if (!ToCallOpOrErr)
 return ToCallOpOrErr.takeError();
 
-  ToClass->completeDefinition();
-
   SmallVector ToCaptures;
   ToCaptures.reserve(E->capture_size());
   for (const auto &FromCapture : E->captures()) {

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=365315&r1=365314&r2=365315&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Jul  8 05:49:13 2019
@@ -5083,6 +5083,45 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTes
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, CanonicalRedeclChain,
 ::testing::Values(ArgVector()), );
 
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionBody) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  void f() {
+auto L = [](){};
+  }
+  )",
+  Lang_CXX11, "input0.cc");
+  auto Pattern = lambdaExpr();
+  CXXRecordDecl *FromL =
+  FirstDeclMatcher().match(FromTU, Pattern)->getLambdaClass();
+
+  auto ToL = Import(FromL, Lang_CXX11);
+  unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
+  unsigned FromLSize =
+  std::distance(FromL->decls().begin(), FromL->decls().end());
+  EXPECT_NE(ToLSize, 0u);
+  EXPECT_EQ(ToLSize, FromLSize);
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, LambdaInFunctionParam) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  template 
+  void f(F L = [](){}) {}
+  )",
+  Lang_CXX11, "input0.cc");
+  auto Pattern = lambdaExpr();
+  CXXRecordDecl *FromL =
+  FirstDeclMatcher().match(FromTU, Pattern)->getLambdaClass();
+
+  auto ToL = Import(FromL, Lang_CXX11);
+  unsigned ToLSize = std::distance(ToL->decls().begin(), ToL->decls().end());
+  unsigned FromLSize =
+  std::distance(FromL->decls().begin(), FromL->decls().end());
+  EXPECT_NE(ToLSize, 0u);
+  EXPECT_EQ(ToLSize, FromLSize);
+}
+
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
 DefaultTestValuesForRunOptions, );
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r365639 - [analyzer]Add user docs rst

2019-07-10 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Jul 10 07:49:53 2019
New Revision: 365639

URL: http://llvm.org/viewvc/llvm-project?rev=365639&view=rev
Log:
[analyzer]Add user docs rst

Summary:
Add user documentation page. This is an empty page atm, later patches will add
the specific user documentatoins.

Reviewers: dkrupp

Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, 
a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, gamesh411, Charusso, 
cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64494

Added:
cfe/trunk/docs/analyzer/user-docs.rst
Modified:
cfe/trunk/docs/ClangStaticAnalyzer.rst

Modified: cfe/trunk/docs/ClangStaticAnalyzer.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangStaticAnalyzer.rst?rev=365639&r1=365638&r2=365639&view=diff
==
--- cfe/trunk/docs/ClangStaticAnalyzer.rst (original)
+++ cfe/trunk/docs/ClangStaticAnalyzer.rst Wed Jul 10 07:49:53 2019
@@ -5,15 +5,16 @@ Clang Static Analyzer
 The Clang Static Analyzer is a source code analysis tool that finds bugs in C, 
C++, and Objective-C programs.
 It implements *path-sensitive*, *inter-procedural analysis* based on *symbolic 
execution* technique.
 
-This is the Static Analyzer documentation page. 
+This is the Static Analyzer documentation page.
 
 See the `Official Tool Page `_.
 
 .. toctree::
:caption: Table of Contents
:numbered:
-   :maxdepth: 2  
- 
+   :maxdepth: 2
+
analyzer/checkers
+   analyzer/user-docs
analyzer/developer-docs
 

Added: cfe/trunk/docs/analyzer/user-docs.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/user-docs.rst?rev=365639&view=auto
==
--- cfe/trunk/docs/analyzer/user-docs.rst (added)
+++ cfe/trunk/docs/analyzer/user-docs.rst Wed Jul 10 07:49:53 2019
@@ -0,0 +1,4 @@
+User Docs
+=
+
+Contents:


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r360572 - [ASTImporter] Separate unittest files

2019-05-13 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon May 13 03:06:25 2019
New Revision: 360572

URL: http://llvm.org/viewvc/llvm-project?rev=360572&view=rev
Log:
[ASTImporter] Separate unittest files

Summary:
Move generic redecl chain tests and visibility tests into their own
separate test files.

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: mgorny, rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D61786

Added:
cfe/trunk/unittests/AST/ASTImporterFixtures.cpp
cfe/trunk/unittests/AST/ASTImporterFixtures.h
cfe/trunk/unittests/AST/ASTImporterGenericRedeclTest.cpp
cfe/trunk/unittests/AST/ASTImporterVisibilityTest.cpp
Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/CMakeLists.txt

Added: cfe/trunk/unittests/AST/ASTImporterFixtures.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterFixtures.cpp?rev=360572&view=auto
==
--- cfe/trunk/unittests/AST/ASTImporterFixtures.cpp (added)
+++ cfe/trunk/unittests/AST/ASTImporterFixtures.cpp Mon May 13 03:06:25 2019
@@ -0,0 +1,210 @@
+//===- unittest/AST/ASTImporterFixtures.cpp - AST unit test support 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+/// \file
+/// Implementation of fixture classes for testing the ASTImporter.
+//
+//===--===//
+
+#include "ASTImporterFixtures.h"
+
+#include "clang/AST/ASTImporter.h"
+#include "clang/AST/ASTImporterLookupTable.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Tooling/Tooling.h"
+
+namespace clang {
+namespace ast_matchers {
+
+void createVirtualFileIfNeeded(ASTUnit *ToAST, StringRef FileName,
+   std::unique_ptr &&Buffer) {
+  assert(ToAST);
+  ASTContext &ToCtx = ToAST->getASTContext();
+  auto *OFS = static_cast(
+  &ToCtx.getSourceManager().getFileManager().getVirtualFileSystem());
+  auto *MFS = static_cast(
+  OFS->overlays_begin()->get());
+  MFS->addFile(FileName, 0, std::move(Buffer));
+}
+
+void createVirtualFileIfNeeded(ASTUnit *ToAST, StringRef FileName,
+   StringRef Code) {
+  return createVirtualFileIfNeeded(ToAST, FileName,
+   llvm::MemoryBuffer::getMemBuffer(Code));
+}
+
+ASTImporterTestBase::TU::TU(StringRef Code, StringRef FileName, ArgVector Args,
+ImporterConstructor C)
+: Code(Code), FileName(FileName),
+  Unit(tooling::buildASTFromCodeWithArgs(this->Code, Args, 
this->FileName)),
+  TUDecl(Unit->getASTContext().getTranslationUnitDecl()), Creator(C) {
+  Unit->enableSourceFileDiagnostics();
+
+  // If the test doesn't need a specific ASTImporter, we just create a
+  // normal ASTImporter with it.
+  if (!Creator)
+Creator = [](ASTContext &ToContext, FileManager &ToFileManager,
+ ASTContext &FromContext, FileManager &FromFileManager,
+ bool MinimalImport, ASTImporterLookupTable *LookupTable) {
+  return new ASTImporter(ToContext, ToFileManager, FromContext,
+ FromFileManager, MinimalImport, LookupTable);
+};
+}
+
+ASTImporterTestBase::TU::~TU() {}
+
+void ASTImporterTestBase::TU::lazyInitImporter(
+ASTImporterLookupTable &LookupTable, ASTUnit *ToAST) {
+  assert(ToAST);
+  if (!Importer)
+Importer.reset(Creator(ToAST->getASTContext(), ToAST->getFileManager(),
+   Unit->getASTContext(), Unit->getFileManager(), 
false,
+   &LookupTable));
+  assert(&ToAST->getASTContext() == &Importer->getToContext());
+  createVirtualFileIfNeeded(ToAST, FileName, Code);
+}
+
+Decl *ASTImporterTestBase::TU::import(ASTImporterLookupTable &LookupTable,
+  ASTUnit *ToAST, Decl *FromDecl) {
+  lazyInitImporter(LookupTable, ToAST);
+  if (auto ImportedOrErr = Importer->Import_New(FromDecl))
+return *ImportedOrErr;
+  else {
+llvm::consumeError(ImportedOrErr.takeError());
+return nullptr;
+  }
+}
+
+QualType ASTImporterTestBase::TU::import(ASTImporterLookupTable &LookupTable,
+ ASTUnit *ToAST, QualType FromType) {
+  lazyInitImporter(LookupTable, ToAST);
+  if (auto ImportedOrErr = Importer->Import_New(FromType))
+return *ImportedOrErr;
+  else {
+llvm::consumeError(ImportedOrErr.takeError());
+return QualType{};
+  }
+}
+
+void ASTImporterTestBase::lazyInitLookupTable(TranslationUnitDecl *ToTU) {
+  assert(ToTU);
+  if (!LookupTablePtr)
+LookupTablePtr = llvm::make_unique(*ToTU);
+}
+
+void ASTImporterTestBase::lazyInitToAST(Langu

r360760 - [ASTImporter] Use llvm::Expected and Error in the importer API

2019-05-15 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed May 15 03:29:48 2019
New Revision: 360760

URL: http://llvm.org/viewvc/llvm-project?rev=360760&view=rev
Log:
[ASTImporter] Use llvm::Expected and Error in the importer API

Summary:
This is the final phase of the refactoring towards using llvm::Expected
and llvm::Error in the ASTImporter API.
This involves the following:
- remove old Import functions which returned with a pointer,
- use the Import_New functions (which return with Err or Expected) everywhere
  and handle their return value
- rename Import_New functions to Import
This affects both Clang and LLDB.

Reviewers: shafik, teemperor, aprantl, a_sidorin, balazske, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits, lldb-commits

Tags: #clang, #lldb

Differential Revision: https://reviews.llvm.org/D61438

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/ExternalASTMerger.cpp
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
cfe/trunk/lib/Frontend/ASTMerge.cpp
cfe/trunk/unittests/AST/ASTImporterFixtures.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=360760&r1=360759&r2=360760&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Wed May 15 03:29:48 2019
@@ -183,7 +183,7 @@ class TypeSourceInfo;
 /// \return Error information (success or error).
 template 
 LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
-  auto ToOrErr = Import_New(From);
+  auto ToOrErr = Import(From);
   if (ToOrErr)
 To = *ToOrErr;
   return ToOrErr.takeError();
@@ -193,40 +193,29 @@ class TypeSourceInfo;
 /// context. A null type is imported as a null type (no error).
 ///
 /// \returns The equivalent type in the "to" context, or the import error.
-llvm::Expected Import_New(QualType FromT);
-// FIXME: Remove this version.
-QualType Import(QualType FromT);
+llvm::Expected Import(QualType FromT);
 
 /// Import the given type source information from the
 /// "from" context into the "to" context.
 ///
 /// \returns The equivalent type source information in the "to"
 /// context, or the import error.
-llvm::Expected Import_New(TypeSourceInfo *FromTSI);
-// FIXME: Remove this version.
-TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
+llvm::Expected Import(TypeSourceInfo *FromTSI);
 
 /// Import the given attribute from the "from" context into the
 /// "to" context.
 ///
 /// \returns The equivalent attribute in the "to" context, or the import
 /// error.
-llvm::Expected Import_New(const Attr *FromAttr);
-// FIXME: Remove this version.
-Attr *Import(const Attr *FromAttr);
+llvm::Expected Import(const Attr *FromAttr);
 
 /// Import the given declaration from the "from" context into the
 /// "to" context.
 ///
 /// \returns The equivalent declaration in the "to" context, or the import
 /// error.
-llvm::Expected Import_New(Decl *FromD);
-llvm::Expected Import_New(const Decl *FromD) {
-  return Import_New(const_cast(FromD));
-}
-// FIXME: Remove this version.
-Decl *Import(Decl *FromD);
-Decl *Import(const Decl *FromD) {
+llvm::Expected Import(Decl *FromD);
+llvm::Expected Import(const Decl *FromD) {
   return Import(const_cast(FromD));
 }
 
@@ -251,28 +240,21 @@ class TypeSourceInfo;
 ///
 /// \returns The equivalent expression in the "to" context, or the import
 /// error.
-llvm::Expected Import_New(Expr *FromE);
-// FIXME: Remove this version.
-Expr *Import(Expr *FromE);
+llvm::Expected Import(Expr *FromE);
 
 /// Import the given statement from the "from" context into the
 /// "to" context.
 ///
 /// \returns The equivalent statement in the "to" context, or the import
 /// error.
-llvm::Expected Import_New(Stmt *FromS);
-// FIXME: Remove this version.
-Stmt *Import(Stmt *FromS);
+llvm::Expected Import(Stmt *FromS);
 
 /// Import the given nested-name-specifier from the "from"
 /// context into the "to" context.
 ///
 /// \returns The equivalent nested-name-specifier in the "to"
 /// context, or the import error.
-llvm::Expected
-Import_New(NestedNameSpecifier *FromNNS);
-// FIXME: Remove this version.
-NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
+llvm::Expected Import(NestedNameSpecifier *FromNNS);
 
 /// Import the given nested-name-specifier-loc from the "from"
 /// context into the "to" context.
@@ -280,42 +262,32 @@ class TypeSourceInfo;
 /// \returns The equivalent nested-name-specifier-loc in the "to"
 /// context, or the 

r361139 - [ASTImporter] Enable disabled but passing tests

2019-05-20 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon May 20 03:38:14 2019
New Revision: 361139

URL: http://llvm.org/viewvc/llvm-project?rev=361139&view=rev
Log:
[ASTImporter] Enable disabled but passing tests

Reviewers: a_sidorin, a.sidorin, shafik

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62066

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=361139&r1=361138&r2=361139&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon May 20 03:38:14 2019
@@ -2362,12 +2362,7 @@ TEST_P(ImportFriendFunctions,
   EXPECT_EQ(ToFD->getPreviousDecl(), ImportedD);
 }
 
-// Disabled temporarily, because the new structural equivalence check
-// (https://reviews.llvm.org/D48628) breaks it.
-// PreviousDecl is not set because there is no structural match.
-// FIXME Enable!
-TEST_P(ImportFriendFunctions,
-DISABLED_ImportFriendFunctionRedeclChainDefWithClass) {
+TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) {
   auto Pattern = functionDecl(hasName("f"));
 
   Decl *FromTU = getTuDecl(
@@ -2395,12 +2390,8 @@ TEST_P(ImportFriendFunctions,
 (*ImportedD->param_begin())->getOriginalType());
 }
 
-// Disabled temporarily, because the new structural equivalence check
-// (https://reviews.llvm.org/D48628) breaks it.
-// PreviousDecl is not set because there is no structural match.
-// FIXME Enable!
 TEST_P(ImportFriendFunctions,
-DISABLED_ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) {
+   ImportFriendFunctionRedeclChainDefWithClass_ImportTheProto) {
   auto Pattern = functionDecl(hasName("f"));
 
   Decl *FromTU = getTuDecl(

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=361139&r1=361138&r2=361139&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Mon May 20 03:38:14 
2019
@@ -300,8 +300,7 @@ TEST_F(StructuralEquivalenceFunctionTest
   EXPECT_FALSE(testStructuralMatch(t));
 }
 
-TEST_F(StructuralEquivalenceFunctionTest, DISABLED_NoexceptNonMatch) {
-  // The expression is not checked yet.
+TEST_F(StructuralEquivalenceFunctionTest, NoexceptNonMatch) {
   auto t = makeNamedDecls("void foo() noexcept(false);",
   "void foo() noexcept(true);", Lang_CXX11);
   EXPECT_FALSE(testStructuralMatch(t));


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r348923 - [ASTImporter] Remove import of definition from GetAlreadyImportedOrNull

2018-12-12 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Dec 12 03:22:55 2018
New Revision: 348923

URL: http://llvm.org/viewvc/llvm-project?rev=348923&view=rev
Log:
[ASTImporter] Remove import of definition from GetAlreadyImportedOrNull

Summary: a_sidorin

Reviewers: a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53755

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/lib/AST/ASTImporter.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=348923&r1=348922&r2=348923&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Wed Dec 12 03:22:55 2018
@@ -209,7 +209,7 @@ class Attr;
 /// Return the copy of the given declaration in the "to" context if
 /// it has already been imported from the "from" context.  Otherwise return
 /// NULL.
-Decl *GetAlreadyImportedOrNull(Decl *FromD);
+Decl *GetAlreadyImportedOrNull(const Decl *FromD) const;
 
 /// Import the given declaration context from the "from"
 /// AST context into the "to" AST context.

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=348923&r1=348922&r2=348923&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Dec 12 03:22:55 2018
@@ -1580,6 +1580,9 @@ Error ASTNodeImporter::ImportDeclParts(
 return Err;
 
   ToD = cast_or_null(Importer.GetAlreadyImportedOrNull(D));
+  if (ToD)
+if (Error Err = ASTNodeImporter(*this).ImportDefinitionIfNeeded(D, ToD))
+  return Err;
 
   return Error::success();
 }
@@ -7745,17 +7748,12 @@ Attr *ASTImporter::Import(const Attr *Fr
   return ToAttr;
 }
 
-Decl *ASTImporter::GetAlreadyImportedOrNull(Decl *FromD) {
-  llvm::DenseMap::iterator Pos = ImportedDecls.find(FromD);
-  if (Pos != ImportedDecls.end()) {
-Decl *ToD = Pos->second;
-// FIXME: move this call to ImportDeclParts().
-if (Error Err = ASTNodeImporter(*this).ImportDefinitionIfNeeded(FromD, 
ToD))
-  llvm::consumeError(std::move(Err));
-return ToD;
-  } else {
+Decl *ASTImporter::GetAlreadyImportedOrNull(const Decl *FromD) const {
+  auto Pos = ImportedDecls.find(FromD);
+  if (Pos != ImportedDecls.end())
+return Pos->second;
+  else
 return nullptr;
-  }
 }
 
 Expected ASTImporter::Import_New(Decl *FromD) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r349349 - [ASTImporter] Fix redecl chain of classes and class templates

2018-12-17 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Dec 17 04:42:12 2018
New Revision: 349349

URL: http://llvm.org/viewvc/llvm-project?rev=349349&view=rev
Log:
[ASTImporter] Fix redecl chain of classes and class templates

Summary:
The crux of the issue that is being fixed is that lookup could not find
previous decls of a friend class. The solution involves making the
friend declarations visible in their decl context (i.e. adding them to
the lookup table).
Also, we simplify `VisitRecordDecl` greatly.

This fix involves two other repairs (without these the unittests fail):
(1) We could not handle the addition of injected class types properly
when a redecl chain was involved, now this is fixed.
(2) DeclContext::removeDecl failed if the lookup table in Vector form
did not contain the to be removed element. This caused troubles in
ASTImporter::ImportDeclContext. This is also fixed.

Reviewers: a_sidorin, balazske, a.sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53655

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=349349&r1=349348&r2=349349&view=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Mon Dec 17 04:42:12 2018
@@ -300,6 +300,16 @@ Example matches f
 
 
 
+MatcherDecl>indirectFieldDeclMatcherIndirectFieldDecl>...
+Matches indirect 
field declarations.
+
+Given
+  struct X { struct { int a; }; };
+indirectFieldDecl()
+  matches 'a'.
+
+
+
 MatcherDecl>labelDeclMatcherLabelDecl>...
 Matches a declaration of 
label.
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=349349&r1=349348&r2=349349&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Mon Dec 17 04:42:12 2018
@@ -1158,6 +1158,17 @@ extern const internal::VariadicDynCastAl
 ///   matches 'm'.
 extern const internal::VariadicDynCastAllOfMatcher fieldDecl;
 
+/// Matches indirect field declarations.
+///
+/// Given
+/// \code
+///   struct X { struct { int a; }; };
+/// \endcode
+/// indirectFieldDecl()
+///   matches 'a'.
+extern const internal::VariadicDynCastAllOfMatcher
+indirectFieldDecl;
+
 /// Matches function declarations.
 ///
 /// Example matches f

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=349349&r1=349348&r2=349349&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Dec 17 04:42:12 2018
@@ -122,6 +122,8 @@ namespace clang {
   return getCanonicalForwardRedeclChain(FD);
 if (auto *VD = dyn_cast(D))
   return getCanonicalForwardRedeclChain(VD);
+if (auto *TD = dyn_cast(D))
+  return getCanonicalForwardRedeclChain(TD);
 llvm_unreachable("Bad declaration kind");
   }
 
@@ -2607,10 +2609,9 @@ ExpectedDecl ASTNodeImporter::VisitRecor
   return std::move(Err);
 IDNS = Decl::IDNS_Ordinary;
   } else if (Importer.getToContext().getLangOpts().CPlusPlus)
-IDNS |= Decl::IDNS_Ordinary;
+IDNS |= Decl::IDNS_Ordinary | Decl::IDNS_TagFriend;
 
   // We may already have a record of the same name; try to find and match it.
-  RecordDecl *AdoptDecl = nullptr;
   RecordDecl *PrevDecl = nullptr;
   if (!DC->isFunctionOrMethod()) {
 SmallVector ConflictingDecls;
@@ -2643,26 +2644,22 @@ ExpectedDecl ASTNodeImporter::VisitRecor
   }
 
   if (auto *FoundRecord = dyn_cast(Found)) {
-if (!SearchName) {
+// Do not emit false positive diagnostic in case of unnamed
+// struct/union and in case of anonymous structs.  Would be false
+// because there may be several anonymous/unnamed structs in a class.
+// E.g. these are both valid:
+//  struct A { // unnamed structs
+//struct { struct A *next; } entry0;
+//struct { struct A *next; } entry1;
+//  };
+//  

r349351 - [ASTImporter] Add importer specific lookup

2018-12-17 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Dec 17 05:53:12 2018
New Revision: 349351

URL: http://llvm.org/viewvc/llvm-project?rev=349351&view=rev
Log:
[ASTImporter] Add importer specific lookup

Summary:
There are certain cases when normal C/C++ lookup (localUncachedLookup)
does not find AST nodes. E.g.:

Example 1:

  template 
  struct X {
friend void foo(); // this is never found in the DC of the TU.
  };

Example 2:

  // The fwd decl to Foo is not found in the lookupPtr of the DC of the
  // translation unit decl.
  struct A { struct Foo *p; };

In these cases we create a new node instead of returning with the old one.
To fix it we create a new lookup table which holds every node and we are
not interested in any C++ specific visibility considerations.
Simply, we must know if there is an existing Decl in a given DC.

Reviewers: a_sidorin, a.sidorin

Subscribers: mgorny, rnkovacs, dkrupp, Szelethus, cfe-commits

Differential Revision: https://reviews.llvm.org/D53708

Added:
cfe/trunk/include/clang/AST/ASTImporterLookupTable.h
cfe/trunk/lib/AST/ASTImporterLookupTable.cpp
Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/CMakeLists.txt
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
cfe/trunk/lib/Frontend/ASTMerge.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=349351&r1=349350&r2=349351&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Mon Dec 17 05:53:12 2018
@@ -33,6 +33,7 @@
 namespace clang {
 
 class ASTContext;
+class ASTImporterLookupTable;
 class CXXBaseSpecifier;
 class CXXCtorInitializer;
 class Decl;
@@ -80,12 +81,21 @@ class Attr;
   /// Imports selected nodes from one AST context into another context,
   /// merging AST nodes where appropriate.
   class ASTImporter {
+friend class ASTNodeImporter;
   public:
 using NonEquivalentDeclSet = llvm::DenseSet>;
 using ImportedCXXBaseSpecifierMap =
 llvm::DenseMap;
 
   private:
+
+/// Pointer to the import specific lookup table, which may be shared
+/// amongst several ASTImporter objects.
+/// This is an externally managed resource (and should exist during the
+/// lifetime of the ASTImporter object)
+/// If not set then the original C/C++ lookup is used.
+ASTImporterLookupTable *LookupTable = nullptr;
+
 /// The contexts we're importing to and from.
 ASTContext &ToContext, &FromContext;
 
@@ -123,9 +133,13 @@ class Attr;
 /// (which we have already complained about).
 NonEquivalentDeclSet NonEquivalentDecls;
 
+using FoundDeclsTy = SmallVector;
+FoundDeclsTy findDeclsInToCtx(DeclContext *DC, DeclarationName Name);
+
+void AddToLookupTable(Decl *ToD);
+
   public:
-/// Create a new AST importer.
-///
+
 /// \param ToContext The context we'll be importing into.
 ///
 /// \param ToFileManager The file manager we'll be importing into.
@@ -137,9 +151,14 @@ class Attr;
 /// \param MinimalImport If true, the importer will attempt to import
 /// as little as it can, e.g., by importing declarations as forward
 /// declarations that can be completed at a later point.
+///
+/// \param LookupTable The importer specific lookup table which may be
+/// shared amongst several ASTImporter objects.
+/// If not set then the original C/C++ lookup is used.
 ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
 ASTContext &FromContext, FileManager &FromFileManager,
-bool MinimalImport);
+bool MinimalImport,
+ASTImporterLookupTable *LookupTable = nullptr);
 
 virtual ~ASTImporter();
 

Added: cfe/trunk/include/clang/AST/ASTImporterLookupTable.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporterLookupTable.h?rev=349351&view=auto
==
--- cfe/trunk/include/clang/AST/ASTImporterLookupTable.h (added)
+++ cfe/trunk/include/clang/AST/ASTImporterLookupTable.h Mon Dec 17 05:53:12 
2018
@@ -0,0 +1,75 @@
+//===- ASTImporterLookupTable.h - ASTImporter specific lookup--*- C++ 
-*---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+//  This file defines the ASTImporterLookupTable class which implements a
+//  lookup procedure for the import mechanism.
+//
+//===--===//
+
+#ifndef LLV

r350521 - [CTU] Make loadExternalAST return with non nullptr on success

2019-01-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jan  7 06:05:19 2019
New Revision: 350521

URL: http://llvm.org/viewvc/llvm-project?rev=350521&view=rev
Log:
[CTU] Make loadExternalAST return with non nullptr on success

Summary:
In loadExternalAST we return with either an error or with a valid
ASTUnit pointer which should not be a nullptr.
This prevents in the call site any superfluous check for being a nullptr.

Reviewers: xazax.hun, a_sidorin, Szelethus, balazske

Subscribers: rnkovacs, dkrupp, gamesh411, cfe-commits

Differential Revision: https://reviews.llvm.org/D55280

Modified:
cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp

Modified: cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h?rev=350521&r1=350520&r2=350521&view=diff
==
--- cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h (original)
+++ cfe/trunk/include/clang/CrossTU/CrossTranslationUnit.h Mon Jan  7 06:05:19 
2019
@@ -130,8 +130,9 @@ public:
   /// \p IndexName. In case the declaration is found in the index the
   /// corresponding AST file will be loaded.
   ///
-  /// \return Returns an ASTUnit that contains the definition of the looked up
-  /// function.
+  /// \return Returns a pointer to the ASTUnit that contains the definition of
+  /// the looked up function or an Error.
+  /// The returned pointer is never a nullptr.
   ///
   /// Note that the AST files should also be in the \p CrossTUDir.
   llvm::Expected loadExternalAST(StringRef LookupName,

Modified: cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp?rev=350521&r1=350520&r2=350521&view=diff
==
--- cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp (original)
+++ cfe/trunk/lib/CrossTU/CrossTranslationUnit.cpp Mon Jan  7 06:05:19 2019
@@ -208,9 +208,6 @@ CrossTranslationUnitContext::getCrossTUD
   if (!ASTUnitOrError)
 return ASTUnitOrError.takeError();
   ASTUnit *Unit = *ASTUnitOrError;
-  if (!Unit)
-return llvm::make_error(
-index_error_code::failed_to_get_external_ast);
   assert(&Unit->getFileManager() ==
  &Unit->getASTContext().getSourceManager().getFileManager());
 
@@ -324,6 +321,9 @@ llvm::Expected CrossTranslati
   } else {
 Unit = FnUnitCacheEntry->second;
   }
+  if (!Unit)
+return llvm::make_error(
+index_error_code::failed_to_get_external_ast);
   return Unit;
 }
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r371839 - [ASTImporter] Add development internals docs

2019-09-13 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Sep 13 04:21:52 2019
New Revision: 371839

URL: http://llvm.org/viewvc/llvm-project?rev=371839&view=rev
Log:
[ASTImporter] Add development internals docs

Reviewers: a_sidorin, shafik, teemperor, gamesh411, balazske, dkrupp, a.sidorin

Subscribers: rnkovacs, Szelethus, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D66336

Modified:
cfe/trunk/docs/InternalsManual.rst

Modified: cfe/trunk/docs/InternalsManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/InternalsManual.rst?rev=371839&r1=371838&r2=371839&view=diff
==
--- cfe/trunk/docs/InternalsManual.rst (original)
+++ cfe/trunk/docs/InternalsManual.rst Fri Sep 13 04:21:52 2019
@@ -1447,6 +1447,495 @@ or by simply a pointer to the canonical
 are not ``Redeclarable`` -- in that case, a ``Mergeable`` base class is used
 instead).
 
+The ASTImporter
+---
+
+The ``ASTImporter`` class imports nodes of an ``ASTContext`` into another
+``ASTContext``. Please refer to the document :doc:`ASTImporter: Merging Clang
+ASTs ` for an introduction. And please read through the
+high-level `description of the import algorithm
+`_, this is essential for
+understanding further implementation details of the importer.
+
+.. _templated:
+
+Abstract Syntax Graph
+^
+
+Despite the name, the Clang AST is not a tree. It is a directed graph with
+cycles. One example of a cycle is the connection between a
+``ClassTemplateDecl`` and its "templated" ``CXXRecordDecl``. The *templated*
+``CXXRecordDecl`` represents all the fields and methods inside the class
+template, while the ``ClassTemplateDecl`` holds the information which is
+related to being a template, i.e. template arguments, etc. We can get the
+*templated* class (the ``CXXRecordDecl``) of a ``ClassTemplateDecl`` with
+``ClassTemplateDecl::getTemplatedDecl()``. And we can get back a pointer of the
+"described" class template from the *templated* class:
+``CXXRecordDecl::getDescribedTemplate()``. So, this is a cycle between two
+nodes: between the *templated* and the *described* node. There may be various
+other kinds of cycles in the AST especially in case of declarations.
+
+.. _structural-eq:
+
+Structural Equivalency
+^^
+
+Importing one AST node copies that node into the destination ``ASTContext``. To
+copy one node means that we create a new node in the "to" context then we set
+its properties to be equal to the properties of the source node. Before the
+copy, we make sure that the source node is not *structurally equivalent* to any
+existing node in the destination context. If it happens to be equivalent then
+we skip the copy.
+
+The informal definition of structural equivalency is the following:
+Two nodes are **structurally equivalent** if they are
+
+- builtin types and refer to the same type, e.g. ``int`` and ``int`` are
+  structurally equivalent,
+- function types and all their parameters have structurally equivalent types,
+- record types and all their fields in order of their definition have the same
+  identifier names and structurally equivalent types,
+- variable or function declarations and they have the same identifier name and
+  their types are structurally equivalent.
+
+In C, two types are structurally equivalent if they are *compatible types*. For
+a formal definition of *compatible types*, please refer to 6.2.7/1 in the C11
+standard. However, there is no definition for *compatible types* in the C++
+standard. Still, we extend the definition of structural equivalency to
+templates and their instantiations similarly: besides checking the previously
+mentioned properties, we have to check for equivalent template
+parameters/arguments, etc.
+
+The structural equivalent check can be and is used independently from the
+ASTImporter, e.g. the ``clang::Sema`` class uses it also.
+
+The equivalence of nodes may depend on the equivalency of other pairs of nodes.
+Thus, the check is implemented as a parallel graph traversal. We traverse
+through the nodes of both graphs at the same time. The actual implementation is
+similar to breadth-first-search. Let's say we start the traverse with the 
+pair of nodes. Whenever the traversal reaches a pair  then the following
+statements are true:
+
+- A and X are nodes from the same ASTContext.
+- B and Y are nodes from the same ASTContext.
+- A and B may or may not be from the same ASTContext.
+- if A == X (pointer equivalency) then (there is a cycle during the traverse)
+
+  - A and B are structurally equivalent if and only if
+
+- B and Y are part of the same redeclaration chain,
+- All dependent nodes on the path from  to  are structurally
+  equivalent.
+
+When we compare two classes or enums and one of them is incomplete or has
+unloaded external lexical declarations then we cannot descend to compare their
+contained declarations. So in these cases they are con

r372564 - [ASTImporter][NFC] Add comprehensive tests for ODR violation handling strategies

2019-09-23 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Sep 23 02:32:07 2019
New Revision: 372564

URL: http://llvm.org/viewvc/llvm-project?rev=372564&view=rev
Log:
[ASTImporter][NFC] Add comprehensive tests for ODR violation handling strategies

Summary:
In this patch we provide additional and comprehensive tests for the ODR
handling strategies. This is the continuation of
https://reviews.llvm.org/D59692.

Reviewers: shafik, a_sidorin, balazske, a.sidorin

Subscribers: mgorny, rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D66951

Added:
cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp
Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/CMakeLists.txt

Added: cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp?rev=372564&view=auto
==
--- cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp (added)
+++ cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp Mon Sep 23 
02:32:07 2019
@@ -0,0 +1,670 @@
+//===- unittest/AST/ASTImporterODRStrategiesTest.cpp 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// Type-parameterized tests to verify the import behaviour in case of ODR
+// violation.
+//
+//===--===//
+
+#include "ASTImporterFixtures.h"
+
+namespace clang {
+namespace ast_matchers {
+
+using internal::BindableMatcher;
+
+// DeclTy: Type of the Decl to check.
+// Prototype: "Prototype" (forward declaration) of the Decl.
+// Definition: A definition for the Prototype.
+// ConflictingPrototype: A prototype with the same name but different
+// declaration.
+// ConflictingDefinition: A different definition for Prototype.
+// ConflictingProtoDef: A definition for ConflictingPrototype.
+// getPattern: Return a matcher that matches any of Prototype, Definition,
+// ConflictingPrototype, ConflictingDefinition, ConflictingProtoDef.
+
+struct Function {
+  using DeclTy = FunctionDecl;
+  static constexpr auto *Prototype = "void X(int);";
+  static constexpr auto *ConflictingPrototype = "void X(double);";
+  static constexpr auto *Definition = "void X(int a) {}";
+  static constexpr auto *ConflictingDefinition = "void X(double a) {}";
+  BindableMatcher getPattern() {
+return functionDecl(hasName("X"), unless(isImplicit()));
+  }
+  Language getLang() { return Lang_C; }
+};
+
+struct Typedef {
+  using DeclTy = TypedefNameDecl;
+  static constexpr auto *Definition = "typedef int X;";
+  static constexpr auto *ConflictingDefinition = "typedef double X;";
+  BindableMatcher getPattern() { return typedefNameDecl(hasName("X")); }
+  Language getLang() { return Lang_CXX; }
+};
+
+struct TypedefAlias {
+  using DeclTy = TypedefNameDecl;
+  static constexpr auto *Definition = "using X = int;";
+  static constexpr auto *ConflictingDefinition = "using X = double;";
+  BindableMatcher getPattern() { return typedefNameDecl(hasName("X")); }
+  Language getLang() { return Lang_CXX11; }
+};
+
+struct Enum {
+  using DeclTy = EnumDecl;
+  static constexpr auto *Definition = "enum X { a, b };";
+  static constexpr auto *ConflictingDefinition = "enum X { a, b, c };";
+  BindableMatcher getPattern() { return enumDecl(hasName("X")); }
+  Language getLang() { return Lang_CXX; }
+};
+
+struct EnumConstant {
+  using DeclTy = EnumConstantDecl;
+  static constexpr auto *Definition = "enum E { X = 0 };";
+  static constexpr auto *ConflictingDefinition = "enum E { X = 1 };";
+  BindableMatcher getPattern() { return enumConstantDecl(hasName("X")); }
+  Language getLang() { return Lang_CXX; }
+};
+
+struct Class {
+  using DeclTy = CXXRecordDecl;
+  static constexpr auto *Prototype = "class X;";
+  static constexpr auto *Definition = "class X {};";
+  static constexpr auto *ConflictingDefinition = "class X { int A; };";
+  BindableMatcher getPattern() {
+return cxxRecordDecl(hasName("X"), unless(isImplicit()));
+  }
+  Language getLang() { return Lang_CXX; }
+};
+
+struct Variable {
+  using DeclTy = VarDecl;
+  static constexpr auto *Prototype = "extern int X;";
+  static constexpr auto *ConflictingPrototype = "extern float X;";
+  static constexpr auto *Definition = "int X;";
+  static constexpr auto *ConflictingDefinition = "float X;";
+  BindableMatcher getPattern() { return varDecl(hasName("X")); }
+  Language getLang() { return Lang_CXX; }
+};
+
+struct ClassTemplate {
+  using DeclTy = ClassTemplateDecl;
+  static constexpr auto *Prototype = "template  class X;";
+  static constexpr auto *ConflictingPrototype = "templa

r372633 - [ASTImporter] Attempt to fix Windows buildbot test errors

2019-09-23 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Sep 23 10:29:08 2019
New Revision: 372633

URL: http://llvm.org/viewvc/llvm-project?rev=372633&view=rev
Log:
[ASTImporter] Attempt to fix Windows buildbot test errors

Modified:
cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp?rev=372633&r1=372632&r2=372633&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp Mon Sep 23 
10:29:08 2019
@@ -30,9 +30,9 @@ using internal::BindableMatcher;
 
 struct Function {
   using DeclTy = FunctionDecl;
-  static constexpr auto *Prototype = "void X(int);";
+  static constexpr auto *Prototype = "void X(long);";
   static constexpr auto *ConflictingPrototype = "void X(double);";
-  static constexpr auto *Definition = "void X(int a) {}";
+  static constexpr auto *Definition = "void X(long a) {}";
   static constexpr auto *ConflictingDefinition = "void X(double a) {}";
   BindableMatcher getPattern() {
 return functionDecl(hasName("X"), unless(isImplicit()));


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372646 - [ASTImporter] 2nd attempt to fix Windows buildbot test errors

2019-09-23 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Sep 23 12:49:45 2019
New Revision: 372646

URL: http://llvm.org/viewvc/llvm-project?rev=372646&view=rev
Log:
[ASTImporter] 2nd attempt to fix Windows buildbot test errors

Modified:
cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp?rev=372646&r1=372645&r2=372646&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp Mon Sep 23 
12:49:45 2019
@@ -30,9 +30,9 @@ using internal::BindableMatcher;
 
 struct Function {
   using DeclTy = FunctionDecl;
-  static constexpr auto *Prototype = "void X(long);";
+  static constexpr auto *Prototype = "void X(char*, char);";
   static constexpr auto *ConflictingPrototype = "void X(double);";
-  static constexpr auto *Definition = "void X(long a) {}";
+  static constexpr auto *Definition = "void X(char *a, char b) {}";
   static constexpr auto *ConflictingDefinition = "void X(double a) {}";
   BindableMatcher getPattern() {
 return functionDecl(hasName("X"), unless(isImplicit()));


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372688 - [ASTImporter] 3rd attempt to fix Windows buildbot test errors

2019-09-23 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Sep 23 22:50:02 2019
New Revision: 372688

URL: http://llvm.org/viewvc/llvm-project?rev=372688&view=rev
Log:
[ASTImporter] 3rd attempt to fix Windows buildbot test errors

Modified:
cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp?rev=372688&r1=372687&r2=372688&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp Mon Sep 23 
22:50:02 2019
@@ -30,9 +30,9 @@ using internal::BindableMatcher;
 
 struct Function {
   using DeclTy = FunctionDecl;
-  static constexpr auto *Prototype = "void X(char*, char);";
+  static constexpr auto *Prototype = "void X(int);";
   static constexpr auto *ConflictingPrototype = "void X(double);";
-  static constexpr auto *Definition = "void X(char *a, char b) {}";
+  static constexpr auto *Definition = "void X(int a) {}";
   static constexpr auto *ConflictingDefinition = "void X(double a) {}";
   BindableMatcher getPattern() {
 return functionDecl(hasName("X"), unless(isImplicit()));
@@ -582,7 +582,8 @@ ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_C
 
 INSTANTIATE_TEST_CASE_P(
 ODRViolationTests, FunctionConservative,
-DefaultTestValuesForRunOptions, );
+// These tests fail on Windows.
+::testing::Values(ArgVector{"-target", "x86_64-pc-linux-gnu"}), );
 INSTANTIATE_TEST_CASE_P(
 ODRViolationTests, TypedefConservative,
 DefaultTestValuesForRunOptions, );
@@ -624,7 +625,8 @@ INSTANTIATE_TEST_CASE_P(
 
 INSTANTIATE_TEST_CASE_P(
 ODRViolationTests, FunctionLiberal,
-DefaultTestValuesForRunOptions, );
+// These tests fail on Windows.
+::testing::Values(ArgVector{"-target", "x86_64-pc-linux-gnu"}), );
 INSTANTIATE_TEST_CASE_P(
 ODRViolationTests, TypedefLiberal,
 DefaultTestValuesForRunOptions, );


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372705 - [ASTImporter] 4th attempt to fix Windows buildbot test errors

2019-09-24 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Sep 24 02:00:46 2019
New Revision: 372705

URL: http://llvm.org/viewvc/llvm-project?rev=372705&view=rev
Log:
[ASTImporter] 4th attempt to fix Windows buildbot test errors

Modified:
cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp?rev=372705&r1=372704&r2=372705&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterODRStrategiesTest.cpp Tue Sep 24 
02:00:46 2019
@@ -580,10 +580,12 @@ ASTIMPORTER_ODR_INSTANTIATE_TYPED_TEST_C
 // Instantiate the tests.
 // ==
 
+// FIXME: These fail on Windows.
+#if !defined(_WIN32)
 INSTANTIATE_TEST_CASE_P(
 ODRViolationTests, FunctionConservative,
-// These tests fail on Windows.
-::testing::Values(ArgVector{"-target", "x86_64-pc-linux-gnu"}), );
+DefaultTestValuesForRunOptions, );
+#endif
 INSTANTIATE_TEST_CASE_P(
 ODRViolationTests, TypedefConservative,
 DefaultTestValuesForRunOptions, );
@@ -623,10 +625,12 @@ INSTANTIATE_TEST_CASE_P(
 //ODRViolationTests, VarTemplateSpecConservative,
 //DefaultTestValuesForRunOptions, );
 
+// FIXME: These fail on Windows.
+#if !defined(_WIN32)
 INSTANTIATE_TEST_CASE_P(
 ODRViolationTests, FunctionLiberal,
-// These tests fail on Windows.
-::testing::Values(ArgVector{"-target", "x86_64-pc-linux-gnu"}), );
+DefaultTestValuesForRunOptions, );
+#endif
 INSTANTIATE_TEST_CASE_P(
 ODRViolationTests, TypedefLiberal,
 DefaultTestValuesForRunOptions, );


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r335455 - [ASTImporter] Add new tests about templated-described swing

2018-06-25 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jun 25 04:38:43 2018
New Revision: 335455

URL: http://llvm.org/viewvc/llvm-project?rev=335455&view=rev
Log:
[ASTImporter] Add new tests about templated-described swing

Summary:
Add a new test about importing a partial specialization (of a class).  Also,
this patch adds new tests about the templated-described swing, some of these
fail ATM, but subsequent patches will fix them.

Reviewers: a.sidorin, r.stahl, xazax.hun

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D47534

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=335455&r1=335454&r2=335455&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Jun 25 04:38:43 2018
@@ -1095,6 +1095,20 @@ TEST(ImportDecl, ImportTemplatedDeclForT
  unless(has(cxxRecordDecl(hasName("declToImport";
 }
 
+TEST(ImportDecl, ImportClassTemplatePartialSpecialization) {
+  MatchVerifier Verifier;
+  auto Code =
+  R"s(
+  struct declToImport {
+template  struct X;
+template  struct X {};
+  };
+  )s";
+  testImport(Code, Lang_CXX, "", Lang_CXX, Verifier,
+ recordDecl(has(classTemplateDecl()),
+has(classTemplateSpecializationDecl(;
+}
+
 TEST(ImportExpr, CXXOperatorCallExpr) {
   MatchVerifier Verifier;
   testImport("class declToImport {"
@@ -1128,6 +1142,52 @@ TEST_P(ASTImporterTestBase, ImportOfTemp
   EXPECT_EQ(ToTemplated1, ToTemplated);
 }
 
+TEST_P(ASTImporterTestBase,
+   DISABLED_ImportOfTemplatedDeclOfFunctionTemplateDecl) {
+  Decl *FromTU = getTuDecl("template void f(){}", Lang_CXX);
+  auto From = FirstDeclMatcher().match(
+  FromTU, functionTemplateDecl());
+  ASSERT_TRUE(From);
+  auto To = cast(Import(From, Lang_CXX));
+  ASSERT_TRUE(To);
+  Decl *ToTemplated = To->getTemplatedDecl();
+  Decl *ToTemplated1 = Import(From->getTemplatedDecl(), Lang_CXX);
+  EXPECT_TRUE(ToTemplated1);
+  EXPECT_EQ(ToTemplated1, ToTemplated);
+}
+
+TEST_P(ASTImporterTestBase,
+   ImportOfTemplatedDeclShouldImportTheClassTemplateDecl) {
+  Decl *FromTU = getTuDecl("template struct S{};", Lang_CXX);
+  auto FromFT =
+  FirstDeclMatcher().match(FromTU, classTemplateDecl());
+  ASSERT_TRUE(FromFT);
+
+  auto ToTemplated =
+  cast(Import(FromFT->getTemplatedDecl(), Lang_CXX));
+  EXPECT_TRUE(ToTemplated);
+  auto ToTU = ToTemplated->getTranslationUnitDecl();
+  auto ToFT =
+  FirstDeclMatcher().match(ToTU, classTemplateDecl());
+  EXPECT_TRUE(ToFT);
+}
+
+TEST_P(ASTImporterTestBase,
+   DISABLED_ImportOfTemplatedDeclShouldImportTheFunctionTemplateDecl) {
+  Decl *FromTU = getTuDecl("template void f(){}", Lang_CXX);
+  auto FromFT = FirstDeclMatcher().match(
+  FromTU, functionTemplateDecl());
+  ASSERT_TRUE(FromFT);
+
+  auto ToTemplated =
+  cast(Import(FromFT->getTemplatedDecl(), Lang_CXX));
+  EXPECT_TRUE(ToTemplated);
+  auto ToTU = ToTemplated->getTranslationUnitDecl();
+  auto ToFT = FirstDeclMatcher().match(
+  ToTU, functionTemplateDecl());
+  EXPECT_TRUE(ToFT);
+}
+
 TEST_P(ASTImporterTestBase, ImportCorrectTemplatedDecl) {
   auto Code =
 R"(


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r335464 - [ASTImporter] Add ms compatibility to tests which use the TestBase

2018-06-25 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jun 25 06:04:37 2018
New Revision: 335464

URL: http://llvm.org/viewvc/llvm-project?rev=335464&view=rev
Log:
[ASTImporter] Add ms compatibility to tests which use the TestBase

Summary:
In order to avoid build failures on MS, we use -fms-compatibility too in
the tests which use the TestBase.  Moved the family of `testImport`
functions under a test fixture class, so we can use parameterized tests.
Refactored `testImport` and `testImportSequence`, because `for` loops over
the different compiler options is no longer needed, that is handeld by
the test framework via parameters from now on.

Reviewers: a.sidorin, r.stahl, xazax.hun

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D47367

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/Language.cpp
cfe/trunk/unittests/AST/Language.h

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=335464&r1=335463&r2=335464&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Jun 25 06:04:37 2018
@@ -50,114 +50,233 @@ static void createVirtualFileIfNeeded(AS
llvm::MemoryBuffer::getMemBuffer(Code));
 }
 
-template 
-NodeType importNode(ASTUnit *From, ASTUnit *To, ASTImporter &Importer,
-NodeType Node) {
-  ASTContext &ToCtx = To->getASTContext();
-
-  // Add 'From' file to virtual file system so importer can 'find' it
-  // while importing SourceLocations. It is safe to add same file multiple
-  // times - it just isn't replaced.
-  StringRef FromFileName = From->getMainFileName();
-  createVirtualFileIfNeeded(To, FromFileName,
-From->getBufferForFile(FromFileName));
-
-  auto Imported = Importer.Import(Node);
-
-  // This should dump source locations and assert if some source locations
-  // were not imported.
-  SmallString<1024> ImportChecker;
-  llvm::raw_svector_ostream ToNothing(ImportChecker);
-  ToCtx.getTranslationUnitDecl()->print(ToNothing);
-
-  // This traverses the AST to catch certain bugs like poorly or not
-  // implemented subtrees.
-  Imported->dump(ToNothing);
-
-  return Imported;
-}
-
 const StringRef DeclToImportID = "declToImport";
 const StringRef DeclToVerifyID = "declToVerify";
 
-template 
-testing::AssertionResult
-testImport(const std::string &FromCode, const ArgVector &FromArgs,
-   const std::string &ToCode, const ArgVector &ToArgs,
-   MatchVerifier &Verifier,
-   const BindableMatcher &SearchMatcher,
-   const BindableMatcher &VerificationMatcher) {
-  const char *const InputFileName = "input.cc";
-  const char *const OutputFileName = "output.cc";
+// Common base for the different families of ASTImporter tests that are
+// parameterized on the compiler options which may result a different AST. E.g.
+// -fms-compatibility or -fdelayed-template-parsing.
+struct ParameterizedTestsFixture : ::testing::TestWithParam {
 
-  std::unique_ptr
-  FromAST = tooling::buildASTFromCodeWithArgs(
-FromCode, FromArgs, InputFileName),
-  ToAST = tooling::buildASTFromCodeWithArgs(ToCode, ToArgs, 
OutputFileName);
-
-  ASTContext &FromCtx = FromAST->getASTContext(),
-  &ToCtx = ToAST->getASTContext();
-
-  FromAST->enableSourceFileDiagnostics();
-  ToAST->enableSourceFileDiagnostics();
-
-  ASTImporter Importer(ToCtx, ToAST->getFileManager(),
-   FromCtx, FromAST->getFileManager(), false);
-
-  auto FoundNodes = match(SearchMatcher, FromCtx);
-  if (FoundNodes.size() != 1)
-return testing::AssertionFailure()
-   << "Multiple potential nodes were found!";
-
-  auto ToImport = selectFirst(DeclToImportID, FoundNodes);
-  if (!ToImport)
-return testing::AssertionFailure() << "Node type mismatch!";
-
-  // Sanity check: the node being imported should match in the same way as
-  // the result node.
-  BindableMatcher WrapperMatcher(VerificationMatcher);
-  EXPECT_TRUE(Verifier.match(ToImport, WrapperMatcher));
-
-  auto Imported = importNode(FromAST.get(), ToAST.get(), Importer, ToImport);
-  if (!Imported)
-return testing::AssertionFailure() << "Import failed, nullptr returned!";
-
-  return Verifier.match(Imported, WrapperMatcher);
-}
-
-template 
-testing::AssertionResult
-testImport(const std::string &FromCode, const ArgVector &FromArgs,
-   const std::string &ToCode, const ArgVector &ToArgs,
-   MatchVerifier &Verifier,
-   const BindableMatcher &VerificationMatcher) {
-  return testImport(
-  FromCode, FromArgs, ToCode, ToArgs, Verifier,
-  translationUnitDecl(
-  has(namedDecl(hasName(DeclToImportID)).bind(DeclToImportID))),
-  VerificationMatcher);
-}
-
-/// Test how AST node named "declToImport" loc

r335480 - [ASTImporter] Import the whole redecl chain of functions

2018-06-25 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jun 25 07:41:58 2018
New Revision: 335480

URL: http://llvm.org/viewvc/llvm-project?rev=335480&view=rev
Log:
[ASTImporter] Import the whole redecl chain of functions

Summary:
With this patch when any `FunctionDecl` of a redeclaration chain is imported
then we bring in the whole declaration chain.  This involves functions and
function template specializations.  Also friend functions are affected.  The
chain is imported as it is in the "from" tu, the order of the redeclarations
are kept.  I also changed the lookup logic in order to find friends, but first
making them visible in their declaration context.  We may have long
redeclaration chains if all TU contains the same prototype, but our
measurements shows no degradation in time of CTU analysis (Tmux, Xerces,
Bitcoin, Protobuf).  Also, as further work we could squash redundant
prototypes, but first ensure that functionality is working properly; then
should we optimize.

This may seem like a huge patch, sorry about that. But, most of the changes are
new tests, changes in the production code is not that much.  I also tried to
create a smaller patch which does not affect specializations, but that patch
failed to pass some of the `clang-import-test`s because there we import
function specializations. Also very importantly, we can't just change the
import of `FunctionDecl`s without changing the import of function template
specializations because they are handled as `FunctionDecl`s.

Reviewers: a.sidorin, r.stahl, xazax.hun, balazske

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D47532

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/test/ASTMerge/class/test.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=335480&r1=335479&r2=335480&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Mon Jun 25 07:41:58 2018
@@ -43,6 +43,15 @@ class TagDecl;
 class TypeSourceInfo;
 class Attr;
 
+  // \brief Returns with a list of declarations started from the canonical decl
+  // then followed by subsequent decls in the translation unit.
+  // This gives a canonical list for each entry in the redecl chain.
+  // `Decl::redecls()` gives a list of decls which always start from the
+  // previous decl and the next item is actually the previous item in the order
+  // of source locations.  Thus, `Decl::redecls()` gives different lists for
+  // the different entries in a given redecl chain.
+  llvm::SmallVector getCanonicalForwardRedeclChain(Decl* D);
+
   /// Imports selected nodes from one AST context into another context,
   /// merging AST nodes where appropriate.
   class ASTImporter {

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=335480&r1=335479&r2=335480&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jun 25 07:41:58 2018
@@ -71,6 +71,25 @@
 
 namespace clang {
 
+  template 
+  SmallVector
+  getCanonicalForwardRedeclChain(Redeclarable* D) {
+SmallVector Redecls;
+for (auto *R : D->getFirstDecl()->redecls()) {
+  if (R != D->getFirstDecl())
+Redecls.push_back(R);
+}
+Redecls.push_back(D->getFirstDecl());
+std::reverse(Redecls.begin(), Redecls.end());
+return Redecls;
+  }
+
+  SmallVector getCanonicalForwardRedeclChain(Decl* D) {
+// Currently only FunctionDecl is supported
+auto FD = cast(D);
+return getCanonicalForwardRedeclChain(FD);
+  }
+
   class ASTNodeImporter : public TypeVisitor,
   public DeclVisitor,
   public StmtVisitor {
@@ -195,6 +214,12 @@ namespace clang {
 const InContainerTy &Container,
 TemplateArgumentListInfo &Result);
 
+using TemplateArgsTy = SmallVector;
+using OptionalTemplateArgsTy = Optional;
+std::tuple
+ImportFunctionTemplateWithTemplateArgsFromSpecialization(
+FunctionDecl *FromFD);
+
 bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
 
 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
@@ -408,6 +433,8 @@ namespace clang {
 
 // Importing overrides.
 void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod);
+
+FunctionDecl *FindFunctionTemplateSpecialization(FunctionDecl *FromFD);
   };
 
 template 
@@ -437,6 +464,25 @@ bool ASTNodeImporter::ImportTemplateArgu
 From.arguments(),

r335491 - Revert "[ASTImporter] Import the whole redecl chain of functions"

2018-06-25 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Jun 25 09:25:30 2018
New Revision: 335491

URL: http://llvm.org/viewvc/llvm-project?rev=335491&view=rev
Log:
Revert "[ASTImporter] Import the whole redecl chain of functions"

This reverts commit r335480.

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/test/ASTMerge/class/test.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=335491&r1=335490&r2=335491&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Mon Jun 25 09:25:30 2018
@@ -43,15 +43,6 @@ class TagDecl;
 class TypeSourceInfo;
 class Attr;
 
-  // \brief Returns with a list of declarations started from the canonical decl
-  // then followed by subsequent decls in the translation unit.
-  // This gives a canonical list for each entry in the redecl chain.
-  // `Decl::redecls()` gives a list of decls which always start from the
-  // previous decl and the next item is actually the previous item in the order
-  // of source locations.  Thus, `Decl::redecls()` gives different lists for
-  // the different entries in a given redecl chain.
-  llvm::SmallVector getCanonicalForwardRedeclChain(Decl* D);
-
   /// Imports selected nodes from one AST context into another context,
   /// merging AST nodes where appropriate.
   class ASTImporter {

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=335491&r1=335490&r2=335491&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jun 25 09:25:30 2018
@@ -71,25 +71,6 @@
 
 namespace clang {
 
-  template 
-  SmallVector
-  getCanonicalForwardRedeclChain(Redeclarable* D) {
-SmallVector Redecls;
-for (auto *R : D->getFirstDecl()->redecls()) {
-  if (R != D->getFirstDecl())
-Redecls.push_back(R);
-}
-Redecls.push_back(D->getFirstDecl());
-std::reverse(Redecls.begin(), Redecls.end());
-return Redecls;
-  }
-
-  SmallVector getCanonicalForwardRedeclChain(Decl* D) {
-// Currently only FunctionDecl is supported
-auto FD = cast(D);
-return getCanonicalForwardRedeclChain(FD);
-  }
-
   class ASTNodeImporter : public TypeVisitor,
   public DeclVisitor,
   public StmtVisitor {
@@ -214,12 +195,6 @@ namespace clang {
 const InContainerTy &Container,
 TemplateArgumentListInfo &Result);
 
-using TemplateArgsTy = SmallVector;
-using OptionalTemplateArgsTy = Optional;
-std::tuple
-ImportFunctionTemplateWithTemplateArgsFromSpecialization(
-FunctionDecl *FromFD);
-
 bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
 
 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
@@ -433,8 +408,6 @@ namespace clang {
 
 // Importing overrides.
 void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod);
-
-FunctionDecl *FindFunctionTemplateSpecialization(FunctionDecl *FromFD);
   };
 
 template 
@@ -464,25 +437,6 @@ bool ASTNodeImporter::ImportTemplateArgu
 From.arguments(), Result);
 }
 
-std::tuple
-ASTNodeImporter::ImportFunctionTemplateWithTemplateArgsFromSpecialization(
-FunctionDecl *FromFD) {
-  assert(FromFD->getTemplatedKind() ==
- FunctionDecl::TK_FunctionTemplateSpecialization);
-  auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
-  auto *Template = cast_or_null(
-  Importer.Import(FTSInfo->getTemplate()));
-
-  // Import template arguments.
-  auto TemplArgs = FTSInfo->TemplateArguments->asArray();
-  TemplateArgsTy ToTemplArgs;
-  if (ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
-  ToTemplArgs)) // Error during import.
-return std::make_tuple(Template, OptionalTemplateArgsTy());
-
-  return std::make_tuple(Template, ToTemplArgs);
-}
-
 } // namespace clang
 
 //
@@ -2298,17 +2252,23 @@ bool ASTNodeImporter::ImportTemplateInfo
   }
 
   case FunctionDecl::TK_FunctionTemplateSpecialization: {
-FunctionTemplateDecl* Template;
-OptionalTemplateArgsTy ToTemplArgs;
-std::tie(Template, ToTemplArgs) =
-ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
-if (!Template || !ToTemplArgs)
+auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
+auto *Template = cast_or_null(
+Importer.Import(FTSInfo->getTemplate()));
+if (!Template)
+  

r335600 - [ASTImporter] Use InjectedClassNameType at import of templated record.

2018-06-26 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Jun 26 06:44:24 2018
New Revision: 335600

URL: http://llvm.org/viewvc/llvm-project?rev=335600&view=rev
Log:
[ASTImporter] Use InjectedClassNameType at import of templated record.

Summary:
At import of a record describing a template set its type to
InjectedClassNameType (instead of RecordType).

Reviewers: a.sidorin, martong, r.stahl

Reviewed By: a.sidorin, martong, r.stahl

Subscribers: a_sidorin, rnkovacs, martong, cfe-commits

Differential Revision: https://reviews.llvm.org/D47450

Patch by Balazs Keri!

Added:
cfe/trunk/test/ASTMerge/injected-class-name-decl/
cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/
cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp
cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp
cfe/trunk/test/ASTMerge/injected-class-name-decl/test.cpp
Modified:
cfe/trunk/lib/AST/ASTImporter.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=335600&r1=335599&r2=335600&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Jun 26 06:44:24 2018
@@ -2135,6 +2135,29 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
 if (!ToDescribed)
   return nullptr;
 D2CXX->setDescribedClassTemplate(ToDescribed);
+if (!DCXX->isInjectedClassName()) {
+  // In a record describing a template the type should be an
+  // InjectedClassNameType (see Sema::CheckClassTemplate). Update the
+  // previously set type to the correct value here (ToDescribed is not
+  // available at record create).
+  // FIXME: The previous type is cleared but not removed from
+  // ASTContext's internal storage.
+  CXXRecordDecl *Injected = nullptr;
+  for (NamedDecl *Found : D2CXX->noload_lookup(Name)) {
+auto *Record = dyn_cast(Found);
+if (Record && Record->isInjectedClassName()) {
+  Injected = Record;
+  break;
+}
+  }
+  D2CXX->setTypeForDecl(nullptr);
+  Importer.getToContext().getInjectedClassNameType(D2CXX,
+  ToDescribed->getInjectedClassNameSpecialization());
+  if (Injected) {
+Injected->setTypeForDecl(nullptr);
+Importer.getToContext().getTypeDeclType(Injected, D2CXX);
+  }
+}
   } else if (MemberSpecializationInfo *MemberInfo =
DCXX->getMemberSpecializationInfo()) {
 TemplateSpecializationKind SK =

Added: cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp?rev=335600&view=auto
==
--- cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp (added)
+++ cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject1.cpp Tue Jun 
26 06:44:24 2018
@@ -0,0 +1,2 @@
+template 
+class C { static X x; };

Added: cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp?rev=335600&view=auto
==
--- cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp (added)
+++ cfe/trunk/test/ASTMerge/injected-class-name-decl/Inputs/inject2.cpp Tue Jun 
26 06:44:24 2018
@@ -0,0 +1,2 @@
+template 
+X C::x;

Added: cfe/trunk/test/ASTMerge/injected-class-name-decl/test.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/injected-class-name-decl/test.cpp?rev=335600&view=auto
==
--- cfe/trunk/test/ASTMerge/injected-class-name-decl/test.cpp (added)
+++ cfe/trunk/test/ASTMerge/injected-class-name-decl/test.cpp Tue Jun 26 
06:44:24 2018
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -std=c++1z -emit-pch -o %t.ast %S/Inputs/inject1.cpp
+// RUN: %clang_cc1 -std=c++1z -emit-obj -o /dev/null -ast-merge %t.ast 
%S/Inputs/inject2.cpp
+// expected-no-diagnostics


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r335731 - Re-apply: [ASTImporter] Import the whole redecl chain of functions

2018-06-27 Thread Gabor Marton via cfe-commits
Author: martong
Date: Wed Jun 27 06:32:50 2018
New Revision: 335731

URL: http://llvm.org/viewvc/llvm-project?rev=335731&view=rev
Log:
Re-apply: [ASTImporter] Import the whole redecl chain of functions

Summary:
With this patch when any `FunctionDecl` of a redeclaration chain is imported
then we bring in the whole declaration chain.  This involves functions and
function template specializations.  Also friend functions are affected.  The
chain is imported as it is in the "from" tu, the order of the redeclarations
are kept.  I also changed the lookup logic in order to find friends, but first
making them visible in their declaration context.  We may have long
redeclaration chains if all TU contains the same prototype, but our
measurements shows no degradation in time of CTU analysis (Tmux, Xerces,
Bitcoin, Protobuf).  Also, as further work we could squash redundant
prototypes, but first ensure that functionality is working properly; then
should we optimize.

This may seem like a huge patch, sorry about that. But, most of the changes are
new tests, changes in the production code is not that much.  I also tried to
create a smaller patch which does not affect specializations, but that patch
failed to pass some of the `clang-import-test`s because there we import
function specializations. Also very importantly, we can't just change the
import of `FunctionDecl`s without changing the import of function template
specializations because they are handled as `FunctionDecl`s.

Reviewers: a.sidorin, r.stahl, xazax.hun, balazske, a_sidorin

Reviewed By: a_sidorin

Subscribers: labath, aprantl, a_sidorin, rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D47532

Re-apply commit rC335480

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/test/ASTMerge/class/test.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=335731&r1=335730&r2=335731&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Wed Jun 27 06:32:50 2018
@@ -43,6 +43,15 @@ class TagDecl;
 class TypeSourceInfo;
 class Attr;
 
+  // \brief Returns with a list of declarations started from the canonical decl
+  // then followed by subsequent decls in the translation unit.
+  // This gives a canonical list for each entry in the redecl chain.
+  // `Decl::redecls()` gives a list of decls which always start from the
+  // previous decl and the next item is actually the previous item in the order
+  // of source locations.  Thus, `Decl::redecls()` gives different lists for
+  // the different entries in a given redecl chain.
+  llvm::SmallVector getCanonicalForwardRedeclChain(Decl* D);
+
   /// Imports selected nodes from one AST context into another context,
   /// merging AST nodes where appropriate.
   class ASTImporter {

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=335731&r1=335730&r2=335731&view=diff
==
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Jun 27 06:32:50 2018
@@ -1779,10 +1779,14 @@ public:
 
   /// Removes a declaration from this context.
   void removeDecl(Decl *D);
-
+
   /// Checks whether a declaration is in this context.
   bool containsDecl(Decl *D) const;
 
+  /// Checks whether a declaration is in this context.
+  /// This also loads the Decls from the external source before the check.
+  bool containsDeclAndLoad(Decl *D) const;
+
   using lookup_result = DeclContextLookupResult;
   using lookup_iterator = lookup_result::iterator;
 

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=335731&r1=335730&r2=335731&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Jun 27 06:32:50 2018
@@ -71,6 +71,25 @@
 
 namespace clang {
 
+  template 
+  SmallVector
+  getCanonicalForwardRedeclChain(Redeclarable* D) {
+SmallVector Redecls;
+for (auto *R : D->getFirstDecl()->redecls()) {
+  if (R != D->getFirstDecl())
+Redecls.push_back(R);
+}
+Redecls.push_back(D->getFirstDecl());
+std::reverse(Redecls.begin(), Redecls.end());
+return Redecls;
+  }
+
+  SmallVector getCanonicalForwardRedeclChain(Decl* D) {
+// Currently only FunctionDecl is supported
+auto FD = cast(D);
+return getCanonicalForwardRedeclChain(FD);
+  }
+
   class ASTNodeImporter : public TypeVisi

r335959 - [ASTImporter] Eliminated some unittest warnings.

2018-06-29 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Jun 29 03:25:19 2018
New Revision: 335959

URL: http://llvm.org/viewvc/llvm-project?rev=335959&view=rev
Log:
[ASTImporter] Eliminated some unittest warnings.

Summary:
When running the ASTTests test, warnings produced by the compiler can be
distracting when looking for test errors. A part of the warnings is removed
by setting extra compiler options.

Reviewers: a.sidorin

Reviewed By: a.sidorin

Subscribers: a_sidorin, martong, cfe-commits

Differential Revision: https://reviews.llvm.org/D47459

Patch by Balazs Keri!

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=335959&r1=335958&r2=335959&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Fri Jun 29 03:25:19 2018
@@ -472,138 +472,110 @@ TEST_P(CanonicalRedeclChain, ShouldBeSam
 
 TEST_P(ImportExpr, ImportStringLiteral) {
   MatchVerifier Verifier;
-  testImport("void declToImport() { \"foo\"; }",
- Lang_CXX, "", Lang_CXX, Verifier,
- functionDecl(
-   hasBody(
- compoundStmt(
-   has(
- stringLiteral(
-   hasType(
- asString("const char [4]";
-  testImport("void declToImport() { L\"foo\"; }",
- Lang_CXX, "", Lang_CXX, Verifier,
- functionDecl(
-   hasBody(
- compoundStmt(
-   has(
- stringLiteral(
-   hasType(
-asString("const wchar_t [4]";
-  testImport("void declToImport() { \"foo\" \"bar\"; }",
- Lang_CXX, "", Lang_CXX, Verifier,
- functionDecl(
-   hasBody(
- compoundStmt(
-   has(
- stringLiteral(
-   hasType(
- asString("const char [7]";
+  testImport(
+  "void declToImport() { (void)\"foo\"; }",
+  Lang_CXX, "", Lang_CXX, Verifier,
+  functionDecl(hasDescendant(
+  stringLiteral(hasType(asString("const char [4]"));
+  testImport(
+  "void declToImport() { (void)L\"foo\"; }",
+  Lang_CXX, "", Lang_CXX, Verifier,
+  functionDecl(hasDescendant(
+  stringLiteral(hasType(asString("const wchar_t [4]"));
+  testImport(
+  "void declToImport() { (void) \"foo\" \"bar\"; }",
+  Lang_CXX, "", Lang_CXX, Verifier,
+  functionDecl(hasDescendant(
+  stringLiteral(hasType(asString("const char [7]"));
 }
 
 TEST_P(ImportExpr, ImportGNUNullExpr) {
   MatchVerifier Verifier;
-  testImport("void declToImport() { __null; }",
- Lang_CXX, "", Lang_CXX, Verifier,
- functionDecl(
-   hasBody(
- compoundStmt(
-   has(
- gnuNullExpr(
-   hasType(isInteger(;
+  testImport(
+  "void declToImport() { (void)__null; }",
+  Lang_CXX, "", Lang_CXX, Verifier,
+  functionDecl(hasDescendant(gnuNullExpr(hasType(isInteger());
 }
 
 TEST_P(ImportExpr, ImportCXXNullPtrLiteralExpr) {
   MatchVerifier Verifier;
-  testImport("void declToImport() { nullptr; }",
- Lang_CXX11, "", Lang_CXX11, Verifier,
- functionDecl(
-   hasBody(
- compoundStmt(
-   has(
- cxxNullPtrLiteralExpr());
+  testImport(
+  "void declToImport() { (void)nullptr; }",
+  Lang_CXX11, "", Lang_CXX11, Verifier,
+  functionDecl(hasDescendant(cxxNullPtrLiteralExpr(;
 }
 
 
 TEST_P(ImportExpr, ImportFloatinglLiteralExpr) {
   MatchVerifier Verifier;
-  testImport("void declToImport() { 1.0; }",
- Lang_C, "", Lang_C, Verifier,
- functionDecl(
-   hasBody(
- compoundStmt(
-   has(
- floatLiteral(
-   equals(1.0),
-   hasType(asString("double";
-  testImport("void declToImport() { 1.0e-5f; }",
-  Lang_C, "", Lang_C, Verifier,
-  functionDecl(
-hasBody(
-  compoundStmt(
-has(
-  floatLiteral(
-equals(1.0e-5f),
-hasType(asString("float";
+  testImport(
+  "void declToImport() { (void)1.0; }",
+  Lang_C, "", Lang_C, Verifier,
+  functionDecl(hasDescendant(
+  floatLiteral(equals(1.0), hasType(asString("double"));
+  testImport(
+  "void declToImport() { (void)1.0e-5f; }",
+  Lang_C, "", Lang_C, Verifier,
+  functionDecl(hasDescendant(
+  floatLiteral(equals(1.0e-5f),

r335968 - [ASTImporter] Added import of CXXStdInitializerListExpr

2018-06-29 Thread Gabor Marton via cfe-commits
Author: martong
Date: Fri Jun 29 05:17:34 2018
New Revision: 335968

URL: http://llvm.org/viewvc/llvm-project?rev=335968&view=rev
Log:
[ASTImporter] Added import of CXXStdInitializerListExpr

Reviewers: a.sidorin

Reviewed By: a.sidorin

Subscribers: martong, cfe-commits

Differential Revision: https://reviews.llvm.org/D48631

Patch by Balazs Keri!

Added:
cfe/trunk/test/ASTMerge/std-initializer-list/
cfe/trunk/test/ASTMerge/std-initializer-list/Inputs/
cfe/trunk/test/ASTMerge/std-initializer-list/Inputs/il.cpp
cfe/trunk/test/ASTMerge/std-initializer-list/test.cpp
Modified:
cfe/trunk/lib/AST/ASTImporter.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=335968&r1=335967&r2=335968&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Fri Jun 29 05:17:34 2018
@@ -384,6 +384,7 @@ namespace clang {
 Expr *VisitCallExpr(CallExpr *E);
 Expr *VisitLambdaExpr(LambdaExpr *LE);
 Expr *VisitInitListExpr(InitListExpr *E);
+Expr *VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
 Expr *VisitArrayInitLoopExpr(ArrayInitLoopExpr *E);
 Expr *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E);
 Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
@@ -6622,6 +6623,19 @@ Expr *ASTNodeImporter::VisitInitListExpr
   return To;
 }
 
+Expr *ASTNodeImporter::VisitCXXStdInitializerListExpr(
+CXXStdInitializerListExpr *E) {
+  QualType T = Importer.Import(E->getType());
+  if (T.isNull())
+return nullptr;
+
+  Expr *SE = Importer.Import(E->getSubExpr());
+  if (!SE)
+return nullptr;
+
+  return new (Importer.getToContext()) CXXStdInitializerListExpr(T, SE);
+}
+
 Expr *ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
   QualType ToType = Importer.Import(E->getType());
   if (ToType.isNull())

Added: cfe/trunk/test/ASTMerge/std-initializer-list/Inputs/il.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/std-initializer-list/Inputs/il.cpp?rev=335968&view=auto
==
--- cfe/trunk/test/ASTMerge/std-initializer-list/Inputs/il.cpp (added)
+++ cfe/trunk/test/ASTMerge/std-initializer-list/Inputs/il.cpp Fri Jun 29 
05:17:34 2018
@@ -0,0 +1,9 @@
+namespace std {
+template 
+struct initializer_list {
+  const T *begin, *end;
+  initializer_list();
+};
+} // namespace std
+
+std::initializer_list IL = {1, 2, 3, 4};

Added: cfe/trunk/test/ASTMerge/std-initializer-list/test.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/std-initializer-list/test.cpp?rev=335968&view=auto
==
--- cfe/trunk/test/ASTMerge/std-initializer-list/test.cpp (added)
+++ cfe/trunk/test/ASTMerge/std-initializer-list/test.cpp Fri Jun 29 05:17:34 
2018
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/il.cpp
+// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck 
--allow-empty %s
+// CHECK-NOT: unsupported AST node


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r336332 - [ASTImporter] Fix import of objects with anonymous types

2018-07-05 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jul  5 02:51:13 2018
New Revision: 336332

URL: http://llvm.org/viewvc/llvm-project?rev=336332&view=rev
Log:
[ASTImporter] Fix import of objects with anonymous types

Summary:
Currently, anonymous types are merged into the same redecl chain even if they
are structurally inequivalent. This results that global objects are not
imported, if there are at least two global objects with different anonymous
types. This patch provides a fix.

Reviewers: a.sidorin, balazske, r.stahl

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D48773

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=336332&r1=336331&r2=336332&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Jul  5 02:51:13 2018
@@ -2072,17 +2072,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
 
   if (auto *FoundRecord = dyn_cast(Found)) {
 if (!SearchName) {
-  // If both unnamed structs/unions are in a record context, make sure
-  // they occur in the same location in the context records.
-  if (Optional Index1 =
-  StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
-  D)) {
-if (Optional Index2 = StructuralEquivalenceContext::
-findUntaggedStructOrUnionIndex(FoundRecord)) {
-  if (*Index1 != *Index2)
-continue;
-}
-  }
+  if (!IsStructuralMatch(D, FoundRecord, false))
+continue;
 }
 
 PrevDecl = FoundRecord;

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=336332&r1=336331&r2=336332&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu Jul  5 02:51:13 2018
@@ -1682,6 +1682,35 @@ TEST_P(
 .match(ToTU, classTemplateSpecializationDecl()));
 }
 
+TEST_P(ASTImporterTestBase, ObjectsWithUnnamedStructType) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  struct { int a; int b; } object0 = { 2, 3 };
+  struct { int x; int y; int z; } object1;
+  )",
+  Lang_CXX, "input0.cc");
+
+  auto getRecordDecl = [](VarDecl *VD) {
+auto *ET = cast(VD->getType().getTypePtr());
+return cast(ET->getNamedType().getTypePtr())->getDecl();
+  };
+
+  auto *Obj0 =
+  FirstDeclMatcher().match(FromTU, varDecl(hasName("object0")));
+  auto *From0 = getRecordDecl(Obj0);
+  auto *Obj1 =
+  FirstDeclMatcher().match(FromTU, varDecl(hasName("object1")));
+  auto *From1 = getRecordDecl(Obj1);
+
+  auto *To0 = Import(From0, Lang_CXX);
+  auto *To1 = Import(From1, Lang_CXX);
+
+  EXPECT_TRUE(To0);
+  EXPECT_TRUE(To1);
+  EXPECT_NE(To0, To1);
+  EXPECT_NE(To0->getCanonicalDecl(), To1->getCanonicalDecl());
+}
+
 struct ImportFunctions : ASTImporterTestBase {};
 
 TEST_P(ImportFunctions,


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r336896 - [ASTImporter] Refactor Decl creation

2018-07-12 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jul 12 02:42:05 2018
New Revision: 336896

URL: http://llvm.org/viewvc/llvm-project?rev=336896&view=rev
Log:
[ASTImporter] Refactor Decl creation

Summary:
Generalize the creation of Decl nodes during Import.  With this patch we do the
same things after and before a new AST node is created (::Create) The import
logic should be really simple, we create the node, then we mark that as
imported, then we recursively import the parts for that node and then set them
on that node.  However, the AST is actually a graph, so we have to handle
circles.  If we mark something as imported (`MapImported()`) then we return with
the corresponding `To` decl whenever we want to import that node again, this way
circles are handled.  In order to make this algorithm work we must ensure
things, which are handled in the generic CreateDecl<> template:
* There are no `Import()` calls in between any node creation (::Create)
and the `MapImported()` call.
* Before actually creating an AST node (::Create), we must check if
the Node had been imported already, if yes then return with that one.
One very important case for this is connected to templates: we may
start an import both from the templated decl of a template and from
the template itself.

Now, the virtual `Imported` function is called in `ASTImporter::Impor(Decl *)`,
but only once, when the `Decl` is imported.  One point of this refactor is to
separate responsibilities. The original `Imported()` had 3 responsibilities:
- notify subclasses when an import happened
- register the decl into `ImportedDecls`
- initialise the Decl (set attributes, etc)
Now all of these are in separate functions:
- `Imported`
- `MapImported`
- `InitializeImportedDecl`
I tried to check all the clients, I executed tests for `ExternalASTMerger.cpp`
and some unittests for lldb.

Reviewers: a.sidorin, balazske, xazax.hun, r.stahl

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D47632

Modified:
cfe/trunk/include/clang/AST/ASTImporter.h
cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/lib/AST/ExternalASTMerger.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=336896&r1=336895&r2=336896&view=diff
==
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Thu Jul 12 02:42:05 2018
@@ -314,13 +314,13 @@ class Attr;
 /// \param D A declaration in the "to" context.
 virtual void CompleteDecl(Decl* D);
 
-/// Note that we have imported the "from" declaration by mapping it
-/// to the (potentially-newly-created) "to" declaration.
-///
 /// Subclasses can override this function to observe all of the \c From ->
 /// \c To declaration mappings as they are imported.
-virtual Decl *Imported(Decl *From, Decl *To);
-  
+virtual Decl *Imported(Decl *From, Decl *To) { return To; }
+
+/// Store and assign the imported declaration to its counterpart.
+Decl *MapImported(Decl *From, Decl *To);
+
 /// Called by StructuralEquivalenceContext.  If a RecordDecl is
 /// being compared to another RecordDecl as part of import, completing the
 /// other RecordDecl may trigger importation of the first RecordDecl. This

Modified: cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h?rev=336896&r1=336895&r2=336896&view=diff
==
--- cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h (original)
+++ cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h Thu Jul 12 02:42:05 
2018
@@ -30,6 +30,14 @@ class QualType;
 class RecordDecl;
 class SourceLocation;
 
+/// \brief Whether to perform a normal or minimal equivalence check.
+/// In case of `Minimal`, we do not perform a recursive check of decls with
+/// external storage.
+enum class StructuralEquivalenceKind {
+  Default,
+  Minimal,
+};
+
 struct StructuralEquivalenceContext {
   /// AST contexts for which we are checking structural equivalence.
   ASTContext &FromCtx, &ToCtx;
@@ -47,6 +55,8 @@ struct StructuralEquivalenceContext {
   /// (which we have already complained about).
   llvm::DenseSet> &NonEquivalentDecls;
 
+  StructuralEquivalenceKind EqKind;
+
   /// Whether we're being strict about the spelling of types when
   /// unifying two types.
   bool StrictTypeSpelling;
@@ -63,10 +73,11 @@ struct StructuralEquivalenceContext {
   StructuralEquivalenceContext(
   A

r336898 - [ASTImporter] Fix infinite recursion on function import with struct definition in parameters

2018-07-12 Thread Gabor Marton via cfe-commits
Author: martong
Date: Thu Jul 12 04:50:21 2018
New Revision: 336898

URL: http://llvm.org/viewvc/llvm-project?rev=336898&view=rev
Log:
[ASTImporter] Fix infinite recursion on function import with struct definition 
in parameters

Summary:
Importing a function having a struct definition in the parameter list
causes a crash in the importer via infinite recursion. This patch avoids
the crash and reports such functions as not supported. Unit tests make
sure that normal struct definitions inside function bodies work normally
on the other hand and LLDB-like type imports also do.

Reviewers: a.sidorin, martong

Differential Revision: https://reviews.llvm.org/D47946

Patch by Zoltan Gera!

Modified:
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=336898&r1=336897&r2=336898&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Jul 12 04:50:21 2018
@@ -1138,8 +1138,26 @@ bool ASTNodeImporter::ImportDeclParts(Na
   DeclarationName &Name, 
   NamedDecl *&ToD,
   SourceLocation &Loc) {
+  // Check if RecordDecl is in FunctionDecl parameters to avoid infinite loop.
+  // example: int struct_in_proto(struct data_t{int a;int b;} *d);
+  DeclContext *OrigDC = D->getDeclContext();
+  FunctionDecl *FunDecl;
+  if (isa(D) && (FunDecl = dyn_cast(OrigDC)) &&
+  FunDecl->hasBody()) {
+SourceRange RecR = D->getSourceRange();
+SourceRange BodyR = FunDecl->getBody()->getSourceRange();
+// If RecordDecl is not in Body (it is a param), we bail out.
+if (RecR.isValid() && BodyR.isValid() &&
+(RecR.getBegin() < BodyR.getBegin() ||
+ BodyR.getEnd() < RecR.getEnd())) {
+  Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
+  << D->getDeclKindName();
+  return true;
+}
+  }
+
   // Import the context of this declaration.
-  DC = Importer.ImportContext(D->getDeclContext());
+  DC = Importer.ImportContext(OrigDC);
   if (!DC)
 return true;
   

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=336898&r1=336897&r2=336898&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu Jul 12 04:50:21 2018
@@ -301,14 +301,25 @@ class ASTImporterTestBase : public Param
   Unit->enableSourceFileDiagnostics();
 }
 
-Decl *import(ASTUnit *ToAST, Decl *FromDecl) {
+void lazyInitImporter(ASTUnit *ToAST) {
   assert(ToAST);
   if (!Importer) {
 Importer.reset(new ASTImporter(
 ToAST->getASTContext(), ToAST->getFileManager(),
 Unit->getASTContext(), Unit->getFileManager(), false));
   }
+  assert(&ToAST->getASTContext() == &Importer->getToContext());
+  createVirtualFileIfNeeded(ToAST, FileName, Code);
+}
+
+Decl *import(ASTUnit *ToAST, Decl *FromDecl) {
+  lazyInitImporter(ToAST);
   return Importer->Import(FromDecl);
+ }
+
+QualType import(ASTUnit *ToAST, QualType FromType) {
+  lazyInitImporter(ToAST);
+  return Importer->Import(FromType);
 }
   };
 
@@ -321,6 +332,26 @@ class ASTImporterTestBase : public Param
   // vector is expanding, with the list we won't have these issues.
   std::list FromTUs;
 
+  void lazyInitToAST(Language ToLang) {
+if (ToAST)
+  return;
+ArgVector ToArgs = getArgVectorForLanguage(ToLang);
+// Build the AST from an empty file.
+ToAST = tooling::buildASTFromCodeWithArgs(/*Code=*/"", ToArgs, "empty.cc");
+ToAST->enableSourceFileDiagnostics();
+  }
+
+  TU *findFromTU(Decl *From) {
+// Create a virtual file in the To Ctx which corresponds to the file from
+// which we want to import the `From` Decl. Without this source locations
+// will be invalid in the ToCtx.
+auto It = std::find_if(FromTUs.begin(), FromTUs.end(), [From](const TU &E) 
{
+  return E.TUDecl == From->getTranslationUnitDecl();
+});
+assert(It != FromTUs.end());
+return &*It;
+  }
+
 public:
   // We may have several From context but only one To context.
   std::unique_ptr ToAST;
@@ -394,26 +425,17 @@ public:
   // May be called several times in a given test.
   // The different instances of the param From may have different ASTContext.
   Decl *Import(Decl *From, Language ToLang) {
-if (!ToAST) {
-  ArgVector ToArgs = getArgVectorForLanguage(ToLang);
-  // Build the AST from an empty file.
-  ToAST =
-  tooling::buildASTFromCodeWithArgs(/*Code=*/"", ToArgs, "empty.cc");
-  ToAST->ena

r337267 - [ASTImporter] Fix import of unnamed structs

2018-07-17 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Jul 17 05:06:36 2018
New Revision: 337267

URL: http://llvm.org/viewvc/llvm-project?rev=337267&view=rev
Log:
[ASTImporter] Fix import of unnamed structs

Summary:
D48773 simplified ASTImporter nicely, but it introduced a new error: Unnamed
structs are not imported correctly, if they appear in a recursive context.
This patch provides a fix for structural equivalency.

Reviewers: a.sidorin, a_sidorin, balazske, gerazo

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D49296

Modified:
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=337267&r1=337266&r2=337267&view=diff
==
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Tue Jul 17 05:06:36 2018
@@ -924,7 +924,7 @@ static bool IsStructurallyEquivalent(Str
 return false;
   }
 
-  if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) {
+  if (!D1->getDeclName() && !D2->getDeclName()) {
 // If both anonymous structs/unions are in a record context, make sure
 // they occur in the same location in the context records.
 if (Optional Index1 =

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=337267&r1=337266&r2=337267&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Tue Jul 17 05:06:36 2018
@@ -273,6 +273,11 @@ public:
   }
 };
 
+template  RecordDecl *getRecordDecl(T *D) {
+  auto *ET = cast(D->getType().getTypePtr());
+  return cast(ET->getNamedType().getTypePtr())->getDecl();
+};
+
 // This class provides generic methods to write tests which can check internal
 // attributes of AST nodes like getPreviousDecl(), isVirtual(), etc. Also,
 // this fixture makes it possible to import from several "From" contexts.
@@ -1755,11 +1760,6 @@ TEST_P(ASTImporterTestBase, ObjectsWithU
   )",
   Lang_CXX, "input0.cc");
 
-  auto getRecordDecl = [](VarDecl *VD) {
-auto *ET = cast(VD->getType().getTypePtr());
-return cast(ET->getNamedType().getTypePtr())->getDecl();
-  };
-
   auto *Obj0 =
   FirstDeclMatcher().match(FromTU, varDecl(hasName("object0")));
   auto *From0 = getRecordDecl(Obj0);
@@ -2580,6 +2580,38 @@ TEST_P(ASTImporterTestBase, ImportOfNonE
   EXPECT_NE(ToM1, ToM2);
 }
 
+TEST_P(ASTImporterTestBase, ImportUnnamedStructsWithRecursingField) {
+  Decl *FromTU = getTuDecl(
+  R"(
+  struct A {
+struct {
+  struct A *next;
+} entry0;
+struct {
+  struct A *next;
+} entry1;
+  };
+  )",
+  Lang_C, "input0.cc");
+  auto *From =
+  FirstDeclMatcher().match(FromTU, recordDecl(hasName("A")));
+
+  Import(From, Lang_C);
+
+  auto *ToTU = ToAST->getASTContext().getTranslationUnitDecl();
+  auto *Entry0 =
+  FirstDeclMatcher().match(ToTU, fieldDecl(hasName("entry0")));
+  auto *Entry1 =
+  FirstDeclMatcher().match(ToTU, fieldDecl(hasName("entry1")));
+  auto *R0 = getRecordDecl(Entry0);
+  auto *R1 = getRecordDecl(Entry1);
+  EXPECT_NE(R0, R1);
+  EXPECT_TRUE(MatchVerifier().match(
+  R0, recordDecl(has(fieldDecl(hasName("next"));
+  EXPECT_TRUE(MatchVerifier().match(
+  R1, recordDecl(has(fieldDecl(hasName("next"));
+}
+
 struct DeclContextTest : ASTImporterTestBase {};
 
 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {

Modified: cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp?rev=337267&r1=337266&r2=337267&view=diff
==
--- cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp (original)
+++ cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp Tue Jul 17 05:06:36 
2018
@@ -42,6 +42,21 @@ struct StructuralEquivalenceTest : ::tes
 return std::make_tuple(D0, D1);
   }
 
+  std::tuple makeTuDecls(
+  const std::string &SrcCode0, const std::string &SrcCode1, Language Lang) 
{
+this->Code0 = SrcCode0;
+this->Code1 = SrcCode1;
+ArgVector Args = getBasicRunOptionsForLanguage(Lang);
+
+const char *const InputFileName = "input.cc";
+
+AST0 = tooling::buildASTFromCodeWithArgs(Code0, Args, InputFileName);
+AST1 = tooling::buildASTFromCodeWithArgs(Code1, Args, InputFileName);
+
+return std::make_tuple(AST0->getASTContext().getTranslationUnitDecl(),
+   AST1->getASTContext().getTranslationUnitDe

r337275 - [ASTImporter] Fix poisonous structural equivalence cache

2018-07-17 Thread Gabor Marton via cfe-commits
Author: martong
Date: Tue Jul 17 05:39:27 2018
New Revision: 337275

URL: http://llvm.org/viewvc/llvm-project?rev=337275&view=rev
Log:
[ASTImporter] Fix poisonous structural equivalence cache

Summary:
Implementation functions call into the member functions of
ASTStructuralEquivalence, thus they can falsely alter the DeclsToCheck state
(they add decls).  This results that some leaf declarations can be stated as
inequivalent as a side effect of one inequivalent element in the DeclsToCheck
list.  And since we store the non-equivalencies, any (otherwise independent)
decls will be rendered as non-equivalent.  Solution: I tried to clearly
separate the implementation functions (the static ones) and the public
interface.  From now on, the implementation functions do not call any public
member functions, only other implementation functions.

Reviewers: a.sidorin, a_sidorin, r.stahl

Subscribers: rnkovacs, dkrupp, cfe-commits

Differential Revision: https://reviews.llvm.org/D49300

Modified:
cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h
cfe/trunk/lib/AST/ASTImporter.cpp
cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/unittests/AST/StructuralEquivalenceTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h?rev=337275&r1=337274&r2=337275&view=diff
==
--- cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h (original)
+++ cfe/trunk/include/clang/AST/ASTStructuralEquivalence.h Tue Jul 17 05:39:27 
2018
@@ -85,10 +85,18 @@ struct StructuralEquivalenceContext {
 
   /// Determine whether the two declarations are structurally
   /// equivalent.
-  bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
+  /// Implementation functions (all static functions in
+  /// ASTStructuralEquivalence.cpp) must never call this function because that
+  /// will wreak havoc the internal state (\c DeclsToCheck and
+  /// \c TentativeEquivalences members) and can cause faulty equivalent 
results.
+  bool IsEquivalent(Decl *D1, Decl *D2);
 
   /// Determine whether the two types are structurally equivalent.
-  bool IsStructurallyEquivalent(QualType T1, QualType T2);
+  /// Implementation functions (all static functions in
+  /// ASTStructuralEquivalence.cpp) must never call this function because that
+  /// will wreak havoc the internal state (\c DeclsToCheck and
+  /// \c TentativeEquivalences members) and can cause faulty equivalent 
results.
+  bool IsEquivalent(QualType T1, QualType T2);
 
   /// Find the index of the given anonymous struct/union within its
   /// context.

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=337275&r1=337274&r2=337275&view=diff
==
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Jul 17 05:39:27 2018
@@ -295,6 +295,7 @@ namespace clang {
 
 bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
 
+bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
 bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
 bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
@@ -1592,7 +1593,15 @@ getStructuralEquivalenceKind(const ASTIm
 : StructuralEquivalenceKind::Default;
 }
 
-bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, 
+bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain) {
+  StructuralEquivalenceContext Ctx(
+  Importer.getFromContext(), Importer.getToContext(),
+  Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
+  false, Complain);
+  return Ctx.IsEquivalent(From, To);
+}
+
+bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
 RecordDecl *ToRecord, bool Complain) {
   // Eliminate a potential failure point where we attempt to re-import
   // something we're trying to import while completing ToRecord.
@@ -1608,7 +1617,7 @@ bool ASTNodeImporter::IsStructuralMatch(
Importer.getNonEquivalentDecls(),
getStructuralEquivalenceKind(Importer),
false, Complain);
-  return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
+  return Ctx.IsEquivalent(FromRecord, ToRecord);
 }
 
 bool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
@@ -1617,14 +1626,14 @@ bool ASTNodeImporter::IsStructuralMatch(
   Importer.getFromContext(), Importer.getToContext(),
   Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
   false, Complain);
-  return Ctx.IsStru

r373894 - [ASTImporter][NFC] Fix typo in user docs

2019-10-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Oct  7 04:14:53 2019
New Revision: 373894

URL: http://llvm.org/viewvc/llvm-project?rev=373894&view=rev
Log:
[ASTImporter][NFC] Fix typo in user docs

Modified:
cfe/trunk/docs/LibASTImporter.rst

Modified: cfe/trunk/docs/LibASTImporter.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTImporter.rst?rev=373894&r1=373893&r2=373894&view=diff
==
--- cfe/trunk/docs/LibASTImporter.rst (original)
+++ cfe/trunk/docs/LibASTImporter.rst Mon Oct  7 04:14:53 2019
@@ -106,7 +106,7 @@ Next, we define a matcher to match ``MyC
 
 .. code-block:: cpp
 
-  auto Matcher = cxxRecordDecl(hasName("C"));
+  auto Matcher = cxxRecordDecl(hasName("MyClass"));
   auto *From = getFirstDecl(Matcher, FromUnit);
 
 Now we create the Importer and do the import:


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r373895 - [ASTImporter][NFC] Update ASTImporter internals docs

2019-10-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Oct  7 04:15:18 2019
New Revision: 373895

URL: http://llvm.org/viewvc/llvm-project?rev=373895&view=rev
Log:
[ASTImporter][NFC] Update ASTImporter internals docs

Modified:
cfe/trunk/docs/InternalsManual.rst

Modified: cfe/trunk/docs/InternalsManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/InternalsManual.rst?rev=373895&r1=373894&r2=373895&view=diff
==
--- cfe/trunk/docs/InternalsManual.rst (original)
+++ cfe/trunk/docs/InternalsManual.rst Mon Oct  7 04:15:18 2019
@@ -1519,11 +1519,11 @@ statements are true:
 - A and X are nodes from the same ASTContext.
 - B and Y are nodes from the same ASTContext.
 - A and B may or may not be from the same ASTContext.
-- if A == X (pointer equivalency) then (there is a cycle during the traverse)
+- if A == X and B == Y (pointer equivalency) then (there is a cycle during the
+  traverse)
 
   - A and B are structurally equivalent if and only if
 
-- B and Y are part of the same redeclaration chain,
 - All dependent nodes on the path from  to  are structurally
   equivalent.
 
@@ -1563,15 +1563,6 @@ the whole redeclaration chain of the fun
 declarations - regardless if they are definitions or prototypes - in the order
 as they appear in the "from" context.
 
-.. Structural eq requires proper redecl chains
-
-Another reason why we must maintain and import redeclaration chains properly is
-that the :ref:`Structural Equivalency ` check would report false
-positive in-equivalencies otherwise. We must not allow having two (or more)
-independent redeclaration chains of structurally equivalent declarations.
-Structural equivalency identifies the chains with the canonical declaration,
-that becomes different for independent chains.
-
 .. One definition
 
 If we have an existing definition in the "to" context, then we cannot import


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r373896 - [ASTImporter][NFC] Enable disabled but passing test

2019-10-07 Thread Gabor Marton via cfe-commits
Author: martong
Date: Mon Oct  7 04:34:54 2019
New Revision: 373896

URL: http://llvm.org/viewvc/llvm-project?rev=373896&view=rev
Log:
[ASTImporter][NFC] Enable disabled but passing test

RedeclChainShouldBeCorrectAmongstNamespaces

Modified:
cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=373896&r1=373895&r2=373896&view=diff
==
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Oct  7 04:34:54 2019
@@ -4785,11 +4785,8 @@ TEST_P(ASTImporterLookupTableTest, Looku
   EXPECT_EQ(*Res.begin(), A);
 }
 
-
-// FIXME This test is disabled currently, upcoming patches will make it
-// possible to enable.
 TEST_P(ASTImporterOptionSpecificTestBase,
-   DISABLED_RedeclChainShouldBeCorrectAmongstNamespaces) {
+   RedeclChainShouldBeCorrectAmongstNamespaces) {
   Decl *FromTU = getTuDecl(
   R"(
   namespace NS {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] bd03ef1 - [analyzer] ApiModeling: Add buffer size arg constraint

2020-05-29 Thread Gabor Marton via cfe-commits

Author: Gabor Marton
Date: 2020-05-29T16:13:57+02:00
New Revision: bd03ef19beb8a3476d5cd9f744c5fba5ca287c51

URL: 
https://github.com/llvm/llvm-project/commit/bd03ef19beb8a3476d5cd9f744c5fba5ca287c51
DIFF: 
https://github.com/llvm/llvm-project/commit/bd03ef19beb8a3476d5cd9f744c5fba5ca287c51.diff

LOG: [analyzer] ApiModeling: Add buffer size arg constraint

Summary:
Introducing a new argument constraint to confine buffer sizes. It is typical in
C APIs that a parameter represents a buffer and another param holds the size of
the buffer (or the size of the data we want to handle from the buffer).

Reviewers: NoQ, Szelethus, Charusso, steakhal

Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, 
a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, ASDenysPetrov, 
cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77066

Added: 


Modified: 
clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
clang/lib/StaticAnalyzer/Core/DynamicSize.cpp
clang/test/Analysis/std-c-library-functions-arg-constraints.c

Removed: 




diff  --git 
a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
index b48914c53d82..398f9b6ac33a 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h
@@ -32,6 +32,21 @@ DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef 
State,
 SValBuilder &SVB,
 QualType ElementTy);
 
+/// Get the dynamic size for a symbolic value that represents a buffer. If
+/// there is an offsetting to the underlying buffer we consider that too.
+/// Returns with an SVal that represents the size, this is Unknown if the
+/// engine cannot deduce the size.
+/// E.g.
+///   char buf[3];
+///   (buf); // size is 3
+///   (buf + 1); // size is 2
+///   (buf + 3); // size is 0
+///   (buf + 4); // size is -1
+///
+///   char *bufptr;
+///   (bufptr) // size is unknown
+SVal getDynamicSizeWithOffset(ProgramStateRef State, const SVal &BufV);
+
 } // namespace ento
 } // namespace clang
 

diff  --git a/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp 
b/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
index fec9fb59b2eb..dc9cd717be9e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
@@ -63,28 +63,8 @@ class PlacementNewChecker : public 
Checker> {
 
 SVal PlacementNewChecker::getExtentSizeOfPlace(const CXXNewExpr *NE,
CheckerContext &C) const {
-  ProgramStateRef State = C.getState();
   const Expr *Place = NE->getPlacementArg(0);
-
-  const MemRegion *MRegion = C.getSVal(Place).getAsRegion();
-  if (!MRegion)
-return UnknownVal();
-  RegionOffset Offset = MRegion->getAsOffset();
-  if (Offset.hasSymbolicOffset())
-return UnknownVal();
-  const MemRegion *BaseRegion = MRegion->getBaseRegion();
-  if (!BaseRegion)
-return UnknownVal();
-
-  SValBuilder &SvalBuilder = C.getSValBuilder();
-  NonLoc OffsetInBytes = SvalBuilder.makeArrayIndex(
-  Offset.getOffset() / C.getASTContext().getCharWidth());
-  DefinedOrUnknownSVal ExtentInBytes =
-  getDynamicSize(State, BaseRegion, SvalBuilder);
-
-  return SvalBuilder.evalBinOp(State, BinaryOperator::Opcode::BO_Sub,
-   ExtentInBytes, OffsetInBytes,
-   SvalBuilder.getArrayIndexType());
+  return getDynamicSizeWithOffset(C.getState(), C.getSVal(Place));
 }
 
 SVal PlacementNewChecker::getExtentSizeOfNewTarget(const CXXNewExpr *NE,

diff  --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index aefcad374596..f661f29948b6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -56,6 +56,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h"
 
 using namespace clang;
 using namespace clang::ento;
@@ -108,7 +109,8 @@ class StdLibraryFunctionsChecker
 /// Apply the effects of the constraint on the given program state. If null
 /// is returned then the constraint is not feasible.
 virtual ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call,
-  const Summary

  1   2   3   >