<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">On Dec 10, 2013, at 7:39 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br><div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">Sorry for the delay, fixed in r197000.</div></blockquote><div><br></div>Thank you!</div><div><br><blockquote type="cite"><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Dec 10, 2013 at 6:44 PM, Argyrios Kyrtzidis <span dir="ltr"><<a href="mailto:kyrtzidis@apple.com" target="_blank">kyrtzidis@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Ping ?<br>
<div><div class="h5"><br>
On Dec 5, 2013, at 10:16 PM, Argyrios Kyrtzidis <<a href="mailto:kyrtzidis@apple.com">kyrtzidis@apple.com</a>> wrote:<br>
<br>
> Hi Richard,<br>
><br>
> This commit is causing a compiler error for the attached test case, could you look into it ?<br>
><br>
> $ clang -fsyntax-only t.cpp<br>
> t.cpp:10:27: error: 'private_struct' is a private member of 'test'<br>
>  extern int array[sizeof(private_struct)];<br>
>                          ^<br>
> t.cpp:3:10: note: declared private here<br>
>  struct private_struct {<br>
>         ^<br>
> 1 error generated.<br>
><br>
</div></div>> <t.cpp><br>
<div class="HOEnZb"><div class="h5">> On Sep 19, 2013, at 6:15 PM, Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>> wrote:<br>
><br>
>> Author: rsmith<br>
>> Date: Thu Sep 19 20:15:31 2013<br>
>> New Revision: 191064<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=191064&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=191064&view=rev</a><br>
>> Log:<br>
>> Switch the semantic DeclContext for a block-scope declaration of a function or<br>
>> variable from being the function to being the enclosing namespace scope (in<br>
>> C++) or the TU (in C). This allows us to fix a selection of related issues<br>
>> where we would build incorrect redeclaration chains for such declarations, and<br>
>> fail to notice type mismatches.<br>
>><br>
>> Such declarations are put into a new IdentifierNamespace, IDNS_LocalExtern,<br>
>> which is only found when searching scopes, and not found when searching<br>
>> DeclContexts. Such a declaration is only made visible in its DeclContext if<br>
>> there are no non-LocalExtern declarations.<br>
>><br>
>> Added:<br>
>>   cfe/trunk/test/CXX/basic/basic.link/p7.cpp<br>
>> Modified:<br>
>>   cfe/trunk/include/clang/AST/Decl.h<br>
>>   cfe/trunk/include/clang/AST/DeclBase.h<br>
>>   cfe/trunk/include/clang/Sema/Lookup.h<br>
>>   cfe/trunk/include/clang/Sema/Sema.h<br>
>>   cfe/trunk/lib/Sema/SemaAccess.cpp<br>
>>   cfe/trunk/lib/Sema/SemaCodeComplete.cpp<br>
>>   cfe/trunk/lib/Sema/SemaDecl.cpp<br>
>>   cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
>>   cfe/trunk/lib/Sema/SemaExpr.cpp<br>
>>   cfe/trunk/lib/Sema/SemaLookup.cpp<br>
>>   cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
>>   cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
>>   cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp<br>
>>   cfe/trunk/test/CXX/drs/dr0xx.cpp<br>
>>   cfe/trunk/test/CodeGenCXX/mangle.cpp<br>
>>   cfe/trunk/test/Index/usrs.m<br>
>>   cfe/trunk/test/Sema/struct-decl.c<br>
>>   cfe/trunk/test/SemaCXX/blocks-1.cpp<br>
>>   cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp<br>
>>   cfe/trunk/test/SemaCXX/extern-c.cpp<br>
>>   cfe/trunk/test/SemaCXX/function-redecl.cpp<br>
>>   cfe/trunk/test/SemaCXX/warn-unreachable.cpp<br>
>>   cfe/trunk/www/cxx_dr_status.html<br>
>><br>
>> Modified: cfe/trunk/include/clang/AST/Decl.h<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/include/clang/AST/Decl.h (original)<br>
>> +++ cfe/trunk/include/clang/AST/Decl.h Thu Sep 19 20:15:31 2013<br>
>> @@ -873,7 +873,7 @@ public:<br>
>>  bool isLocalVarDecl() const {<br>
>>    if (getKind() != Decl::Var)<br>
>>      return false;<br>
>> -    if (const DeclContext *DC = getDeclContext())<br>
>> +    if (const DeclContext *DC = getLexicalDeclContext())<br>
>>      return DC->getRedeclContext()->isFunctionOrMethod();<br>
>>    return false;<br>
>>  }<br>
>> @@ -883,7 +883,7 @@ public:<br>
>>  bool isFunctionOrMethodVarDecl() const {<br>
>>    if (getKind() != Decl::Var)<br>
>>      return false;<br>
>> -    const DeclContext *DC = getDeclContext()->getRedeclContext();<br>
>> +    const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();<br>
>>    return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;<br>
>>  }<br>
>><br>
>> @@ -959,7 +959,7 @@ public:<br>
>>    if (K == ParmVar || K == ImplicitParam)<br>
>>      return false;<br>
>><br>
>> -    if (getDeclContext()->getRedeclContext()->isFileContext())<br>
>> +    if (getLexicalDeclContext()->getRedeclContext()->isFileContext())<br>
>>      return true;<br>
>><br>
>>    if (isStaticDataMember())<br>
>> @@ -3472,10 +3472,8 @@ void Redeclarable<decl_type>::setPreviou<br>
>><br>
>>    // If the declaration was previously visible, a redeclaration of it remains<br>
>>    // visible even if it wouldn't be visible by itself.<br>
>> -    // FIXME: Once we handle local extern decls properly, this should inherit<br>
>> -    // the visibility from MostRecent, not from PrevDecl.<br>
>>    static_cast<decl_type*>(this)->IdentifierNamespace |=<br>
>> -      PrevDecl->getIdentifierNamespace() &<br>
>> +      MostRecent->getIdentifierNamespace() &<br>
>>      (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);<br>
>>  } else {<br>
>>    // Make this first.<br>
>><br>
>> Modified: cfe/trunk/include/clang/AST/DeclBase.h<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/include/clang/AST/DeclBase.h (original)<br>
>> +++ cfe/trunk/include/clang/AST/DeclBase.h Thu Sep 19 20:15:31 2013<br>
>> @@ -159,7 +159,12 @@ public:<br>
>>    /// This declaration is a C++ operator declared in a non-class<br>
>>    /// context.  All such operators are also in IDNS_Ordinary.<br>
>>    /// C++ lexical operator lookup looks for these.<br>
>> -    IDNS_NonMemberOperator   = 0x0400<br>
>> +    IDNS_NonMemberOperator   = 0x0400,<br>
>> +<br>
>> +    /// This declaration is a function-local extern declaration of a<br>
>> +    /// variable or function. This may also be IDNS_Ordinary if it<br>
>> +    /// has been declared outside any function.<br>
>> +    IDNS_LocalExtern         = 0x0800<br>
>>  };<br>
>><br>
>>  /// ObjCDeclQualifier - 'Qualifiers' written next to the return and<br>
>> @@ -829,6 +834,32 @@ public:<br>
>>  bool isFunctionOrFunctionTemplate() const;<br>
>><br>
>>  /// \brief Changes the namespace of this declaration to reflect that it's<br>
>> +  /// a function-local extern declaration.<br>
>> +  ///<br>
>> +  /// These declarations appear in the lexical context of the extern<br>
>> +  /// declaration, but in the semantic context of the enclosing namespace<br>
>> +  /// scope.<br>
>> +  void setLocalExternDecl() {<br>
>> +    assert((IdentifierNamespace == IDNS_Ordinary ||<br>
>> +            IdentifierNamespace == IDNS_OrdinaryFriend) &&<br>
>> +           "namespace is not ordinary");<br>
>> +<br>
>> +    Decl *Prev = getPreviousDecl();<br>
>> +    IdentifierNamespace &= ~IDNS_Ordinary;<br>
>> +<br>
>> +    IdentifierNamespace |= IDNS_LocalExtern;<br>
>> +    if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary)<br>
>> +      IdentifierNamespace |= IDNS_Ordinary;<br>
>> +  }<br>
>> +<br>
>> +  /// \brief Determine whether this is a block-scope declaration with linkage.<br>
>> +  /// This will either be a local variable declaration declared 'extern', or a<br>
>> +  /// local function declaration.<br>
>> +  bool isLocalExternDecl() {<br>
>> +    return IdentifierNamespace & IDNS_LocalExtern;<br>
>> +  }<br>
>> +<br>
>> +  /// \brief Changes the namespace of this declaration to reflect that it's<br>
>>  /// the object of a friend declaration.<br>
>>  ///<br>
>>  /// These declarations appear in the lexical context of the friending<br>
>> @@ -838,22 +869,25 @@ public:<br>
>>  void setObjectOfFriendDecl(bool PerformFriendInjection = false) {<br>
>>    unsigned OldNS = IdentifierNamespace;<br>
>>    assert((OldNS & (IDNS_Tag | IDNS_Ordinary |<br>
>> -                     IDNS_TagFriend | IDNS_OrdinaryFriend)) &&<br>
>> +                     IDNS_TagFriend | IDNS_OrdinaryFriend |<br>
>> +                     IDNS_LocalExtern)) &&<br>
>>           "namespace includes neither ordinary nor tag");<br>
>>    assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |<br>
>> -                       IDNS_TagFriend | IDNS_OrdinaryFriend)) &&<br>
>> +                       IDNS_TagFriend | IDNS_OrdinaryFriend |<br>
>> +                       IDNS_LocalExtern)) &&<br>
>>           "namespace includes other than ordinary or tag");<br>
>><br>
>>    Decl *Prev = getPreviousDecl();<br>
>> -    IdentifierNamespace = 0;<br>
>> +    IdentifierNamespace &= ~(IDNS_Ordinary | IDNS_Tag | IDNS_Type);<br>
>> +<br>
>>    if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {<br>
>>      IdentifierNamespace |= IDNS_TagFriend;<br>
>> -      if (PerformFriendInjection ||<br>
>> +      if (PerformFriendInjection ||<br>
>>          (Prev && Prev->getIdentifierNamespace() & IDNS_Tag))<br>
>>        IdentifierNamespace |= IDNS_Tag | IDNS_Type;<br>
>>    }<br>
>><br>
>> -    if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) {<br>
>> +    if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend | IDNS_LocalExtern)) {<br>
>>      IdentifierNamespace |= IDNS_OrdinaryFriend;<br>
>>      if (PerformFriendInjection ||<br>
>>          (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary))<br>
>><br>
>> Modified: cfe/trunk/include/clang/Sema/Lookup.h<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Lookup.h?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Lookup.h?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/include/clang/Sema/Lookup.h (original)<br>
>> +++ cfe/trunk/include/clang/Sema/Lookup.h Thu Sep 19 20:15:31 2013<br>
>> @@ -613,6 +613,13 @@ public:<br>
>>    return Filter(*this);<br>
>>  }<br>
>><br>
>> +  void setFindLocalExtern(bool FindLocalExtern) {<br>
>> +    if (FindLocalExtern)<br>
>> +      IDNS |= Decl::IDNS_LocalExtern;<br>
>> +    else<br>
>> +      IDNS &= ~Decl::IDNS_LocalExtern;<br>
>> +  }<br>
>> +<br>
>> private:<br>
>>  void diagnose() {<br>
>>    if (isAmbiguous())<br>
>><br>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
>> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Sep 19 20:15:31 2013<br>
>> @@ -1451,6 +1451,7 @@ public:<br>
>>  bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,<br>
>>                                    DeclarationName Name,<br>
>>                                    SourceLocation Loc);<br>
>> +  static bool adjustContextForLocalExternDecl(DeclContext *&DC);<br>
>>  void DiagnoseFunctionSpecifiers(const DeclSpec &DS);<br>
>>  void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);<br>
>>  void CheckShadow(Scope *S, VarDecl *D);<br>
>> @@ -6465,8 +6466,9 @@ public:<br>
>>  void<br>
>>  BuildVariableInstantiation(VarDecl *NewVar, VarDecl *OldVar,<br>
>>                             const MultiLevelTemplateArgumentList &TemplateArgs,<br>
>> -                             LateInstantiatedAttrVec *LateAttrs = 0,<br>
>> -                             LocalInstantiationScope *StartingScope = 0,<br>
>> +                             LateInstantiatedAttrVec *LateAttrs,<br>
>> +                             DeclContext *Owner,<br>
>> +                             LocalInstantiationScope *StartingScope,<br>
>>                             bool InstantiatingVarTemplate = false);<br>
>>  void InstantiateVariableInitializer(<br>
>>      VarDecl *Var, VarDecl *OldVar,<br>
>><br>
>> Modified: cfe/trunk/lib/Sema/SemaAccess.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAccess.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Sema/SemaAccess.cpp (original)<br>
>> +++ cfe/trunk/lib/Sema/SemaAccess.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -1483,7 +1483,9 @@ void Sema::HandleDelayedAccessCheck(Dela<br>
>><br>
>>  DeclContext *DC = D->getDeclContext();<br>
>>  if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {<br>
>> -    if (!DC->isFunctionOrMethod())<br>
>> +    if (D->getLexicalDeclContext()->isFunctionOrMethod())<br>
>> +      DC = D->getLexicalDeclContext();<br>
>> +    else<br>
>>      DC = FN;<br>
>>  } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {<br>
>>    DC = cast<DeclContext>(TD->getTemplatedDecl());<br>
>><br>
>> Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)<br>
>> +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -715,8 +715,8 @@ unsigned ResultBuilder::getBasePriority(<br>
>>    return CCP_Unlikely;<br>
>><br>
>>  // Context-based decisions.<br>
>> -  const DeclContext *DC = ND->getDeclContext()->getRedeclContext();<br>
>> -  if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC)) {<br>
>> +  const DeclContext *LexicalDC = ND->getLexicalDeclContext();<br>
>> +  if (LexicalDC->isFunctionOrMethod()) {<br>
>>    // _cmd is relatively rare<br>
>>    if (const ImplicitParamDecl *ImplicitParam =<br>
>>        dyn_cast<ImplicitParamDecl>(ND))<br>
>> @@ -726,6 +726,8 @@ unsigned ResultBuilder::getBasePriority(<br>
>><br>
>>    return CCP_LocalDeclaration;<br>
>>  }<br>
>> +<br>
>> +  const DeclContext *DC = ND->getDeclContext()->getRedeclContext();<br>
>>  if (DC->isRecord() || isa<ObjCContainerDecl>(DC))<br>
>>    return CCP_MemberDeclaration;<br>
>><br>
>> @@ -876,8 +878,8 @@ void ResultBuilder::MaybeAddResult(Resul<br>
>>    for (; I != IEnd; ++I) {<br>
>>      // A tag declaration does not hide a non-tag declaration.<br>
>>      if (I->first->hasTagIdentifierNamespace() &&<br>
>> -          (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |<br>
>> -                   Decl::IDNS_ObjCProtocol)))<br>
>> +          (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |<br>
>> +                   Decl::IDNS_LocalExtern | Decl::IDNS_ObjCProtocol)))<br>
>>        continue;<br>
>><br>
>>      // Protocols are in distinct namespaces from everything else.<br>
>> @@ -1038,7 +1040,9 @@ void ResultBuilder::ExitScope() {<br>
>> bool ResultBuilder::IsOrdinaryName(const NamedDecl *ND) const {<br>
>>  ND = cast<NamedDecl>(ND->getUnderlyingDecl());<br>
>><br>
>> -  unsigned IDNS = Decl::IDNS_Ordinary;<br>
>> +  // If name lookup finds a local extern declaration, then we are in a<br>
>> +  // context where it behaves like an ordinary name.<br>
>> +  unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;<br>
>>  if (SemaRef.getLangOpts().CPlusPlus)<br>
>>    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;<br>
>>  else if (SemaRef.getLangOpts().ObjC1) {<br>
>> @@ -1056,7 +1060,7 @@ bool ResultBuilder::IsOrdinaryNonTypeNam<br>
>>  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))<br>
>>    return false;<br>
>><br>
>> -  unsigned IDNS = Decl::IDNS_Ordinary;<br>
>> +  unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;<br>
>>  if (SemaRef.getLangOpts().CPlusPlus)<br>
>>    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;<br>
>>  else if (SemaRef.getLangOpts().ObjC1) {<br>
>> @@ -1083,7 +1087,7 @@ bool ResultBuilder::IsIntegralConstantVa<br>
>> bool ResultBuilder::IsOrdinaryNonValueName(const NamedDecl *ND) const {<br>
>>  ND = cast<NamedDecl>(ND->getUnderlyingDecl());<br>
>><br>
>> -  unsigned IDNS = Decl::IDNS_Ordinary;<br>
>> +  unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;<br>
>>  if (SemaRef.getLangOpts().CPlusPlus)<br>
>>    IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;<br>
>><br>
>><br>
>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -1020,12 +1020,12 @@ void Sema::PushOnScopeChains(NamedDecl *<br>
>>  if (AddToContext)<br>
>>    CurContext->addDecl(D);<br>
>><br>
>> -  // Out-of-line definitions shouldn't be pushed into scope in C++.<br>
>> -  // Out-of-line variable and function definitions shouldn't even in C.<br>
>> -  if ((getLangOpts().CPlusPlus || isa<VarDecl>(D) || isa<FunctionDecl>(D)) &&<br>
>> -      D->isOutOfLine() &&<br>
>> +  // Out-of-line definitions shouldn't be pushed into scope in C++, unless they<br>
>> +  // are function-local declarations.<br>
>> +  if (getLangOpts().CPlusPlus && D->isOutOfLine() &&<br>
>>      !D->getDeclContext()->getRedeclContext()->Equals(<br>
>> -        D->getLexicalDeclContext()->getRedeclContext()))<br>
>> +        D->getLexicalDeclContext()->getRedeclContext()) &&<br>
>> +      !D->getLexicalDeclContext()->isFunctionOrMethod())<br>
>>    return;<br>
>><br>
>>  // Template instantiations should also not be pushed into scope.<br>
>> @@ -2426,7 +2426,9 @@ bool Sema::MergeFunctionDecl(FunctionDec<br>
>>      ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>()<br>
>>      : NewType)->getResultType();<br>
>>    QualType ResQT;<br>
>> -    if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType)) {<br>
>> +    if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) &&<br>
>> +        !((NewQType->isDependentType() || OldQType->isDependentType()) &&<br>
>> +          New->isLocalExternDecl())) {<br>
>>      if (NewDeclaredReturnType->isObjCObjectPointerType() &&<br>
>>          OldDeclaredReturnType->isObjCObjectPointerType())<br>
>>        ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType);<br>
>> @@ -2578,6 +2580,14 @@ bool Sema::MergeFunctionDecl(FunctionDec<br>
>>    if (OldQTypeForComparison == NewQType)<br>
>>      return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld);<br>
>><br>
>> +    if ((NewQType->isDependentType() || OldQType->isDependentType()) &&<br>
>> +        New->isLocalExternDecl()) {<br>
>> +      // It's OK if we couldn't merge types for a local function declaraton<br>
>> +      // if either the old or new type is dependent. We'll merge the types<br>
>> +      // when we instantiate the function.<br>
>> +      return false;<br>
>> +    }<br>
>> +<br>
>>    // Fall through for conflicting redeclarations and redefinitions.<br>
>>  }<br>
>><br>
>> @@ -2710,7 +2720,7 @@ bool Sema::MergeFunctionDecl(FunctionDec<br>
>>      // local declaration will produce a hard error; if it doesn't<br>
>>      // remain visible, a single bogus local redeclaration (which is<br>
>>      // actually only a warning) could break all the downstream code.<br>
>> -      if (!New->getDeclContext()->isFunctionOrMethod())<br>
>> +      if (!New->getLexicalDeclContext()->isFunctionOrMethod())<br>
>>        New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin);<br>
>><br>
>>      return false;<br>
>> @@ -2820,18 +2830,21 @@ void Sema::MergeVarDeclTypes(VarDecl *Ne<br>
>>                              NewArray->getElementType()))<br>
>>        MergedT = New->getType();<br>
>>    } else if (Old->getType()->isArrayType() &&<br>
>> -             New->getType()->isIncompleteArrayType()) {<br>
>> +               New->getType()->isIncompleteArrayType()) {<br>
>>      const ArrayType *OldArray = Context.getAsArrayType(Old->getType());<br>
>>      const ArrayType *NewArray = Context.getAsArrayType(New->getType());<br>
>>      if (Context.hasSameType(OldArray->getElementType(),<br>
>>                              NewArray->getElementType()))<br>
>>        MergedT = Old->getType();<br>
>> -    } else if (New->getType()->isObjCObjectPointerType()<br>
>> -               && Old->getType()->isObjCObjectPointerType()) {<br>
>> -        MergedT = Context.mergeObjCGCQualifiers(New->getType(),<br>
>> -                                                        Old->getType());<br>
>> +    } else if (New->getType()->isObjCObjectPointerType() &&<br>
>> +               Old->getType()->isObjCObjectPointerType()) {<br>
>> +      MergedT = Context.mergeObjCGCQualifiers(New->getType(),<br>
>> +                                              Old->getType());<br>
>>    }<br>
>>  } else {<br>
>> +    // C 6.2.7p2:<br>
>> +    //   All declarations that refer to the same object or function shall have<br>
>> +    //   compatible type.<br>
>>    MergedT = Context.mergeTypes(New->getType(), Old->getType());<br>
>>  }<br>
>>  if (MergedT.isNull()) {<br>
>> @@ -4308,8 +4321,15 @@ NamedDecl *Sema::HandleDeclarator(Scope<br>
>>  // If this has an identifier and is not an invalid redeclaration or<br>
>>  // function template specialization, add it to the scope stack.<br>
>>  if (New->getDeclName() && AddToScope &&<br>
>> -       !(D.isRedeclaration() && New->isInvalidDecl()))<br>
>> -    PushOnScopeChains(New, S);<br>
>> +       !(D.isRedeclaration() && New->isInvalidDecl())) {<br>
>> +    // Only make a locally-scoped extern declaration visible if it is the first<br>
>> +    // declaration of this entity. Qualified lookup for such an entity should<br>
>> +    // only find this declaration if there is no visible declaration of it.<br>
>> +    bool AddToContext = !D.isRedeclaration() || !New->isLocalExternDecl();<br>
>> +    PushOnScopeChains(New, S, AddToContext);<br>
>> +    if (!AddToContext)<br>
>> +      CurContext->addHiddenDecl(New);<br>
>> +  }<br>
>><br>
>>  return New;<br>
>> }<br>
>> @@ -4808,6 +4828,30 @@ static bool shouldConsiderLinkage(const<br>
>>  llvm_unreachable("Unexpected context");<br>
>> }<br>
>><br>
>> +/// Adjust the \c DeclContext for a function or variable that might be a<br>
>> +/// function-local external declaration.<br>
>> +bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) {<br>
>> +  if (!DC->isFunctionOrMethod())<br>
>> +    return false;<br>
>> +<br>
>> +  // If this is a local extern function or variable declared within a function<br>
>> +  // template, don't add it into the enclosing namespace scope until it is<br>
>> +  // instantiated; it might have a dependent type right now.<br>
>> +  if (DC->isDependentContext())<br>
>> +    return true;<br>
>> +<br>
>> +  // C++11 [basic.link]p7:<br>
>> +  //   When a block scope declaration of an entity with linkage is not found to<br>
>> +  //   refer to some other declaration, then that entity is a member of the<br>
>> +  //   innermost enclosing namespace.<br>
>> +  //<br>
>> +  // Per C++11 [namespace.def]p6, the innermost enclosing namespace is a<br>
>> +  // semantically-enclosing namespace, not a lexically-enclosing one.<br>
>> +  while (!DC->isFileContext() && !isa<LinkageSpecDecl>(DC))<br>
>> +    DC = DC->getParent();<br>
>> +  return true;<br>
>> +}<br>
>> +<br>
>> NamedDecl *<br>
>> Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,<br>
>>                              TypeSourceInfo *TInfo, LookupResult &Previous,<br>
>> @@ -4820,6 +4864,10 @@ Sema::ActOnVariableDeclarator(Scope *S,<br>
>>  VarDecl::StorageClass SC =<br>
>>    StorageClassSpecToVarDeclStorageClass(D.getDeclSpec());<br>
>><br>
>> +  DeclContext *OriginalDC = DC;<br>
>> +  bool IsLocalExternDecl = SC == SC_Extern &&<br>
>> +                           adjustContextForLocalExternDecl(DC);<br>
>> +<br>
>>  if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16) {<br>
>>    // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and<br>
>>    // half array type (unless the cl_khr_fp16 extension is enabled).<br>
>> @@ -5150,6 +5198,9 @@ Sema::ActOnVariableDeclarator(Scope *S,<br>
>>  if (NewTemplate)<br>
>>    NewTemplate->setLexicalDeclContext(CurContext);<br>
>><br>
>> +  if (IsLocalExternDecl)<br>
>> +    NewVD->setLocalExternDecl();<br>
>> +<br>
>>  if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) {<br>
>>    if (NewVD->hasLocalStorage()) {<br>
>>      // C++11 [dcl.stc]p4:<br>
>> @@ -5277,7 +5328,7 @@ Sema::ActOnVariableDeclarator(Scope *S,<br>
>>  // scope and are out-of-semantic-context declarations (if the new<br>
>>  // declaration has linkage).<br>
>>  FilterLookupForScope(<br>
>> -      Previous, DC, S, shouldConsiderLinkage(NewVD),<br>
>> +      Previous, OriginalDC, S, shouldConsiderLinkage(NewVD),<br>
>>      IsExplicitSpecialization || IsVariableTemplateSpecialization);<br>
>><br>
>>  // Check whether the previous declaration is in the same block scope. This<br>
>> @@ -5286,7 +5337,7 @@ Sema::ActOnVariableDeclarator(Scope *S,<br>
>>      NewVD->isLocalVarDecl() && NewVD->hasExternalStorage())<br>
>>    NewVD->setPreviousDeclInSameBlockScope(<br>
>>        Previous.isSingleResult() && !Previous.isShadowed() &&<br>
>> -        isDeclInScope(Previous.getFoundDecl(), DC, S, false));<br>
>> +        isDeclInScope(Previous.getFoundDecl(), OriginalDC, S, false));<br>
>><br>
>>  if (!getLangOpts().CPlusPlus) {<br>
>>    D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));<br>
>> @@ -5543,12 +5594,8 @@ static bool checkForConflictWithNonVisib<br>
>>                                                  LookupResult &Previous) {<br>
>>  if (!S.getLangOpts().CPlusPlus) {<br>
>>    // In C, when declaring a global variable, look for a corresponding 'extern'<br>
>> -    // variable declared in function scope.<br>
>> -    //<br>
>> -    // FIXME: The corresponding case in C++ does not work.  We should instead<br>
>> -    // set the semantic DC for an extern local variable to be the innermost<br>
>> -    // enclosing namespace, and ensure they are only found by redeclaration<br>
>> -    // lookup.<br>
>> +    // variable declared in function scope. We don't need this in C++, because<br>
>> +    // we find local extern decls in the surrounding file-scope DeclContext.<br>
>>    if (ND->getDeclContext()->getRedeclContext()->isTranslationUnit()) {<br>
>>      if (NamedDecl *Prev = S.findLocallyScopedExternCDecl(ND->getDeclName())) {<br>
>>        Previous.clear();<br>
>> @@ -6032,6 +6079,7 @@ static NamedDecl *DiagnoseInvalidRedecla<br>
>>    bool FDisConst = MD && MD->isConst();<br>
>>    bool IsMember = MD || !IsLocalFriend;<br>
>><br>
>> +    // FIXME: These notes are poorly worded for the local friend case.<br>
>>    if (unsigned Idx = NearMatch->second) {<br>
>>      ParmVarDecl *FDParam = FD->getParamDecl(Idx-1);<br>
>>      SourceLocation Loc = FDParam->getTypeSpecStartLoc();<br>
>> @@ -6455,6 +6503,9 @@ Sema::ActOnFunctionDeclarator(Scope *S,<br>
>><br>
>>  bool isVirtualOkay = false;<br>
>><br>
>> +  DeclContext *OriginalDC = DC;<br>
>> +  bool IsLocalExternDecl = adjustContextForLocalExternDecl(DC);<br>
>> +<br>
>>  FunctionDecl *NewFD = CreateNewFunctionDecl(*this, D, DC, R, TInfo, SC,<br>
>>                                              isVirtualOkay);<br>
>>  if (!NewFD) return 0;<br>
>> @@ -6462,6 +6513,14 @@ Sema::ActOnFunctionDeclarator(Scope *S,<br>
>>  if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer())<br>
>>    NewFD->setTopLevelDeclInObjCContainer();<br>
>><br>
>> +  // Set the lexical context. If this is a function-scope declaration, or has a<br>
>> +  // C++ scope specifier, or is the object of a friend declaration, the lexical<br>
>> +  // context will be different from the semantic context.<br>
>> +  NewFD->setLexicalDeclContext(CurContext);<br>
>> +<br>
>> +  if (IsLocalExternDecl)<br>
>> +    NewFD->setLocalExternDecl();<br>
>> +<br>
>>  if (getLangOpts().CPlusPlus) {<br>
>>    bool isInline = D.getDeclSpec().isInlineSpecified();<br>
>>    bool isVirtual = D.getDeclSpec().isVirtualSpecified();<br>
>> @@ -6489,12 +6548,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,<br>
>>    isFunctionTemplateSpecialization = false;<br>
>>    if (D.isInvalidType())<br>
>>      NewFD->setInvalidDecl();<br>
>> -<br>
>> -    // Set the lexical context. If the declarator has a C++<br>
>> -    // scope specifier, or is the object of a friend declaration, the<br>
>> -    // lexical context will be different from the semantic context.<br>
>> -    NewFD->setLexicalDeclContext(CurContext);<br>
>> -<br>
>> +<br>
>>    // Match up the template parameter lists with the scope specifier, then<br>
>>    // determine whether we have a template or a template specialization.<br>
>>    bool Invalid = false;<br>
>> @@ -6750,7 +6804,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,<br>
>>  }<br>
>><br>
>>  // Filter out previous declarations that don't match the scope.<br>
>> -  FilterLookupForScope(Previous, DC, S, shouldConsiderLinkage(NewFD),<br>
>> +  FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewFD),<br>
>>                       isExplicitSpecialization ||<br>
>>                       isFunctionTemplateSpecialization);<br>
>><br>
>> @@ -9232,21 +9286,21 @@ static bool ShouldWarnAboutMissingProtot<br>
>>  // Don't warn for OpenCL kernels.<br>
>>  if (FD->hasAttr<OpenCLKernelAttr>())<br>
>>    return false;<br>
>> -<br>
>> +<br>
>>  bool MissingPrototype = true;<br>
>>  for (const FunctionDecl *Prev = FD->getPreviousDecl();<br>
>>       Prev; Prev = Prev->getPreviousDecl()) {<br>
>>    // Ignore any declarations that occur in function or method<br>
>>    // scope, because they aren't visible from the header.<br>
>> -    if (Prev->getDeclContext()->isFunctionOrMethod())<br>
>> +    if (Prev->getLexicalDeclContext()->isFunctionOrMethod())<br>
>>      continue;<br>
>> -<br>
>> +<br>
>>    MissingPrototype = !Prev->getType()->isFunctionProtoType();<br>
>>    if (FD->getNumParams() == 0)<br>
>>      PossibleZeroParamPrototype = Prev;<br>
>>    break;<br>
>>  }<br>
>> -<br>
>> +<br>
>>  return MissingPrototype;<br>
>> }<br>
>><br>
>><br>
>> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
>> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -438,9 +438,9 @@ bool Sema::MergeCXXFunctionDecl(Function<br>
>>  //   declaration (not even to the same value).<br>
>>  //<br>
>>  // C++ [dcl.fct.default]p6:<br>
>> -  //   Except for member functions of class templates, the default arguments<br>
>> -  //   in a member function definition that appears outside of the class<br>
>> -  //   definition are added to the set of default arguments provided by the<br>
>> +  //   Except for member functions of class templates, the default arguments<br>
>> +  //   in a member function definition that appears outside of the class<br>
>> +  //   definition are added to the set of default arguments provided by the<br>
>>  //   member function declaration in the class definition.<br>
>>  for (unsigned p = 0, NumParams = Old->getNumParams(); p < NumParams; ++p) {<br>
>>    ParmVarDecl *OldParam = Old->getParamDecl(p);<br>
>> @@ -450,9 +450,18 @@ bool Sema::MergeCXXFunctionDecl(Function<br>
>>    bool NewParamHasDfl = NewParam->hasDefaultArg();<br>
>><br>
>>    NamedDecl *ND = Old;<br>
>> -    if (S && !isDeclInScope(ND, New->getDeclContext(), S))<br>
>> +<br>
>> +    // The declaration context corresponding to the scope is the semantic<br>
>> +    // parent, unless this is a local function declaration, in which case<br>
>> +    // it is that surrounding function.<br>
>> +    DeclContext *ScopeDC = New->getLexicalDeclContext();<br>
>> +    if (!ScopeDC->isFunctionOrMethod())<br>
>> +      ScopeDC = New->getDeclContext();<br>
>> +    if (S && !isDeclInScope(ND, ScopeDC, S) &&<br>
>> +        !New->getDeclContext()->isRecord())<br>
>>      // Ignore default parameters of old decl if they are not in<br>
>> -      // the same scope.<br>
>> +      // the same scope and this is not an out-of-line definition of<br>
>> +      // a member function.<br>
>>      OldParamHasDfl = false;<br>
>><br>
>>    if (OldParamHasDfl && NewParamHasDfl) {<br>
>> @@ -11486,6 +11495,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl<br>
>>      // declared the function in, if we were permitted to, for error recovery.<br>
>>      DC = FunctionContainingLocalClass;<br>
>>    }<br>
>> +    adjustContextForLocalExternDecl(DC);<br>
>><br>
>>    // C++ [class.friend]p6:<br>
>>    //   A function can be defined in a friend declaration of a class if and<br>
>><br>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -2459,7 +2459,7 @@ bool Sema::UseArgumentDependentLookup(co<br>
>>    // turn off ADL anyway).<br>
>>    if (isa<UsingShadowDecl>(D))<br>
>>      D = cast<UsingShadowDecl>(D)->getTargetDecl();<br>
>> -    else if (D->getDeclContext()->isFunctionOrMethod())<br>
>> +    else if (D->getLexicalDeclContext()->isFunctionOrMethod())<br>
>>      return false;<br>
>><br>
>>    // C++0x [basic.lookup.argdep]p3:<br>
>><br>
>> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)<br>
>> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -223,6 +223,8 @@ static inline unsigned getIDNS(Sema::Loo<br>
>>      if (Redeclaration)<br>
>>        IDNS |= Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend;<br>
>>    }<br>
>> +    if (Redeclaration)<br>
>> +      IDNS |= Decl::IDNS_LocalExtern;<br>
>>    break;<br>
>><br>
>>  case Sema::LookupOperatorName:<br>
>> @@ -847,6 +849,26 @@ static std::pair<DeclContext *, bool> fi<br>
>>  return std::make_pair(Lexical, false);<br>
>> }<br>
>><br>
>> +namespace {<br>
>> +/// An RAII object to specify that we want to find block scope extern<br>
>> +/// declarations.<br>
>> +struct FindLocalExternScope {<br>
>> +  FindLocalExternScope(LookupResult &R)<br>
>> +      : R(R), OldFindLocalExtern(R.getIdentifierNamespace() &<br>
>> +                                 Decl::IDNS_LocalExtern) {<br>
>> +    R.setFindLocalExtern(R.getIdentifierNamespace() & Decl::IDNS_Ordinary);<br>
>> +  }<br>
>> +  void restore() {<br>
>> +    R.setFindLocalExtern(OldFindLocalExtern);<br>
>> +  }<br>
>> +  ~FindLocalExternScope() {<br>
>> +    restore();<br>
>> +  }<br>
>> +  LookupResult &R;<br>
>> +  bool OldFindLocalExtern;<br>
>> +};<br>
>> +}<br>
>> +<br>
>> bool Sema::CppLookupName(LookupResult &R, Scope *S) {<br>
>>  assert(getLangOpts().CPlusPlus && "Can perform only C++ lookup");<br>
>><br>
>> @@ -891,6 +913,10 @@ bool Sema::CppLookupName(LookupResult &R<br>
>>  bool VisitedUsingDirectives = false;<br>
>>  bool LeftStartingScope = false;<br>
>>  DeclContext *OutsideOfTemplateParamDC = 0;<br>
>> +<br>
>> +  // When performing a scope lookup, we want to find local extern decls.<br>
>> +  FindLocalExternScope FindLocals(R);<br>
>> +<br>
>>  for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) {<br>
>>    DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity());<br>
>><br>
>> @@ -1046,7 +1072,12 @@ bool Sema::CppLookupName(LookupResult &R<br>
>>    UDirs.visitScopeChain(Initial, S);<br>
>>    UDirs.done();<br>
>>  }<br>
>> -<br>
>> +<br>
>> +  // If we're not performing redeclaration lookup, do not look for local<br>
>> +  // extern declarations outside of a function scope.<br>
>> +  if (!R.isForRedeclaration())<br>
>> +    FindLocals.restore();<br>
>> +<br>
>>  // Lookup namespace scope, and global scope.<br>
>>  // Unqualified name lookup in C++ requires looking into scopes<br>
>>  // that aren't strictly lexical, and therefore we walk through the<br>
>> @@ -1292,6 +1323,9 @@ bool Sema::LookupName(LookupResult &R, S<br>
>>        S = S->getParent();<br>
>>    }<br>
>><br>
>> +    // When performing a scope lookup, we want to find local extern decls.<br>
>> +    FindLocalExternScope FindLocals(R);<br>
>> +<br>
>>    // Scan up the scope chain looking for a decl that matches this<br>
>>    // identifier that is in the appropriate namespace.  This search<br>
>>    // should not take long, as shadowing of names is uncommon, and<br>
>> @@ -1361,6 +1395,7 @@ bool Sema::LookupName(LookupResult &R, S<br>
>><br>
>>          R.resolveKind();<br>
>>        }<br>
>> +<br>
>>        return true;<br>
>>      }<br>
>>  } else {<br>
>> @@ -2858,7 +2893,11 @@ void Sema::ArgumentDependentLookup(Decla<br>
>>      NamedDecl *D = *I;<br>
>>      // If the only declaration here is an ordinary friend, consider<br>
>>      // it only if it was declared in an associated classes.<br>
>> -      if (D->getIdentifierNamespace() == Decl::IDNS_OrdinaryFriend) {<br>
>> +      if ((D->getIdentifierNamespace() & Decl::IDNS_Ordinary) == 0) {<br>
>> +        // If it's neither ordinarily visible nor a friend, we can't find it.<br>
>> +        if ((D->getIdentifierNamespace() & Decl::IDNS_OrdinaryFriend) == 0)<br>
>> +          continue;<br>
>> +<br>
>>        bool DeclaredInAssociatedClass = false;<br>
>>        for (Decl *DI = D; DI; DI = DI->getPreviousDecl()) {<br>
>>          DeclContext *LexDC = DI->getLexicalDeclContext();<br>
>> @@ -3160,6 +3199,7 @@ static void LookupVisibleDecls(Scope *S,<br>
>>      (!S->getParent() &&<br>
>>       !Visited.alreadyVisitedContext((DeclContext *)S->getEntity())) ||<br>
>>      ((DeclContext *)S->getEntity())->isFunctionOrMethod()) {<br>
>> +    FindLocalExternScope FindLocals(Result);<br>
>>    // Walk through the declarations in this Scope.<br>
>>    for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();<br>
>>         D != DEnd; ++D) {<br>
>><br>
>> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)<br>
>> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -347,8 +347,12 @@ Decl *TemplateDeclInstantiator::VisitVar<br>
>>    return 0;<br>
>>  }<br>
>><br>
>> +  DeclContext *DC = Owner;<br>
>> +  if (D->isLocalExternDecl())<br>
>> +    SemaRef.adjustContextForLocalExternDecl(DC);<br>
>> +<br>
>>  // Build the instantiated declaration.<br>
>> -  VarDecl *Var = VarDecl::Create(SemaRef.Context, Owner, D->getInnerLocStart(),<br>
>> +  VarDecl *Var = VarDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),<br>
>>                                 D->getLocation(), D->getIdentifier(),<br>
>>                                 DI->getType(), DI, D->getStorageClass());<br>
>><br>
>> @@ -361,7 +365,7 @@ Decl *TemplateDeclInstantiator::VisitVar<br>
>>  if (SubstQualifier(D, Var))<br>
>>    return 0;<br>
>><br>
>> -  SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs,<br>
>> +  SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner,<br>
>>                                     StartingScope, InstantiatingVarTemplate);<br>
>>  return Var;<br>
>> }<br>
>> @@ -1199,11 +1203,13 @@ Decl *TemplateDeclInstantiator::VisitFun<br>
>>  }<br>
>><br>
>>  // If we're instantiating a local function declaration, put the result<br>
>> -  // in the owner;  otherwise we need to find the instantiated context.<br>
>> +  // in the enclosing namespace; otherwise we need to find the instantiated<br>
>> +  // context.<br>
>>  DeclContext *DC;<br>
>> -  if (D->getDeclContext()->isFunctionOrMethod())<br>
>> +  if (D->isLocalExternDecl()) {<br>
>>    DC = Owner;<br>
>> -  else if (isFriend && QualifierLoc) {<br>
>> +    SemaRef.adjustContextForLocalExternDecl(DC);<br>
>> +  } else if (isFriend && QualifierLoc) {<br>
>>    CXXScopeSpec SS;<br>
>>    SS.Adopt(QualifierLoc);<br>
>>    DC = SemaRef.computeDeclContext(SS);<br>
>> @@ -1227,8 +1233,11 @@ Decl *TemplateDeclInstantiator::VisitFun<br>
>>  if (QualifierLoc)<br>
>>    Function->setQualifierInfo(QualifierLoc);<br>
>><br>
>> +  if (D->isLocalExternDecl())<br>
>> +    Function->setLocalExternDecl();<br>
>> +<br>
>>  DeclContext *LexicalDC = Owner;<br>
>> -  if (!isFriend && D->isOutOfLine()) {<br>
>> +  if (!isFriend && D->isOutOfLine() && !D->isLocalExternDecl()) {<br>
>>    assert(D->getDeclContext()->isFileContext());<br>
>>    LexicalDC = D->getDeclContext();<br>
>>  }<br>
>> @@ -1294,8 +1303,11 @@ Decl *TemplateDeclInstantiator::VisitFun<br>
>><br>
>>  bool isExplicitSpecialization = false;<br>
>><br>
>> -  LookupResult Previous(SemaRef, Function->getDeclName(), SourceLocation(),<br>
>> -                        Sema::LookupOrdinaryName, Sema::ForRedeclaration);<br>
>> +  LookupResult Previous(<br>
>> +      SemaRef, Function->getDeclName(), SourceLocation(),<br>
>> +      D->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage<br>
>> +                             : Sema::LookupOrdinaryName,<br>
>> +      Sema::ForRedeclaration);<br>
>><br>
>>  if (DependentFunctionTemplateSpecializationInfo *Info<br>
>>        = D->getDependentSpecializationInfo()) {<br>
>> @@ -1427,6 +1439,9 @@ Decl *TemplateDeclInstantiator::VisitFun<br>
>>    }<br>
>>  }<br>
>><br>
>> +  if (Function->isLocalExternDecl() && !Function->getPreviousDecl())<br>
>> +    DC->makeDeclVisibleInContext(PrincipalDecl);<br>
>> +<br>
>>  if (Function->isOverloadedOperator() && !DC->isRecord() &&<br>
>>      PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))<br>
>>    PrincipalDecl->setNonMemberOperator();<br>
>> @@ -2358,7 +2373,7 @@ Decl *TemplateDeclInstantiator::VisitVar<br>
>>    return 0;<br>
>><br>
>>  SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs,<br>
>> -                                     StartingScope);<br>
>> +                                     Owner, StartingScope);<br>
>><br>
>>  return Var;<br>
>> }<br>
>> @@ -2680,7 +2695,7 @@ TemplateDeclInstantiator::InstantiateVar<br>
>>  if (VarDecl *Def = PartialSpec->getDefinition(SemaRef.getASTContext()))<br>
>>    PartialSpec = cast<VarTemplatePartialSpecializationDecl>(Def);<br>
>>  SemaRef.BuildVariableInstantiation(InstPartialSpec, PartialSpec, TemplateArgs,<br>
>> -                                     LateAttrs, StartingScope);<br>
>> +                                     LateAttrs, Owner, StartingScope);<br>
>>  InstPartialSpec->setInit(PartialSpec->getInit());<br>
>><br>
>>  return InstPartialSpec;<br>
>> @@ -3335,13 +3350,19 @@ VarTemplateSpecializationDecl *Sema::Com<br>
>> void Sema::BuildVariableInstantiation(<br>
>>    VarDecl *NewVar, VarDecl *OldVar,<br>
>>    const MultiLevelTemplateArgumentList &TemplateArgs,<br>
>> -    LateInstantiatedAttrVec *LateAttrs, LocalInstantiationScope *StartingScope,<br>
>> +    LateInstantiatedAttrVec *LateAttrs, DeclContext *Owner,<br>
>> +    LocalInstantiationScope *StartingScope,<br>
>>    bool InstantiatingVarTemplate) {<br>
>><br>
>> +  // If we are instantiating a local extern declaration, the<br>
>> +  // instantiation belongs lexically to the containing function.<br>
>>  // If we are instantiating a static data member defined<br>
>>  // out-of-line, the instantiation will have the same lexical<br>
>>  // context (which will be a namespace scope) as the template.<br>
>> -  if (OldVar->isOutOfLine())<br>
>> +  if (OldVar->isLocalExternDecl()) {<br>
>> +    NewVar->setLocalExternDecl();<br>
>> +    NewVar->setLexicalDeclContext(Owner);<br>
>> +  } else if (OldVar->isOutOfLine())<br>
>>    NewVar->setLexicalDeclContext(OldVar->getLexicalDeclContext());<br>
>>  NewVar->setTSCSpec(OldVar->getTSCSpec());<br>
>>  NewVar->setInitStyle(OldVar->getInitStyle());<br>
>> @@ -3374,11 +3395,13 @@ void Sema::BuildVariableInstantiation(<br>
>>  if (NewVar->hasAttrs())<br>
>>    CheckAlignasUnderalignment(NewVar);<br>
>><br>
>> -  LookupResult Previous(*this, NewVar->getDeclName(), NewVar->getLocation(),<br>
>> -                        Sema::LookupOrdinaryName, Sema::ForRedeclaration);<br>
>> +  LookupResult Previous(<br>
>> +      *this, NewVar->getDeclName(), NewVar->getLocation(),<br>
>> +      NewVar->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage<br>
>> +                                  : Sema::LookupOrdinaryName,<br>
>> +      Sema::ForRedeclaration);<br>
>><br>
>> -  if (NewVar->getLexicalDeclContext()->isFunctionOrMethod() &&<br>
>> -      OldVar->getPreviousDecl()) {<br>
>> +  if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl()) {<br>
>>    // We have a previous declaration. Use that one, so we merge with the<br>
>>    // right type.<br>
>>    if (NamedDecl *NewPrev = FindInstantiatedDecl(<br>
>> @@ -3389,13 +3412,13 @@ void Sema::BuildVariableInstantiation(<br>
>>    LookupQualifiedName(Previous, NewVar->getDeclContext(), false);<br>
>>  CheckVariableDeclaration(NewVar, Previous);<br>
>><br>
>> -  if (OldVar->isOutOfLine()) {<br>
>> -    OldVar->getLexicalDeclContext()->addDecl(NewVar);<br>
>> -    if (!InstantiatingVarTemplate)<br>
>> +  if (!InstantiatingVarTemplate) {<br>
>> +    NewVar->getLexicalDeclContext()->addHiddenDecl(NewVar);<br>
>> +    if (!NewVar->isLocalExternDecl() || !NewVar->getPreviousDecl())<br>
>>      NewVar->getDeclContext()->makeDeclVisibleInContext(NewVar);<br>
>> -  } else {<br>
>> -    if (!InstantiatingVarTemplate)<br>
>> -      NewVar->getDeclContext()->addDecl(NewVar);<br>
>> +  }<br>
>> +<br>
>> +  if (!OldVar->isOutOfLine()) {<br>
>>    if (NewVar->getDeclContext()->isFunctionOrMethod())<br>
>>      CurrentInstantiationScope->InstantiatedLocal(OldVar, NewVar);<br>
>>  }<br>
>><br>
>> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)<br>
>> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -946,7 +946,13 @@ ASTDeclReader::RedeclarableResult ASTDec<br>
>>  VD->VarDeclBits.ARCPseudoStrong = Record[Idx++];<br>
>>  VD->VarDeclBits.IsConstexpr = Record[Idx++];<br>
>>  VD->VarDeclBits.PreviousDeclInSameBlockScope = Record[Idx++];<br>
>> -  VD->setCachedLinkage(Linkage(Record[Idx++]));<br>
>> +  Linkage VarLinkage = Linkage(Record[Idx++]);<br>
>> +  VD->setCachedLinkage(VarLinkage);<br>
>> +<br>
>> +  // Reconstruct the one piece of the IdentifierNamespace that we need.<br>
>> +  if (VarLinkage != NoLinkage &&<br>
>> +      VD->getLexicalDeclContext()->isFunctionOrMethod())<br>
>> +    VD->setLocalExternDecl();<br>
>><br>
>>  // Only true variables (not parameters or implicit parameters) can be merged.<br>
>>  if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam)<br>
>> @@ -2199,8 +2205,6 @@ void ASTDeclReader::attachPreviousDecl(D<br>
>>  //<br>
>>  // FIXME: In this case, the declaration should only be visible if a module<br>
>>  //        that makes it visible has been imported.<br>
>> -  // FIXME: This is not correct in the case where previous is a local extern<br>
>> -  //        declaration and D is a friend declaraton.<br>
>>  D->IdentifierNamespace |=<br>
>>      previous->IdentifierNamespace &<br>
>>      (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);<br>
>><br>
>> Added: cfe/trunk/test/CXX/basic/basic.link/p7.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.link/p7.cpp?rev=191064&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.link/p7.cpp?rev=191064&view=auto</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/CXX/basic/basic.link/p7.cpp (added)<br>
>> +++ cfe/trunk/test/CXX/basic/basic.link/p7.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -0,0 +1,73 @@<br>
>> +// RUN: %clang_cc1 -verify -std=c++1y %s<br>
>> +<br>
>> +// Example from the standard.<br>
>> +namespace X {<br>
>> +  void p() {<br>
>> +    q(); // expected-error {{undeclared}}<br>
>> +    extern void q();<br>
>> +  }<br>
>> +  void middle() {<br>
>> +    q(); // expected-error {{undeclared}}<br>
>> +  }<br>
>> +  void q() { /*...*/ }<br>
>> +  void bottom() {<br>
>> +    q();<br>
>> +  }<br>
>> +}<br>
>> +int q();<br>
>> +<br>
>> +namespace Test1 {<br>
>> +  void f() {<br>
>> +    extern int a; // expected-note {{previous}}<br>
>> +    int g(void); // expected-note {{previous}}<br>
>> +  }<br>
>> +  double a; // expected-error {{different type: 'double' vs 'int'}}<br>
>> +  double g(); // expected-error {{differ only in their return type}}<br>
>> +}<br>
>> +<br>
>> +namespace Test2 {<br>
>> +  void f() {<br>
>> +    extern int a; // expected-note {{previous}}<br>
>> +    int g(void); // expected-note {{previous}}<br>
>> +  }<br>
>> +  void h() {<br>
>> +    extern double a; // expected-error {{different type: 'double' vs 'int'}}<br>
>> +    double g(void); // expected-error {{differ only in their return type}}<br>
>> +  }<br>
>> +}<br>
>> +<br>
>> +namespace Test3 {<br>
>> +  constexpr void (*f())() {<br>
>> +    void h();<br>
>> +    return &h;<br>
>> +  }<br>
>> +  constexpr void (*g())() {<br>
>> +    void h();<br>
>> +    return &h;<br>
>> +  }<br>
>> +  static_assert(f() == g(), "");<br>
>> +}<br>
>> +<br>
>> +namespace Test4 {<br>
>> +  template<typename T><br>
>> +  constexpr void (*f())() {<br>
>> +    void h();<br>
>> +    return &h;<br>
>> +  }<br>
>> +  static_assert(f<int>() == f<char>(), "");<br>
>> +  void h();<br>
>> +  static_assert(f<int>() == &h, "");<br>
>> +}<br>
>> +<br>
>> +namespace Test5 {<br>
>> +  constexpr auto f() -> void (*)() {<br>
>> +    void g();<br>
>> +    struct X {<br>
>> +      friend void g();<br>
>> +      static constexpr auto h() -> void (*)() { return g; }<br>
>> +    };<br>
>> +    return X::h();<br>
>> +  }<br>
>> +  void g();<br>
>> +  static_assert(f() == g, "");<br>
>> +}<br>
>><br>
>> Modified: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp<br>
>> URL: <a href="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" target="_blank">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</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp (original)<br>
>> +++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/dcl.array/p3.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -61,6 +61,8 @@ namespace test6 {<br>
>>      int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}<br>
>>    }<br>
>>    int y = sizeof(array);<br>
>> +    extern int array[];<br>
>> +    int z = sizeof(array);<br>
>>  }<br>
>> }<br>
>><br>
>> @@ -71,6 +73,19 @@ namespace test7 {<br>
>>    int x = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}<br>
>>  }<br>
>>  int y = sizeof(array);<br>
>> +  extern int array[];<br>
>> +  int z = sizeof(array);<br>
>> +}<br>
>> +<br>
>> +namespace test8 {<br>
>> +  extern int array[];<br>
>> +  void test() {<br>
>> +    extern int array[100];<br>
>> +    int x = sizeof(array);<br>
>> +  }<br>
>> +  int y = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}<br>
>> +  extern int array[];<br>
>> +  int z = sizeof(array); // expected-error {{invalid application of 'sizeof' to an incomplete type 'int []'}}<br>
>> }<br>
>><br>
>> namespace dependent {<br>
>> @@ -143,10 +158,52 @@ namespace dependent {<br>
>>  }<br>
>><br>
>>  template<typename T> void n() {<br>
>> -    extern T n_var;<br>
>> +    extern T n_var; // expected-error {{redefinition of 'n_var' with a different type: 'double' vs 'int'}} expected-note {{previous}}<br>
>> +    extern T n_fn(); // expected-error {{functions that differ only in their return type cannot be overloaded}} expected-note {{previous}}<br>
>>  }<br>
>>  template void n<int>();<br>
>> -  // FIXME: Diagnose this!<br>
>> -  float n_var;<br>
>> -  template void n<double>();<br>
>> +  template void n<double>(); // expected-note {{in instantiation of}}<br>
>> +<br>
>> +  template<typename T> void o() {<br>
>> +    extern T o_var; // expected-note {{previous}}<br>
>> +    extern T o_fn(); // expected-note {{previous}}<br>
>> +  }<br>
>> +  template void o<int>();<br>
>> +  float o_var; // expected-error {{redefinition of 'o_var' with a different type: 'float' vs 'int'}}<br>
>> +  float o_fn(); // expected-error {{functions that differ only in their return type cannot be overloaded}}<br>
>> +<br>
>> +  int p_var;<br>
>> +  int p_fn();<br>
>> +  template<typename T> void p() {<br>
>> +    extern T p_var;<br>
>> +    extern T p_fn();<br>
>> +  }<br>
>> +}<br>
>> +<br>
>> +namespace use_outside_ns {<br>
>> +  namespace A {<br>
>> +    extern int a[3];<br>
>> +    extern int b[];<br>
>> +    extern int c[3];<br>
>> +    void f() {<br>
>> +      extern int a[];<br>
>> +      extern int b[3];<br>
>> +    }<br>
>> +    template<typename T> void x() {<br>
>> +      extern T c;<br>
>> +      extern T d;<br>
>> +    }<br>
>> +    extern int d[3];<br>
>> +    template void x<int[]>();<br>
>> +  }<br>
>> +  int w = sizeof(A::a);<br>
>> +  int x = sizeof(A::b); // expected-error {{incomplete}}<br>
>> +  int y = sizeof(A::c);<br>
>> +  int z = sizeof(A::d);<br>
>> +  namespace A {<br>
>> +    int g() { return sizeof(a); }<br>
>> +    int h() { return sizeof(b); } // expected-error {{incomplete}}<br>
>> +    int i() { return sizeof(c); }<br>
>> +    int j() { return sizeof(d); }<br>
>> +  }<br>
>> }<br>
>><br>
>> Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)<br>
>> +++ cfe/trunk/test/CXX/drs/dr0xx.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -280,7 +280,7 @@ namespace dr27 { // dr27: yes<br>
>><br>
>> // dr28: na<br>
>><br>
>> -namespace dr29 { // dr29: no<br>
>> +namespace dr29 { // dr29: 3.4<br>
>>  void dr29_f0(); // expected-note {{here}}<br>
>>  void g0() { void dr29_f0(); }<br>
>>  extern "C++" void g0_cxx() { void dr29_f0(); }<br>
>> @@ -291,17 +291,14 @@ namespace dr29 { // dr29: no<br>
>>  extern "C" void g1_c() { void dr29_f1(); }<br>
>>  extern "C++" void g1_cxx() { void dr29_f1(); } // expected-error {{different language linkage}}<br>
>><br>
>> -  // FIXME: We should reject this.<br>
>> -  void g2() { void dr29_f2(); }<br>
>> -  extern "C" void dr29_f2();<br>
>> -<br>
>> -  // FIXME: We should reject this.<br>
>> -  extern "C" void g3() { void dr29_f3(); }<br>
>> -  extern "C++" void dr29_f3();<br>
>> -<br>
>> -  // FIXME: We should reject this.<br>
>> -  extern "C++" void g4() { void dr29_f4(); }<br>
>> -  extern "C" void dr29_f4();<br>
>> +  void g2() { void dr29_f2(); } // expected-note {{here}}<br>
>> +  extern "C" void dr29_f2(); // expected-error {{different language linkage}}<br>
>> +<br>
>> +  extern "C" void g3() { void dr29_f3(); } // expected-note {{here}}<br>
>> +  extern "C++" void dr29_f3(); // expected-error {{different language linkage}}<br>
>> +<br>
>> +  extern "C++" void g4() { void dr29_f4(); } // expected-note {{here}}<br>
>> +  extern "C" void dr29_f4(); // expected-error {{different language linkage}}<br>
>><br>
>>  extern "C" void g5();<br>
>>  extern "C++" void dr29_f5();<br>
>><br>
>> Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)<br>
>> +++ cfe/trunk/test/CodeGenCXX/mangle.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -9,7 +9,7 @@ struct Y { };<br>
>> // CHECK: @_ZGVZN1N1gEvE1a = internal global<br>
>><br>
>> //CHECK: @pr5966_i = external global<br>
>> -//CHECK: @_ZL8pr5966_i = internal global<br>
>> +//CHECK: @_ZL8pr5966_j = internal global<br>
>><br>
>> // CHECK-LABEL: define zeroext i1 @_ZplRK1YRA100_P1X<br>
>> bool operator+(const Y&, X* (&xs)[100]) { return false; }<br>
>> @@ -314,10 +314,10 @@ void pr5966_foo() {<br>
>>  pr5966_i = 0;<br>
>> }<br>
>><br>
>> -static int pr5966_i;<br>
>> +static int pr5966_j;<br>
>><br>
>> void pr5966_bar() {<br>
>> -  pr5966_i = 0;<br>
>> +  pr5966_j = 0;<br>
>> }<br>
>><br>
>> namespace test0 {<br>
>> @@ -652,10 +652,10 @@ namespace test24 {<br>
>>    foo();<br>
>>  }<br>
>><br>
>> -  static char foo() {}<br>
>> +  static char bar() {}<br>
>>  void test1() {<br>
>> -    // CHECK: call signext i8 @_ZN6test24L3fooEv()<br>
>> -    foo();<br>
>> +    // CHECK: call signext i8 @_ZN6test24L3barEv()<br>
>> +    bar();<br>
>>  }<br>
>> }<br>
>><br>
>><br>
>> Modified: cfe/trunk/test/Index/usrs.m<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/usrs.m?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/usrs.m?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/Index/usrs.m (original)<br>
>> +++ cfe/trunk/test/Index/usrs.m Thu Sep 19 20:15:31 2013<br>
>> @@ -118,7 +118,7 @@ int test_multi_declaration(void) {<br>
>> // CHECK: usrs.m c:objc(cs)Foo Extent=[34:1 - 45:2]<br>
>> // CHECK: usrs.m c:objc(cs)Foo(im)godzilla Extent=[35:1 - 39:2]<br>
>> // CHECK: usrs.m c:usrs.m@402objc(cs)Foo(im)godzilla@a Extent=[36:3 - 36:19]<br>
>> -// CHECK: usrs.m c:objc(cs)Foo(im)godzilla@z Extent=[37:3 - 37:15]<br>
>> +// CHECK: usrs.m c:@z Extent=[37:3 - 37:15]<br>
>> // CHECK: usrs.m c:objc(cs)Foo(cm)kingkong Extent=[40:1 - 43:2]<br>
>> // CHECK: usrs.m c:usrs.m@470objc(cs)Foo(cm)kingkong@local_var Extent=[41:3 - 41:16]<br>
>> // CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[44:1 - 44:15]<br>
>><br>
>> Modified: cfe/trunk/test/Sema/struct-decl.c<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/struct-decl.c?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/struct-decl.c?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/Sema/struct-decl.c (original)<br>
>> +++ cfe/trunk/test/Sema/struct-decl.c Thu Sep 19 20:15:31 2013<br>
>> @@ -57,3 +57,12 @@ const struct test2 { // expected-warning<br>
>> inline struct test3 { // expected-error {{'inline' can only appear on functions}}<br>
>>  int x;<br>
>> };<br>
>> +<br>
>> +struct hiding_1 {};<br>
>> +struct hiding_2 {};<br>
>> +void test_hiding() {<br>
>> +  struct hiding_1 *hiding_1();<br>
>> +  extern struct hiding_2 *hiding_2;<br>
>> +  struct hiding_1 *p = hiding_1();<br>
>> +  struct hiding_2 *q = hiding_2;<br>
>> +}<br>
>><br>
>> Modified: cfe/trunk/test/SemaCXX/blocks-1.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/blocks-1.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/blocks-1.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/SemaCXX/blocks-1.cpp (original)<br>
>> +++ cfe/trunk/test/SemaCXX/blocks-1.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -1,5 +1,4 @@<br>
>> -// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks -std=c++11<br>
>> -// expected-no-diagnostics<br>
>> +// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks -std=c++1y<br>
>><br>
>> extern "C" int exit(int);<br>
>><br>
>> @@ -57,3 +56,18 @@ namespace rdar11055105 {<br>
>>    foo(a);<br>
>>  };<br>
>> }<br>
>> +<br>
>> +namespace LocalDecls {<br>
>> +  void f() {<br>
>> +    (void) ^{<br>
>> +      extern int a; // expected-note {{previous}}<br>
>> +      extern int b(); // expected-note {{previous}}<br>
>> +    };<br>
>> +  }<br>
>> +  void g() {<br>
>> +    (void) ^{<br>
>> +      extern float a; // expected-error {{different type}}<br>
>> +      extern float b(); // expected-error {{cannot be overloaded}}<br>
>> +    };<br>
>> +  }<br>
>> +}<br>
>><br>
>> Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp (original)<br>
>> +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -36,10 +36,10 @@ namespace reference {<br>
>>  };<br>
>><br>
>>  void call() {<br>
>> -    void f(const int&);<br>
>> +    one f(const int&);<br>
>>    f({1});<br>
>><br>
>> -    void g(int&); // expected-note {{passing argument}}<br>
>> +    one g(int&); // expected-note {{passing argument}}<br>
>>    g({1}); // expected-error {{cannot bind to an initializer list temporary}}<br>
>>    int i = 0;<br>
>>    g({i});<br>
>><br>
>> Modified: cfe/trunk/test/SemaCXX/extern-c.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/extern-c.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/extern-c.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/SemaCXX/extern-c.cpp (original)<br>
>> +++ cfe/trunk/test/SemaCXX/extern-c.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -29,16 +29,27 @@ namespace test3 {<br>
>>  }<br>
>> }<br>
>><br>
>> -extern "C" {<br>
>> -  void test4_f() {<br>
>> -    extern int test4_b; // expected-note {{declared with C language linkage here}}<br>
>> +namespace N {<br>
>> +  extern "C" {<br>
>> +    void test4_f() {<br>
>> +      extern int test4_b; // expected-note {{declared with C language linkage here}}<br>
>> +    }<br>
>>  }<br>
>> }<br>
>> static float test4_b; // expected-error {{declaration of 'test4_b' in global scope conflicts with declaration with C language linkage}}<br>
>><br>
>> extern "C" {<br>
>> -  void test5_f() {<br>
>> -    extern int test5_b; // expected-note {{declared with C language linkage here}}<br>
>> +  void test4c_f() {<br>
>> +    extern int test4_c; // expected-note {{previous}}<br>
>> +  }<br>
>> +}<br>
>> +static float test4_c; // expected-error {{redefinition of 'test4_c' with a different type: 'float' vs 'int'}}<br>
>> +<br>
>> +namespace N {<br>
>> +  extern "C" {<br>
>> +    void test5_f() {<br>
>> +      extern int test5_b; // expected-note {{declared with C language linkage here}}<br>
>> +    }<br>
>>  }<br>
>> }<br>
>> extern "C" {<br>
>> @@ -46,6 +57,15 @@ extern "C" {<br>
>> }<br>
>><br>
>> extern "C" {<br>
>> +  void test5c_f() {<br>
>> +    extern int test5_c; // expected-note {{previous}}<br>
>> +  }<br>
>> +}<br>
>> +extern "C" {<br>
>> +  static float test5_c; // expected-error {{redefinition of 'test5_c' with a different type: 'float' vs 'int'}}<br>
>> +}<br>
>> +<br>
>> +extern "C" {<br>
>>  void f() {<br>
>>    extern int test6_b;<br>
>>  }<br>
>><br>
>> Modified: cfe/trunk/test/SemaCXX/function-redecl.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/function-redecl.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/function-redecl.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/SemaCXX/function-redecl.cpp (original)<br>
>> +++ cfe/trunk/test/SemaCXX/function-redecl.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -4,17 +4,14 @@ int foo(int);<br>
>> namespace N {<br>
>>  void f1() {<br>
>>    void foo(int); // okay<br>
>> -    void bar(int);<br>
>> +    void bar(int); // expected-note 2{{previous declaration is here}}<br>
>>  }<br>
>><br>
>>  void foo(int); // expected-note 2{{previous declaration is here}}<br>
>><br>
>>  void f2() {<br>
>>    int foo(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}<br>
>> -    // FIXME: We should be able to diagnose the conflict between this<br>
>> -    // declaration of 'bar' and the previous one, even though they come<br>
>> -    // from different lexical scopes.<br>
>> -    int bar(int); // expected-note {{previous declaration is here}}<br>
>> +    int bar(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}<br>
>>    int baz(int); // expected-note {{previous declaration is here}}<br>
>><br>
>>    {<br>
>><br>
>> Modified: cfe/trunk/test/SemaCXX/warn-unreachable.cpp<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unreachable.cpp?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unreachable.cpp?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/test/SemaCXX/warn-unreachable.cpp (original)<br>
>> +++ cfe/trunk/test/SemaCXX/warn-unreachable.cpp Thu Sep 19 20:15:31 2013<br>
>> @@ -62,8 +62,8 @@ void test5() {<br>
>>  struct S {<br>
>>    int mem;<br>
>>  } s;<br>
>> -  S &foor() __attribute__((noreturn));<br>
>> -  foor()<br>
>> +  S &foonr() __attribute__((noreturn));<br>
>> +  foonr()<br>
>>    .mem;       // expected-warning {{will never be executed}}<br>
>> }<br>
>><br>
>><br>
>> Modified: cfe/trunk/www/cxx_dr_status.html<br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=191064&r1=191063&r2=191064&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=191064&r1=191063&r2=191064&view=diff</a><br>

>> ==============================================================================<br>
>> --- cfe/trunk/www/cxx_dr_status.html (original)<br>
>> +++ cfe/trunk/www/cxx_dr_status.html Thu Sep 19 20:15:31 2013<br>
>> @@ -212,7 +212,7 @@<br>
>>    <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#29" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#29</a>">29</a></td><br>

>>    <td>CD1</td><br>
>>    <td>Linkage of locally declared functions</td><br>
>> -    <td class="none" align="center">No</td><br>
>> +    <td class="svn" align="center">SVN</td><br>
>>  </tr><br>
>>  <tr><br>
>>    <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#30" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#30</a>">30</a></td><br>

>><br>
>><br>
>> _______________________________________________<br>
>> cfe-commits mailing list<br>
>> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br>
</div></div></blockquote></div><br></div>
_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits<br></blockquote></div><br></body></html>