r185256 - Revert r185229 as it breaks compilation of <windows.h>

Timur Iskhodzhanov timurrrr at google.com
Sat Jun 29 01:38:43 PDT 2013


Author: timurrrr
Date: Sat Jun 29 03:38:42 2013
New Revision: 185256

URL: http://llvm.org/viewvc/llvm-project?rev=185256&view=rev
Log:
Revert r185229 as it breaks compilation of <windows.h>

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/class.access/class.friend/p1.cpp
    cfe/trunk/test/Sema/overloadable.c
    cfe/trunk/test/SemaCXX/extern-c.cpp
    cfe/trunk/test/SemaCXX/friend.cpp
    cfe/trunk/test/SemaCXX/linkage-spec.cpp
    cfe/trunk/test/SemaCXX/linkage2.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Jun 29 03:38:42 2013
@@ -3493,11 +3493,6 @@ def err_static_non_static : Error<
   "static declaration of %0 follows non-static declaration">;
 def err_different_language_linkage : Error<
   "declaration of %0 has a different language linkage">;
-def err_extern_c_global_conflict : Error<
-  "declaration of %1 %select{with C language linkage|in global scope}0 "
-  "conflicts with declaration %select{in global scope|with C language linkage}0">;
-def note_extern_c_global_conflict : Note<
-  "declared %select{in global scope|with C language linkage}0 here">;
 def warn_weak_import : Warning <
   "an already-declared variable is made a weak_import declaration %0">;
 def warn_static_non_static : ExtWarn<

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Jun 29 03:38:42 2013
@@ -4359,14 +4359,10 @@ TryToFixInvalidVariablyModifiedTypeSourc
 /// function-scope declarations.
 void
 Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S) {
-  if (!getLangOpts().CPlusPlus &&
-      ND->getLexicalDeclContext()->getRedeclContext()->isTranslationUnit())
-    // Don't need to track declarations in the TU in C.
-    return;
-
+  assert(
+      !ND->getLexicalDeclContext()->getRedeclContext()->isTranslationUnit() &&
+      "Decl is not a locally-scoped decl!");
   // Note that we have a locally-scoped external with this name.
-  // FIXME: There can be multiple such declarations if they are functions marked
-  // __attribute__((overloadable)) declared in function scope in C.
   LocallyScopedExternCDecls[ND->getDeclName()] = ND;
 }
 
@@ -4685,32 +4681,6 @@ static bool isFunctionDefinitionDiscarde
   return isC99Inline;
 }
 
