aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-04-14 02:25:56 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-04-14 02:25:56 +0000
commit5466c7b0ca8ce662e2c0bc295cecba2b78d6957d (patch)
treef2e6d04f1fdd87b396c1508c82eaaad032cfd73b /lib/Sema/SemaDecl.cpp
parentb286a78c8cce4592306dae6abc3656daf6379c77 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69020 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp29
1 files changed, 13 insertions, 16 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f4f131141f..73d2a5237a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -884,8 +884,7 @@ bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
// 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 @@ bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
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 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
// 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 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
// 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 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
}
}
} 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 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
// 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 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
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 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
// 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 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
// 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))