[ASTImporter] Add Visitor for TypedefNameDecl's

We found a case where Typedef Name Declarations were not being added
correctly when importing builtin types. This exposed the need for a
TypedefNameDecl visitor so these types can be added by RecordDecl and
fields.

This code is covered by the ASTImporterTest cases that use the implicit
struct __NSConstantString_tag definitions.

Thanks to @martong for the debugging assist!

Depends on D83970.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D83992
This commit is contained in:
Vince Bridgers 2020-07-16 17:46:48 -05:00 committed by einvbri
parent 12f27fc4b5
commit f761acfb1a
4 changed files with 50 additions and 0 deletions

View File

@ -22,6 +22,20 @@ namespace {
struct Builder : RecursiveASTVisitor<Builder> {
ASTImporterLookupTable &LT;
Builder(ASTImporterLookupTable &LT) : LT(LT) {}
bool VisitTypedefNameDecl(TypedefNameDecl *D) {
QualType Ty = D->getUnderlyingType();
Ty = Ty.getCanonicalType();
if (const auto *RTy = dyn_cast<RecordType>(Ty)) {
LT.add(RTy->getAsRecordDecl());
// iterate over the field decls, adding them
for (auto *it : RTy->getAsRecordDecl()->fields()) {
LT.add(it);
}
}
return true;
}
bool VisitNamedDecl(NamedDecl *D) {
LT.add(D);
return true;

View File

@ -0,0 +1,15 @@
// Use an internal, implicitly defined type, called by
// a function imported for CTU. This should not crash.
int foo(void);
int foobar(int skip) {
__NSConstantString str = {.flags = 1};
if (str.flags >= 0)
str.flags = 0;
return 4;
}
int testStaticImplicit(void) {
return foobar(3);
}

View File

@ -0,0 +1 @@
c:@F@testStaticImplicit ctu-import.c.ast

View File

@ -0,0 +1,20 @@
// RUN: rm -rf %t && mkdir %t
// RUN: mkdir -p %t/ctudir2
// RUN: %clang_cc1 \
// RUN: -emit-pch -o %t/ctudir2/ctu-import.c.ast %S/Inputs/ctu-import.c
// RUN: cp %S/Inputs/ctu-import.c.externalDefMap.ast-dump.txt %t/ctudir2/externalDefMap.txt
// RUN: %clang_cc1 -analyze \
// RUN: -analyzer-checker=core,debug.ExprInspection \
// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \
// RUN: -analyzer-config display-ctu-progress=true \
// RUN: -analyzer-config ctu-dir=%t/ctudir2 \
// RUN: -verify %s
void clang_analyzer_eval(int);
int testStaticImplicit(void);
int func(void) {
int ret = testStaticImplicit();
clang_analyzer_eval(ret == 4); // expected-warning{{TRUE}}
return testStaticImplicit();
}