kfunk updated this revision to Diff 49999.
kfunk added a comment.
This revision is now accepted and ready to land.

Remove TODO statement


http://reviews.llvm.org/D15729

Files:
  include/clang/Frontend/CompilerInstance.h
  lib/Frontend/ASTUnit.cpp
  lib/Frontend/CompilerInstance.cpp
  lib/FrontendTool/ExecuteCompilerInvocation.cpp
  test/CXX/drs/dr3xx.cpp
  unittests/Frontend/CMakeLists.txt
  unittests/Frontend/FrontendActionTest.cpp
  unittests/Frontend/PrintFunctionNamesTestPlugin/CMakeLists.txt
  
unittests/Frontend/PrintFunctionNamesTestPlugin/PrintFunctionNamesTestPlugin.cpp

Index: unittests/Frontend/PrintFunctionNamesTestPlugin/PrintFunctionNamesTestPlugin.cpp
===================================================================
--- /dev/null
+++ unittests/Frontend/PrintFunctionNamesTestPlugin/PrintFunctionNamesTestPlugin.cpp
@@ -0,0 +1,123 @@
+//===- PrintFunctionNames.cpp ---------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Example clang plugin which simply prints the names of all the top-level decls
+// in the input file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Sema/Sema.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+namespace {
+
+class PrintFunctionsConsumer : public ASTConsumer {
+  CompilerInstance &Instance;
+  std::set<std::string> ParsedTemplates;
+
+public:
+  PrintFunctionsConsumer(CompilerInstance &Instance,
+                         std::set<std::string> ParsedTemplates)
+      : Instance(Instance), ParsedTemplates(ParsedTemplates) {}
+
+  bool HandleTopLevelDecl(DeclGroupRef DG) override {
+    for (DeclGroupRef::iterator i = DG.begin(), e = DG.end(); i != e; ++i) {
+      const Decl *D = *i;
+      if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+        llvm::errs() << "top-level-decl: \"" << ND->getNameAsString() << "\"\n";
+    }
+
+    return true;
+  }
+
+  void HandleTranslationUnit(ASTContext& context) override {
+    if (!Instance.getLangOpts().DelayedTemplateParsing)
+      return;
+
+    // This demonstrates how to force instantiation of some templates in
+    // -fdelayed-template-parsing mode. (Note: Doing this unconditionally for
+    // all templates is similar to not using -fdelayed-template-parsig in the
+    // first place.)
+    // The advantage of doing this in HandleTranslationUnit() is that all
+    // codegen (when using -add-plugin) is completely finished and this can't
+    // affect the compiler output.
+    struct Visitor : public RecursiveASTVisitor<Visitor> {
+      const std::set<std::string> &ParsedTemplates;
+      Visitor(const std::set<std::string> &ParsedTemplates)
+          : ParsedTemplates(ParsedTemplates) {}
+      bool VisitFunctionDecl(FunctionDecl *FD) {
+        if (FD->isLateTemplateParsed() &&
+            ParsedTemplates.count(FD->getNameAsString()))
+          LateParsedDecls.insert(FD);
+        return true;
+      }
+
+      std::set<FunctionDecl*> LateParsedDecls;
+    } v(ParsedTemplates);
+    v.TraverseDecl(context.getTranslationUnitDecl());
+    clang::Sema &sema = Instance.getSema();
+    for (const FunctionDecl *FD : v.LateParsedDecls) {
+      clang::LateParsedTemplate* LPT = sema.LateParsedTemplateMap.lookup(FD);
+      sema.LateTemplateParser(sema.OpaqueParser, *LPT);
+      llvm::errs() << "late-parsed-decl: \"" << FD->getNameAsString() << "\"\n";
+    }
+  }
+};
+
+class PrintFunctionNamesAction : public PluginASTAction {
+  std::set<std::string> ParsedTemplates;
+protected:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 llvm::StringRef) override {
+    return llvm::make_unique<PrintFunctionsConsumer>(CI, ParsedTemplates);
+  }
+
+  bool ParseArgs(const CompilerInstance &CI,
+                 const std::vector<std::string> &args) override {
+    for (unsigned i = 0, e = args.size(); i != e; ++i) {
+      llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n";
+
+      // Example error handling.
+      DiagnosticsEngine &D = CI.getDiagnostics();
+      if (args[i] == "-an-error") {
+        unsigned DiagID = D.getCustomDiagID(DiagnosticsEngine::Error,
+                                            "invalid argument '%0'");
+        D.Report(DiagID) << args[i];
+        return false;
+      } else if (args[i] == "-parse-template") {
+        if (i + 1 >= e) {
+          D.Report(D.getCustomDiagID(DiagnosticsEngine::Error,
+                                     "missing -parse-template argument"));
+          return false;
+        }
+        ++i;
+        ParsedTemplates.insert(args[i]);
+      }
+    }
+    if (!args.empty() && args[0] == "help")
+      PrintHelp(llvm::errs());
+
+    return true;
+  }
+  void PrintHelp(llvm::raw_ostream& ros) {
+    ros << "Help for PrintFunctionNames plugin goes here\n";
+  }
+
+};
+
+}
+
+static FrontendPluginRegistry::Add<PrintFunctionNamesAction>
+X("print-fns", "print function names");
Index: unittests/Frontend/PrintFunctionNamesTestPlugin/CMakeLists.txt
===================================================================
--- /dev/null
+++ unittests/Frontend/PrintFunctionNamesTestPlugin/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_llvm_loadable_module(PrintFunctionNamesTestPlugin PrintFunctionNamesTestPlugin.cpp)
+
+if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
+  target_link_libraries(PrintFunctionNamesTestPlugin ${cmake_2_8_12_PRIVATE}
+    clangAST
+    clangBasic
+    clangFrontend
+    LLVMSupport
+    )
+endif()
Index: unittests/Frontend/FrontendActionTest.cpp
===================================================================
--- unittests/Frontend/FrontendActionTest.cpp
+++ unittests/Frontend/FrontendActionTest.cpp
@@ -8,17 +8,21 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Sema.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "gtest/gtest.h"
 
+#include <iostream>
+
 using namespace llvm;
 using namespace clang;
 
@@ -144,6 +148,40 @@
   EXPECT_EQ("c", test_action.decl_names[12]);
 }
 
+bool pluginIsLoaded(const std::string &pluginName) {
+  for (auto it = FrontendPluginRegistry::begin(),
+       ie = FrontendPluginRegistry::end();
+       it != ie; ++it) {
+    if (it->getName() == pluginName) {
+      return true;
+    }
+  }
+  return false;
+}
+
+TEST(ASTFrontendAction, PluginLoadTest) {
+  CompilerInvocation *invocation = new CompilerInvocation;
+  invocation->getLangOpts()->CPlusPlus = true;
+  invocation->getPreprocessorOpts().addRemappedFile(
+      "test.cc",
+      MemoryBuffer::getMemBuffer("int main() { }").release());
+  invocation->getFrontendOpts().Inputs.push_back(FrontendInputFile("test.cc",
+                                                                   IK_CXX));
+  invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
+  invocation->getFrontendOpts().Plugins.push_back("PrintFunctionNamesTestPlugin.so");
+  invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
+
+  CompilerInstance compiler;
+  compiler.setInvocation(invocation);
+  compiler.createDiagnostics();
+  compiler.loadPlugins();
+
+  TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true,
+                                    /*actOnEndOfTranslationUnit=*/true);
+  ASSERT_TRUE(compiler.ExecuteAction(test_action));
+  ASSERT_TRUE(pluginIsLoaded("print-fns"));
+}
+
 struct TestPPCallbacks : public PPCallbacks {
   TestPPCallbacks() : SeenEnd(false) {}
 
Index: unittests/Frontend/CMakeLists.txt
===================================================================
--- unittests/Frontend/CMakeLists.txt
+++ unittests/Frontend/CMakeLists.txt
@@ -1,3 +1,5 @@
+add_subdirectory(PrintFunctionNamesTestPlugin)
+
 set(LLVM_LINK_COMPONENTS
   Support
   )
@@ -14,3 +16,4 @@
   clangSema
   clangCodeGen
   )
+add_dependencies(FrontendTests PrintFunctionNamesTestPlugin)
Index: test/CXX/drs/dr3xx.cpp
===================================================================
--- test/CXX/drs/dr3xx.cpp
+++ /dev/null
@@ -1,1291 +0,0 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-
-namespace dr300 { // dr300: yes
-  template<typename R, typename A> void f(R (&)(A)) {}
-  int g(int);
-  void h() { f(g); }
-}
-
-namespace dr301 { // dr301: yes
-  // see also dr38
-  struct S;
-  template<typename T> void operator+(T, T);
-  void operator-(S, S);
-
-  void f() {
-    bool a = (void(*)(S, S))operator+<S> <
-             (void(*)(S, S))operator+<S>;
-    bool b = (void(*)(S, S))operator- <
-             (void(*)(S, S))operator-;
-    bool c = (void(*)(S, S))operator+ <
-             (void(*)(S, S))operator-; // expected-error {{expected '>'}}
-  }
-
-  template<typename T> void f() {
-    typename T::template operator+<int> a; // expected-error {{typename specifier refers to a non-type template}} expected-error +{{}}
-    // FIXME: This shouldn't say (null).
-    class T::template operator+<int> b; // expected-error {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}}
-    enum T::template operator+<int> c; // expected-error {{expected identifier}} expected-error {{does not declare anything}}
-    enum T::template operator+<int>::E d; // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} expected-error {{forward reference}}
-    enum T::template X<int>::E e;
-    T::template operator+<int>::foobar(); // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}}
-    T::template operator+<int>(0); // ok
-  }
-
-  template<typename T> class operator&<T*> {}; // expected-error +{{}}
-  template<typename T> class T::operator& {}; // expected-error +{{}}
-  template<typename T> class S::operator&<T*> {}; // expected-error +{{}}
-}
-
-namespace dr302 { // dr302: yes
-  struct A { A(); ~A(); };
-#if __cplusplus < 201103L
-  struct B { // expected-error {{implicit default constructor for 'dr302::B' must explicitly initialize the const member 'n'}}
-    const int n; // expected-note {{declared here}}
-    A a;
-  } b = B(); // expected-note {{first required here}}
-  // Trivial default constructor C::C() is not called here.
-  struct C {
-    const int n;
-  } c = C();
-#else
-  struct B {
-    const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}}
-    A a;
-  } b = B(); // expected-error {{call to implicitly-deleted default constructor}}
-  // C::C() is called here, because even though it's trivial, it's deleted.
-  struct C {
-    const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}}
-  } c = C(); // expected-error {{call to implicitly-deleted default constructor}}
-  struct D {
-    const int n = 0;
-  } d = D();
-#endif
-}
-
-// dr303: na
-
-namespace dr304 { // dr304: yes
-  typedef int &a;
-  int n = a(); // expected-error {{requires an initializer}}
-
-  struct S { int &b; };
-  int m = S().b;
-#if __cplusplus < 201103L
-  // expected-error@-3 {{requires an initializer}}
-  // expected-note@-3 {{in value-initialization}}
-#else
-  // expected-error@-5 {{deleted}}
-  // expected-note@-7 {{reference}}
-#endif
-}
-
-namespace dr305 { // dr305: no
-  struct A {
-    typedef A C;
-  };
-  void f(A *a) {
-    struct A {};
-    a->~A();
-    a->~C();
-  }
-  typedef A B;
-  void g(B *b) {
-    b->~B();
-    b->~C();
-  }
-  void h(B *b) {
-    struct B {}; // expected-note {{declared here}}
-    b->~B(); // expected-error {{does not match}}
-  }
-
-  template<typename T> struct X {};
-  void i(X<int>* x) {
-    struct X {};
-    x->~X<int>();
-    x->~X();
-    x->~X<char>(); // expected-error {{no member named}}
-  }
-
-#if __cplusplus >= 201103L
-  struct Y {
-    template<typename T> using T1 = Y;
-  };
-  template<typename T> using T2 = Y;
-  void j(Y *y) {
-    y->~T1<int>();
-    y->~T2<int>();
-  }
-  struct Z {
-    template<typename T> using T2 = T;
-  };
-  void k(Z *z) {
-    // FIXME: This diagnostic is terrible.
-    z->~T1<int>(); // expected-error {{'T1' following the 'template' keyword does not refer to a template}} expected-error +{{}}
-    z->~T2<int>(); // expected-error {{no member named '~int'}}
-    z->~T2<Z>();
-  }
-
-  // FIXME: This is valid.
-  namespace Q {
-    template<typename A> struct R {};
-  }
-  template<typename A> using R = Q::R<int>;
-  void qr(Q::R<int> x) { x.~R<char>(); } // expected-error {{no member named}}
-#endif
-}
-
-namespace dr306 { // dr306: no
-  // FIXME: dup 39
-  // FIXME: This should be accepted.
-  struct A { struct B {}; }; // expected-note 2{{member}}
-  struct C { typedef A::B B; }; // expected-note {{member}}
-  struct D : A, A::B, C {};
-  D::B b; // expected-error {{found in multiple base classes of different types}}
-}
-
-// dr307: na
-
-namespace dr308 { // dr308: yes
-  // This is mostly an ABI library issue.
-  struct A {};
-  struct B : A {};
-  struct C : A {};
-  struct D : B, C {};
-  void f() {
-    try {
-      throw D();
-    } catch (const A&) { // expected-note {{for type 'const dr308::A &'}}
-      // unreachable
-    } catch (const B&) { // expected-warning {{exception of type 'const dr308::B &' will be caught by earlier handler}}
-      // get here instead
-    }
-  }
-}
-
-// dr309: dup 485
-
-namespace dr311 { // dr311: yes
-  namespace X { namespace Y {} }
-  namespace X::Y {}
-#if __cplusplus <= 201402L
-  // expected-error@-2 {{define each namespace separately}}
-#endif
-  namespace X {
-    namespace X::Y {}
-#if __cplusplus <= 201402L
-  // expected-error@-2 {{define each namespace separately}}
-#endif
-  }
-  // FIXME: The diagnostics here are not very good.
-  namespace ::dr311::X {} // expected-error 2+{{}} // expected-warning {{extra qual}}
-}
-
-// dr312: dup 616
-
-namespace dr313 { // dr313: dup 299 c++11
-  struct A { operator int() const; };
-  int *p = new int[A()];
-#if __cplusplus < 201103L
-  // FIXME: should this be available in c++98 mode? expected-error@-2 {{extension}}
-#endif
-}
-
-namespace dr314 { // FIXME 314: dup 1710
-  template<typename T> struct A {
-    template<typename U> struct B {};
-  };
-  template<typename T> struct C : public A<T>::template B<T> {
-    C() : A<T>::template B<T>() {}
-  };
-}
-
-// dr315: na
-// dr316: sup 1004
-
-namespace dr317 { // dr317: 3.5
-  void f() {} // expected-note {{previous}}
-  inline void f(); // expected-error {{inline declaration of 'f' follows non-inline definition}}
-
-  int g();
-  int n = g();
-  inline int g() { return 0; }
-
-  int h();
-  int m = h();
-  int h() { return 0; } // expected-note {{previous}}
-  inline int h(); // expected-error {{inline declaration of 'h' follows non-inline definition}}
-}
-
-namespace dr318 { // dr318: sup 1310
-  struct A {};
-  struct A::A a;
-}
-
-namespace dr319 { // dr319: no
-  // FIXME: dup dr389
-  // FIXME: We don't have a diagnostic for a name with linkage
-  //        having a type without linkage.
-  typedef struct {
-    int i;
-  } *ps;
-  extern "C" void f(ps);
-  void g(ps); // FIXME: ill-formed, type 'ps' has no linkage
-
-  static enum { e } a1;
-  enum { e2 } a2; // FIXME: ill-formed, enum type has no linkage
-
-  enum { n1 = 1u };
-  typedef int (*pa)[n1];
-  pa parr; // ok, type has linkage despite using 'n1'
-
-  template<typename> struct X {};
-
-  void f() {
-    struct A { int n; };
-    extern A a; // FIXME: ill-formed
-    X<A> xa;
-
-    typedef A B;
-    extern B b; // FIXME: ill-formed
-    X<B> xb;
-
-    const int n = 1;
-    typedef int (*C)[n];
-    extern C c; // ok
-    X<C> xc;
-  }
-#if __cplusplus < 201103L
-  // expected-error@-12 {{uses local type 'A'}}
-  // expected-error@-9 {{uses local type 'A'}}
-#endif
-}
-
-namespace dr320 { // dr320: yes
-#if __cplusplus >= 201103L
-  struct X {
-    constexpr X() {}
-    constexpr X(const X &x) : copies(x.copies + 1) {}
-    unsigned copies = 0;
-  };
-  constexpr X f(X x) { return x; }
-  constexpr unsigned g(X x) { return x.copies; }
-  static_assert(f(X()).copies == g(X()) + 1, "expected one extra copy for return value");
-#endif
-}
-
-namespace dr321 { // dr321: dup 557
-  namespace N {
-    template<int> struct A {
-      template<int> struct B;
-    };
-    template<> template<> struct A<0>::B<0>;
-    void f(A<0>::B<0>);
-  }
-  template<> template<> struct N::A<0>::B<0> {};
-
-  template<typename T> void g(T t) { f(t); }
-  template void g(N::A<0>::B<0>);
-
-  namespace N {
-    template<typename> struct I { friend bool operator==(const I&, const I&); };
-  }
-  N::I<int> i, j;
-  bool x = i == j;
-}
-
-namespace dr322 { // dr322: yes
-  struct A {
-    template<typename T> operator T&();
-  } a;
-  int &r = static_cast<int&>(a);
-  int &s = a;
-}
-
-// dr323: no
-
-namespace dr324 { // dr324: yes
-  struct S { int n : 1; } s; // expected-note 3{{bit-field is declared here}}
-  int &a = s.n; // expected-error {{non-const reference cannot bind to bit-field}}
-  int *b = &s.n; // expected-error {{address of bit-field}}
-  int &c = (s.n = 0); // expected-error {{non-const reference cannot bind to bit-field}}
-  int *d = &(s.n = 0); // expected-error {{address of bit-field}}
-  int &e = true ? s.n : s.n; // expected-error {{non-const reference cannot bind to bit-field}}
-  int *f = &(true ? s.n : s.n); // expected-error {{address of bit-field}}
-  int &g = (void(), s.n); // expected-error {{non-const reference cannot bind to bit-field}}
-  int *h = &(void(), s.n); // expected-error {{address of bit-field}}
-  int *i = &++s.n; // expected-error {{address of bit-field}}
-}
-
-namespace dr326 { // dr326: yes
-  struct S {};
-  int test[__is_trivially_constructible(S, const S&) ? 1 : -1];
-}
-
-namespace dr327 { // dr327: dup 538
-  struct A;
-  class A {};
-
-  class B;
-  struct B {};
-}
-
-namespace dr328 { // dr328: yes
-  struct A; // expected-note 3{{forward declaration}}
-  struct B { A a; }; // expected-error {{incomplete}}
-  template<typename> struct C { A a; }; // expected-error {{incomplete}}
-  A *p = new A[0]; // expected-error {{incomplete}}
-}
-
-namespace dr329 { // dr329: 3.5
-  struct B {};
-  template<typename T> struct A : B {
-    friend void f(A a) { g(a); }
-    friend void h(A a) { g(a); } // expected-error {{undeclared}}
-    friend void i(B b) {} // expected-error {{redefinition}} expected-note {{previous}}
-  };
-  A<int> a;
-  A<char> b; // expected-note {{instantiation}}
-
-  void test() {
-    h(a); // expected-note {{instantiation}}
-  }
-}
-
-namespace dr331 { // dr331: yes
-  struct A {
-    A(volatile A&); // expected-note {{candidate}}
-  } const a, b(a); // expected-error {{no matching constructor}}
-}
-
-namespace dr332 { // dr332: dup 577
-  void f(volatile void); // expected-error {{'void' as parameter must not have type qualifiers}}
-  void g(const void); // expected-error {{'void' as parameter must not have type qualifiers}}
-  void h(int n, volatile void); // expected-error {{'void' must be the first and only parameter}}
-}
-
-namespace dr333 { // dr333: yes
-  int n = 0;
-  int f(int(n));
-  int g((int(n)));
-  int h = f(g);
-}
-
-namespace dr334 { // dr334: yes
-  template<typename T> void f() {
-    T x;
-    f((x, 123));
-  }
-  struct S {
-    friend S operator,(S, int);
-    friend void f(S);
-  };
-  template void f<S>();
-}
-
-// dr335: no
-
-namespace dr336 { // dr336: yes
-  namespace Pre {
-    template<class T1> class A {
-      template<class T2> class B {
-        template<class T3> void mf1(T3);
-        void mf2();
-      };
-    };
-    template<> template<class X> class A<int>::B {};
-    template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} // expected-error {{does not match}}
-    template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}}
-  }
-  namespace Post {
-    template<class T1> class A {
-      template<class T2> class B {
-        template<class T3> void mf1(T3);
-        void mf2();
-      };
-    };
-    template<> template<class X> class A<int>::B {
-      template<class T> void mf1(T);
-    };
-    template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {}
-    // FIXME: This diagnostic isn't very good.
-    template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}}
-  }
-}
-
-namespace dr337 { // dr337: yes
-  template<typename T> void f(T (*)[1]);
-  template<typename T> int &f(...);
-
-  struct A { virtual ~A() = 0; };
-  int &r = f<A>(0);
-
-  // FIXME: The language rules here are completely broken. We cannot determine
-  // whether an incomplete type is abstract. See DR1640, which will probably
-  // supersede this one and remove this rule.
-  struct B;
-  int &s = f<B>(0); // expected-error {{of type 'void'}}
-  struct B { virtual ~B() = 0; };
-}
-
-namespace dr339 { // dr339: yes
-  template <int I> struct A { static const int value = I; };
-
-  char xxx(int);
-  char (&xxx(float))[2];
-
-  template<class T> A<sizeof(xxx((T)0))> f(T) {} // expected-note {{candidate}}
-
-  void test() {
-    A<1> a = f(0);
-    A<2> b = f(0.0f);
-    A<3> c = f("foo"); // expected-error {{no matching function}}
-  }
-
-
-  char f(int);
-  int f(...);
-
-  template <class T> struct conv_int {
-    static const bool value = sizeof(f(T())) == 1;
-  };
-
-  template <class T> bool conv_int2(A<sizeof(f(T()))> p);
-
-  template<typename T> A<sizeof(f(T()))> make_A();
-
-  int a[conv_int<char>::value ? 1 : -1];
-  bool b = conv_int2<char>(A<1>());
-  A<1> c = make_A<char>();
-}
-
-namespace dr340 { // dr340: yes
-  struct A { A(int); };
-  struct B { B(A, A, int); };
-  int x, y;
-  B b(A(x), A(y), 3);
-}
-
-namespace dr341 { // dr341: sup 1708
-  namespace A {
-    int n;
-    extern "C" int &dr341_a = n; // expected-note {{previous}} expected-note {{declared with C language linkage here}}
-  }
-  namespace B {
-    extern "C" int &dr341_a = dr341_a; // expected-error {{redefinition}}
-  }
-  extern "C" void dr341_b(); // expected-note {{declared with C language linkage here}}
-}
-int dr341_a; // expected-error {{declaration of 'dr341_a' in global scope conflicts with declaration with C language linkage}}
-int dr341_b; // expected-error {{declaration of 'dr341_b' in global scope conflicts with declaration with C language linkage}}
-int dr341_c; // expected-note {{declared in global scope here}}
-int dr341_d; // expected-note {{declared in global scope here}}
-namespace dr341 {
-  extern "C" int dr341_c; // expected-error {{declaration of 'dr341_c' with C language linkage conflicts with declaration in global scope}}
-  extern "C" void dr341_d(); // expected-error {{declaration of 'dr341_d' with C language linkage conflicts with declaration in global scope}}
-
-  namespace A { extern "C" int dr341_e; } // expected-note {{previous}}
-  namespace B { extern "C" void dr341_e(); } // expected-error {{redefinition of 'dr341_e' as different kind of symbol}}
-}
-
-// dr342: na
-
-namespace dr343 { // FIXME 343: no
-  // FIXME: dup 1710
-  template<typename T> struct A {
-    template<typename U> struct B {};
-  };
-  // FIXME: In these contexts, the 'template' keyword is optional.
-  template<typename T> struct C : public A<T>::B<T> { // expected-error {{use 'template'}}
-    C() : A<T>::B<T>() {} // expected-error {{use 'template'}}
-  };
-}
-
-namespace dr344 { // dr344: dup 1435
-  struct A { inline virtual ~A(); };
-  struct B { friend A::~A(); };
-}
-
-namespace dr345 { // dr345: yes
-  struct A {
-    struct X {};
-    int X; // expected-note {{here}}
-  };
-  struct B {
-    struct X {};
-  };
-  template <class T> void f(T t) { typename T::X x; } // expected-error {{refers to non-type member 'X'}}
-  void f(A a, B b) {
-    f(b);
-    f(a); // expected-note {{instantiation}}
-  }
-}
-
-// dr346: na
-
-namespace dr347 { // dr347: yes
-  struct base {
-    struct nested;
-    static int n;
-    static void f();
-    void g();
-  };
-
-  struct derived : base {};
-
-  struct derived::nested {}; // expected-error {{no struct named 'nested'}}
-  int derived::n; // expected-error {{no member named 'n'}}
-  void derived::f() {} // expected-error {{does not match any}}
-  void derived::g() {} // expected-error {{does not match any}}
-}
-
-// dr348: na
-
-namespace dr349 { // dr349: no
-  struct A {
-    template <class T> operator T ***() {
-      int ***p = 0;
-      return p; // expected-error {{cannot initialize return object of type 'const int ***' with an lvalue of type 'int ***'}}
-    }
-  };
-
-  // FIXME: This is valid.
-  A a;
-  const int *const *const *p1 = a; // expected-note {{in instantiation of}}
-
-  struct B {
-    template <class T> operator T ***() {
-      const int ***p = 0;
-      return p;
-    }
-  };
-
-  // FIXME: This is invalid.
-  B b;
-  const int *const *const *p2 = b;
-}
-
-// dr351: na
-
-namespace dr352 { // dr352: yes
-  namespace example1 {
-    namespace A {
-      enum E {};
-      template<typename R, typename A> void foo(E, R (*)(A)); // expected-note 2{{couldn't infer template argument 'R'}}
-    }
-
-    template<typename T> void arg(T);
-    template<typename T> int arg(T) = delete; // expected-note {{here}} expected-error 0-1{{extension}}
-
-    void f(A::E e) {
-      foo(e, &arg); // expected-error {{no matching function}}
-
-      using A::foo;
-      foo<int, int>(e, &arg); // expected-error {{deleted}}
-    }
-
-    int arg(int);
-
-    void g(A::E e) {
-      foo(e, &arg); // expected-error {{no matching function}}
-
-      using A::foo;
-      foo<int, int>(e, &arg); // ok, uses non-template
-    }
-  }
-
-  namespace contexts {
-    template<int I> void f1(int (&)[I]);
-    template<int I> void f2(int (&)[I+1]); // expected-note {{couldn't infer}}
-    template<int I> void f3(int (&)[I+1], int (&)[I]);
-    void f() {
-      int a[4];
-      int b[3];
-      f1(a);
-      f2(a); // expected-error {{no matching function}}
-      f3(a, b);
-    }
-
-    template<int I> struct S {};
-    template<int I> void g1(S<I>);
-    template<int I> void g2(S<I+1>); // expected-note {{couldn't infer}}
-    template<int I> void g3(S<I+1>, S<I>);
-    void g() {
-      S<4> a;
-      S<3> b;
-      g1(a);
-      g2(a); // expected-error {{no matching function}}
-      g3(a, b);
-    }
-
-    template<typename T> void h1(T = 0); // expected-note {{couldn't infer}}
-    template<typename T> void h2(T, T = 0);
-    void h() {
-      h1(); // expected-error {{no matching function}}
-      h1(0);
-      h1<int>();
-      h2(0);
-    }
-
-    template<typename T> int tmpl(T);
-    template<typename R, typename A> void i1(R (*)(A)); // expected-note 3{{couldn't infer}}
-    template<typename R, typename A> void i2(R, A, R (*)(A)); // expected-note {{not viable}}
-    void i() {
-      extern int single(int);
-      i1(single);
-      i2(0, 0, single);
-
-      extern int ambig(float), ambig(int);
-      i1(ambig); // expected-error {{no matching function}}
-      i2(0, 0, ambig);
-
-      extern void no_match(float), no_match(int);
-      i1(no_match); // expected-error {{no matching function}}
-      i2(0, 0, no_match); // expected-error {{no matching function}}
-
-      i1(tmpl); // expected-error {{no matching function}}
-      i2(0, 0, tmpl);
-    }
-  }
-
-  template<typename T> struct is_int;
-  template<> struct is_int<int> {};
-
-  namespace example2 {
-    template<typename T> int f(T (*p)(T)) { is_int<T>(); }
-    int g(int);
-    int g(char);
-    int i = f(g);
-  }
-
-  namespace example3 {
-    template<typename T> int f(T, T (*p)(T)) { is_int<T>(); }
-    int g(int);
-    char g(char);
-    int i = f(1, g);
-  }
-
-  namespace example4 {
-    template <class T> int f(T, T (*p)(T)) { is_int<T>(); }
-    char g(char);
-    template <class T> T g(T);
-    int i = f(1, g);
-  }
-
-  namespace example5 {
-    template<int I> class A {};
-    template<int I> void g(A<I+1>); // expected-note {{couldn't infer}}
-    template<int I> void f(A<I>, A<I+1>);
-    void h(A<1> a1, A<2> a2) {
-      g(a1); // expected-error {{no matching function}}
-      g<0>(a1);
-      f(a1, a2);
-    }
-  }
-}
-
-// dr353 needs an IRGen test.
-
-namespace dr354 { // dr354: yes c++11
-  // FIXME: Should we allow this in C++98 too?
-  struct S {};
-
-  template<int*> struct ptr {}; // expected-note 0-4{{here}}
-  ptr<0> p0;
-  ptr<(int*)0> p1;
-  ptr<(float*)0> p2;
-  ptr<(int S::*)0> p3;
-#if __cplusplus < 201103L
-  // expected-error@-5 {{does not refer to any decl}}
-  // expected-error@-5 {{does not refer to any decl}}
-  // expected-error@-5 {{does not refer to any decl}}
-  // expected-error@-5 {{does not refer to any decl}}
-#elif __cplusplus <= 201402L
-  // expected-error@-10 {{must be cast}}
-  // ok
-  // expected-error@-10 {{does not match}}
-  // expected-error@-10 {{does not match}}
-#else
-  // expected-error@-15 {{conversion from 'int' to 'int *' is not allowed}}
-  // ok
-  // expected-error@-15 {{'float *' is not implicitly convertible to 'int *'}}
-  // expected-error@-15 {{'int dr354::S::*' is not implicitly convertible to 'int *'}}
-#endif
-
-  template<int*> int both();
-  template<int> int both();
-  int b0 = both<0>();
-  int b1 = both<(int*)0>();
-#if __cplusplus < 201103L
-  // expected-error@-2 {{no matching function}}
-  // expected-note@-6 {{candidate}}
-  // expected-note@-6 {{candidate}}
-#endif
-
-  template<int S::*> struct ptr_mem {}; // expected-note 0-4{{here}}
-  ptr_mem<0> m0;
-  ptr_mem<(int S::*)0> m1;
-  ptr_mem<(float S::*)0> m2;
-  ptr_mem<(int *)0> m3;
-#if __cplusplus < 201103L
-  // expected-error@-5 {{cannot be converted}}
-  // expected-error@-5 {{is not a pointer to member constant}}
-  // expected-error@-5 {{cannot be converted}}
-  // expected-error@-5 {{cannot be converted}}
-#elif __cplusplus <= 201402L
-  // expected-error@-10 {{must be cast}}
-  // ok
-  // expected-error@-10 {{does not match}}
-  // expected-error@-10 {{does not match}}
-#else
-  // expected-error@-15 {{conversion from 'int' to 'int dr354::S::*' is not allowed}}
-  // ok
-  // expected-error@-15 {{'float dr354::S::*' is not implicitly convertible to 'int dr354::S::*'}}
-  // expected-error@-15 {{'int *' is not implicitly convertible to 'int dr354::S::*'}}
-#endif
-}
-
-struct dr355_S; // dr355: yes
-struct ::dr355_S {}; // expected-warning {{extra qualification}}
-namespace dr355 { struct ::dr355_S s; }
-
-// dr356: na
-
-namespace dr357 { // dr357: yes
-  template<typename T> struct A {
-    void f() const; // expected-note {{const qualified}}
-  };
-  template<typename T> void A<T>::f() {} // expected-error {{does not match}}
-
-  struct B {
-    template<typename T> void f();
-  };
-  template<typename T> void B::f() const {} // expected-error {{does not match}}
-}
-
-namespace dr358 { // dr358: yes
-  extern "C" void dr358_f();
-  namespace N {
-    int var;
-    extern "C" void dr358_f() { var = 10; }
-  }
-}
-
-namespace dr359 { // dr359: yes
-  // Note, the example in the DR is wrong; it doesn't contain an anonymous
-  // union.
-  struct E {
-    union {
-      struct {
-        int x;
-      } s;
-    } v;
-
-    union {
-      struct { // expected-error {{extension}}
-        int x;
-      } s;
-
-      struct S { // expected-error {{types cannot be declared in an anonymous union}}
-        int x;
-      } t;
-
-      union { // expected-error {{extension}}
-        int u;
-      };
-    };
-  };
-}
-
-// dr362: na
-// dr363: na
-
-namespace dr364 { // dr364: yes
-  struct S {
-    static void f(int);
-    void f(char);
-  };
-
-  void g() {
-    S::f('a'); // expected-error {{call to non-static}}
-    S::f(0);
-  }
-}
-
-#if "foo" // expected-error {{invalid token}} dr366: yes
-#endif
-
-namespace dr367 { // dr367: yes
-  // FIXME: These diagnostics are terrible. Don't diagnose an ill-formed global
-  // array as being a VLA!
-  int a[true ? throw 0 : 4]; // expected-error 2{{variable length array}}
-  int b[true ? 4 : throw 0];
-  int c[true ? *new int : 4]; // expected-error 2{{variable length array}}
-  int d[true ? 4 : *new int];
-#if __cplusplus < 201103L
-  // expected-error@-4 {{variable length array}} expected-error@-4 {{constant expression}}
-  // expected-error@-3 {{variable length array}} expected-error@-3 {{constant expression}}
-#endif
-}
-
-namespace dr368 { // dr368: yes
-  template<typename T, T> struct S {}; // expected-note {{here}}
-  template<typename T> int f(S<T, T()> *); // expected-error {{function type}}
-  //template<typename T> int g(S<T, (T())> *); // FIXME: crashes clang
-  template<typename T> int g(S<T, true ? T() : T()> *); // expected-note {{cannot have type 'dr368::X'}}
-  struct X {};
-  int n = g<X>(0); // expected-error {{no matching}}
-}
-
-// dr370: na
-
-namespace dr372 { // dr372: no
-  namespace example1 {
-    template<typename T> struct X {
-    protected:
-      typedef T Type; // expected-note 2{{protected}}
-    };
-    template<typename T> struct Y {};
-
-    // FIXME: These two are valid; deriving from T1<T> gives Z1 access to
-    // the protected member T1<T>::Type.
-    template<typename T,
-             template<typename> class T1,
-             template<typename> class T2> struct Z1 :
-      T1<T>,
-      T2<typename T1<T>::Type> {}; // expected-error {{protected}}
-
-    template<typename T,
-             template<typename> class T1,
-             template<typename> class T2> struct Z2 :
-      T2<typename T1<T>::Type>, // expected-error {{protected}}
-      T1<T> {};
-
-    Z1<int, X, Y> z1; // expected-note {{instantiation of}}
-    Z2<int, X, Y> z2; // expected-note {{instantiation of}}
-  }
-
-  namespace example2 {
-    struct X {
-    private:
-      typedef int Type; // expected-note {{private}}
-    };
-    template<typename T> struct A {
-      typename T::Type t; // expected-error {{private}}
-    };
-    A<X> ax; // expected-note {{instantiation of}}
-  }
-
-  namespace example3 {
-    struct A {
-    protected:
-      typedef int N; // expected-note 2{{protected}}
-    };
-
-    template<typename T> struct B {};
-    template<typename U> struct C : U, B<typename U::N> {}; // expected-error {{protected}}
-    template<typename U> struct D : B<typename U::N>, U {}; // expected-error {{protected}}
-
-    C<A> x; // expected-note {{instantiation of}}
-    D<A> y; // expected-note {{instantiation of}}
-  }
-
-  namespace example4 {
-    class A {
-      class B {};
-      friend class X;
-    };
-
-    struct X : A::B {
-      A::B mx;
-      class Y {
-        A::B my;
-      };
-    };
-  }
-}
-
-namespace dr373 { // dr373: no
-  // FIXME: This is valid.
-  namespace X { int dr373; } // expected-note 2{{here}}
-  struct dr373 { // expected-note {{here}}
-    void f() {
-      using namespace dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}}
-      int k = dr373; // expected-error {{does not refer to a value}}
-
-      namespace Y = dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}}
-      k = Y::dr373;
-    }
-  };
-}
-
-namespace dr374 { // dr374: yes c++11
-  namespace N {
-    template<typename T> void f();
-    template<typename T> struct A { void f(); };
-  }
-  template<> void N::f<char>() {}
-  template<> void N::A<char>::f() {}
-  template<> struct N::A<int> {};
-#if __cplusplus < 201103L
-  // expected-error@-4 {{extension}} expected-note@-7 {{here}}
-  // expected-error@-4 {{extension}} expected-note@-7 {{here}}
-  // expected-error@-4 {{extension}} expected-note@-8 {{here}}
-#endif
-}
-
-// dr375: dup 345
-// dr376: na
-
-namespace dr377 { // dr377: yes
-  enum E { // expected-error {{enumeration values exceed range of largest integer}}
-    a = -__LONG_LONG_MAX__ - 1, // expected-error 0-1{{extension}}
-    b = 2 * (unsigned long long)__LONG_LONG_MAX__ // expected-error 0-2{{extension}}
-  };
-}
-
-// dr378: dup 276
-// dr379: na
-
-namespace dr381 { // dr381: yes
-  struct A {
-    int a;
-  };
-  struct B : virtual A {};
-  struct C : B {};
-  struct D : B {};
-  struct E : public C, public D {};
-  struct F : public A {};
-  void f() {
-    E e;
-    e.B::a = 0; // expected-error {{ambiguous conversion}}
-    F f;
-    f.A::a = 1;
-  }
-}
-
-namespace dr382 { // dr382: yes c++11
-  // FIXME: Should we allow this in C++98 mode?
-  struct A { typedef int T; };
-  typename A::T t;
-  typename dr382::A a;
-#if __cplusplus < 201103L
-  // expected-error@-3 {{occurs outside of a template}}
-  // expected-error@-3 {{occurs outside of a template}}
-#endif
-  typename A b; // expected-error {{expected a qualified name}}
-}
-
-namespace dr383 { // dr383: yes
-  struct A { A &operator=(const A&); };
-  struct B { ~B(); };
-  union C { C &operator=(const C&); };
-  union D { ~D(); };
-  int check[(__is_pod(A) || __is_pod(B) || __is_pod(C) || __is_pod(D)) ? -1 : 1];
-}
-
-namespace dr384 { // dr384: yes
-  namespace N1 {
-    template<typename T> struct Base {};
-    template<typename T> struct X {
-      struct Y : public Base<T> {
-        Y operator+(int) const;
-      };
-      Y f(unsigned i) { return Y() + i; }
-    };
-  }
-
-  namespace N2 {
-    struct Z {};
-    template<typename T> int *operator+(T, unsigned);
-  }
-
-  int main() {
-    N1::X<N2::Z> v;
-    v.f(0);
-  }
-}
-
-namespace dr385 { // dr385: yes
-  struct A { protected: void f(); }; 
-  struct B : A { using A::f; };
-  struct C : A { void g(B b) { b.f(); } };
-  void h(B b) { b.f(); }
-
-  struct D { int n; }; // expected-note {{member}}
-  struct E : protected D {}; // expected-note 2{{protected}}
-  struct F : E { friend int i(E); };
-  int i(E e) { return e.n; } // expected-error {{protected base}} expected-error {{protected member}}
-}
-
-namespace dr387 { // dr387: yes
-  namespace old {
-    template<typename T> class number {
-      number(int); // expected-note 2{{here}}
-      friend number gcd(number &x, number &y) {}
-    };
-
-    void g() {
-      number<double> a(3), b(4); // expected-error 2{{private}}
-      a = gcd(a, b);
-      b = gcd(3, 4); // expected-error {{undeclared}}
-    }
-  }
-
-  namespace newer {
-    template <typename T> class number {
-    public:
-      number(int);
-      friend number gcd(number x, number y) { return 0; }
-    };
-
-    void g() {
-      number<double> a(3), b(4);
-      a = gcd(a, b);
-      b = gcd(3, 4); // expected-error {{undeclared}}
-    }
-  }
-}
-
-// FIXME: dr388 needs codegen test
-
-namespace dr389 { // dr389: no
-  struct S {
-    typedef struct {} A;
-    typedef enum {} B;
-    typedef struct {} const C; // expected-note 0-2{{here}}
-    typedef enum {} const D; // expected-note 0-1{{here}}
-  };
-  template<typename> struct T {};
-
-  struct WithLinkage1 {};
-  enum WithLinkage2 {};
-  typedef struct {} *WithLinkage3a, WithLinkage3b;
-  typedef enum {} WithLinkage4a, *WithLinkage4b;
-  typedef S::A WithLinkage5;
-  typedef const S::B WithLinkage6;
-  typedef int WithLinkage7;
-  typedef void (*WithLinkage8)(WithLinkage2 WithLinkage1::*, WithLinkage5 *);
-  typedef T<WithLinkage5> WithLinkage9;
-
-  typedef struct {} *WithoutLinkage1; // expected-note 0-1{{here}}
-  typedef enum {} const WithoutLinkage2; // expected-note 0-1{{here}}
-  // These two types don't have linkage even though they are externally visible
-  // and the ODR requires them to be merged across TUs.
-  typedef S::C WithoutLinkage3;
-  typedef S::D WithoutLinkage4;
-  typedef void (*WithoutLinkage5)(int (WithoutLinkage3::*)(char));
-
-#if __cplusplus >= 201103L
-  // This has linkage even though its template argument does not.
-  // FIXME: This is probably a defect.
-  typedef T<WithoutLinkage1> WithLinkage10;
-#else
-  typedef int WithLinkage10; // dummy
-
-  typedef T<WithLinkage1> GoodArg1;
-  typedef T<WithLinkage2> GoodArg2;
-  typedef T<WithLinkage3a> GoodArg3a;
-  typedef T<WithLinkage3b> GoodArg3b;
-  typedef T<WithLinkage4a> GoodArg4a;
-  typedef T<WithLinkage4b> GoodArg4b;
-  typedef T<WithLinkage5> GoodArg5;
-  typedef T<WithLinkage6> GoodArg6;
-  typedef T<WithLinkage7> GoodArg7;
-  typedef T<WithLinkage8> GoodArg8;
-  typedef T<WithLinkage9> GoodArg9;
-
-  typedef T<WithoutLinkage1> BadArg1; // expected-error{{template argument uses}}
-  typedef T<WithoutLinkage2> BadArg2; // expected-error{{template argument uses}}
-  typedef T<WithoutLinkage3> BadArg3; // expected-error{{template argument uses}}
-  typedef T<WithoutLinkage4> BadArg4; // expected-error{{template argument uses}}
-  typedef T<WithoutLinkage5> BadArg5; // expected-error{{template argument uses}}
-#endif
-
-  extern WithLinkage1 withLinkage1;
-  extern WithLinkage2 withLinkage2;
-  extern WithLinkage3a withLinkage3a;
-  extern WithLinkage3b withLinkage3b;
-  extern WithLinkage4a withLinkage4a;
-  extern WithLinkage4b withLinkage4b;
-  extern WithLinkage5 withLinkage5;
-  extern WithLinkage6 withLinkage6;
-  extern WithLinkage7 withLinkage7;
-  extern WithLinkage8 withLinkage8;
-  extern WithLinkage9 withLinkage9;
-  extern WithLinkage10 withLinkage10;
-
-  // FIXME: These are all ill-formed.
-  extern WithoutLinkage1 withoutLinkage1;
-  extern WithoutLinkage2 withoutLinkage2;
-  extern WithoutLinkage3 withoutLinkage3;
-  extern WithoutLinkage4 withoutLinkage4;
-  extern WithoutLinkage5 withoutLinkage5;
-
-  // OK, extern "C".
-  extern "C" {
-    extern WithoutLinkage1 dr389_withoutLinkage1;
-    extern WithoutLinkage2 dr389_withoutLinkage2;
-    extern WithoutLinkage3 dr389_withoutLinkage3;
-    extern WithoutLinkage4 dr389_withoutLinkage4;
-    extern WithoutLinkage5 dr389_withoutLinkage5;
-  }
-
-  // OK, defined.
-  WithoutLinkage1 withoutLinkageDef1;
-  WithoutLinkage2 withoutLinkageDef2 = WithoutLinkage2();
-  WithoutLinkage3 withoutLinkageDef3 = {};
-  WithoutLinkage4 withoutLinkageDef4 = WithoutLinkage4();
-  WithoutLinkage5 withoutLinkageDef5;
-
-  void use(const void *);
-  void use_all() {
-    use(&withLinkage1); use(&withLinkage2); use(&withLinkage3a); use(&withLinkage3b);
-    use(&withLinkage4a); use(&withLinkage4b); use(&withLinkage5); use(&withLinkage6);
-    use(&withLinkage7); use(&withLinkage8); use(&withLinkage9); use(&withLinkage10);
-
-    use(&withoutLinkage1); use(&withoutLinkage2); use(&withoutLinkage3);
-    use(&withoutLinkage4); use(&withoutLinkage5);
-
-    use(&dr389_withoutLinkage1); use(&dr389_withoutLinkage2);
-    use(&dr389_withoutLinkage3); use(&dr389_withoutLinkage4);
-    use(&dr389_withoutLinkage5);
-
-    use(&withoutLinkageDef1); use(&withoutLinkageDef2); use(&withoutLinkageDef3);
-    use(&withoutLinkageDef4); use(&withoutLinkageDef5);
-  }
-
-  void local() {
-    // FIXME: This is ill-formed.
-    extern WithoutLinkage1 withoutLinkageLocal;
-  }
-}
-
-namespace dr390 { // dr390: yes
-  template<typename T>
-  struct A {
-    A() { f(); } // expected-warning {{call to pure virt}}
-    virtual void f() = 0; // expected-note {{here}}
-    virtual ~A() = 0;
-  };
-  template<typename T> A<T>::~A() { T::error; } // expected-error {{cannot be used prior to}}
-  template<typename T> void A<T>::f() { T::error; } // ok, not odr-used
-  struct B : A<int> { // expected-note 2{{in instantiation of}}
-    void f() {}
-  } b;
-}
-
-namespace dr391 { // dr391: yes c++11
-  // FIXME: Should this apply to C++98 too?
-  class A { A(const A&); }; // expected-note 0-1{{here}}
-  A fa();
-  const A &a = fa();
-#if __cplusplus < 201103L
-  // expected-error@-2 {{C++98 requires an accessible copy constructor}}
-#endif
-
-  struct B { B(const B&) = delete; }; // expected-error 0-1{{extension}} expected-note 0-1{{here}}
-  B fb();
-  const B &b = fb();
-#if __cplusplus < 201103L
-  // expected-error@-2 {{deleted}}
-#endif
-
-  template<typename T>
-  struct C {
-    C(const C&) { T::error; }
-  };
-  C<int> fc();
-  const C<int> &c = fc();
-}
-
-// dr392 FIXME write codegen test
-// dr394: na
-
-namespace dr395 { // dr395: yes
-  struct S {
-    template <typename T, int N>(&operator T())[N]; // expected-error {{cannot specify any part of a return type}}
-    template <typename T, int N> operator(T (&)[N])(); // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error +{{}}
-    template <typename T> operator T *() const { return 0; }
-    template <typename T, typename U> operator T U::*() const { return 0; }
-    template <typename T, typename U> operator T (U::*)()() const { return 0; } // expected-error +{{}}
-  };
-
-  struct null1_t {
-    template <class T, class U> struct ptr_mem_fun_t {
-      typedef T (U::*type)();
-    };
-
-    template <class T, class U>
-    operator typename ptr_mem_fun_t<T, U>::type() const { // expected-note {{couldn't infer}}
-      return 0;
-    }
-  } null1;
-  int (S::*p)() = null1; // expected-error {{no viable conversion}}
-
-  template <typename T> using id = T; // expected-error 0-1{{extension}}
-
-  struct T {
-    template <typename T, int N> operator id<T[N]> &();
-    template <typename T, typename U> operator id<T (U::*)()>() const;
-  };
-
-  struct null2_t {
-    template<class T, class U> using ptr_mem_fun_t = T (U::*)(); // expected-error 0-1{{extension}}
-    template<class T, class U> operator ptr_mem_fun_t<T, U>() const { return 0; };
-  } null2;
-  int (S::*q)() = null2;
-}
-
-namespace dr396 { // dr396: yes
-  void f() {
-    auto int a(); // expected-error {{storage class on function}}
-    int (i); // expected-note {{previous}}
-    auto int (i); // expected-error {{redefinition}}
-#if __cplusplus >= 201103L
-  // expected-error@-4 {{'auto' storage class}} expected-error@-2 {{'auto' storage class}}
-#endif
-  }
-}
-
-// dr397: sup 1823
-
-namespace dr398 { // dr398: yes
-  namespace example1 {
-    struct S {
-      static int const I = 42;
-    };
-    template <int N> struct X {};
-    template <typename T> void f(X<T::I> *) {}
-    template <typename T> void f(X<T::J> *) {}
-    void foo() { f<S>(0); }
-  }
-
-  namespace example2 {
-    template <int I> struct X {};
-    template <template <class T> class> struct Z {};
-    template <class T> void f(typename T::Y *) {} // expected-note 2{{substitution failure}}
-    template <class T> void g(X<T::N> *) {} // expected-note {{substitution failure}}
-    template <class T> void h(Z<T::template TT> *) {} // expected-note {{substitution failure}}
-    struct A {};
-    struct B {
-      int Y;
-    };
-    struct C {
-      typedef int N;
-    };
-    struct D {
-      typedef int TT;
-    };
-
-    void test() {
-      f<A>(0); // expected-error {{no matching function}}
-      f<B>(0); // expected-error {{no matching function}}
-      g<C>(0); // expected-error {{no matching function}}
-      h<D>(0); // expected-error {{no matching function}}
-    }
-  }
-}
Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -185,14 +185,8 @@
   }
 
   // Load any requested plugins.
-  for (unsigned i = 0,
-         e = Clang->getFrontendOpts().Plugins.size(); i != e; ++i) {
-    const std::string &Path = Clang->getFrontendOpts().Plugins[i];
-    std::string Error;
-    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
-      Clang->getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
-        << Path << Error;
-  }
+  Clang->loadPlugins();
+
 
   // Honor -mllvm.
   //
Index: lib/Frontend/CompilerInstance.cpp
===================================================================
--- lib/Frontend/CompilerInstance.cpp
+++ lib/Frontend/CompilerInstance.cpp
@@ -45,6 +45,7 @@
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/DynamicLibrary.h"
 #include <sys/stat.h>
 #include <system_error>
 #include <time.h>
@@ -1752,3 +1753,15 @@
   return false;
 }
 void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); }
+
+void
+CompilerInstance::loadPlugins(){
+  // Load any requested plugins.
+  for (unsigned i = 0, e = getFrontendOpts().Plugins.size(); i != e; ++i) {
+    const std::string &Path = getFrontendOpts().Plugins[i];
+    std::string Error;
+    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))
+      getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)
+        << Path << Error;
+  }
+}
Index: lib/Frontend/ASTUnit.cpp
===================================================================
--- lib/Frontend/ASTUnit.cpp
+++ lib/Frontend/ASTUnit.cpp
@@ -1135,6 +1135,8 @@
   llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
     ActCleanup(Act.get());
 
+  Clang->loadPlugins();
+
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
     goto error;
 
Index: include/clang/Frontend/CompilerInstance.h
===================================================================
--- include/clang/Frontend/CompilerInstance.h
+++ include/clang/Frontend/CompilerInstance.h
@@ -779,6 +779,9 @@
   void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
     DependencyCollectors.push_back(std::move(Listener));
   }
+
+  /// load plugins that were added by -load
+  void loadPlugins();
 };
 
 } // end namespace clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to