Skip to content

Commit

Permalink
[clang][NFC] Refactor PredefinedExpr::IdentKind
Browse files Browse the repository at this point in the history
This patch converts `PredefinedExpr::IdentKind` into a scoped enum in namespace scope, making it eligible for forward declaring. This is useful in certain contexts, such as `preferred_type` annotations on bit-fields.
  • Loading branch information
Endilll committed Nov 5, 2023
1 parent 13956fd commit 6e35db0
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ void LambdaFunctionNameCheck::registerPPCallbacks(

void LambdaFunctionNameCheck::check(const MatchFinder::MatchResult &Result) {
const auto *E = Result.Nodes.getNodeAs<PredefinedExpr>("E");
if (E->getIdentKind() != PredefinedExpr::Func &&
E->getIdentKind() != PredefinedExpr::Function) {
if (E->getIdentKind() != PredefinedIdentKind::Func &&
E->getIdentKind() != PredefinedIdentKind::Function) {
// We don't care about other PredefinedExprs.
return;
}
Expand Down
43 changes: 21 additions & 22 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1999,6 +1999,19 @@ class StringLiteral final
}
};

enum class PredefinedIdentKind {
Func,
Function,
LFunction, // Same as Function, but as wide string.
FuncDName,
FuncSig,
LFuncSig, // Same as FuncSig, but as wide string
PrettyFunction,
/// The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual
};

/// [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr final
: public Expr,
Expand All @@ -2010,22 +2023,7 @@ class PredefinedExpr final
// "Stmt *" for the predefined identifier. It is present if and only if
// hasFunctionName() is true and is always a "StringLiteral *".

public:
enum IdentKind {
Func,
Function,
LFunction, // Same as Function, but as wide string.
FuncDName,
FuncSig,
LFuncSig, // Same as FuncSig, but as wide string
PrettyFunction,
/// The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual
};

private:
PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
PredefinedExpr(SourceLocation L, QualType FNTy, PredefinedIdentKind IK,
bool IsTransparent, StringLiteral *SL);

explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
Expand All @@ -2045,15 +2043,15 @@ class PredefinedExpr final
/// If IsTransparent, the PredefinedExpr is transparently handled as a
/// StringLiteral.
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK, bool IsTransparent,
StringLiteral *SL);
QualType FNTy, PredefinedIdentKind IK,
bool IsTransparent, StringLiteral *SL);

/// Create an empty PredefinedExpr.
static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
bool HasFunctionName);

IdentKind getIdentKind() const {
return static_cast<IdentKind>(PredefinedExprBits.Kind);
PredefinedIdentKind getIdentKind() const {
return static_cast<PredefinedIdentKind>(PredefinedExprBits.Kind);
}

bool isTransparent() const { return PredefinedExprBits.IsTransparent; }
Expand All @@ -2073,12 +2071,13 @@ class PredefinedExpr final
: nullptr;
}

static StringRef getIdentKindName(IdentKind IK);
static StringRef getIdentKindName(PredefinedIdentKind IK);
StringRef getIdentKindName() const {
return getIdentKindName(getIdentKind());
}

static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl);
static std::string ComputeName(PredefinedIdentKind IK,
const Decl *CurrentDecl);

SourceLocation getBeginLoc() const { return getLocation(); }
SourceLocation getEndLoc() const { return getLocation(); }
Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -5723,8 +5723,7 @@ class Sema final {
// __FUNCTION__) are replaced (expanded) with string-literal Tokens.
std::vector<Token> ExpandFunctionLocalPredefinedMacros(ArrayRef<Token> Toks);

ExprResult BuildPredefinedExpr(SourceLocation Loc,
PredefinedExpr::IdentKind IK);
ExprResult BuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK);
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);

Expand Down
55 changes: 31 additions & 24 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,11 @@ std::string SYCLUniqueStableNameExpr::ComputeName(ASTContext &Context,
return Out.str();
}

PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
bool IsTransparent, StringLiteral *SL)
PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy,
PredefinedIdentKind IK, bool IsTransparent,
StringLiteral *SL)
: Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary) {
PredefinedExprBits.Kind = IK;
PredefinedExprBits.Kind = llvm::to_underlying(IK);
assert((getIdentKind() == IK) &&
"IdentKind do not fit in PredefinedExprBitfields!");
bool HasFunctionName = SL != nullptr;
Expand All @@ -625,7 +626,7 @@ PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName)
}

PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK,
QualType FNTy, PredefinedIdentKind IK,
bool IsTransparent, StringLiteral *SL) {
bool HasFunctionName = SL != nullptr;
void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName),
Expand All @@ -640,34 +641,35 @@ PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx,
return new (Mem) PredefinedExpr(EmptyShell(), HasFunctionName);
}

StringRef PredefinedExpr::getIdentKindName(PredefinedExpr::IdentKind IK) {
StringRef PredefinedExpr::getIdentKindName(PredefinedIdentKind IK) {
switch (IK) {
case Func:
case PredefinedIdentKind::Func:
return "__func__";
case Function:
case PredefinedIdentKind::Function:
return "__FUNCTION__";
case FuncDName:
case PredefinedIdentKind::FuncDName:
return "__FUNCDNAME__";
case LFunction:
case PredefinedIdentKind::LFunction:
return "L__FUNCTION__";
case PrettyFunction:
case PredefinedIdentKind::PrettyFunction:
return "__PRETTY_FUNCTION__";
case FuncSig:
case PredefinedIdentKind::FuncSig:
return "__FUNCSIG__";
case LFuncSig:
case PredefinedIdentKind::LFuncSig:
return "L__FUNCSIG__";
case PrettyFunctionNoVirtual:
case PredefinedIdentKind::PrettyFunctionNoVirtual:
break;
}
llvm_unreachable("Unknown ident kind for PredefinedExpr");
}

// FIXME: Maybe this should use DeclPrinter with a special "print predefined
// expr" policy instead.
std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK,
const Decl *CurrentDecl) {
ASTContext &Context = CurrentDecl->getASTContext();

if (IK == PredefinedExpr::FuncDName) {
if (IK == PredefinedIdentKind::FuncDName) {
if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
std::unique_ptr<MangleContext> MC;
MC.reset(Context.createMangleContext());
Expand Down Expand Up @@ -712,15 +714,17 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
return std::string(Out.str());
}
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
if (IK != PrettyFunction && IK != PrettyFunctionNoVirtual &&
IK != FuncSig && IK != LFuncSig)
if (IK != PredefinedIdentKind::PrettyFunction &&
IK != PredefinedIdentKind::PrettyFunctionNoVirtual &&
IK != PredefinedIdentKind::FuncSig &&
IK != PredefinedIdentKind::LFuncSig)
return FD->getNameAsString();

SmallString<256> Name;
llvm::raw_svector_ostream Out(Name);

if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
if (MD->isVirtual() && IK != PrettyFunctionNoVirtual)
if (MD->isVirtual() && IK != PredefinedIdentKind::PrettyFunctionNoVirtual)
Out << "virtual ";
if (MD->isStatic())
Out << "static ";
Expand Down Expand Up @@ -752,7 +756,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(AFT);

if (IK == FuncSig || IK == LFuncSig) {
if (IK == PredefinedIdentKind::FuncSig ||
IK == PredefinedIdentKind::LFuncSig) {
switch (AFT->getCallConv()) {
case CC_C: POut << "__cdecl "; break;
case CC_X86StdCall: POut << "__stdcall "; break;
Expand All @@ -777,7 +782,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {
if (FT->isVariadic()) {
if (FD->getNumParams()) POut << ", ";
POut << "...";
} else if ((IK == FuncSig || IK == LFuncSig ||
} else if ((IK == PredefinedIdentKind::FuncSig ||
IK == PredefinedIdentKind::LFuncSig ||
!Context.getLangOpts().CPlusPlus) &&
!Decl->getNumParams()) {
POut << "void";
Expand Down Expand Up @@ -902,7 +908,8 @@ std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) {

return std::string(Name);
}
if (isa<TranslationUnitDecl>(CurrentDecl) && IK == PrettyFunction) {
if (isa<TranslationUnitDecl>(CurrentDecl) &&
IK == PredefinedIdentKind::PrettyFunction) {
// __PRETTY_FUNCTION__ -> "top level", the others produce an empty string.
return "top level";
}
Expand Down Expand Up @@ -2282,8 +2289,8 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
case SourceLocIdentKind::FuncSig: {
const auto *CurDecl = dyn_cast<Decl>(Context);
const auto Kind = getIdentKind() == SourceLocIdentKind::Function
? PredefinedExpr::Function
: PredefinedExpr::FuncSig;
? PredefinedIdentKind::Function
: PredefinedIdentKind::FuncSig;
return MakeStringLiteral(
CurDecl ? PredefinedExpr::ComputeName(Kind, CurDecl) : std::string(""));
}
Expand Down Expand Up @@ -2317,7 +2324,7 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
Value.getStructField(F->getFieldIndex()) = MakeStringLiteral(
CurDecl && !isa<TranslationUnitDecl>(CurDecl)
? StringRef(PredefinedExpr::ComputeName(
PredefinedExpr::PrettyFunction, CurDecl))
PredefinedIdentKind::PrettyFunction, CurDecl))
: "");
} else if (Name == "_M_line") {
llvm::APSInt IntVal = Ctx.MakeIntValue(PLoc.getLine(), F->getType());
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1328,7 +1328,7 @@ void StmtProfiler::VisitSYCLUniqueStableNameExpr(

void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
VisitExpr(S);
ID.AddInteger(S->getIdentKind());
ID.AddInteger(llvm::to_underlying(S->getIdentKind()));
}

void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
Expand Down
26 changes: 11 additions & 15 deletions clang/lib/AST/VTableBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1956,9 +1956,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
case VTableComponent::CK_FunctionPointer: {
const CXXMethodDecl *MD = Component.getFunctionDecl();

std::string Str =
PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
MD);
std::string Str = PredefinedExpr::ComputeName(
PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
Out << Str;
if (MD->isPure())
Out << " [pure]";
Expand Down Expand Up @@ -2036,9 +2035,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
case VTableComponent::CK_UnusedFunctionPointer: {
const CXXMethodDecl *MD = Component.getUnusedFunctionDecl();

std::string Str =
PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
MD);
std::string Str = PredefinedExpr::ComputeName(
PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
Out << "[unused] " << Str;
if (MD->isPure())
Out << " [pure]";
Expand Down Expand Up @@ -2115,9 +2113,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {

for (const auto &I : Thunks) {
const CXXMethodDecl *MD = I.first;
std::string MethodName =
PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
MD);
std::string MethodName = PredefinedExpr::ComputeName(
PredefinedIdentKind::PrettyFunctionNoVirtual, MD);

MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
}
Expand Down Expand Up @@ -2181,9 +2178,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
continue;
MD = MD->getCanonicalDecl();

std::string MethodName =
PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
MD);
std::string MethodName = PredefinedExpr::ComputeName(
PredefinedIdentKind::PrettyFunctionNoVirtual, MD);

if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
GlobalDecl GD(DD, Dtor_Complete);
Expand Down Expand Up @@ -3177,7 +3173,7 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
// FIXME: Figure out how to print the real thunk type, since they can
// differ in the return type.
std::string Str = PredefinedExpr::ComputeName(
PredefinedExpr::PrettyFunctionNoVirtual, MD);
PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
Out << Str;
if (MD->isPure())
Out << " [pure]";
Expand Down Expand Up @@ -3232,7 +3228,7 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
for (const auto &I : Thunks) {
const CXXMethodDecl *MD = I.first;
std::string MethodName = PredefinedExpr::ComputeName(
PredefinedExpr::PrettyFunctionNoVirtual, MD);
PredefinedIdentKind::PrettyFunctionNoVirtual, MD);

MethodNamesAndDecls.insert(std::make_pair(MethodName, MD));
}
Expand Down Expand Up @@ -3664,7 +3660,7 @@ void MicrosoftVTableContext::dumpMethodLocations(
assert(hasVtableSlot(MD));

std::string MethodName = PredefinedExpr::ComputeName(
PredefinedExpr::PrettyFunctionNoVirtual, MD);
PredefinedIdentKind::PrettyFunctionNoVirtual, MD);

if (isa<CXXDestructorDecl>(MD)) {
IndicesMap[I.second] = MethodName + " [scalar deleting]";
Expand Down
21 changes: 11 additions & 10 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1884,24 +1884,24 @@ ExprResult Sema::CreateGenericSelectionExpr(
ContainsUnexpandedParameterPack, ResultIndex);
}

static PredefinedExpr::IdentKind getPredefinedExprKind(tok::TokenKind Kind) {
static PredefinedIdentKind getPredefinedExprKind(tok::TokenKind Kind) {
switch (Kind) {
default:
llvm_unreachable("unexpected TokenKind");
case tok::kw___func__:
return PredefinedExpr::Func; // [C99 6.4.2.2]
return PredefinedIdentKind::Func; // [C99 6.4.2.2]
case tok::kw___FUNCTION__:
return PredefinedExpr::Function;
return PredefinedIdentKind::Function;
case tok::kw___FUNCDNAME__:
return PredefinedExpr::FuncDName; // [MS]
return PredefinedIdentKind::FuncDName; // [MS]
case tok::kw___FUNCSIG__:
return PredefinedExpr::FuncSig; // [MS]
return PredefinedIdentKind::FuncSig; // [MS]
case tok::kw_L__FUNCTION__:
return PredefinedExpr::LFunction; // [MS]
return PredefinedIdentKind::LFunction; // [MS]
case tok::kw_L__FUNCSIG__:
return PredefinedExpr::LFuncSig; // [MS]
return PredefinedIdentKind::LFuncSig; // [MS]
case tok::kw___PRETTY_FUNCTION__:
return PredefinedExpr::PrettyFunction; // [GNU]
return PredefinedIdentKind::PrettyFunction; // [GNU]
}
}

Expand Down Expand Up @@ -3716,7 +3716,7 @@ static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
}

ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
PredefinedExpr::IdentKind IK) {
PredefinedIdentKind IK) {
Decl *currentDecl = getPredefinedExprDecl(CurContext);
if (!currentDecl) {
Diag(Loc, diag::ext_predef_outside_function);
Expand All @@ -3734,7 +3734,8 @@ ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
unsigned Length = Str.length();

llvm::APInt LengthI(32, Length + 1);
if (IK == PredefinedExpr::LFunction || IK == PredefinedExpr::LFuncSig) {
if (IK == PredefinedIdentKind::LFunction ||
IK == PredefinedIdentKind::LFuncSig) {
ResTy =
Context.adjustStringLiteralBaseType(Context.WideCharTy.withConst());
SmallString<32> RawChars;
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -2620,8 +2620,7 @@ class TreeTransform {
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildPredefinedExpr(SourceLocation Loc,
PredefinedExpr::IdentKind IK) {
ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
return getSema().BuildPredefinedExpr(Loc, IK);
}

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@ void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {

bool HasFunctionName = E->getFunctionName() != nullptr;
Record.push_back(HasFunctionName);
Record.push_back(E->getIdentKind()); // FIXME: stable encoding
Record.push_back(
llvm::to_underlying(E->getIdentKind())); // FIXME: stable encoding
Record.push_back(E->isTransparent());
Record.AddSourceLocation(E->getLocation());
if (HasFunctionName)
Expand Down

0 comments on commit 6e35db0

Please sign in to comment.