зеркало из https://github.com/microsoft/clang-1.git
Added AccessSpecDecl node.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105525 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
21d07e499e
Коммит
6206d53f67
|
@ -92,6 +92,53 @@ namespace llvm {
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
|
||||||
|
/// AccessSpecDecl - An access specifier followed by colon ':'.
|
||||||
|
///
|
||||||
|
/// An objects of this class represents sugar for the syntactic occurrence
|
||||||
|
/// of an access specifier followed by a colon in the list of member
|
||||||
|
/// specifiers of a C++ class definition.
|
||||||
|
///
|
||||||
|
/// Note that they do not represent other uses of access specifiers,
|
||||||
|
/// such as those occurring in a list of base specifiers.
|
||||||
|
/// Also note that this class has nothing to do with so-called
|
||||||
|
/// "access declarations" (C++98 11.3 [class.access.dcl]).
|
||||||
|
class AccessSpecDecl : public Decl {
|
||||||
|
/// ColonLoc - The location of the ':'.
|
||||||
|
SourceLocation ColonLoc;
|
||||||
|
|
||||||
|
AccessSpecDecl(AccessSpecifier AS, DeclContext *DC,
|
||||||
|
SourceLocation ASLoc, SourceLocation ColonLoc)
|
||||||
|
: Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
|
||||||
|
setAccess(AS);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
/// getAccessSpecifierLoc - The location of the access specifier.
|
||||||
|
SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
|
||||||
|
/// setAccessSpecifierLoc - Sets the location of the access specifier.
|
||||||
|
void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); }
|
||||||
|
|
||||||
|
/// getColonLoc - The location of the colon following the access specifier.
|
||||||
|
SourceLocation getColonLoc() const { return ColonLoc; }
|
||||||
|
/// setColonLoc - Sets the location of the colon.
|
||||||
|
void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
|
||||||
|
|
||||||
|
SourceRange getSourceRange() const {
|
||||||
|
return SourceRange(getAccessSpecifierLoc(), getColonLoc());
|
||||||
|
}
|
||||||
|
|
||||||
|
static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
|
||||||
|
DeclContext *DC, SourceLocation ASLoc,
|
||||||
|
SourceLocation ColonLoc) {
|
||||||
|
return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement isa/cast/dyncast/etc.
|
||||||
|
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||||
|
static bool classof(const AccessSpecDecl *D) { return true; }
|
||||||
|
static bool classofKind(Kind K) { return K == AccessSpec; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// CXXBaseSpecifier - A base class of a C++ class.
|
/// CXXBaseSpecifier - A base class of a C++ class.
|
||||||
///
|
///
|
||||||
/// Each CXXBaseSpecifier represents a single, direct base class (or
|
/// Each CXXBaseSpecifier represents a single, direct base class (or
|
||||||
|
|
|
@ -61,6 +61,7 @@ def ObjCPropertyImpl : Decl;
|
||||||
def ObjCForwardProtocol : Decl;
|
def ObjCForwardProtocol : Decl;
|
||||||
def ObjCClass : Decl;
|
def ObjCClass : Decl;
|
||||||
def FileScopeAsm : Decl;
|
def FileScopeAsm : Decl;
|
||||||
|
def AccessSpec : Decl;
|
||||||
def Friend : Decl;
|
def Friend : Decl;
|
||||||
def FriendTemplate : Decl;
|
def FriendTemplate : Decl;
|
||||||
def StaticAssert : Decl;
|
def StaticAssert : Decl;
|
||||||
|
|
|
@ -562,6 +562,8 @@ namespace clang {
|
||||||
DECL_CXX_DESTRUCTOR,
|
DECL_CXX_DESTRUCTOR,
|
||||||
/// \brief A CXXConversionDecl record.
|
/// \brief A CXXConversionDecl record.
|
||||||
DECL_CXX_CONVERSION,
|
DECL_CXX_CONVERSION,
|
||||||
|
/// \brief An AccessSpecDecl record.
|
||||||
|
DECL_ACCESS_SPEC,
|
||||||
|
|
||||||
// FIXME: Implement serialization for these decl types. This just
|
// FIXME: Implement serialization for these decl types. This just
|
||||||
// allocates the order in which
|
// allocates the order in which
|
||||||
|
|
|
@ -1769,6 +1769,15 @@ public:
|
||||||
unsigned NumBases) {
|
unsigned NumBases) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ActOnAccessSpecifier - This is invoked when an access specifier
|
||||||
|
/// (and the colon following it) is found during the parsing of a
|
||||||
|
/// C++ class member declarator.
|
||||||
|
virtual DeclPtrTy ActOnAccessSpecifier(AccessSpecifier AS,
|
||||||
|
SourceLocation ASLoc,
|
||||||
|
SourceLocation ColonLoc) {
|
||||||
|
return DeclPtrTy();
|
||||||
|
}
|
||||||
|
|
||||||
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
|
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
|
||||||
/// declarator is parsed. 'AS' is the access specifier, 'BitfieldWidth'
|
/// declarator is parsed. 'AS' is the access specifier, 'BitfieldWidth'
|
||||||
/// specifies the bitfield width if there is one and 'Init' specifies the
|
/// specifies the bitfield width if there is one and 'Init' specifies the
|
||||||
|
|
|
@ -291,6 +291,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
|
||||||
// Never have names.
|
// Never have names.
|
||||||
case Friend:
|
case Friend:
|
||||||
case FriendTemplate:
|
case FriendTemplate:
|
||||||
|
case AccessSpec:
|
||||||
case LinkageSpec:
|
case LinkageSpec:
|
||||||
case FileScopeAsm:
|
case FileScopeAsm:
|
||||||
case StaticAssert:
|
case StaticAssert:
|
||||||
|
|
|
@ -183,7 +183,7 @@ void DeclPrinter::Print(AccessSpecifier AS) {
|
||||||
case AS_none: assert(0 && "No access specifier!"); break;
|
case AS_none: assert(0 && "No access specifier!"); break;
|
||||||
case AS_public: Out << "public"; break;
|
case AS_public: Out << "public"; break;
|
||||||
case AS_protected: Out << "protected"; break;
|
case AS_protected: Out << "protected"; break;
|
||||||
case AS_private: Out << " private"; break;
|
case AS_private: Out << "private"; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,9 +195,6 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
|
||||||
if (Indent)
|
if (Indent)
|
||||||
Indentation += Policy.Indentation;
|
Indentation += Policy.Indentation;
|
||||||
|
|
||||||
bool PrintAccess = isa<CXXRecordDecl>(DC);
|
|
||||||
AccessSpecifier CurAS = AS_none;
|
|
||||||
|
|
||||||
llvm::SmallVector<Decl*, 2> Decls;
|
llvm::SmallVector<Decl*, 2> Decls;
|
||||||
for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
|
for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
|
||||||
D != DEnd; ++D) {
|
D != DEnd; ++D) {
|
||||||
|
@ -211,18 +208,6 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PrintAccess) {
|
|
||||||
AccessSpecifier AS = D->getAccess();
|
|
||||||
|
|
||||||
if (AS != CurAS) {
|
|
||||||
if (Indent)
|
|
||||||
this->Indent(Indentation - Policy.Indentation);
|
|
||||||
Print(AS);
|
|
||||||
Out << ":\n";
|
|
||||||
CurAS = AS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The next bits of code handles stuff like "struct {int x;} a,b"; we're
|
// The next bits of code handles stuff like "struct {int x;} a,b"; we're
|
||||||
// forced to merge the declarations because there's no other way to
|
// forced to merge the declarations because there's no other way to
|
||||||
// refer to the struct in question. This limited merging is safe without
|
// refer to the struct in question. This limited merging is safe without
|
||||||
|
@ -251,6 +236,16 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
|
||||||
Decls.push_back(*D);
|
Decls.push_back(*D);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isa<AccessSpecDecl>(*D)) {
|
||||||
|
Indentation -= Policy.Indentation;
|
||||||
|
this->Indent();
|
||||||
|
Print(D->getAccess());
|
||||||
|
Out << ":\n";
|
||||||
|
Indentation += Policy.Indentation;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
this->Indent();
|
this->Indent();
|
||||||
Visit(*D);
|
Visit(*D);
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
|
||||||
case Decl::ObjCImplementation:
|
case Decl::ObjCImplementation:
|
||||||
case Decl::ObjCProperty:
|
case Decl::ObjCProperty:
|
||||||
case Decl::ObjCCompatibleAlias:
|
case Decl::ObjCCompatibleAlias:
|
||||||
|
case Decl::AccessSpec:
|
||||||
case Decl::LinkageSpec:
|
case Decl::LinkageSpec:
|
||||||
case Decl::ObjCPropertyImpl:
|
case Decl::ObjCPropertyImpl:
|
||||||
case Decl::ObjCClass:
|
case Decl::ObjCClass:
|
||||||
|
|
|
@ -80,6 +80,7 @@ namespace {
|
||||||
void VisitUsingShadow(UsingShadowDecl *D);
|
void VisitUsingShadow(UsingShadowDecl *D);
|
||||||
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
|
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
|
||||||
void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
|
void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD);
|
||||||
|
void VisitAccessSpecDecl(AccessSpecDecl *D);
|
||||||
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
|
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
|
||||||
void VisitStaticAssertDecl(StaticAssertDecl *D);
|
void VisitStaticAssertDecl(StaticAssertDecl *D);
|
||||||
void VisitBlockDecl(BlockDecl *BD);
|
void VisitBlockDecl(BlockDecl *BD);
|
||||||
|
@ -607,6 +608,11 @@ void PCHDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) {
|
||||||
VisitCXXMethodDecl(D);
|
VisitCXXMethodDecl(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PCHDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) {
|
||||||
|
VisitDecl(D);
|
||||||
|
D->setColonLoc(Reader.ReadSourceLocation(Record, Idx));
|
||||||
|
}
|
||||||
|
|
||||||
void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
|
void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
|
||||||
assert(false && "cannot read FriendTemplateDecl");
|
assert(false && "cannot read FriendTemplateDecl");
|
||||||
}
|
}
|
||||||
|
@ -971,6 +977,10 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
|
||||||
case pch::DECL_CXX_CONVERSION:
|
case pch::DECL_CXX_CONVERSION:
|
||||||
D = CXXConversionDecl::Create(*Context, Decl::EmptyShell());
|
D = CXXConversionDecl::Create(*Context, Decl::EmptyShell());
|
||||||
break;
|
break;
|
||||||
|
case pch::DECL_ACCESS_SPEC:
|
||||||
|
D = AccessSpecDecl::Create(*Context, AS_none, 0, SourceLocation(),
|
||||||
|
SourceLocation());
|
||||||
|
break;
|
||||||
case pch::DECL_FRIEND:
|
case pch::DECL_FRIEND:
|
||||||
assert(false && "cannot read FriendDecl");
|
assert(false && "cannot read FriendDecl");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -81,6 +81,7 @@ namespace {
|
||||||
void VisitUsingShadow(UsingShadowDecl *D);
|
void VisitUsingShadow(UsingShadowDecl *D);
|
||||||
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
|
void VisitLinkageSpecDecl(LinkageSpecDecl *D);
|
||||||
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
|
void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
|
||||||
|
void VisitAccessSpecDecl(AccessSpecDecl *D);
|
||||||
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
|
void VisitFriendTemplateDecl(FriendTemplateDecl *D);
|
||||||
void VisitStaticAssertDecl(StaticAssertDecl *D);
|
void VisitStaticAssertDecl(StaticAssertDecl *D);
|
||||||
void VisitBlockDecl(BlockDecl *D);
|
void VisitBlockDecl(BlockDecl *D);
|
||||||
|
@ -607,6 +608,12 @@ void PCHDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
|
||||||
Code = pch::DECL_CXX_CONVERSION;
|
Code = pch::DECL_CXX_CONVERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PCHDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) {
|
||||||
|
VisitDecl(D);
|
||||||
|
Writer.AddSourceLocation(D->getColonLoc(), Record);
|
||||||
|
Code = pch::DECL_ACCESS_SPEC;
|
||||||
|
}
|
||||||
|
|
||||||
void PCHDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
|
void PCHDeclWriter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
|
||||||
assert(false && "cannot write FriendTemplateDecl");
|
assert(false && "cannot write FriendTemplateDecl");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1570,8 +1570,13 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
|
||||||
if (AS != AS_none) {
|
if (AS != AS_none) {
|
||||||
// Current token is a C++ access specifier.
|
// Current token is a C++ access specifier.
|
||||||
CurAS = AS;
|
CurAS = AS;
|
||||||
|
SourceLocation ASLoc = Tok.getLocation();
|
||||||
|
ConsumeToken();
|
||||||
|
if (Tok.is(tok::colon))
|
||||||
|
Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
|
||||||
|
else
|
||||||
|
Diag(Tok, diag::err_expected_colon);
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
ExpectAndConsume(tok::colon, diag::err_expected_colon);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2544,6 +2544,10 @@ public:
|
||||||
virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
|
virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
|
||||||
const CXXScopeSpec *SS);
|
const CXXScopeSpec *SS);
|
||||||
|
|
||||||
|
virtual DeclPtrTy ActOnAccessSpecifier(AccessSpecifier Access,
|
||||||
|
SourceLocation ASLoc,
|
||||||
|
SourceLocation ColonLoc);
|
||||||
|
|
||||||
virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
|
virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
|
||||||
Declarator &D,
|
Declarator &D,
|
||||||
MultiTemplateParamsArg TemplateParameterLists,
|
MultiTemplateParamsArg TemplateParameterLists,
|
||||||
|
|
|
@ -1770,6 +1770,8 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
|
||||||
<< (int)Record->isUnion();
|
<< (int)Record->isUnion();
|
||||||
Invalid = true;
|
Invalid = true;
|
||||||
}
|
}
|
||||||
|
} else if (isa<AccessSpecDecl>(*Mem)) {
|
||||||
|
// Any access specifier is fine.
|
||||||
} else {
|
} else {
|
||||||
// We have something that isn't a non-static data
|
// We have something that isn't a non-static data
|
||||||
// member. Complain about it.
|
// member. Complain about it.
|
||||||
|
|
|
@ -871,6 +871,17 @@ std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) {
|
||||||
// C++ class member Handling
|
// C++ class member Handling
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// ActOnAccessSpecifier - Parsed an access specifier followed by a colon.
|
||||||
|
Sema::DeclPtrTy
|
||||||
|
Sema::ActOnAccessSpecifier(AccessSpecifier Access,
|
||||||
|
SourceLocation ASLoc, SourceLocation ColonLoc) {
|
||||||
|
assert(Access != AS_none && "Invalid kind for syntactic access specifier!");
|
||||||
|
AccessSpecDecl* ASDecl = AccessSpecDecl::Create(Context, Access, CurContext,
|
||||||
|
ASLoc, ColonLoc);
|
||||||
|
CurContext->addHiddenDecl(ASDecl);
|
||||||
|
return DeclPtrTy::make(ASDecl);
|
||||||
|
}
|
||||||
|
|
||||||
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
|
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
|
||||||
/// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
|
/// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
|
||||||
/// bitfield width if there is one and 'InitExpr' specifies the initializer if
|
/// bitfield width if there is one and 'InitExpr' specifies the initializer if
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace {
|
||||||
Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
|
Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
|
||||||
Decl *VisitTypedefDecl(TypedefDecl *D);
|
Decl *VisitTypedefDecl(TypedefDecl *D);
|
||||||
Decl *VisitVarDecl(VarDecl *D);
|
Decl *VisitVarDecl(VarDecl *D);
|
||||||
|
Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
|
||||||
Decl *VisitFieldDecl(FieldDecl *D);
|
Decl *VisitFieldDecl(FieldDecl *D);
|
||||||
Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
|
Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
|
||||||
Decl *VisitEnumDecl(EnumDecl *D);
|
Decl *VisitEnumDecl(EnumDecl *D);
|
||||||
|
@ -437,6 +438,14 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
||||||
return Var;
|
return Var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Decl *TemplateDeclInstantiator::VisitAccessSpecDecl(AccessSpecDecl *D) {
|
||||||
|
AccessSpecDecl* AD
|
||||||
|
= AccessSpecDecl::Create(SemaRef.Context, D->getAccess(), Owner,
|
||||||
|
D->getAccessSpecifierLoc(), D->getColonLoc());
|
||||||
|
Owner->addHiddenDecl(AD);
|
||||||
|
return AD;
|
||||||
|
}
|
||||||
|
|
||||||
Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
|
Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
|
||||||
bool Invalid = false;
|
bool Invalid = false;
|
||||||
TypeSourceInfo *DI = D->getTypeSourceInfo();
|
TypeSourceInfo *DI = D->getTypeSourceInfo();
|
||||||
|
|
|
@ -2041,6 +2041,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
|
||||||
case Decl::TemplateTemplateParm:
|
case Decl::TemplateTemplateParm:
|
||||||
case Decl::ObjCCategoryImpl:
|
case Decl::ObjCCategoryImpl:
|
||||||
case Decl::ObjCImplementation:
|
case Decl::ObjCImplementation:
|
||||||
|
case Decl::AccessSpec:
|
||||||
case Decl::LinkageSpec:
|
case Decl::LinkageSpec:
|
||||||
case Decl::ObjCPropertyImpl:
|
case Decl::ObjCPropertyImpl:
|
||||||
case Decl::FileScopeAsm:
|
case Decl::FileScopeAsm:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче