printing logic to help customize the output. For now, we use this
rather than a special flag to suppress the "struct" when printing
"struct X" and to print the Boolean type as "bool" in C++ but "_Bool"
in C.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72590 91177308-0d34-0410-b5e6-96231b3b80d8
instantiation of tags local to member functions of class templates
(and, eventually, function templates) works when the tag is defined as
part of the decl-specifier-seq, e.g.,
struct S { T x, y; } s1;
Also, make sure that we don't try to default-initialize a dependent
type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72568 91177308-0d34-0410-b5e6-96231b3b80d8
specifier resulted in the creation of a new TagDecl node, which
happens either when the tag specifier was a definition or when the tag
specifier was the first declaration of that tag type. This information
has several uses, the first of which is implemented in this commit:
1) In C++, one is not allowed to define tag types within a type
specifier (e.g., static_cast<struct S { int x; } *>(0) is
ill-formed) or within the result or parameter types of a
function. We now diagnose this.
2) We can extend DeclGroups to contain information about any tags
that are declared/defined within the declaration specifiers of a
variable, e.g.,
struct Point { int x, y, z; } p;
This will help improve AST printing and template instantiation,
among other things.
3) For C99, we can keep track of whether a tag type is defined
within the type of a parameter, to properly cope with cases like,
e.g.,
int bar(struct T2 { int x; } y) {
struct T2 z;
}
We can also do similar things wherever there is a type specifier,
e.g., to keep track of where the definition of S occurs in this
legal C99 code:
(struct S { int x, y; } *)0
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72555 91177308-0d34-0410-b5e6-96231b3b80d8
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72526 91177308-0d34-0410-b5e6-96231b3b80d8
diagnostic to include the full instantiation location for the
invalid paste. For:
#define foo(a, b) a ## b
#define bar(x) foo(x, ])
bar(a)
bar(zdy)
Instead of:
t.c:3:22: error: pasting formed 'a]', an invalid preprocessing token
#define foo(a, b) a ## b
^
t.c:3:22: error: pasting formed 'zdy]', an invalid preprocessing token
we now produce:
t.c:7:1: error: pasting formed 'a]', an invalid preprocessing token
bar(a)
^
t.c:4:16: note: instantiated from:
#define bar(x) foo(x, ])
^
t.c:3:22: note: instantiated from:
#define foo(a, b) a ## b
^
t.c:8:1: error: pasting formed 'zdy]', an invalid preprocessing token
bar(zdy)
^
t.c:4:16: note: instantiated from:
#define bar(x) foo(x, ])
^
t.c:3:22: note: instantiated from:
#define foo(a, b) a ## b
^
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72519 91177308-0d34-0410-b5e6-96231b3b80d8
parser. Rather than placing all of the delayed member function
declarations and inline definitions into a single bucket corresponding
to the top-level class, we instead mirror the nesting structure of the
nested classes and place the delayed member functions into their
appropriate place. Then, when we actually parse the delayed member
function declarations, set up the scope stack the same way as it was
when we originally saw the declaration, so that we can find, e.g.,
template parameters that are in scope.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72502 91177308-0d34-0410-b5e6-96231b3b80d8
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72486 91177308-0d34-0410-b5e6-96231b3b80d8
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72482 91177308-0d34-0410-b5e6-96231b3b80d8
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72481 91177308-0d34-0410-b5e6-96231b3b80d8