Push DeclGroup much farther throughout the compiler. Now the various
productions (except the already broken ObjC cases like @class X,Y;) in
the parser that can produce more than one Decl return a DeclGroup instead
of a Decl, etc.
This allows elimination of the Decl::NextDeclarator field, and exposes
various clients that should look at all decls in a group, but which were
only looking at one (such as the dumper, printer, etc). These have been
fixed.
Still TODO:
1) there are some FIXME's in the code about potentially using
DeclGroup for better location info.
2) ParseObjCAtDirectives should return a DeclGroup due to @class etc.
3) I'm not sure what is going on with StmtIterator.cpp, or if it can
be radically simplified now.
4) I put a truly horrible hack in ParseTemplate.cpp.
I plan to bring up #3/4 on the mailing list, but don't plan to tackle
#1/2 in the short term.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68002 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/clang-cc/ASTConsumers.cpp b/tools/clang-cc/ASTConsumers.cpp
index cb09659..3910c77 100644
--- a/tools/clang-cc/ASTConsumers.cpp
+++ b/tools/clang-cc/ASTConsumers.cpp
@@ -539,8 +539,9 @@
public:
ASTPrinter(llvm::raw_ostream* o = NULL) : DeclPrinter(o) {}
- virtual void HandleTopLevelDecl(Decl *D) {
- PrintDecl(D);
+ virtual void HandleTopLevelDecl(DeclGroupRef D) {
+ for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+ PrintDecl(*I);
}
};
} // end anonymous namespace
@@ -562,11 +563,15 @@
SM = &Context.getSourceManager();
}
- virtual void HandleTopLevelDecl(Decl *D);
+ virtual void HandleTopLevelDecl(DeclGroupRef D) {
+ for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+ HandleTopLevelSingleDecl(*I);
+ }
+ void HandleTopLevelSingleDecl(Decl *D);
};
} // end anonymous namespace
-void ASTDumper::HandleTopLevelDecl(Decl *D) {
+void ASTDumper::HandleTopLevelSingleDecl(Decl *D) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
PrintFunctionDeclStart(FD);
@@ -624,12 +629,17 @@
void Initialize(ASTContext &Context) {
SM = &Context.getSourceManager();
}
+
+ virtual void HandleTopLevelDecl(DeclGroupRef D) {
+ for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+ HandleTopLevelSingleDecl(*I);
+ }
- virtual void HandleTopLevelDecl(Decl *D);
+ void HandleTopLevelSingleDecl(Decl *D);
};
}
-void ASTViewer::HandleTopLevelDecl(Decl *D) {
+void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
DeclPrinter().PrintFunctionDeclStart(FD);
diff --git a/tools/clang-cc/AnalysisConsumer.cpp b/tools/clang-cc/AnalysisConsumer.cpp
index 366f384..bc38593 100644
--- a/tools/clang-cc/AnalysisConsumer.cpp
+++ b/tools/clang-cc/AnalysisConsumer.cpp
@@ -220,7 +220,12 @@
Ctx = &Context;
}
- virtual void HandleTopLevelDecl(Decl *D);
+ virtual void HandleTopLevelDecl(DeclGroupRef D) {
+ for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+ HandleTopLevelSingleDecl(*I);
+ }
+
+ void HandleTopLevelSingleDecl(Decl *D);
virtual void HandleTranslationUnit(ASTContext &C);
void HandleCode(Decl* D, Stmt* Body, Actions& actions);
@@ -411,7 +416,7 @@
// AnalysisConsumer implementation.
//===----------------------------------------------------------------------===//
-void AnalysisConsumer::HandleTopLevelDecl(Decl *D) {
+void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
switch (D->getKind()) {
case Decl::Function: {
FunctionDecl* FD = cast<FunctionDecl>(D);
diff --git a/tools/clang-cc/Backend.cpp b/tools/clang-cc/Backend.cpp
index 0faabbe..3b3be31 100644
--- a/tools/clang-cc/Backend.cpp
+++ b/tools/clang-cc/Backend.cpp
@@ -8,11 +8,12 @@
//===----------------------------------------------------------------------===//
#include "ASTConsumers.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/CompileOptions.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/Basic/TargetInfo.h"
#include "llvm/Module.h"
#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
@@ -117,13 +118,14 @@
LLVMIRGeneration.stopTimer();
}
- virtual void HandleTopLevelDecl(Decl *D) {
- PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
+ virtual void HandleTopLevelDecl(DeclGroupRef D) {
+ PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
Context->getSourceManager(),
"LLVM IR generation of declaration");
+
if (CompileOpts.TimePasses)
LLVMIRGeneration.startTimer();
-
+
Gen->HandleTopLevelDecl(D);
if (CompileOpts.TimePasses)
diff --git a/tools/clang-cc/PrintParserCallbacks.cpp b/tools/clang-cc/PrintParserCallbacks.cpp
index 9dce6d8..dc25f54 100644
--- a/tools/clang-cc/PrintParserCallbacks.cpp
+++ b/tools/clang-cc/PrintParserCallbacks.cpp
@@ -29,8 +29,7 @@
/// ActOnDeclarator - This callback is invoked when a declarator is parsed
/// and 'Init' specifies the initializer if any. This is for things like:
/// "int X = 4" or "typedef int foo".
- virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D,
- DeclPtrTy LastInGroup) {
+ virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
llvm::cout << __FUNCTION__ << " ";
if (IdentifierInfo *II = D.getIdentifier()) {
llvm::cout << "'" << II->getName() << "'";
@@ -40,7 +39,7 @@
llvm::cout << "\n";
// Pass up to EmptyActions so that the symbol table is maintained right.
- return MinimalAction::ActOnDeclarator(S, D, LastInGroup);
+ return MinimalAction::ActOnDeclarator(S, D);
}
/// ActOnPopScope - This callback is called immediately before the specified
/// scope is popped and deleted.
@@ -112,17 +111,20 @@
llvm::cout << __FUNCTION__ << "\n";
}
- /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
- /// gives the actions implementation a chance to process the group as a whole.
- virtual DeclPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy Group) {
+ /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed,
+ /// this gives the actions implementation a chance to process the group as
+ /// a whole.
+ virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, DeclPtrTy *Group,
+ unsigned NumDecls) {
llvm::cout << __FUNCTION__ << "\n";
- return DeclPtrTy();
+ return DeclGroupPtrTy();
}
/// ActOnStartOfFunctionDef - This is called at the start of a function
/// definition, instead of calling ActOnDeclarator. The Declarator includes
/// information about formal arguments that are part of this function.
- virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
+ virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *FnBodyScope,
+ Declarator &D){
llvm::cout << __FUNCTION__ << "\n";
return DeclPtrTy();
}
@@ -256,7 +258,7 @@
llvm::cout << __FUNCTION__ << "\n";
return StmtEmpty();
}
- virtual OwningStmtResult ActOnDeclStmt(DeclPtrTy Decl,
+ virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
SourceLocation StartLoc,
SourceLocation EndLoc) {
llvm::cout << __FUNCTION__ << "\n";
diff --git a/tools/clang-cc/RewriteBlocks.cpp b/tools/clang-cc/RewriteBlocks.cpp
index 2672d32..f302913 100644
--- a/tools/clang-cc/RewriteBlocks.cpp
+++ b/tools/clang-cc/RewriteBlocks.cpp
@@ -83,7 +83,11 @@
const char *NewStr, unsigned NewLength);
// Top Level Driver code.
- virtual void HandleTopLevelDecl(Decl *D);
+ virtual void HandleTopLevelDecl(DeclGroupRef D) {
+ for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+ HandleTopLevelSingleDecl(*I);
+ }
+ void HandleTopLevelSingleDecl(Decl *D);
void HandleDeclInMainFile(Decl *D);
// Top level
@@ -336,7 +340,7 @@
// Top Level Driver Code
//===----------------------------------------------------------------------===//
-void RewriteBlocks::HandleTopLevelDecl(Decl *D) {
+void RewriteBlocks::HandleTopLevelSingleDecl(Decl *D) {
// Two cases: either the decl could be in the main file, or it could be in a
// #included file. If the former, rewrite it now. If the later, check to see
// if we rewrote the #include/#import.
diff --git a/tools/clang-cc/RewriteObjC.cpp b/tools/clang-cc/RewriteObjC.cpp
index e0267ec..5fcecc6 100644
--- a/tools/clang-cc/RewriteObjC.cpp
+++ b/tools/clang-cc/RewriteObjC.cpp
@@ -126,7 +126,11 @@
virtual void Initialize(ASTContext &context);
// Top Level Driver code.
- virtual void HandleTopLevelDecl(Decl *D);
+ virtual void HandleTopLevelDecl(DeclGroupRef D) {
+ for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
+ HandleTopLevelSingleDecl(*I);
+ }
+ void HandleTopLevelSingleDecl(Decl *D);
void HandleDeclInMainFile(Decl *D);
RewriteObjC(std::string inFile, std::string outFile,
Diagnostic &D, const LangOptions &LOpts);
@@ -550,7 +554,7 @@
// Top Level Driver Code
//===----------------------------------------------------------------------===//
-void RewriteObjC::HandleTopLevelDecl(Decl *D) {
+void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
// Two cases: either the decl could be in the main file, or it could be in a
// #included file. If the former, rewrite it now. If the later, check to see
// if we rewrote the #include/#import.
@@ -583,7 +587,7 @@
for (DeclContext::decl_iterator DI = LSD->decls_begin(),
DIEnd = LSD->decls_end();
DI != DIEnd; ++DI)
- HandleTopLevelDecl(*DI);
+ HandleTopLevelSingleDecl(*DI);
}
// If we have a decl in the main file, see if we should rewrite it.
if (SM->isFromMainFile(Loc))
diff --git a/tools/clang-cc/SerializationTest.cpp b/tools/clang-cc/SerializationTest.cpp
index 74ccb4b..fda8d88 100644
--- a/tools/clang-cc/SerializationTest.cpp
+++ b/tools/clang-cc/SerializationTest.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/CFG.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
#include "clang.h"
#include "ASTConsumers.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -73,7 +74,7 @@
TranslationUnitDecl *TUD = Ctx.getTranslationUnitDecl();
for (DeclContext::decl_iterator I = TUD->decls_begin(), E =TUD->decls_end();
I != E; ++I)
- FilePrinter->HandleTopLevelDecl(*I);
+ FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I));
}
// Serialize the translation unit.
@@ -124,7 +125,7 @@
TranslationUnitDecl *TUD = NewCtx->getTranslationUnitDecl();
for (DeclContext::decl_iterator I = TUD->decls_begin(), E = TUD->decls_end();
I != E; ++I)
- FilePrinter->HandleTopLevelDecl(*I);
+ FilePrinter->HandleTopLevelDecl(DeclGroupRef(*I));
}
delete NewCtx;
diff --git a/tools/clang-cc/clang.cpp b/tools/clang-cc/clang.cpp
index c0a2ae7..5b1e6ab 100644
--- a/tools/clang-cc/clang.cpp
+++ b/tools/clang-cc/clang.cpp
@@ -37,6 +37,7 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
#include "clang/Parse/Parser.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/LexDiagnostic.h"
@@ -1563,7 +1564,7 @@
TranslationUnitDecl *TUD = Ctx->getTranslationUnitDecl();
for (DeclContext::decl_iterator I = TUD->decls_begin(), E = TUD->decls_end();
I != E; ++I)
- Consumer->HandleTopLevelDecl(*I);
+ Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
}