tblgen: Diagnose duplicate includes.
authorSean Silva <silvas@purdue.edu>
Thu, 7 Feb 2013 04:30:39 +0000 (04:30 +0000)
committerSean Silva <silvas@purdue.edu>
Thu, 7 Feb 2013 04:30:39 +0000 (04:30 +0000)
A double inclusion will pretty much always be an error in TableGen, so
there's no point going on just to die with "def already defined" or
whatnot.

I'm not too thrilled about the "public: ... private: ..." to expose the
DependenciesMapTy, but I really didn't see a better way to keep that
type centralized. It's a smell that indicates that some refactoring is
needed to make this code more loosely coupled.

This should avoid all bugs of the same nature as PR15189.

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

lib/TableGen/Main.cpp
lib/TableGen/TGLexer.cpp
lib/TableGen/TGLexer.h
lib/TableGen/TGParser.h

index d0ca756016f2ac2a8343b16bbfece1167bc8001d..e1cd6237832c5ace7ca554db988d4ca1fc00307b 100644 (file)
@@ -64,11 +64,11 @@ static int createDependencyFile(const TGParser &Parser, const char *argv0) {
     return 1;
   }
   DepOut.os() << OutputFilename << ":";
-  const std::vector<std::string> &Dependencies = Parser.getDependencies();
-  for (std::vector<std::string>::const_iterator I = Dependencies.begin(),
-                                                E = Dependencies.end();
+  const TGLexer::DependenciesMapTy &Dependencies = Parser.getDependencies();
+  for (TGLexer::DependenciesMapTy::const_iterator I = Dependencies.begin(),
+                                                  E = Dependencies.end();
        I != E; ++I) {
-    DepOut.os() << " " << (*I);
+    DepOut.os() << " " << I->first;
   }
   DepOut.os() << "\n";
   DepOut.keep();
index e75abcfa38b92f62fee9cce5799912ff7fcd0bb6..c6be4f8a118937ac68250ebb033f73c0df76a4ba 100644 (file)
@@ -309,7 +309,15 @@ bool TGLexer::LexInclude() {
     return true;
   }
   
-  Dependencies.push_back(IncludedFile);
+  DependenciesMapTy::const_iterator Found = Dependencies.find(IncludedFile);
+  if (Found != Dependencies.end()) {
+    PrintError(getLoc(),
+               "File '" + IncludedFile + "' has already been included.");
+    SrcMgr.PrintMessage(Found->second, SourceMgr::DK_Note,
+                        "previously included here");
+    return true;
+  }
+  Dependencies.insert(std::make_pair(IncludedFile, getLoc()));
   // Save the line number and lex buffer of the includer.
   CurBuf = SrcMgr.getMemoryBuffer(CurBuffer);
   CurPtr = CurBuf->getBufferStart();
index a0818f9db74c4a0b49452ea47e5ecab7c0528ec9..d1bd70d2eca427caf9778ab51118bbf171d0cdde 100644 (file)
 #define TGLEXER_H
 
 #include "llvm/Support/DataTypes.h"
+#include "llvm/Support/SMLoc.h"
 #include <cassert>
+#include <map>
 #include <string>
-#include <vector>
 
 namespace llvm {
 class MemoryBuffer;
@@ -73,9 +74,13 @@ class TGLexer {
   /// CurBuffer - This is the current buffer index we're lexing from as managed
   /// by the SourceMgr object.
   int CurBuffer;
+
+public:
+  typedef std::map<std::string, SMLoc> DependenciesMapTy;
+private:
   /// Dependencies - This is the list of all included files.
-  std::vector<std::string> Dependencies;
-  
+  DependenciesMapTy Dependencies;
+
 public:
   TGLexer(SourceMgr &SrcMgr);
   ~TGLexer() {}
@@ -84,7 +89,7 @@ public:
     return CurCode = LexToken();
   }
 
-  const std::vector<std::string> &getDependencies() const {
+  const DependenciesMapTy &getDependencies() const {
     return Dependencies;
   }
   
index e55805d55255342c368a41e3b84012db1d4e93c7..044e3a02ba4bc7e200075bec56482576b13711bb 100644 (file)
@@ -96,7 +96,7 @@ public:
   bool TokError(const Twine &Msg) const {
     return Error(Lex.getLoc(), Msg);
   }
-  const std::vector<std::string> &getDependencies() const {
+  const TGLexer::DependenciesMapTy &getDependencies() const {
     return Lex.getDependencies();
   }