From 159ee39f4d3382165e8374a6879850808509d827 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 18 Jan 2008 01:15:54 +0000 Subject: [PATCH] Insert #pragma once when rewriting a header file. llvm-svn: 46155 --- clang/Driver/ASTConsumers.h | 3 ++- clang/Driver/RewriteTest.cpp | 41 ++++++++++++++++++++++++++++++------ clang/Driver/clang.cpp | 2 +- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/clang/Driver/ASTConsumers.h b/clang/Driver/ASTConsumers.h index 19c339c589c9..423b23f27d60 100644 --- a/clang/Driver/ASTConsumers.h +++ b/clang/Driver/ASTConsumers.h @@ -48,7 +48,8 @@ ASTConsumer *CreateBCWriter(const std::string& InFile, Diagnostic &Diags, const LangOptions &LOpts); -ASTConsumer *CreateCodeRewriterTest(Diagnostic &Diags); +ASTConsumer *CreateCodeRewriterTest(const std::string& InFile, + Diagnostic &Diags); ASTConsumer *CreateSerializationTest(Diagnostic &Diags, FileManager& FMgr, diff --git a/clang/Driver/RewriteTest.cpp b/clang/Driver/RewriteTest.cpp index 8d3035bd1212..fb52dfe29f75 100644 --- a/clang/Driver/RewriteTest.cpp +++ b/clang/Driver/RewriteTest.cpp @@ -65,6 +65,9 @@ namespace { ObjCMethodDecl *CurMethodDecl; RecordDecl *SuperStructDecl; + // Needed for header files being rewritten + bool IsHeader; + static const int OBJC_ABI_VERSION =7 ; public: void Initialize(ASTContext &context) { @@ -96,7 +99,8 @@ namespace { Rewrite.setSourceMgr(Context->getSourceManager()); // declaring objc_selector outside the parameter list removes a silly // scope related warning... - const char *s = "struct objc_selector; struct objc_class;\n" + const char *s = "#pragma once\n" + "struct objc_selector; struct objc_class;\n" "#ifndef OBJC_SUPER\n" "struct objc_super { struct objc_object *o; " "struct objc_object *superClass; };\n" @@ -136,15 +140,23 @@ namespace { "unsigned long extra[5];\n};\n" "#define __FASTENUMERATIONSTATE\n" "#endif\n"; - - Rewrite.InsertText(SourceLocation::getFileLoc(MainFileID, 0), - s, strlen(s)); + if (IsHeader) { + // insert the whole string when rewriting a header file + Rewrite.InsertText(SourceLocation::getFileLoc(MainFileID, 0), + s, strlen(s)); + } + else { + // Not rewriting header, exclude the #pragma once pragma + const char *p = s + strlen("#pragma once\n"); + Rewrite.InsertText(SourceLocation::getFileLoc(MainFileID, 0), + p, strlen(p)); + } } // Top Level Driver code. virtual void HandleTopLevelDecl(Decl *D); void HandleDeclInMainFile(Decl *D); - RewriteTest(Diagnostic &D) : Diags(D) {} + RewriteTest(bool isHeader, Diagnostic &D) : Diags(D) {IsHeader = isHeader;} ~RewriteTest(); // Syntactic Rewriting. @@ -226,8 +238,23 @@ namespace { }; } -ASTConsumer *clang::CreateCodeRewriterTest(Diagnostic &Diags) { - return new RewriteTest(Diags); +static bool IsHeaderFile(const std::string &Filename) { + std::string::size_type DotPos = Filename.rfind('.'); + + if (DotPos == std::string::npos) { + // no file extension + return false; + } + + std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end()); + // C header: .h + // C++ header: .hh or .H; + return Ext == "h" || Ext == "hh" || Ext == "H"; +} + +ASTConsumer *clang::CreateCodeRewriterTest(const std::string& InFile, + Diagnostic &Diags) { + return new RewriteTest(IsHeaderFile(InFile), Diags); } //===----------------------------------------------------------------------===// diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 17df87a53ee0..19c40d88fe26 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -964,7 +964,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, return CreateASTSerializer(InFile, OutputFile, Diag, LangOpts); case RewriteTest: - return CreateCodeRewriterTest(Diag); + return CreateCodeRewriterTest(InFile, Diag); } }