[cfe-commits] r61110 - in /cfe/trunk: Driver/ASTConsumers.cpp include/clang/AST/DeclCXX.h include/clang/Parse/Action.h lib/AST/DeclCXX.cpp lib/AST/DeclSerialization.cpp lib/Parse/ParseDeclCXX.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp
Douglas Gregor
dgregor at apple.com
Tue Dec 16 14:23:03 PST 2008
Author: dgregor
Date: Tue Dec 16 16:23:02 2008
New Revision: 61110
URL: http://llvm.org/viewvc/llvm-project?rev=61110&view=rev
Log:
Make linkage-specifications hold on to all of their declarations
Modified:
cfe/trunk/Driver/ASTConsumers.cpp
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/AST/DeclSerialization.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=61110&r1=61109&r2=61110&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Tue Dec 16 16:23:02 2008
@@ -185,9 +185,19 @@
"unknown language in linkage specification");
l = "C++";
}
- Out << "extern \"" << l << "\" { ";
- PrintDecl(LS->getDecl());
- Out << "}\n";
+
+ Out << "extern \"" << l << "\" ";
+ 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) {
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=61110&r1=61109&r2=61110&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Dec 16 16:23:02 2008
@@ -894,18 +894,46 @@
private:
/// Language - The language for this linkage specification.
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)
- : 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:
+ ~LinkageSpecDecl();
+
static LinkageSpecDecl *Create(ASTContext &C, SourceLocation L,
LanguageIDs Lang, Decl *D);
+
+ static LinkageSpecDecl *Create(ASTContext &C, SourceLocation L,
+ LanguageIDs Lang,
+ Decl **Decls, unsigned NumDecls);
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) {
return D->getKind() == LinkageSpec;
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=61110&r1=61109&r2=61110&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Dec 16 16:23:02 2008
@@ -240,8 +240,21 @@
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,
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) {
return 0;
}
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=61110&r1=61109&r2=61110&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Dec 16 16:23:02 2008
@@ -285,6 +285,21 @@
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,
SourceLocation L,
LanguageIDs Lang, Decl *D) {
@@ -292,3 +307,20 @@
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;
+}
Modified: cfe/trunk/lib/AST/DeclSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclSerialization.cpp?rev=61110&r1=61109&r2=61110&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclSerialization.cpp (original)
+++ cfe/trunk/lib/AST/DeclSerialization.cpp Tue Dec 16 16:23:02 2008
@@ -660,13 +660,30 @@
void LinkageSpecDecl::EmitInRec(Serializer& S) const {
Decl::EmitInRec(S);
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) {
Decl::ReadInRec(D, C);
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);
+ }
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=61110&r1=61109&r2=61110&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Dec 16 16:23:02 2008
@@ -108,24 +108,26 @@
SourceLocation Loc = ConsumeStringToken();
DeclTy *D = 0;
- SourceLocation LBrace, RBrace;
if (Tok.isNot(tok::l_brace)) {
D = ParseDeclarationOrFunctionDefinition();
- } else {
- LBrace = ConsumeBrace();
- 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 Actions.ActOnLinkageSpec(Loc, LangBufPtr, StrSize, D);
- if (!D)
return 0;
+ }
+
+ 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);
+ }
- return Actions.ActOnLinkageSpec(Loc, LBrace, RBrace, LangBufPtr, StrSize, 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
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=61110&r1=61109&r2=61110&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Dec 16 16:23:02 2008
@@ -288,6 +288,9 @@
virtual DeclTy *ActOnFinishFunctionBody(DeclTy *Decl, StmtArg Body);
virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, SourceLocation LBrace,
SourceLocation RBrace, const char *Lang,
+ unsigned StrSize,
+ DeclTy **Decls, unsigned NumDecls);
+ virtual DeclTy *ActOnLinkageSpec(SourceLocation Loc, const char *Lang,
unsigned StrSize, DeclTy *D);
virtual DeclTy *ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=61110&r1=61109&r2=61110&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Dec 16 16:23:02 2008
@@ -3382,11 +3382,34 @@
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,
SourceLocation LBrace,
SourceLocation RBrace,
const char *Lang,
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) {
LinkageSpecDecl::LanguageIDs Language;
Decl *dcl = static_cast<Decl *>(D);
More information about the cfe-commits
mailing list