Author: brunoricci Date: Sat Oct 27 12:21:19 2018 New Revision: 345460 URL: http://llvm.org/viewvc/llvm-project?rev=345460&view=rev Log: [AST] Refactor PredefinedExpr
Make the following changes to PredefinedExpr: 1. Move PredefinedExpr below StringLiteral so that it can use its definition. 2. Rename IdentType to IdentKind to be more in line with clang's conventions, and propagate the change to its users. 3. Move the location and the IdentKind into the newly available space of the bit-fields of Stmt. 4. Only store the function name when needed. When parsing all of Boost, of the 1357 PredefinedExpr 919 have no function name. Differential Revision: https://reviews.llvm.org/D53605 Reviewed By: rjmccall Modified: cfe/trunk/include/clang/AST/Expr.h cfe/trunk/include/clang/AST/Stmt.h cfe/trunk/include/clang/AST/StmtDataCollectors.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/AST/ASTDumper.cpp cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/AST/StmtPrinter.cpp cfe/trunk/lib/AST/StmtProfile.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprConstant.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp cfe/trunk/lib/Sema/TreeTransform.h cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Modified: cfe/trunk/include/clang/AST/Expr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Expr.h (original) +++ cfe/trunk/include/clang/AST/Expr.h Sat Oct 27 12:21:19 2018 @@ -32,6 +32,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/TrailingObjects.h" namespace clang { class APValue; @@ -1204,64 +1205,6 @@ public: friend class ASTStmtWriter; }; -/// [C99 6.4.2.2] - A predefined identifier such as __func__. -class PredefinedExpr : public Expr { -public: - enum IdentType { - Func, - Function, - LFunction, // Same as Function, but as wide string. - FuncDName, - FuncSig, - LFuncSig, // Same as FuncSig, but as as wide string - PrettyFunction, - /// The same as PrettyFunction, except that the - /// 'virtual' keyword is omitted for virtual member functions. - PrettyFunctionNoVirtual - }; - -private: - SourceLocation Loc; - IdentType Type; - Stmt *FnName; - -public: - PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT, - StringLiteral *SL); - - /// Construct an empty predefined expression. - explicit PredefinedExpr(EmptyShell Empty) - : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {} - - IdentType getIdentType() const { return Type; } - - SourceLocation getLocation() const { return Loc; } - void setLocation(SourceLocation L) { Loc = L; } - - StringLiteral *getFunctionName(); - const StringLiteral *getFunctionName() const { - return const_cast<PredefinedExpr *>(this)->getFunctionName(); - } - - static StringRef getIdentTypeName(IdentType IT); - static std::string ComputeName(IdentType IT, const Decl *CurrentDecl); - - SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } - SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == PredefinedExprClass; - } - - // Iterators - child_range children() { return child_range(&FnName, &FnName + 1); } - const_child_range children() const { - return const_child_range(&FnName, &FnName + 1); - } - - friend class ASTStmtReader; -}; - /// Used by IntegerLiteral/FloatingLiteral to store the numeric without /// leaking memory. /// @@ -1732,6 +1675,91 @@ public: } }; +/// [C99 6.4.2.2] - A predefined identifier such as __func__. +class PredefinedExpr final + : public Expr, + private llvm::TrailingObjects<PredefinedExpr, Stmt *> { + friend class ASTStmtReader; + friend TrailingObjects; + + // PredefinedExpr is optionally followed by a single trailing + // "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 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, + StringLiteral *SL); + + explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName); + + /// True if this PredefinedExpr has storage for a function name. + bool hasFunctionName() const { return PredefinedExprBits.HasFunctionName; } + + void setFunctionName(StringLiteral *SL) { + assert(hasFunctionName() && + "This PredefinedExpr has no storage for a function name!"); + *getTrailingObjects<Stmt *>() = SL; + } + +public: + /// Create a PredefinedExpr. + static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L, + QualType FNTy, IdentKind IK, StringLiteral *SL); + + /// Create an empty PredefinedExpr. + static PredefinedExpr *CreateEmpty(const ASTContext &Ctx, + bool HasFunctionName); + + IdentKind getIdentKind() const { + return static_cast<IdentKind>(PredefinedExprBits.Kind); + } + + SourceLocation getLocation() const { return PredefinedExprBits.Loc; } + void setLocation(SourceLocation L) { PredefinedExprBits.Loc = L; } + + StringLiteral *getFunctionName() { + return hasFunctionName() + ? static_cast<StringLiteral *>(*getTrailingObjects<Stmt *>()) + : nullptr; + } + + const StringLiteral *getFunctionName() const { + return hasFunctionName() + ? static_cast<StringLiteral *>(*getTrailingObjects<Stmt *>()) + : nullptr; + } + + static StringRef getIdentKindName(IdentKind IK); + static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl); + + SourceLocation getBeginLoc() const { return getLocation(); } + SourceLocation getEndLoc() const { return getLocation(); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == PredefinedExprClass; + } + + // Iterators + child_range children() { + return child_range(getTrailingObjects<Stmt *>(), + getTrailingObjects<Stmt *>() + hasFunctionName()); + } +}; + /// ParenExpr - This represents a parethesized expression, e.g. "(1)". This /// AST node is only formed if full location information is requested. class ParenExpr : public Expr { Modified: cfe/trunk/include/clang/AST/Stmt.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Stmt.h (original) +++ cfe/trunk/include/clang/AST/Stmt.h Sat Oct 27 12:21:19 2018 @@ -268,6 +268,24 @@ protected: }; enum { NumExprBits = 17 }; + class PredefinedExprBitfields { + friend class ASTStmtReader; + friend class PredefinedExpr; + + unsigned : NumExprBits; + + /// The kind of this PredefinedExpr. One of the enumeration values + /// in PredefinedExpr::IdentKind. + unsigned Kind : 4; + + /// True if this PredefinedExpr has a trailing "StringLiteral *" + /// for the predefined identifier. + unsigned HasFunctionName : 1; + + /// The location of this PredefinedExpr. + SourceLocation Loc; + }; + class CharacterLiteralBitfields { friend class CharacterLiteral; @@ -432,6 +450,7 @@ protected: // Expressions ExprBitfields ExprBits; + PredefinedExprBitfields PredefinedExprBits; CharacterLiteralBitfields CharacterLiteralBits; FloatingLiteralBitfields FloatingLiteralBits; UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits; Modified: cfe/trunk/include/clang/AST/StmtDataCollectors.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtDataCollectors.td?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/StmtDataCollectors.td (original) +++ cfe/trunk/include/clang/AST/StmtDataCollectors.td Sat Oct 27 12:21:19 2018 @@ -27,7 +27,7 @@ class ExpressionTraitExpr { } class PredefinedExpr { code Code = [{ - addData(S->getIdentType()); + addData(S->getIdentKind()); }]; } class TypeTraitExpr { Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Sat Oct 27 12:21:19 2018 @@ -4214,7 +4214,7 @@ public: TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr); ExprResult BuildPredefinedExpr(SourceLocation Loc, - PredefinedExpr::IdentType IT); + PredefinedExpr::IdentKind IK); ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); Modified: cfe/trunk/lib/AST/ASTDumper.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTDumper.cpp (original) +++ cfe/trunk/lib/AST/ASTDumper.cpp Sat Oct 27 12:21:19 2018 @@ -2198,7 +2198,7 @@ void ASTDumper::VisitObjCIvarRefExpr(con void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { VisitExpr(Node); - OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType()); + OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind()); } void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Sat Oct 27 12:21:19 2018 @@ -6148,8 +6148,8 @@ ExpectedStmt ASTNodeImporter::VisitPrede StringLiteral *ToFunctionName; std::tie(ToBeginLoc, ToType, ToFunctionName) = *Imp; - return new (Importer.getToContext()) PredefinedExpr( - ToBeginLoc, ToType, E->getIdentType(), ToFunctionName); + return PredefinedExpr::Create(Importer.getToContext(), ToBeginLoc, ToType, + E->getIdentKind(), ToFunctionName); } ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { Modified: cfe/trunk/lib/AST/Expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/AST/Expr.cpp (original) +++ cfe/trunk/lib/AST/Expr.cpp Sat Oct 27 12:21:19 2018 @@ -458,20 +458,45 @@ SourceLocation DeclRefExpr::getEndLoc() return getNameInfo().getEndLoc(); } -PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT, +PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK, StringLiteral *SL) : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary, FNTy->isDependentType(), FNTy->isDependentType(), FNTy->isInstantiationDependentType(), - /*ContainsUnexpandedParameterPack=*/false), - Loc(L), Type(IT), FnName(SL) {} + /*ContainsUnexpandedParameterPack=*/false) { + PredefinedExprBits.Kind = IK; + assert((getIdentKind() == IK) && + "IdentKind do not fit in PredefinedExprBitfields!"); + bool HasFunctionName = SL != nullptr; + PredefinedExprBits.HasFunctionName = HasFunctionName; + PredefinedExprBits.Loc = L; + if (HasFunctionName) + setFunctionName(SL); +} + +PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName) + : Expr(PredefinedExprClass, Empty) { + PredefinedExprBits.HasFunctionName = HasFunctionName; +} + +PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L, + QualType FNTy, IdentKind IK, + StringLiteral *SL) { + bool HasFunctionName = SL != nullptr; + void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName), + alignof(PredefinedExpr)); + return new (Mem) PredefinedExpr(L, FNTy, IK, SL); +} -StringLiteral *PredefinedExpr::getFunctionName() { - return cast_or_null<StringLiteral>(FnName); +PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx, + bool HasFunctionName) { + void *Mem = Ctx.Allocate(totalSizeToAlloc<Stmt *>(HasFunctionName), + alignof(PredefinedExpr)); + return new (Mem) PredefinedExpr(EmptyShell(), HasFunctionName); } -StringRef PredefinedExpr::getIdentTypeName(PredefinedExpr::IdentType IT) { - switch (IT) { +StringRef PredefinedExpr::getIdentKindName(PredefinedExpr::IdentKind IK) { + switch (IK) { case Func: return "__func__"; case Function: @@ -489,15 +514,15 @@ StringRef PredefinedExpr::getIdentTypeNa case PrettyFunctionNoVirtual: break; } - llvm_unreachable("Unknown ident type for PredefinedExpr"); + 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(IdentType IT, const Decl *CurrentDecl) { +std::string PredefinedExpr::ComputeName(IdentKind IK, const Decl *CurrentDecl) { ASTContext &Context = CurrentDecl->getASTContext(); - if (IT == PredefinedExpr::FuncDName) { + if (IK == PredefinedExpr::FuncDName) { if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) { std::unique_ptr<MangleContext> MC; MC.reset(Context.createMangleContext()); @@ -532,21 +557,21 @@ std::string PredefinedExpr::ComputeName( llvm::raw_svector_ostream Out(Buffer); if (auto *DCBlock = dyn_cast<BlockDecl>(DC)) // For nested blocks, propagate up to the parent. - Out << ComputeName(IT, DCBlock); + Out << ComputeName(IK, DCBlock); else if (auto *DCDecl = dyn_cast<Decl>(DC)) - Out << ComputeName(IT, DCDecl) << "_block_invoke"; + Out << ComputeName(IK, DCDecl) << "_block_invoke"; return Out.str(); } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { - if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && - IT != FuncSig && IT != LFuncSig) + if (IK != PrettyFunction && IK != PrettyFunctionNoVirtual && + IK != FuncSig && IK != LFuncSig) return FD->getNameAsString(); SmallString<256> Name; llvm::raw_svector_ostream Out(Name); if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { - if (MD->isVirtual() && IT != PrettyFunctionNoVirtual) + if (MD->isVirtual() && IK != PrettyFunctionNoVirtual) Out << "virtual "; if (MD->isStatic()) Out << "static "; @@ -564,7 +589,7 @@ std::string PredefinedExpr::ComputeName( if (FD->hasWrittenPrototype()) FT = dyn_cast<FunctionProtoType>(AFT); - if (IT == FuncSig || IT == LFuncSig) { + if (IK == FuncSig || IK == LFuncSig) { switch (AFT->getCallConv()) { case CC_C: POut << "__cdecl "; break; case CC_X86StdCall: POut << "__stdcall "; break; @@ -589,7 +614,7 @@ std::string PredefinedExpr::ComputeName( if (FT->isVariadic()) { if (FD->getNumParams()) POut << ", "; POut << "..."; - } else if ((IT == FuncSig || IT == LFuncSig || + } else if ((IK == FuncSig || IK == LFuncSig || !Context.getLangOpts().CPlusPlus) && !Decl->getNumParams()) { POut << "void"; @@ -688,7 +713,7 @@ std::string PredefinedExpr::ComputeName( // CapturedDecl. if (DC->isFunctionOrMethod() && (DC->getDeclKind() != Decl::Captured)) { const Decl *D = Decl::castFromDeclContext(DC); - return ComputeName(IT, D); + return ComputeName(IK, D); } llvm_unreachable("CapturedDecl not inside a function or method"); } @@ -713,7 +738,7 @@ std::string PredefinedExpr::ComputeName( return Name.str().str(); } - if (isa<TranslationUnitDecl>(CurrentDecl) && IT == PrettyFunction) { + if (isa<TranslationUnitDecl>(CurrentDecl) && IK == PrettyFunction) { // __PRETTY_FUNCTION__ -> "top level", the others produce an empty string. return "top level"; } Modified: cfe/trunk/lib/AST/StmtPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) +++ cfe/trunk/lib/AST/StmtPrinter.cpp Sat Oct 27 12:21:19 2018 @@ -991,7 +991,7 @@ void StmtPrinter::VisitObjCSubscriptRefE } void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { - OS << PredefinedExpr::getIdentTypeName(Node->getIdentType()); + OS << PredefinedExpr::getIdentKindName(Node->getIdentKind()); } void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { Modified: cfe/trunk/lib/AST/StmtProfile.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/AST/StmtProfile.cpp (original) +++ cfe/trunk/lib/AST/StmtProfile.cpp Sat Oct 27 12:21:19 2018 @@ -1010,7 +1010,7 @@ void StmtProfiler::VisitDeclRefExpr(cons void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) { VisitExpr(S); - ID.AddInteger(S->getIdentType()); + ID.AddInteger(S->getIdentKind()); } void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) { Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat Oct 27 12:21:19 2018 @@ -2662,7 +2662,7 @@ LValue CodeGenFunction::EmitPredefinedLV if (FnName.startswith("\01")) FnName = FnName.substr(1); StringRef NameItems[] = { - PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName}; + PredefinedExpr::getIdentKindName(E->getIdentKind()), FnName}; std::string GVName = llvm::join(NameItems, NameItems + 2, "."); if (auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl)) { std::string Name = SL->getString(); Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Sat Oct 27 12:21:19 2018 @@ -1783,7 +1783,7 @@ ConstantLValueEmitter::VisitPredefinedEx return cast<ConstantAddress>(Res.getAddress()); } - auto kind = E->getIdentType(); + auto kind = E->getIdentKind(); if (kind == PredefinedExpr::PrettyFunction) { return CGM.GetAddrOfConstantCString("top level", ".tmp"); } Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Oct 27 12:21:19 2018 @@ -3036,7 +3036,7 @@ static void ConvertUTF8ToWideString(unsi } ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, - PredefinedExpr::IdentType IT) { + PredefinedExpr::IdentKind IK) { // Pick the current block, lambda, captured statement or function. Decl *currentDecl = nullptr; if (const BlockScopeInfo *BSI = getCurBlock()) @@ -3060,11 +3060,11 @@ ExprResult Sema::BuildPredefinedExpr(Sou else { // Pre-defined identifiers are of type char[x], where x is the length of // the string. - auto Str = PredefinedExpr::ComputeName(IT, currentDecl); + auto Str = PredefinedExpr::ComputeName(IK, currentDecl); unsigned Length = Str.length(); llvm::APInt LengthI(32, Length + 1); - if (IT == PredefinedExpr::LFunction || IT == PredefinedExpr::LFuncSig) { + if (IK == PredefinedExpr::LFunction || IK == PredefinedExpr::LFuncSig) { ResTy = Context.adjustStringLiteralBaseType(Context.WideCharTy.withConst()); SmallString<32> RawChars; @@ -3083,24 +3083,24 @@ ExprResult Sema::BuildPredefinedExpr(Sou } } - return new (Context) PredefinedExpr(Loc, ResTy, IT, SL); + return PredefinedExpr::Create(Context, Loc, ResTy, IK, SL); } ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { - PredefinedExpr::IdentType IT; + PredefinedExpr::IdentKind IK; switch (Kind) { default: llvm_unreachable("Unknown simple primary expr!"); - case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2] - case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break; - case tok::kw___FUNCDNAME__: IT = PredefinedExpr::FuncDName; break; // [MS] - case tok::kw___FUNCSIG__: IT = PredefinedExpr::FuncSig; break; // [MS] - case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break; // [MS] - case tok::kw_L__FUNCSIG__: IT = PredefinedExpr::LFuncSig; break; // [MS] - case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break; + case tok::kw___func__: IK = PredefinedExpr::Func; break; // [C99 6.4.2.2] + case tok::kw___FUNCTION__: IK = PredefinedExpr::Function; break; + case tok::kw___FUNCDNAME__: IK = PredefinedExpr::FuncDName; break; // [MS] + case tok::kw___FUNCSIG__: IK = PredefinedExpr::FuncSig; break; // [MS] + case tok::kw_L__FUNCTION__: IK = PredefinedExpr::LFunction; break; // [MS] + case tok::kw_L__FUNCSIG__: IK = PredefinedExpr::LFuncSig; break; // [MS] + case tok::kw___PRETTY_FUNCTION__: IK = PredefinedExpr::PrettyFunction; break; } - return BuildPredefinedExpr(Loc, IT); + return BuildPredefinedExpr(Loc, IK); } ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) { Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Oct 27 12:21:19 2018 @@ -1167,7 +1167,7 @@ TemplateInstantiator::TransformPredefine if (!E->isTypeDependent()) return E; - return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType()); + return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind()); } ExprResult Modified: cfe/trunk/lib/Sema/TreeTransform.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/Sema/TreeTransform.h (original) +++ cfe/trunk/lib/Sema/TreeTransform.h Sat Oct 27 12:21:19 2018 @@ -2096,8 +2096,8 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildPredefinedExpr(SourceLocation Loc, - PredefinedExpr::IdentType IT) { - return getSema().BuildPredefinedExpr(Loc, IT); + PredefinedExpr::IdentKind IK) { + return getSema().BuildPredefinedExpr(Loc, IK); } /// Build a new expression that references a declaration. @@ -8921,7 +8921,7 @@ TreeTransform<Derived>::TransformPredefi return E; return getDerived().RebuildPredefinedExpr(E->getLocation(), - E->getIdentType()); + E->getIdentKind()); } template<typename Derived> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Sat Oct 27 12:21:19 2018 @@ -496,9 +496,12 @@ void ASTStmtReader::VisitExpr(Expr *E) { void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) { VisitExpr(E); + bool HasFunctionName = Record.readInt(); + E->PredefinedExprBits.HasFunctionName = HasFunctionName; + E->PredefinedExprBits.Kind = Record.readInt(); E->setLocation(ReadSourceLocation()); - E->Type = (PredefinedExpr::IdentType)Record.readInt(); - E->FnName = cast_or_null<StringLiteral>(Record.readSubExpr()); + if (HasFunctionName) + E->setFunctionName(cast<StringLiteral>(Record.readSubExpr())); } void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { @@ -2334,12 +2337,14 @@ Stmt *ASTReader::ReadStmtFromStream(Modu break; case STMT_CAPTURED: - S = CapturedStmt::CreateDeserialized(Context, - Record[ASTStmtReader::NumStmtFields]); + S = CapturedStmt::CreateDeserialized( + Context, Record[ASTStmtReader::NumStmtFields]); break; case EXPR_PREDEFINED: - S = new (Context) PredefinedExpr(Empty); + S = PredefinedExpr::CreateEmpty( + Context, + /*HasFunctionName*/ Record[ASTStmtReader::NumExprFields]); break; case EXPR_DECL_REF: Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=345460&r1=345459&r2=345460&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Sat Oct 27 12:21:19 2018 @@ -388,9 +388,13 @@ void ASTStmtWriter::VisitExpr(Expr *E) { void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) { VisitExpr(E); + + bool HasFunctionName = E->getFunctionName() != nullptr; + Record.push_back(HasFunctionName); + Record.push_back(E->getIdentKind()); // FIXME: stable encoding Record.AddSourceLocation(E->getLocation()); - Record.push_back(E->getIdentType()); // FIXME: stable encoding - Record.AddStmt(E->getFunctionName()); + if (HasFunctionName) + Record.AddStmt(E->getFunctionName()); Code = serialization::EXPR_PREDEFINED; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits