Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/amd-common' into HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
rocm-hcc committed Aug 14, 2019
2 parents 8ab3385 + 97f66fd commit 3082659
Show file tree
Hide file tree
Showing 41 changed files with 1,230 additions and 391 deletions.
10 changes: 9 additions & 1 deletion docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,15 @@ release of Clang. Users of the build system should adjust accordingly.
install-clang-headers target now installs clang's API headers (corresponding
to its libraries), which is consistent with the install-llvm-headers target.

- ...
- In 9.0.0 and later Clang added a new target, clang-cpp, which generates a
shared library comprised of all the clang component libraries and exporting
the clang C++ APIs. Additionally the build system gained the new
"CLANG_LINK_CLANG_DYLIB" option, which defaults Off, and when set to On, will
force clang (and clang-based tools) to link the clang-cpp library instead of
statically linking clang's components. This option will reduce the size of
binary distributions at the expense of compiler performance.

- ...

AST Matchers
------------
Expand Down
14 changes: 14 additions & 0 deletions include/clang/AST/ASTImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,20 @@ class TypeSourceInfo;
/// imported. If it does not exist nullptr is returned.
TranslationUnitDecl *GetFromTU(Decl *ToD);

/// Return the declaration in the "from" context from which the declaration
/// in the "to" context was imported. If it was not imported or of the wrong
/// type a null value is returned.
template <typename DeclT>
llvm::Optional<DeclT *> getImportedFromDecl(const DeclT *ToD) const {
auto FromI = ImportedFromDecls.find(ToD);
if (FromI == ImportedFromDecls.end())
return {};
auto *FromD = dyn_cast<DeclT>(FromI->second);
if (!FromD)
return {};
return FromD;
}

/// Import the given declaration context from the "from"
/// AST context into the "to" AST context.
///
Expand Down
6 changes: 6 additions & 0 deletions include/clang/AST/FormatString.h
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,12 @@ bool ParseScanfString(FormatStringHandler &H,
const char *beg, const char *end, const LangOptions &LO,
const TargetInfo &Target);

/// Return true if the given string has at least one formatting specifier.
bool parseFormatStringHasFormattingSpecifiers(const char *Begin,
const char *End,
const LangOptions &LO,
const TargetInfo &Target);

} // end analyze_format_string namespace
} // end clang namespace
#endif
3 changes: 2 additions & 1 deletion include/clang/AST/RawCommentList.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ class RawCommentList {
void addComment(const RawComment &RC, const CommentOptions &CommentOpts,
llvm::BumpPtrAllocator &Allocator);

/// \returns nullptr in case there are no comments in in \p File.
/// \returns A mapping from an offset of the start of the comment to the
/// comment itself, or nullptr in case there are no comments in \p File.
const std::map<unsigned, RawComment *> *getCommentsInFile(FileID File) const;

bool empty() const;
Expand Down
179 changes: 177 additions & 2 deletions include/clang/Analysis/CFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,144 @@ class CFGBlock {
bool empty() const { return Impl.empty(); }
};

/// A convenience class for comparing CFGElements, since methods of CFGBlock
/// like operator[] return CFGElements by value. This is practically a wrapper
/// around a (CFGBlock, Index) pair.
template <bool IsConst> class ElementRefImpl {

template <bool IsOtherConst> friend class ElementRefImpl;

using CFGBlockPtr =
typename std::conditional<IsConst, const CFGBlock *, CFGBlock *>::type;

using CFGElementPtr = typename std::conditional<IsConst, const CFGElement *,
CFGElement *>::type;

protected:
CFGBlockPtr Parent;
size_t Index;

public:
ElementRefImpl(CFGBlockPtr Parent, size_t Index)
: Parent(Parent), Index(Index) {}

template <bool IsOtherConst>
ElementRefImpl(ElementRefImpl<IsOtherConst> Other)
: ElementRefImpl(Other.Parent, Other.Index) {}

size_t getIndexInBlock() const { return Index; }

CFGBlockPtr getParent() { return Parent; }
CFGBlockPtr getParent() const { return Parent; }

bool operator<(ElementRefImpl Other) const {
return std::make_pair(Parent, Index) <
std::make_pair(Other.Parent, Other.Index);
}

bool operator==(ElementRefImpl Other) const {
return Parent == Other.Parent && Index == Other.Index;
}

bool operator!=(ElementRefImpl Other) const { return !(*this == Other); }
CFGElement operator*() { return (*Parent)[Index]; }
CFGElementPtr operator->() { return &*(Parent->begin() + Index); }
};

template <bool IsReverse, bool IsConst> class ElementRefIterator {

template <bool IsOtherReverse, bool IsOtherConst>
friend class ElementRefIterator;

using CFGBlockRef =
typename std::conditional<IsConst, const CFGBlock *, CFGBlock *>::type;

using UnderlayingIteratorTy = typename std::conditional<
IsConst,
typename std::conditional<IsReverse,
ElementList::const_reverse_iterator,
ElementList::const_iterator>::type,
typename std::conditional<IsReverse, ElementList::reverse_iterator,
ElementList::iterator>::type>::type;

using IteratorTraits = typename std::iterator_traits<UnderlayingIteratorTy>;
using ElementRef = typename CFGBlock::ElementRefImpl<IsConst>;

public:
using difference_type = typename IteratorTraits::difference_type;
using value_type = ElementRef;
using pointer = ElementRef *;
using iterator_category = typename IteratorTraits::iterator_category;

private:
CFGBlockRef Parent;
UnderlayingIteratorTy Pos;

public:
ElementRefIterator(CFGBlockRef Parent, UnderlayingIteratorTy Pos)
: Parent(Parent), Pos(Pos) {}

template <bool IsOtherConst>
ElementRefIterator(ElementRefIterator<false, IsOtherConst> E)
: ElementRefIterator(E.Parent, E.Pos.base()) {}

template <bool IsOtherConst>
ElementRefIterator(ElementRefIterator<true, IsOtherConst> E)
: ElementRefIterator(E.Parent, llvm::make_reverse_iterator(E.Pos)) {}

bool operator<(ElementRefIterator Other) const {
assert(Parent == Other.Parent);
return Pos < Other.Pos;
}

bool operator==(ElementRefIterator Other) const {
return Parent == Other.Parent && Pos == Other.Pos;
}

bool operator!=(ElementRefIterator Other) const {
return !(*this == Other);
}

private:
template <bool IsOtherConst>
static size_t
getIndexInBlock(CFGBlock::ElementRefIterator<true, IsOtherConst> E) {
return E.Parent->size() - (E.Pos - E.Parent->rbegin()) - 1;
}

template <bool IsOtherConst>
static size_t
getIndexInBlock(CFGBlock::ElementRefIterator<false, IsOtherConst> E) {
return E.Pos - E.Parent->begin();
}

public:
value_type operator*() { return {Parent, getIndexInBlock(*this)}; }

difference_type operator-(ElementRefIterator Other) const {
return Pos - Other.Pos;
}

ElementRefIterator operator++() {
++this->Pos;
return *this;
}
ElementRefIterator operator++(int) {
ElementRefIterator Ret = *this;
++*this;
return Ret;
}
ElementRefIterator operator+(size_t count) {
this->Pos += count;
return *this;
}
ElementRefIterator operator-(size_t count) {
this->Pos -= count;
return *this;
}
};

public:
/// The set of statements in the basic block.
ElementList Elements;

Expand Down Expand Up @@ -715,6 +853,8 @@ class CFGBlock {
using reverse_iterator = ElementList::reverse_iterator;
using const_reverse_iterator = ElementList::const_reverse_iterator;

size_t getIndexInCFG() const;

CFGElement front() const { return Elements.front(); }
CFGElement back() const { return Elements.back(); }

Expand All @@ -728,6 +868,38 @@ class CFGBlock {
const_reverse_iterator rbegin() const { return Elements.rbegin(); }
const_reverse_iterator rend() const { return Elements.rend(); }

using CFGElementRef = ElementRefImpl<false>;
using ConstCFGElementRef = ElementRefImpl<true>;

using ref_iterator = ElementRefIterator<false, false>;
using ref_iterator_range = llvm::iterator_range<ref_iterator>;
using const_ref_iterator = ElementRefIterator<false, true>;
using const_ref_iterator_range = llvm::iterator_range<const_ref_iterator>;

using reverse_ref_iterator = ElementRefIterator<true, false>;
using reverse_ref_iterator_range = llvm::iterator_range<reverse_ref_iterator>;

using const_reverse_ref_iterator = ElementRefIterator<true, true>;
using const_reverse_ref_iterator_range =
llvm::iterator_range<const_reverse_ref_iterator>;

ref_iterator ref_begin() { return {this, begin()}; }
ref_iterator ref_end() { return {this, end()}; }
const_ref_iterator ref_begin() const { return {this, begin()}; }
const_ref_iterator ref_end() const { return {this, end()}; }

reverse_ref_iterator rref_begin() { return {this, rbegin()}; }
reverse_ref_iterator rref_end() { return {this, rend()}; }
const_reverse_ref_iterator rref_begin() const { return {this, rbegin()}; }
const_reverse_ref_iterator rref_end() const { return {this, rend()}; }

ref_iterator_range refs() { return {ref_begin(), ref_end()}; }
const_ref_iterator_range refs() const { return {ref_begin(), ref_end()}; }
reverse_ref_iterator_range rrefs() { return {rref_begin(), rref_end()}; }
const_reverse_ref_iterator_range rrefs() const {
return {rref_begin(), rref_end()};
}

unsigned size() const { return Elements.size(); }
bool empty() const { return Elements.empty(); }

Expand Down Expand Up @@ -855,6 +1027,10 @@ class CFGBlock {
void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
void setHasNoReturnElement() { HasNoReturnElement = true; }

/// Returns true if the block would eventually end with a sink (a noreturn
/// node).
bool isInevitablySinking() const;

CFGTerminator getTerminator() const { return Terminator; }

Stmt *getTerminatorStmt() { return Terminator.getStmt(); }
Expand Down Expand Up @@ -894,7 +1070,7 @@ class CFGBlock {
void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
void printTerminatorJson(raw_ostream &Out, const LangOptions &LO,
bool AddQuotes) const;

void printAsOperand(raw_ostream &OS, bool /*PrintType*/) {
OS << "BB#" << getBlockID();
}
Expand Down Expand Up @@ -1010,7 +1186,6 @@ class CFGBlock {
*I = CFGScopeEnd(VD, S);
return ++I;
}

};

/// CFGCallback defines methods that should be called when a logical
Expand Down
6 changes: 6 additions & 0 deletions include/clang/Basic/IdentifierTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,12 @@ class Selector {
return getIdentifierInfoFlag() == ZeroArg;
}

/// If this selector is the specific keyword selector described by Names.
bool isKeywordSelector(ArrayRef<StringRef> Names) const;

/// If this selector is the specific unary selector described by Name.
bool isUnarySelector(StringRef Name) const;

unsigned getNumArgs() const;

/// Retrieve the identifier at a given position in the selector.
Expand Down
9 changes: 9 additions & 0 deletions include/clang/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "clang/Driver/Util.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/StringSaver.h"

Expand Down Expand Up @@ -250,9 +251,17 @@ class Driver {

// getFinalPhase - Determine which compilation mode we are in and record
// which option we used to determine the final phase.
// TODO: Much of what getFinalPhase returns are not actually true compiler
// modes. Fold this functionality into Types::getCompilationPhases and
// handleArguments.
phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
llvm::opt::Arg **FinalPhaseArg = nullptr) const;

// handleArguments - All code related to claiming and printing diagnostics
// related to arguments to the driver are done here.
void handleArguments(Compilation &C, llvm::opt::DerivedArgList &Args,
const InputList &Inputs, ActionList &Actions) const;

// Before executing jobs, sets up response files for commands that need them.
void setUpResponseFiles(Compilation &C, Command &Cmd);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ class FindLastStoreBRVisitor final : public BugReporterVisitor {

using TrackingKind = bugreporter::TrackingKind;
TrackingKind TKind;
const StackFrameContext *OriginSFC;

public:
/// Creates a visitor for every VarDecl inside a Stmt and registers it with
Expand All @@ -145,11 +146,18 @@ class FindLastStoreBRVisitor final : public BugReporterVisitor {
/// \param EnableNullFPSuppression Whether we should employ false positive
/// suppression (inlined defensive checks, returned null).
/// \param TKind May limit the amount of notes added to the bug report.
/// \param OriginSFC Only adds notes when the last store happened in a
/// different stackframe to this one. Disregarded if the tracking kind
/// is thorough.
/// This is useful, because for non-tracked regions, notes about
/// changes to its value in a nested stackframe could be pruned, and
/// this visitor can prevent that without polluting the bugpath too
/// much.
FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R,
bool InEnableNullFPSuppression,
TrackingKind TKind)
bool InEnableNullFPSuppression, TrackingKind TKind,
const StackFrameContext *OriginSFC = nullptr)
: R(R), V(V), EnableNullFPSuppression(InEnableNullFPSuppression),
TKind(TKind) {
TKind(TKind), OriginSFC(OriginSFC) {
assert(R);
}

Expand Down
2 changes: 0 additions & 2 deletions include/clang/Tooling/AllTUsExecution.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ class AllTUsToolExecutor : public ToolExecutor {

StringRef getExecutorName() const override { return ExecutorName; }

bool isSingleProcess() const override { return true; }

using ToolExecutor::execute;

llvm::Error
Expand Down
7 changes: 0 additions & 7 deletions include/clang/Tooling/Execution.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,6 @@ class ToolExecutor {
/// Returns the name of a specific executor.
virtual StringRef getExecutorName() const = 0;

/// Should return true iff executor runs all actions in a single process.
/// Clients can use this signal to find out if they can collect results
/// in-memory (e.g. to avoid serialization costs of using ToolResults).
/// The single-process executors can still run multiple threads, but all
/// executions are guaranteed to share the same memory.
virtual bool isSingleProcess() const = 0;

/// Executes each action with a corresponding arguments adjuster.
virtual llvm::Error
execute(llvm::ArrayRef<
Expand Down
2 changes: 0 additions & 2 deletions include/clang/Tooling/StandaloneExecution.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ class StandaloneToolExecutor : public ToolExecutor {

StringRef getExecutorName() const override { return ExecutorName; }

bool isSingleProcess() const override { return true; }

using ToolExecutor::execute;

llvm::Error
Expand Down
Loading

0 comments on commit 3082659

Please sign in to comment.