[clang] 71ff749 - Revert "[clang][AST] fix ast-print of extern <lang> with >=2 declarators"

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 1 11:20:22 PDT 2024


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);
 


        


More information about the cfe-commits mailing list