summaryrefslogtreecommitdiff
path: root/lib/Frontend
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-06-27 10:45:02 +0000
committerEd Schouten <ed@FreeBSD.org>2009-06-27 10:45:02 +0000
commit4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (patch)
tree2c5a83521a20c02e7805581a174008aa9bc23579 /lib/Frontend
parentf698f7e71940663e26a4806a96fb0bdfa160c886 (diff)
Notes
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/ASTUnit.cpp6
-rw-r--r--lib/Frontend/AnalysisConsumer.cpp4
-rw-r--r--lib/Frontend/CMakeLists.txt7
-rw-r--r--lib/Frontend/PCHReader.cpp9
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp8
-rw-r--r--lib/Frontend/PCHWriter.cpp16
-rw-r--r--lib/Frontend/ResolveLocation.cpp322
7 files changed, 361 insertions, 11 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index a7fbcda8fc2be..8143263ca2f94 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -113,14 +113,10 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
break;
case PCHReader::Failure:
- // Unrecoverable failure: don't even try to process the input
- // file.
+ case PCHReader::IgnorePCH:
if (ErrMsg)
*ErrMsg = "Could not load PCH file";
return NULL;
-
- case PCHReader::IgnorePCH:
- assert(0 && "Is there a validation that should not have happened ?");
}
// PCH loaded successfully. Now create the preprocessor.
diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp
index ae90594a40991..d8fa141d8cb6e 100644
--- a/lib/Frontend/AnalysisConsumer.cpp
+++ b/lib/Frontend/AnalysisConsumer.cpp
@@ -469,10 +469,6 @@ static void ActionCheckerCFRef(AnalysisManager& mgr) {
}
}
-static void ActionCheckerSimple(AnalysisManager& mgr) {
- ActionGRExprEngine(mgr, MakeGRSimpleValsTF());
-}
-
static void ActionDisplayLiveVariables(AnalysisManager& mgr) {
if (LiveVariables* L = mgr.getLiveVariables()) {
mgr.DisplayFunction();
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 4ba39c9594248..f8d09dbee89e2 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_NO_RTTI 1)
add_clang_library(clangFrontend
AnalysisConsumer.cpp
ASTConsumers.cpp
+ ASTUnit.cpp
Backend.cpp
CacheTokens.cpp
DeclXML.cpp
@@ -25,6 +26,7 @@ add_clang_library(clangFrontend
PlistDiagnostics.cpp
PrintParserCallbacks.cpp
PrintPreprocessedOutput.cpp
+ ResolveLocation.cpp
RewriteBlocks.cpp
RewriteMacros.cpp
RewriteObjC.cpp
@@ -36,4 +38,7 @@ add_clang_library(clangFrontend
Warnings.cpp
)
-add_dependencies(clangFrontend ClangDiagnosticFrontend)
+add_dependencies(clangFrontend
+ ClangDiagnosticFrontend
+ ClangDiagnosticLex
+ ClangDiagnosticSema)
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 96f21f1128674..765655b01dd0c 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -71,6 +71,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
PARSE_LANGOPT_BENIGN(WritableStrings);
PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
diag::warn_pch_lax_vector_conversions);
+ PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
@@ -105,6 +106,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
}
PARSE_LANGOPT_BENIGN(getVisibilityMode());
PARSE_LANGOPT_BENIGN(InstantiationDepth);
+ PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
#undef PARSE_LANGOPT_IRRELEVANT
#undef PARSE_LANGOPT_BENIGN
@@ -1629,6 +1631,7 @@ bool PCHReader::ParseLanguageOptions(
PARSE_LANGOPT(PascalStrings);
PARSE_LANGOPT(WritableStrings);
PARSE_LANGOPT(LaxVectorConversions);
+ PARSE_LANGOPT(AltiVec);
PARSE_LANGOPT(Exceptions);
PARSE_LANGOPT(NeXTRuntime);
PARSE_LANGOPT(Freestanding);
@@ -1652,6 +1655,7 @@ bool PCHReader::ParseLanguageOptions(
LangOpts.setVisibilityMode((LangOptions::VisibilityMode)Record[Idx]);
++Idx;
PARSE_LANGOPT(InstantiationDepth);
+ PARSE_LANGOPT(OpenCL);
#undef PARSE_LANGOPT
return Listener->ReadLanguageOptions(LangOpts);
@@ -1822,7 +1826,10 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
QualType UnderlyingType = GetType(Record[0]);
return Context->getTypeOfType(UnderlyingType);
}
-
+
+ case pch::TYPE_DECLTYPE:
+ return Context->getDecltypeType(ReadTypeExpr());
+
case pch::TYPE_RECORD:
assert(Record.size() == 1 && "incorrect encoding of record type");
return Context->getTypeDeclType(cast<RecordDecl>(GetDecl(Record[0])));
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 3dd84c7b08ad5..3f6ae354dc3f8 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -489,6 +489,14 @@ Attr *PCHReader::ReadAttributes() {
New = ::new (*Context) NonNullAttr(ArgNums.data(), Size);
break;
}
+
+ case Attr::ReqdWorkGroupSize: {
+ unsigned X = Record[Idx++];
+ unsigned Y = Record[Idx++];
+ unsigned Z = Record[Idx++];
+ New = ::new (*Context) ReqdWorkGroupSizeAttr(X, Y, Z);
+ break;
+ }
SIMPLE_ATTR(ObjCException);
SIMPLE_ATTR(ObjCNSObject);
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 3b1eb080f229b..e93219e01d5c8 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -185,6 +185,11 @@ void PCHTypeWriter::VisitTypeOfType(const TypeOfType *T) {
Code = pch::TYPE_TYPEOF;
}
+void PCHTypeWriter::VisitDecltypeType(const DecltypeType *T) {
+ Writer.AddStmt(T->getUnderlyingExpr());
+ Code = pch::TYPE_DECLTYPE;
+}
+
void PCHTypeWriter::VisitTagType(const TagType *T) {
Writer.AddDeclRef(T->getDecl(), Record);
assert(!T->isBeingDefined() &&
@@ -526,6 +531,7 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings
Record.push_back(LangOpts.WritableStrings); // Allow writable strings
Record.push_back(LangOpts.LaxVectorConversions);
+ Record.push_back(LangOpts.AltiVec);
Record.push_back(LangOpts.Exceptions); // Support exception handling.
Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime.
@@ -563,6 +569,7 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
Record.push_back(LangOpts.getGCMode());
Record.push_back(LangOpts.getVisibilityMode());
Record.push_back(LangOpts.InstantiationDepth);
+ Record.push_back(LangOpts.OpenCL);
Stream.EmitRecord(pch::LANGUAGE_OPTIONS, Record);
}
@@ -1615,6 +1622,12 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
case Attr::Regparm:
Record.push_back(cast<RegparmAttr>(Attr)->getNumParams());
break;
+
+ case Attr::ReqdWorkGroupSize:
+ Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim());
+ Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim());
+ Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getZDim());
+ break;
case Attr::Section:
AddString(cast<SectionAttr>(Attr)->getName(), Record);
@@ -1896,6 +1909,9 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
case BuiltinType::NullPtr: ID = pch::PREDEF_TYPE_NULLPTR_ID; break;
case BuiltinType::Overload: ID = pch::PREDEF_TYPE_OVERLOAD_ID; break;
case BuiltinType::Dependent: ID = pch::PREDEF_TYPE_DEPENDENT_ID; break;
+ case BuiltinType::UndeducedAuto:
+ assert(0 && "Should not see undeduced auto here");
+ break;
}
Record.push_back((ID << 3) | T.getCVRQualifiers());
diff --git a/lib/Frontend/ResolveLocation.cpp b/lib/Frontend/ResolveLocation.cpp
new file mode 100644
index 0000000000000..a5f0d1f163651
--- /dev/null
+++ b/lib/Frontend/ResolveLocation.cpp
@@ -0,0 +1,322 @@
+//===--- ResolveLocation.cpp - Source location resolver ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines the ResolveLocationInAST function, which resolves a
+// source location into a <Decl *, Stmt *> pair.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/Support/Compiler.h"
+using namespace clang;
+
+namespace {
+
+/// \brief Base for the LocResolver classes. Mostly does source range checking.
+class VISIBILITY_HIDDEN LocResolverBase {
+protected:
+ ASTContext &Ctx;
+ SourceLocation Loc;
+
+ Decl *Dcl;
+ Stmt *Stm;
+ bool PassedLoc;
+
+ /// \brief Checks whether Loc is in the source range of 'D'.
+ ///
+ /// If it is, updates Dcl. If Loc is passed the source range, it sets
+ /// PassedLoc, otherwise it does nothing.
+ void CheckRange(Decl *D);
+
+ /// \brief Checks whether Loc is in the source range of 'Node'.
+ ///
+ /// If it is, updates Stm. If Loc is passed the source range, it sets
+ /// PassedLoc, otherwise it does nothing.
+ void CheckRange(Stmt *Node);
+
+ /// \brief Updates the end source range to cover the full length of the token
+ /// positioned at the end of the source range.
+ ///
+ /// e.g.,
+ /// @code
+ /// int foo
+ /// ^ ^
+ /// @endcode
+ /// will be updated to
+ /// @code
+ /// int foo
+ /// ^ ^
+ /// @endcode
+ void FixRange(SourceRange &Range);
+
+public:
+ LocResolverBase(ASTContext &ctx, SourceLocation loc)
+ : Ctx(ctx), Loc(loc), Dcl(0), Stm(0), PassedLoc(0) {}
+
+ /// \brief We found a AST node that corresponds to the source location.
+ bool FoundIt() const { return Dcl != 0 || Stm != 0; }
+
+ /// \brief We either found a AST node or we passed the source location while
+ /// searching.
+ bool Finished() const { return FoundIt() || PassedLoc; }
+
+ Decl *getDecl() const { return Dcl; }
+ Stmt *getStmt() const { return Stm; }
+
+ std::pair<Decl *, Stmt *> getResult() const {
+ return std::make_pair(getDecl(), getStmt());
+ }
+
+ /// \brief Debugging output.
+ void print(Decl *D);
+ /// \brief Debugging output.
+ void print(Stmt *Node);
+};
+
+/// \brief Searches a statement for the AST node that corresponds to a source
+/// location.
+class VISIBILITY_HIDDEN StmtLocResolver : public LocResolverBase,
+ public StmtVisitor<StmtLocResolver> {
+public:
+ StmtLocResolver(ASTContext &ctx, SourceLocation loc)
+ : LocResolverBase(ctx, loc) {}
+
+ void VisitDeclStmt(DeclStmt *Node);
+ void VisitStmt(Stmt *Node);
+};
+
+/// \brief Searches a declaration for the AST node that corresponds to a source
+/// location.
+class VISIBILITY_HIDDEN DeclLocResolver : public LocResolverBase,
+ public DeclVisitor<DeclLocResolver> {
+public:
+ DeclLocResolver(ASTContext &ctx, SourceLocation loc)
+ : LocResolverBase(ctx, loc) {}
+
+ void VisitDeclContext(DeclContext *DC);
+ void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
+ void VisitVarDecl(VarDecl *D);
+ void VisitFunctionDecl(FunctionDecl *D);
+ void VisitDecl(Decl *D);
+};
+
+} // anonymous namespace
+
+void StmtLocResolver::VisitDeclStmt(DeclStmt *Node) {
+ CheckRange(Node);
+ if (!FoundIt())
+ return;
+ assert(Stm == Node && "Result not updated ?");
+
+ // Search all declarations of this DeclStmt. If we found the one corresponding
+ // to the source location, update this StmtLocResolver's result.
+ DeclLocResolver DLR(Ctx, Loc);
+ for (DeclStmt::decl_iterator
+ I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) {
+ DLR.Visit(*I);
+ if (DLR.Finished()) {
+ if (DLR.FoundIt())
+ llvm::tie(Dcl, Stm) = DLR.getResult();
+ return;
+ }
+ }
+}
+
+void StmtLocResolver::VisitStmt(Stmt *Node) {
+ CheckRange(Node);
+ if (!FoundIt())
+ return;
+ assert(Stm == Node && "Result not updated ?");
+
+ // Search the child statements.
+ StmtLocResolver SLR(Ctx, Loc);
+ for (Stmt::child_iterator
+ I = Node->child_begin(), E = Node->child_end(); I != E; ++I) {
+ SLR.Visit(*I);
+ if (!SLR.Finished())
+ continue;
+
+ // We either found it or we passed the source location.
+
+ if (SLR.FoundIt()) {
+ // Only update Dcl if we found another more immediate 'parent' Decl for
+ // the statement.
+ if (SLR.getDecl())
+ Dcl = SLR.getDecl();
+ Stm = SLR.getStmt();
+ }
+
+ return;
+ }
+}
+
+void DeclLocResolver::VisitDeclContext(DeclContext *DC) {
+ DeclLocResolver DLR(Ctx, Loc);
+ for (DeclContext::decl_iterator
+ I = DC->decls_begin(Ctx), E = DC->decls_end(Ctx); I != E; ++I) {
+ DLR.Visit(*I);
+ if (DLR.Finished()) {
+ if (DLR.FoundIt())
+ llvm::tie(Dcl, Stm) = DLR.getResult();
+ return;
+ }
+ }
+}
+
+void DeclLocResolver::VisitTranslationUnitDecl(TranslationUnitDecl *TU) {
+ VisitDeclContext(TU);
+}
+
+void DeclLocResolver::VisitFunctionDecl(FunctionDecl *D) {
+ CheckRange(D);
+ if (!FoundIt())
+ return;
+ assert(Dcl == D && "Result not updated ?");
+
+ // First, search through the parameters of the function.
+ DeclLocResolver ParmRes(Ctx, Loc);
+ for (FunctionDecl::param_iterator
+ I = D->param_begin(), E = D->param_end(); I != E; ++I) {
+ ParmRes.Visit(*I);
+ if (ParmRes.Finished()) {
+ if (ParmRes.FoundIt())
+ llvm::tie(Dcl, Stm) = ParmRes.getResult();
+ return;
+ }
+ }
+
+ // We didn't found the location in the parameters and we didn't get passed it.
+
+ // Second, search through the declarations that are part of the function.
+ // If we find he location there, we won't have to search through its body.
+ DeclLocResolver DLR(Ctx, Loc);
+ DLR.VisitDeclContext(D);
+ if (DLR.FoundIt()) {
+ llvm::tie(Dcl, Stm) = DLR.getResult();
+ return;
+ }
+
+ // We didn't find a declaration that corresponds to the source location.
+
+ // Finally, search through the body of the function.
+ if (D->isThisDeclarationADefinition()) {
+ StmtLocResolver SLR(Ctx, Loc);
+ SLR.Visit(D->getBody(Ctx));
+ if (SLR.FoundIt()) {
+ llvm::tie(Dcl, Stm) = SLR.getResult();
+ // If we didn't find a more immediate 'parent' declaration for the
+ // statement, set the function as the parent.
+ if (Dcl == 0)
+ Dcl = D;
+ }
+ }
+}
+
+void DeclLocResolver::VisitVarDecl(VarDecl *D) {
+ CheckRange(D);
+ if (!FoundIt())
+ return;
+ assert(Dcl == D && "Result not updated ?");
+
+ // Check whether the location points to the init expression.
+ if (D->getInit()) {
+ StmtLocResolver SLR(Ctx, Loc);
+ SLR.Visit(D->getInit());
+ Stm = SLR.getStmt();
+ }
+}
+
+void DeclLocResolver::VisitDecl(Decl *D) {
+ CheckRange(D);
+}
+
+void LocResolverBase::CheckRange(Decl *D) {
+ SourceRange Range = D->getSourceRange();
+ if (!Range.isValid())
+ return;
+
+ FixRange(Range);
+
+ SourceManager &SourceMgr = Ctx.getSourceManager();
+ if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), Loc))
+ return;
+
+ if (SourceMgr.isBeforeInTranslationUnit(Loc, Range.getBegin()))
+ PassedLoc = true;
+ else
+ Dcl = D;
+}
+
+void LocResolverBase::CheckRange(Stmt *Node) {
+ SourceRange Range = Node->getSourceRange();
+ if (!Range.isValid())
+ return;
+
+ FixRange(Range);
+
+ SourceManager &SourceMgr = Ctx.getSourceManager();
+ if (SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), Loc))
+ return;
+
+ if (SourceMgr.isBeforeInTranslationUnit(Loc, Range.getBegin()))
+ PassedLoc = true;
+ else
+ Stm = Node;
+}
+
+void LocResolverBase::FixRange(SourceRange &Range) {
+ if (!Range.isValid())
+ return;
+
+ unsigned TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
+ Ctx.getSourceManager(),
+ Ctx.getLangOptions());
+ Range.setEnd(Range.getEnd().getFileLocWithOffset(TokSize-1));
+}
+
+void LocResolverBase::print(Decl *D) {
+ llvm::raw_ostream &OS = llvm::outs();
+ OS << "#### DECL ####\n";
+ D->print(OS, Ctx);
+ OS << " <";
+ D->getLocStart().print(OS, Ctx.getSourceManager());
+ OS << " > - <";
+ D->getLocEnd().print(OS, Ctx.getSourceManager());
+ OS << ">\n\n";
+ OS.flush();
+}
+
+void LocResolverBase::print(Stmt *Node) {
+ llvm::raw_ostream &OS = llvm::outs();
+ OS << "#### STMT ####\n";
+ Node->printPretty(OS, Ctx);
+ OS << " <";
+ Node->getLocStart().print(OS, Ctx.getSourceManager());
+ OS << " > - <";
+ Node->getLocEnd().print(OS, Ctx.getSourceManager());
+ OS << ">\n\n";
+ OS.flush();
+}
+
+
+/// \brief Returns the AST node that a source location points to.
+///
+std::pair<Decl *, Stmt *>
+clang::ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc) {
+ if (Loc.isInvalid())
+ return std::make_pair((Decl*)0, (Stmt*)0);
+
+ DeclLocResolver DLR(Ctx, Loc);
+ DLR.Visit(Ctx.getTranslationUnitDecl());
+ return DLR.getResult();
+}