[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