r191064 - Switch the semantic DeclContext for a block-scope declaration of a function or
Richard Smith
richard at metafoo.co.uk
Tue Dec 10 19:39:57 PST 2013
Sorry for the delay, fixed in r197000.
On Tue, Dec 10, 2013 at 6:44 PM, Argyrios Kyrtzidis <kyrtzidis at apple.com>wrote:
> Ping ?
>
> On Dec 5, 2013, at 10:16 PM, Argyrios Kyrtzidis <kyrtzidis at apple.com>
> wrote:
>
> > Hi Richard,
> >
> > This commit is causing a compiler error for the attached test case,
> could you look into it ?
> >
> > $ clang -fsyntax-only t.cpp
> > t.cpp:10:27: error: 'private_struct' is a private member of 'test'
> > extern int array[sizeof(private_struct)];
> > ^
> > t.cpp:3:10: note: declared private here
> > struct private_struct {
> > ^
> > 1 error generated.
> >
> > <t.cpp>
> > On Sep 19, 2013, at 6:15 PM, Richard Smith <richard-llvm at metafoo.co.uk>
> wrote:
> >
> >> Author: rsmith
> >> Date: Thu Sep 19 20:15:31 2013
> >> New Revision: 191064
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=191064&view=rev
> >> Log:
> >> Switch the semantic DeclContext for a block-scope declaration of a
> function or
> >> variable from being the function to being the enclosing namespace scope
> (in
> >> C++) or the TU (in C). This allows us to fix a selection of related
> issues
> >> where we would build incorrect redeclaration chains for such
> declarations, and
> >> fail to notice type mismatches.
> >>
> >> Such declarations are put into a new IdentifierNamespace,
> IDNS_LocalExtern,
> >> which is only found when searching scopes, and not found when searching
> >> DeclContexts. Such a declaration is only made visible in its
> DeclContext if
> >> there are no non-LocalExtern declarations.
> >>
> >> Added:
> >> cfe/trunk/test/CXX/basic/basic.link/p7.cpp
> >> Modified:
> >> cfe/trunk/include/clang/AST/Decl.h
> >> cfe/trunk/include/clang/AST/DeclBase.h
> >> cfe/trunk/include/clang/Sema/Lookup.h
> >> cfe/trunk/include/clang/Sema/Sema.h
> >> cfe/trunk/lib/Sema/SemaAccess.cpp
> >> cfe/trunk/lib/Sema/SemaCodeComplete.cpp
> >> cfe/trunk/lib/Sema/SemaDecl.cpp
> >> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> >> cfe/trunk/lib/Sema/SemaExpr.cpp
> >> cfe/trunk/lib/Sema/SemaLookup.cpp
> >> cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> >> cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> >> cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp
> >> cfe/trunk/test/CXX/drs/dr0xx.cpp
> >> cfe/trunk/test/CodeGenCXX/mangle.cpp
> >> cfe/trunk/test/Index/usrs.m
> >> cfe/trunk/test/Sema/struct-decl.c
> >> cfe/trunk/test/SemaCXX/blocks-1.cpp
> >> cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
> >> cfe/trunk/test/SemaCXX/extern-c.cpp
> >> cfe/trunk/test/SemaCXX/function-redecl.cpp
> >> cfe/trunk/test/SemaCXX/warn-unreachable.cpp
> >> cfe/trunk/www/cxx_dr_status.html
> >>
> >> Modified: cfe/trunk/include/clang/AST/Decl.h
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/AST/Decl.h (original)
> >> +++ cfe/trunk/include/clang/AST/Decl.h Thu Sep 19 20:15:31 2013
> >> @@ -873,7 +873,7 @@ public:
> >> bool isLocalVarDecl() const {
> >> if (getKind() != Decl::Var)
> >> return false;
> >> - if (const DeclContext *DC = getDeclContext())
> >> + if (const DeclContext *DC = getLexicalDeclContext())
> >> return DC->getRedeclContext()->isFunctionOrMethod();
> >> return false;
> >> }
> >> @@ -883,7 +883,7 @@ public:
> >> bool isFunctionOrMethodVarDecl() const {
> >> if (getKind() != Decl::Var)
> >> return false;
> >> - const DeclContext *DC = getDeclContext()->getRedeclContext();
> >> + const DeclContext *DC =
> getLexicalDeclContext()->getRedeclContext();
> >> return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
> >> }
> >>
> >> @@ -959,7 +959,7 @@ public:
> >> if (K == ParmVar || K == ImplicitParam)
> >> return false;
> >>
> >> - if (getDeclContext()->getRedeclContext()->isFileContext())
> >> + if (getLexicalDeclContext()->getRedeclContext()->isFileContext())
> >> return true;
> >>
> >> if (isStaticDataMember())
> >> @@ -3472,10 +3472,8 @@ void Redeclarable<decl_type>::setPreviou
> >>
> >> // If the declaration was previously visible, a redeclaration of it
> remains
> >> // visible even if it wouldn't be visible by itself.
> >> - // FIXME: Once we handle local extern decls properly, this should
> inherit
> >> - // the visibility from MostRecent, not from PrevDecl.
> >> static_cast<decl_type*>(this)->IdentifierNamespace |=
> >> - PrevDecl->getIdentifierNamespace() &
> >> + MostRecent->getIdentifierNamespace() &
> >> (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
> >> } else {
> >> // Make this first.
> >>
> >> Modified: cfe/trunk/include/clang/AST/DeclBase.h
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/AST/DeclBase.h (original)
> >> +++ cfe/trunk/include/clang/AST/DeclBase.h Thu Sep 19 20:15:31 2013
> >> @@ -159,7 +159,12 @@ public:
> >> /// This declaration is a C++ operator declared in a non-class
> >> /// context. All such operators are also in IDNS_Ordinary.
> >> /// C++ lexical operator lookup looks for these.
> >> - IDNS_NonMemberOperator = 0x0400
> >> + IDNS_NonMemberOperator = 0x0400,
> >> +
> >> + /// This declaration is a function-local extern declaration of a
> >> + /// variable or function. This may also be IDNS_Ordinary if it
> >> + /// has been declared outside any function.
> >> + IDNS_LocalExtern = 0x0800
> >> };
> >>
> >> /// ObjCDeclQualifier - 'Qualifiers' written next to the return and
> >> @@ -829,6 +834,32 @@ public:
> >> bool isFunctionOrFunctionTemplate() const;
> >>
> >> /// \brief Changes the namespace of this declaration to reflect that
> it's
> >> + /// a function-local extern declaration.
> >> + ///
> >> + /// These declarations appear in the lexical context of the extern
> >> + /// declaration, but in the semantic context of the enclosing
> namespace
> >> + /// scope.
> >> + void setLocalExternDecl() {
> >> + assert((IdentifierNamespace == IDNS_Ordinary ||
> >> + IdentifierNamespace == IDNS_OrdinaryFriend) &&
> >> + "namespace is not ordinary");
> >> +
> >> + Decl *Prev = getPreviousDecl();
> >> + IdentifierNamespace &= ~IDNS_Ordinary;
> >> +
> >> + IdentifierNamespace |= IDNS_LocalExtern;
> >> + if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)
> >> + IdentifierNamespace |= IDNS_Ordinary;
> >> + }
> >> +
> >> + /// \brief Determine whether this is a block-scope declaration with
> linkage.
> >> + /// This will either be a local variable declaration declared
> 'extern', or a
> >> + /// local function declaration.
> >> + bool isLocalExternDecl() {
> >> + return IdentifierNamespace & IDNS_LocalExtern;
> >> + }
> >> +
> >> + /// \brief Changes the namespace of this declaration to reflect that
> it's
> >> /// the object of a friend declaration.
> >> ///
> >> /// These declarations appear in the lexical context of the friending
> >> @@ -838,22 +869,25 @@ public:
> >> void setObjectOfFriendDecl(bool PerformFriendInjection = false) {
> >> unsigned OldNS = IdentifierNamespace;
> >> assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
> >> - IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
> >> + IDNS_TagFriend | IDNS_OrdinaryFriend |
> >> + IDNS_LocalExtern)) &&
> >> "namespace includes neither ordinary nor tag");
> >> assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
> >> - IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
> >> + IDNS_TagFriend | IDNS_OrdinaryFriend |
> >> + IDNS_LocalExtern)) &&
> >> "namespace includes other than ordinary or tag");
> >>
> >> Decl *Prev = getPreviousDecl();
> >> - IdentifierNamespace = 0;
> >> + IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type);
> >> +
> >> if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
> >> IdentifierNamespace |= IDNS_TagFriend;
> >> - if (PerformFriendInjection ||
> >> + if (PerformFriendInjection ||
> >> (Prev && Prev->getIdentifierNamespace() & IDNS_Tag))
> >> IdentifierNamespace |= IDNS_Tag | IDNS_Type;
> >> }
> >>
> >> - if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) {
> >> + if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend |
> IDNS_LocalExtern)) {
> >> IdentifierNamespace |= IDNS_OrdinaryFriend;
> >> if (PerformFriendInjection ||
> >> (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))
> >>
> >> Modified: cfe/trunk/include/clang/Sema/Lookup.h
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Lookup.h?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/Sema/Lookup.h (original)
> >> +++ cfe/trunk/include/clang/Sema/Lookup.h Thu Sep 19 20:15:31 2013
> >> @@ -613,6 +613,13 @@ public:
> >> return Filter(*this);
> >> }
> >>
> >> + void setFindLocalExtern(bool FindLocalExtern) {
> >> + if (FindLocalExtern)
> >> + IDNS |= Decl::IDNS_LocalExtern;
> >> + else
> >> + IDNS &= ~Decl::IDNS_LocalExtern;
> >> + }
> >> +
> >> private:
> >> void diagnose() {
> >> if (isAmbiguous())
> >>
> >> Modified: cfe/trunk/include/clang/Sema/Sema.h
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> >> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Sep 19 20:15:31 2013
> >> @@ -1451,6 +1451,7 @@ public:
> >> bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
> >> DeclarationName Name,
> >> SourceLocation Loc);
> >> + static bool adjustContextForLocalExternDecl(DeclContext *&DC);
> >> void DiagnoseFunctionSpecifiers(const DeclSpec &DS);
> >> void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
> >> void CheckShadow(Scope *S, VarDecl *D);
> >> @@ -6465,8 +6466,9 @@ public:
> >> void
> >> BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar,
> >> const MultiLevelTemplateArgumentList
> &TemplateArgs,
> >> - LateInstantiatedAttrVec *LateAttrs = 0,
> >> - LocalInstantiationScope *StartingScope =
> 0,
> >> + LateInstantiatedAttrVec *LateAttrs,
> >> + DeclContext *Owner,
> >> + LocalInstantiationScope *StartingScope,
> >> bool InstantiatingVarTemplate = false);
> >> void InstantiateVariableInitializer(
> >> VarDecl *Var, VarDecl *OldVar,
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaAccess.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaAccess.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaAccess.cpp Thu Sep 19 20:15:31 2013
> >> @@ -1483,7 +1483,9 @@ void Sema::HandleDelayedAccessCheck(Dela
> >>
> >> DeclContext *DC = D->getDeclContext();
> >> if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
> >> - if (!DC->isFunctionOrMethod())
> >> + if (D->getLexicalDeclContext()->isFunctionOrMethod())
> >> + DC = D->getLexicalDeclContext();
> >> + else
> >> DC = FN;
> >> } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
> >> DC = cast<DeclContext>(TD->getTemplatedDecl());
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Sep 19 20:15:31 2013
> >> @@ -715,8 +715,8 @@ unsigned ResultBuilder::getBasePriority(
> >> return CCP_Unlikely;
> >>
> >> // Context-based decisions.
> >> - const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
> >> - if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC)) {
> >> + const DeclContext *LexicalDC = ND->getLexicalDeclContext();
> >> + if (LexicalDC->isFunctionOrMethod()) {
> >> // _cmd is relatively rare
> >> if (const ImplicitParamDecl *ImplicitParam =
> >> dyn_cast<ImplicitParamDecl>(ND))
> >> @@ -726,6 +726,8 @@ unsigned ResultBuilder::getBasePriority(
> >>
> >> return CCP_LocalDeclaration;
> >> }
> >> +
> >> + const DeclContext *DC = ND->getDeclContext()->getRedeclContext();
> >> if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
> >> return CCP_MemberDeclaration;
> >>
> >> @@ -876,8 +878,8 @@ void ResultBuilder::MaybeAddResult(Resul
> >> for (; I != IEnd; ++I) {
> >> // A tag declaration does not hide a non-tag declaration.
> >> if (I->first->hasTagIdentifierNamespace() &&
> >> - (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
> >> - Decl::IDNS_ObjCProtocol)))
> >> + (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
> >> + Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol)))
> >> continue;
> >>
> >> // Protocols are in distinct namespaces from everything else.
> >> @@ -1038,7 +1040,9 @@ void ResultBuilder::ExitScope() {
> >> bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {
> >> ND = cast<NamedDecl>(ND->getUnderlyingDecl());
> >>
> >> - unsigned IDNS = Decl::IDNS_Ordinary;
> >> + // If name lookup finds a local extern declaration, then we are in a
> >> + // context where it behaves like an ordinary name.
> >> + unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
> >> if (SemaRef.getLangOpts().CPlusPlus)
> >> IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
> >> else if (SemaRef.getLangOpts().ObjC1) {
> >> @@ -1056,7 +1060,7 @@ bool ResultBuilder::IsOrdinaryNonTypeNam
> >> if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
> >> return false;
> >>
> >> - unsigned IDNS = Decl::IDNS_Ordinary;
> >> + unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
> >> if (SemaRef.getLangOpts().CPlusPlus)
> >> IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
> >> else if (SemaRef.getLangOpts().ObjC1) {
> >> @@ -1083,7 +1087,7 @@ bool ResultBuilder::IsIntegralConstantVa
> >> bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {
> >> ND = cast<NamedDecl>(ND->getUnderlyingDecl());
> >>
> >> - unsigned IDNS = Decl::IDNS_Ordinary;
> >> + unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
> >> if (SemaRef.getLangOpts().CPlusPlus)
> >> IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
> >>
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Sep 19 20:15:31 2013
> >> @@ -1020,12 +1020,12 @@ void Sema::PushOnScopeChains(NamedDecl *
> >> if (AddToContext)
> >> CurContext->addDecl(D);
> >>
> >> - // Out-of-line definitions shouldn't be pushed into scope in C++.
> >> - // Out-of-line variable and function definitions shouldn't even in C.
> >> - if ((getLangOpts().CPlusPlus || isa<VarDecl>(D) ||
> isa<FunctionDecl>(D)) &&
> >> - D->isOutOfLine() &&
> >> + // Out-of-line definitions shouldn't be pushed into scope in C++,
> unless they
> >> + // are function-local declarations.
> >> + if (getLangOpts().CPlusPlus && D->isOutOfLine() &&
> >> !D->getDeclContext()->getRedeclContext()->Equals(
> >> - D->getLexicalDeclContext()->getRedeclContext()))
> >> + D->getLexicalDeclContext()->getRedeclContext()) &&
> >> + !D->getLexicalDeclContext()->isFunctionOrMethod())
> >> return;
> >>
> >> // Template instantiations should also not be pushed into scope.
> >> @@ -2426,7 +2426,9 @@ bool Sema::MergeFunctionDecl(FunctionDec
> >> ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>()
> >> : NewType)->getResultType();
> >> QualType ResQT;
> >> - if (!Context.hasSameType(OldDeclaredReturnType,
> NewDeclaredReturnType)) {
> >> + if (!Context.hasSameType(OldDeclaredReturnType,
> NewDeclaredReturnType) &&
> >> + !((NewQType->isDependentType() || OldQType->isDependentType())
> &&
> >> + New->isLocalExternDecl())) {
> >> if (NewDeclaredReturnType->isObjCObjectPointerType() &&
> >> OldDeclaredReturnType->isObjCObjectPointerType())
> >> ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType);
> >> @@ -2578,6 +2580,14 @@ bool Sema::MergeFunctionDecl(FunctionDec
> >> if (OldQTypeForComparison == NewQType)
> >> return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld);
> >>
> >> + if ((NewQType->isDependentType() || OldQType->isDependentType()) &&
> >> + New->isLocalExternDecl()) {
> >> + // It's OK if we couldn't merge types for a local function
> declaraton
> >> + // if either the old or new type is dependent. We'll merge the
> types
> >> + // when we instantiate the function.
> >> + return false;
> >> + }
> >> +
> >> // Fall through for conflicting redeclarations and redefinitions.
> >> }
> >>
> >> @@ -2710,7 +2720,7 @@ bool Sema::MergeFunctionDecl(FunctionDec
> >> // local declaration will produce a hard error; if it doesn't
> >> // remain visible, a single bogus local redeclaration (which is
> >> // actually only a warning) could break all the downstream code.
> >> - if (!New->getDeclContext()->isFunctionOrMethod())
> >> + if (!New->getLexicalDeclContext()->isFunctionOrMethod())
> >> New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin);
> >>
> >> return false;
> >> @@ -2820,18 +2830,21 @@ void Sema::MergeVarDeclTypes(VarDecl *Ne
> >> NewArray->getElementType()))
> >> MergedT = New->getType();
> >> } else if (Old->getType()->isArrayType() &&
> >> - New->getType()->isIncompleteArrayType()) {
> >> + New->getType()->isIncompleteArrayType()) {
> >> const ArrayType *OldArray = Context.getAsArrayType(Old->getType());
> >> const ArrayType *NewArray = Context.getAsArrayType(New->getType());
> >> if (Context.hasSameType(OldArray->getElementType(),
> >> NewArray->getElementType()))
> >> MergedT = Old->getType();
> >> - } else if (New->getType()->isObjCObjectPointerType()
> >> - && Old->getType()->isObjCObjectPointerType()) {
> >> - MergedT = Context.mergeObjCGCQualifiers(New->getType(),
> >> -
> Old->getType());
> >> + } else if (New->getType()->isObjCObjectPointerType() &&
> >> + Old->getType()->isObjCObjectPointerType()) {
> >> + MergedT = Context.mergeObjCGCQualifiers(New->getType(),
> >> + Old->getType());
> >> }
> >> } else {
> >> + // C 6.2.7p2:
> >> + // All declarations that refer to the same object or function
> shall have
> >> + // compatible type.
> >> MergedT = Context.mergeTypes(New->getType(), Old->getType());
> >> }
> >> if (MergedT.isNull()) {
> >> @@ -4308,8 +4321,15 @@ NamedDecl *Sema::HandleDeclarator(Scope
> >> // If this has an identifier and is not an invalid redeclaration or
> >> // function template specialization, add it to the scope stack.
> >> if (New->getDeclName() && AddToScope &&
> >> - !(D.isRedeclaration() && New->isInvalidDecl()))
> >> - PushOnScopeChains(New, S);
> >> + !(D.isRedeclaration() && New->isInvalidDecl())) {
> >> + // Only make a locally-scoped extern declaration visible if it is
> the first
> >> + // declaration of this entity. Qualified lookup for such an entity
> should
> >> + // only find this declaration if there is no visible declaration
> of it.
> >> + bool AddToContext = !D.isRedeclaration() ||
> !New->isLocalExternDecl();
> >> + PushOnScopeChains(New, S, AddToContext);
> >> + if (!AddToContext)
> >> + CurContext->addHiddenDecl(New);
> >> + }
> >>
> >> return New;
> >> }
> >> @@ -4808,6 +4828,30 @@ static bool shouldConsiderLinkage(const
> >> llvm_unreachable("Unexpected context");
> >> }
> >>
> >> +/// Adjust the \c DeclContext for a function or variable that might be
> a
> >> +/// function-local external declaration.
> >> +bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) {
> >> + if (!DC->isFunctionOrMethod())
> >> + return false;
> >> +
> >> + // If this is a local extern function or variable declared within a
> function
> >> + // template, don't add it into the enclosing namespace scope until
> it is
> >> + // instantiated; it might have a dependent type right now.
> >> + if (DC->isDependentContext())
> >> + return true;
> >> +
> >> + // C++11 [basic.link]p7:
> >> + // When a block scope declaration of an entity with linkage is not
> found to
> >> + // refer to some other declaration, then that entity is a member
> of the
> >> + // innermost enclosing namespace.
> >> + //
> >> + // Per C++11 [namespace.def]p6, the innermost enclosing namespace is
> a
> >> + // semantically-enclosing namespace, not a lexically-enclosing one.
> >> + while (!DC->isFileContext() && !isa<LinkageSpecDecl>(DC))
> >> + DC = DC->getParent();
> >> + return true;
> >> +}
> >> +
> >> NamedDecl *
> >> Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
> >> TypeSourceInfo *TInfo, LookupResult
> &Previous,
> >> @@ -4820,6 +4864,10 @@ Sema::ActOnVariableDeclarator(Scope *S,
> >> VarDecl::StorageClass SC =
> >> StorageClassSpecToVarDeclStorageClass(D.getDeclSpec());
> >>
> >> + DeclContext *OriginalDC = DC;
> >> + bool IsLocalExternDecl = SC == SC_Extern &&
> >> + adjustContextForLocalExternDecl(DC);
> >> +
> >> if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16) {
> >> // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and
> >> // half array type (unless the cl_khr_fp16 extension is enabled).
> >> @@ -5150,6 +5198,9 @@ Sema::ActOnVariableDeclarator(Scope *S,
> >> if (NewTemplate)
> >> NewTemplate->setLexicalDeclContext(CurContext);
> >>
> >> + if (IsLocalExternDecl)
> >> + NewVD->setLocalExternDecl();
> >> +
> >> if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
> {
> >> if (NewVD->hasLocalStorage()) {
> >> // C++11 [dcl.stc]p4:
> >> @@ -5277,7 +5328,7 @@ Sema::ActOnVariableDeclarator(Scope *S,
> >> // scope and are out-of-semantic-context declarations (if the new
> >> // declaration has linkage).
> >> FilterLookupForScope(
> >> - Previous, DC, S, shouldConsiderLinkage(NewVD),
> >> + Previous, OriginalDC, S, shouldConsiderLinkage(NewVD),
> >> IsExplicitSpecialization || IsVariableTemplateSpecialization);
> >>
> >> // Check whether the previous declaration is in the same block scope.
> This
> >> @@ -5286,7 +5337,7 @@ Sema::ActOnVariableDeclarator(Scope *S,
> >> NewVD->isLocalVarDecl() && NewVD->hasExternalStorage())
> >> NewVD->setPreviousDeclInSameBlockScope(
> >> Previous.isSingleResult() && !Previous.isShadowed() &&
> >> - isDeclInScope(Previous.getFoundDecl(), DC, S, false));
> >> + isDeclInScope(Previous.getFoundDecl(), OriginalDC, S, false));
> >>
> >> if (!getLangOpts().CPlusPlus) {
> >> D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
> >> @@ -5543,12 +5594,8 @@ static bool checkForConflictWithNonVisib
> >> LookupResult
> &Previous) {
> >> if (!S.getLangOpts().CPlusPlus) {
> >> // In C, when declaring a global variable, look for a corresponding
> 'extern'
> >> - // variable declared in function scope.
> >> - //
> >> - // FIXME: The corresponding case in C++ does not work. We should
> instead
> >> - // set the semantic DC for an extern local variable to be the
> innermost
> >> - // enclosing namespace, and ensure they are only found by
> redeclaration
> >> - // lookup.
> >> + // variable declared in function scope. We don't need this in C++,
> because
> >> + // we find local extern decls in the surrounding file-scope
> DeclContext.
> >> if (ND->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
> >> if (NamedDecl *Prev =
> S.findLocallyScopedExternCDecl(ND->getDeclName())) {
> >> Previous.clear();
> >> @@ -6032,6 +6079,7 @@ static NamedDecl *DiagnoseInvalidRedecla
> >> bool FDisConst = MD && MD->isConst();
> >> bool IsMember = MD || !IsLocalFriend;
> >>
> >> + // FIXME: These notes are poorly worded for the local friend case.
> >> if (unsigned Idx = NearMatch->second) {
> >> ParmVarDecl *FDParam = FD->getParamDecl(Idx-1);
> >> SourceLocation Loc = FDParam->getTypeSpecStartLoc();
> >> @@ -6455,6 +6503,9 @@ Sema::ActOnFunctionDeclarator(Scope *S,
> >>
> >> bool isVirtualOkay = false;
> >>
> >> + DeclContext *OriginalDC = DC;
> >> + bool IsLocalExternDecl = adjustContextForLocalExternDecl(DC);
> >> +
> >> FunctionDecl *NewFD = CreateNewFunctionDecl(*this, D, DC, R, TInfo, SC,
> >> isVirtualOkay);
> >> if (!NewFD) return 0;
> >> @@ -6462,6 +6513,14 @@ Sema::ActOnFunctionDeclarator(Scope *S,
> >> if (OriginalLexicalContext &&
> OriginalLexicalContext->isObjCContainer())
> >> NewFD->setTopLevelDeclInObjCContainer();
> >>
> >> + // Set the lexical context. If this is a function-scope declaration,
> or has a
> >> + // C++ scope specifier, or is the object of a friend declaration,
> the lexical
> >> + // context will be different from the semantic context.
> >> + NewFD->setLexicalDeclContext(CurContext);
> >> +
> >> + if (IsLocalExternDecl)
> >> + NewFD->setLocalExternDecl();
> >> +
> >> if (getLangOpts().CPlusPlus) {
> >> bool isInline = D.getDeclSpec().isInlineSpecified();
> >> bool isVirtual = D.getDeclSpec().isVirtualSpecified();
> >> @@ -6489,12 +6548,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,
> >> isFunctionTemplateSpecialization = false;
> >> if (D.isInvalidType())
> >> NewFD->setInvalidDecl();
> >> -
> >> - // Set the lexical context. If the declarator has a C++
> >> - // scope specifier, or is the object of a friend declaration, the
> >> - // lexical context will be different from the semantic context.
> >> - NewFD->setLexicalDeclContext(CurContext);
> >> -
> >> +
> >> // Match up the template parameter lists with the scope specifier,
> then
> >> // determine whether we have a template or a template specialization.
> >> bool Invalid = false;
> >> @@ -6750,7 +6804,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,
> >> }
> >>
> >> // Filter out previous declarations that don't match the scope.
> >> - FilterLookupForScope(Previous, DC, S, shouldConsiderLinkage(NewFD),
> >> + FilterLookupForScope(Previous, OriginalDC, S,
> shouldConsiderLinkage(NewFD),
> >> isExplicitSpecialization ||
> >> isFunctionTemplateSpecialization);
> >>
> >> @@ -9232,21 +9286,21 @@ static bool ShouldWarnAboutMissingProtot
> >> // Don't warn for OpenCL kernels.
> >> if (FD->hasAttr<OpenCLKernelAttr>())
> >> return false;
> >> -
> >> +
> >> bool MissingPrototype = true;
> >> for (const FunctionDecl *Prev = FD->getPreviousDecl();
> >> Prev; Prev = Prev->getPreviousDecl()) {
> >> // Ignore any declarations that occur in function or method
> >> // scope, because they aren't visible from the header.
> >> - if (Prev->getDeclContext()->isFunctionOrMethod())
> >> + if (Prev->getLexicalDeclContext()->isFunctionOrMethod())
> >> continue;
> >> -
> >> +
> >> MissingPrototype = !Prev->getType()->isFunctionProtoType();
> >> if (FD->getNumParams() == 0)
> >> PossibleZeroParamPrototype = Prev;
> >> break;
> >> }
> >> -
> >> +
> >> return MissingPrototype;
> >> }
> >>
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Sep 19 20:15:31 2013
> >> @@ -438,9 +438,9 @@ bool Sema::MergeCXXFunctionDecl(Function
> >> // declaration (not even to the same value).
> >> //
> >> // C++ [dcl.fct.default]p6:
> >> - // Except for member functions of class templates, the default
> arguments
> >> - // in a member function definition that appears outside of the
> class
> >> - // definition are added to the set of default arguments provided
> by the
> >> + // Except for member functions of class templates, the default
> arguments
> >> + // in a member function definition that appears outside of the
> class
> >> + // definition are added to the set of default arguments provided
> by the
> >> // member function declaration in the class definition.
> >> for (unsigned p = 0, NumParams = Old->getNumParams(); p < NumParams;
> ++p) {
> >> ParmVarDecl *OldParam = Old->getParamDecl(p);
> >> @@ -450,9 +450,18 @@ bool Sema::MergeCXXFunctionDecl(Function
> >> bool NewParamHasDfl = NewParam->hasDefaultArg();
> >>
> >> NamedDecl *ND = Old;
> >> - if (S && !isDeclInScope(ND, New->getDeclContext(), S))
> >> +
> >> + // The declaration context corresponding to the scope is the
> semantic
> >> + // parent, unless this is a local function declaration, in which
> case
> >> + // it is that surrounding function.
> >> + DeclContext *ScopeDC = New->getLexicalDeclContext();
> >> + if (!ScopeDC->isFunctionOrMethod())
> >> + ScopeDC = New->getDeclContext();
> >> + if (S && !isDeclInScope(ND, ScopeDC, S) &&
> >> + !New->getDeclContext()->isRecord())
> >> // Ignore default parameters of old decl if they are not in
> >> - // the same scope.
> >> + // the same scope and this is not an out-of-line definition of
> >> + // a member function.
> >> OldParamHasDfl = false;
> >>
> >> if (OldParamHasDfl && NewParamHasDfl) {
> >> @@ -11486,6 +11495,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl
> >> // declared the function in, if we were permitted to, for error
> recovery.
> >> DC = FunctionContainingLocalClass;
> >> }
> >> + adjustContextForLocalExternDecl(DC);
> >>
> >> // C++ [class.friend]p6:
> >> // A function can be defined in a friend declaration of a class if
> and
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Sep 19 20:15:31 2013
> >> @@ -2459,7 +2459,7 @@ bool Sema::UseArgumentDependentLookup(co
> >> // turn off ADL anyway).
> >> if (isa<UsingShadowDecl>(D))
> >> D = cast<UsingShadowDecl>(D)->getTargetDecl();
> >> - else if (D->getDeclContext()->isFunctionOrMethod())
> >> + else if (D->getLexicalDeclContext()->isFunctionOrMethod())
> >> return false;
> >>
> >> // C++0x [basic.lookup.argdep]p3:
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Sep 19 20:15:31 2013
> >> @@ -223,6 +223,8 @@ static inline unsigned getIDNS(Sema::Loo
> >> if (Redeclaration)
> >> IDNS |= Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend;
> >> }
> >> + if (Redeclaration)
> >> + IDNS |= Decl::IDNS_LocalExtern;
> >> break;
> >>
> >> case Sema::LookupOperatorName:
> >> @@ -847,6 +849,26 @@ static std::pair<DeclContext *, bool> fi
> >> return std::make_pair(Lexical, false);
> >> }
> >>
> >> +namespace {
> >> +/// An RAII object to specify that we want to find block scope extern
> >> +/// declarations.
> >> +struct FindLocalExternScope {
> >> + FindLocalExternScope(LookupResult &R)
> >> + : R(R), OldFindLocalExtern(R.getIdentifierNamespace() &
> >> + Decl::IDNS_LocalExtern) {
> >> + R.setFindLocalExtern(R.getIdentifierNamespace() &
> Decl::IDNS_Ordinary);
> >> + }
> >> + void restore() {
> >> + R.setFindLocalExtern(OldFindLocalExtern);
> >> + }
> >> + ~FindLocalExternScope() {
> >> + restore();
> >> + }
> >> + LookupResult &R;
> >> + bool OldFindLocalExtern;
> >> +};
> >> +}
> >> +
> >> bool Sema::CppLookupName(LookupResult &R, Scope *S) {
> >> assert(getLangOpts().CPlusPlus && "Can perform only C++ lookup");
> >>
> >> @@ -891,6 +913,10 @@ bool Sema::CppLookupName(LookupResult &R
> >> bool VisitedUsingDirectives = false;
> >> bool LeftStartingScope = false;
> >> DeclContext *OutsideOfTemplateParamDC = 0;
> >> +
> >> + // When performing a scope lookup, we want to find local extern
> decls.
> >> + FindLocalExternScope FindLocals(R);
> >> +
> >> for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent())
> {
> >> DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity());
> >>
> >> @@ -1046,7 +1072,12 @@ bool Sema::CppLookupName(LookupResult &R
> >> UDirs.visitScopeChain(Initial, S);
> >> UDirs.done();
> >> }
> >> -
> >> +
> >> + // If we're not performing redeclaration lookup, do not look for
> local
> >> + // extern declarations outside of a function scope.
> >> + if (!R.isForRedeclaration())
> >> + FindLocals.restore();
> >> +
> >> // Lookup namespace scope, and global scope.
> >> // Unqualified name lookup in C++ requires looking into scopes
> >> // that aren't strictly lexical, and therefore we walk through the
> >> @@ -1292,6 +1323,9 @@ bool Sema::LookupName(LookupResult &R, S
> >> S = S->getParent();
> >> }
> >>
> >> + // When performing a scope lookup, we want to find local extern
> decls.
> >> + FindLocalExternScope FindLocals(R);
> >> +
> >> // Scan up the scope chain looking for a decl that matches this
> >> // identifier that is in the appropriate namespace. This search
> >> // should not take long, as shadowing of names is uncommon, and
> >> @@ -1361,6 +1395,7 @@ bool Sema::LookupName(LookupResult &R, S
> >>
> >> R.resolveKind();
> >> }
> >> +
> >> return true;
> >> }
> >> } else {
> >> @@ -2858,7 +2893,11 @@ void Sema::ArgumentDependentLookup(Decla
> >> NamedDecl *D = *I;
> >> // If the only declaration here is an ordinary friend, consider
> >> // it only if it was declared in an associated classes.
> >> - if (D->getIdentifierNamespace() == Decl::IDNS_OrdinaryFriend) {
> >> + if ((D->getIdentifierNamespace() & Decl::IDNS_Ordinary) == 0) {
> >> + // If it's neither ordinarily visible nor a friend, we can't
> find it.
> >> + if ((D->getIdentifierNamespace() & Decl::IDNS_OrdinaryFriend)
> == 0)
> >> + continue;
> >> +
> >> bool DeclaredInAssociatedClass = false;
> >> for (Decl *DI = D; DI; DI = DI->getPreviousDecl()) {
> >> DeclContext *LexDC = DI->getLexicalDeclContext();
> >> @@ -3160,6 +3199,7 @@ static void LookupVisibleDecls(Scope *S,
> >> (!S->getParent() &&
> >> !Visited.alreadyVisitedContext((DeclContext *)S->getEntity())) ||
> >> ((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
> >> + FindLocalExternScope FindLocals(Result);
> >> // Walk through the declarations in this Scope.
> >> for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
> >> D != DEnd; ++D) {
> >>
> >> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> >> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Sep 19
> 20:15:31 2013
> >> @@ -347,8 +347,12 @@ Decl *TemplateDeclInstantiator::VisitVar
> >> return 0;
> >> }
> >>
> >> + DeclContext *DC = Owner;
> >> + if (D->isLocalExternDecl())
> >> + SemaRef.adjustContextForLocalExternDecl(DC);
> >> +
> >> // Build the instantiated declaration.
> >> - VarDecl *Var = VarDecl::Create(SemaRef.Context, Owner,
> D->getInnerLocStart(),
> >> + VarDecl *Var = VarDecl::Create(SemaRef.Context, DC,
> D->getInnerLocStart(),
> >> D->getLocation(), D->getIdentifier(),
> >> DI->getType(), DI,
> D->getStorageClass());
> >>
> >> @@ -361,7 +365,7 @@ Decl *TemplateDeclInstantiator::VisitVar
> >> if (SubstQualifier(D, Var))
> >> return 0;
> >>
> >> - SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs,
> >> + SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs,
> Owner,
> >> StartingScope,
> InstantiatingVarTemplate);
> >> return Var;
> >> }
> >> @@ -1199,11 +1203,13 @@ Decl *TemplateDeclInstantiator::VisitFun
> >> }
> >>
> >> // If we're instantiating a local function declaration, put the result
> >> - // in the owner; otherwise we need to find the instantiated context.
> >> + // in the enclosing namespace; otherwise we need to find the
> instantiated
> >> + // context.
> >> DeclContext *DC;
> >> - if (D->getDeclContext()->isFunctionOrMethod())
> >> + if (D->isLocalExternDecl()) {
> >> DC = Owner;
> >> - else if (isFriend && QualifierLoc) {
> >> + SemaRef.adjustContextForLocalExternDecl(DC);
> >> + } else if (isFriend && QualifierLoc) {
> >> CXXScopeSpec SS;
> >> SS.Adopt(QualifierLoc);
> >> DC = SemaRef.computeDeclContext(SS);
> >> @@ -1227,8 +1233,11 @@ Decl *TemplateDeclInstantiator::VisitFun
> >> if (QualifierLoc)
> >> Function->setQualifierInfo(QualifierLoc);
> >>
> >> + if (D->isLocalExternDecl())
> >> + Function->setLocalExternDecl();
> >> +
> >> DeclContext *LexicalDC = Owner;
> >> - if (!isFriend && D->isOutOfLine()) {
> >> + if (!isFriend && D->isOutOfLine() && !D->isLocalExternDecl()) {
> >> assert(D->getDeclContext()->isFileContext());
> >> LexicalDC = D->getDeclContext();
> >> }
> >> @@ -1294,8 +1303,11 @@ Decl *TemplateDeclInstantiator::VisitFun
> >>
> >> bool isExplicitSpecialization = false;
> >>
> >> - LookupResult Previous(SemaRef, Function->getDeclName(),
> SourceLocation(),
> >> - Sema::LookupOrdinaryName,
> Sema::ForRedeclaration);
> >> + LookupResult Previous(
> >> + SemaRef, Function->getDeclName(), SourceLocation(),
> >> + D->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage
> >> + : Sema::LookupOrdinaryName,
> >> + Sema::ForRedeclaration);
> >>
> >> if (DependentFunctionTemplateSpecializationInfo *Info
> >> = D->getDependentSpecializationInfo()) {
> >> @@ -1427,6 +1439,9 @@ Decl *TemplateDeclInstantiator::VisitFun
> >> }
> >> }
> >>
> >> + if (Function->isLocalExternDecl() && !Function->getPreviousDecl())
> >> + DC->makeDeclVisibleInContext(PrincipalDecl);
> >> +
> >> if (Function->isOverloadedOperator() && !DC->isRecord() &&
> >> PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
> >> PrincipalDecl->setNonMemberOperator();
> >> @@ -2358,7 +2373,7 @@ Decl *TemplateDeclInstantiator::VisitVar
> >> return 0;
> >>
> >> SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs,
> >> - StartingScope);
> >> + Owner, StartingScope);
> >>
> >> return Var;
> >> }
> >> @@ -2680,7 +2695,7 @@ TemplateDeclInstantiator::InstantiateVar
> >> if (VarDecl *Def = PartialSpec->getDefinition(SemaRef.getASTContext()))
> >> PartialSpec = cast<VarTemplatePartialSpecializationDecl>(Def);
> >> SemaRef.BuildVariableInstantiation(InstPartialSpec, PartialSpec,
> TemplateArgs,
> >> - LateAttrs, StartingScope);
> >> + LateAttrs, Owner, StartingScope);
> >> InstPartialSpec->setInit(PartialSpec->getInit());
> >>
> >> return InstPartialSpec;
> >> @@ -3335,13 +3350,19 @@ VarTemplateSpecializationDecl *Sema::Com
> >> void Sema::BuildVariableInstantiation(
> >> VarDecl *NewVar, VarDecl *OldVar,
> >> const MultiLevelTemplateArgumentList &TemplateArgs,
> >> - LateInstantiatedAttrVec *LateAttrs, LocalInstantiationScope
> *StartingScope,
> >> + LateInstantiatedAttrVec *LateAttrs, DeclContext *Owner,
> >> + LocalInstantiationScope *StartingScope,
> >> bool InstantiatingVarTemplate) {
> >>
> >> + // If we are instantiating a local extern declaration, the
> >> + // instantiation belongs lexically to the containing function.
> >> // If we are instantiating a static data member defined
> >> // out-of-line, the instantiation will have the same lexical
> >> // context (which will be a namespace scope) as the template.
> >> - if (OldVar->isOutOfLine())
> >> + if (OldVar->isLocalExternDecl()) {
> >> + NewVar->setLocalExternDecl();
> >> + NewVar->setLexicalDeclContext(Owner);
> >> + } else if (OldVar->isOutOfLine())
> >> NewVar->setLexicalDeclContext(OldVar->getLexicalDeclContext());
> >> NewVar->setTSCSpec(OldVar->getTSCSpec());
> >> NewVar->setInitStyle(OldVar->getInitStyle());
> >> @@ -3374,11 +3395,13 @@ void Sema::BuildVariableInstantiation(
> >> if (NewVar->hasAttrs())
> >> CheckAlignasUnderalignment(NewVar);
> >>
> >> - LookupResult Previous(*this, NewVar->getDeclName(),
> NewVar->getLocation(),
> >> - Sema::LookupOrdinaryName,
> Sema::ForRedeclaration);
> >> + LookupResult Previous(
> >> + *this, NewVar->getDeclName(), NewVar->getLocation(),
> >> + NewVar->isLocalExternDecl() ?
> Sema::LookupRedeclarationWithLinkage
> >> + : Sema::LookupOrdinaryName,
> >> + Sema::ForRedeclaration);
> >>
> >> - if (NewVar->getLexicalDeclContext()->isFunctionOrMethod() &&
> >> - OldVar->getPreviousDecl()) {
> >> + if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl()) {
> >> // We have a previous declaration. Use that one, so we merge with the
> >> // right type.
> >> if (NamedDecl *NewPrev = FindInstantiatedDecl(
> >> @@ -3389,13 +3412,13 @@ void Sema::BuildVariableInstantiation(
> >> LookupQualifiedName(Previous, NewVar->getDeclContext(), false);
> >> CheckVariableDeclaration(NewVar, Previous);
> >>
> >> - if (OldVar->isOutOfLine()) {
> >> - OldVar->getLexicalDeclContext()->addDecl(NewVar);
> >> - if (!InstantiatingVarTemplate)
> >> + if (!InstantiatingVarTemplate) {
> >> + NewVar->getLexicalDeclContext()->addHiddenDecl(NewVar);
> >> + if (!NewVar->isLocalExternDecl() || !NewVar->getPreviousDecl())
> >> NewVar->getDeclContext()->makeDeclVisibleInContext(NewVar);
> >> - } else {
> >> - if (!InstantiatingVarTemplate)
> >> - NewVar->getDeclContext()->addDecl(NewVar);
> >> + }
> >> +
> >> + if (!OldVar->isOutOfLine()) {
> >> if (NewVar->getDeclContext()->isFunctionOrMethod())
> >> CurrentInstantiationScope->InstantiatedLocal(OldVar, NewVar);
> >> }
> >>
> >> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
> >> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Sep 19 20:15:31
> 2013
> >> @@ -946,7 +946,13 @@ ASTDeclReader::RedeclarableResult ASTDec
> >> VD->VarDeclBits.ARCPseudoStrong = Record[Idx++];
> >> VD->VarDeclBits.IsConstexpr = Record[Idx++];
> >> VD->VarDeclBits.PreviousDeclInSameBlockScope = Record[Idx++];
> >> - VD->setCachedLinkage(Linkage(Record[Idx++]));
> >> + Linkage VarLinkage = Linkage(Record[Idx++]);
> >> + VD->setCachedLinkage(VarLinkage);
> >> +
> >> + // Reconstruct the one piece of the IdentifierNamespace that we need.
> >> + if (VarLinkage != NoLinkage &&
> >> + VD->getLexicalDeclContext()->isFunctionOrMethod())
> >> + VD->setLocalExternDecl();
> >>
> >> // Only true variables (not parameters or implicit parameters) can be
> merged.
> >> if (VD->getKind() != Decl::ParmVar && VD->getKind() !=
> Decl::ImplicitParam)
> >> @@ -2199,8 +2205,6 @@ void ASTDeclReader::attachPreviousDecl(D
> >> //
> >> // FIXME: In this case, the declaration should only be visible if a
> module
> >> // that makes it visible has been imported.
> >> - // FIXME: This is not correct in the case where previous is a local
> extern
> >> - // declaration and D is a friend declaraton.
> >> D->IdentifierNamespace |=
> >> previous->IdentifierNamespace &
> >> (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
> >>
> >> Added: cfe/trunk/test/CXX/basic/basic.link/p7.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.link/p7.cpp?rev=191064&view=auto
> >>
> ==============================================================================
> >> --- cfe/trunk/test/CXX/basic/basic.link/p7.cpp (added)
> >> +++ cfe/trunk/test/CXX/basic/basic.link/p7.cpp Thu Sep 19 20:15:31 2013
> >> @@ -0,0 +1,73 @@
> >> +// RUN: %clang_cc1 -verify -std=c++1y %s
> >> +
> >> +// Example from the standard.
> >> +namespace X {
> >> + void p() {
> >> + q(); // expected-error {{undeclared}}
> >> + extern void q();
> >> + }
> >> + void middle() {
> >> + q(); // expected-error {{undeclared}}
> >> + }
> >> + void q() { /*...*/ }
> >> + void bottom() {
> >> + q();
> >> + }
> >> +}
> >> +int q();
> >> +
> >> +namespace Test1 {
> >> + void f() {
> >> + extern int a; // expected-note {{previous}}
> >> + int g(void); // expected-note {{previous}}
> >> + }
> >> + double a; // expected-error {{different type: 'double' vs 'int'}}
> >> + double g(); // expected-error {{differ only in their return type}}
> >> +}
> >> +
> >> +namespace Test2 {
> >> + void f() {
> >> + extern int a; // expected-note {{previous}}
> >> + int g(void); // expected-note {{previous}}
> >> + }
> >> + void h() {
> >> + extern double a; // expected-error {{different type: 'double' vs
> 'int'}}
> >> + double g(void); // expected-error {{differ only in their return
> type}}
> >> + }
> >> +}
> >> +
> >> +namespace Test3 {
> >> + constexpr void (*f())() {
> >> + void h();
> >> + return &h;
> >> + }
> >> + constexpr void (*g())() {
> >> + void h();
> >> + return &h;
> >> + }
> >> + static_assert(f() == g(), "");
> >> +}
> >> +
> >> +namespace Test4 {
> >> + template<typename T>
> >> + constexpr void (*f())() {
> >> + void h();
> >> + return &h;
> >> + }
> >> + static_assert(f<int>() == f<char>(), "");
> >> + void h();
> >> + static_assert(f<int>() == &h, "");
> >> +}
> >> +
> >> +namespace Test5 {
> >> + constexpr auto f() -> void (*)() {
> >> + void g();
> >> + struct X {
> >> + friend void g();
> >> + static constexpr auto h() -> void (*)() { return g; }
> >> + };
> >> + return X::h();
> >> + }
> >> + void g();
> >> + static_assert(f() == g, "");
> >> +}
> >>
> >> Modified: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp (original)
> >> +++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp Thu Sep 19
> 20:15:31 2013
> >> @@ -61,6 +61,8 @@ namespace test6 {
> >> int x = sizeof(array); // expected-error {{invalid application of
> 'sizeof' to an incomplete type 'int []'}}
> >> }
> >> int y = sizeof(array);
> >> + extern int array[];
> >> + int z = sizeof(array);
> >> }
> >> }
> >>
> >> @@ -71,6 +73,19 @@ namespace test7 {
> >> int x = sizeof(array); // expected-error {{invalid application of
> 'sizeof' to an incomplete type 'int []'}}
> >> }
> >> int y = sizeof(array);
> >> + extern int array[];
> >> + int z = sizeof(array);
> >> +}
> >> +
> >> +namespace test8 {
> >> + extern int array[];
> >> + void test() {
> >> + extern int array[100];
> >> + int x = sizeof(array);
> >> + }
> >> + int y = sizeof(array); // expected-error {{invalid application of
> 'sizeof' to an incomplete type 'int []'}}
> >> + extern int array[];
> >> + int z = sizeof(array); // expected-error {{invalid application of
> 'sizeof' to an incomplete type 'int []'}}
> >> }
> >>
> >> namespace dependent {
> >> @@ -143,10 +158,52 @@ namespace dependent {
> >> }
> >>
> >> template<typename T> void n() {
> >> - extern T n_var;
> >> + extern T n_var; // expected-error {{redefinition of 'n_var' with a
> different type: 'double' vs 'int'}} expected-note {{previous}}
> >> + extern T n_fn(); // expected-error {{functions that differ only in
> their return type cannot be overloaded}} expected-note {{previous}}
> >> }
> >> template void n<int>();
> >> - // FIXME: Diagnose this!
> >> - float n_var;
> >> - template void n<double>();
> >> + template void n<double>(); // expected-note {{in instantiation of}}
> >> +
> >> + template<typename T> void o() {
> >> + extern T o_var; // expected-note {{previous}}
> >> + extern T o_fn(); // expected-note {{previous}}
> >> + }
> >> + template void o<int>();
> >> + float o_var; // expected-error {{redefinition of 'o_var' with a
> different type: 'float' vs 'int'}}
> >> + float o_fn(); // expected-error {{functions that differ only in
> their return type cannot be overloaded}}
> >> +
> >> + int p_var;
> >> + int p_fn();
> >> + template<typename T> void p() {
> >> + extern T p_var;
> >> + extern T p_fn();
> >> + }
> >> +}
> >> +
> >> +namespace use_outside_ns {
> >> + namespace A {
> >> + extern int a[3];
> >> + extern int b[];
> >> + extern int c[3];
> >> + void f() {
> >> + extern int a[];
> >> + extern int b[3];
> >> + }
> >> + template<typename T> void x() {
> >> + extern T c;
> >> + extern T d;
> >> + }
> >> + extern int d[3];
> >> + template void x<int[]>();
> >> + }
> >> + int w = sizeof(A::a);
> >> + int x = sizeof(A::b); // expected-error {{incomplete}}
> >> + int y = sizeof(A::c);
> >> + int z = sizeof(A::d);
> >> + namespace A {
> >> + int g() { return sizeof(a); }
> >> + int h() { return sizeof(b); } // expected-error {{incomplete}}
> >> + int i() { return sizeof(c); }
> >> + int j() { return sizeof(d); }
> >> + }
> >> }
> >>
> >> Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)
> >> +++ cfe/trunk/test/CXX/drs/dr0xx.cpp Thu Sep 19 20:15:31 2013
> >> @@ -280,7 +280,7 @@ namespace dr27 { // dr27: yes
> >>
> >> // dr28: na
> >>
> >> -namespace dr29 { // dr29: no
> >> +namespace dr29 { // dr29: 3.4
> >> void dr29_f0(); // expected-note {{here}}
> >> void g0() { void dr29_f0(); }
> >> extern "C++" void g0_cxx() { void dr29_f0(); }
> >> @@ -291,17 +291,14 @@ namespace dr29 { // dr29: no
> >> extern "C" void g1_c() { void dr29_f1(); }
> >> extern "C++" void g1_cxx() { void dr29_f1(); } // expected-error
> {{different language linkage}}
> >>
> >> - // FIXME: We should reject this.
> >> - void g2() { void dr29_f2(); }
> >> - extern "C" void dr29_f2();
> >> -
> >> - // FIXME: We should reject this.
> >> - extern "C" void g3() { void dr29_f3(); }
> >> - extern "C++" void dr29_f3();
> >> -
> >> - // FIXME: We should reject this.
> >> - extern "C++" void g4() { void dr29_f4(); }
> >> - extern "C" void dr29_f4();
> >> + void g2() { void dr29_f2(); } // expected-note {{here}}
> >> + extern "C" void dr29_f2(); // expected-error {{different language
> linkage}}
> >> +
> >> + extern "C" void g3() { void dr29_f3(); } // expected-note {{here}}
> >> + extern "C++" void dr29_f3(); // expected-error {{different language
> linkage}}
> >> +
> >> + extern "C++" void g4() { void dr29_f4(); } // expected-note {{here}}
> >> + extern "C" void dr29_f4(); // expected-error {{different language
> linkage}}
> >>
> >> extern "C" void g5();
> >> extern "C++" void dr29_f5();
> >>
> >> Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
> >> +++ cfe/trunk/test/CodeGenCXX/mangle.cpp Thu Sep 19 20:15:31 2013
> >> @@ -9,7 +9,7 @@ struct Y { };
> >> // CHECK: @_ZGVZN1N1gEvE1a = internal global
> >>
> >> //CHECK: @pr5966_i = external global
> >> -//CHECK: @_ZL8pr5966_i = internal global
> >> +//CHECK: @_ZL8pr5966_j = internal global
> >>
> >> // CHECK-LABEL: define zeroext i1 @_ZplRK1YRA100_P1X
> >> bool operator+(const Y&, X* (&xs)[100]) { return false; }
> >> @@ -314,10 +314,10 @@ void pr5966_foo() {
> >> pr5966_i = 0;
> >> }
> >>
> >> -static int pr5966_i;
> >> +static int pr5966_j;
> >>
> >> void pr5966_bar() {
> >> - pr5966_i = 0;
> >> + pr5966_j = 0;
> >> }
> >>
> >> namespace test0 {
> >> @@ -652,10 +652,10 @@ namespace test24 {
> >> foo();
> >> }
> >>
> >> - static char foo() {}
> >> + static char bar() {}
> >> void test1() {
> >> - // CHECK: call signext i8 @_ZN6test24L3fooEv()
> >> - foo();
> >> + // CHECK: call signext i8 @_ZN6test24L3barEv()
> >> + bar();
> >> }
> >> }
> >>
> >>
> >> Modified: cfe/trunk/test/Index/usrs.m
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/usrs.m?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/Index/usrs.m (original)
> >> +++ cfe/trunk/test/Index/usrs.m Thu Sep 19 20:15:31 2013
> >> @@ -118,7 +118,7 @@ int test_multi_declaration(void) {
> >> // CHECK: usrs.m c:objc(cs)Foo Extent=[34:1 - 45:2]
> >> // CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[35:1 - 39:2]
> >> // CHECK: usrs.m c:usrs.m at 402objc(cs)Foo(im)godzilla at a Extent=[36:3 -
> 36:19]
> >> -// CHECK: usrs.m c:objc(cs)Foo(im)godzilla at z Extent=[37:3 - 37:15]
> >> +// CHECK: usrs.m c:@z Extent=[37:3 - 37:15]
> >> // CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[40:1 - 43:2]
> >> // CHECK: usrs.m c:usrs.m at 470objc(cs)Foo(cm)kingkong at local_varExtent=[41:3 - 41:16]
> >> // CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[44:1 - 44:15]
> >>
> >> Modified: cfe/trunk/test/Sema/struct-decl.c
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/struct-decl.c?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/Sema/struct-decl.c (original)
> >> +++ cfe/trunk/test/Sema/struct-decl.c Thu Sep 19 20:15:31 2013
> >> @@ -57,3 +57,12 @@ const struct test2 { // expected-warning
> >> inline struct test3 { // expected-error {{'inline' can only appear on
> functions}}
> >> int x;
> >> };
> >> +
> >> +struct hiding_1 {};
> >> +struct hiding_2 {};
> >> +void test_hiding() {
> >> + struct hiding_1 *hiding_1();
> >> + extern struct hiding_2 *hiding_2;
> >> + struct hiding_1 *p = hiding_1();
> >> + struct hiding_2 *q = hiding_2;
> >> +}
> >>
> >> Modified: cfe/trunk/test/SemaCXX/blocks-1.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/blocks-1.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/SemaCXX/blocks-1.cpp (original)
> >> +++ cfe/trunk/test/SemaCXX/blocks-1.cpp Thu Sep 19 20:15:31 2013
> >> @@ -1,5 +1,4 @@
> >> -// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks -std=c++11
> >> -// expected-no-diagnostics
> >> +// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks -std=c++1y
> >>
> >> extern "C" int exit(int);
> >>
> >> @@ -57,3 +56,18 @@ namespace rdar11055105 {
> >> foo(a);
> >> };
> >> }
> >> +
> >> +namespace LocalDecls {
> >> + void f() {
> >> + (void) ^{
> >> + extern int a; // expected-note {{previous}}
> >> + extern int b(); // expected-note {{previous}}
> >> + };
> >> + }
> >> + void g() {
> >> + (void) ^{
> >> + extern float a; // expected-error {{different type}}
> >> + extern float b(); // expected-error {{cannot be overloaded}}
> >> + };
> >> + }
> >> +}
> >>
> >> Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp (original)
> >> +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp Thu Sep 19
> 20:15:31 2013
> >> @@ -36,10 +36,10 @@ namespace reference {
> >> };
> >>
> >> void call() {
> >> - void f(const int&);
> >> + one f(const int&);
> >> f({1});
> >>
> >> - void g(int&); // expected-note {{passing argument}}
> >> + one g(int&); // expected-note {{passing argument}}
> >> g({1}); // expected-error {{cannot bind to an initializer list
> temporary}}
> >> int i = 0;
> >> g({i});
> >>
> >> Modified: cfe/trunk/test/SemaCXX/extern-c.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/extern-c.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/SemaCXX/extern-c.cpp (original)
> >> +++ cfe/trunk/test/SemaCXX/extern-c.cpp Thu Sep 19 20:15:31 2013
> >> @@ -29,16 +29,27 @@ namespace test3 {
> >> }
> >> }
> >>
> >> -extern "C" {
> >> - void test4_f() {
> >> - extern int test4_b; // expected-note {{declared with C language
> linkage here}}
> >> +namespace N {
> >> + extern "C" {
> >> + void test4_f() {
> >> + extern int test4_b; // expected-note {{declared with C language
> linkage here}}
> >> + }
> >> }
> >> }
> >> static float test4_b; // expected-error {{declaration of 'test4_b' in
> global scope conflicts with declaration with C language linkage}}
> >>
> >> extern "C" {
> >> - void test5_f() {
> >> - extern int test5_b; // expected-note {{declared with C language
> linkage here}}
> >> + void test4c_f() {
> >> + extern int test4_c; // expected-note {{previous}}
> >> + }
> >> +}
> >> +static float test4_c; // expected-error {{redefinition of 'test4_c'
> with a different type: 'float' vs 'int'}}
> >> +
> >> +namespace N {
> >> + extern "C" {
> >> + void test5_f() {
> >> + extern int test5_b; // expected-note {{declared with C language
> linkage here}}
> >> + }
> >> }
> >> }
> >> extern "C" {
> >> @@ -46,6 +57,15 @@ extern "C" {
> >> }
> >>
> >> extern "C" {
> >> + void test5c_f() {
> >> + extern int test5_c; // expected-note {{previous}}
> >> + }
> >> +}
> >> +extern "C" {
> >> + static float test5_c; // expected-error {{redefinition of 'test5_c'
> with a different type: 'float' vs 'int'}}
> >> +}
> >> +
> >> +extern "C" {
> >> void f() {
> >> extern int test6_b;
> >> }
> >>
> >> Modified: cfe/trunk/test/SemaCXX/function-redecl.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/function-redecl.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/SemaCXX/function-redecl.cpp (original)
> >> +++ cfe/trunk/test/SemaCXX/function-redecl.cpp Thu Sep 19 20:15:31 2013
> >> @@ -4,17 +4,14 @@ int foo(int);
> >> namespace N {
> >> void f1() {
> >> void foo(int); // okay
> >> - void bar(int);
> >> + void bar(int); // expected-note 2{{previous declaration is here}}
> >> }
> >>
> >> void foo(int); // expected-note 2{{previous declaration is here}}
> >>
> >> void f2() {
> >> int foo(int); // expected-error {{functions that differ only in
> their return type cannot be overloaded}}
> >> - // FIXME: We should be able to diagnose the conflict between this
> >> - // declaration of 'bar' and the previous one, even though they come
> >> - // from different lexical scopes.
> >> - int bar(int); // expected-note {{previous declaration is here}}
> >> + int bar(int); // expected-error {{functions that differ only in
> their return type cannot be overloaded}}
> >> int baz(int); // expected-note {{previous declaration is here}}
> >>
> >> {
> >>
> >> Modified: cfe/trunk/test/SemaCXX/warn-unreachable.cpp
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unreachable.cpp?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/test/SemaCXX/warn-unreachable.cpp (original)
> >> +++ cfe/trunk/test/SemaCXX/warn-unreachable.cpp Thu Sep 19 20:15:31 2013
> >> @@ -62,8 +62,8 @@ void test5() {
> >> struct S {
> >> int mem;
> >> } s;
> >> - S &foor() __attribute__((noreturn));
> >> - foor()
> >> + S &foonr() __attribute__((noreturn));
> >> + foonr()
> >> .mem; // expected-warning {{will never be executed}}
> >> }
> >>
> >>
> >> Modified: cfe/trunk/www/cxx_dr_status.html
> >> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=191064&r1=191063&r2=191064&view=diff
> >>
> ==============================================================================
> >> --- cfe/trunk/www/cxx_dr_status.html (original)
> >> +++ cfe/trunk/www/cxx_dr_status.html Thu Sep 19 20:15:31 2013
> >> @@ -212,7 +212,7 @@
> >> <td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#29
> ">29</a></td>
> >> <td>CD1</td>
> >> <td>Linkage of locally declared functions</td>
> >> - <td class="none" align="center">No</td>
> >> + <td class="svn" align="center">SVN</td>
> >> </tr>
> >> <tr>
> >> <td><a href="
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#30
> ">30</a></td>
> >>
> >>
> >> _______________________________________________
> >> cfe-commits mailing list
> >> cfe-commits at cs.uiuc.edu
> >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131210/9b9f06b6/attachment.html>
More information about the cfe-commits
mailing list