Author: Aaron Ballman Date: 2024-07-01T14:19:37-04:00 New Revision: 71ff749d6b9aee70c6d26d9781b9f70bf6a8c445
URL: https://github.com/llvm/llvm-project/commit/71ff749d6b9aee70c6d26d9781b9f70bf6a8c445 DIFF: https://github.com/llvm/llvm-project/commit/71ff749d6b9aee70c6d26d9781b9f70bf6a8c445.diff LOG: Revert "[clang][AST] fix ast-print of extern <lang> with >=2 declarators" This reverts commit 48f13d48a88c14acbaea7c3ee05018bb173fb360. It broke some external bots: https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/6805/console https://logs.chromium.org/logs/fuchsia/buildbucket/cr-buildbucket/8743609724828014497/+/u/clang/build/stdout Added: Modified: clang/lib/AST/Decl.cpp clang/lib/AST/DeclPrinter.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaExpr.cpp lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp Removed: clang/test/AST/ast-print-language-linkage.cpp ################################################################################ diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index ff3325543919f..16ed6d88d1cb1 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -576,16 +576,13 @@ template <typename T> static bool isFirstInExternCContext(T *D) { return First->isInExternCContext(); } -static bool isUnbracedLanguageLinkage(const DeclContext *DC) { - if (const auto *SD = dyn_cast_if_present<LinkageSpecDecl>(DC)) - return !SD->hasBraces(); +static bool isSingleLineLanguageLinkage(const Decl &D) { + if (const auto *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext())) + if (!SD->hasBraces()) + return true; return false; } -static bool hasUnbracedLanguageLinkage(const Decl &D) { - return isUnbracedLanguageLinkage(D.getDeclContext()); -} - static bool isDeclaredInModuleInterfaceOrPartition(const NamedDecl *D) { if (auto *M = D->getOwningModule()) return M->isInterfaceOrPartition(); @@ -647,7 +644,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, if (Var->getStorageClass() != SC_Extern && Var->getStorageClass() != SC_PrivateExtern && - !hasUnbracedLanguageLinkage(*Var)) + !isSingleLineLanguageLinkage(*Var)) return LinkageInfo::internal(); } @@ -2121,12 +2118,6 @@ VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC, "ParmVarDeclBitfields too large!"); static_assert(sizeof(NonParmVarDeclBitfields) <= sizeof(unsigned), "NonParmVarDeclBitfields too large!"); - - // The unbraced `extern "C"` invariant is that the storage class - // specifier is omitted in the source code, i.e. SC_None (but is, - // implicitly, `extern`). - assert(!isUnbracedLanguageLinkage(DC) || SC == SC_None); - AllBits = 0; VarDeclBits.SClass = SC; // Everything else is implicitly initialized to false. @@ -2310,7 +2301,7 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const { // A declaration directly contained in a linkage-specification is treated // as if it contains the extern specifier for the purpose of determining // the linkage of the declared name and whether it is a definition. - if (hasUnbracedLanguageLinkage(*this)) + if (isSingleLineLanguageLinkage(*this)) return DeclarationOnly; // C99 6.9.2p2: @@ -3036,12 +3027,6 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, DeclContext(DK), redeclarable_base(C), Body(), ODRHash(0), EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) { assert(T.isNull() || T->isFunctionType()); - - // The unbraced `extern "C"` invariant is that the storage class - // specifier is omitted in the source code, i.e. SC_None (but is, - // implicitly, `extern`). - assert(!isUnbracedLanguageLinkage(DC) || S == SC_None); - FunctionDeclBits.SClass = S; FunctionDeclBits.IsInline = isInlineSpecified; FunctionDeclBits.IsInlineSpecified = isInlineSpecified; diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index b8e0ef1b40358..26773a69ab9ac 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -633,7 +633,7 @@ static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out, Out << Proto; } -static void maybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy, +static void MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy, QualType T, llvm::raw_ostream &Out) { StringRef prefix = T->isClassType() ? "class " @@ -643,22 +643,6 @@ static void maybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy, Out << prefix; } -/// Return the language of the linkage spec of `D`, if applicable. -/// -/// \Return - "C" if `D` has been declared with unbraced `extern "C"` -/// - "C++" if `D` has been declared with unbraced `extern "C++"` -/// - nullptr in any other case -static const char *tryGetUnbracedLinkageLanguage(const Decl *D) { - const auto *SD = dyn_cast<LinkageSpecDecl>(D->getDeclContext()); - if (!SD || SD->hasBraces()) - return nullptr; - if (SD->getLanguage() == LinkageSpecLanguageIDs::C) - return "C"; - assert(SD->getLanguage() == LinkageSpecLanguageIDs::CXX && - "unknown language in linkage specification"); - return "C++"; -} - void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { if (!D->getDescribedFunctionTemplate() && !D->isFunctionTemplateSpecialization()) { @@ -678,11 +662,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D); CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D); if (!Policy.SuppressSpecifiers) { - if (const char *Lang = tryGetUnbracedLinkageLanguage(D)) { - // the "extern" specifier is implicit - assert(D->getStorageClass() == SC_None); - Out << "extern \"" << Lang << "\" "; - } switch (D->getStorageClass()) { case SC_None: break; case SC_Extern: Out << "extern "; break; @@ -828,7 +807,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { } if (!Policy.SuppressTagKeyword && Policy.SuppressScope && !Policy.SuppressUnwrittenScope) - maybePrintTagKeywordIfSupressingScopes(Policy, AFT->getReturnType(), + MaybePrintTagKeywordIfSupressingScopes(Policy, AFT->getReturnType(), Out); AFT->getReturnType().print(Out, Policy, Proto); Proto.clear(); @@ -953,11 +932,6 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { : D->getASTContext().getUnqualifiedObjCPointerType(D->getType()); if (!Policy.SuppressSpecifiers) { - if (const char *Lang = tryGetUnbracedLinkageLanguage(D)) { - // the "extern" specifier is implicit - assert(D->getStorageClass() == SC_None); - Out << "extern \"" << Lang << "\" "; - } StorageClass SC = D->getStorageClass(); if (SC != SC_None) Out << VarDecl::getStorageClassSpecifierString(SC) << " "; @@ -987,7 +961,7 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { if (!Policy.SuppressTagKeyword && Policy.SuppressScope && !Policy.SuppressUnwrittenScope) - maybePrintTagKeywordIfSupressingScopes(Policy, T, Out); + MaybePrintTagKeywordIfSupressingScopes(Policy, T, Out); printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters && D->getIdentifier()) @@ -1090,8 +1064,6 @@ void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) { prettyPrintAttributes(D); - if (const char *Lang = tryGetUnbracedLinkageLanguage(D)) - Out << "extern \"" << Lang << "\";"; } void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { @@ -1164,21 +1136,22 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { } void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { - if (!D->hasBraces()) { - VisitDeclContext(D); - return; - } - const char *L; + const char *l; if (D->getLanguage() == LinkageSpecLanguageIDs::C) - L = "C"; + l = "C"; else { assert(D->getLanguage() == LinkageSpecLanguageIDs::CXX && "unknown language in linkage specification"); - L = "C++"; + l = "C++"; } - Out << "extern \"" << L << "\" {\n"; - VisitDeclContext(D); - Indent() << "}"; + + Out << "extern \"" << l << "\" "; + if (D->hasBraces()) { + Out << "{\n"; + VisitDeclContext(D); + Indent() << "}"; + } else + Visit(*D->decls_begin()); } void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index da2e167d1f97a..262a2547e23fd 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2286,7 +2286,7 @@ FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type, } FunctionDecl *New = FunctionDecl::Create(Context, Parent, Loc, Loc, II, Type, - /*TInfo=*/nullptr, SC_None, + /*TInfo=*/nullptr, SC_Extern, getCurFPFeatures().isFPConstrained(), false, Type->isFunctionProtoType()); New->setImplicit(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 59facdf5d92a5..6ecf9e177ba42 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6161,7 +6161,7 @@ static FunctionDecl *rewriteBuiltinFunctionDecl(Sema *Sema, ASTContext &Context, FunctionDecl *OverloadDecl = FunctionDecl::Create( Context, Parent, FDecl->getLocation(), FDecl->getLocation(), FDecl->getIdentifier(), OverloadTy, - /*TInfo=*/nullptr, SC_None, Sema->getCurFPFeatures().isFPConstrained(), + /*TInfo=*/nullptr, SC_Extern, Sema->getCurFPFeatures().isFPConstrained(), false, /*hasPrototype=*/true); SmallVector<ParmVarDecl*, 16> Params; diff --git a/clang/test/AST/ast-print-language-linkage.cpp b/clang/test/AST/ast-print-language-linkage.cpp deleted file mode 100644 index 7e4dc3f25f062..0000000000000 --- a/clang/test/AST/ast-print-language-linkage.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s - -// CHECK: extern "C" int printf(const char *, ...); -extern "C" int printf(const char *...); - -// CHECK: extern "C++" int f(int); -// CHECK-NEXT: extern "C++" int g(int); -extern "C++" int f(int), g(int); - -// CHECK: extern "C" char a; -// CHECK-NEXT: extern "C" char b; -extern "C" char a, b; - -// CHECK: extern "C" { -// CHECK-NEXT: void foo(); -// CHECK-NEXT: int x; -// CHECK-NEXT: int y; -// CHECK-NEXT: extern short z; -// CHECK-NEXT: } -extern "C" { - void foo(void); - int x, y; - extern short z; -} - -// CHECK: extern "C" { -// CHECK-NEXT: } -extern "C" {} - -// CHECK: extern "C++"; -extern "C++"; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 4849458e7c054..303e88feea20b 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -881,7 +881,7 @@ class CodeComplete : public CodeCompleteConsumer { else ToInsert += "("; raw_string_ostream OS(Description); - F->print(OS, m_desc_policy); + F->print(OS, m_desc_policy, false); OS.flush(); } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) { Description = V->getType().getAsString(m_desc_policy); diff --git a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp index e02b418b1e793..da59855a9f162 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp @@ -77,8 +77,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, clang::FunctionDecl *func_decl = FunctionDecl::Create( ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type, - nullptr, SC_None, /*UsesFPIntrin=*/false, isInlineSpecified, - hasWrittenPrototype, + nullptr, SC_Extern, /*UsesFPIntrin=*/false, isInlineSpecified, hasWrittenPrototype, isConstexprSpecified ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits