r189850 - Refactor computation of whether a variable declaration's type should be merged
Richard Smith
richard-llvm at metafoo.co.uk
Tue Sep 3 14:00:58 PDT 2013
Author: rsmith
Date: Tue Sep 3 16:00:58 2013
New Revision: 189850
URL: http://llvm.org/viewvc/llvm-project?rev=189850&view=rev
Log:
Refactor computation of whether a variable declaration's type should be merged
with a prior declaration. No functionality change intended.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=189850&r1=189849&r2=189850&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Sep 3 16:00:58 2013
@@ -1867,8 +1867,7 @@ public:
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
Scope *S, bool MergeTypeWithOld);
void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old);
- void MergeVarDecl(VarDecl *New, LookupResult &Previous,
- bool MergeTypeWithPrevious);
+ void MergeVarDecl(VarDecl *New, LookupResult &Previous);
void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=189850&r1=189849&r2=189850&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Sep 3 16:00:58 2013
@@ -2863,11 +2863,40 @@ void Sema::MergeVarDeclTypes(VarDecl *Ne
}
// Don't actually update the type on the new declaration if the old
- // declaration was a extern declaration in a different scope.
+ // declaration was an extern declaration in a different scope.
if (MergeTypeWithOld)
New->setType(MergedT);
}
+static bool mergeTypeWithPrevious(Sema &S, VarDecl *NewVD, VarDecl *OldVD,
+ LookupResult &Previous) {
+ // C11 6.2.7p4:
+ // For an identifier with internal or external linkage declared
+ // in a scope in which a prior declaration of that identifier is
+ // visible, if the prior declaration specifies internal or
+ // external linkage, the type of the identifier at the later
+ // declaration becomes the composite type.
+ //
+ // If the variable isn't visible, we do not merge with its type.
+ if (Previous.isShadowed())
+ return false;
+
+ if (S.getLangOpts().CPlusPlus) {
+ // C++11 [dcl.array]p3:
+ // If there is a preceding declaration of the entity in the same
+ // scope in which the bound was specified, an omitted array bound
+ // is taken to be the same as in that earlier declaration.
+ return NewVD->isPreviousDeclInSameBlockScope() ||
+ (!OldVD->getLexicalDeclContext()->isFunctionOrMethod() &&
+ !NewVD->getLexicalDeclContext()->isFunctionOrMethod());
+ } else {
+ // If the old declaration was function-local, don't merge with its
+ // type unless we're in the same function.
+ return !OldVD->getLexicalDeclContext()->isFunctionOrMethod() ||
+ OldVD->getLexicalDeclContext() == NewVD->getLexicalDeclContext();
+ }
+}
+
/// MergeVarDecl - We just parsed a variable 'New' which has the same name
/// and scope as a previous declaration 'Old'. Figure out how to resolve this
/// situation, merging decls or emitting diagnostics as appropriate.
@@ -2876,8 +2905,7 @@ void Sema::MergeVarDeclTypes(VarDecl *Ne
/// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative
/// definitions here, since the initializer hasn't been attached.
///
-void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
- bool MergeTypeWithPrevious) {
+void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
// If the new decl is already invalid, don't do any other checking.
if (New->isInvalidDecl())
return;
@@ -2926,7 +2954,8 @@ void Sema::MergeVarDecl(VarDecl *New, Lo
}
// Merge the types.
- MergeVarDeclTypes(New, Old, MergeTypeWithPrevious);
+ MergeVarDeclTypes(New, Old, mergeTypeWithPrevious(*this, New, Old, Previous));
+
if (New->isInvalidDecl())
return;
@@ -5711,48 +5740,15 @@ bool Sema::CheckVariableDeclaration(VarD
// If we did not find anything by this name, look for a non-visible
// extern "C" declaration with the same name.
- //
- // The actual standards text here is:
- //
- // C++11 [basic.link]p6:
- // The name of a function declared in block scope and the name
- // of a variable declared by a block scope extern declaration
- // have linkage. If there is a visible declaration of an entity
- // with linkage having the same name and type, ignoring entities
- // declared outside the innermost enclosing namespace scope, the
- // block scope declaration declares that same entity and
- // receives the linkage of the previous declaration.
- //
- // C++11 [dcl.array]p3:
- // If there is a preceding declaration of the entity in the same
- // scope in which the bound was specified, an omitted array bound
- // is taken to be the same as in that earlier declaration.
- //
- // C11 6.2.7p4:
- // For an identifier with internal or external linkage declared
- // in a scope in which a prior declaration of that identifier is
- // visible, if the prior declaration specifies internal or
- // external linkage, the type of the identifier at the later
- // declaration becomes the composite type.
- //
- // The most important point here is that we're not allowed to
- // update our understanding of the type according to declarations
- // not in scope (in C++) or not visible (in C).
- bool MergeTypeWithPrevious;
if (Previous.empty() &&
checkForConflictWithNonVisibleExternC(*this, NewVD, Previous))
- MergeTypeWithPrevious = false;
- else
- MergeTypeWithPrevious =
- !Previous.isShadowed() &&
- (!getLangOpts().CPlusPlus || NewVD->isPreviousDeclInSameBlockScope() ||
- !NewVD->getLexicalDeclContext()->isFunctionOrMethod());
+ Previous.setShadowed();
// Filter out any non-conflicting previous declarations.
filterNonConflictingPreviousDecls(Context, NewVD, Previous);
if (!Previous.empty()) {
- MergeVarDecl(NewVD, Previous, MergeTypeWithPrevious);
+ MergeVarDecl(NewVD, Previous);
return true;
}
return false;
More information about the cfe-commits
mailing list