-/// Determine whether a variable is extern "C" prior to attaching
-/// an initializer. We can't just call isExternC() here, because that
-/// will also compute and cache whether the declaration is externally
-/// visible, which might change when we attach the initializer.
-///
-/// This can only be used if the declaration is known to not be a
-/// redeclaration of an internal linkage declaration.
-///
-/// For instance:
-///
-///   auto x = []{};
-///
-/// Attaching the initializer here makes this declaration not externally
-/// visible, because its type has internal linkage.
-///
-/// FIXME: This is a hack.
-template<typename T>
-static bool isIncompleteDeclExternC(Sema &S, const T *D) {
-  if (S.getLangOpts().CPlusPlus) {
-    // In C++, the overloadable attribute negates the effects of extern "C".
-    if (!D->isInExternCContext() || D->template hasAttr<OverloadableAttr>())
-      return false;
-  }
-  return D->isExternC();
-}
-
 static bool shouldConsiderLinkage(const VarDecl *VD) {
   const DeclContext *DC = VD->getDeclContext()->getRedeclContext();
   if (DC->isFunctionOrMethod())
@@ -5100,10 +5070,16 @@ Sema::ActOnVariableDeclarator(Scope *S,
   ProcessPragmaWeak(S, NewVD);
   checkAttributesAfterMerging(*this, *NewVD);
 
-  // If this is the first declaration of an extern C variable, update
-  // the map of such variables.
-  if (!NewVD->getPreviousDecl() && !NewVD->isInvalidDecl() &&
-      isIncompleteDeclExternC(*this, NewVD))
+  // If this is the first declaration of an extern C variable that is not
+  // declared directly in the translation unit, update the map of such
+  // variables.
+  if (!CurContext->getRedeclContext()->isTranslationUnit() &&
+      !NewVD->getPreviousDecl() && !NewVD->isInvalidDecl() &&
+      // FIXME: We only check isExternC if we're in an extern C context,
+      // to avoid computing and caching an 'externally visible' flag which
+      // could change if the variable's type is not visible.
+      (!getLangOpts().CPlusPlus || NewVD->isInExternCContext()) &&
+      NewVD->isExternC())
     RegisterLocallyScopedExternCDecl(NewVD, S);
 
   return NewVD;
@@ -5204,120 +5180,30 @@ void Sema::CheckShadow(Scope *S, VarDecl
   CheckShadow(S, D, R);
 }
 
-/// Check for conflict between this global or extern "C" declaration and
-/// previous global or extern "C" declarations. This is only used in C++.
 template<typename T>
-static bool checkGlobalOrExternCConflict(
-    Sema &S, const T *ND, bool IsGlobal, LookupResult &Previous) {
-  assert(S.getLangOpts().CPlusPlus && "only C++ has extern \"C\"");
-  NamedDecl *Prev = S.findLocallyScopedExternCDecl(ND->getDeclName());
-
-  if (!Prev && IsGlobal && !isIncompleteDeclExternC(S, ND)) {
-    // The common case: this global doesn't conflict with any extern "C"
-    // declaration.
-    return false;
-  }
-
-  if (Prev) {
-    if (!IsGlobal || isIncompleteDeclExternC(S, ND)) {
-      // Both the old and new declarations have C language linkage. This is a
-      // redeclaration.
-      Previous.clear();
-      Previous.addDecl(Prev);
-      return true;
-    }
-
-    // This is a global, non-extern "C" declaration, and there is a previous
-    // non-global extern "C" declaration. Diagnose.
-  } else {
-    // The declaration is extern "C". Check for any declaration in the
-    // translation unit which might conflict.
-    if (IsGlobal) {
-      // We have already performed the lookup into the translation unit.
-      IsGlobal = false;
-      for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
-           I != E; ++I) {
-        if (isa<VarDecl>(*I) || isa<FunctionDecl>(*I)) {
-          Prev = *I;
-          break;
-        }
-      }
-    } else {
-      DeclContext::lookup_result R =
-          S.Context.getTranslationUnitDecl()->lookup(ND->getDeclName());
-      for (DeclContext::lookup_result::iterator I = R.begin(), E = R.end();
-           I != E; ++I) {
-        if (isa<VarDecl>(*I) || isa<FunctionDecl>(*I)) {
-          Prev = *I;
-          break;
-        }
-        // FIXME: If we have any other entity with this name in global scope,
-        // the declaration is ill-formed, but that is a defect: it breaks the
-        // 'stat' hack, for instance.
-      }
-    }
+static bool mayConflictWithNonVisibleExternC(const T *ND) {
+  const DeclContext *DC = ND->getDeclContext();
+  if (DC->getRedeclContext()->isTranslationUnit())
+    return true;
 
-    if (!Prev)
+  // We know that is the first decl we see, other than function local
+  // extern C ones. If this is C++ and the decl is not in a extern C context
+  // it cannot have C language linkage. Avoid calling isExternC in that case.
+  // We need to this because of code like
+  //
+  // namespace { struct bar {}; }
+  // auto foo = bar();
+  //
+  // This code runs before the init of foo is set, and therefore before
+  // the type of foo is known. Not knowing the type we cannot know its linkage
+  // unless it is in an extern C block.
+  if (!ND->isInExternCContext()) {
+    const ASTContext &Context = ND->getASTContext();
+    if (Context.getLangOpts().CPlusPlus)
       return false;
   }
 
-  // Use the first declaration's location to ensure we point at something which
-  // is lexically inside an extern "C" linkage-spec.
-  assert(Prev && "should have found a previous declaration to diagnose");
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Prev))
-    Prev = FD->getFirstDeclaration();
-  else
-    Prev = cast<VarDecl>(Prev)->getFirstDeclaration();
-
-  S.Diag(ND->getLocation(), diag::err_extern_c_global_conflict)
-    << IsGlobal << ND;
-  S.Diag(Prev->getLocation(), diag::note_extern_c_global_conflict)
-    << IsGlobal;
-  return false;
-}
-
-/// Apply special rules for handling extern "C" declarations. Returns \c true
-/// if we have found that this is a redeclaration of some prior entity.
-///
-/// Per C++ [dcl.link]p6:
-///   Two declarations [for a function or variable] with C language linkage
-///   with the same name that appear in different scopes refer to the same
-///   [entity]. An entity with C language linkage shall not be declared with
-///   the same name as an entity in global scope.
-template<typename T>
-static bool checkForConflictWithNonVisibleExternC(Sema &S, const T *ND,
-                                                  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.
-    if (ND->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
-      if (NamedDecl *Prev = S.findLocallyScopedExternCDecl(ND->getDeclName())) {
-        Previous.clear();
-        Previous.addDecl(Prev);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  // A declaration in the translation unit can conflict with an extern "C"
-  // declaration.
-  if (ND->getDeclContext()->getRedeclContext()->isTranslationUnit())
-    return checkGlobalOrExternCConflict(S, ND, /*IsGlobal*/true, Previous);
-
-  // An extern "C" declaration can conflict with a declaration in the
-  // translation unit or can be a redeclaration of an extern "C" declaration
-  // in another scope.
-  if (isIncompleteDeclExternC(S,ND))
-    return checkGlobalOrExternCConflict(S, ND, /*IsGlobal*/false, Previous);
-
-  // Neither global nor extern "C": nothing to do.
-  return false;
+  return ND->isExternC();
 }
 
 void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
@@ -5500,9 +5386,14 @@ bool Sema::CheckVariableDeclaration(VarD
   // The most important point here is that we're not allowed to
   // update our understanding of the type according to declarations
   // not in scope.
-  bool PreviousWasHidden =
-      Previous.empty() &&
-      checkForConflictWithNonVisibleExternC(*this, NewVD, Previous);
+  bool PreviousWasHidden = false;
+  if (Previous.empty() && mayConflictWithNonVisibleExternC(NewVD)) {
+    if (NamedDecl *ExternCPrev =
+            findLocallyScopedExternCDecl(NewVD->getDeclName())) {
+      Previous.addDecl(ExternCPrev);
+      PreviousWasHidden = true;
+    }
+  }
 
   // Filter out any non-conflicting previous declarations.
   filterNonConflictingPreviousDecls(Context, NewVD, Previous);
@@ -6734,10 +6625,12 @@ Sema::ActOnFunctionDeclarator(Scope *S,
   // marking the function.
   AddCFAuditedAttribute(NewFD);
 
-  // If this is the first declaration of an extern C variable, update
-  // the map of such variables.
-  if (!NewFD->getPreviousDecl() && !NewFD->isInvalidDecl() &&
-      isIncompleteDeclExternC(*this, NewFD))
+  // If this is the first declaration of an extern C variable that is not
+  // declared directly in the translation unit, update the map of such
+  // variables.
+  if (!CurContext->getRedeclContext()->isTranslationUnit() &&
+      !NewFD->getPreviousDecl() && NewFD->isExternC() &&
+      !NewFD->isInvalidDecl())
     RegisterLocallyScopedExternCDecl(NewFD, S);
 
   // Set this FunctionDecl's range up to the right paren.
@@ -6841,6 +6734,15 @@ bool Sema::CheckFunctionDeclaration(Scop
   assert(!NewFD->getResultType()->isVariablyModifiedType() 
          && "Variably modified return types are not handled here");
 
+  // Check for a previous declaration of this name.
+  if (Previous.empty() && mayConflictWithNonVisibleExternC(NewFD)) {
+    // Since we did not find anything by this name, look for a non-visible
+    // extern "C" declaration with the same name.
+    if (NamedDecl *ExternCPrev =
+            findLocallyScopedExternCDecl(NewFD->getDeclName()))
+      Previous.addDecl(ExternCPrev);
+  }
+
   // Filter out any non-conflicting previous declarations.
   filterNonConflictingPreviousDecls(Context, NewFD, Previous);
 
@@ -6894,34 +6796,6 @@ bool Sema::CheckFunctionDeclaration(Scop
       }
     }
   }
-
-  // Check for a previous extern "C" declaration with this name.
-  if (!Redeclaration &&
-      checkForConflictWithNonVisibleExternC(*this, NewFD, Previous)) {
-    filterNonConflictingPreviousDecls(Context, NewFD, Previous);
-    if (!Previous.empty()) {
-      // This is an extern "C" declaration with the same name as a previous
-      // declaration, and thus redeclares that entity...
-      Redeclaration = true;
-      OldDecl = Previous.getFoundDecl();
-
-      // ... except in the presence of __attribute__((overloadable)).
-      if (OldDecl->hasAttr<OverloadableAttr>()) {
-        if (!getLangOpts().CPlusPlus && !NewFD->hasAttr<OverloadableAttr>()) {
-          Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
-            << Redeclaration << NewFD;
-          Diag(Previous.getFoundDecl()->getLocation(),
-               diag::note_attribute_overloadable_prev_overload);
-          NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(),
-                                                          Context));
-        }
-        if (IsOverload(NewFD, cast<FunctionDecl>(OldDecl), false)) {
-          Redeclaration = false;
-          OldDecl = 0;
-        }
-      }
-    }
-  }
 
   // C++11 [dcl.constexpr]p8:
   //   A constexpr specifier for a non-static member function that is not

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Jun 29 03:38:42 2013
@@ -977,12 +977,21 @@ Sema::CheckOverload(Scope *S, FunctionDe
   return Ovl_Overload;
 }
 
-bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
-                      bool UseUsingDeclRules) {
-  // C++ [basic.start.main]p2: This function shall not be overloaded.
-  if (New->isMain())
+static bool canBeOverloaded(const FunctionDecl &D) {
+  if (D.getAttr<OverloadableAttr>())
+    return true;
+  if (D.isExternC())
+    return false;
+
+  // Main cannot be overloaded (basic.start.main).
+  if (D.isMain())
     return false;
 
+  return true;
+}
+
+static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old,
+                                bool UseUsingDeclRules) {
   FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
   FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
 
@@ -993,8 +1002,8 @@ bool Sema::IsOverload(FunctionDecl *New,
     return true;
 
   // Is the function New an overload of the function Old?
-  QualType OldQType = Context.getCanonicalType(Old->getType());
-  QualType NewQType = Context.getCanonicalType(New->getType());
+  QualType OldQType = S.Context.getCanonicalType(Old->getType());
+  QualType NewQType = S.Context.getCanonicalType(New->getType());
 
   // Compare the signatures (C++ 1.3.10) of the two functions to
   // determine whether they are overloads. If we find any mismatch
@@ -1015,7 +1024,7 @@ bool Sema::IsOverload(FunctionDecl *New,
   if (OldQType != NewQType &&
       (OldType->getNumArgs() != NewType->getNumArgs() ||
        OldType->isVariadic() != NewType->isVariadic() ||
-       !FunctionArgTypesAreEqual(OldType, NewType)))
+       !S.FunctionArgTypesAreEqual(OldType, NewType)))
     return true;
 
   // C++ [temp.over.link]p4:
@@ -1031,9 +1040,9 @@ bool Sema::IsOverload(FunctionDecl *New,
   // However, we don't consider either of these when deciding whether
   // a member introduced by a shadow declaration is hidden.
   if (!UseUsingDeclRules && NewTemplate &&
-      (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
-                                       OldTemplate->getTemplateParameters(),
-                                       false, TPL_TemplateMatch) ||
+      (!S.TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
+                                         OldTemplate->getTemplateParameters(),
+                                         false, S.TPL_TemplateMatch) ||
        OldType->getResultType() != NewType->getResultType()))
     return true;
 
@@ -1059,9 +1068,9 @@ bool Sema::IsOverload(FunctionDecl *New,
         //     declarations with the same name, the same parameter-type-list, and
         //     the same template parameter lists cannot be overloaded if any of
         //     them, but not all, have a ref-qualifier (8.3.5).
-        Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload)
+        S.Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload)
           << NewMethod->getRefQualifier() << OldMethod->getRefQualifier();
-        Diag(OldMethod->getLocation(), diag::note_previous_declaration);
+        S.Diag(OldMethod->getLocation(), diag::note_previous_declaration);
       }
       return true;
     }
@@ -1071,7 +1080,7 @@ bool Sema::IsOverload(FunctionDecl *New,
     // or non-static member function). Add it now, on the assumption that this
     // is a redeclaration of OldMethod.
     unsigned NewQuals = NewMethod->getTypeQualifiers();
-    if (!getLangOpts().CPlusPlus1y && NewMethod->isConstexpr() &&
+    if (!S.getLangOpts().CPlusPlus1y && NewMethod->isConstexpr() &&
         !isa<CXXConstructorDecl>(NewMethod))
       NewQuals |= Qualifiers::Const;
     if (OldMethod->getTypeQualifiers() != NewQuals)
@@ -1082,6 +1091,19 @@ bool Sema::IsOverload(FunctionDecl *New,
   return false;
 }
 
+bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
+                      bool UseUsingDeclRules) {
+  if (!shouldTryToOverload(*this, New, Old, UseUsingDeclRules))
+    return false;
+
+  // If both of the functions are extern "C", then they are not
+  // overloads.
+  if (!canBeOverloaded(*Old) && !canBeOverloaded(*New))
+    return false;
+
+  return true;
+}
+
 /// \brief Checks availability of the function depending on the current
 /// function context. Inside an unavailable function, unavailability is ignored.
 ///

Modified: cfe/trunk/test/CXX/class.access/class.friend/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class.access/class.friend/p1.cpp?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class.access/class.friend/p1.cpp (original)
+++ cfe/trunk/test/CXX/class.access/class.friend/p1.cpp Sat Jun 29 03:38:42 2013
@@ -287,22 +287,22 @@ namespace test9 {
 
 // PR7230
 namespace test10 {
-  extern "C" void test10_f(void);
-  extern "C" void test10_g(void);
+  extern "C" void f(void);
+  extern "C" void g(void);
 
   namespace NS {
     class C {
       void foo(void); // expected-note {{declared private here}}
-      friend void test10::test10_f(void);
+      friend void test10::f(void);
     };
     static C* bar;
   }
 
-  void test10_f(void) {
+  void f(void) {
     NS::bar->foo();
   }
 
-  void test10_g(void) {
+  void g(void) {
     NS::bar->foo(); // expected-error {{private member}}
   }
 }

Modified: cfe/trunk/test/Sema/overloadable.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/overloadable.c?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/test/Sema/overloadable.c (original)
+++ cfe/trunk/test/Sema/overloadable.c Sat Jun 29 03:38:42 2013
@@ -69,18 +69,3 @@ void test() {
   f0();
   f1();
 }
-
-void before_local_1(int) __attribute__((overloadable)); // expected-note {{here}}
-void before_local_2(int); // expected-note {{here}}
-void before_local_3(int) __attribute__((overloadable));
-void local() {
-  void before_local_1(char); // expected-error {{must have the 'overloadable' attribute}}
-  void before_local_2(char) __attribute__((overloadable)); // expected-error {{conflicting types}}
-  void before_local_3(char) __attribute__((overloadable));
-  void after_local_1(char); // expected-note {{here}}
-  void after_local_2(char) __attribute__((overloadable)); // expected-note {{here}}
-  void after_local_3(char) __attribute__((overloadable));
-}
-void after_local_1(int) __attribute__((overloadable)); // expected-error {{conflicting types}}
-void after_local_2(int); // expected-error {{must have the 'overloadable' attribute}}
-void after_local_3(int) __attribute__((overloadable));

Modified: cfe/trunk/test/SemaCXX/extern-c.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/extern-c.cpp?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/extern-c.cpp (original)
+++ cfe/trunk/test/SemaCXX/extern-c.cpp Sat Jun 29 03:38:42 2013
@@ -3,20 +3,20 @@
 namespace test1 {
   extern "C" {
     void test1_f() {
-      void test1_g(int); // expected-note {{declared with C language linkage here}}
+      void test1_g(int); // expected-note {{previous declaration is here}}
     }
   }
 }
-int test1_g(int); // expected-error {{declaration of 'test1_g' in global scope conflicts with declaration with C language linkage}}
+int test1_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}
 
 namespace test2 {
   extern "C" {
     void test2_f() {
-      extern int test2_x; // expected-note {{declared with C language linkage here}}
+      extern int test2_x; // expected-note {{previous definition is here}}
     }
   }
 }
-float test2_x; // expected-error {{declaration of 'test2_x' in global scope conflicts with declaration with C language linkage}}
+float test2_x; // expected-error {{redefinition of 'test2_x' with a different type: 'float' vs 'int'}}
 
 namespace test3 {
   extern "C" {
@@ -31,18 +31,18 @@ namespace test3 {
 
 extern "C" {
   void test4_f() {
-    extern int test4_b; // expected-note {{declared with C language linkage here}}
+    extern int test4_b; // expected-note {{previous definition is here}}
   }
 }
-static float test4_b; // expected-error {{declaration of 'test4_b' in global scope conflicts with declaration with C language linkage}}
+static float test4_b; // expected-error {{redefinition of 'test4_b' with a different type: 'float' vs 'int'}}
 
 extern "C" {
   void test5_f() {
-    extern int test5_b; // expected-note {{declared with C language linkage here}}
+    extern int test5_b; // expected-note {{previous definition is here}}
   }
 }
 extern "C" {
-  static float test5_b; // expected-error {{declaration of 'test5_b' in global scope conflicts with declaration with C language linkage}}
+  static float test5_b; // expected-error {{redefinition of 'test5_b' with a different type: 'float' vs 'int'}}
 }
 
 extern "C" {
@@ -69,11 +69,11 @@ namespace linkage {
     }
   }
   namespace from_outer {
-    void linkage_from_outer_1(); // expected-note {{previous}}
+    void linkage_from_outer_1();
     void linkage_from_outer_2(); // expected-note {{previous}}
     extern "C" {
-      void linkage_from_outer_1(int);
-      void linkage_from_outer_1(); // expected-error {{different language linkage}}
+      void linkage_from_outer_1(int); // expected-note {{previous}}
+      void linkage_from_outer_1(); // expected-error {{conflicting types}}
       void linkage_from_outer_2(); // expected-error {{different language linkage}}
     }
   }
@@ -98,44 +98,11 @@ namespace linkage {
   }
 }
 
-void lookup_in_global_f(); // expected-note {{here}}
+void lookup_in_global_f();
 namespace lookup_in_global {
   void lookup_in_global_f();
-  void lookup_in_global_g();
   extern "C" {
-    void lookup_in_global_f(int); // expected-error {{conflicts with declaration in global scope}}
-    void lookup_in_global_g(int); // expected-note {{here}}
+    // FIXME: We should reject this.
+    void lookup_in_global_f(int);
   }
 }
-void lookup_in_global_g(); // expected-error {{conflicts with declaration with C language linkage}}
-
-namespace N1 {
-  extern "C" int different_kind_1; // expected-note {{here}}
-  extern "C" void different_kind_2(); // expected-note {{here}}
-}
-namespace N2 {
-  extern "C" void different_kind_1(); // expected-error {{different kind of symbol}}
-  extern "C" int different_kind_2; // expected-error {{different kind of symbol}}
-}
-
-extern "C" {
-  struct stat {};
-  void stat(struct stat);
-}
-namespace X {
-  extern "C" {
-    void stat(struct ::stat);
-  }
-}
-
-extern "C" void name_with_using_decl_1(int);
-namespace using_decl {
-  void name_with_using_decl_1();
-  void name_with_using_decl_2();
-  void name_with_using_decl_3();
-}
-using using_decl::name_with_using_decl_1;
-using using_decl::name_with_using_decl_2;
-extern "C" void name_with_using_decl_2(int);
-extern "C" void name_with_using_decl_3(int);
-using using_decl::name_with_using_decl_3;

Modified: cfe/trunk/test/SemaCXX/friend.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/friend.cpp?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/friend.cpp (original)
+++ cfe/trunk/test/SemaCXX/friend.cpp Sat Jun 29 03:38:42 2013
@@ -134,7 +134,7 @@ namespace test6_3 {
 namespace test7 {
   extern "C" {
     class X {
-      friend int test7_f() { return 42; }
+      friend int f() { return 42; }
     };
   }
 }

Modified: cfe/trunk/test/SemaCXX/linkage-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage-spec.cpp?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/linkage-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/linkage-spec.cpp Sat Jun 29 03:38:42 2013
@@ -41,32 +41,20 @@ namespace pr5430 {
 using namespace pr5430;
 extern "C" void pr5430::func(void) { }
 
-// PR5405
-int f2(char *) // expected-note {{here}}
+// PR5404
+int f2(char *)
 {
         return 0;
 }
 
 extern "C"
 {
-    int f2(int) // expected-error {{with C language linkage conflicts with declaration in global scope}}
+    int f2(int)
     {
         return f2((char *)0);
     }
 }
 
-namespace PR5405 {
-  int f2b(char *) {
-    return 0;
-  }
-
-  extern "C" {
-    int f2b(int) {
-      return f2b((char *)0); // ok
-    }
-  }
-}
-
 // PR6991
 extern "C" typedef int (*PutcFunc_t)(int);
 
@@ -129,28 +117,3 @@ namespace pr14958 {
 
 extern "C" void PR16167; // expected-error {{variable has incomplete type 'void'}}
 extern void PR16167_0; // expected-error {{variable has incomplete type 'void'}}
-
-// PR7927
-enum T_7927 {
-  E_7927
-};
-
-extern "C" void f_pr7927(int);
-
-namespace {
-  extern "C" void f_pr7927(int);
-
-  void foo_pr7927() {
-    f_pr7927(E_7927);
-    f_pr7927(0);
-    ::f_pr7927(E_7927);
-    ::f_pr7927(0);
-  }
-}
-
-void bar_pr7927() {
-  f_pr7927(E_7927);
-  f_pr7927(0);
-  ::f_pr7927(E_7927);
-  ::f_pr7927(0);
-}

Modified: cfe/trunk/test/SemaCXX/linkage2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage2.cpp?rev=185256&r1=185255&r2=185256&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/linkage2.cpp (original)
+++ cfe/trunk/test/SemaCXX/linkage2.cpp Sat Jun 29 03:38:42 2013
@@ -201,15 +201,3 @@ namespace test18 {
   }
   void *h() { return f(); }
 }
-
-extern "C" void pr16247_foo(int); // expected-note {{here}}
-static void pr16247_foo(double); // expected-error {{conflicts with declaration with C language linkage}}
-void pr16247_foo(int) {}
-void pr16247_foo(double) {}
-
-namespace PR16247 {
-  extern "C" void pr16247_bar(int);
-  static void pr16247_bar(double);
-  void pr16247_bar(int) {}
-  void pr16247_bar(double) {}
-}





More information about the cfe-commits mailing list