]> granicus.if.org Git - clang/commitdiff
Several fixes/simplifications surrounding how we stream top-level decl AST's.
authorSteve Naroff <snaroff@apple.com>
Wed, 28 Nov 2007 22:54:11 +0000 (22:54 +0000)
committerSteve Naroff <snaroff@apple.com>
Wed, 28 Nov 2007 22:54:11 +0000 (22:54 +0000)
The following code...

typedef struct cssm_data {} CSSM_DATA, *CSSM_DATA_PTR;

struct Y { int A; };

struct X { int A; } D;

struct X E, F;

...now produces the following output...

> ../../Debug/bin/clang xx.c -ast-print
Read top-level tag decl: 'cssm_data'
typedef struct cssm_data CSSM_DATA;
typedef struct cssm_data *CSSM_DATA_PTR;
Read top-level tag decl: 'Y'
Read top-level tag decl: 'X'
Read top-level variable decl: 'D'
Read top-level variable decl: 'E'
Read top-level variable decl: 'F'

...which is much more accurate than the previous -ast-print output...

typedef struct cssm_data CSSM_DATA;
typedef struct cssm_data CSSM_DATA;
Read top-level variable decl: 'D'
Read top-level variable decl: 'E'
Read top-level variable decl: 'E'

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44421 91177308-0d34-0410-b5e6-96231b3b80d8

Driver/ASTConsumers.cpp
Parse/Parser.cpp
Sema/ASTStreamer.cpp
Sema/Sema.cpp
Sema/Sema.h
Sema/SemaDecl.cpp
clang.xcodeproj/project.pbxproj
include/clang/Parse/Parser.h

index 3479cfb20ab6c1db944fa16f54dbc2e7260184a3..a3d837fb2c36ba0e5046166dc76987db16a5f921 100644 (file)
@@ -331,6 +331,8 @@ namespace {
         PrintObjcCompatibleAliasDecl(OID);
       } else if (isa<ObjcClassDecl>(D)) {
         Out << "@class [printing todo]\n";
+      } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+        Out << "Read top-level tag decl: '" << TD->getName() << "'\n";
       } else if (ScopedDecl *SD = dyn_cast<ScopedDecl>(D)) {
         Out << "Read top-level variable decl: '" << SD->getName() << "'\n";
       } else {
index 8a0d8c7ecd0103212532be4de0d4880e738fc535..6e03328592d183104080bfae942ba5993f354899 100644 (file)
@@ -259,11 +259,10 @@ void Parser::Initialize() {
 
 /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
 /// action tells us to.  This returns true if the EOF was encountered.
-bool Parser::ParseTopLevelDecl(DeclTy*& Result) {
-  Result = 0;
+bool Parser::ParseTopLevelDecl() {
   if (Tok.is(tok::eof)) return true;
   
-  Result = ParseExternalDeclaration();
+  ParseExternalDeclaration();
   return false;
 }
 
@@ -281,8 +280,7 @@ void Parser::Finalize() {
 void Parser::ParseTranslationUnit() {
   Initialize();
   
-  DeclTy *Res;
-  while (!ParseTopLevelDecl(Res))
+  while (!ParseTopLevelDecl())
     /*parse them all*/;
   
   Finalize();
index be43289be516b367bc5dd3a3b821ef2663368a33..5a372da088ea03b9b44bdbd40c9c13c2f523a8dc 100644 (file)
@@ -24,10 +24,10 @@ ASTConsumer::~ASTConsumer() {}
 namespace {
   class ASTStreamer {
     Parser P;
-    std::vector<Decl*> LastInGroupList;
+    std::vector<Decl*> TopLevelDeclList;
   public:
     ASTStreamer(Preprocessor &pp, ASTContext &ctxt, unsigned MainFileID)
-      : P(pp, *new Sema(pp, ctxt, LastInGroupList)) {
+      : P(pp, *new Sema(pp, ctxt, TopLevelDeclList)) {
       pp.EnterMainSourceFile(MainFileID);
       
       // Initialize the parser.
@@ -53,29 +53,28 @@ Decl *ASTStreamer::ReadTopLevelDecl() {
   
   /// If the previous time through we read something like 'int X, Y', return
   /// the next declarator.
-  if (!LastInGroupList.empty()) {
-    Result = LastInGroupList.back();
-    LastInGroupList.pop_back();
+  if (!TopLevelDeclList.empty()) {
+    Result = TopLevelDeclList.back();
+    TopLevelDeclList.pop_back();
     return static_cast<Decl*>(Result);
   }
   
   do {
-    if (P.ParseTopLevelDecl(Result))
+    if (P.ParseTopLevelDecl())
       return 0;  // End of file.
     
     // If we got a null return and something *was* parsed, try again.  This
     // is due to a top-level semicolon, an action override, or a parse error
     // skipping something.
-  } while (Result == 0);
+  } while (TopLevelDeclList.size() == 0);
   
   // If we parsed a declspec with multiple declarators, reverse the list and
   // return the first one.
-  if (!LastInGroupList.empty()) {
-    LastInGroupList.push_back((Decl*)Result);
-    std::reverse(LastInGroupList.begin(), LastInGroupList.end());
-    Result = LastInGroupList.back();
-    LastInGroupList.pop_back();
-  }
+  if (TopLevelDeclList.size() > 1)
+    std::reverse(TopLevelDeclList.begin(), TopLevelDeclList.end());
+
+  Result = TopLevelDeclList.back();
+  TopLevelDeclList.pop_back();
   
   return static_cast<Decl*>(Result);
 }
index 323483586bca690c0c11603a3f425e21e5f5e79f..d3930f60faff4918a4687243dc8806c9b4c0d9dd 100644 (file)
@@ -64,7 +64,7 @@ QualType Sema::GetObjcProtoType(SourceLocation Loc) {
 }
 
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup)
-  : PP(pp), Context(ctxt), CurFunctionDecl(0), LastInGroupList(prevInGroup) {
+  : PP(pp), Context(ctxt), CurFunctionDecl(0), TopLevelDeclList(prevInGroup) {
   
   // Get IdentifierInfo objects for known functions for which we
   // do extra checking.  
index 1b232df356b748ab8ff604653def5ed0359fb0f4..cbb94bc372a0c065e551e0620d2e5221e15ac439 100644 (file)
@@ -69,11 +69,9 @@ class Sema : public Action {
   /// the method decl for the method being parsed.
   ObjcMethodDecl *CurMethodDecl;
   
-  /// LastInGroupList - This vector is populated when there are multiple
-  /// declarators in a single decl group (e.g. "int A, B, C").  In this case,
-  /// all but the last decl will be entered into this.  This is used by the
-  /// ASTStreamer.
-  std::vector<Decl*> &LastInGroupList;
+  /// TopLevelDeclList - This vector is populated with all declarators from
+  /// a top-level declaration. This is used by the ASTStreamer.
+  std::vector<Decl*> &TopLevelDeclList;
   
   /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
   /// it (which acts like the label decl in some ways).  Forward referenced
@@ -231,7 +229,7 @@ private:
   VarDecl *MergeVarDecl(VarDecl *New, ScopedDecl *Old);
   /// AddTopLevelDecl - called after the decl has been fully processed.
   /// Allows for bookkeeping and post-processing of each declaration.
-  void AddTopLevelDecl(Decl *current, Decl *last);
+  void AddTopLevelDecl(Decl *current);
 
   /// More parsing and symbol table subroutines...
   ParmVarDecl *ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI, 
index 88635c3bc5badd5cf8ace9f1a88b5cb1e8f664b0..9907c06f2b5aa6f62fe072408cb3bdfa6925d2a7 100644 (file)
@@ -192,7 +192,7 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
     II->setFETokenInfo(New);
   }    
   // Make sure clients iterating over decls see this.
-  LastInGroupList.push_back(New);
+  AddTopLevelDecl(New);
   
   return New;
 }
@@ -678,7 +678,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
   }
   
   if (S->getParent() == 0)
-    AddTopLevelDecl(New, LastDeclarator);
+    AddTopLevelDecl(New);
 
   // If any semantic error occurred, mark the decl as invalid.
   if (D.getInvalidType() || InvalidDecl)
@@ -973,7 +973,7 @@ void Sema::ObjcActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
   NewFD->setNext(II->getFETokenInfo<ScopedDecl>());
   II->setFETokenInfo(NewFD);
   GlobalScope->AddDecl(NewFD);
-  AddTopLevelDecl(NewFD, 0);
+  AddTopLevelDecl(NewFD);
   
   // Allow all of Sema to see that we are entering a method definition.
   CurMethodDecl = MDecl;
@@ -1683,6 +1683,12 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
     break;
   }    
   
+  // For top-level tag definitions, make sure we chain the the tag decl to
+  // the vardecl. This enables the AST streamer to see both X and D in the
+  // following example: struct X { int A; } D; 
+  if (S->getParent() == 0)
+    AddTopLevelDecl(New);
+
   // If this has an identifier, add it to the scope stack.
   if (Name) {
     // The scope passed in may not be a decl scope.  Zip up the scope tree until
@@ -1695,7 +1701,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK,
     Name->setFETokenInfo(New);
     S->AddDecl(New);
   }
-  
+
   return New;
 }
 
@@ -2456,13 +2462,12 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX,
   Enum->defineElements(EltList, BestType);
 }
 
-void Sema::AddTopLevelDecl(Decl *current, Decl *last) {
+void Sema::AddTopLevelDecl(Decl *current) {
   if (!current) return;
 
   // If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
-  // remember this in the LastInGroupList list.
-  if (last)
-    LastInGroupList.push_back((Decl*)last);
+  // remember this in the TopLevelDeclList list.
+  TopLevelDeclList.push_back((Decl*)current);
 }
 
 void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) {
index db10ad3f4485e2c426c967ccbb81ca21eff00545..1585d851d9ab75d8c3735019ca05102a2daa5db4 100644 (file)
                08FB7793FE84155DC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
                        projectDirPath = "";
index 3fb3e2e7c86e1c3eac62850fb812816ab0637ab4..7b479e6620e2b45380180c4cee414e0a984c2963 100644 (file)
@@ -74,9 +74,9 @@ public:
   ///
   void Initialize();
   
-  /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
-  /// action tells us to.  This returns true if the EOF was encountered.
-  bool ParseTopLevelDecl(DeclTy*& Result);
+  /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if 
+  /// the EOF was encountered.
+  bool ParseTopLevelDecl();
   
   /// Finalize - Shut down the parser.
   ///