зеркало из https://github.com/microsoft/clang.git
Make linkage-specifications hold on to all of their declarations
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61110 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
f595eb04a7
Коммит
f44515a49b
|
@ -185,9 +185,19 @@ void DeclPrinter::PrintLinkageSpec(LinkageSpecDecl *LS) {
|
||||||
"unknown language in linkage specification");
|
"unknown language in linkage specification");
|
||||||
l = "C++";
|
l = "C++";
|
||||||
}
|
}
|
||||||
Out << "extern \"" << l << "\" { ";
|
|
||||||
PrintDecl(LS->getDecl());
|
Out << "extern \"" << l << "\" ";
|
||||||
Out << "}\n";
|
if (LS->hasBraces())
|
||||||
|
Out << "{\n";
|
||||||
|
|
||||||
|
for (LinkageSpecDecl::decl_const_iterator D = LS->decls_begin(),
|
||||||
|
DEnd = LS->decls_end();
|
||||||
|
D != DEnd; ++D)
|
||||||
|
PrintDecl(*D);
|
||||||
|
|
||||||
|
if (LS->hasBraces())
|
||||||
|
Out << "}";
|
||||||
|
Out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclPrinter::PrintObjCMethodDecl(ObjCMethodDecl *OMD) {
|
void DeclPrinter::PrintObjCMethodDecl(ObjCMethodDecl *OMD) {
|
||||||
|
|
|
@ -894,18 +894,46 @@ public:
|
||||||
private:
|
private:
|
||||||
/// Language - The language for this linkage specification.
|
/// Language - The language for this linkage specification.
|
||||||
LanguageIDs Language;
|
LanguageIDs Language;
|
||||||
/// D - This is the Decl of the linkage specification.
|
|
||||||
Decl *D;
|
/// HadBraces - Whether this linkage specification had curly braces or not.
|
||||||
|
bool HadBraces : 1;
|
||||||
|
|
||||||
|
/// Decls - The declarations that were parsed as part of this
|
||||||
|
/// linkage specification. If HadBraces is false, this is a
|
||||||
|
/// Decl*. Otherwise, it's a Decl**.
|
||||||
|
void *Decls;
|
||||||
|
|
||||||
|
/// NumDecls - The number of declarations stored in this linkage
|
||||||
|
/// specification.
|
||||||
|
unsigned NumDecls : 31;
|
||||||
|
|
||||||
LinkageSpecDecl(SourceLocation L, LanguageIDs lang, Decl *d)
|
LinkageSpecDecl(SourceLocation L, LanguageIDs lang, Decl *d)
|
||||||
: Decl(LinkageSpec, L), Language(lang), D(d) {}
|
: Decl(LinkageSpec, L), Language(lang), HadBraces(false),
|
||||||
|
Decls(d), NumDecls(1) {}
|
||||||
|
|
||||||
|
LinkageSpecDecl(SourceLocation L, LanguageIDs lang,
|
||||||
|
Decl **InDecls, unsigned InNumDecls);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
~LinkageSpecDecl();
|
||||||
|
|
||||||
static LinkageSpecDecl *Create(ASTContext &C, SourceLocation L,
|
static LinkageSpecDecl *Create(ASTContext &C, SourceLocation L,
|
||||||
LanguageIDs Lang, Decl *D);
|
LanguageIDs Lang, Decl *D);
|
||||||
|
|
||||||
|
static LinkageSpecDecl *Create(ASTContext &C, SourceLocation L,
|
||||||
|
LanguageIDs Lang,
|
||||||
|
Decl **Decls, unsigned NumDecls);
|
||||||
|
|
||||||
LanguageIDs getLanguage() const { return Language; }
|
LanguageIDs getLanguage() const { return Language; }
|
||||||
const Decl *getDecl() const { return D; }
|
|
||||||
Decl *getDecl() { return D; }
|
/// hasBraces - Determines whether this linkage specification had
|
||||||
|
/// braces in its syntactic form.
|
||||||
|
bool hasBraces() const { return HadBraces; }
|
||||||
|
|
||||||
|
typedef Decl** decl_iterator;
|
||||||
|
typedef Decl** decl_const_iterator;
|
||||||
|
decl_const_iterator decls_begin() const;
|
||||||
|
decl_const_iterator decls_end() const;
|
||||||
|
|
||||||
static bool classof(const Decl *D) {
|
static bool classof(const Decl *D) {
|
||||||
return D->getKind() == LinkageSpec;
|
return D->getKind() == LinkageSpec;
|
||||||
|
|
|
@ -240,8 +240,21 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ActOnLinkageSpec - Parsed a C++ linkage-specification that
|
||||||
|
/// contained braces. Lang/StrSize contains the language string that
|
||||||
|
/// was parsed at location Loc. Decls/NumDecls provides the
|
||||||
|
/// declarations parsed inside the linkage specification.
|
||||||
virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
|
virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
|
||||||
SourceLocation RBrace, const char *Lang,
|
SourceLocation RBrace, const char *Lang,
|
||||||
|
unsigned StrSize,
|
||||||
|
DeclTy **Decls, unsigned NumDecls) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ActOnLinkageSpec - Parsed a C++ linkage-specification without
|
||||||
|
/// braces. Lang/StrSize contains the language string that was
|
||||||
|
/// parsed at location Loc. D is the declaration parsed.
|
||||||
|
virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, const char *Lang,
|
||||||
unsigned StrSize, DeclTy *D) {
|
unsigned StrSize, DeclTy *D) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,6 +285,21 @@ OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
|
||||||
return new (Mem) OverloadedFunctionDecl(DC, N);
|
return new (Mem) OverloadedFunctionDecl(DC, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkageSpecDecl::LinkageSpecDecl(SourceLocation L, LanguageIDs lang,
|
||||||
|
Decl **InDecls, unsigned InNumDecls)
|
||||||
|
: Decl(LinkageSpec, L), Language(lang), HadBraces(true),
|
||||||
|
Decls(0), NumDecls(InNumDecls) {
|
||||||
|
Decl **NewDecls = new Decl*[NumDecls];
|
||||||
|
for (unsigned I = 0; I < NumDecls; ++I)
|
||||||
|
NewDecls[I] = InDecls[I];
|
||||||
|
Decls = NewDecls;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkageSpecDecl::~LinkageSpecDecl() {
|
||||||
|
if (HadBraces)
|
||||||
|
delete [] (Decl**)Decls;
|
||||||
|
}
|
||||||
|
|
||||||
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
|
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
|
||||||
SourceLocation L,
|
SourceLocation L,
|
||||||
LanguageIDs Lang, Decl *D) {
|
LanguageIDs Lang, Decl *D) {
|
||||||
|
@ -292,3 +307,20 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
|
||||||
return new (Mem) LinkageSpecDecl(L, Lang, D);
|
return new (Mem) LinkageSpecDecl(L, Lang, D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
|
||||||
|
SourceLocation L,
|
||||||
|
LanguageIDs Lang,
|
||||||
|
Decl **Decls, unsigned NumDecls) {
|
||||||
|
void *Mem = C.getAllocator().Allocate<LinkageSpecDecl>();
|
||||||
|
return new (Mem) LinkageSpecDecl(L, Lang, Decls, NumDecls);
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkageSpecDecl::decl_const_iterator LinkageSpecDecl::decls_begin() const {
|
||||||
|
if (hasBraces()) return (Decl**)Decls;
|
||||||
|
else return (Decl**)&Decls;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinkageSpecDecl::decl_iterator LinkageSpecDecl::decls_end() const {
|
||||||
|
if (hasBraces()) return (Decl**)Decls + NumDecls;
|
||||||
|
else return (Decl**)&Decls + 1;
|
||||||
|
}
|
||||||
|
|
|
@ -660,13 +660,30 @@ TemplateTypeParmDecl::CreateImpl(Deserializer& D, ASTContext& C) {
|
||||||
void LinkageSpecDecl::EmitInRec(Serializer& S) const {
|
void LinkageSpecDecl::EmitInRec(Serializer& S) const {
|
||||||
Decl::EmitInRec(S);
|
Decl::EmitInRec(S);
|
||||||
S.EmitInt(getLanguage());
|
S.EmitInt(getLanguage());
|
||||||
S.EmitPtr(D);
|
S.EmitBool(HadBraces);
|
||||||
|
if (HadBraces) {
|
||||||
|
S.EmitInt(NumDecls);
|
||||||
|
for (decl_const_iterator D = decls_begin(), DEnd = decls_end();
|
||||||
|
D != DEnd; ++D)
|
||||||
|
S.EmitPtr(*D);
|
||||||
|
} else {
|
||||||
|
S.EmitPtr((Decl*)Decls);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkageSpecDecl::ReadInRec(Deserializer& D, ASTContext& C) {
|
void LinkageSpecDecl::ReadInRec(Deserializer& D, ASTContext& C) {
|
||||||
Decl::ReadInRec(D, C);
|
Decl::ReadInRec(D, C);
|
||||||
Language = static_cast<LanguageIDs>(D.ReadInt());
|
Language = static_cast<LanguageIDs>(D.ReadInt());
|
||||||
D.ReadPtr(this->D);
|
HadBraces = D.ReadBool();
|
||||||
|
if (HadBraces) {
|
||||||
|
NumDecls = D.ReadInt();
|
||||||
|
Decl **NewDecls = new Decl*[NumDecls];
|
||||||
|
Decls = NewDecls;
|
||||||
|
for (unsigned I = 0; I < NumDecls; ++I)
|
||||||
|
D.ReadPtr(NewDecls[I]);
|
||||||
|
} else {
|
||||||
|
D.ReadPtr(this->Decls);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -108,24 +108,26 @@ Parser::DeclTy *Parser::ParseLinkage(unsigned Context) {
|
||||||
|
|
||||||
SourceLocation Loc = ConsumeStringToken();
|
SourceLocation Loc = ConsumeStringToken();
|
||||||
DeclTy *D = 0;
|
DeclTy *D = 0;
|
||||||
SourceLocation LBrace, RBrace;
|
|
||||||
|
|
||||||
if (Tok.isNot(tok::l_brace)) {
|
if (Tok.isNot(tok::l_brace)) {
|
||||||
D = ParseDeclarationOrFunctionDefinition();
|
D = ParseDeclarationOrFunctionDefinition();
|
||||||
} else {
|
if (D)
|
||||||
LBrace = ConsumeBrace();
|
return Actions.ActOnLinkageSpec(Loc, LangBufPtr, StrSize, D);
|
||||||
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
|
||||||
// FIXME capture the decls.
|
|
||||||
D = ParseExternalDeclaration();
|
|
||||||
}
|
|
||||||
|
|
||||||
RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!D)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return Actions.ActOnLinkageSpec(Loc, LBrace, RBrace, LangBufPtr, StrSize, D);
|
SourceLocation LBrace = ConsumeBrace();
|
||||||
|
llvm::SmallVector<DeclTy *, 8> InnerDecls;
|
||||||
|
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
||||||
|
D = ParseExternalDeclaration();
|
||||||
|
if (D)
|
||||||
|
InnerDecls.push_back(D);
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
|
||||||
|
return Actions.ActOnLinkageSpec(Loc, LBrace, RBrace, LangBufPtr, StrSize,
|
||||||
|
&InnerDecls.front(), InnerDecls.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseClassName - Parse a C++ class-name, which names a class. Note
|
/// ParseClassName - Parse a C++ class-name, which names a class. Note
|
||||||
|
|
|
@ -288,6 +288,9 @@ public:
|
||||||
virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtArg Body);
|
virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtArg Body);
|
||||||
virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
|
virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
|
||||||
SourceLocation RBrace, const char *Lang,
|
SourceLocation RBrace, const char *Lang,
|
||||||
|
unsigned StrSize,
|
||||||
|
DeclTy **Decls, unsigned NumDecls);
|
||||||
|
virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, const char *Lang,
|
||||||
unsigned StrSize, DeclTy *D);
|
unsigned StrSize, DeclTy *D);
|
||||||
virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
|
virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
|
||||||
|
|
||||||
|
|
|
@ -3382,11 +3382,34 @@ Sema::DeclTy *Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
|
||||||
return FileScopeAsmDecl::Create(Context, Loc, AsmString);
|
return FileScopeAsmDecl::Create(Context, Loc, AsmString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ActOnLinkageSpec - Parsed a C++ linkage-specification that
|
||||||
|
/// contained braces. Lang/StrSize contains the language string that
|
||||||
|
/// was parsed at location Loc. Decls/NumDecls provides the
|
||||||
|
/// declarations parsed inside the linkage specification.
|
||||||
Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc,
|
Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc,
|
||||||
SourceLocation LBrace,
|
SourceLocation LBrace,
|
||||||
SourceLocation RBrace,
|
SourceLocation RBrace,
|
||||||
const char *Lang,
|
const char *Lang,
|
||||||
unsigned StrSize,
|
unsigned StrSize,
|
||||||
|
DeclTy **Decls, unsigned NumDecls) {
|
||||||
|
LinkageSpecDecl::LanguageIDs Language;
|
||||||
|
if (strncmp(Lang, "\"C\"", StrSize) == 0)
|
||||||
|
Language = LinkageSpecDecl::lang_c;
|
||||||
|
else if (strncmp(Lang, "\"C++\"", StrSize) == 0)
|
||||||
|
Language = LinkageSpecDecl::lang_cxx;
|
||||||
|
else {
|
||||||
|
Diag(Loc, diag::err_bad_language);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Add all the various semantics of linkage specifications
|
||||||
|
|
||||||
|
return LinkageSpecDecl::Create(Context, Loc, Language,
|
||||||
|
(Decl **)Decls, NumDecls);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc,
|
||||||
|
const char *Lang, unsigned StrSize,
|
||||||
DeclTy *D) {
|
DeclTy *D) {
|
||||||
LinkageSpecDecl::LanguageIDs Language;
|
LinkageSpecDecl::LanguageIDs Language;
|
||||||
Decl *dcl = static_cast<Decl *>(D);
|
Decl *dcl = static_cast<Decl *>(D);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче