Skip to content
  1. Jun 26, 2009
    • Douglas Gregor's avatar
      Implicit instantiation for function template specializations. · 4adbc6d9
      Douglas Gregor authored
      For a FunctionDecl that has been instantiated due to template argument
      deduction, we now store the primary template from which it was
      instantiated and the deduced template arguments. From this
      information, we can instantiate the body of the function template.
      
      llvm-svn: 74232
      4adbc6d9
    • Douglas Gregor's avatar
      Improved semantic analysis and AST respresentation for function · ad3f2fcf
      Douglas Gregor authored
      templates.
      
      For example, this now type-checks (but does not instantiate the body
      of deref<int>):
      
        template<typename T> T& deref(T* t) { return *t; }
      
        void test(int *ip) {
          int &ir = deref(ip);
        }
      
      Specific changes/additions:
        * Template argument deduction from a call to a function template.
        * Instantiation of a function template specializations (just the
        declarations) from the template arguments deduced from a call.
        * FunctionTemplateDecls are stored directly in declaration contexts
        and found via name lookup (all forms), rather than finding the
        FunctionDecl and then realizing it is a template. This is
        responsible for most of the churn, since some of the core
        declaration matching and lookup code assumes that all functions are
        FunctionDecls.
      
      llvm-svn: 74213
      ad3f2fcf
  2. Jun 23, 2009
  3. Jun 22, 2009
    • Douglas Gregor's avatar
      Rework the way we track which declarations are "used" during · 0b6a6242
      Douglas Gregor authored
      compilation, and (hopefully) introduce RAII objects for changing the
      "potentially evaluated" state at all of the necessary places within
      Sema and Parser. Other changes:
      
        - Set the unevaluated/potentially-evaluated context appropriately
          during template instantiation.
        - We now recognize three different states while parsing or
          instantiating expressions: unevaluated, potentially evaluated, and
          potentially potentially evaluated (for C++'s typeid).
        - When we're in a potentially potentially-evaluated context, queue
          up MarkDeclarationReferenced calls in a stack. For C++ typeid
          expressions that are potentially evaluated, we will play back
          these MarkDeclarationReferenced calls when we exit the
          corresponding potentially potentially-evaluated context.
        - Non-type template arguments are now parsed as constant
          expressions, so they are not potentially-evaluated.
      
      llvm-svn: 73899
      0b6a6242
  4. May 29, 2009
  5. May 28, 2009
    • Douglas Gregor's avatar
      Introduced DeclContext::isDependentContext, which determines whether a · 9e927abc
      Douglas Gregor authored
      given DeclContext is dependent on type parameters. Use this to
      properly determine whether a TagDecl is dependent; previously, we were
      missing the case where the TagDecl is a local class of a member
      function of a class template (phew!).
      
      Also, make sure that, when we instantiate declarations within a member
      function of a class template (or a function template, eventually),
      that we add those declarations to the "instantiated locals" map so
      that they can be found when instantiating declaration references.
      
      Unfortunately, I was not able to write a useful test for this change,
      although the assert() that fires when uncommenting the FIXME'd line in
      test/SemaTemplate/instantiate-declref.cpp tells the "experienced user"
      that we're now doing the right thing.
      
      llvm-svn: 72526
      9e927abc
  6. May 27, 2009
    • Douglas Gregor's avatar
      Simplify, and improve the performance of, template instantiation for · cd3a0979
      Douglas Gregor authored
      declaration references. The key realization is that dependent Decls,
      which actually require instantiation, can only refer to the current
      instantiation or members thereof. And, since the current context
      during instantiation contains all of those members of the current
      instantiation, we can simply find the real instantiate that matches up
      with the "current instantiation" template.
      
      llvm-svn: 72486
      cd3a0979
    • Douglas Gregor's avatar
      Enumeration declarations that were instantiated from an enumeration · 7a74938f
      Douglas Gregor authored
      within a template now have a link back to the enumeration from which
      they were instantiated. This means that we can now find the
      instantiation of an anonymous enumeration.
      
      llvm-svn: 72482
      7a74938f
    • Douglas Gregor's avatar
      Improve name lookup for and template instantiation of declaration · f98d9b60
      Douglas Gregor authored
      references. There are several smallish fixes here:
      
        - Make sure we look through template parameter scope when
          determining whether we're parsing a nested class (or nested class
          *template*). This makes sure that we delay parsing the bodies of
          inline member functions until after we're out of the outermost
          class (template) scope.
        - Since the bodies of member functions are always parsed
          "out-of-line", even when they were declared in-line, teach
          unqualified name lookup to look into the (semantic) parents.
        - Use the new InstantiateDeclRef to handle the instantiation of a
          reference to a declaration (in DeclRefExpr), which drastically
          simplifies template instantiation for DeclRefExprs.
        - When we're instantiating a ParmVarDecl, it must be in the current
          instantiation scope, so only look there.
      
      Also, remove the #if 0's and FIXME's from the dynarray example, which
      now compiles and executes thanks to Anders and Eli.
      
      llvm-svn: 72481
      f98d9b60
    • Douglas Gregor's avatar
      Initial stab at a generalized operation for determining the · 51783313
      Douglas Gregor authored
      instantiation of a declaration from the template version (or version
      that lives in a template) and a given set of template arguments. This
      needs much, much more testing, but it suffices for simple examples
      like
      
        typedef T* iterator;
        iterator begin();
      
      llvm-svn: 72461
      51783313
  7. May 26, 2009
  8. May 21, 2009
  9. May 18, 2009
  10. May 16, 2009
  11. May 15, 2009
  12. May 14, 2009
  13. May 13, 2009
  14. May 12, 2009
  15. May 11, 2009
    • Douglas Gregor's avatar
      Implement the semantics of the injected-class-name within a class · e362cea5
      Douglas Gregor authored
      template. The injected-class-name is either a type or a template,
      depending on whether a '<' follows it. As a type, the
      injected-class-name's template argument list contains its template
      parameters in declaration order.
      
      As part of this, add logic for canonicalizing declarations, and be
      sure to canonicalize declarations used in template names and template
      arguments. 
      
      A TagType is dependent if the declaration it references is dependent.
      
      I'm not happy about the rather complicated protocol needed to use
      ASTContext::getTemplateSpecializationType.
      
      llvm-svn: 71408
      e362cea5
  16. May 01, 2009
  17. Apr 25, 2009
    • Chris Lattner's avatar
      This is a pretty big cleanup for how invalid decl/type are handle. · f6d1c9c7
      Chris Lattner authored
      This gets rid of a bunch of random InvalidDecl bools in sema, changing
      us to use the following approach:
      
      1. When analyzing a declspec or declarator, if an error is found, we 
         set a bit in Declarator saying that it is invalid.
      2. Once the Decl is created by sema, we immediately set the isInvalid
         bit on it from what is in the declarator.  From this point on, sema
         consistently looks at and sets the bit on the decl.
      
      This gives a very clear separation of concerns and simplifies a bunch
      of code.  In addition to this, this patch makes these changes:
      
      1. it renames DeclSpec::getInvalidType() -> isInvalidType().
      2. various "merge" functions no longer return bools: they just set the
         invalid bit on the dest decl if invalid.
      3. The ActOnTypedefDeclarator/ActOnFunctionDeclarator/ActOnVariableDeclarator
         methods now set invalid on the decl returned instead of returning an
         invalid bit byref.
      4. In SemaType, refering to a typedef that was invalid now propagates the
         bit into the resultant type.  Stuff declared with the invalid typedef
         will now be marked invalid.
      5. Various methods like CheckVariableDeclaration now return void and set the
         invalid bit on the decl they check.
      
      
      There are a few minor changes to tests with this, but the only major bad
      result is test/SemaCXX/constructor-recovery.cpp.  I'll take a look at this
      next.
      
      llvm-svn: 70020
      f6d1c9c7
  18. Apr 09, 2009
  19. Mar 28, 2009
    • Chris Lattner's avatar
      Introduce a new OpaquePtr<N> struct type, which is a simple POD wrapper for a · 83f095cc
      Chris Lattner authored
      pointer.  Its purpose in life is to be a glorified void*, but which does not
      implicitly convert to void* or other OpaquePtr's with a different UID.
      
      Introduce Action::DeclPtrTy which is a typedef for OpaquePtr<0>.  Change the 
      entire parser/sema interface to use DeclPtrTy instead of DeclTy*.  This
      makes the C++ compiler enforce that these aren't convertible to other opaque
      types.
      
      We should also convert ExprTy, StmtTy, TypeTy, AttrTy, BaseTy, etc,
      but I don't plan to do that in the short term.
      
      The one outstanding known problem with this patch is that we lose the 
      bitmangling optimization where ActionResult<DeclPtrTy> doesn't know how to
      bitmangle the success bit into the low bit of DeclPtrTy.  I will rectify
      this with a subsequent patch.
      
      llvm-svn: 67952
      83f095cc
  20. Mar 26, 2009
    • Douglas Gregor's avatar
      The injected-class-name of class templates and class template · 97f1f1c4
      Douglas Gregor authored
      specializations can be treated as a template. Finally, we can parse
      and process the first implementation of Fibonacci I wrote!
      
      Note that this code does not handle all of the cases where
      injected-class-names can be treated as templates. In particular,
      there's an ambiguity case that we should be able to handle (but
      can't), e.g.,
      
        template <class T> struct Base { }; 
        template <class T> struct Derived : Base<int>, Base<char> {
          typename Derived::Base b;       // error: ambiguous
          typename Derived::Base<double> d;  // OK 
        };
      
      llvm-svn: 67720
      97f1f1c4
    • Douglas Gregor's avatar
      Implement template instantiation for static data members of class · ef1a09a3
      Douglas Gregor authored
      templates, including in-class initializers. For example:
      
        template<typename T, T Divisor>
        class X {
        public:
          static const T value = 10 / Divisor;
        };
      
      instantiated with, e.g.,
      
        X<int, 5>::value
      
      to get the value '2'.
      
      llvm-svn: 67715
      ef1a09a3
  21. Mar 25, 2009
  22. Mar 24, 2009
Loading