Skip to content

Commit 719d98d

Browse files
[clang] Use a StringRef instead of a raw char pointer to store builtin and call information
This avoids recomputing string length that is already known at compile time. It has a slight impact on preprocessing / compile time, see https://llvm-compile-time-tracker.com/compare.php?from=3f36d2d579d8b0e8824d9dd99bfa79f456858f88&to=e49640c507ddc6615b5e503144301c8e41f8f434&stat=instructions:u Differential Revision: https://reviews.llvm.org/D139881
1 parent a4e3457 commit 719d98d

File tree

70 files changed

+597
-562
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+597
-562
lines changed

clang-tools-extra/clangd/CompileCommands.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,10 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
466466
NextAlias[T] = Self;
467467
};
468468
// Also grab prefixes for each option, these are not fully exposed.
469-
const char *const *Prefixes[DriverID::LastOption] = {nullptr};
470-
#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
469+
std::initializer_list<llvm::StringLiteral> Prefixes[DriverID::LastOption];
470+
471+
#define PREFIX(NAME, VALUE) \
472+
static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;
471473
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
472474
HELP, METAVAR, VALUES) \
473475
Prefixes[DriverID::OPT_##ID] = PREFIX;
@@ -499,7 +501,7 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
499501
llvm::SmallVector<Rule> Rules;
500502
// Iterate over each alias, to add rules for parsing it.
501503
for (unsigned A = ID; A != DriverID::OPT_INVALID; A = NextAlias[A]) {
502-
if (Prefixes[A] == nullptr) // option groups.
504+
if (!Prefixes[A].size()) // option groups.
503505
continue;
504506
auto Opt = DriverTable.getOption(A);
505507
// Exclude - and -foo pseudo-options.
@@ -508,8 +510,8 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
508510
auto Modes = getModes(Opt);
509511
std::pair<unsigned, unsigned> ArgCount = getArgCount(Opt);
510512
// Iterate over each spelling of the alias, e.g. -foo vs --foo.
511-
for (auto *Prefix = Prefixes[A]; *Prefix != nullptr; ++Prefix) {
512-
llvm::SmallString<64> Buf(*Prefix);
513+
for (StringRef Prefix : Prefixes[A]) {
514+
llvm::SmallString<64> Buf(Prefix);
513515
Buf.append(Opt.getName());
514516
llvm::StringRef Spelling = Result->try_emplace(Buf).first->getKey();
515517
Rules.emplace_back();

clang/include/clang/Basic/Builtins.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ enum ID {
5757
};
5858

5959
struct Info {
60-
const char *Name, *Type, *Attributes, *HeaderName;
60+
llvm::StringRef Name;
61+
const char *Type, *Attributes, *HeaderName;
6162
LanguageID Langs;
6263
const char *Features;
6364
};
@@ -86,9 +87,7 @@ class Context {
8687

8788
/// Return the identifier name for the specified builtin,
8889
/// e.g. "__builtin_abs".
89-
const char *getName(unsigned ID) const {
90-
return getRecord(ID).Name;
91-
}
90+
llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
9291

9392
/// Get the type descriptor string for the specified builtin.
9493
const char *getTypeString(unsigned ID) const {

clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,12 @@ class CallDescription {
6363
/// @param RequiredArgs The number of arguments that is expected to match a
6464
/// call. Omit this parameter to match every occurrence of call with a given
6565
/// name regardless the number of arguments.
66-
CallDescription(CallDescriptionFlags Flags,
67-
ArrayRef<const char *> QualifiedName,
66+
CallDescription(CallDescriptionFlags Flags, ArrayRef<StringRef> QualifiedName,
6867
MaybeCount RequiredArgs = std::nullopt,
6968
MaybeCount RequiredParams = std::nullopt);
7069

7170
/// Construct a CallDescription with default flags.
72-
CallDescription(ArrayRef<const char *> QualifiedName,
71+
CallDescription(ArrayRef<StringRef> QualifiedName,
7372
MaybeCount RequiredArgs = std::nullopt,
7473
MaybeCount RequiredParams = std::nullopt);
7574

clang/lib/AST/ExprConstant.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9242,8 +9242,8 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
92429242
case Builtin::BIwmemchr:
92439243
if (Info.getLangOpts().CPlusPlus11)
92449244
Info.CCEDiag(E, diag::note_constexpr_invalid_function)
9245-
<< /*isConstexpr*/0 << /*isConstructor*/0
9246-
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");
9245+
<< /*isConstexpr*/ 0 << /*isConstructor*/ 0
9246+
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();
92479247
else
92489248
Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
92499249
[[fallthrough]];
@@ -9288,7 +9288,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
92889288
// FIXME: We can compare the bytes in the correct order.
92899289
if (IsRawByte && !isOneByteCharacterType(CharTy)) {
92909290
Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
9291-
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'")
9291+
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str()
92929292
<< CharTy;
92939293
return false;
92949294
}
@@ -9350,8 +9350,8 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
93509350
case Builtin::BIwmemmove:
93519351
if (Info.getLangOpts().CPlusPlus11)
93529352
Info.CCEDiag(E, diag::note_constexpr_invalid_function)
9353-
<< /*isConstexpr*/0 << /*isConstructor*/0
9354-
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");
9353+
<< /*isConstexpr*/ 0 << /*isConstructor*/ 0
9354+
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();
93559355
else
93569356
Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
93579357
[[fallthrough]];
@@ -12209,8 +12209,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1220912209
// A call to strlen is not a constant expression.
1221012210
if (Info.getLangOpts().CPlusPlus11)
1221112211
Info.CCEDiag(E, diag::note_constexpr_invalid_function)
12212-
<< /*isConstexpr*/0 << /*isConstructor*/0
12213-
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");
12212+
<< /*isConstexpr*/ 0 << /*isConstructor*/ 0
12213+
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();
1221412214
else
1221512215
Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
1221612216
[[fallthrough]];
@@ -12234,8 +12234,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1223412234
// A call to strlen is not a constant expression.
1223512235
if (Info.getLangOpts().CPlusPlus11)
1223612236
Info.CCEDiag(E, diag::note_constexpr_invalid_function)
12237-
<< /*isConstexpr*/0 << /*isConstructor*/0
12238-
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");
12237+
<< /*isConstexpr*/ 0 << /*isConstructor*/ 0
12238+
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();
1223912239
else
1224012240
Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
1224112241
[[fallthrough]];
@@ -12290,7 +12290,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1229012290
!(isOneByteCharacterType(CharTy1) && isOneByteCharacterType(CharTy2))) {
1229112291
// FIXME: Consider using our bit_cast implementation to support this.
1229212292
Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
12293-
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'")
12293+
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str()
1229412294
<< CharTy1 << CharTy2;
1229512295
return false;
1229612296
}

clang/lib/Basic/Builtins.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
#include "llvm/ADT/StringRef.h"
1919
using namespace clang;
2020

21-
static const Builtin::Info BuiltinInfo[] = {
22-
{ "not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,nullptr},
21+
static constexpr Builtin::Info BuiltinInfo[] = {
22+
{"not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,
23+
nullptr},
2324
#define BUILTIN(ID, TYPE, ATTRS) \
2425
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
2526
#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
134134
AIXLongDouble64Builtins.end())
135135
Name = AIXLongDouble64Builtins[BuiltinID];
136136
else
137-
Name = Context.BuiltinInfo.getName(BuiltinID) + 10;
137+
Name = Context.BuiltinInfo.getName(BuiltinID).substr(10);
138138
}
139139

140140
llvm::FunctionType *Ty =
@@ -5302,7 +5302,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
53025302
LargestVectorWidth = std::max(LargestVectorWidth, VectorWidth);
53035303

53045304
// See if we have a target specific intrinsic.
5305-
const char *Name = getContext().BuiltinInfo.getName(BuiltinID);
5305+
StringRef Name = getContext().BuiltinInfo.getName(BuiltinID);
53065306
Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
53075307
StringRef Prefix =
53085308
llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());

clang/lib/Driver/DriverOptions.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ using namespace clang::driver;
1616
using namespace clang::driver::options;
1717
using namespace llvm::opt;
1818

19-
#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
19+
#define PREFIX(NAME, VALUE) \
20+
static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;
2021
#include "clang/Driver/Options.inc"
2122
#undef PREFIX
2223

23-
static constexpr OptTable::Info InfoTable[] = {
24+
static constexpr std::initializer_list<OptTable::Info> InfoTable = {
2425
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
2526
HELPTEXT, METAVAR, VALUES) \
2627
{PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, \

clang/lib/Sema/SemaChecking.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6956,7 +6956,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
69566956
// Get the decl for the concrete builtin from this, we can tell what the
69576957
// concrete integer type we should convert to is.
69586958
unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
6959-
const char *NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID);
6959+
StringRef NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID);
69606960
FunctionDecl *NewBuiltinDecl;
69616961
if (NewBuiltinID == BuiltinID)
69626962
NewBuiltinDecl = FDecl;
@@ -11008,7 +11008,7 @@ static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range,
1100811008
unsigned AbsKind, QualType ArgType) {
1100911009
bool EmitHeaderHint = true;
1101011010
const char *HeaderName = nullptr;
11011-
const char *FunctionName = nullptr;
11011+
StringRef FunctionName;
1101211012
if (S.getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
1101311013
FunctionName = "std::abs";
1101411014
if (ArgType->isIntegralOrEnumerationType()) {
@@ -11116,7 +11116,7 @@ void Sema::CheckAbsoluteValueFunction(const CallExpr *Call,
1111611116
// Unsigned types cannot be negative. Suggest removing the absolute value
1111711117
// function call.
1111811118
if (ArgType->isUnsignedIntegerType()) {
11119-
const char *FunctionName =
11119+
StringRef FunctionName =
1112011120
IsStdAbs ? "std::abs" : Context.BuiltinInfo.getName(AbsKind);
1112111121
Diag(Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
1112211122
Diag(Call->getExprLoc(), diag::note_remove_abs)

clang/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -532,10 +532,10 @@ namespace {
532532
class CFRetainReleaseChecker : public Checker<check::PreCall> {
533533
mutable APIMisuse BT{this, "null passed to CF memory management function"};
534534
const CallDescriptionSet ModelledCalls = {
535-
{"CFRetain", 1},
536-
{"CFRelease", 1},
537-
{"CFMakeCollectable", 1},
538-
{"CFAutorelease", 1},
535+
{{"CFRetain"}, 1},
536+
{{"CFRelease"}, 1},
537+
{{"CFMakeCollectable"}, 1},
538+
{{"CFAutorelease"}, 1},
539539
};
540540

541541
public:

clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,15 @@ class BlockInCriticalSectionChecker : public Checker<check::PostCall> {
6464
REGISTER_TRAIT_WITH_PROGRAMSTATE(MutexCounter, unsigned)
6565

6666
BlockInCriticalSectionChecker::BlockInCriticalSectionChecker()
67-
: IILockGuard(nullptr), IIUniqueLock(nullptr),
68-
LockFn("lock"), UnlockFn("unlock"), SleepFn("sleep"), GetcFn("getc"),
69-
FgetsFn("fgets"), ReadFn("read"), RecvFn("recv"),
70-
PthreadLockFn("pthread_mutex_lock"),
71-
PthreadTryLockFn("pthread_mutex_trylock"),
72-
PthreadUnlockFn("pthread_mutex_unlock"),
73-
MtxLock("mtx_lock"),
74-
MtxTimedLock("mtx_timedlock"),
75-
MtxTryLock("mtx_trylock"),
76-
MtxUnlock("mtx_unlock"),
77-
ClassLockGuard("lock_guard"),
78-
ClassUniqueLock("unique_lock"),
79-
IdentifierInfoInitialized(false) {
67+
: IILockGuard(nullptr), IIUniqueLock(nullptr), LockFn({"lock"}),
68+
UnlockFn({"unlock"}), SleepFn({"sleep"}), GetcFn({"getc"}),
69+
FgetsFn({"fgets"}), ReadFn({"read"}), RecvFn({"recv"}),
70+
PthreadLockFn({"pthread_mutex_lock"}),
71+
PthreadTryLockFn({"pthread_mutex_trylock"}),
72+
PthreadUnlockFn({"pthread_mutex_unlock"}), MtxLock({"mtx_lock"}),
73+
MtxTimedLock({"mtx_timedlock"}), MtxTryLock({"mtx_trylock"}),
74+
MtxUnlock({"mtx_unlock"}), ClassLockGuard("lock_guard"),
75+
ClassUniqueLock("unique_lock"), IdentifierInfoInitialized(false) {
8076
// Initialize the bug type.
8177
BlockInCritSectionBugType.reset(
8278
new BugType(this, "Call to blocking function in critical section",

0 commit comments

Comments
 (0)