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
This commit is contained in:
Aaron Ballman 2024-07-01 14:19:37 -04:00
parent 7888d66af2
commit 71ff749d6b
7 changed files with 24 additions and 98 deletions

View File

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

View File

@ -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,

View File

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

View File

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

View File

@ -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++";

View File

@ -881,7 +881,7 @@ private:
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);

View File

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