[cfe-commits] r69020 - in /cfe/trunk: lib/AST/StmtDumper.cpp lib/AST/StmtPrinter.cpp lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExpr.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclObjC.cpp test/Sema/private-extern.c
Daniel Dunbar
daniel at zuster.org
Mon Apr 13 19:25:56 PDT 2009
Author: ddunbar
Date: Mon Apr 13 21:25:56 2009
New Revision: 69020
URL: http://llvm.org/viewvc/llvm-project?rev=69020&view=rev
Log:
Audit __private_extern__ handling.
- Exposed quite a few Sema issues and a CodeGen crash.
- See FIXMEs in test case, and in SemaDecl.cpp (PR3983).
I'm skeptical that __private_extern__ should actually be a storage
class value. I think that __private_extern__ basically amounts to
extern A __attribute__((visibility("hidden")))
and would be better off handled (a) as that, or (b) with an extra bit
in the VarDecl.
Added:
cfe/trunk/test/Sema/private-extern.c
Modified:
cfe/trunk/lib/AST/StmtDumper.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/CodeGen/CGBlocks.cpp
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=69020&r1=69019&r2=69020&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Mon Apr 13 21:25:56 2009
@@ -217,14 +217,9 @@
fprintf(F, "\"");
// Emit storage class for vardecls.
if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
- switch (V->getStorageClass()) {
- default: assert(0 && "Unknown storage class!");
- case VarDecl::None: break;
- case VarDecl::Extern: fprintf(F, "extern "); break;
- case VarDecl::Static: fprintf(F, "static "); break;
- case VarDecl::Auto: fprintf(F, "auto "); break;
- case VarDecl::Register: fprintf(F, "register "); break;
- }
+ if (V->getStorageClass() != VarDecl::None)
+ fprintf(F, "%s ",
+ VarDecl::getStorageClassSpecifierString(V->getStorageClass()));
}
std::string Name = VD->getNameAsString();
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=69020&r1=69019&r2=69020&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Apr 13 21:25:56 2009
@@ -117,15 +117,9 @@
} else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
// Emit storage class for vardecls.
if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
- switch (V->getStorageClass()) {
- default: assert(0 && "Unknown storage class!");
- case VarDecl::None: break;
- case VarDecl::Extern: OS << "extern "; break;
- case VarDecl::Static: OS << "static "; break;
- case VarDecl::Auto: OS << "auto "; break;
- case VarDecl::Register: OS << "register "; break;
- case VarDecl::PrivateExtern: OS << "__private_extern "; break;
- }
+ if (V->getStorageClass() != VarDecl::None)
+ OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass())
+ << ' ';
}
std::string Name = VD->getNameAsString();
Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=69020&r1=69019&r2=69020&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Mon Apr 13 21:25:56 2009
@@ -608,8 +608,7 @@
++i) {
const VarDecl *VD = dyn_cast<VarDecl>(i->first);
- if (VD->getStorageClass() == VarDecl::Static
- || VD->getStorageClass() == VarDecl::Extern)
+ if (VD->getStorageClass() == VarDecl::Static || VD->hasExternalStorage())
LocalDeclMap[VD] = i->second;
}
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=69020&r1=69019&r2=69020&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Apr 13 21:25:56 2009
@@ -68,18 +68,19 @@
CGM.ErrorUnsupported(&D, "thread local ('__thread') variable", true);
switch (D.getStorageClass()) {
+ case VarDecl::None:
+ case VarDecl::Auto:
+ case VarDecl::Register:
+ return EmitLocalBlockVarDecl(D);
case VarDecl::Static:
return EmitStaticBlockVarDecl(D);
case VarDecl::Extern:
+ case VarDecl::PrivateExtern:
// Don't emit it now, allow it to be emitted lazily on its first use.
return;
- default:
- assert((D.getStorageClass() == VarDecl::None ||
- D.getStorageClass() == VarDecl::Auto ||
- D.getStorageClass() == VarDecl::Register) &&
- "Unknown storage class");
- return EmitLocalBlockVarDecl(D);
}
+
+ assert(0 && "Unknown storage class");
}
llvm::GlobalVariable *
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=69020&r1=69019&r2=69020&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Apr 13 21:25:56 2009
@@ -632,7 +632,7 @@
isa<ImplicitParamDecl>(VD))) {
LValue LV;
bool GCable = VD->hasLocalStorage() && ! VD->getAttr<BlocksAttr>();
- if (VD->getStorageClass() == VarDecl::Extern) {
+ if (VD->hasExternalStorage()) {
LV = LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD),
E->getType().getCVRQualifiers(),
getContext().getObjCGCAttrKind(E->getType()));
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=69020&r1=69019&r2=69020&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Apr 13 21:25:56 2009
@@ -884,8 +884,7 @@
// C99 6.2.2p4: Check if we have a static decl followed by a non-static.
if (New->getStorageClass() == VarDecl::Static &&
- (Old->getStorageClass() == VarDecl::None ||
- Old->getStorageClass() == VarDecl::Extern)) {
+ (Old->getStorageClass() == VarDecl::None || Old->hasExternalStorage())) {
Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
return true;
@@ -907,8 +906,12 @@
Diag(Old->getLocation(), diag::note_previous_definition);
return true;
}
+
// Variables with external linkage are analyzed in FinalizeDeclaratorGroup.
- if (New->getStorageClass() != VarDecl::Extern && !New->isFileVarDecl() &&
+
+ // FIXME: The test for external storage here seems wrong? We still
+ // need to check for mismatches.
+ if (!New->hasExternalStorage() && !New->isFileVarDecl() &&
// Don't complain about out-of-line definitions of static members.
!(Old->getLexicalDeclContext()->isRecord() &&
!New->getLexicalDeclContext()->isRecord())) {
@@ -2422,8 +2425,7 @@
// CheckInitializerTypes may change it.
QualType DclT = VDecl->getType(), SavT = DclT;
if (VDecl->isBlockVarDecl()) {
- VarDecl::StorageClass SC = VDecl->getStorageClass();
- if (SC == VarDecl::Extern) { // C99 6.7.8p5
+ if (VDecl->hasExternalStorage()) { // C99 6.7.8p5
Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
VDecl->setInvalidDecl();
} else if (!VDecl->isInvalidDecl()) {
@@ -2434,7 +2436,7 @@
// C++ 3.6.2p2, allow dynamic initialization of static initializers.
// Don't check invalid declarations to avoid emitting useless diagnostics.
if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
- if (SC == VarDecl::Static) // C99 6.7.8p4.
+ if (VDecl->getStorageClass() == VarDecl::Static) // C99 6.7.8p4.
CheckForConstantInitializer(Init, DclT);
}
}
@@ -2486,7 +2488,7 @@
}
}
} else if (VDecl->isFileVarDecl()) {
- if (VDecl->getStorageClass() == VarDecl::Extern)
+ if (VDecl->hasExternalStorage())
Diag(VDecl->getLocation(), diag::warn_extern_init);
if (!VDecl->isInvalidDecl())
if (CheckInitializerTypes(Init, DclT, VDecl->getLocation(),
@@ -2529,9 +2531,7 @@
// function return type, in the declaration of a class member
// within its class declaration (9.2), and where the extern
// specifier is explicitly used.
- if (Type->isReferenceType() &&
- Var->getStorageClass() != VarDecl::Extern &&
- Var->getStorageClass() != VarDecl::PrivateExtern) {
+ if (Type->isReferenceType() && !Var->hasExternalStorage()) {
Diag(Var->getLocation(), diag::err_reference_var_requires_init)
<< Var->getDeclName()
<< SourceRange(Var->getLocation(), Var->getLocation());
@@ -2550,9 +2550,7 @@
QualType InitType = Type;
if (const ArrayType *Array = Context.getAsArrayType(Type))
InitType = Array->getElementType();
- if (Var->getStorageClass() != VarDecl::Extern &&
- Var->getStorageClass() != VarDecl::PrivateExtern &&
- InitType->isRecordType()) {
+ if (!Var->hasExternalStorage() && InitType->isRecordType()) {
const CXXConstructorDecl *Constructor = 0;
if (!RequireCompleteType(Var->getLocation(), InitType,
diag::err_invalid_incomplete_type_use))
@@ -2593,7 +2591,7 @@
// constructor check.
if (getLangOptions().CPlusPlus &&
Context.getCanonicalType(Type).isConstQualified() &&
- Var->getStorageClass() != VarDecl::Extern)
+ !Var->hasExternalStorage())
Diag(Var->getLocation(), diag::err_const_var_requires_init)
<< Var->getName()
<< SourceRange(Var->getLocation(), Var->getLocation());
@@ -2619,8 +2617,7 @@
// Block scope. C99 6.7p7: If an identifier for an object is declared with
// no linkage (C99 6.2.2p6), the type for the object shall be complete...
- if (IDecl->isBlockVarDecl() &&
- IDecl->getStorageClass() != VarDecl::Extern) {
+ if (IDecl->isBlockVarDecl() && !IDecl->hasExternalStorage()) {
if (!IDecl->isInvalidDecl() &&
RequireCompleteType(IDecl->getLocation(), T,
diag::err_typecheck_decl_incomplete_type))
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=69020&r1=69019&r2=69020&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Apr 13 21:25:56 2009
@@ -1356,8 +1356,7 @@
DeclGroupRef DG = allTUVars[i].getAsVal<DeclGroupRef>();
for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
if (VarDecl *VDecl = dyn_cast<VarDecl>(*I)) {
- if (VDecl->getStorageClass() != VarDecl::Extern &&
- VDecl->getStorageClass() != VarDecl::PrivateExtern)
+ if (!VDecl->hasExternalStorage())
Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass);
}
}
Added: cfe/trunk/test/Sema/private-extern.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/private-extern.c?rev=69020&view=auto
==============================================================================
--- cfe/trunk/test/Sema/private-extern.c (added)
+++ cfe/trunk/test/Sema/private-extern.c Mon Apr 13 21:25:56 2009
@@ -0,0 +1,89 @@
+// RUN: clang-cc -verify -fsyntax-only %s
+
+static int g0; // expected-note{{previous definition}}
+int g0; // expected-error{{non-static declaration of 'g0' follows static declaration}}
+
+static int g1;
+extern int g1;
+
+static int g2;
+__private_extern__ int g2;
+
+int g3; // expected-note{{previous definition}}
+static int g3; // expected-error{{static declaration of 'g3' follows non-static declaration}}
+
+extern int g4; // expected-note{{previous definition}}
+static int g4; // expected-error{{static declaration of 'g4' follows non-static declaration}}
+
+__private_extern__ int g5; // expected-note{{previous definition}}
+static int g5; // expected-error{{static declaration of 'g5' follows non-static declaration}}
+
+void f0() {
+ // FIXME: Diagnose this?
+ int g6;
+ extern int g6;
+}
+
+void f1() {
+ // FIXME: Diagnose this?
+ int g7;
+ __private_extern__ int g7;
+}
+
+void f2() {
+ extern int g8; // expected-note{{previous definition}}
+ // FIXME: Improve this diagnostic.
+ int g8; // expected-error{{redefinition of 'g8'}}
+}
+
+void f3() {
+ __private_extern__ int g9; // expected-note{{previous definition}}
+ // FIXME: Improve this diagnostic.
+ int g9; // expected-error{{redefinition of 'g9'}}
+}
+
+void f4() {
+ extern int g10;
+ extern int g10;
+}
+
+void f5() {
+ __private_extern__ int g11;
+ __private_extern__ int g11;
+}
+
+void f6() {
+ // FIXME: Diagnose
+ extern int g12;
+ __private_extern__ int g12;
+}
+
+void f7() {
+ // FIXME: Diagnose
+ __private_extern__ int g13;
+ extern int g13;
+}
+
+struct s0;
+void f8() {
+ extern struct s0 g14;
+ __private_extern__ struct s0 g14;
+}
+struct s0 { int x; };
+
+void f9() {
+ extern int g15 = 0; // expected-error{{'extern' variable cannot have an initializer}}
+ // FIXME: linkage specifier in warning.
+ __private_extern__ int g16 = 0; // expected-error{{'extern' variable cannot have an initializer}}
+}
+
+extern int g17;
+int g17 = 0;
+
+extern int g18 = 0; // expected-warning{{'extern' variable has an initializer}}
+
+__private_extern__ int g19;
+int g19 = 0;
+
+// FIXME: linkage specifier in warning.
+__private_extern__ int g20 = 0; // expected-warning{{'extern' variable has an initializer}}
More information about the cfe-commits
mailing list