зеркало из https://github.com/microsoft/clang-1.git
Parser support for C++ using directives, from Piotr Rak
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61486 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
fc820a4394
Коммит
f780abc21c
|
@ -1462,6 +1462,10 @@ DIAG(err_expected_class_name, ERROR,
|
||||||
DIAG(err_anon_type_definition, ERROR,
|
DIAG(err_anon_type_definition, ERROR,
|
||||||
"declaration of anonymous %0 must be a definition")
|
"declaration of anonymous %0 must be a definition")
|
||||||
|
|
||||||
|
// Namespaces.
|
||||||
|
DIAG(err_expected_namespace_name, ERROR,
|
||||||
|
"expected namespace name")
|
||||||
|
|
||||||
// C++ member initializers.
|
// C++ member initializers.
|
||||||
DIAG(err_mem_init_not_member_or_class, ERROR,
|
DIAG(err_mem_init_not_member_or_class, ERROR,
|
||||||
"member initializer %0 does not name a non-static data member or base "
|
"member initializer %0 does not name a non-static data member or base "
|
||||||
|
|
|
@ -731,6 +731,15 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ActOnUsingDirective - This is called when using-directive is parsed.
|
||||||
|
virtual DeclTy *ActOnUsingDirective(Scope *CurScope,
|
||||||
|
SourceLocation UsingLoc,
|
||||||
|
SourceLocation NamespcLoc,
|
||||||
|
const CXXScopeSpec &SS,
|
||||||
|
SourceLocation IdentLoc,
|
||||||
|
IdentifierInfo *NamespcName,
|
||||||
|
AttributeList *AttrList);
|
||||||
|
|
||||||
/// ActOnParamDefaultArgument - Parse default argument for function parameter
|
/// ActOnParamDefaultArgument - Parse default argument for function parameter
|
||||||
virtual void ActOnParamDefaultArgument(DeclTy *param,
|
virtual void ActOnParamDefaultArgument(DeclTy *param,
|
||||||
SourceLocation EqualLoc,
|
SourceLocation EqualLoc,
|
||||||
|
|
|
@ -931,6 +931,9 @@ private:
|
||||||
|
|
||||||
DeclTy *ParseNamespace(unsigned Context);
|
DeclTy *ParseNamespace(unsigned Context);
|
||||||
DeclTy *ParseLinkage(unsigned Context);
|
DeclTy *ParseLinkage(unsigned Context);
|
||||||
|
DeclTy *ParseUsingDirectiveOrDeclaration(unsigned Context);
|
||||||
|
DeclTy *ParseUsingDirective(unsigned Context, SourceLocation UsingLoc);
|
||||||
|
DeclTy *ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C++ 9: classes [class] and C structs/unions.
|
// C++ 9: classes [class] and C structs/unions.
|
||||||
|
|
|
@ -216,6 +216,8 @@ void Parser::FuzzyParseMicrosoftDeclSpec() {
|
||||||
/// others [FIXME]
|
/// others [FIXME]
|
||||||
/// [C++] template-declaration
|
/// [C++] template-declaration
|
||||||
/// [C++] namespace-definition
|
/// [C++] namespace-definition
|
||||||
|
/// [C++] using-directive
|
||||||
|
/// [C++] using-declaration [TODO]
|
||||||
/// others... [FIXME]
|
/// others... [FIXME]
|
||||||
///
|
///
|
||||||
Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
|
Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
|
||||||
|
@ -225,6 +227,8 @@ Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
|
||||||
return ParseTemplateDeclaration(Context);
|
return ParseTemplateDeclaration(Context);
|
||||||
case tok::kw_namespace:
|
case tok::kw_namespace:
|
||||||
return ParseNamespace(Context);
|
return ParseNamespace(Context);
|
||||||
|
case tok::kw_using:
|
||||||
|
return ParseUsingDirectiveOrDeclaration(Context);
|
||||||
default:
|
default:
|
||||||
return ParseSimpleDeclaration(Context);
|
return ParseSimpleDeclaration(Context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,91 @@ Parser::DeclTy *Parser::ParseLinkage(unsigned Context) {
|
||||||
&InnerDecls.front(), InnerDecls.size());
|
&InnerDecls.front(), InnerDecls.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
|
||||||
|
/// using-directive. Assumes that current token is 'using'.
|
||||||
|
Parser::DeclTy *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context)
|
||||||
|
{
|
||||||
|
assert(Tok.is(tok::kw_using) && "Not using token");
|
||||||
|
|
||||||
|
// Eat 'using'.
|
||||||
|
SourceLocation UsingLoc = ConsumeToken();
|
||||||
|
|
||||||
|
if (Tok.is(tok::kw_namespace)) {
|
||||||
|
// Next token after 'using' is 'namespace' so it must be using-directive
|
||||||
|
return ParseUsingDirective(Context, UsingLoc);
|
||||||
|
} else {
|
||||||
|
// Otherwise, it must be using-declaration.
|
||||||
|
return ParseUsingDeclaration(Context, UsingLoc); //FIXME: It is just stub.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ParseUsingDirective - Parse C++ using-directive, assumes
|
||||||
|
/// that current token is 'namespace' and 'using' was already parsed.
|
||||||
|
///
|
||||||
|
/// using-directive: [C++ 7.3.p4: namespace.udir]
|
||||||
|
/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
|
||||||
|
/// namespace-name ;
|
||||||
|
/// [GNU] using-directive:
|
||||||
|
/// 'using' 'namespace' ::[opt] nested-name-specifier[opt]
|
||||||
|
/// namespace-name attributes[opt] ;
|
||||||
|
///
|
||||||
|
Parser::DeclTy *Parser::ParseUsingDirective(unsigned Context,
|
||||||
|
SourceLocation UsingLoc) {
|
||||||
|
assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
|
||||||
|
|
||||||
|
// Eat 'namespace'.
|
||||||
|
SourceLocation NamespcLoc = ConsumeToken();
|
||||||
|
|
||||||
|
CXXScopeSpec SS;
|
||||||
|
// Parse (optional) nested-name-specifier.
|
||||||
|
MaybeParseCXXScopeSpecifier(SS);
|
||||||
|
|
||||||
|
AttributeList *AttrList = 0;
|
||||||
|
IdentifierInfo *NamespcName = 0;
|
||||||
|
SourceLocation IdentLoc = SourceLocation();
|
||||||
|
|
||||||
|
// Parse namespace-name.
|
||||||
|
if (!SS.isInvalid() && Tok.is(tok::identifier)) {
|
||||||
|
// Parse identifier.
|
||||||
|
NamespcName = Tok.getIdentifierInfo();
|
||||||
|
IdentLoc = ConsumeToken();
|
||||||
|
// Parse (optional) attributes (most likely GNU strong-using extension)
|
||||||
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
|
AttrList = ParseAttributes();
|
||||||
|
}
|
||||||
|
// Eat ';'.
|
||||||
|
if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
|
||||||
|
AttrList? "attributes list" : "namespace name")) {
|
||||||
|
SkipUntil(tok::semi);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Diag(Tok, diag::err_expected_namespace_name);
|
||||||
|
// If there was invalid namespace name, skip to end of decl, and eat ';'.
|
||||||
|
SkipUntil(tok::semi);
|
||||||
|
// FIXME: Are there cases, when we would like to call ActOnUsingDirective?
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Actions.ActOnUsingDirective(CurScope, UsingLoc, NamespcLoc, SS,
|
||||||
|
IdentLoc ,NamespcName, AttrList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
|
||||||
|
/// 'using' was already seen.
|
||||||
|
///
|
||||||
|
/// using-declaration: [C++ 7.3.p3: namespace.udecl]
|
||||||
|
/// 'using' 'typename'[opt] ::[opt] nested-name-specifier
|
||||||
|
/// unqualified-id [TODO]
|
||||||
|
/// 'using' :: unqualified-id [TODO]
|
||||||
|
///
|
||||||
|
Parser::DeclTy *Parser::ParseUsingDeclaration(unsigned Context,
|
||||||
|
SourceLocation UsingLoc) {
|
||||||
|
assert(false && "Not implemented");
|
||||||
|
// FIXME: Implement parsing.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// ParseClassName - Parse a C++ class-name, which names a class. Note
|
/// ParseClassName - Parse a C++ class-name, which names a class. Note
|
||||||
/// that we only check that the result names a type; semantic analysis
|
/// that we only check that the result names a type; semantic analysis
|
||||||
/// will need to verify that the type names a class. The result is
|
/// will need to verify that the type names a class. The result is
|
||||||
|
|
|
@ -43,6 +43,21 @@ ActionBase::~ActionBase() {}
|
||||||
/// Out-of-line virtual destructor to provide home for Action class.
|
/// Out-of-line virtual destructor to provide home for Action class.
|
||||||
Action::~Action() {}
|
Action::~Action() {}
|
||||||
|
|
||||||
|
// Defined out-of-line here because of dependecy on AttributeList
|
||||||
|
Action::DeclTy *Action::ActOnUsingDirective(Scope *CurScope,
|
||||||
|
SourceLocation UsingLoc,
|
||||||
|
SourceLocation NamespcLoc,
|
||||||
|
const CXXScopeSpec &SS,
|
||||||
|
SourceLocation IdentLoc,
|
||||||
|
IdentifierInfo *NamespcName,
|
||||||
|
AttributeList *AttrList) {
|
||||||
|
|
||||||
|
// FIXME: Parser seems to assume that Action::ActOn* takes ownership over
|
||||||
|
// passed AttributeList, however other actions don't free it, is it
|
||||||
|
// temporary state or bug?
|
||||||
|
delete AttrList;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
|
DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
|
||||||
return Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID);
|
return Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID);
|
||||||
|
@ -358,6 +373,7 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
case tok::kw_using:
|
||||||
case tok::kw_namespace:
|
case tok::kw_namespace:
|
||||||
case tok::kw_typedef:
|
case tok::kw_typedef:
|
||||||
case tok::kw_template:
|
case tok::kw_template:
|
||||||
|
|
|
@ -491,11 +491,25 @@ public:
|
||||||
void CheckCXXDefaultArguments(FunctionDecl *FD);
|
void CheckCXXDefaultArguments(FunctionDecl *FD);
|
||||||
void CheckExtraCXXDefaultArguments(Declarator &D);
|
void CheckExtraCXXDefaultArguments(Declarator &D);
|
||||||
|
|
||||||
|
// FIXME: NamespaceNameOnly parameter is added temporarily
|
||||||
|
// we will need a better way to specify lookup criteria for things
|
||||||
|
// like template specializations, explicit template instatatiation etc.
|
||||||
|
|
||||||
/// More parsing and symbol table subroutines...
|
/// More parsing and symbol table subroutines...
|
||||||
Decl *LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
Decl *LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
||||||
const DeclContext *LookupCtx = 0,
|
const DeclContext *LookupCtx = 0,
|
||||||
bool enableLazyBuiltinCreation = true,
|
bool enableLazyBuiltinCreation = true,
|
||||||
bool LookInParent = true);
|
bool LookInParent = true,
|
||||||
|
bool NamespaceNameOnly = false);
|
||||||
|
|
||||||
|
Decl *LookupNamespaceName(DeclarationName Name, Scope *S,
|
||||||
|
const DeclContext *LookupCtx) {
|
||||||
|
return LookupDecl(Name, Decl::IDNS_Tag | Decl::IDNS_Ordinary, S,
|
||||||
|
LookupCtx,
|
||||||
|
/* enableLazyBuiltinCreation */ false,
|
||||||
|
/* LookInParent */ true,
|
||||||
|
/* NamespaceNameOnly */ true);
|
||||||
|
}
|
||||||
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
|
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
|
||||||
ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
|
ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
|
||||||
Scope *S);
|
Scope *S);
|
||||||
|
@ -807,6 +821,14 @@ public:
|
||||||
SourceLocation LBrace);
|
SourceLocation LBrace);
|
||||||
virtual void ActOnFinishNamespaceDef(DeclTy *Dcl, SourceLocation RBrace);
|
virtual void ActOnFinishNamespaceDef(DeclTy *Dcl, SourceLocation RBrace);
|
||||||
|
|
||||||
|
virtual DeclTy *ActOnUsingDirective(Scope *CurScope,
|
||||||
|
SourceLocation UsingLoc,
|
||||||
|
SourceLocation NamespcLoc,
|
||||||
|
const CXXScopeSpec &SS,
|
||||||
|
SourceLocation IdentLoc,
|
||||||
|
IdentifierInfo *NamespcName,
|
||||||
|
AttributeList *AttrList);
|
||||||
|
|
||||||
/// AddCXXDirectInitializerToDecl - This action is called immediately after
|
/// AddCXXDirectInitializerToDecl - This action is called immediately after
|
||||||
/// ActOnDeclarator, when a C++ direct initializer is present.
|
/// ActOnDeclarator, when a C++ direct initializer is present.
|
||||||
/// e.g: "int x(1);"
|
/// e.g: "int x(1);"
|
||||||
|
|
|
@ -243,11 +243,15 @@ MaybeConstructOverloadSet(ASTContext &Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LookupDecl - Look up the inner-most declaration in the specified
|
/// LookupDecl - Look up the inner-most declaration in the specified
|
||||||
/// namespace.
|
/// namespace. NamespaceNameOnly - during lookup only namespace names
|
||||||
|
/// are considered as required in C++ [basic.lookup.udir] 3.4.6.p1
|
||||||
|
/// 'When looking up a namespace-name in a using-directive or
|
||||||
|
/// namespace-alias-definition, only namespace names are considered.'
|
||||||
Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
||||||
const DeclContext *LookupCtx,
|
const DeclContext *LookupCtx,
|
||||||
bool enableLazyBuiltinCreation,
|
bool enableLazyBuiltinCreation,
|
||||||
bool LookInParent) {
|
bool LookInParent,
|
||||||
|
bool NamespaceNameOnly) {
|
||||||
if (!Name) return 0;
|
if (!Name) return 0;
|
||||||
unsigned NS = NSI;
|
unsigned NS = NSI;
|
||||||
if (getLangOptions().CPlusPlus && (NS & Decl::IDNS_Ordinary))
|
if (getLangOptions().CPlusPlus && (NS & Decl::IDNS_Ordinary))
|
||||||
|
@ -259,6 +263,7 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
||||||
// labels in C++ is purely lexical, so search in the
|
// labels in C++ is purely lexical, so search in the
|
||||||
// declarations attached to the name.
|
// declarations attached to the name.
|
||||||
assert(!LookupCtx && "Can't perform qualified name lookup here");
|
assert(!LookupCtx && "Can't perform qualified name lookup here");
|
||||||
|
assert(!NamespaceNameOnly && "Can't perform namespace name lookup here");
|
||||||
IdentifierResolver::iterator I
|
IdentifierResolver::iterator I
|
||||||
= IdResolver.begin(Name, CurContext, LookInParent);
|
= IdResolver.begin(Name, CurContext, LookInParent);
|
||||||
|
|
||||||
|
@ -268,14 +273,19 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
||||||
// deep shadowing is extremely uncommon.
|
// deep shadowing is extremely uncommon.
|
||||||
for (; I != IdResolver.end(); ++I)
|
for (; I != IdResolver.end(); ++I)
|
||||||
if ((*I)->getIdentifierNamespace() & NS)
|
if ((*I)->getIdentifierNamespace() & NS)
|
||||||
return *I;
|
return *I;
|
||||||
} else if (LookupCtx) {
|
} else if (LookupCtx) {
|
||||||
// Perform qualified name lookup into the LookupCtx.
|
// Perform qualified name lookup into the LookupCtx.
|
||||||
// FIXME: Will need to look into base classes and such.
|
// FIXME: Will need to look into base classes and such.
|
||||||
DeclContext::lookup_const_iterator I, E;
|
DeclContext::lookup_const_iterator I, E;
|
||||||
for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I)
|
for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I)
|
||||||
if ((*I)->getIdentifierNamespace() & NS)
|
if ((*I)->getIdentifierNamespace() & NS) {
|
||||||
return MaybeConstructOverloadSet(Context, I, E);
|
if (NamespaceNameOnly && !isa<NamespaceDecl>(*I)) {
|
||||||
|
// Skip non-namespace name.
|
||||||
|
} else {
|
||||||
|
return MaybeConstructOverloadSet(Context, I, E);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Name lookup for ordinary names and tag names in C++ requires
|
// Name lookup for ordinary names and tag names in C++ requires
|
||||||
// looking into scopes that aren't strictly lexical, and
|
// looking into scopes that aren't strictly lexical, and
|
||||||
|
@ -289,17 +299,21 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
||||||
// FIXME: The isDeclScope check could be expensive. Can we do better?
|
// FIXME: The isDeclScope check could be expensive. Can we do better?
|
||||||
for (; I != IEnd && S->isDeclScope(*I); ++I) {
|
for (; I != IEnd && S->isDeclScope(*I); ++I) {
|
||||||
if ((*I)->getIdentifierNamespace() & NS) {
|
if ((*I)->getIdentifierNamespace() & NS) {
|
||||||
// We found something. Look for anything else in our scope
|
if (NamespaceNameOnly && !isa<NamespaceDecl>(*I)) {
|
||||||
// with this same name and in an acceptable identifier
|
// Skip non-namespace name.
|
||||||
// namespace, so that we can construct an overload set if we
|
} else {
|
||||||
// need to.
|
// We found something. Look for anything else in our scope
|
||||||
IdentifierResolver::iterator LastI = I;
|
// with this same name and in an acceptable identifier
|
||||||
for (++LastI; LastI != IEnd; ++LastI) {
|
// namespace, so that we can construct an overload set if we
|
||||||
if (((*LastI)->getIdentifierNamespace() & NS) == 0 ||
|
// need to.
|
||||||
!S->isDeclScope(*LastI))
|
IdentifierResolver::iterator LastI = I;
|
||||||
break;
|
for (++LastI; LastI != IEnd; ++LastI) {
|
||||||
|
if (((*LastI)->getIdentifierNamespace() & NS) == 0 ||
|
||||||
|
!S->isDeclScope(*LastI))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return MaybeConstructOverloadSet(Context, I, LastI);
|
||||||
}
|
}
|
||||||
return MaybeConstructOverloadSet(Context, I, LastI);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,8 +328,10 @@ Decl *Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
|
||||||
DeclContext::lookup_const_iterator I, E;
|
DeclContext::lookup_const_iterator I, E;
|
||||||
for (llvm::tie(I, E) = Ctx->lookup(Context, Name); I != E; ++I) {
|
for (llvm::tie(I, E) = Ctx->lookup(Context, Name); I != E; ++I) {
|
||||||
// FIXME: Cache this result in the IdResolver
|
// FIXME: Cache this result in the IdResolver
|
||||||
if ((*I)->getIdentifierNamespace() & NS)
|
if ((*I)->getIdentifierNamespace() & NS) {
|
||||||
return MaybeConstructOverloadSet(Context, I, E);
|
if (NamespaceNameOnly && !isa<NamespaceDecl>(*I)) {}
|
||||||
|
else return MaybeConstructOverloadSet(Context, I, E);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ctx = Ctx->getParent();
|
Ctx = Ctx->getParent();
|
||||||
|
|
|
@ -1349,6 +1349,34 @@ void Sema::ActOnFinishNamespaceDef(DeclTy *D, SourceLocation RBrace) {
|
||||||
PopDeclContext();
|
PopDeclContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sema::DeclTy *Sema::ActOnUsingDirective(Scope *S,
|
||||||
|
SourceLocation UsingLoc,
|
||||||
|
SourceLocation NamespcLoc,
|
||||||
|
const CXXScopeSpec &SS,
|
||||||
|
SourceLocation IdentLoc,
|
||||||
|
IdentifierInfo *NamespcName,
|
||||||
|
AttributeList *AttrList) {
|
||||||
|
assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
|
||||||
|
assert(NamespcName && "Invalid NamespcName.");
|
||||||
|
assert(IdentLoc.isValid() && "Invalid NamespceName location.");
|
||||||
|
|
||||||
|
// FIXME: This still requires lot more checks, and AST support.
|
||||||
|
// Lookup namespace name.
|
||||||
|
DeclContext *DC = static_cast<DeclContext*>(SS.getScopeRep());
|
||||||
|
Decl *NS = 0;
|
||||||
|
|
||||||
|
if ((NS = LookupNamespaceName(NamespcName, S, DC))) {
|
||||||
|
assert(isa<NamespaceDecl>(NS) && "expected namespace decl");
|
||||||
|
} else {
|
||||||
|
DiagnosticBuilder Builder = Diag(IdentLoc, diag::err_expected_namespace_name);
|
||||||
|
if (SS.isSet())
|
||||||
|
Builder << SS.getRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: We ignore AttrList for now, and delete it to avoid leak.
|
||||||
|
delete AttrList;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// AddCXXDirectInitializerToDecl - This action is called immediately after
|
/// AddCXXDirectInitializerToDecl - This action is called immediately after
|
||||||
/// ActOnDeclarator, when a C++ direct initializer is present.
|
/// ActOnDeclarator, when a C++ direct initializer is present.
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// RUN: clang -fsyntax-only -verify %s
|
||||||
|
|
||||||
|
class A {};
|
||||||
|
|
||||||
|
namespace B {
|
||||||
|
namespace A {}
|
||||||
|
using namespace A ;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace C {}
|
||||||
|
|
||||||
|
namespace D {
|
||||||
|
|
||||||
|
class C {
|
||||||
|
|
||||||
|
using namespace B ; // expected-error{{expected unqualified-id}}
|
||||||
|
//FIXME: this needs better error message
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace B {}
|
||||||
|
|
||||||
|
using namespace C ;
|
||||||
|
using namespace B::A ; // expected-error{{expected namespace name}}
|
||||||
|
//FIXME: would be nice to note, that A is not member of D::B
|
||||||
|
using namespace ::B::A ;
|
||||||
|
using namespace ::D::C ; // expected-error{{expected namespace name}}
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace ! ; // expected-error{{expected namespace name}}
|
||||||
|
using namespace A ; // expected-error{{expected namespace name}}
|
||||||
|
using namespace ::A B ; // expected-error{{expected ';' after namespace name}}
|
||||||
|
|
|
@ -963,7 +963,14 @@ welcome!</p>
|
||||||
<tr><td> 7.3.1.2 [namespace.memdef]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
<tr><td> 7.3.1.2 [namespace.memdef]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||||
<tr><td> 7.3.2 [namespace.alias]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
<tr><td> 7.3.2 [namespace.alias]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||||
<tr><td> 7.3.3 [namespace.udecl]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
<tr><td> 7.3.3 [namespace.udecl]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||||
<tr><td> 7.3.4 [namespace.udir]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
<tr>
|
||||||
|
<td> 7.3.4[namespace.udir]</td>
|
||||||
|
<td class="complete" align="center">✓</td>
|
||||||
|
<td class="broken" align="center"></td>
|
||||||
|
<td class="broken" align="center"></td>
|
||||||
|
<td class="broken" align="center"></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr><td> 7.4 [dcl.asm]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
<tr><td> 7.4 [dcl.asm]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||||
<tr><td> 7.5 [dcl.link]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
<tr><td> 7.5 [dcl.link]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||||
<tr><td>8 [dcl.decl]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
<tr><td>8 [dcl.decl]</td><td></td><td></td><td></td><td></td><td></td></tr>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче