Skip to content

Commit f746b08

Browse files
committed
Mark functions with bounds attributes to process in...
importBoundsAttributes This allows an early exit without redundant processing or extra allocations.
1 parent 6117969 commit f746b08

File tree

3 files changed

+33
-37
lines changed

3 files changed

+33
-37
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8510,22 +8510,26 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
85108510
}
85118511

85128512
namespace {
8513-
class PointerParamInfo {
8513+
class PointerParamInfoPrinter {
85148514
public:
8515-
virtual void print(clang::ASTContext &ctx, llvm::raw_ostream &out) const = 0;
8516-
virtual ~PointerParamInfo() = default;
8517-
};
8515+
clang::ASTContext &ctx;
8516+
llvm::raw_ostream &out;
8517+
bool firstParam = true;
8518+
PointerParamInfoPrinter(clang::ASTContext &ctx, llvm::raw_ostream &out)
8519+
: ctx(ctx), out(out) {
8520+
out << "@PointerBounds(";
8521+
}
8522+
~PointerParamInfoPrinter() { out << ")"; }
85188523

8519-
class CountedByParam : public PointerParamInfo {
8520-
public:
8521-
size_t pointerIndex;
8522-
clang::Expr *countExpr;
8523-
bool isSizedBy;
8524-
CountedByParam(size_t idx, clang::Expr *E, bool sizedBy)
8525-
: pointerIndex(idx), countExpr(E), isSizedBy(sizedBy) {}
8526-
8527-
virtual void print(clang::ASTContext &ctx,
8528-
llvm::raw_ostream &out) const override {
8524+
void printCountedBy(const clang::CountAttributedType *CAT,
8525+
size_t pointerIndex) {
8526+
if (!firstParam) {
8527+
out << ", ";
8528+
} else {
8529+
firstParam = false;
8530+
}
8531+
clang::Expr *countExpr = CAT->getCountExpr();
8532+
bool isSizedBy = CAT->isCountInBytes();
85298533
out << ".";
85308534
if (isSizedBy)
85318535
out << "sizedBy";
@@ -8541,7 +8545,6 @@ class CountedByParam : public PointerParamInfo {
85418545
out, {}, {ctx.getLangOpts()}); // TODO: map clang::Expr to Swift Expr
85428546
out << "\")";
85438547
}
8544-
virtual ~CountedByParam() {}
85458548
};
85468549
} // namespace
85478550

@@ -8551,43 +8554,31 @@ void ClangImporter::Implementation::importBoundsAttributes(
85518554
dyn_cast_or_null<clang::FunctionDecl>(MappedDecl->getClangDecl());
85528555
if (!ClangDecl)
85538556
return;
8554-
8555-
SmallVector<PointerParamInfo *, 4> BoundsInfo;
8556-
size_t parameterIndex = 1;
8557-
for (auto param : ClangDecl->parameters()) {
8558-
if (auto CAT = param->getType()->getAs<clang::CountAttributedType>()) {
8559-
BoundsInfo.push_back(new CountedByParam(
8560-
parameterIndex, CAT->getCountExpr(), CAT->isCountInBytes()));
8561-
}
8562-
parameterIndex++;
8563-
}
8564-
if (BoundsInfo.empty())
8557+
if (!funcsWithPointerBounds.count(ClangDecl))
85658558
return;
85668559

85678560
llvm::SmallString<128> MacroString;
85688561
{
85698562
llvm::raw_svector_ostream out(MacroString);
85708563

8571-
out << "@PointerBounds(";
8572-
for (size_t i = 0; i < BoundsInfo.size(); i++) {
8573-
BoundsInfo[i]->print(getClangASTContext(), out);
8574-
if (i + 1 < BoundsInfo.size()) {
8575-
out << ", ";
8564+
size_t parameterIndex = 1;
8565+
PointerParamInfoPrinter printer(getClangASTContext(), out);
8566+
for (auto param : ClangDecl->parameters()) {
8567+
if (auto CAT = param->getType()->getAs<clang::CountAttributedType>()) {
8568+
printer.printCountedBy(CAT, parameterIndex);
85768569
}
8570+
parameterIndex++;
85778571
}
8578-
out << ")";
85798572
}
85808573

8581-
// Dig out a buffer with the attribute text.
8582-
unsigned bufferID = getClangSwiftAttrSourceBuffer(MacroString);
85838574

85848575
// Dig out a source file we can use for parsing.
85858576
auto &sourceFile = getClangSwiftAttrSourceFile(
8586-
*MappedDecl->getDeclContext()->getParentModule(), bufferID);
8577+
*MappedDecl->getDeclContext()->getParentModule(), MacroString);
85878578

85888579
// Spin up a parser.
8589-
swift::Parser parser(bufferID, sourceFile, &SwiftContext.Diags, nullptr,
8590-
nullptr);
8580+
swift::Parser parser(sourceFile.getBufferID(), sourceFile,
8581+
&SwiftContext.Diags, nullptr, nullptr);
85918582
// Prime the lexer.
85928583
parser.consumeTokenWithoutFeedingReceiver();
85938584

lib/ClangImporter/ImportType.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,6 +2438,9 @@ ClangImporter::Implementation::importParameterType(
24382438
// Treat as a normal pointer. importBoundsAttributes() will generate a safe
24392439
// overload later.
24402440
paramTy = CAT->desugar();
2441+
if (auto FuncD =
2442+
dyn_cast<clang::FunctionDecl>(param->getParentFunctionOrMethod()))
2443+
funcsWithPointerBounds.insert(FuncD);
24412444
} else if (isa<clang::PointerType>(paramTy) &&
24422445
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType())) {
24432446
auto pointeeType = paramTy->getPointeeType();

lib/ClangImporter/ImporterImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
544544
/// These are re-used when parsing the Swift attributes on import.
545545
llvm::StringMap<llvm::TinyPtrVector<SourceFile *>> ClangSwiftAttrSourceFiles;
546546

547+
llvm::SmallPtrSet<const clang::FunctionDecl *, 16> funcsWithPointerBounds;
548+
547549
public:
548550
/// The Swift lookup table for the bridging header.
549551
std::unique_ptr<SwiftLookupTable> BridgingHeaderLookupTable;

0 commit comments

Comments
 (0)