aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-11-19 09:00:00 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-11-19 09:00:00 +0000
commitf5bd02d290ff15268853e0456c130a1afa15e907 (patch)
treec7f5a7b6fd212399d821b83b22c1e6a42e8c4a0d
parentb3d5a323a5ca92ea73443499cee2f15db1ff0fb3 (diff)
downloadsrc-f5bd02d290ff15268853e0456c130a1afa15e907.tar.gz
src-f5bd02d290ff15268853e0456c130a1afa15e907.zip
Update clang to r89337.
Notes
Notes: svn path=/vendor/clang/dist/; revision=199512
-rw-r--r--include/clang/AST/CFG.h408
-rw-r--r--include/clang/AST/DeclObjC.h2
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h28
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h30
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h28
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h34
-rw-r--r--include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h39
-rw-r--r--include/clang/Analysis/Visitors/CFGVarDeclVisitor.h63
-rw-r--r--include/clang/Basic/Diagnostic.h4
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--include/clang/CMakeLists.txt1
-rw-r--r--include/clang/Driver/ArgList.h50
-rw-r--r--include/clang/Driver/CC1Options.h34
-rw-r--r--include/clang/Driver/CC1Options.td26
-rw-r--r--include/clang/Driver/CMakeLists.txt11
-rw-r--r--include/clang/Driver/Makefile16
-rw-r--r--include/clang/Driver/OptParser.td116
-rw-r--r--include/clang/Driver/OptSpecifier.h36
-rw-r--r--include/clang/Driver/OptTable.h163
-rw-r--r--include/clang/Driver/Option.h39
-rw-r--r--include/clang/Driver/Options.def661
-rw-r--r--include/clang/Driver/Options.h68
-rw-r--r--include/clang/Driver/Options.td607
-rw-r--r--include/clang/Frontend/CompileOptions.h77
-rw-r--r--include/clang/Frontend/HeaderSearchOptions.h4
-rw-r--r--include/clang/Frontend/InitHeaderSearch.h98
-rw-r--r--include/clang/Frontend/InitPreprocessor.h79
-rw-r--r--include/clang/Frontend/ManagerRegistry.h53
-rw-r--r--include/clang/Makefile2
-rw-r--r--include/clang/Parse/Action.h113
-rw-r--r--include/clang/Parse/Parser.h3
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h53
-rw-r--r--lib/CodeGen/CGCXX.cpp4
-rw-r--r--lib/CodeGen/CGDecl.cpp1
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp5
-rw-r--r--lib/CodeGen/CGRtti.cpp107
-rw-r--r--lib/CodeGen/CGVtable.cpp111
-rw-r--r--lib/CodeGen/CGVtable.h4
-rw-r--r--lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--lib/Driver/ArgList.cpp59
-rw-r--r--lib/Driver/CC1Options.cpp43
-rw-r--r--lib/Driver/CMakeLists.txt4
-rw-r--r--lib/Driver/Compilation.cpp1
-rw-r--r--lib/Driver/Driver.cpp54
-rw-r--r--lib/Driver/DriverOptions.cpp42
-rw-r--r--lib/Driver/HostInfo.cpp10
-rw-r--r--lib/Driver/OptTable.cpp220
-rw-r--r--lib/Driver/Option.cpp53
-rw-r--r--lib/Driver/ToolChains.cpp11
-rw-r--r--lib/Driver/Tools.cpp30
-rw-r--r--lib/Driver/Types.cpp6
-rw-r--r--lib/Frontend/CompilerInvocation.cpp15
-rw-r--r--lib/Frontend/InitPreprocessor.cpp11
-rw-r--r--lib/Frontend/PCHReader.cpp5
-rw-r--r--lib/Headers/stdint.h34
-rw-r--r--lib/Parse/ParseExpr.cpp11
-rw-r--r--lib/Parse/ParseObjc.cpp113
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp61
-rw-r--r--lib/Sema/Lookup.h86
-rw-r--r--lib/Sema/Sema.cpp2
-rw-r--r--lib/Sema/Sema.h66
-rw-r--r--lib/Sema/SemaCXXCast.cpp26
-rw-r--r--lib/Sema/SemaCodeComplete.cpp523
-rw-r--r--lib/Sema/SemaDecl.cpp457
-rw-r--r--lib/Sema/SemaDeclCXX.cpp22
-rw-r--r--lib/Sema/SemaDeclObjC.cpp7
-rw-r--r--lib/Sema/SemaExprCXX.cpp6
-rw-r--r--lib/Sema/SemaLookup.cpp6
-rw-r--r--lib/Sema/SemaOverload.cpp222
-rw-r--r--lib/Sema/SemaTemplate.cpp41
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp42
-rw-r--r--lib/Sema/TreeTransform.h23
-rw-r--r--test/Analysis/null-deref-ps.c2
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp6
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp4
-rw-r--r--test/CXX/special/class.dtor/p2.cpp7
-rw-r--r--test/CodeGen/libcalls.c4
-rw-r--r--test/Driver/analyze.c2
-rw-r--r--test/Driver/clang-translation.c1
-rw-r--r--test/Driver/clang_f_opts.c5
-rw-r--r--test/Index/TestClassDecl.m28
-rw-r--r--test/Index/TestClassForwardDecl.m28
-rw-r--r--test/Index/c-index-api-loadTU-test.m30
-rw-r--r--test/Index/complete-categories.m39
-rw-r--r--test/Index/complete-interfaces.m43
-rw-r--r--test/Index/complete-objc-message.m29
-rw-r--r--test/Index/complete-properties.m40
-rw-r--r--test/Index/complete-property-flags.m23
-rw-r--r--test/Index/complete-property-getset.m41
-rw-r--r--test/Parser/objc-synthesized-recover.m15
-rw-r--r--test/Preprocessor/init.c44
-rw-r--r--test/Preprocessor/stdint.c142
-rw-r--r--test/Sema/unused-expr.c2
-rw-r--r--test/SemaCXX/abstract.cpp17
-rw-r--r--test/SemaCXX/cxx-member-pointer-op.cpp21
-rw-r--r--test/SemaCXX/overloaded-operator.cpp38
-rw-r--r--test/SemaCXX/reinterpret-cast.cpp6
-rw-r--r--test/SemaCXX/rval-references.cpp8
-rw-r--r--test/SemaCXX/using-directive.cpp12
-rw-r--r--test/SemaObjC/class-protocol.m6
-rw-r--r--test/SemaObjC/no-warn-qual-mismatch.m16
-rw-r--r--test/SemaTemplate/constructor-template.cpp8
-rw-r--r--test/SemaTemplate/instantiate-case.cpp21
-rw-r--r--tools/CIndex/CIndex.cpp2
-rw-r--r--tools/clang-cc/Options.cpp94
-rw-r--r--tools/driver/CMakeLists.txt12
-rw-r--r--tools/driver/Makefile3
-rw-r--r--tools/driver/cc1_main.cpp88
-rw-r--r--tools/driver/driver.cpp8
110 files changed, 3682 insertions, 2721 deletions
diff --git a/include/clang/AST/CFG.h b/include/clang/AST/CFG.h
deleted file mode 100644
index e60e58e1ac23..000000000000
--- a/include/clang/AST/CFG.h
+++ /dev/null
@@ -1,408 +0,0 @@
-//===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CFG and CFGBuilder classes for representing and
-// building Control-Flow Graphs (CFGs) from ASTs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_CFG_H
-#define LLVM_CLANG_CFG_H
-
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/Support/Allocator.h"
-#include <list>
-#include <vector>
-#include <cassert>
-
-namespace llvm {
- class raw_ostream;
-}
-namespace clang {
- class Stmt;
- class Expr;
- class CFG;
- class PrinterHelper;
- class BlockEdge;
- class LangOptions;
-
-/// CFGBlock - Represents a single basic block in a source-level CFG.
-/// It consists of:
-///
-/// (1) A set of statements/expressions (which may contain subexpressions).
-/// (2) A "terminator" statement (not in the set of statements).
-/// (3) A list of successors and predecessors.
-///
-/// Terminator: The terminator represents the type of control-flow that occurs
-/// at the end of the basic block. The terminator is a Stmt* referring to an
-/// AST node that has control-flow: if-statements, breaks, loops, etc.
-/// If the control-flow is conditional, the condition expression will appear
-/// within the set of statements in the block (usually the last statement).
-///
-/// Predecessors: the order in the set of predecessors is arbitrary.
-///
-/// Successors: the order in the set of successors is NOT arbitrary. We
-/// currently have the following orderings based on the terminator:
-///
-/// Terminator Successor Ordering
-/// -----------------------------------------------------
-/// if Then Block; Else Block
-/// ? operator LHS expression; RHS expression
-/// &&, || expression that uses result of && or ||, RHS
-///
-class CFGBlock {
- typedef std::vector<Stmt*> StatementListTy;
- /// Stmts - The set of statements in the basic block.
- StatementListTy Stmts;
-
- /// Label - An (optional) label that prefixes the executable
- /// statements in the block. When this variable is non-NULL, it is
- /// either an instance of LabelStmt or SwitchCase.
- Stmt *Label;
-
- /// Terminator - The terminator for a basic block that
- /// indicates the type of control-flow that occurs between a block
- /// and its successors.
- Stmt *Terminator;
-
- /// LoopTarget - Some blocks are used to represent the "loop edge" to
- /// the start of a loop from within the loop body. This Stmt* will be
- /// refer to the loop statement for such blocks (and be null otherwise).
- const Stmt *LoopTarget;
-
- /// BlockID - A numerical ID assigned to a CFGBlock during construction
- /// of the CFG.
- unsigned BlockID;
-
- /// Predecessors/Successors - Keep track of the predecessor / successor
- /// CFG blocks.
- typedef std::vector<CFGBlock*> AdjacentBlocks;
- AdjacentBlocks Preds;
- AdjacentBlocks Succs;
-
-public:
- explicit CFGBlock(unsigned blockid) : Label(NULL), Terminator(NULL),
- LoopTarget(NULL), BlockID(blockid) {}
- ~CFGBlock() {};
-
- // Statement iterators
- typedef StatementListTy::iterator iterator;
- typedef StatementListTy::const_iterator const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- Stmt* front() const { return Stmts.front(); }
- Stmt* back() const { return Stmts.back(); }
-
- iterator begin() { return Stmts.begin(); }
- iterator end() { return Stmts.end(); }
- const_iterator begin() const { return Stmts.begin(); }
- const_iterator end() const { return Stmts.end(); }
-
- reverse_iterator rbegin() { return Stmts.rbegin(); }
- reverse_iterator rend() { return Stmts.rend(); }
- const_reverse_iterator rbegin() const { return Stmts.rbegin(); }
- const_reverse_iterator rend() const { return Stmts.rend(); }
-
- unsigned size() const { return Stmts.size(); }
- bool empty() const { return Stmts.empty(); }
-
- Stmt* operator[](size_t i) const { assert (i < size()); return Stmts[i]; }
-
- // CFG iterators
- typedef AdjacentBlocks::iterator pred_iterator;
- typedef AdjacentBlocks::const_iterator const_pred_iterator;
- typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator;
- typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator;
-
- typedef AdjacentBlocks::iterator succ_iterator;
- typedef AdjacentBlocks::const_iterator const_succ_iterator;
- typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator;
- typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator;
-
- pred_iterator pred_begin() { return Preds.begin(); }
- pred_iterator pred_end() { return Preds.end(); }
- const_pred_iterator pred_begin() const { return Preds.begin(); }
- const_pred_iterator pred_end() const { return Preds.end(); }
-
- pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); }
- pred_reverse_iterator pred_rend() { return Preds.rend(); }
- const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
- const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
-
- succ_iterator succ_begin() { return Succs.begin(); }
- succ_iterator succ_end() { return Succs.end(); }
- const_succ_iterator succ_begin() const { return Succs.begin(); }
- const_succ_iterator succ_end() const { return Succs.end(); }
-
- succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); }
- succ_reverse_iterator succ_rend() { return Succs.rend(); }
- const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
- const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
-
- unsigned succ_size() const { return Succs.size(); }
- bool succ_empty() const { return Succs.empty(); }
-
- unsigned pred_size() const { return Preds.size(); }
- bool pred_empty() const { return Preds.empty(); }
-
- // Manipulation of block contents
-
- void appendStmt(Stmt* Statement) { Stmts.push_back(Statement); }
- void setTerminator(Stmt* Statement) { Terminator = Statement; }
- void setLabel(Stmt* Statement) { Label = Statement; }
- void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
-
- Stmt* getTerminator() { return Terminator; }
- const Stmt* getTerminator() const { return Terminator; }
-
- Stmt* getTerminatorCondition();
-
- const Stmt* getTerminatorCondition() const {
- return const_cast<CFGBlock*>(this)->getTerminatorCondition();
- }
-
- const Stmt *getLoopTarget() const { return LoopTarget; }
-
- bool hasBinaryBranchTerminator() const;
-
- Stmt* getLabel() { return Label; }
- const Stmt* getLabel() const { return Label; }
-
- void reverseStmts();
-
- void addSuccessor(CFGBlock* Block) {
- Block->Preds.push_back(this);
- Succs.push_back(Block);
- }
-
- unsigned getBlockID() const { return BlockID; }
-
- void dump(const CFG *cfg, const LangOptions &LO) const;
- void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
- void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const;
-};
-
-
-/// CFG - Represents a source-level, intra-procedural CFG that represents the
-/// control-flow of a Stmt. The Stmt can represent an entire function body,
-/// or a single expression. A CFG will always contain one empty block that
-/// represents the Exit point of the CFG. A CFG will also contain a designated
-/// Entry block. The CFG solely represents control-flow; it consists of
-/// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
-/// was constructed from.
-class CFG {
-public:
- //===--------------------------------------------------------------------===//
- // CFG Construction & Manipulation.
- //===--------------------------------------------------------------------===//
-
- /// buildCFG - Builds a CFG from an AST. The responsibility to free the
- /// constructed CFG belongs to the caller.
- static CFG* buildCFG(Stmt* AST);
-
- /// createBlock - Create a new block in the CFG. The CFG owns the block;
- /// the caller should not directly free it.
- CFGBlock* createBlock();
-
- /// setEntry - Set the entry block of the CFG. This is typically used
- /// only during CFG construction. Most CFG clients expect that the
- /// entry block has no predecessors and contains no statements.
- void setEntry(CFGBlock *B) { Entry = B; }
-
- /// setExit - Set the exit block of the CFG. This is typically used
- /// only during CFG construction. Most CFG clients expect that the
- /// exit block has no successors and contains no statements.
- void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; }
-
- //===--------------------------------------------------------------------===//
- // Block Iterators
- //===--------------------------------------------------------------------===//
-
- typedef std::list<CFGBlock> CFGBlockListTy;
-
- typedef CFGBlockListTy::iterator iterator;
- typedef CFGBlockListTy::const_iterator const_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- CFGBlock& front() { return Blocks.front(); }
- CFGBlock& back() { return Blocks.back(); }
-
- iterator begin() { return Blocks.begin(); }
- iterator end() { return Blocks.end(); }
- const_iterator begin() const { return Blocks.begin(); }
- const_iterator end() const { return Blocks.end(); }
-
- reverse_iterator rbegin() { return Blocks.rbegin(); }
- reverse_iterator rend() { return Blocks.rend(); }
- const_reverse_iterator rbegin() const { return Blocks.rbegin(); }
- const_reverse_iterator rend() const { return Blocks.rend(); }
-
- CFGBlock& getEntry() { return *Entry; }
- const CFGBlock& getEntry() const { return *Entry; }
- CFGBlock& getExit() { return *Exit; }
- const CFGBlock& getExit() const { return *Exit; }
-
- CFGBlock* getIndirectGotoBlock() { return IndirectGotoBlock; }
- const CFGBlock* getIndirectGotoBlock() const { return IndirectGotoBlock; }
-
- //===--------------------------------------------------------------------===//
- // Member templates useful for various batch operations over CFGs.
- //===--------------------------------------------------------------------===//
-
- template <typename CALLBACK>
- void VisitBlockStmts(CALLBACK& O) const {
- for (const_iterator I=begin(), E=end(); I != E; ++I)
- for (CFGBlock::const_iterator BI=I->begin(), BE=I->end(); BI != BE; ++BI)
- O(*BI);
- }
-
- //===--------------------------------------------------------------------===//
- // CFG Introspection.
- //===--------------------------------------------------------------------===//
-
- struct BlkExprNumTy {
- const signed Idx;
- explicit BlkExprNumTy(signed idx) : Idx(idx) {}
- explicit BlkExprNumTy() : Idx(-1) {}
- operator bool() const { return Idx >= 0; }
- operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
- };
-
- bool isBlkExpr(const Stmt* S) { return getBlkExprNum(S); }
- BlkExprNumTy getBlkExprNum(const Stmt* S);
- unsigned getNumBlkExprs();
-
- unsigned getNumBlockIDs() const { return NumBlockIDs; }
-
- //===--------------------------------------------------------------------===//
- // CFG Debugging: Pretty-Printing and Visualization.
- //===--------------------------------------------------------------------===//
-
- void viewCFG(const LangOptions &LO) const;
- void print(llvm::raw_ostream& OS, const LangOptions &LO) const;
- void dump(const LangOptions &LO) const;
-
- //===--------------------------------------------------------------------===//
- // Internal: constructors and data.
- //===--------------------------------------------------------------------===//
-
- CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
- BlkExprMap(NULL) {};
-
- ~CFG();
-
- llvm::BumpPtrAllocator& getAllocator() {
- return Alloc;
- }
-
-private:
- CFGBlock* Entry;
- CFGBlock* Exit;
- CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch
- // for indirect gotos
- CFGBlockListTy Blocks;
- unsigned NumBlockIDs;
-
- // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h.
- // It represents a map from Expr* to integers to record the set of
- // block-level expressions and their "statement number" in the CFG.
- void* BlkExprMap;
-
- /// Alloc - An internal allocator.
- llvm::BumpPtrAllocator Alloc;
-};
-} // end namespace clang
-
-//===----------------------------------------------------------------------===//
-// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-
-// Traits for: CFGBlock
-
-template <> struct GraphTraits<clang::CFGBlock* > {
- typedef clang::CFGBlock NodeType;
- typedef clang::CFGBlock::succ_iterator ChildIteratorType;
-
- static NodeType* getEntryNode(clang::CFGBlock* BB)
- { return BB; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->succ_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->succ_end(); }
-};
-
-template <> struct GraphTraits<const clang::CFGBlock* > {
- typedef const clang::CFGBlock NodeType;
- typedef clang::CFGBlock::const_succ_iterator ChildIteratorType;
-
- static NodeType* getEntryNode(const clang::CFGBlock* BB)
- { return BB; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->succ_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->succ_end(); }
-};
-
-template <> struct GraphTraits<Inverse<const clang::CFGBlock*> > {
- typedef const clang::CFGBlock NodeType;
- typedef clang::CFGBlock::const_pred_iterator ChildIteratorType;
-
- static NodeType *getEntryNode(Inverse<const clang::CFGBlock*> G)
- { return G.Graph; }
-
- static inline ChildIteratorType child_begin(NodeType* N)
- { return N->pred_begin(); }
-
- static inline ChildIteratorType child_end(NodeType* N)
- { return N->pred_end(); }
-};
-
-// Traits for: CFG
-
-template <> struct GraphTraits<clang::CFG* >
- : public GraphTraits<clang::CFGBlock* > {
-
- typedef clang::CFG::iterator nodes_iterator;
-
- static NodeType *getEntryNode(clang::CFG* F) { return &F->getEntry(); }
- static nodes_iterator nodes_begin(clang::CFG* F) { return F->begin(); }
- static nodes_iterator nodes_end(clang::CFG* F) { return F->end(); }
-};
-
-template <> struct GraphTraits< const clang::CFG* >
- : public GraphTraits< const clang::CFGBlock* > {
-
- typedef clang::CFG::const_iterator nodes_iterator;
-
- static NodeType *getEntryNode( const clang::CFG* F) { return &F->getEntry(); }
- static nodes_iterator nodes_begin( const clang::CFG* F) { return F->begin(); }
- static nodes_iterator nodes_end( const clang::CFG* F) { return F->end(); }
-};
-
-template <> struct GraphTraits<Inverse<const clang::CFG*> >
- : public GraphTraits<Inverse<const clang::CFGBlock*> > {
-
- typedef clang::CFG::const_iterator nodes_iterator;
-
- static NodeType *getEntryNode(const clang::CFG* F) { return &F->getExit(); }
- static nodes_iterator nodes_begin(const clang::CFG* F) { return F->begin();}
- static nodes_iterator nodes_end(const clang::CFG* F) { return F->end(); }
-};
-
-} // end llvm namespace
-
-#endif
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 13193ffab55e..897776cdb9b8 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -808,7 +808,7 @@ public:
/// - myMethod;
/// @end
///
-/// Cateogries also allow you to split the implementation of a class across
+/// Categories also allow you to split the implementation of a class across
/// several files (a feature more naturally supported in C++).
///
/// Categories were originally inspired by dynamic languages such as Common
diff --git a/include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h b/include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h
deleted file mode 100644
index 007ec093b2e0..000000000000
--- a/include/clang/Analysis/PathSensitive/Checkers/AttrNonNullChecker.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===--- AttrNonNullChecker.h - Undefined arguments checker ----*- C++ -*--===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines AttrNonNullChecker, a builtin check in GRExprEngine that
-// performs checks for arguments declared to have nonnull attribute.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
-
-namespace clang {
-
-class AttrNonNullChecker : public CheckerVisitor<AttrNonNullChecker> {
- BugType *BT;
-
-public:
- AttrNonNullChecker() : BT(0) {}
- static void *getTag();
- void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
-};
-
-}
diff --git a/include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h b/include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h
deleted file mode 100644
index 70f3c44165e0..000000000000
--- a/include/clang/Analysis/PathSensitive/Checkers/BadCallChecker.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===--- BadCallChecker.h - Bad call checker --------------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines BadCallChecker, a builtin check in GRExprEngine that performs
-// checks for bad callee at call sites.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
-
-namespace clang {
-
-class BadCallChecker : public CheckerVisitor<BadCallChecker> {
- BuiltinBug *BT;
-
-public:
- BadCallChecker() : BT(0) {}
-
- static void *getTag();
-
- void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
-};
-
-}
diff --git a/include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h b/include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h
deleted file mode 100644
index 317e43a0e62e..000000000000
--- a/include/clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//== DivZeroChecker.h - Division by zero checker ----------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines DivZeroChecker, a builtin check in GRExprEngine that performs
-// checks for division by zeros.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
-
-namespace clang {
-
-class DivZeroChecker : public CheckerVisitor<DivZeroChecker> {
- BuiltinBug *BT;
-public:
- DivZeroChecker() : BT(0) {}
-
- static void *getTag();
- void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
-};
-
-}
diff --git a/include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h b/include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h
deleted file mode 100644
index 7f4e7d524f6c..000000000000
--- a/include/clang/Analysis/PathSensitive/Checkers/UndefinedArgChecker.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===--- UndefinedArgChecker.h - Undefined arguments checker ----*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines BadCallChecker, a builtin check in GRExprEngine that performs
-// checks for undefined arguments.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_UNDEFARGCHECKER
-#define LLVM_CLANG_UNDEFARGCHECKER
-
-#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
-
-namespace clang {
-
-class UndefinedArgChecker : public CheckerVisitor<UndefinedArgChecker> {
- BugType *BT;
-
-public:
- UndefinedArgChecker() : BT(0) {}
-
- static void *getTag();
-
- void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
-};
-
-}
-#endif
diff --git a/include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h b/include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h
deleted file mode 100644
index b339b3d30141..000000000000
--- a/include/clang/Analysis/PathSensitive/Checkers/VLASizeChecker.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//=== VLASizeChecker.h - Undefined dereference checker ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines two VLASizeCheckers, a builtin check in GRExprEngine that
-// performs checks for declaration of VLA of undefined or zero size.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/Checker.h"
-
-namespace clang {
-
-class UndefSizedVLAChecker : public Checker {
- BugType *BT;
-
-public:
- UndefSizedVLAChecker() : BT(0) {}
- static void *getTag();
- ExplodedNode *CheckType(QualType T, ExplodedNode *Pred,
- const GRState *state, Stmt *S, GRExprEngine &Eng);
-};
-
-class ZeroSizedVLAChecker : public Checker {
- BugType *BT;
-
-public:
- ZeroSizedVLAChecker() : BT(0) {}
- static void *getTag();
- ExplodedNode *CheckType(QualType T, ExplodedNode *Pred,
- const GRState *state, Stmt *S, GRExprEngine &Eng);
-};
-
-}
diff --git a/include/clang/Analysis/Visitors/CFGVarDeclVisitor.h b/include/clang/Analysis/Visitors/CFGVarDeclVisitor.h
deleted file mode 100644
index 1bc798f4e79e..000000000000
--- a/include/clang/Analysis/Visitors/CFGVarDeclVisitor.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//==- CFGVarDeclVisitor - Generic visitor of VarDecls in a CFG --*- C++ --*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the template class CFGVarDeclVisitor, which provides
-// a generic way to visit all the VarDecl's in a CFG.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_CFG_VARDECL_VISITOR_H
-#define LLVM_CLANG_ANALYSIS_CFG_VARDECL_VISITOR_H
-
-#include "clang/Analysis/Visitors/CFGStmtVisitor.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Stmt.h"
-
-namespace clang {
-
-template <typename ImplClass>
-class CFGVarDeclVisitor : public CFGStmtVisitor<ImplClass> {
- const CFG& cfg;
-public:
- CFGVarDeclVisitor(const CFG& c) : cfg(c) {}
-
- void VisitStmt(Stmt* S) {
- static_cast<ImplClass*>(this)->VisitChildren(S);
- }
-
- void VisitDeclRefExpr(DeclRefExpr* DR) {
- static_cast<ImplClass*>(this)->VisitDeclChain(DR->getDecl());
- }
-
- void VisitDeclStmt(DeclStmt* DS) {
- static_cast<ImplClass*>(this)->VisitDeclChain(DS->getDecl());
- }
-
- void VisitDeclChain(ScopedDecl* D) {
- for (; D != NULL ; D = D->getNextDeclarator())
- static_cast<ImplClass*>(this)->VisitScopedDecl(D);
- }
-
- void VisitScopedDecl(ScopedDecl* D) {
- if (VarDecl* V = dyn_cast<VarDecl>(D))
- static_cast<ImplClass*>(this)->VisitVarDecl(V);
- }
-
- void VisitVarDecl(VarDecl* D) {}
-
- void VisitAllDecls() {
- for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI)
- for (CFGBlock::const_iterator SI=BI->begin(),SE = BI->end();SI != SE;++SI)
- static_cast<ImplClass*>(this)->BlockStmt_Visit(const_cast<Stmt*>(*SI));
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 3a70e134b82b..00a5bc6e937d 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -235,8 +235,8 @@ public:
// Diagnostic characterization methods, used by a client to customize how
//
- DiagnosticClient *getClient() { return Client; };
- const DiagnosticClient *getClient() const { return Client; };
+ DiagnosticClient *getClient() { return Client; }
+ const DiagnosticClient *getClient() const { return Client; }
/// pushMappings - Copies the current DiagMappings and pushes the new copy
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 28c46cd2d707..3a8c5bf8f1b8 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -117,8 +117,6 @@ def err_expected_semi_after_static_assert : Error<
"expected ';' after static_assert">;
def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
def err_expected_colon_after : Error<"expected ':' after %0">;
-def err_pointer_to_member_type : Error<
- "invalid use of pointer to member type after %0">;
def err_label_end_of_compound_statement : Error<
"label at end of compound statement: expected statement">;
def err_expected_string_literal : Error<"expected string literal">;
@@ -201,6 +199,8 @@ def warn_expected_implementation : Warning<
"@end must appear in an @implementation context">;
def error_property_ivar_decl : Error<
"property synthesize requires specification of an ivar">;
+def err_synthesized_property_name : Error<
+ "expected a property name in @synthesize">;
def warn_semicolon_before_method_body : Warning<
"semicolon before method body is ignored">,
InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 78a3ae5d47b7..a864d8ab9e72 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -979,6 +979,8 @@ def err_template_arg_not_pointer_to_member_form : Error<
"non-type template argument is not a pointer to member constant">;
def err_template_arg_extra_parens : Error<
"non-type template argument cannot be surrounded by parentheses">;
+def err_pointer_to_member_type : Error<
+ "invalid use of pointer to member type after %select{.*|->*}0">;
// C++ template specialization
def err_template_spec_unknown_kind : Error<
@@ -1811,6 +1813,8 @@ def err_typecheck_bool_condition : Error<
"value of type %0 is not contextually convertible to 'bool'">;
def err_typecheck_ambiguous_condition : Error<
"conversion from %0 to %1 is ambiguous">;
+def err_typecheck_nonviable_condition : Error<
+ "no viable conversion from %0 to %1 is possible">;
def err_expected_class_or_namespace : Error<"expected a class or namespace">;
def err_invalid_declarator_scope : Error<
"definition or redeclaration of %0 not in a namespace enclosing %1">;
diff --git a/include/clang/CMakeLists.txt b/include/clang/CMakeLists.txt
index 39e3698a1655..61d2bf602d9a 100644
--- a/include/clang/CMakeLists.txt
+++ b/include/clang/CMakeLists.txt
@@ -1 +1,2 @@
add_subdirectory(Basic)
+add_subdirectory(Driver)
diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h
index dcb60381a467..5263108d1a6d 100644
--- a/include/clang/Driver/ArgList.h
+++ b/include/clang/Driver/ArgList.h
@@ -10,8 +10,7 @@
#ifndef CLANG_DRIVER_ARGLIST_H_
#define CLANG_DRIVER_ARGLIST_H_
-#include "clang/Driver/Options.h"
-
+#include "clang/Driver/OptSpecifier.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -26,6 +25,7 @@ namespace llvm {
namespace clang {
namespace driver {
class Arg;
+ class Option;
/// ArgList - Ordered collection of driver arguments.
///
@@ -77,20 +77,26 @@ namespace driver {
/// hasArg - Does the arg list contain any option matching \arg Id.
///
/// \arg Claim Whether the argument should be claimed, if it exists.
- bool hasArg(options::ID Id, bool Claim=true) const {
- return getLastArg(Id, Claim) != 0;
+ bool hasArgNoClaim(OptSpecifier Id) const {
+ return getLastArgNoClaim(Id) != 0;
+ }
+ bool hasArg(OptSpecifier Id) const {
+ return getLastArg(Id) != 0;
+ }
+ bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
+ return getLastArg(Id0, Id1) != 0;
}
- bool hasArg(options::ID Id0, options::ID Id1, bool Claim=true) const {
- return getLastArg(Id0, Id1, Claim) != 0;
+ bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
+ return getLastArg(Id0, Id1, Id2) != 0;
}
/// getLastArg - Return the last argument matching \arg Id, or null.
///
/// \arg Claim Whether the argument should be claimed, if it exists.
- Arg *getLastArg(options::ID Id, bool Claim=true) const;
- Arg *getLastArg(options::ID Id0, options::ID Id1, bool Claim=true) const;
- Arg *getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
- bool Claim=true) const;
+ Arg *getLastArgNoClaim(OptSpecifier Id) const;
+ Arg *getLastArg(OptSpecifier Id) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
+ Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
/// getArgString - Return the input argument string at \arg Index.
virtual const char *getArgString(unsigned Index) const = 0;
@@ -102,24 +108,24 @@ namespace driver {
/// negation is present, and \arg Default if neither option is
/// given. If both the option and its negation are present, the
/// last one wins.
- bool hasFlag(options::ID Pos, options::ID Neg, bool Default=true) const;
+ bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
/// AddLastArg - Render only the last argument match \arg Id0, if
/// present.
- void AddLastArg(ArgStringList &Output, options::ID Id0) const;
+ void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
/// AddAllArgs - Render all arguments matching the given ids.
- void AddAllArgs(ArgStringList &Output, options::ID Id0) const;
- void AddAllArgs(ArgStringList &Output, options::ID Id0,
- options::ID Id1) const;
- void AddAllArgs(ArgStringList &Output, options::ID Id0, options::ID Id1,
- options::ID Id2) const;
+ void AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const;
+ void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1) const;
+ void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1,
+ OptSpecifier Id2) const;
/// AddAllArgValues - Render the argument values of all arguments
/// matching the given ids.
- void AddAllArgValues(ArgStringList &Output, options::ID Id0) const;
- void AddAllArgValues(ArgStringList &Output, options::ID Id0,
- options::ID Id1) const;
+ void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const;
+ void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1) const;
/// AddAllArgsTranslated - Render all the arguments matching the
/// given ids, but forced to separate args and using the provided
@@ -127,13 +133,13 @@ namespace driver {
///
/// \param Joined - If true, render the argument as joined with
/// the option specifier.
- void AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
+ void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
const char *Translation,
bool Joined = false) const;
/// ClaimAllArgs - Claim all arguments which match the given
/// option id.
- void ClaimAllArgs(options::ID Id0) const;
+ void ClaimAllArgs(OptSpecifier Id0) const;
/// @}
/// @name Arg Synthesis
diff --git a/include/clang/Driver/CC1Options.h b/include/clang/Driver/CC1Options.h
new file mode 100644
index 000000000000..057022ce38c1
--- /dev/null
+++ b/include/clang/Driver/CC1Options.h
@@ -0,0 +1,34 @@
+//===--- CC1Options.h - Clang CC1 Options Table -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_CC1OPTIONS_H
+#define CLANG_DRIVER_CC1OPTIONS_H
+
+namespace clang {
+namespace driver {
+ class OptTable;
+
+namespace cc1options {
+ enum ID {
+ OPT_INVALID = 0, // This is not an option ID.
+ OPT_INPUT, // Reserved ID for input option.
+ OPT_UNKNOWN, // Reserved ID for unknown option.
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR) OPT_##ID,
+#include "clang/Driver/CC1Options.inc"
+ LastOption
+#undef OPTION
+ };
+}
+
+ OptTable *createCC1OptTable();
+}
+}
+
+#endif
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
new file mode 100644
index 000000000000..ef8d8478282d
--- /dev/null
+++ b/include/clang/Driver/CC1Options.td
@@ -0,0 +1,26 @@
+//===--- CC1Options.td - Options for clang -cc1 ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the options accepted by clang -cc1.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the common option parsing interfaces.
+include "OptParser.td"
+
+// Target Options
+
+def target_abi : Separate<"-target-abi">,
+ HelpText<"Target a particular ABI type">;
+def target_cpu : Separate<"-mcpu">,
+ HelpText<"Target a specific cpu type (-mcpu=help for details)">;
+def target_features : Separate<"-target-feature">,
+ HelpText<"Target specific attributes">;
+def target_triple : Separate<"-triple">,
+ HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
diff --git a/include/clang/Driver/CMakeLists.txt b/include/clang/Driver/CMakeLists.txt
new file mode 100644
index 000000000000..f720d15d8ccc
--- /dev/null
+++ b/include/clang/Driver/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_TARGET_DEFINITIONS Options.td)
+tablegen(Options.inc
+ -gen-opt-parser-defs)
+add_custom_target(ClangDriverOptions
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Options.inc)
+
+set(LLVM_TARGET_DEFINITIONS CC1Options.td)
+tablegen(CC1Options.inc
+ -gen-opt-parser-defs)
+add_custom_target(ClangCC1Options
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CC1Options.inc)
diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile
new file mode 100644
index 000000000000..c0f2cc7b6777
--- /dev/null
+++ b/include/clang/Driver/Makefile
@@ -0,0 +1,16 @@
+LEVEL = ../../../../..
+BUILT_SOURCES = Options.inc CC1Options.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(LEVEL)/Makefile.common
+
+$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(ObjDir)/.dir
+ $(Echo) "Building Clang Driver Option tables with tblgen"
+ $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
+
+$(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(ObjDir)/.dir
+ $(Echo) "Building Clang CC1 Option tables with tblgen"
+ $(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
+
+
diff --git a/include/clang/Driver/OptParser.td b/include/clang/Driver/OptParser.td
new file mode 100644
index 000000000000..70b59c69c264
--- /dev/null
+++ b/include/clang/Driver/OptParser.td
@@ -0,0 +1,116 @@
+//===--- OptParser.td - Common Option Parsing Interfaces ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the common interfaces used by the option parsing TableGen
+// backend.
+//
+//===----------------------------------------------------------------------===//
+
+// Define the kinds of options.
+
+class OptionKind<string name, int predecence = 0> {
+ string Name = name;
+ // The kind precedence, kinds with lower precedence are matched first.
+ int Precedence = predecence;
+}
+
+// An option group.
+def KIND_GROUP : OptionKind<"Group">;
+// A flag with no values.
+def KIND_FLAG : OptionKind<"Flag">;
+// An option which prefixes its (single) value.
+def KIND_JOINED : OptionKind<"Joined", 1>;
+// An option which is followed by its value.
+def KIND_SEPARATE : OptionKind<"Separate">;
+// An option followed by its values, which are separated by commas.
+def KIND_COMMAJOINED : OptionKind<"CommaJoined">;
+// An option which is which takes multiple (separate) arguments.
+def KIND_MULTIARG : OptionKind<"MultiArg">;
+// An option which is either joined to its (non-empty) value, or followed by its
+// value.
+def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
+// An option which is both joined to its (first) value, and followed by its
+// (second) value.
+def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
+
+// Define the option flags.
+
+class OptionFlag {}
+
+// DriverOption - The option is a "driver" option, and should not be forwarded
+// to gcc.
+def DriverOption : OptionFlag;
+
+// LinkerInput - The option is a linker input.
+def LinkerInput : OptionFlag;
+
+// NoArgumentUnused - Don't report argument unused warnings for this option; this
+// is useful for options like -static or -dynamic which a user may always end up
+// passing, even if the platform defaults to (or only supports) that option.
+def NoArgumentUnused : OptionFlag;
+
+// RenderAsInput - The option should not render the name when rendered as an
+// input (i.e., the option is rendered as values).
+def RenderAsInput : OptionFlag;
+
+// RenderJoined - The option should be rendered joined, even if separate (only
+// sensible on single value separate options).
+def RenderJoined : OptionFlag;
+
+// RenderSeparate - The option should be rendered separately, even if joined
+// (only sensible on joined options).
+def RenderSeparate : OptionFlag;
+
+// Unsupported - The option is unsupported, and the driver will reject command
+// lines that use it.
+def Unsupported : OptionFlag;
+
+// Define the option group class.
+
+class OptionGroup<string name> {
+ string EnumName = ?; // Uses the def name if undefined.
+ string Name = name;
+ OptionGroup Group = ?;
+}
+
+// Define the option class.
+
+class Option<string name, OptionKind kind> {
+ string EnumName = ?; // Uses the def name if undefined.
+ string Name = name;
+ OptionKind Kind = kind;
+ // Used by MultiArg option kind.
+ int NumArgs = 0;
+ string HelpText = ?;
+ string MetaVarName = ?;
+ list<OptionFlag> Flags = [];
+ OptionGroup Group = ?;
+ Option Alias = ?;
+}
+
+// Helpers for defining options.
+
+class Flag<string name> : Option<name, KIND_FLAG>;
+class Joined<string name> : Option<name, KIND_JOINED>;
+class Separate<string name> : Option<name, KIND_SEPARATE>;
+class CommaJoined<string name> : Option<name, KIND_COMMAJOINED>;
+class MultiArg<string name, int numargs> : Option<name, KIND_MULTIARG> {
+ int NumArgs = numargs;
+}
+class JoinedOrSeparate<string name> : Option<name, KIND_JOINED_OR_SEPARATE>;
+class JoinedAndSeparate<string name> : Option<name, KIND_JOINED_AND_SEPARATE>;
+
+// Mix-ins for adding optional attributes.
+
+class Alias<Option alias> { Option Alias = alias; }
+class EnumName<string name> { string EnumName = name; }
+class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
+class Group<OptionGroup group> { OptionGroup Group = group; }
+class HelpText<string text> { string HelpText = text; }
+class MetaVarName<string name> { string MetaVarName = name; }
diff --git a/include/clang/Driver/OptSpecifier.h b/include/clang/Driver/OptSpecifier.h
new file mode 100644
index 000000000000..c38b36c2f70f
--- /dev/null
+++ b/include/clang/Driver/OptSpecifier.h
@@ -0,0 +1,36 @@
+//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTSPECIFIER_H
+#define CLANG_DRIVER_OPTSPECIFIER_H
+
+namespace clang {
+namespace driver {
+ class Option;
+
+ /// OptSpecifier - Wrapper class for abstracting references to option IDs.
+ class OptSpecifier {
+ unsigned ID;
+
+ private:
+ explicit OptSpecifier(bool); // DO NOT IMPLEMENT
+
+ public:
+ /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
+ /*implicit*/ OptSpecifier(const Option *Opt);
+
+ unsigned getID() const { return ID; }
+
+ bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
+ bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
+ };
+}
+}
+
+#endif
diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h
new file mode 100644
index 000000000000..faaeba69e2e6
--- /dev/null
+++ b/include/clang/Driver/OptTable.h
@@ -0,0 +1,163 @@
+//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_OPTTABLE_H
+#define CLANG_DRIVER_OPTTABLE_H
+
+#include "clang/Driver/OptSpecifier.h"
+#include <cassert>
+
+namespace clang {
+namespace driver {
+namespace options {
+ enum DriverFlag {
+ DriverOption = (1 << 0),
+ LinkerInput = (1 << 1),
+ NoArgumentUnused = (1 << 2),
+ RenderAsInput = (1 << 3),
+ RenderJoined = (1 << 4),
+ RenderSeparate = (1 << 5),
+ Unsupported = (1 << 6)
+ };
+}
+
+ class Arg;
+ class InputArgList;
+ class Option;
+
+ /// OptTable - Provide access to the Option info table.
+ ///
+ /// The OptTable class provides a layer of indirection which allows Option
+ /// instance to be created lazily. In the common case, only a few options will
+ /// be needed at runtime; the OptTable class maintains enough information to
+ /// parse command lines without instantiating Options, while letting other
+ /// parts of the driver still use Option instances where convenient.
+ class OptTable {
+ public:
+ /// Info - Entry for a single option instance in the option data table.
+ struct Info {
+ const char *Name;
+ const char *HelpText;
+ const char *MetaVar;
+ unsigned char Kind;
+ unsigned char Flags;
+ unsigned char Param;
+ unsigned short GroupID;
+ unsigned short AliasID;
+ };
+
+ private:
+ /// The static option information table.
+ const Info *OptionInfos;
+ unsigned NumOptionInfos;
+
+ /// The lazily constructed options table, indexed by option::ID - 1.
+ mutable Option **Options;
+
+ /// Prebound input option instance.
+ const Option *TheInputOption;
+
+ /// Prebound unknown option instance.
+ const Option *TheUnknownOption;
+
+ /// The index of the first option which can be parsed (i.e., is not a
+ /// special option like 'input' or 'unknown', and is not an option group).
+ unsigned FirstSearchableIndex;
+
+ private:
+ const Info &getInfo(OptSpecifier Opt) const {
+ unsigned id = Opt.getID();
+ assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID.");
+ return OptionInfos[id - 1];
+ }
+
+ Option *CreateOption(unsigned id) const;
+
+ protected:
+ OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos);
+ public:
+ ~OptTable();
+
+ /// getNumOptions - Return the total number of option classes.
+ unsigned getNumOptions() const { return NumOptionInfos; }
+
+ /// getOption - Get the given \arg id's Option instance, lazily creating it
+ /// if necessary.
+ ///
+ /// \return The option, or null for the INVALID option id.
+ const Option *getOption(OptSpecifier Opt) const {
+ unsigned id = Opt.getID();
+ if (id == 0)
+ return 0;
+
+ assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
+ Option *&Entry = Options[id - 1];
+ if (!Entry)
+ Entry = CreateOption(id);
+ return Entry;
+ }
+
+ /// getOptionName - Lookup the name of the given option.
+ const char *getOptionName(OptSpecifier id) const {
+ return getInfo(id).Name;
+ }
+
+ /// getOptionKind - Get the kind of the given option.
+ unsigned getOptionKind(OptSpecifier id) const {
+ return getInfo(id).Kind;
+ }
+
+ /// getOptionHelpText - Get the help text to use to describe this option.
+ const char *getOptionHelpText(OptSpecifier id) const {
+ return getInfo(id).HelpText;
+ }
+
+ /// getOptionMetaVar - Get the meta-variable name to use when describing
+ /// this options values in the help text.
+ const char *getOptionMetaVar(OptSpecifier id) const {
+ return getInfo(id).MetaVar;
+ }
+
+ /// ParseOneArg - Parse a single argument; returning the new argument and
+ /// updating Index.
+ ///
+ /// \param [in] [out] Index - The current parsing position in the argument
+ /// string list; on return this will be the index of the next argument
+ /// string to parse.
+ ///
+ /// \return - The parsed argument, or 0 if the argument is missing values
+ /// (in which case Index still points at the conceptual next argument string
+ /// to parse).
+ Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const;
+
+ /// ParseArgs - Parse an list of arguments into an InputArgList.
+ ///
+ /// The resulting InputArgList will reference the strings in [ArgBegin,
+ /// ArgEnd), and their lifetime should extend past that of the returned
+ /// InputArgList.
+ ///
+ /// The only error that can occur in this routine is if an argument is
+ /// missing values; in this case \arg MissingArgCount will be non-zero.
+ ///
+ /// \param ArgBegin - The beginning of the argument vector.
+ /// \param ArgEnd - The end of the argument vector.
+ /// \param MissingArgIndex - On error, the index of the option which could
+ /// not be parsed.
+ /// \param MissingArgCount - On error, the number of missing options.
+ /// \return - An InputArgList; on error this will contain all the options
+ /// which could be parsed.
+ InputArgList *ParseArgs(const char **ArgBegin,
+ const char **ArgEnd,
+ unsigned &MissingArgIndex,
+ unsigned &MissingArgCount) const;
+ };
+}
+}
+
+#endif
diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h
index c70b6482167b..08b94b1d797d 100644
--- a/include/clang/Driver/Option.h
+++ b/include/clang/Driver/Option.h
@@ -10,8 +10,7 @@
#ifndef CLANG_DRIVER_OPTION_H_
#define CLANG_DRIVER_OPTION_H_
-#include "Options.h"
-
+#include "clang/Driver/OptSpecifier.h"
#include "llvm/Support/Casting.h"
using llvm::isa;
using llvm::cast;
@@ -54,7 +53,8 @@ namespace driver {
private:
OptionClass Kind;
- options::ID ID;
+ /// The option ID.
+ OptSpecifier ID;
/// The option name.
const char *Name;
@@ -89,12 +89,12 @@ namespace driver {
bool NoArgumentUnused : 1;
protected:
- Option(OptionClass Kind, options::ID ID, const char *Name,
+ Option(OptionClass Kind, OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias);
public:
virtual ~Option();
- options::ID getId() const { return ID; }
+ unsigned getID() const { return ID.getID(); }
OptionClass getKind() const { return Kind; }
const char *getName() const { return Name; }
const OptionGroup *getGroup() const { return Group; }
@@ -138,8 +138,11 @@ namespace driver {
/// matches - Predicate for whether this option is part of the
/// given option (which may be a group).
- bool matches(const Option *Opt) const;
- bool matches(options::ID Id) const;
+ ///
+ /// Note that matches against options which are an alias should never be
+ /// done -- aliases do not participate in matching and so such a query will
+ /// always be false.
+ bool matches(OptSpecifier ID) const;
/// accept - Potentially accept the current argument, returning a
/// new Arg instance, or 0 if the option does not accept this
@@ -159,7 +162,7 @@ namespace driver {
/// by the driver.
class OptionGroup : public Option {
public:
- OptionGroup(options::ID ID, const char *Name, const OptionGroup *Group);
+ OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
@@ -174,7 +177,7 @@ namespace driver {
/// InputOption - Dummy option class for representing driver inputs.
class InputOption : public Option {
public:
- InputOption();
+ InputOption(OptSpecifier ID);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
@@ -187,7 +190,7 @@ namespace driver {
/// UnknownOption - Dummy option class for represent unknown arguments.
class UnknownOption : public Option {
public:
- UnknownOption();
+ UnknownOption(OptSpecifier ID);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
@@ -201,7 +204,7 @@ namespace driver {
class FlagOption : public Option {
public:
- FlagOption(options::ID ID, const char *Name, const OptionGroup *Group,
+ FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
const Option *Alias);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
@@ -214,7 +217,7 @@ namespace driver {
class JoinedOption : public Option {
public:
- JoinedOption(options::ID ID, const char *Name, const OptionGroup *Group,
+ JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
const Option *Alias);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
@@ -227,8 +230,8 @@ namespace driver {
class SeparateOption : public Option {
public:
- SeparateOption(options::ID ID, const char *Name, const OptionGroup *Group,
- const Option *Alias);
+ SeparateOption(OptSpecifier ID, const char *Name,
+ const OptionGroup *Group, const Option *Alias);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
@@ -240,7 +243,7 @@ namespace driver {
class CommaJoinedOption : public Option {
public:
- CommaJoinedOption(options::ID ID, const char *Name,
+ CommaJoinedOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
@@ -259,7 +262,7 @@ namespace driver {
unsigned NumArgs;
public:
- MultiArgOption(options::ID ID, const char *Name, const OptionGroup *Group,
+ MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
const Option *Alias, unsigned NumArgs);
unsigned getNumArgs() const { return NumArgs; }
@@ -276,7 +279,7 @@ namespace driver {
/// prefixes its (non-empty) value, or is follwed by a value.
class JoinedOrSeparateOption : public Option {
public:
- JoinedOrSeparateOption(options::ID ID, const char *Name,
+ JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
@@ -291,7 +294,7 @@ namespace driver {
/// value and is followed by another value.
class JoinedAndSeparateOption : public Option {
public:
- JoinedAndSeparateOption(options::ID ID, const char *Name,
+ JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias);
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
deleted file mode 100644
index 2b66b3506b01..000000000000
--- a/include/clang/Driver/Options.def
+++ /dev/null
@@ -1,661 +0,0 @@
-//===--- Options.def - Driver option info -----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the driver option information. Users of this file
-// must define the OPTION macro to make use of this information.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef OPTION
-#error "Define OPTION prior to including this file!"
-#endif
-
-// OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM,
-// HELPTEXT, METAVARNAME)
-
-// The NAME value is the option name as a string.
-
-// The ID is the internal option id, which must be a valid
-// C++ identifier, and results in a clang::driver::options::OPT_XX
-// enum constant for XX.
-//
-// We want to unambiguously be able to refer to options from the
-// driver source code, for this reason the option name is mangled into
-// an id. This mangling isn't guaranteed to have an inverse, but for
-// practical purposes it does.
-//
-// The mangling scheme is to ignore the leading '-', and perform the
-// following substitutions:
-// _ => __
-// - => _
-// # => _HASH
-// , => _COMMA
-// = => _EQ
-// C++ => CXX
-
-// The KIND value is the option type, one of Group, Flag, Joined,
-// Separate, CommaJoined, JoinedOrSeparate, JoinedAndSeparate.
-
-// The GROUP value is the internal name of the option group, or
-// INVALID if the option is not part of a group.
-
-// The ALIAS value is the internal name of an aliased option, or
-// INVALID if the option is not an alias.
-
-// The PARAM value is a string containing option flags. Valid values:
-// d: The option is a "driver" option, and should not be forwarded to
-// gcc.
-//
-// i: The option should not render the name when rendered as an
-// input (i.e., the option is rendered as values).
-//
-// l: The option is a linker input.
-//
-// q: Don't report argument unused warnings for this option; this is
-// useful for options like -static or -dynamic which a user may
-// always end up passing, even if the platform defaults to (or
-// only supports) that option.
-//
-// u: The option is unsupported, and the driver will reject command
-// lines that use it.
-//
-// S: The option should be rendered separately, even if joined (only
-// sensible on joined options).
-//
-// J: The option should be rendered joined, even if separate (only
-// sensible on single value separate options).
-
-// The PARAM value is an arbitrary integer parameter; currently
-// this is only used for specifying the number of arguments for
-// Separate options.
-
-// The HELPTEXT value is the string to print for this option in
-// --help, or 0 if undocumented.
-
-// The METAVAR value is the name to use for this values arguments (if
-// any) in the help text. This must be defined if the help text is
-// specified and this option takes extra arguments.
-
-//
-
-// For now (pre-TableGen, that is) Options must be in order. The
-// ordering is *almost* lexicographic, with two exceptions. First,
-// '\0' comes at the end of the alphabet instead of the beginning
-// (thus options preceed any other options which prefix them). Second,
-// for options with the same name, the less permissive version should
-// come first; a Flag option should preceed a Joined option, for
-// example.
-
-/////////
-// Groups
-
-OPTION("<I group>", I_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<M group>", M_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<T group>", T_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<O group>", O_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<W group>", W_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<X group>", X_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<a group>", a_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<d group>", d_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<f group>", f_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<g group>", g_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<i group>", i_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<clang i group>", clang_i_Group, Group, i_Group, INVALID, "", 0, 0, 0)
-OPTION("<m group>", m_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<m x86 features group>", m_x86_Features_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-OPTION("<u group>", u_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-
-OPTION("<pedantic group>", pedantic_Group, Group, INVALID, INVALID, "", 0, 0, 0)
-
-// Temporary groups for clang options which we know we don't support,
-// but don't want to verbosely warn the user about.
-OPTION("<clang ignored f group>", clang_ignored_f_Group, Group, f_Group,
- INVALID, "", 0, 0, 0)
-OPTION("<clang ignored m group>", clang_ignored_m_Group, Group, m_Group,
- INVALID, "", 0, 0, 0)
-
-//////////
-// Options
-
-OPTION("-###", _HASH_HASH_HASH, Flag, INVALID, INVALID, "d", 0,
- "Print the commands to run for this compilation", 0)
-OPTION("--CLASSPATH=", _CLASSPATH_EQ, Joined, INVALID, fclasspath_EQ, "", 0, 0, 0)
-OPTION("--CLASSPATH", _CLASSPATH, Separate, INVALID, fclasspath_EQ, "J", 0, 0, 0)
-OPTION("--all-warnings", _all_warnings, Flag, INVALID, Wall, "", 0, 0, 0)
-OPTION("--analyze-auto", _analyze_auto, Flag, INVALID, INVALID, "d", 0, 0, 0)
-OPTION("--analyzer-no-default-checks", _analyzer_no_default_checks, Flag, INVALID, INVALID, "d", 0, 0, 0)
-OPTION("--analyzer-output", _analyzer_output, JoinedOrSeparate, INVALID, INVALID, "d", 0, 0, 0)
-OPTION("--analyze", _analyze, Flag, INVALID, INVALID, "d", 0,
- "Run the static analyzer", 0)
-OPTION("--ansi", _ansi, Flag, INVALID, ansi, "", 0, 0, 0)
-OPTION("--assemble", _assemble, Flag, INVALID, S, "", 0, 0, 0)
-OPTION("--assert=", _assert_EQ, Joined, INVALID, A, "S", 0, 0, 0)
-OPTION("--assert", _assert, Separate, INVALID, A, "", 0, 0, 0)
-OPTION("--bootclasspath=", _bootclasspath_EQ, Joined, INVALID, fbootclasspath_EQ, "", 0, 0, 0)
-OPTION("--bootclasspath", _bootclasspath, Separate, INVALID, fbootclasspath_EQ, "J", 0, 0, 0)
-OPTION("--classpath=", _classpath_EQ, Joined, INVALID, fclasspath_EQ, "", 0, 0, 0)
-OPTION("--classpath", _classpath, Separate, INVALID, fclasspath_EQ, "J", 0, 0, 0)
-OPTION("--combine", _combine, Flag, INVALID, combine, "u", 0, 0, 0)
-OPTION("--comments-in-macros", _comments_in_macros, Flag, INVALID, CC, "", 0, 0, 0)
-OPTION("--comments", _comments, Flag, INVALID, C, "", 0, 0, 0)
-OPTION("--compile", _compile, Flag, INVALID, c, "", 0, 0, 0)
-OPTION("--constant-cfstrings", _constant_cfstrings, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("--coverage", _coverage, Flag, INVALID, coverage, "", 0, 0, 0)
-OPTION("--debug=", _debug_EQ, Joined, INVALID, g_Flag, "u", 0, 0, 0)
-OPTION("--debug", _debug, Flag, INVALID, g_Flag, "u", 0, 0, 0)
-OPTION("--define-macro=", _define_macro_EQ, Joined, INVALID, D, "", 0, 0, 0)
-OPTION("--define-macro", _define_macro, Separate, INVALID, D, "J", 0, 0, 0)
-OPTION("--dependencies", _dependencies, Flag, INVALID, M, "", 0, 0, 0)
-OPTION("--encoding=", _encoding_EQ, Joined, INVALID, fencoding_EQ, "", 0, 0, 0)
-OPTION("--encoding", _encoding, Separate, INVALID, fencoding_EQ, "J", 0, 0, 0)
-OPTION("--entry", _entry, Flag, INVALID, e, "", 0, 0, 0)
-OPTION("--extdirs=", _extdirs_EQ, Joined, INVALID, fextdirs_EQ, "", 0, 0, 0)
-OPTION("--extdirs", _extdirs, Separate, INVALID, fextdirs_EQ, "J", 0, 0, 0)
-OPTION("--extra-warnings", _extra_warnings, Flag, INVALID, W_Joined, "", 0, 0, 0)
-OPTION("--for-linker=", _for_linker_EQ, Joined, INVALID, Xlinker, "liS", 0, 0, 0)
-OPTION("--for-linker", _for_linker, Separate, INVALID, Xlinker, "li", 0, 0, 0)
-OPTION("--force-link=", _force_link_EQ, Joined, INVALID, u, "S", 0, 0, 0)
-OPTION("--force-link", _force_link, Separate, INVALID, u, "", 0, 0, 0)
-OPTION("--help-hidden", _help_hidden, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("--help", _help, Flag, INVALID, INVALID, "", 0,
- "Display available options", 0)
-OPTION("--imacros=", _imacros_EQ, Joined, INVALID, imacros, "S", 0, 0, 0)
-OPTION("--imacros", _imacros, Separate, INVALID, imacros, "", 0, 0, 0)
-OPTION("--include-barrier", _include_barrier, Flag, INVALID, I_, "", 0, 0, 0)
-OPTION("--include-directory-after=", _include_directory_after_EQ, Joined, INVALID, idirafter, "S", 0, 0, 0)
-OPTION("--include-directory-after", _include_directory_after, Separate, INVALID, idirafter, "", 0, 0, 0)
-OPTION("--include-directory=", _include_directory_EQ, Joined, INVALID, I, "", 0, 0, 0)
-OPTION("--include-directory", _include_directory, Separate, INVALID, I, "J", 0, 0, 0)
-OPTION("--include-prefix=", _include_prefix_EQ, Joined, INVALID, iprefix, "S", 0, 0, 0)
-OPTION("--include-prefix", _include_prefix, Separate, INVALID, iprefix, "", 0, 0, 0)
-OPTION("--include-with-prefix-after=", _include_with_prefix_after_EQ, Joined, INVALID, iwithprefix, "S", 0, 0, 0)
-OPTION("--include-with-prefix-after", _include_with_prefix_after, Separate, INVALID, iwithprefix, "", 0, 0, 0)
-OPTION("--include-with-prefix-before=", _include_with_prefix_before_EQ, Joined, INVALID, iwithprefixbefore, "S", 0, 0, 0)
-OPTION("--include-with-prefix-before", _include_with_prefix_before, Separate, INVALID, iwithprefixbefore, "", 0, 0, 0)
-OPTION("--include-with-prefix=", _include_with_prefix_EQ, Joined, INVALID, iwithprefix, "S", 0, 0, 0)
-OPTION("--include-with-prefix", _include_with_prefix, Separate, INVALID, iwithprefix, "", 0, 0, 0)
-OPTION("--include=", _include_EQ, Joined, INVALID, include, "S", 0, 0, 0)
-OPTION("--include", _include, Separate, INVALID, include, "", 0, 0, 0)
-OPTION("--language=", _language_EQ, Joined, INVALID, x, "S", 0, 0, 0)
-OPTION("--language", _language, Separate, INVALID, x, "", 0, 0, 0)
-OPTION("--library-directory=", _library_directory_EQ, Joined, INVALID, L, "S", 0, 0, 0)
-OPTION("--library-directory", _library_directory, Separate, INVALID, L, "", 0, 0, 0)
-OPTION("--machine-=", _machine__EQ, Joined, INVALID, m_Joined, "u", 0, 0, 0)
-OPTION("--machine-", _machine_, Joined, INVALID, m_Joined, "u", 0, 0, 0)
-OPTION("--machine=", _machine_EQ, Joined, INVALID, m_Joined, "", 0, 0, 0)
-OPTION("--machine", _machine, Separate, INVALID, m_Joined, "J", 0, 0, 0)
-OPTION("--no-integrated-cpp", _no_integrated_cpp, Flag, INVALID, no_integrated_cpp, "", 0, 0, 0)
-OPTION("--no-line-commands", _no_line_commands, Flag, INVALID, P, "", 0, 0, 0)
-OPTION("--no-standard-includes", _no_standard_includes, Flag, INVALID, nostdinc, "", 0, 0, 0)
-OPTION("--no-standard-libraries", _no_standard_libraries, Flag, INVALID, nostdlib, "", 0, 0, 0)
-OPTION("--no-undefined", _no_undefined, Flag, INVALID, INVALID, "l", 0, 0, 0)
-OPTION("--no-warnings", _no_warnings, Flag, INVALID, w, "", 0, 0, 0)
-OPTION("--optimize=", _optimize_EQ, Joined, INVALID, O, "u", 0, 0, 0)
-OPTION("--optimize", _optimize, Flag, INVALID, O, "u", 0, 0, 0)
-OPTION("--output-class-directory=", _output_class_directory_EQ, Joined, INVALID, foutput_class_dir_EQ, "", 0, 0, 0)
-OPTION("--output-class-directory", _output_class_directory, Separate, INVALID, foutput_class_dir_EQ, "J", 0, 0, 0)
-OPTION("--output=", _output_EQ, Joined, INVALID, o, "S", 0, 0, 0)
-OPTION("--output", _output, Separate, INVALID, o, "", 0, 0, 0)
-OPTION("--param=", _param_EQ, Joined, INVALID, _param, "S", 0, 0, 0)
-OPTION("--param", _param, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("--pass-exit-codes", _pass_exit_codes, Flag, INVALID, pass_exit_codes, "", 0, 0, 0)
-OPTION("--pedantic-errors", _pedantic_errors, Flag, INVALID, pedantic_errors, "", 0, 0, 0)
-OPTION("--pedantic", _pedantic, Flag, INVALID, pedantic, "", 0, 0, 0)
-OPTION("--pipe", _pipe, Flag, INVALID, pipe, "d", 0, 0, 0)
-OPTION("--prefix=", _prefix_EQ, Joined, INVALID, B, "S", 0, 0, 0)
-OPTION("--prefix", _prefix, Separate, INVALID, B, "", 0, 0, 0)
-OPTION("--preprocess", _preprocess, Flag, INVALID, E, "", 0, 0, 0)
-OPTION("--print-file-name=", _print_file_name_EQ, Joined, INVALID, print_file_name_EQ, "", 0, 0, 0)
-OPTION("--print-file-name", _print_file_name, Separate, INVALID, print_file_name_EQ, "", 0, 0, 0)
-OPTION("--print-libgcc-file-name", _print_libgcc_file_name, Flag, INVALID, print_libgcc_file_name, "", 0, 0, 0)
-OPTION("--print-missing-file-dependencies", _print_missing_file_dependencies, Flag, INVALID, MG, "", 0, 0, 0)
-OPTION("--print-multi-directory", _print_multi_directory, Flag, INVALID, print_multi_directory, "", 0, 0, 0)
-OPTION("--print-multi-lib", _print_multi_lib, Flag, INVALID, print_multi_lib, "", 0, 0, 0)
-OPTION("--print-multi-os-directory", _print_multi_os_directory, Flag, INVALID, print_multi_os_directory, "", 0, 0, 0)
-OPTION("--print-prog-name=", _print_prog_name_EQ, Joined, INVALID, print_prog_name_EQ, "", 0, 0, 0)
-OPTION("--print-prog-name", _print_prog_name, Separate, INVALID, print_prog_name_EQ, "", 0, 0, 0)
-OPTION("--print-search-dirs", _print_search_dirs, Flag, INVALID, print_search_dirs, "", 0, 0, 0)
-OPTION("--profile-blocks", _profile_blocks, Flag, INVALID, a, "", 0, 0, 0)
-OPTION("--profile", _profile, Flag, INVALID, p, "", 0, 0, 0)
-OPTION("--relocatable-pch", _relocatable_pch, Flag, INVALID, INVALID, "", 0,
- "Build a relocatable precompiled header", 0)
-OPTION("--resource=", _resource_EQ, Joined, INVALID, fcompile_resource_EQ, "", 0, 0, 0)
-OPTION("--resource", _resource, Separate, INVALID, fcompile_resource_EQ, "J", 0, 0, 0)
-OPTION("--save-temps", _save_temps, Flag, INVALID, save_temps, "", 0, 0, 0)
-OPTION("--shared", _shared, Flag, INVALID, shared, "", 0, 0, 0)
-OPTION("--signed-char", _signed_char, Flag, INVALID, fsigned_char, "", 0, 0, 0)
-OPTION("--specs=", _specs_EQ, Joined, INVALID, specs_EQ, "u", 0, 0, 0)
-OPTION("--specs", _specs, Separate, INVALID, specs_EQ, "uJ", 0, 0, 0)
-OPTION("--static", _static, Flag, INVALID, static, "", 0, 0, 0)
-OPTION("--std=", _std_EQ, Joined, INVALID, std_EQ, "", 0, 0, 0)
-OPTION("--std", _std, Separate, INVALID, std_EQ, "J", 0, 0, 0)
-OPTION("--sysroot=", _sysroot_EQ, Joined, INVALID, INVALID, "", 0, 0, 0)
-OPTION("--sysroot", _sysroot, Separate, INVALID, _sysroot_EQ, "J", 0, 0, 0)
-OPTION("--target-help", _target_help, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("--trace-includes", _trace_includes, Flag, INVALID, H, "", 0, 0, 0)
-OPTION("--traditional-cpp", _traditional_cpp, Flag, INVALID, traditional_cpp, "", 0, 0, 0)
-OPTION("--traditional", _traditional, Flag, INVALID, traditional, "", 0, 0, 0)
-OPTION("--trigraphs", _trigraphs, Flag, INVALID, trigraphs, "", 0, 0, 0)
-OPTION("--undefine-macro=", _undefine_macro_EQ, Joined, INVALID, U, "", 0, 0, 0)
-OPTION("--undefine-macro", _undefine_macro, Separate, INVALID, U, "J", 0, 0, 0)
-OPTION("--unsigned-char", _unsigned_char, Flag, INVALID, funsigned_char, "", 0, 0, 0)
-OPTION("--user-dependencies", _user_dependencies, Flag, INVALID, MM, "", 0, 0, 0)
-OPTION("--verbose", _verbose, Flag, INVALID, v, "", 0, 0, 0)
-OPTION("--version", _version, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("--warn-=", _warn__EQ, Joined, INVALID, W_Joined, "u", 0, 0, 0)
-OPTION("--warn-", _warn_, Joined, INVALID, W_Joined, "u", 0, 0, 0)
-OPTION("--write-dependencies", _write_dependencies, Flag, INVALID, MD, "", 0, 0, 0)
-OPTION("--write-user-dependencies", _write_user_dependencies, Flag, INVALID, MMD, "", 0, 0, 0)
-OPTION("--", _, Joined, INVALID, f, "u", 0, 0, 0)
-OPTION("-A", A, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-B", B, JoinedOrSeparate, INVALID, INVALID, "u", 0, 0, 0)
-OPTION("-CC", CC, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-C", C, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-D", D, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-E", E, Flag, INVALID, INVALID, "d", 0,
- "Only run the preprocessor", 0)
-OPTION("-F", F, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-H", H, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-I-", I_, Flag, I_Group, INVALID, "", 0, 0, 0)
-OPTION("-I", I, JoinedOrSeparate, I_Group, INVALID, "", 0, 0, 0)
-OPTION("-L", L, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-MD", MD, Flag, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-MF", MF, JoinedOrSeparate, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-MG", MG, Flag, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-MMD", MMD, Flag, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-MM", MM, Flag, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-MP", MP, Flag, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-MQ", MQ, JoinedOrSeparate, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-MT", MT, JoinedOrSeparate, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-Mach", Mach, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-M", M, Flag, M_Group, INVALID, "", 0, 0, 0)
-OPTION("-O4", O4, Joined, O_Group, INVALID, "", 0, 0, 0)
-OPTION("-ObjC++", ObjCXX, Flag, INVALID, INVALID, "d", 0,
- "Treat source input files as Objective-C++ inputs", 0)
-OPTION("-ObjC", ObjC, Flag, INVALID, INVALID, "d", 0,
- "Treat source input files as Objective-C inputs", 0)
-OPTION("-O", O, Joined, O_Group, INVALID, "", 0, 0, 0)
-OPTION("-P", P, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-Qn", Qn, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-Qunused-arguments", Qunused_arguments, Flag, INVALID, INVALID, "d", 0,
- "Don't emit warning for unused driver arguments", 0)
-OPTION("-Q", Q, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-R", R, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-S", S, Flag, INVALID, INVALID, "d", 0,
- "Only run preprocess and compilation steps", 0)
-OPTION("-Tbss", Tbss, JoinedOrSeparate, T_Group, INVALID, "", 0, 0, 0)
-OPTION("-Tdata", Tdata, JoinedOrSeparate, T_Group, INVALID, "", 0, 0, 0)
-OPTION("-Ttext", Ttext, JoinedOrSeparate, T_Group, INVALID, "", 0, 0, 0)
-OPTION("-T", T, JoinedOrSeparate, T_Group, INVALID, "", 0, 0, 0)
-OPTION("-U", U, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-V", V, JoinedOrSeparate, INVALID, INVALID, "du", 0, 0, 0)
-OPTION("-Wa,", Wa_COMMA, CommaJoined, INVALID, INVALID, "", 0,
- "Pass the comma separated arguments in <arg> to the assembler", "<arg>")
-OPTION("-Wall", Wall, Flag, W_Group, INVALID, "", 0, 0, 0)
-OPTION("-Wextra", Wextra, Flag, W_Group, INVALID, "", 0, 0, 0)
-OPTION("-Wl,", Wl_COMMA, CommaJoined, INVALID, INVALID, "li", 0,
- "Pass the comma separated arguments in <arg> to the linker", "<arg>")
-OPTION("-Wno-nonportable-cfstrings", Wno_nonportable_cfstrings, Joined, W_Group, INVALID, "", 0, 0, 0)
-OPTION("-Wnonportable-cfstrings", Wnonportable_cfstrings, Joined, W_Group, INVALID, "", 0, 0, 0)
-OPTION("-Wp,", Wp_COMMA, CommaJoined, INVALID, INVALID, "", 0,
- "Pass the comma separated arguments in <arg> to the preprocessor", "<arg>")
-OPTION("-W", W_Joined, Joined, W_Group, INVALID, "", 0, 0, 0)
-OPTION("-Xanalyzer", Xanalyzer, Separate, INVALID, INVALID, "", 0,
- "Pass <arg> to the static analyzer", "<arg>")
-OPTION("-Xarch_", Xarch__, JoinedAndSeparate, INVALID, INVALID, "d", 0, 0, 0)
-OPTION("-Xassembler", Xassembler, Separate, INVALID, INVALID, "", 0,
- "Pass <arg> to the assembler", "<arg>")
-OPTION("-Xclang", Xclang, Separate, INVALID, INVALID, "", 0,
- "Pass <arg> to the clang compiler", "<arg>")
-OPTION("-Xlinker", Xlinker, Separate, INVALID, INVALID, "li", 0,
- "Pass <arg> to the linker", "<arg>")
-OPTION("-Xpreprocessor", Xpreprocessor, Separate, INVALID, INVALID, "", 0,
- "Pass <arg> to the preprocessor", "<arg>")
-OPTION("-X", X_Flag, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-X", X_Joined, Joined, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-Z", Z_Flag, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-Z", Z_Joined, Joined, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-all_load", all__load, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-allowable_client", allowable__client, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-ansi", ansi, Flag, a_Group, INVALID, "", 0, 0, 0)
-OPTION("-arch_errors_fatal", arch__errors__fatal, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-arch", arch, Separate, INVALID, INVALID, "d", 0, 0, 0)
-OPTION("-a", a, Joined, a_Group, INVALID, "", 0, 0, 0)
-OPTION("-bind_at_load", bind__at__load, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-bundle_loader", bundle__loader, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-bundle", bundle, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-b", b, JoinedOrSeparate, INVALID, INVALID, "u", 0, 0, 0)
-OPTION("-client_name", client__name, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-combine", combine, Flag, INVALID, INVALID, "du", 0, 0, 0)
-OPTION("-compatibility_version", compatibility__version, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-coverage", coverage, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-cpp-precomp", cpp_precomp, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-current_version", current__version, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-c", c, Flag, INVALID, INVALID, "d", 0,
- "Only run preprocess, compile, and assemble steps", 0)
-OPTION("-dA", dA, Flag, d_Group, INVALID, "", 0, 0, 0)
-OPTION("-dD", dD, Flag, d_Group, INVALID, "", 0, 0, 0)
-OPTION("-dM", dM, Flag, d_Group, INVALID, "", 0, 0, 0)
-OPTION("-dead_strip", dead__strip, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-dependency-file", dependency_file, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-dumpmachine", dumpmachine, Flag, INVALID, INVALID, "u", 0, 0, 0)
-OPTION("-dumpspecs", dumpspecs, Flag, INVALID, INVALID, "u", 0, 0, 0)
-OPTION("-dumpversion", dumpversion, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-dylib_file", dylib__file, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-dylinker_install_name", dylinker__install__name, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-dylinker", dylinker, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-dynamiclib", dynamiclib, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-dynamic", dynamic, Flag, INVALID, INVALID, "q", 0, 0, 0)
-OPTION("-d", d_Flag, Flag, d_Group, INVALID, "", 0, 0, 0)
-OPTION("-d", d_Joined, Joined, d_Group, INVALID, "", 0, 0, 0)
-OPTION("-emit-ast", emit_ast, Flag, INVALID, INVALID, "", 0,
- "Emit Clang AST files for source inputs", 0)
-OPTION("-emit-llvm", emit_llvm, Flag, INVALID, INVALID, "", 0,
- "Use the LLVM representation for assembler and object files", 0)
-OPTION("-exported_symbols_list", exported__symbols__list, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-e", e, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-fPIC", fPIC, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fPIE", fPIE, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fapple-kext", fapple_kext, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fasm-blocks", fasm_blocks, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fastcp", fastcp, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fastf", fastf, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fast", fast, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fasynchronous-unwind-tables", fasynchronous_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fblock-introspection", fblock_introspection, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fblocks", fblocks, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fbootclasspath=", fbootclasspath_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fbuiltin-strcat", fbuiltin_strcat, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fbuiltin-strcpy", fbuiltin_strcpy, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fbuiltin", fbuiltin, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fclasspath=", fclasspath_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fcolor-diagnostics", fcolor_diagnostics, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fcommon", fcommon, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fcompile-resource=", fcompile_resource_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fconstant-cfstrings", fconstant_cfstrings, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fconstant-string-class=", fconstant_string_class_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fcreate-profile", fcreate_profile, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fdebug-pass-arguments", fdebug_pass_arguments, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fdebug-pass-structure", fdebug_pass_structure, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fdiagnostics-fixit-info", fdiagnostics_fixit_info, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fdiagnostics-print-source-range-info", fdiagnostics_print_source_range_info, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fdiagnostics-show-option", fdiagnostics_show_option, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fdollars-in-identifiers", fdollars_in_identifiers, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-feliminate-unused-debug-symbols", feliminate_unused_debug_symbols, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-femit-all-decls", femit_all_decls, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fencoding=", fencoding_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fexceptions", fexceptions, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fextdirs=", fextdirs_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-ffreestanding", ffreestanding, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fgnu-runtime", fgnu_runtime, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fheinous-gnu-extensions", fheinous_gnu_extensions, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-filelist", filelist, Separate, INVALID, INVALID, "l", 0, 0, 0)
-OPTION("-findirect-virtual-calls", findirect_virtual_calls, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-finline-functions", finline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-finline", finline, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fkeep-inline-functions", fkeep_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-flat_namespace", flat__namespace, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-flax-vector-conversions", flax_vector_conversions, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-flimited-precision=", flimited_precision_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-flto", flto, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fmath-errno", fmath_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fmerge-all-constants", fmerge_all_constants, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fmessage-length=", fmessage_length_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fms-extensions", fms_extensions, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fmudflapth", fmudflapth, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fmudflap", fmudflap, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fnested-functions", fnested_functions, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fnext-runtime", fnext_runtime, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-asynchronous-unwind-tables", fno_asynchronous_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-blocks", fno_blocks, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-builtin-strcat", fno_builtin_strcat, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-builtin-strcpy", fno_builtin_strcpy, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-builtin", fno_builtin, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-caret-diagnostics", fno_caret_diagnostics, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-color-diagnostics", fno_color_diagnostics, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-common", fno_common, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-constant-cfstrings", fno_constant_cfstrings, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-diagnostics-fixit-info", fno_diagnostics_fixit_info, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-diagnostics-show-option", fno_diagnostics_show_option, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-dollars-in-identifiers", fno_dollars_in_identifiers, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-eliminate-unused-debug-symbols", fno_eliminate_unused_debug_symbols, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-exceptions", fno_exceptions, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-inline-functions", fno_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-inline", fno_inline, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-keep-inline-functions", fno_keep_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-merge-all-constants", fno_merge_all_constants, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-ms-extensions", fno_ms_extensions, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-omit-frame-pointer", fno_omit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-rtti", fno_rtti, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-show-column", fno_show_column, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-show-source-location", fno_show_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-stack-protector", fno_stack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-strict-aliasing", fno_strict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-unit-at-a-time", fno_unit_at_a_time, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-unwind-tables", fno_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-working-directory", fno_working_directory, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fno-zero-initialized-in-bss", fno_zero_initialized_in_bss, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-atdefs", fobjc_atdefs, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-call-cxx-cdtors", fobjc_call_cxx_cdtors, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-gc-only", fobjc_gc_only, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-gc", fobjc_gc, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-new-property", fobjc_new_property, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-nonfragile-abi", fobjc_nonfragile_abi, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc-sender-dependent-dispatch", fobjc_sender_dependent_dispatch, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fobjc", fobjc, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fomit-frame-pointer", fomit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fopenmp", fopenmp, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-force_cpusubtype_ALL", force__cpusubtype__ALL, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-force_flat_namespace", force__flat__namespace, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-foutput-class-dir=", foutput_class_dir_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fpascal-strings", fpascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fpch-preprocess", fpch_preprocess, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fpic", fpic, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fpie", fpie, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fprofile-arcs", fprofile_arcs, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fprofile-generate", fprofile_generate, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
-OPTION("-frtti", frtti, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fshort-wchar", fshort_wchar, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fsigned-char", fsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fstack-protector-all", fstack_protector_all, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fstack-protector", fstack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fstrict-aliasing", fstrict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fsyntax-only", fsyntax_only, Flag, INVALID, INVALID, "d", 0, 0, 0)
-OPTION("-ftemplate-depth-", ftemplate_depth_, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fterminated-vtables", fterminated_vtables, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-ftime-report", ftime_report, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-ftrapv", ftrapv, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-funit-at-a-time", funit_at_a_time, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-funsigned-bitfields", funsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-funsigned-char", funsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-funwind-tables", funwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fverbose-asm", fverbose_asm, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fvisibility=", fvisibility_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fwritable-strings", fwritable_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-fzero-initialized-in-bss", fzero_initialized_in_bss, Flag, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-f", f, Joined, f_Group, INVALID, "", 0, 0, 0)
-OPTION("-g0", g0, Joined, g_Group, INVALID, "", 0, 0, 0)
-OPTION("-g3", g3, Joined, g_Group, INVALID, "", 0, 0, 0)
-OPTION("-gfull", gfull, Joined, g_Group, INVALID, "", 0, 0, 0)
-OPTION("-gstabs", gstabs, Joined, g_Group, INVALID, "", 0, 0, 0)
-OPTION("-gused", gused, Joined, g_Group, INVALID, "", 0, 0, 0)
-OPTION("-g", g_Flag, Flag, g_Group, INVALID, "", 0, 0, 0)
-OPTION("-g", g_Joined, Joined, g_Group, INVALID, "", 0, 0, 0)
-OPTION("-headerpad_max_install_names", headerpad__max__install__names, Joined, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-idirafter", idirafter, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-iframework", iframework, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-imacros", imacros, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-image_base", image__base, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-include", include, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-init", init, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-install_name", install__name, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-iprefix", iprefix, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-iquote", iquote, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-isysroot", isysroot, JoinedOrSeparate, i_Group, INVALID, "", 0, 0, 0)
-OPTION("-isystem", isystem, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-iwithprefixbefore", iwithprefixbefore, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-iwithprefix", iwithprefix, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
-OPTION("-iwithsysroot", iwithsysroot, JoinedOrSeparate, i_Group, INVALID, "", 0, 0, 0)
-OPTION("-i", i, Joined, i_Group, INVALID, "", 0, 0, 0)
-OPTION("-keep_private_externs", keep__private__externs, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-l", l, JoinedOrSeparate, INVALID, INVALID, "l", 0, 0, 0)
-OPTION("-m32", m32, Flag, m_Group, INVALID, "d", 0, 0, 0)
-OPTION("-m3dnowa", m3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-m3dnow", m3dnow, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-m64", m64, Flag, m_Group, INVALID, "d", 0, 0, 0)
-OPTION("-mabi=", mabi_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
-OPTION("-march=", march_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
-OPTION("-mcmodel=", mcmodel_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
-OPTION("-mconstant-cfstrings", mconstant_cfstrings, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mcpu=", mcpu_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
-OPTION("-mdynamic-no-pic", mdynamic_no_pic, Joined, m_Group, INVALID, "q", 0, 0, 0)
-OPTION("-mfix-and-continue", mfix_and_continue, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mfloat-abi=", mfloat_abi_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mhard-float", mhard_float, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-miphoneos-version-min=", miphoneos_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mkernel", mkernel, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mllvm", mllvm, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-mmacosx-version-min=", mmacosx_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mmmx", mmmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-3dnowa", mno_3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-3dnow", mno_3dnow, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-constant-cfstrings", mno_constant_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-mmx", mno_mmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-pascal-strings", mno_pascal_strings, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-red-zone", mno_red_zone, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-soft-float", mno_soft_float, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse2", mno_sse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse3", mno_sse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse4a", mno_sse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse4", mno_sse4, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse", mno_sse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-ssse3", mno_ssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-thumb", mno_thumb, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-warn-nonportable-cfstrings", mno_warn_nonportable_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mpascal-strings", mpascal_strings, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mred-zone", mred_zone, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-msoft-float", msoft_float, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse2", msse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse3", msse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse4a", msse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse4", msse4, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse", msse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mssse3", mssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mthumb", mthumb, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mtune=", mtune_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-multi_module", multi__module, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-multiply_defined_unused", multiply__defined__unused, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-multiply_defined", multiply__defined, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-mwarn-nonportable-cfstrings", mwarn_nonportable_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-m", m_Separate, Separate, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-m", m_Joined, Joined, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-no-cpp-precomp", no_cpp_precomp, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-no-integrated-cpp", no_integrated_cpp, Flag, INVALID, INVALID, "d", 0, 0, 0)
-OPTION("-no_dead_strip_inits_and_terms", no__dead__strip__inits__and__terms, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-nobuiltininc", nobuiltininc, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-nodefaultlibs", nodefaultlibs, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-nofixprebinding", nofixprebinding, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-nolibc", nolibc, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-nomultidefs", nomultidefs, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-noprebind", noprebind, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-noseglinkedit", noseglinkedit, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-nostartfiles", nostartfiles, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-nostdinc", nostdinc, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-nostdlib", nostdlib, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-object", object, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-o", o, JoinedOrSeparate, INVALID, INVALID, "di", 0,
- "Write output to <file>", "<file>")
-OPTION("-pagezero_size", pagezero__size, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-pass-exit-codes", pass_exit_codes, Flag, INVALID, INVALID, "u", 0, 0, 0)
-OPTION("-pedantic-errors", pedantic_errors, Flag, pedantic_Group, INVALID, "", 0, 0, 0)
-OPTION("-pedantic", pedantic, Flag, pedantic_Group, INVALID, "", 0, 0, 0)
-OPTION("-pg", pg, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-pipe", pipe, Flag, INVALID, INVALID, "", 0,
- "Use pipes between commands, when possible", 0)
-OPTION("-prebind_all_twolevel_modules", prebind__all__twolevel__modules, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-prebind", prebind, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-preload", preload, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-print-file-name=", print_file_name_EQ, Joined, INVALID, INVALID, "", 0,
- "Print the full library path of <file>", "<file>")
-OPTION("-print-ivar-layout", print_ivar_layout, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-print-libgcc-file-name", print_libgcc_file_name, Flag, INVALID, INVALID, "", 0,
- "Print the library path for \"libgcc.a\"", 0)
-OPTION("-print-multi-directory", print_multi_directory, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-print-multi-lib", print_multi_lib, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-print-multi-os-directory", print_multi_os_directory, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-print-prog-name=", print_prog_name_EQ, Joined, INVALID, INVALID, "", 0,
- "Print the full program path of <name>", "<name>")
-OPTION("-print-search-dirs", print_search_dirs, Flag, INVALID, INVALID, "", 0,
- "Print the paths used for finding libraries and programs", 0)
-OPTION("-private_bundle", private__bundle, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-pthreads", pthreads, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-pthread", pthread, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-p", p, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-read_only_relocs", read__only__relocs, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-remap", remap, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-rpath", rpath, Separate, INVALID, INVALID, "l", 0, 0, 0)
-OPTION("-r", r, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-save-temps", save_temps, Flag, INVALID, INVALID, "d", 0,
- "Save intermediate compilation results", 0)
-OPTION("-sectalign", sectalign, MultiArg, INVALID, INVALID, "", 3, 0, 0)
-OPTION("-sectcreate", sectcreate, MultiArg, INVALID, INVALID, "", 3, 0, 0)
-OPTION("-sectobjectsymbols", sectobjectsymbols, MultiArg, INVALID, INVALID, "", 2, 0, 0)
-OPTION("-sectorder", sectorder, MultiArg, INVALID, INVALID, "", 3, 0, 0)
-OPTION("-seg1addr", seg1addr, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-seg_addr_table_filename", seg__addr__table__filename, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-seg_addr_table", seg__addr__table, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-segaddr", segaddr, MultiArg, INVALID, INVALID, "", 2, 0, 0)
-OPTION("-segcreate", segcreate, MultiArg, INVALID, INVALID, "", 3, 0, 0)
-OPTION("-seglinkedit", seglinkedit, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-segprot", segprot, MultiArg, INVALID, INVALID, "", 3, 0, 0)
-OPTION("-segs_read_only_addr", segs__read__only__addr, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-segs_read_write_addr", segs__read__write__addr, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-segs_read_", segs__read__, Joined, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-shared-libgcc", shared_libgcc, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-shared", shared, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-single_module", single__module, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-specs=", specs_EQ, Joined, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-specs", specs, Separate, INVALID, INVALID, "u", 0, 0, 0)
-OPTION("-static-libgcc", static_libgcc, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-static", static, Flag, INVALID, INVALID, "q", 0, 0, 0)
-OPTION("-std-default=", std_default_EQ, Joined, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-std=", std_EQ, Joined, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-sub_library", sub__library, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-sub_umbrella", sub__umbrella, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-s", s, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-time", time, Flag, INVALID, INVALID, "", 0,
- "Time individual commands", 0)
-OPTION("-traditional-cpp", traditional_cpp, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-traditional", traditional, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-trigraphs", trigraphs, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-twolevel_namespace_hints", twolevel__namespace__hints, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-twolevel_namespace", twolevel__namespace, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-t", t, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-umbrella", umbrella, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-undefined", undefined, JoinedOrSeparate, u_Group, INVALID, "", 0, 0, 0)
-OPTION("-undef", undef, Flag, u_Group, INVALID, "", 0, 0, 0)
-OPTION("-unexported_symbols_list", unexported__symbols__list, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-u", u, JoinedOrSeparate, u_Group, INVALID, "", 0, 0, 0)
-OPTION("-v", v, Flag, INVALID, INVALID, "", 0,
- "Show commands to run and use verbose output", 0)
-OPTION("-weak-l", weak_l, Joined, INVALID, INVALID, "l", 0, 0, 0)
-OPTION("-weak_framework", weak__framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
-OPTION("-weak_library", weak__library, Separate, INVALID, INVALID, "l", 0, 0, 0)
-OPTION("-weak_reference_mismatches", weak__reference__mismatches, Separate, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-whatsloaded", whatsloaded, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-whyload", whyload, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-w", w, Flag, INVALID, INVALID, "", 0, 0, 0)
-OPTION("-x", x, JoinedOrSeparate, INVALID, INVALID, "d", 0,
- "Treat subsequent input files as having type <language>", "<language>")
-OPTION("-y", y, Joined, INVALID, INVALID, "", 0, 0, 0)
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
index 7fcaf3f497be..b05d5afd7578 100644
--- a/include/clang/Driver/Options.h
+++ b/include/clang/Driver/Options.h
@@ -7,11 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CLANG_DRIVER_OPTIONS_H_
-#define CLANG_DRIVER_OPTIONS_H_
+#ifndef CLANG_DRIVER_OPTIONS_H
+#define CLANG_DRIVER_OPTIONS_H
namespace clang {
namespace driver {
+ class OptTable;
+
namespace options {
enum ID {
OPT_INVALID = 0, // This is not an option ID.
@@ -19,71 +21,13 @@ namespace options {
OPT_UNKNOWN, // Reserved ID for unknown option.
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
HELPTEXT, METAVAR) OPT_##ID,
-#include "clang/Driver/Options.def"
+#include "clang/Driver/Options.inc"
LastOption
#undef OPTION
};
}
- class Arg;
- class InputArgList;
- class Option;
-
- /// OptTable - Provide access to the Option info table.
- ///
- /// The OptTable class provides a layer of indirection which allows
- /// Option instance to be created lazily. In the common case, only a
- /// few options will be needed at runtime; the OptTable class
- /// maintains enough information to parse command lines without
- /// instantiating Options, while letting other parts of the driver
- /// still use Option instances where convient.
- class OptTable {
- /// The table of options which have been constructed, indexed by
- /// option::ID - 1.
- mutable Option **Options;
-
- /// The index of the first option which can be parsed (i.e., is
- /// not a special option like 'input' or 'unknown', and is not an
- /// option group).
- unsigned FirstSearchableOption;
-
- Option *constructOption(options::ID id) const;
-
- public:
- OptTable();
- ~OptTable();
-
- unsigned getNumOptions() const;
-
- const char *getOptionName(options::ID id) const;
-
- /// getOption - Get the given \arg id's Option instance, lazily
- /// creating it if necessary.
- const Option *getOption(options::ID id) const;
-
- /// getOptionKind - Get the kind of the given option.
- unsigned getOptionKind(options::ID id) const;
-
- /// getOptionHelpText - Get the help text to use to describe this
- /// option.
- const char *getOptionHelpText(options::ID id) const;
-
- /// getOptionMetaVar - Get the meta-variable name to use when
- /// describing this options values in the help text.
- const char *getOptionMetaVar(options::ID id) const;
-
- /// parseOneArg - Parse a single argument; returning the new
- /// argument and updating Index.
- ///
- /// \param [in] [out] Index - The current parsing position in the
- /// argument string list; on return this will be the index of the
- /// next argument string to parse.
- ///
- /// \return - The parsed argument, or 0 if the argument is missing
- /// values (in which case Index still points at the conceptual
- /// next argument string to parse).
- Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const;
- };
+ OptTable *createDriverOptTable();
}
}
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
new file mode 100644
index 000000000000..ace1a3c16add
--- /dev/null
+++ b/include/clang/Driver/Options.td
@@ -0,0 +1,607 @@
+//===--- DriverOptions.td - Options for clang -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the options accepted by clang.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the common option parsing interfaces.
+include "OptParser.td"
+
+/////////
+// Groups
+
+def I_Group : OptionGroup<"<I group>">;
+def M_Group : OptionGroup<"<M group>">;
+def T_Group : OptionGroup<"<T group>">;
+def O_Group : OptionGroup<"<O group>">;
+def W_Group : OptionGroup<"<W group>">;
+def X_Group : OptionGroup<"<X group>">;
+def a_Group : OptionGroup<"<a group>">;
+def d_Group : OptionGroup<"<d group>">;
+def f_Group : OptionGroup<"<f group>">;
+def g_Group : OptionGroup<"<g group>">;
+def i_Group : OptionGroup<"<i group>">;
+def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>;
+def m_Group : OptionGroup<"<m group>">;
+def m_x86_Features_Group : OptionGroup<"<m x86 features group>">;
+def u_Group : OptionGroup<"<u group>">;
+
+def pedantic_Group : OptionGroup<"<pedantic group>">;
+
+// Temporary groups for clang options which we know we don't support,
+// but don't want to verbosely warn the user about.
+def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">,
+ Group<f_Group>;
+def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
+ Group<m_Group>;
+
+/////////
+// Options
+
+// The internal option ID must be a valid C++ identifier and results in a
+// clang::driver::options::OPT_XX enum constant for XX.
+//
+// We want to unambiguously be able to refer to options from the driver source
+// code, for this reason the option name is mangled into an ID. This mangling
+// isn't guaranteed to have an inverse, but for practical purposes it does.
+//
+// The mangling scheme is to ignore the leading '-', and perform the following
+// substitutions:
+// _ => __
+// - => _
+// # => _HASH
+// , => _COMMA
+// = => _EQ
+// C++ => CXX
+
+def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>,
+ HelpText<"Print the commands to run for this compilation">;
+def A : JoinedOrSeparate<"-A">;
+def B : JoinedOrSeparate<"-B">, Flags<[Unsupported]>;
+def CC : Flag<"-CC">;
+def C : Flag<"-C">;
+def D : JoinedOrSeparate<"-D">;
+def E : Flag<"-E">, Flags<[DriverOption]>,
+ HelpText<"Only run the preprocessor">;
+def F : JoinedOrSeparate<"-F">;
+def H : Flag<"-H">;
+def I_ : Flag<"-I-">, Group<I_Group>;
+def I : JoinedOrSeparate<"-I">, Group<I_Group>;
+def L : JoinedOrSeparate<"-L">;
+def MD : Flag<"-MD">, Group<M_Group>;
+def MF : JoinedOrSeparate<"-MF">, Group<M_Group>;
+def MG : Flag<"-MG">, Group<M_Group>;
+def MMD : Flag<"-MMD">, Group<M_Group>;
+def MM : Flag<"-MM">, Group<M_Group>;
+def MP : Flag<"-MP">, Group<M_Group>;
+def MQ : JoinedOrSeparate<"-MQ">, Group<M_Group>;
+def MT : JoinedOrSeparate<"-MT">, Group<M_Group>;
+def Mach : Flag<"-Mach">;
+def M : Flag<"-M">, Group<M_Group>;
+def O4 : Joined<"-O4">, Group<O_Group>;
+def ObjCXX : Flag<"-ObjC++">, Flags<[DriverOption]>,
+ HelpText<"Treat source input files as Objective-C++ inputs">;
+def ObjC : Flag<"-ObjC">, Flags<[DriverOption]>,
+ HelpText<"Treat source input files as Objective-C inputs">;
+def O : Joined<"-O">, Group<O_Group>;
+def P : Flag<"-P">;
+def Qn : Flag<"-Qn">;
+def Qunused_arguments : Flag<"-Qunused-arguments">, Flags<[DriverOption]>,
+ HelpText<"Don't emit warning for unused driver arguments">;
+def Q : Flag<"-Q">;
+def R : Flag<"-R">;
+def S : Flag<"-S">, Flags<[DriverOption]>,
+ HelpText<"Only run preprocess and compilation steps">;
+def Tbss : JoinedOrSeparate<"-Tbss">, Group<T_Group>;
+def Tdata : JoinedOrSeparate<"-Tdata">, Group<T_Group>;
+def Ttext : JoinedOrSeparate<"-Ttext">, Group<T_Group>;
+def T : JoinedOrSeparate<"-T">, Group<T_Group>;
+def U : JoinedOrSeparate<"-U">;
+def V : JoinedOrSeparate<"-V">, Flags<[DriverOption, Unsupported]>;
+def Wa_COMMA : CommaJoined<"-Wa,">,
+ HelpText<"Pass the comma separated arguments in <arg> to the assembler">,
+ MetaVarName<"<arg>">;
+def Wall : Flag<"-Wall">, Group<W_Group>;
+def Wextra : Flag<"-Wextra">, Group<W_Group>;
+def Wl_COMMA : CommaJoined<"-Wl,">, Flags<[LinkerInput, RenderAsInput]>,
+ HelpText<"Pass the comma separated arguments in <arg> to the linker">,
+ MetaVarName<"<arg>">;
+def Wno_nonportable_cfstrings : Joined<"-Wno-nonportable-cfstrings">, Group<W_Group>;
+def Wnonportable_cfstrings : Joined<"-Wnonportable-cfstrings">, Group<W_Group>;
+def Wp_COMMA : CommaJoined<"-Wp,">,
+ HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
+ MetaVarName<"<arg>">;
+def W_Joined : Joined<"-W">, Group<W_Group>;
+def Xanalyzer : Separate<"-Xanalyzer">,
+ HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">;
+def Xarch__ : JoinedAndSeparate<"-Xarch_">, Flags<[DriverOption]>;
+def Xassembler : Separate<"-Xassembler">,
+ HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">;
+def Xclang : Separate<"-Xclang">,
+ HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">;
+def Xlinker : Separate<"-Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
+ HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
+def Xpreprocessor : Separate<"-Xpreprocessor">,
+ HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
+def X_Flag : Flag<"-X">;
+def X_Joined : Joined<"-X">;
+def Z_Flag : Flag<"-Z">;
+def Z_Joined : Joined<"-Z">;
+def all__load : Flag<"-all_load">;
+def allowable__client : Separate<"-allowable_client">;
+def ansi : Flag<"-ansi">, Group<a_Group>;
+def arch__errors__fatal : Flag<"-arch_errors_fatal">;
+def arch : Separate<"-arch">, Flags<[DriverOption]>;
+def a : Joined<"-a">, Group<a_Group>;
+def bind__at__load : Flag<"-bind_at_load">;
+def bundle__loader : Separate<"-bundle_loader">;
+def bundle : Flag<"-bundle">;
+def b : JoinedOrSeparate<"-b">, Flags<[Unsupported]>;
+def client__name : JoinedOrSeparate<"-client_name">;
+def combine : Flag<"-combine">, Flags<[DriverOption, Unsupported]>;
+def compatibility__version : JoinedOrSeparate<"-compatibility_version">;
+def coverage : Flag<"-coverage">;
+def cpp_precomp : Flag<"-cpp-precomp">;
+def current__version : JoinedOrSeparate<"-current_version">;
+def c : Flag<"-c">, Flags<[DriverOption]>,
+ HelpText<"Only run preprocess, compile, and assemble steps">;
+def dA : Flag<"-dA">, Group<d_Group>;
+def dD : Flag<"-dD">, Group<d_Group>;
+def dM : Flag<"-dM">, Group<d_Group>;
+def dead__strip : Flag<"-dead_strip">;
+def dependency_file : Separate<"-dependency-file">;
+def dumpmachine : Flag<"-dumpmachine">, Flags<[Unsupported]>;
+def dumpspecs : Flag<"-dumpspecs">, Flags<[Unsupported]>;
+def dumpversion : Flag<"-dumpversion">;
+def dylib__file : Separate<"-dylib_file">;
+def dylinker__install__name : JoinedOrSeparate<"-dylinker_install_name">;
+def dylinker : Flag<"-dylinker">;
+def dynamiclib : Flag<"-dynamiclib">;
+def dynamic : Flag<"-dynamic">, Flags<[NoArgumentUnused]>;
+def d_Flag : Flag<"-d">, Group<d_Group>;
+def d_Joined : Joined<"-d">, Group<d_Group>;
+def emit_ast : Flag<"-emit-ast">,
+ HelpText<"Emit Clang AST files for source inputs">;
+def emit_llvm : Flag<"-emit-llvm">,
+ HelpText<"Use the LLVM representation for assembler and object files">;
+def exported__symbols__list : Separate<"-exported_symbols_list">;
+def e : JoinedOrSeparate<"-e">;
+def fPIC : Flag<"-fPIC">, Group<f_Group>;
+def fPIE : Flag<"-fPIE">, Group<f_Group>;
+def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
+def fasm_blocks : Flag<"-fasm-blocks">, Group<clang_ignored_f_Group>;
+def fastcp : Flag<"-fastcp">, Group<f_Group>;
+def fastf : Flag<"-fastf">, Group<f_Group>;
+def fast : Flag<"-fast">, Group<f_Group>;
+def fasynchronous_unwind_tables : Flag<"-fasynchronous-unwind-tables">, Group<f_Group>;
+def fblock_introspection : Flag<"-fblock-introspection">, Group<f_Group>;
+def fblocks : Flag<"-fblocks">, Group<f_Group>;
+def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>;
+def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>;
+def fbuiltin_strcpy : Flag<"-fbuiltin-strcpy">, Group<f_Group>;
+def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>;
+def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>;
+def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, Group<f_Group>;
+def fcommon : Flag<"-fcommon">, Group<f_Group>;
+def fcompile_resource_EQ : Joined<"-fcompile-resource=">, Group<f_Group>;
+def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<clang_ignored_f_Group>;
+def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Group>;
+def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
+def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
+def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>;
+def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>;
+def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_Group>;
+def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
+def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>;
+def feliminate_unused_debug_symbols : Flag<"-feliminate-unused-debug-symbols">, Group<f_Group>;
+def femit_all_decls : Flag<"-femit-all-decls">, Group<f_Group>;
+def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>;
+def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
+def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
+def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
+def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
+def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
+def filelist : Separate<"-filelist">, Flags<[LinkerInput]>;
+def findirect_virtual_calls : Flag<"-findirect-virtual-calls">, Group<f_Group>;
+def finline_functions : Flag<"-finline-functions">, Group<clang_ignored_f_Group>;
+def finline : Flag<"-finline">, Group<clang_ignored_f_Group>;
+def fkeep_inline_functions : Flag<"-fkeep-inline-functions">, Group<clang_ignored_f_Group>;
+def flat__namespace : Flag<"-flat_namespace">;
+def flax_vector_conversions : Flag<"-flax-vector-conversions">, Group<f_Group>;
+def flimited_precision_EQ : Joined<"-flimited-precision=">, Group<f_Group>;
+def flto : Flag<"-flto">, Group<f_Group>;
+def fmath_errno : Flag<"-fmath-errno">, Group<f_Group>;
+def fmerge_all_constants : Flag<"-fmerge-all-constants">, Group<f_Group>;
+def fmessage_length_EQ : Joined<"-fmessage-length=">, Group<f_Group>;
+def fms_extensions : Flag<"-fms-extensions">, Group<f_Group>;
+def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>;
+def fmudflap : Flag<"-fmudflap">, Group<f_Group>;
+def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>;
+def fnext_runtime : Flag<"-fnext-runtime">, Group<f_Group>;
+def fno_asynchronous_unwind_tables : Flag<"-fno-asynchronous-unwind-tables">, Group<f_Group>;
+def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>;
+def fno_builtin_strcat : Flag<"-fno-builtin-strcat">, Group<f_Group>;
+def fno_builtin_strcpy : Flag<"-fno-builtin-strcpy">, Group<f_Group>;
+def fno_builtin : Flag<"-fno-builtin">, Group<f_Group>;
+def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">, Group<f_Group>;
+def fno_color_diagnostics : Flag<"-fno-color-diagnostics">, Group<f_Group>;
+def fno_common : Flag<"-fno-common">, Group<f_Group>;
+def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">, Group<f_Group>;
+def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">, Group<f_Group>;
+def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_Group>;
+def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
+def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>;
+def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>;
+def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>;
+def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>;
+def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
+def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>;
+def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>;
+def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>;
+def fno_omit_frame_pointer : Flag<"-fno-omit-frame-pointer">, Group<f_Group>;
+def fno_pascal_strings : Flag<"-fno-pascal-strings">, Group<f_Group>;
+def fno_rtti : Flag<"-fno-rtti">, Group<f_Group>;
+def fno_show_column : Flag<"-fno-show-column">, Group<f_Group>;
+def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>;
+def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
+def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<clang_ignored_f_Group>;
+def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>;
+def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>;
+def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>;
+def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>;
+def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>;
+def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
+def fobjc_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>;
+def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>;
+def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>;
+def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, Group<f_Group>;
+def fobjc_sender_dependent_dispatch : Flag<"-fobjc-sender-dependent-dispatch">, Group<f_Group>;
+def fobjc : Flag<"-fobjc">, Group<f_Group>;
+def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>;
+def fopenmp : Flag<"-fopenmp">, Group<f_Group>;
+def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">;
+def force__flat__namespace : Flag<"-force_flat_namespace">;
+def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>;
+def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>;
+def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>;
+def fpic : Flag<"-fpic">, Group<f_Group>;
+def fpie : Flag<"-fpie">, Group<f_Group>;
+def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>;
+def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>;
+def framework : Separate<"-framework">, Flags<[LinkerInput]>;
+def frtti : Flag<"-frtti">, Group<f_Group>;
+def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
+def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
+def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;
+def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>;
+def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>;
+def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>;
+def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<clang_ignored_f_Group>;
+def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>;
+def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
+def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
+def ftime_report : Flag<"-ftime-report">, Group<f_Group>;
+def ftrapv : Flag<"-ftrapv">, Group<f_Group>;
+def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>;
+def funsigned_bitfields : Flag<"-funsigned-bitfields">, Group<f_Group>;
+def funsigned_char : Flag<"-funsigned-char">, Group<f_Group>;
+def funwind_tables : Flag<"-funwind-tables">, Group<f_Group>;
+def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>;
+def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>;
+def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>;
+def fzero_initialized_in_bss : Flag<"-fzero-initialized-in-bss">, Group<f_Group>;
+def f : Joined<"-f">, Group<f_Group>;
+def g0 : Joined<"-g0">, Group<g_Group>;
+def g3 : Joined<"-g3">, Group<g_Group>;
+def gfull : Joined<"-gfull">, Group<g_Group>;
+def gstabs : Joined<"-gstabs">, Group<g_Group>;
+def gused : Joined<"-gused">, Group<g_Group>;
+def g_Flag : Flag<"-g">, Group<g_Group>;
+def g_Joined : Joined<"-g">, Group<g_Group>;
+def headerpad__max__install__names : Joined<"-headerpad_max_install_names">;
+def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>;
+def iframework : JoinedOrSeparate<"-iframework">, Group<clang_i_Group>;
+def imacros : JoinedOrSeparate<"-imacros">, Group<clang_i_Group>;
+def image__base : Separate<"-image_base">;
+def include_ : JoinedOrSeparate<"-include">, Group<clang_i_Group>, EnumName<"include">;
+def init : Separate<"-init">;
+def install__name : Separate<"-install_name">;
+def iprefix : JoinedOrSeparate<"-iprefix">, Group<clang_i_Group>;
+def iquote : JoinedOrSeparate<"-iquote">, Group<clang_i_Group>;
+def isysroot : JoinedOrSeparate<"-isysroot">, Group<i_Group>;
+def isystem : JoinedOrSeparate<"-isystem">, Group<clang_i_Group>;
+def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">, Group<clang_i_Group>;
+def iwithprefix : JoinedOrSeparate<"-iwithprefix">, Group<clang_i_Group>;
+def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">, Group<i_Group>;
+def i : Joined<"-i">, Group<i_Group>;
+def keep__private__externs : Flag<"-keep_private_externs">;
+def l : JoinedOrSeparate<"-l">, Flags<[LinkerInput]>;
+def m32 : Flag<"-m32">, Group<m_Group>, Flags<[DriverOption]>;
+def m3dnowa : Flag<"-m3dnowa">, Group<m_x86_Features_Group>;
+def m3dnow : Flag<"-m3dnow">, Group<m_x86_Features_Group>;
+def m64 : Flag<"-m64">, Group<m_Group>, Flags<[DriverOption]>;
+def mabi_EQ : Joined<"-mabi=">, Group<m_Group>, Flags<[DriverOption]>;
+def march_EQ : Joined<"-march=">, Group<m_Group>, Flags<[DriverOption]>;
+def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>, Flags<[DriverOption]>;
+def mconstant_cfstrings : Flag<"-mconstant-cfstrings">, Group<clang_ignored_m_Group>;
+def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>, Flags<[DriverOption]>;
+def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>, Flags<[NoArgumentUnused]>;
+def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>;
+def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>;
+def mhard_float : Flag<"-mhard-float">, Group<m_Group>;
+def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>;
+def mkernel : Flag<"-mkernel">, Group<m_Group>;
+def mllvm : Separate<"-mllvm">;
+def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>;
+def mmmx : Flag<"-mmmx">, Group<m_x86_Features_Group>;
+def mno_3dnowa : Flag<"-mno-3dnowa">, Group<m_x86_Features_Group>;
+def mno_3dnow : Flag<"-mno-3dnow">, Group<m_x86_Features_Group>;
+def mno_constant_cfstrings : Flag<"-mno-constant-cfstrings">, Group<m_Group>;
+def mno_mmx : Flag<"-mno-mmx">, Group<m_x86_Features_Group>;
+def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group<m_Group>;
+def mno_red_zone : Flag<"-mno-red-zone">, Group<m_Group>;
+def mno_soft_float : Flag<"-mno-soft-float">, Group<m_Group>;
+def mno_sse2 : Flag<"-mno-sse2">, Group<m_x86_Features_Group>;
+def mno_sse3 : Flag<"-mno-sse3">, Group<m_x86_Features_Group>;
+def mno_sse4a : Flag<"-mno-sse4a">, Group<m_x86_Features_Group>;
+def mno_sse4 : Flag<"-mno-sse4">, Group<m_x86_Features_Group>;
+def mno_sse : Flag<"-mno-sse">, Group<m_x86_Features_Group>;
+def mno_ssse3 : Flag<"-mno-ssse3">, Group<m_x86_Features_Group>;
+def mno_thumb : Flag<"-mno-thumb">, Group<m_Group>;
+def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>;
+def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
+def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
+def msoft_float : Flag<"-msoft-float">, Group<m_Group>;
+def msse2 : Flag<"-msse2">, Group<m_x86_Features_Group>;
+def msse3 : Flag<"-msse3">, Group<m_x86_Features_Group>;
+def msse4a : Flag<"-msse4a">, Group<m_x86_Features_Group>;
+def msse4 : Flag<"-msse4">, Group<m_x86_Features_Group>;
+def msse : Flag<"-msse">, Group<m_x86_Features_Group>;
+def mssse3 : Flag<"-mssse3">, Group<m_x86_Features_Group>;
+def mthumb : Flag<"-mthumb">, Group<m_Group>;
+def mtune_EQ : Joined<"-mtune=">, Group<m_Group>;
+def multi__module : Flag<"-multi_module">;
+def multiply__defined__unused : Separate<"-multiply_defined_unused">;
+def multiply__defined : Separate<"-multiply_defined">;
+def mwarn_nonportable_cfstrings : Flag<"-mwarn-nonportable-cfstrings">, Group<m_Group>;
+def m_Separate : Separate<"-m">, Group<m_Group>;
+def m_Joined : Joined<"-m">, Group<m_Group>;
+def no_cpp_precomp : Flag<"-no-cpp-precomp">;
+def no_integrated_cpp : Flag<"-no-integrated-cpp">, Flags<[DriverOption]>;
+def no__dead__strip__inits__and__terms : Flag<"-no_dead_strip_inits_and_terms">;
+def nobuiltininc : Flag<"-nobuiltininc">;
+def nodefaultlibs : Flag<"-nodefaultlibs">;
+def nofixprebinding : Flag<"-nofixprebinding">;
+def nolibc : Flag<"-nolibc">;
+def nomultidefs : Flag<"-nomultidefs">;
+def noprebind : Flag<"-noprebind">;
+def noseglinkedit : Flag<"-noseglinkedit">;
+def nostartfiles : Flag<"-nostartfiles">;
+def nostdinc : Flag<"-nostdinc">;
+def nostdlib : Flag<"-nostdlib">;
+def object : Flag<"-object">;
+def o : JoinedOrSeparate<"-o">, Flags<[DriverOption, RenderAsInput]>,
+ HelpText<"Write output to <file>">, MetaVarName<"<file>">;
+def pagezero__size : JoinedOrSeparate<"-pagezero_size">;
+def pass_exit_codes : Flag<"-pass-exit-codes">, Flags<[Unsupported]>;
+def pedantic_errors : Flag<"-pedantic-errors">, Group<pedantic_Group>;
+def pedantic : Flag<"-pedantic">, Group<pedantic_Group>;
+def pg : Flag<"-pg">;
+def pipe : Flag<"-pipe">,
+ HelpText<"Use pipes between commands, when possible">;
+def prebind__all__twolevel__modules : Flag<"-prebind_all_twolevel_modules">;
+def prebind : Flag<"-prebind">;
+def preload : Flag<"-preload">;
+def print_file_name_EQ : Joined<"-print-file-name=">,
+ HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">;
+def print_ivar_layout : Flag<"-print-ivar-layout">;
+def print_libgcc_file_name : Flag<"-print-libgcc-file-name">,
+ HelpText<"Print the library path for \"libgcc.a\"">;
+def print_multi_directory : Flag<"-print-multi-directory">;
+def print_multi_lib : Flag<"-print-multi-lib">;
+def print_multi_os_directory : Flag<"-print-multi-os-directory">;
+def print_prog_name_EQ : Joined<"-print-prog-name=">,
+ HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">;
+def print_search_dirs : Flag<"-print-search-dirs">,
+ HelpText<"Print the paths used for finding libraries and programs">;
+def private__bundle : Flag<"-private_bundle">;
+def pthreads : Flag<"-pthreads">;
+def pthread : Flag<"-pthread">;
+def p : Flag<"-p">;
+def read__only__relocs : Separate<"-read_only_relocs">;
+def remap : Flag<"-remap">;
+def rpath : Separate<"-rpath">, Flags<[LinkerInput]>;
+def r : Flag<"-r">;
+def save_temps : Flag<"-save-temps">, Flags<[DriverOption]>,
+ HelpText<"Save intermediate compilation results">;
+def sectalign : MultiArg<"-sectalign", 3>;
+def sectcreate : MultiArg<"-sectcreate", 3>;
+def sectobjectsymbols : MultiArg<"-sectobjectsymbols", 2>;
+def sectorder : MultiArg<"-sectorder", 3>;
+def seg1addr : JoinedOrSeparate<"-seg1addr">;
+def seg__addr__table__filename : Separate<"-seg_addr_table_filename">;
+def seg__addr__table : Separate<"-seg_addr_table">;
+def segaddr : MultiArg<"-segaddr", 2>;
+def segcreate : MultiArg<"-segcreate", 3>;
+def seglinkedit : Flag<"-seglinkedit">;
+def segprot : MultiArg<"-segprot", 3>;
+def segs__read__only__addr : Separate<"-segs_read_only_addr">;
+def segs__read__write__addr : Separate<"-segs_read_write_addr">;
+def segs__read__ : Joined<"-segs_read_">;
+def shared_libgcc : Flag<"-shared-libgcc">;
+def shared : Flag<"-shared">;
+def single__module : Flag<"-single_module">;
+def specs_EQ : Joined<"-specs=">;
+def specs : Separate<"-specs">, Flags<[Unsupported]>;
+def static_libgcc : Flag<"-static-libgcc">;
+def static : Flag<"-static">, Flags<[NoArgumentUnused]>;
+def std_default_EQ : Joined<"-std-default=">;
+def std_EQ : Joined<"-std=">;
+def sub__library : JoinedOrSeparate<"-sub_library">;
+def sub__umbrella : JoinedOrSeparate<"-sub_umbrella">;
+def s : Flag<"-s">;
+def time : Flag<"-time">,
+ HelpText<"Time individual commands">;
+def traditional_cpp : Flag<"-traditional-cpp">;
+def traditional : Flag<"-traditional">;
+def trigraphs : Flag<"-trigraphs">;
+def twolevel__namespace__hints : Flag<"-twolevel_namespace_hints">;
+def twolevel__namespace : Flag<"-twolevel_namespace">;
+def t : Flag<"-t">;
+def umbrella : Separate<"-umbrella">;
+def undefined : JoinedOrSeparate<"-undefined">, Group<u_Group>;
+def undef : Flag<"-undef">, Group<u_Group>;
+def unexported__symbols__list : Separate<"-unexported_symbols_list">;
+def u : JoinedOrSeparate<"-u">, Group<u_Group>;
+def v : Flag<"-v">,
+ HelpText<"Show commands to run and use verbose output">;
+def weak_l : Joined<"-weak-l">, Flags<[LinkerInput]>;
+def weak__framework : Separate<"-weak_framework">, Flags<[LinkerInput]>;
+def weak__library : Separate<"-weak_library">, Flags<[LinkerInput]>;
+def weak__reference__mismatches : Separate<"-weak_reference_mismatches">;
+def whatsloaded : Flag<"-whatsloaded">;
+def whyload : Flag<"-whyload">;
+def w : Flag<"-w">;
+def x : JoinedOrSeparate<"-x">, Flags<[DriverOption]>,
+ HelpText<"Treat subsequent input files as having type <language>">,
+ MetaVarName<"<language>">;
+def y : Joined<"-y">;
+
+// Double dash options, which are usually an alias for one of the previous
+// options.
+
+def _CLASSPATH_EQ : Joined<"--CLASSPATH=">, Alias<fclasspath_EQ>;
+def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
+def _all_warnings : Flag<"--all-warnings">, Alias<Wall>;
+def _analyze_auto : Flag<"--analyze-auto">, Flags<[DriverOption]>;
+def _analyzer_no_default_checks : Flag<"--analyzer-no-default-checks">, Flags<[DriverOption]>;
+def _analyzer_output : JoinedOrSeparate<"--analyzer-output">, Flags<[DriverOption]>;
+def _analyze : Flag<"--analyze">, Flags<[DriverOption]>,
+ HelpText<"Run the static analyzer">;
+def _ansi : Flag<"--ansi">, Alias<ansi>;
+def _assemble : Flag<"--assemble">, Alias<S>;
+def _assert_EQ : Joined<"--assert=">, Alias<A>, Flags<[RenderSeparate]>;
+def _assert : Separate<"--assert">, Alias<A>;
+def _bootclasspath_EQ : Joined<"--bootclasspath=">, Alias<fbootclasspath_EQ>;
+def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>, Flags<[RenderJoined]>;
+def _classpath_EQ : Joined<"--classpath=">, Alias<fclasspath_EQ>;
+def _classpath : Separate<"--classpath">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
+def _combine : Flag<"--combine">, Alias<combine>, Flags<[Unsupported]>;
+def _comments_in_macros : Flag<"--comments-in-macros">, Alias<CC>;
+def _comments : Flag<"--comments">, Alias<C>;
+def _compile : Flag<"--compile">, Alias<c>;
+def _constant_cfstrings : Flag<"--constant-cfstrings">;
+def _coverage : Flag<"--coverage">, Alias<coverage>;
+def _debug_EQ : Joined<"--debug=">, Alias<g_Flag>, Flags<[Unsupported]>;
+def _debug : Flag<"--debug">, Alias<g_Flag>, Flags<[Unsupported]>;
+def _define_macro_EQ : Joined<"--define-macro=">, Alias<D>;
+def _define_macro : Separate<"--define-macro">, Alias<D>, Flags<[RenderJoined]>;
+def _dependencies : Flag<"--dependencies">, Alias<M>;
+def _encoding_EQ : Joined<"--encoding=">, Alias<fencoding_EQ>;
+def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>, Flags<[RenderJoined]>;
+def _entry : Flag<"--entry">, Alias<e>;
+def _extdirs_EQ : Joined<"--extdirs=">, Alias<fextdirs_EQ>;
+def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>, Flags<[RenderJoined]>;
+def _extra_warnings : Flag<"--extra-warnings">, Alias<W_Joined>;
+def _for_linker_EQ : Joined<"--for-linker=">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput, RenderSeparate]>;
+def _for_linker : Separate<"--for-linker">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput]>;
+def _force_link_EQ : Joined<"--force-link=">, Alias<u>, Flags<[RenderSeparate]>;
+def _force_link : Separate<"--force-link">, Alias<u>;
+def _help_hidden : Flag<"--help-hidden">;
+def _help : Flag<"--help">,
+ HelpText<"Display available options">;
+def _imacros_EQ : Joined<"--imacros=">, Alias<imacros>, Flags<[RenderSeparate]>;
+def _imacros : Separate<"--imacros">, Alias<imacros>;
+def _include_barrier : Flag<"--include-barrier">, Alias<I_>;
+def _include_directory_after_EQ : Joined<"--include-directory-after=">, Alias<idirafter>, Flags<[RenderSeparate]>;
+def _include_directory_after : Separate<"--include-directory-after">, Alias<idirafter>;
+def _include_directory_EQ : Joined<"--include-directory=">, Alias<I>;
+def _include_directory : Separate<"--include-directory">, Alias<I>, Flags<[RenderJoined]>;
+def _include_prefix_EQ : Joined<"--include-prefix=">, Alias<iprefix>, Flags<[RenderSeparate]>;
+def _include_prefix : Separate<"--include-prefix">, Alias<iprefix>;
+def _include_with_prefix_after_EQ : Joined<"--include-with-prefix-after=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
+def _include_with_prefix_after : Separate<"--include-with-prefix-after">, Alias<iwithprefix>;
+def _include_with_prefix_before_EQ : Joined<"--include-with-prefix-before=">, Alias<iwithprefixbefore>, Flags<[RenderSeparate]>;
+def _include_with_prefix_before : Separate<"--include-with-prefix-before">, Alias<iwithprefixbefore>;
+def _include_with_prefix_EQ : Joined<"--include-with-prefix=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
+def _include_with_prefix : Separate<"--include-with-prefix">, Alias<iwithprefix>;
+def _include_EQ : Joined<"--include=">, Alias<include_>, Flags<[RenderSeparate]>;
+def _include : Separate<"--include">, Alias<include_>;
+def _language_EQ : Joined<"--language=">, Alias<x>, Flags<[RenderSeparate]>;
+def _language : Separate<"--language">, Alias<x>;
+def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>, Flags<[RenderSeparate]>;
+def _library_directory : Separate<"--library-directory">, Alias<L>;
+def _machine__EQ : Joined<"--machine-=">, Alias<m_Joined>, Flags<[Unsupported]>;
+def _machine_ : Joined<"--machine-">, Alias<m_Joined>, Flags<[Unsupported]>;
+def _machine_EQ : Joined<"--machine=">, Alias<m_Joined>;
+def _machine : Separate<"--machine">, Alias<m_Joined>, Flags<[RenderJoined]>;
+def _no_integrated_cpp : Flag<"--no-integrated-cpp">, Alias<no_integrated_cpp>;
+def _no_line_commands : Flag<"--no-line-commands">, Alias<P>;
+def _no_standard_includes : Flag<"--no-standard-includes">, Alias<nostdinc>;
+def _no_standard_libraries : Flag<"--no-standard-libraries">, Alias<nostdlib>;
+def _no_undefined : Flag<"--no-undefined">, Flags<[LinkerInput]>;
+def _no_warnings : Flag<"--no-warnings">, Alias<w>;
+def _optimize_EQ : Joined<"--optimize=">, Alias<O>, Flags<[Unsupported]>;
+def _optimize : Flag<"--optimize">, Alias<O>, Flags<[Unsupported]>;
+def _output_class_directory_EQ : Joined<"--output-class-directory=">, Alias<foutput_class_dir_EQ>;
+def _output_class_directory : Separate<"--output-class-directory">, Alias<foutput_class_dir_EQ>, Flags<[RenderJoined]>;
+def _output_EQ : Joined<"--output=">, Alias<o>, Flags<[RenderSeparate]>;
+def _output : Separate<"--output">, Alias<o>;
+def _param : Separate<"--param">;
+def _param_EQ : Joined<"--param=">, Alias<_param>, Flags<[RenderSeparate]>;
+def _pass_exit_codes : Flag<"--pass-exit-codes">, Alias<pass_exit_codes>;
+def _pedantic_errors : Flag<"--pedantic-errors">, Alias<pedantic_errors>;
+def _pedantic : Flag<"--pedantic">, Alias<pedantic>;
+def _pipe : Flag<"--pipe">, Alias<pipe>, Flags<[DriverOption]>;
+def _prefix_EQ : Joined<"--prefix=">, Alias<B>, Flags<[RenderSeparate]>;
+def _prefix : Separate<"--prefix">, Alias<B>;
+def _preprocess : Flag<"--preprocess">, Alias<E>;
+def _print_file_name_EQ : Joined<"--print-file-name=">, Alias<print_file_name_EQ>;
+def _print_file_name : Separate<"--print-file-name">, Alias<print_file_name_EQ>;
+def _print_libgcc_file_name : Flag<"--print-libgcc-file-name">, Alias<print_libgcc_file_name>;
+def _print_missing_file_dependencies : Flag<"--print-missing-file-dependencies">, Alias<MG>;
+def _print_multi_directory : Flag<"--print-multi-directory">, Alias<print_multi_directory>;
+def _print_multi_lib : Flag<"--print-multi-lib">, Alias<print_multi_lib>;
+def _print_multi_os_directory : Flag<"--print-multi-os-directory">, Alias<print_multi_os_directory>;
+def _print_prog_name_EQ : Joined<"--print-prog-name=">, Alias<print_prog_name_EQ>;
+def _print_prog_name : Separate<"--print-prog-name">, Alias<print_prog_name_EQ>;
+def _print_search_dirs : Flag<"--print-search-dirs">, Alias<print_search_dirs>;
+def _profile_blocks : Flag<"--profile-blocks">, Alias<a>;
+def _profile : Flag<"--profile">, Alias<p>;
+def _relocatable_pch : Flag<"--relocatable-pch">,
+ HelpText<"Build a relocatable precompiled header">;
+def _resource_EQ : Joined<"--resource=">, Alias<fcompile_resource_EQ>;
+def _resource : Separate<"--resource">, Alias<fcompile_resource_EQ>, Flags<[RenderJoined]>;
+def _save_temps : Flag<"--save-temps">, Alias<save_temps>;
+def _shared : Flag<"--shared">, Alias<shared>;
+def _signed_char : Flag<"--signed-char">, Alias<fsigned_char>;
+def _specs_EQ : Joined<"--specs=">, Alias<specs_EQ>, Flags<[Unsupported]>;
+def _specs : Separate<"--specs">, Alias<specs_EQ>, Flags<[RenderJoined, Unsupported]>;
+def _static : Flag<"--static">, Alias<static>;
+def _std_EQ : Joined<"--std=">, Alias<std_EQ>;
+def _std : Separate<"--std">, Alias<std_EQ>, Flags<[RenderJoined]>;
+def _sysroot_EQ : Joined<"--sysroot=">;
+def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>, Flags<[RenderJoined]>;
+def _target_help : Flag<"--target-help">;
+def _trace_includes : Flag<"--trace-includes">, Alias<H>;
+def _traditional_cpp : Flag<"--traditional-cpp">, Alias<traditional_cpp>;
+def _traditional : Flag<"--traditional">, Alias<traditional>;
+def _trigraphs : Flag<"--trigraphs">, Alias<trigraphs>;
+def _undefine_macro_EQ : Joined<"--undefine-macro=">, Alias<U>;
+def _undefine_macro : Separate<"--undefine-macro">, Alias<U>, Flags<[RenderJoined]>;
+def _unsigned_char : Flag<"--unsigned-char">, Alias<funsigned_char>;
+def _user_dependencies : Flag<"--user-dependencies">, Alias<MM>;
+def _verbose : Flag<"--verbose">, Alias<v>;
+def _version : Flag<"--version">;
+def _warn__EQ : Joined<"--warn-=">, Alias<W_Joined>, Flags<[Unsupported]>;
+def _warn_ : Joined<"--warn-">, Alias<W_Joined>, Flags<[Unsupported]>;
+def _write_dependencies : Flag<"--write-dependencies">, Alias<MD>;
+def _write_user_dependencies : Flag<"--write-user-dependencies">, Alias<MMD>;
+def _ : Joined<"--">, Alias<f>, Flags<[Unsupported]>;
diff --git a/include/clang/Frontend/CompileOptions.h b/include/clang/Frontend/CompileOptions.h
deleted file mode 100644
index ad53a8d592ba..000000000000
--- a/include/clang/Frontend/CompileOptions.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===--- CompileOptions.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CompileOptions interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_COMPILEOPTIONS_H
-#define LLVM_CLANG_FRONTEND_COMPILEOPTIONS_H
-
-#include <string>
-#include <vector>
-
-namespace clang {
-
-/// CompileOptions - Track various options which control how the code
-/// is optimized and passed to the backend.
-class CompileOptions {
-public:
- enum InliningMethod {
- NoInlining, // Perform no inlining whatsoever.
- NormalInlining, // Use the standard function inlining pass.
- OnlyAlwaysInlining // Only run the always inlining pass.
- };
-
- unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
- unsigned OptimizeSize : 1; /// If -Os is specified.
- unsigned DebugInfo : 1; /// Should generate deubg info (-g).
- unsigned UnitAtATime : 1; /// Unused. For mirroring GCC
- /// optimization selection.
- unsigned SimplifyLibCalls : 1; /// Should standard library calls be
- /// treated specially.
- unsigned UnrollLoops : 1; /// Control whether loops are unrolled.
- unsigned VerifyModule : 1; /// Control whether the module
- /// should be run through the LLVM Verifier.
- unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
- unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
- unsigned DisableRedZone : 1; /// Set when -mno-red-zone is enabled.
- unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
- unsigned MergeAllConstants : 1; // Merge identical constants.
-
- /// Inlining - The kind of inlining to perform.
- InliningMethod Inlining;
-
- /// CPU - An optional CPU to target.
- std::string CPU;
-
- /// Features - A list of subtarget features to pass to the code
- /// generator.
- std::vector<std::string> Features;
-
-public:
- CompileOptions() {
- OptimizationLevel = 0;
- OptimizeSize = 0;
- DebugInfo = 0;
- UnitAtATime = 1;
- SimplifyLibCalls = UnrollLoops = 0;
- VerifyModule = 1;
- TimePasses = 0;
- NoCommon = 0;
- Inlining = NoInlining;
- DisableRedZone = 0;
- NoImplicitFloat = 0;
- MergeAllConstants = 1;
- }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h
index 2edc7e1f4ab4..67129775ac8d 100644
--- a/include/clang/Frontend/HeaderSearchOptions.h
+++ b/include/clang/Frontend/HeaderSearchOptions.h
@@ -72,8 +72,8 @@ public:
unsigned Verbose : 1;
public:
- HeaderSearchOptions(llvm::StringRef _Sysroot = "")
- : Sysroot(_Sysroot), UseStandardIncludes(true) {}
+ HeaderSearchOptions(llvm::StringRef _Sysroot = "/")
+ : Sysroot(_Sysroot), UseStandardIncludes(true), Verbose(false) {}
/// AddPath - Add the \arg Path path to the specified \arg Group list.
void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
diff --git a/include/clang/Frontend/InitHeaderSearch.h b/include/clang/Frontend/InitHeaderSearch.h
deleted file mode 100644
index 48c426825262..000000000000
--- a/include/clang/Frontend/InitHeaderSearch.h
+++ /dev/null
@@ -1,98 +0,0 @@
-//===--- InitHeaderSearch.h - Initialize header search paths ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the InitHeaderSearch class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_INIT_HEADER_SEARCH_H_
-#define LLVM_CLANG_FRONTEND_INIT_HEADER_SEARCH_H_
-
-#include "clang/Lex/DirectoryLookup.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include <string>
-#include <vector>
-
-namespace clang {
-
-class HeaderSearch;
-class LangOptions;
-
-/// InitHeaderSearch - This class makes it easier to set the search paths of
-/// a HeaderSearch object. InitHeaderSearch stores several search path lists
-/// internally, which can be sent to a HeaderSearch object in one swoop.
-class InitHeaderSearch {
- std::vector<DirectoryLookup> IncludeGroup[4];
- HeaderSearch& Headers;
- bool Verbose;
- std::string isysroot;
-
-public:
- /// InitHeaderSearch::IncludeDirGroup - Identifies the several search path
- /// lists stored internally.
- enum IncludeDirGroup {
- Quoted = 0, //< `#include ""` paths. Thing `gcc -iquote`.
- Angled, //< Paths for both `#include ""` and `#include <>`. (`-I`)
- System, //< Like Angled, but marks system directories.
- After //< Like System, but searched after the system directories.
- };
-
- InitHeaderSearch(HeaderSearch &HS,
- bool verbose = false, const std::string &iSysroot = "")
- : Headers(HS), Verbose(verbose), isysroot(iSysroot) {}
-
- /// AddPath - Add the specified path to the specified group list.
- void AddPath(const llvm::StringRef &Path, IncludeDirGroup Group,
- bool isCXXAware, bool isUserSupplied,
- bool isFramework, bool IgnoreSysRoot = false);
-
- /// AddEnvVarPaths - Add a list of paths from an environment variable to a
- /// header search list.
- void AddEnvVarPaths(const char *Name);
-
- /// AddGnuCPlusPlusIncludePaths - Add the necessary paths to suport a gnu
- /// libstdc++.
- void AddGnuCPlusPlusIncludePaths(const std::string &Base, const char *Dir32,
- const char *Dir64,
- const llvm::Triple &triple);
-
- /// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to suport a MinGW
- /// libstdc++.
- void AddMinGWCPlusPlusIncludePaths(const std::string &Base,
- const char *Arch,
- const char *Version);
-
- /// AddDefaultEnvVarPaths - Adds list of paths from default environment
- /// variables such as CPATH.
- void AddDefaultEnvVarPaths(const LangOptions &Lang);
-
- // AddDefaultCIncludePaths - Add paths that should always be searched.
- void AddDefaultCIncludePaths(const llvm::Triple &triple);
-
- // AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when
- // compiling c++.
- void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple);
-
- // AddDefaultFrameworkIncludePaths - Add the framework paths. Used on darwin.
- void AddDefaultFrameworkIncludePaths(const llvm::Triple &triple);
-
- /// AddDefaultSystemIncludePaths - Adds the default system include paths so
- /// that e.g. stdio.h is found.
- void AddDefaultSystemIncludePaths(const LangOptions &Lang,
- const llvm::Triple &triple);
-
- /// Realize - Merges all search path lists into one list and send it to
- /// HeaderSearch.
- void Realize();
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/InitPreprocessor.h b/include/clang/Frontend/InitPreprocessor.h
deleted file mode 100644
index 415acea79a26..000000000000
--- a/include/clang/Frontend/InitPreprocessor.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===--- InitPreprocessor.h - InitializePreprocessor function. --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the clang::InitializePreprocessor function.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_INIT_PREPROCESSOR_H_
-#define LLVM_CLANG_FRONTEND_INIT_PREPROCESSOR_H_
-
-#include <string>
-#include <vector>
-
-namespace clang {
-
-class Preprocessor;
-class LangOptions;
-
-/// PreprocessorInitOptions - This class is used for passing the various
-/// options used in preprocessor initialization to InitializePreprocessor().
-class PreprocessorInitOptions {
- std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
- std::vector<std::pair<std::string, bool/*isPTH*/> > Includes;
- std::vector<std::string> MacroIncludes;
-
- unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
- /// and target specific predefines.
-
-public:
- PreprocessorInitOptions() : UsePredefines(true) {}
-
- bool getUsePredefines() const { return UsePredefines; }
- void setUsePredefines(bool Value) {
- UsePredefines = Value;
- }
-
- void addMacroDef(const std::string &Name) {
- Macros.push_back(std::make_pair(Name, false));
- }
- void addMacroUndef(const std::string &Name) {
- Macros.push_back(std::make_pair(Name, true));
- }
- void addInclude(const std::string &Name, bool isPTH = false) {
- Includes.push_back(std::make_pair(Name, isPTH));
- }
- void addMacroInclude(const std::string &Name) {
- MacroIncludes.push_back(Name);
- }
-
- typedef std::vector<std::pair<std::string,
- bool> >::const_iterator macro_iterator;
- macro_iterator macro_begin() const { return Macros.begin(); }
- macro_iterator macro_end() const { return Macros.end(); }
-
- typedef std::vector<std::pair<std::string,
- bool> >::const_iterator include_iterator;
- include_iterator include_begin() const { return Includes.begin(); }
- include_iterator include_end() const { return Includes.end(); }
-
- typedef std::vector<std::string>::const_iterator imacro_iterator;
- imacro_iterator imacro_begin() const { return MacroIncludes.begin(); }
- imacro_iterator imacro_end() const { return MacroIncludes.end(); }
-};
-
-/// InitializePreprocessor - Initialize the preprocessor getting it and the
-/// environment ready to process a single file.
-///
-void InitializePreprocessor(Preprocessor &PP,
- const PreprocessorInitOptions& InitOptions);
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Frontend/ManagerRegistry.h b/include/clang/Frontend/ManagerRegistry.h
deleted file mode 100644
index f05cfe6df6b8..000000000000
--- a/include/clang/Frontend/ManagerRegistry.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===-- ManagerRegistry.h - Pluggable analyzer module registry --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ManagerRegistry and Register* classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_FRONTEND_MANAGER_REGISTRY_H
-#define LLVM_CLANG_FRONTEND_MANAGER_REGISTRY_H
-
-#include "clang/Analysis/PathSensitive/GRState.h"
-
-namespace clang {
-
-/// ManagerRegistry - This class records manager creators registered at
-/// runtime. The information is communicated to AnalysisManager through static
-/// members. Better design is expected.
-
-class ManagerRegistry {
-public:
- static StoreManagerCreator StoreMgrCreator;
- static ConstraintManagerCreator ConstraintMgrCreator;
-};
-
-/// RegisterConstraintManager - This class is used to setup the constraint
-/// manager of the static analyzer. The constructor takes a creator function
-/// pointer for creating the constraint manager.
-///
-/// It is used like this:
-///
-/// class MyConstraintManager {};
-/// ConstraintManager* CreateMyConstraintManager(GRStateManager& statemgr) {
-/// return new MyConstraintManager(statemgr);
-/// }
-/// RegisterConstraintManager X(CreateMyConstraintManager);
-
-class RegisterConstraintManager {
-public:
- RegisterConstraintManager(ConstraintManagerCreator CMC) {
- assert(ManagerRegistry::ConstraintMgrCreator == 0
- && "ConstraintMgrCreator already set!");
- ManagerRegistry::ConstraintMgrCreator = CMC;
- }
-};
-
-}
-#endif
diff --git a/include/clang/Makefile b/include/clang/Makefile
index 82a16d53ea33..624292a128ee 100644
--- a/include/clang/Makefile
+++ b/include/clang/Makefile
@@ -1,4 +1,4 @@
LEVEL = ../../../..
-DIRS := Basic
+DIRS := Basic Driver
include $(LEVEL)/Makefile.common
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index a9b32133234a..3d3232b6f68e 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -2329,29 +2329,75 @@ public:
/// found after the left paren.
///
/// \param S the scope in which the operator keyword occurs.
- virtual void CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS) { }
-
+ virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { }
+
+ /// \brief Code completion for the getter of an Objective-C property
+ /// declaration.
+ ///
+ /// This code completion action is invoked when the code-completion
+ /// token is found after the "getter = " in a property declaration.
+ ///
+ /// \param S the scope in which the property is being declared.
+ ///
+ /// \param ClassDecl the Objective-C class or category in which the property
+ /// is being defined.
+ ///
+ /// \param Methods the set of methods declared thus far within \p ClassDecl.
+ ///
+ /// \param NumMethods the number of methods in \p Methods
+ virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods) {
+ }
+
+ /// \brief Code completion for the setter of an Objective-C property
+ /// declaration.
+ ///
+ /// This code completion action is invoked when the code-completion
+ /// token is found after the "setter = " in a property declaration.
+ ///
+ /// \param S the scope in which the property is being declared.
+ ///
+ /// \param ClassDecl the Objective-C class or category in which the property
+ /// is being defined.
+ ///
+ /// \param Methods the set of methods declared thus far within \p ClassDecl.
+ ///
+ /// \param NumMethods the number of methods in \p Methods
+ virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods) {
+ }
+
/// \brief Code completion for an ObjC message expression that refers to
/// a class method.
///
/// This code completion action is invoked when the code-completion token is
- /// found after the class name.
+ /// found after the class name and after each argument.
///
/// \param S the scope in which the message expression occurs.
/// \param FName the factory name.
/// \param FNameLoc the source location of the factory name.
+ /// \param SelIdents the identifiers that describe the selector (thus far).
+ /// \param NumSelIdents the number of identifiers in \p SelIdents.
virtual void CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
- SourceLocation FNameLoc){ }
+ SourceLocation FNameLoc,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents){ }
/// \brief Code completion for an ObjC message expression that refers to
/// an instance method.
///
/// This code completion action is invoked when the code-completion token is
- /// found after the receiver expression.
+ /// found after the receiver expression and after each argument.
///
/// \param S the scope in which the operator keyword occurs.
/// \param Receiver an expression for the receiver of the message.
- virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) { }
+ /// \param SelIdents the identifiers that describe the selector (thus far).
+ /// \param NumSelIdents the number of identifiers in \p SelIdents.
+ virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) { }
/// \brief Code completion for a list of protocol references in Objective-C,
/// such as P1 and P2 in \c id<P1,P2>.
@@ -2371,6 +2417,61 @@ public:
///
/// \param S the scope in which the protocol declaration occurs.
virtual void CodeCompleteObjCProtocolDecl(Scope *S) { }
+
+ /// \brief Code completion for an Objective-C interface, after the
+ /// @interface but before any identifier.
+ virtual void CodeCompleteObjCInterfaceDecl(Scope *S) { }
+
+ /// \brief Code completion for the superclass of an Objective-C
+ /// interface, after the ':'.
+ ///
+ /// \param S the scope in which the interface declaration occurs.
+ ///
+ /// \param ClassName the name of the class being defined.
+ virtual void CodeCompleteObjCSuperclass(Scope *S,
+ IdentifierInfo *ClassName) {
+ }
+
+ /// \brief Code completion for an Objective-C implementation, after the
+ /// @implementation but before any identifier.
+ virtual void CodeCompleteObjCImplementationDecl(Scope *S) { }
+
+ /// \brief Code completion for the category name in an Objective-C interface
+ /// declaration.
+ ///
+ /// This code completion action is invoked after the '(' that indicates
+ /// a category name within an Objective-C interface declaration.
+ virtual void CodeCompleteObjCInterfaceCategory(Scope *S,
+ IdentifierInfo *ClassName) {
+ }
+
+ /// \brief Code completion for the category name in an Objective-C category
+ /// implementation.
+ ///
+ /// This code completion action is invoked after the '(' that indicates
+ /// the category name within an Objective-C category implementation.
+ virtual void CodeCompleteObjCImplementationCategory(Scope *S,
+ IdentifierInfo *ClassName) {
+ }
+
+ /// \brief Code completion for the property names when defining an
+ /// Objective-C property.
+ ///
+ /// This code completion action is invoked after @synthesize or @dynamic and
+ /// after each "," within one of those definitions.
+ virtual void CodeCompleteObjCPropertyDefinition(Scope *S,
+ DeclPtrTy ObjCImpDecl) {
+ }
+
+ /// \brief Code completion for the instance variable name that should
+ /// follow an '=' when synthesizing an Objective-C property.
+ ///
+ /// This code completion action is invoked after each '=' that occurs within
+ /// an @synthesized definition.
+ virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
+ IdentifierInfo *PropertyName,
+ DeclPtrTy ObjCImpDecl) {
+ }
//@}
};
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index e7dabdbd5b66..f7ccccac0952 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -810,7 +810,8 @@ private:
DeclPtrTy ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
DeclPtrTy classDecl,
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
- void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
+ void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods, unsigned NumMethods);
DeclPtrTy ParseObjCMethodDefinition();
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 43ff6869184d..ed747613c385 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -123,6 +123,9 @@ public:
/// \brief Create a new current-parameter chunk.
static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter);
+ /// \brief Clone the given chunk.
+ Chunk Clone() const;
+
/// \brief Destroy this chunk, deallocating any memory it owns.
void Destroy();
};
@@ -192,15 +195,21 @@ public:
/// \brief Add a new chunk.
void AddChunk(Chunk C) { Chunks.push_back(C); }
+ /// \brief Returns the text in the TypedText chunk.
+ const char *getTypedText() const;
+
/// \brief Retrieve a string representation of the code completion string,
/// which is mainly useful for debugging.
std::string getAsString() const;
+ /// \brief Clone this code-completion string.
+ CodeCompletionString *Clone() const;
+
/// \brief Serialize this code-completion string to the given stream.
void Serialize(llvm::raw_ostream &OS) const;
/// \brief Deserialize a code-completion string from the given string.
- static CodeCompletionString *Deserialize(llvm::StringRef &Str);
+ static CodeCompletionString *Deserialize(llvm::StringRef &Str);
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
@@ -220,7 +229,8 @@ public:
enum ResultKind {
RK_Declaration = 0, //< Refers to a declaration
RK_Keyword, //< Refers to a keyword or symbol.
- RK_Macro //< Refers to a macro
+ RK_Macro, //< Refers to a macro
+ RK_Pattern //< Refers to a precomputed pattern.
};
/// \brief The kind of result stored here.
@@ -235,6 +245,10 @@ public:
/// or symbol's spelling.
const char *Keyword;
+ /// \brief When Kind == RK_Pattern, the code-completion string that
+ /// describes the completion text to insert.
+ CodeCompletionString *Pattern;
+
/// \brief When Kind == RK_Macro, the identifier that refers to a macro.
IdentifierInfo *Macro;
};
@@ -243,6 +257,10 @@ public:
/// result and progressively higher numbers representing poorer results.
unsigned Rank;
+ /// \brief Specifiers which parameter (of a function, Objective-C method,
+ /// macro, etc.) we should start with when formatting the result.
+ unsigned StartParameter;
+
/// \brief Whether this result is hidden by another name.
bool Hidden : 1;
@@ -252,7 +270,11 @@ public:
/// \brief Whether this declaration is the beginning of a
/// nested-name-specifier and, therefore, should be followed by '::'.
bool StartsNestedNameSpecifier : 1;
-
+
+ /// \brief Whether all parameters (of a function, Objective-C
+ /// method, etc.) should be considered "informative".
+ bool AllParametersAreInformative : 1;
+
/// \brief If the result should have a nested-name-specifier, this is it.
/// When \c QualifierIsInformative, the nested-name-specifier is
/// informative rather than required.
@@ -263,20 +285,31 @@ public:
NestedNameSpecifier *Qualifier = 0,
bool QualifierIsInformative = false)
: Kind(RK_Declaration), Declaration(Declaration), Rank(Rank),
- Hidden(false), QualifierIsInformative(QualifierIsInformative),
- StartsNestedNameSpecifier(false), Qualifier(Qualifier) { }
+ StartParameter(0), Hidden(false),
+ QualifierIsInformative(QualifierIsInformative),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ Qualifier(Qualifier) { }
/// \brief Build a result that refers to a keyword or symbol.
Result(const char *Keyword, unsigned Rank)
- : Kind(RK_Keyword), Keyword(Keyword), Rank(Rank), Hidden(false),
- QualifierIsInformative(0), StartsNestedNameSpecifier(false),
+ : Kind(RK_Keyword), Keyword(Keyword), Rank(Rank), StartParameter(0),
+ Hidden(false), QualifierIsInformative(0),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
Qualifier(0) { }
/// \brief Build a result that refers to a macro.
Result(IdentifierInfo *Macro, unsigned Rank)
- : Kind(RK_Macro), Macro(Macro), Rank(Rank), Hidden(false),
- QualifierIsInformative(0), StartsNestedNameSpecifier(false),
+ : Kind(RK_Macro), Macro(Macro), Rank(Rank), StartParameter(0),
+ Hidden(false), QualifierIsInformative(0),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
Qualifier(0) { }
+
+ /// \brief Build a result that refers to a pattern.
+ Result(CodeCompletionString *Pattern, unsigned Rank)
+ : Kind(RK_Pattern), Pattern(Pattern), Rank(Rank), StartParameter(0),
+ Hidden(false), QualifierIsInformative(0),
+ StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
+ Qualifier(0) { }
/// \brief Retrieve the declaration stored in this result.
NamedDecl *getDeclaration() const {
@@ -293,6 +326,8 @@ public:
/// \brief Create a new code-completion string that describes how to insert
/// this result into a program.
CodeCompletionString *CreateCodeCompletionString(Sema &S);
+
+ void Destroy();
};
class OverloadCandidate {
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 8f5cff4efafe..b1d30a68bbb7 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -603,8 +603,8 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
EmitBlock(AfterFor, true);
}
-/// GenerateCXXAggrDestructorHelper - Generates a helper function which when invoked,
-/// calls the default destructor on array elements in reverse order of
+/// GenerateCXXAggrDestructorHelper - Generates a helper function which when
+/// invoked, calls the default destructor on array elements in reverse order of
/// construction.
llvm::Constant *
CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 1d2040bae203..349ede51c63b 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -611,4 +611,3 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg) {
DI->EmitDeclareOfArgVariable(&D, DeclPtr, Builder);
}
}
-
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 8e0864b8dd83..a63c8325ffa7 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -345,6 +345,11 @@ static const CXXMethodDecl *GetKeyFunction(const RecordDecl *D) {
if (MD->isPure())
continue;
+ // FIXME: This doesn't work. If we have an out of line body, that body will
+ // set the MD to have a body, what we want to know is, was the body present
+ // inside the declaration of the class. For now, we just avoid the problem
+ // by pretending there is no key function.
+ return 0;
if (MD->getBody())
continue;
diff --git a/lib/CodeGen/CGRtti.cpp b/lib/CodeGen/CGRtti.cpp
index e18843d5cf3f..79d866427f0b 100644
--- a/lib/CodeGen/CGRtti.cpp
+++ b/lib/CodeGen/CGRtti.cpp
@@ -47,21 +47,35 @@ public:
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
}
- llvm::Constant *BuildName(QualType Ty, bool Hidden) {
+ llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRttiName(CGM.getMangleContext(), Ty, Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable::LinkageTypes linktype;
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
+ if (!Extern)
+ linktype = llvm::GlobalValue::InternalLinkage;
+
+ llvm::GlobalVariable *GV;
+ GV = CGM.getModule().getGlobalVariable(Name);
+ if (GV && !GV->isDeclaration())
+ return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
llvm::Constant *C;
- C = llvm::ConstantArray::get(VMContext, Out.str().substr(4));
+ C = llvm::ConstantArray::get(VMContext, Name.substr(4));
- llvm::GlobalVariable * GV = new llvm::GlobalVariable(CGM.getModule(),
- C->getType(),
- true, linktype, C,
- Out.str());
+ llvm::GlobalVariable *OGV = GV;
+ GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
+ C, Name);
+ if (OGV) {
+ GV->takeName(OGV);
+ llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
+ OGV->getType());
+ OGV->replaceAllUsesWith(NewPtr);
+ OGV->eraseFromParent();
+ }
if (Hidden)
GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
@@ -87,8 +101,9 @@ public:
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
+ llvm::StringRef Name = Out.str();
- C = CGM.getModule().getGlobalVariable(Out.str());
+ C = CGM.getModule().getGlobalVariable(Name);
if (C)
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
@@ -96,7 +111,7 @@ public:
linktype = llvm::GlobalValue::ExternalLinkage;;
C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
- 0, Out.str());
+ 0, Name);
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
}
@@ -147,20 +162,19 @@ public:
llvm::Constant *finish(std::vector<llvm::Constant *> &info,
llvm::GlobalVariable *GV,
- llvm::StringRef Name, bool Hidden) {
+ llvm::StringRef Name, bool Hidden, bool Extern) {
llvm::GlobalVariable::LinkageTypes linktype;
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
+ if (!Extern)
+ linktype = llvm::GlobalValue::InternalLinkage;
llvm::Constant *C;
C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
- if (GV == 0)
- GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
- linktype, C, Name);
- else {
- llvm::GlobalVariable *OGV = GV;
- GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
- linktype, C, Name);
+ llvm::GlobalVariable *OGV = GV;
+ GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
+ C, Name);
+ if (OGV) {
GV->takeName(OGV);
llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
OGV->getType());
@@ -183,15 +197,17 @@ public:
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD),
Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable *GV;
- GV = CGM.getModule().getGlobalVariable(Out.str());
+ GV = CGM.getModule().getGlobalVariable(Name);
if (GV && !GV->isDeclaration())
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
std::vector<llvm::Constant *> info;
bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
+ bool Extern = !RD->isInAnonymousNamespace();
bool simple = false;
if (RD->getNumBases() == 0)
@@ -202,7 +218,8 @@ public:
} else
C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
info.push_back(C);
- info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden));
+ info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
+ Extern));
// If we have no bases, there are no more fields.
if (RD->getNumBases()) {
@@ -235,7 +252,7 @@ public:
}
}
- return finish(info, GV, Out.str(), Hidden);
+ return finish(info, GV, Name, Hidden, Extern);
}
/// - BuildFlags - Build a __flags value for __pbase_type_info.
@@ -250,23 +267,49 @@ public:
return BuildType(Ty);
}
+ bool DecideExtern(QualType Ty) {
+ // For this type, see if all components are never in an anonymous namespace.
+ if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
+ return (DecideExtern(MPT->getPointeeType())
+ && DecideExtern(QualType(MPT->getClass(), 0)));
+ if (const PointerType *PT = Ty->getAs<PointerType>())
+ return DecideExtern(PT->getPointeeType());
+ if (const RecordType *RT = Ty->getAs<RecordType>())
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ return !RD->isInAnonymousNamespace();
+ return true;
+ }
+
+ bool DecideHidden(QualType Ty) {
+ // For this type, see if all components are never hidden.
+ if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
+ return (DecideHidden(MPT->getPointeeType())
+ && DecideHidden(QualType(MPT->getClass(), 0)));
+ if (const PointerType *PT = Ty->getAs<PointerType>())
+ return DecideHidden(PT->getPointeeType());
+ if (const RecordType *RT = Ty->getAs<RecordType>())
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
+ return false;
+ }
+
llvm::Constant *BuildPointerType(QualType Ty) {
llvm::Constant *C;
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable *GV;
- GV = CGM.getModule().getGlobalVariable(Out.str());
+ GV = CGM.getModule().getGlobalVariable(Name);
if (GV && !GV->isDeclaration())
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
std::vector<llvm::Constant *> info;
- // FIXME: pointer to hidden should be hidden, we should be able to
- // grab a bit off the type for this.
- bool Hidden = false;
+ bool Extern = DecideExtern(Ty);
+ bool Hidden = DecideHidden(Ty);
QualType PTy = Ty->getPointeeType();
QualType BTy;
@@ -282,7 +325,7 @@ public:
else
C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
info.push_back(C);
- info.push_back(BuildName(Ty, Hidden));
+ info.push_back(BuildName(Ty, Hidden, Extern));
Qualifiers Q = PTy.getQualifiers();
PTy = CGM.getContext().getCanonicalType(PTy).getUnqualifiedType();
int flags = 0;
@@ -300,7 +343,8 @@ public:
if (PtrMem)
info.push_back(BuildType2(BTy));
- return finish(info, GV, Out.str(), true);
+ // We always generate these as hidden, only the name isn't hidden.
+ return finish(info, GV, Name, true, Extern);
}
llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
@@ -309,23 +353,24 @@ public:
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable *GV;
- GV = CGM.getModule().getGlobalVariable(Out.str());
+ GV = CGM.getModule().getGlobalVariable(Name);
if (GV && !GV->isDeclaration())
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
std::vector<llvm::Constant *> info;
- // FIXME: pointer to hidden should be hidden, we should be able to
- // grab a bit off the type for this.
- bool Hidden = false;
+ bool Extern = DecideExtern(Ty);
+ bool Hidden = DecideHidden(Ty);
C = BuildVtableRef(vtbl);
info.push_back(C);
- info.push_back(BuildName(Ty, Hidden));
+ info.push_back(BuildName(Ty, Hidden, Extern));
- return finish(info, GV, Out.str(), true);
+ // We always generate these as hidden, only the name isn't hidden.
+ return finish(info, GV, Name, true, Extern);
}
llvm::Constant *BuildType(QualType Ty) {
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 4c97a9bdeebf..9be1a3b22b33 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -69,7 +69,6 @@ private:
llvm::DenseMap<CtorVtable_t, int64_t> &AddressPoints;
typedef CXXRecordDecl::method_iterator method_iter;
- // FIXME: Linkage should follow vtable
const bool Extern;
const uint32_t LLVMPointerWidth;
Index_t extra;
@@ -82,7 +81,7 @@ public:
BLayout(cgm.getContext().getASTRecordLayout(l)),
rtti(cgm.GenerateRttiRef(c)), VMContext(cgm.getModule().getContext()),
CGM(cgm), AddressPoints(*new llvm::DenseMap<CtorVtable_t, int64_t>),
- Extern(true),
+ Extern(!l->isInAnonymousNamespace()),
LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) {
Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
@@ -788,37 +787,73 @@ llvm::Constant *CodeGenModule::GenerateVtable(const CXXRecordDecl *LayoutClass,
mangleCXXCtorVtable(getMangleContext(), LayoutClass, Offset/8, RD, Out);
else
mangleCXXVtable(getMangleContext(), RD, Out);
+ llvm::StringRef Name = Out.str();
- llvm::GlobalVariable::LinkageTypes linktype;
- linktype = llvm::GlobalValue::LinkOnceODRLinkage;
std::vector<llvm::Constant *> methods;
llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
int64_t AddressPoint;
- VtableBuilder b(methods, RD, LayoutClass, Offset, *this);
+ llvm::GlobalVariable *GV = getModule().getGlobalVariable(Name);
+ if (GV && AddressPoints[LayoutClass] && !GV->isDeclaration())
+ AddressPoint=(*(*(AddressPoints[LayoutClass]))[RD])[std::make_pair(RD,
+ Offset)];
+ else {
+ VtableBuilder b(methods, RD, LayoutClass, Offset, *this);
- D1(printf("vtable %s\n", RD->getNameAsCString()));
- // First comes the vtables for all the non-virtual bases...
- AddressPoint = b.GenerateVtableForBase(RD, Offset);
+ D1(printf("vtable %s\n", RD->getNameAsCString()));
+ // First comes the vtables for all the non-virtual bases...
+ AddressPoint = b.GenerateVtableForBase(RD, Offset);
- // then the vtables for all the virtual bases.
- b.GenerateVtableForVBases(RD, Offset);
+ // then the vtables for all the virtual bases.
+ b.GenerateVtableForVBases(RD, Offset);
- CodeGenModule::AddrMap_t *&ref = AddressPoints[LayoutClass];
- if (ref == 0)
- ref = new CodeGenModule::AddrMap_t;
+ CodeGenModule::AddrMap_t *&ref = AddressPoints[LayoutClass];
+ if (ref == 0)
+ ref = new CodeGenModule::AddrMap_t;
- (*ref)[RD] = b.getAddressPoints();
+ (*ref)[RD] = b.getAddressPoints();
+
+ bool CreateDefinition = true;
+ if (LayoutClass != RD)
+ CreateDefinition = true;
+ else {
+ // We have to convert it to have a record layout.
+ Types.ConvertTagDeclType(LayoutClass);
+ const CGRecordLayout &CGLayout = Types.getCGRecordLayout(LayoutClass);
+ if (const CXXMethodDecl *KeyFunction = CGLayout.getKeyFunction()) {
+ if (!KeyFunction->getBody()) {
+ // If there is a KeyFunction, and it isn't defined, just build a
+ // reference to the vtable.
+ CreateDefinition = false;
+ }
+ }
+ }
- llvm::Constant *C;
- llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
- C = llvm::ConstantArray::get(type, methods);
- llvm::GlobalVariable *GV = new llvm::GlobalVariable(getModule(), type,
- true, linktype, C,
- Out.str());
- bool Hidden = getDeclVisibilityMode(RD) == LangOptions::Hidden;
- if (Hidden)
- GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
+ llvm::Constant *C = 0;
+ llvm::Type *type = Ptr8Ty;
+ llvm::GlobalVariable::LinkageTypes linktype
+ = llvm::GlobalValue::ExternalLinkage;
+ if (CreateDefinition) {
+ llvm::ArrayType *ntype = llvm::ArrayType::get(Ptr8Ty, methods.size());
+ C = llvm::ConstantArray::get(ntype, methods);
+ linktype = llvm::GlobalValue::LinkOnceODRLinkage;
+ if (LayoutClass->isInAnonymousNamespace())
+ linktype = llvm::GlobalValue::InternalLinkage;
+ type = ntype;
+ }
+ llvm::GlobalVariable *OGV = GV;
+ GV = new llvm::GlobalVariable(getModule(), type, true, linktype, C, Name);
+ if (OGV) {
+ GV->takeName(OGV);
+ llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
+ OGV->getType());
+ OGV->replaceAllUsesWith(NewPtr);
+ OGV->eraseFromParent();
+ }
+ bool Hidden = getDeclVisibilityMode(RD) == LangOptions::Hidden;
+ if (Hidden)
+ GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
+ }
llvm::Constant *vtable = llvm::ConstantExpr::getBitCast(GV, Ptr8Ty);
llvm::Constant *AddressPointC;
uint32_t LLVMPointerWidth = getContext().Target.getPointerWidth(0);
@@ -1001,9 +1036,12 @@ llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) {
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
mangleCXXVTT(getMangleContext(), RD, Out);
+ llvm::StringRef Name = Out.str();
llvm::GlobalVariable::LinkageTypes linktype;
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
+ if (RD->isInAnonymousNamespace())
+ linktype = llvm::GlobalValue::InternalLinkage;
std::vector<llvm::Constant *> inits;
llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
@@ -1015,20 +1053,41 @@ llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) {
llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, inits.size());
C = llvm::ConstantArray::get(type, inits);
llvm::GlobalVariable *vtt = new llvm::GlobalVariable(getModule(), type, true,
- linktype, C, Out.str());
+ linktype, C, Name);
bool Hidden = getDeclVisibilityMode(RD) == LangOptions::Hidden;
if (Hidden)
vtt->setVisibility(llvm::GlobalVariable::HiddenVisibility);
return llvm::ConstantExpr::getBitCast(vtt, Ptr8Ty);
}
+void CGVtableInfo::GenerateClassData(const CXXRecordDecl *RD) {
+ Vtables[RD] = CGM.GenerateVtable(RD, RD);
+ CGM.GenerateRtti(RD);
+ CGM.GenerateVTT(RD);
+}
+
llvm::Constant *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
llvm::Constant *&vtbl = Vtables[RD];
if (vtbl)
return vtbl;
vtbl = CGM.GenerateVtable(RD, RD);
- CGM.GenerateRtti(RD);
- CGM.GenerateVTT(RD);
+
+ bool CreateDefinition = true;
+ // We have to convert it to have a record layout.
+ CGM.getTypes().ConvertTagDeclType(RD);
+ const CGRecordLayout &CGLayout = CGM.getTypes().getCGRecordLayout(RD);
+ if (const CXXMethodDecl *KeyFunction = CGLayout.getKeyFunction()) {
+ if (!KeyFunction->getBody()) {
+ // If there is a KeyFunction, and it isn't defined, just build a
+ // reference to the vtable.
+ CreateDefinition = false;
+ }
+ }
+
+ if (CreateDefinition) {
+ CGM.GenerateRtti(RD);
+ CGM.GenerateVTT(RD);
+ }
return vtbl;
}
diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h
index f9ddf44284b1..78ae670cf35a 100644
--- a/lib/CodeGen/CGVtable.h
+++ b/lib/CodeGen/CGVtable.h
@@ -61,6 +61,10 @@ public:
llvm::Constant *getVtable(const CXXRecordDecl *RD);
llvm::Constant *getCtorVtable(const CXXRecordDecl *RD,
const CXXRecordDecl *Class, uint64_t Offset);
+ /// GenerateClassData - Generate all the class data requires to be generated
+ /// upon definition of a KeyFunction. This includes the vtable, the
+ /// rtti data structure and the VTT.
+ void GenerateClassData(const CXXRecordDecl *RD);
};
}
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 0e6f4a63a42c..195acc5bc157 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -616,6 +616,16 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
Context.getSourceManager(),
"Generating code for declaration");
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ const CXXRecordDecl *RD = MD->getParent();
+ // We have to convert it to have a record layout.
+ Types.ConvertTagDeclType(RD);
+ const CGRecordLayout &CGLayout = Types.getCGRecordLayout(RD);
+ // A definition of a KeyFunction, generates all the class data, such
+ // as vtable, rtti and the VTT.
+ if (CGLayout.getKeyFunction() == MD)
+ getVtableInfo().GenerateClassData(RD);
+ }
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
EmitCXXConstructor(CD, GD.getCtorType());
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 8d2138df85e8..ea75c34ea566 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -27,38 +27,41 @@ void ArgList::append(Arg *A) {
Args.push_back(A);
}
-Arg *ArgList::getLastArg(options::ID Id, bool Claim) const {
+Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
// FIXME: Make search efficient?
- for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) {
- if ((*it)->getOption().matches(Id)) {
- if (Claim) (*it)->claim();
+ for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
+ if ((*it)->getOption().matches(Id))
return *it;
- }
- }
-
return 0;
}
-Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
- Arg *Res, *A0 = getLastArg(Id0, false), *A1 = getLastArg(Id1, false);
+Arg *ArgList::getLastArg(OptSpecifier Id) const {
+ Arg *A = getLastArgNoClaim(Id);
+ if (A)
+ A->claim();
+ return A;
+}
+
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
+ Arg *Res, *A0 = getLastArgNoClaim(Id0), *A1 = getLastArgNoClaim(Id1);
if (A0 && A1)
Res = A0->getIndex() > A1->getIndex() ? A0 : A1;
else
Res = A0 ? A0 : A1;
- if (Claim && Res)
+ if (Res)
Res->claim();
return Res;
}
-Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
- bool Claim) const {
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
+ OptSpecifier Id2) const {
Arg *Res = 0;
- Arg *A0 = getLastArg(Id0, false);
- Arg *A1 = getLastArg(Id1, false);
- Arg *A2 = getLastArg(Id2, false);
+ Arg *A0 = getLastArgNoClaim(Id0);
+ Arg *A1 = getLastArgNoClaim(Id1);
+ Arg *A2 = getLastArgNoClaim(Id2);
int A0Idx = A0 ? A0->getIndex() : -1;
int A1Idx = A1 ? A1->getIndex() : -1;
@@ -76,26 +79,26 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
Res = A2;
}
- if (Claim && Res)
+ if (Res)
Res->claim();
return Res;
}
-bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
+bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
if (Arg *A = getLastArg(Pos, Neg))
return A->getOption().matches(Pos);
return Default;
}
-void ArgList::AddLastArg(ArgStringList &Output, options::ID Id) const {
+void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
if (Arg *A = getLastArg(Id)) {
A->claim();
A->render(*this, Output);
}
}
-void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const {
+void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const {
// FIXME: Make fast.
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
const Arg *A = *it;
@@ -106,8 +109,8 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const {
}
}
-void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
- options::ID Id1) const {
+void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1) const {
// FIXME: Make fast.
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
const Arg *A = *it;
@@ -118,8 +121,8 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
}
}
-void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
- options::ID Id1, options::ID Id2) const {
+void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1, OptSpecifier Id2) const {
// FIXME: Make fast.
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
const Arg *A = *it;
@@ -131,7 +134,7 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
}
}
-void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const {
+void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const {
// FIXME: Make fast.
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
const Arg *A = *it;
@@ -143,8 +146,8 @@ void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const {
}
}
-void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0,
- options::ID Id1) const {
+void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
+ OptSpecifier Id1) const {
// FIXME: Make fast.
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
const Arg *A = *it;
@@ -156,7 +159,7 @@ void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0,
}
}
-void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
+void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
const char *Translation,
bool Joined) const {
// FIXME: Make fast.
@@ -177,7 +180,7 @@ void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
}
}
-void ArgList::ClaimAllArgs(options::ID Id0) const {
+void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
// FIXME: Make fast.
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
const Arg *A = *it;
diff --git a/lib/Driver/CC1Options.cpp b/lib/Driver/CC1Options.cpp
new file mode 100644
index 000000000000..672fe0401e48
--- /dev/null
+++ b/lib/Driver/CC1Options.cpp
@@ -0,0 +1,43 @@
+//===--- CC1Options.cpp - Clang CC1 Options Table -----------------------*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/CC1Options.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
+
+using namespace clang::driver;
+using namespace clang::driver::options;
+using namespace clang::driver::cc1options;
+
+static OptTable::Info CC1InfoTable[] = {
+ // The InputOption info
+ { "<input>", 0, 0, Option::InputClass, DriverOption, 0, OPT_INVALID, OPT_INVALID },
+ // The UnknownOption info
+ { "<unknown>", 0, 0, Option::UnknownClass, 0, 0, OPT_INVALID, OPT_INVALID },
+
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR) \
+ { NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
+ OPT_##GROUP, OPT_##ALIAS },
+#include "clang/Driver/CC1Options.inc"
+};
+
+namespace {
+
+class CC1OptTable : public OptTable {
+public:
+ CC1OptTable()
+ : OptTable(CC1InfoTable, sizeof(CC1InfoTable) / sizeof(CC1InfoTable[0])) {}
+};
+
+}
+
+OptTable *clang::driver::createCC1OptTable() {
+ return new CC1OptTable();
+}
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index b6998abe4775..60d8e9c927f5 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -4,8 +4,10 @@ add_clang_library(clangDriver
Action.cpp
Arg.cpp
ArgList.cpp
+ CC1Options.cpp
Compilation.cpp
Driver.cpp
+ DriverOptions.cpp
HostInfo.cpp
Job.cpp
OptTable.cpp
@@ -18,4 +20,4 @@ add_clang_library(clangDriver
Types.cpp
)
-add_dependencies(clangDriver ClangDiagnosticDriver)
+add_dependencies(clangDriver ClangDiagnosticDriver ClangDriverOptions ClangCC1Options)
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index c12f5aa88195..ffa627ad2810 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -13,6 +13,7 @@
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
#include "clang/Driver/ToolChain.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index b4693f2ac986..b40dc27740d0 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -16,6 +16,7 @@
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/HostInfo.h"
#include "clang/Driver/Job.h"
+#include "clang/Driver/OptTable.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/Tool.h"
@@ -44,7 +45,7 @@ Driver::Driver(const char *_Name, const char *_Dir,
const char *_DefaultHostTriple,
const char *_DefaultImageName,
bool IsProduction, Diagnostic &_Diags)
- : Opts(new OptTable()), Diags(_Diags),
+ : Opts(createDriverOptTable()), Diags(_Diags),
Name(_Name), Dir(_Dir), DefaultHostTriple(_DefaultHostTriple),
DefaultImageName(_DefaultImageName),
Host(0),
@@ -75,40 +76,23 @@ Driver::~Driver() {
InputArgList *Driver::ParseArgStrings(const char **ArgBegin,
const char **ArgEnd) {
llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
- InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
+ unsigned MissingArgIndex, MissingArgCount;
+ InputArgList *Args = getOpts().ParseArgs(ArgBegin, ArgEnd,
+ MissingArgIndex, MissingArgCount);
- // FIXME: Handle '@' args (or at least error on them).
-
- unsigned Index = 0, End = ArgEnd - ArgBegin;
- while (Index < End) {
- // gcc's handling of empty arguments doesn't make sense, but this is not a
- // common use case. :)
- //
- // We just ignore them here (note that other things may still take them as
- // arguments).
- if (Args->getArgString(Index)[0] == '\0') {
- ++Index;
- continue;
- }
-
- unsigned Prev = Index;
- Arg *A = getOpts().ParseOneArg(*Args, Index);
- assert(Index > Prev && "Parser failed to consume argument.");
-
- // Check for missing argument error.
- if (!A) {
- assert(Index >= End && "Unexpected parser error.");
- Diag(clang::diag::err_drv_missing_argument)
- << Args->getArgString(Prev)
- << (Index - Prev - 1);
- break;
- }
+ // Check for missing argument error.
+ if (MissingArgCount)
+ Diag(clang::diag::err_drv_missing_argument)
+ << Args->getArgString(MissingArgIndex) << MissingArgCount;
+ // Check for unsupported options.
+ for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
+ it != ie; ++it) {
+ Arg *A = *it;
if (A->getOption().isUnsupported()) {
Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(*Args);
continue;
}
- Args->append(A);
}
return Args;
@@ -340,8 +324,8 @@ void Driver::PrintHelp(bool ShowHidden) const {
// Render help text into (option, help) pairs.
std::vector< std::pair<std::string, const char*> > OptionHelp;
- for (unsigned i = options::OPT_INPUT, e = options::LastOption; i != e; ++i) {
- options::ID Id = (options::ID) i;
+ for (unsigned i = 0, e = getOpts().getNumOptions(); i != e; ++i) {
+ options::ID Id = (options::ID) (i + 1);
if (const char *Text = getOpts().getOptionHelpText(Id))
OptionHelp.push_back(std::make_pair(getOptionHelpName(getOpts(), Id),
Text));
@@ -591,7 +575,7 @@ void Driver::BuildUniversalActions(const ArgList &Args,
it != ie; ++it) {
Arg *A = *it;
- if (A->getOption().getId() == options::OPT_arch) {
+ if (A->getOption().matches(options::OPT_arch)) {
// Validate the option here; we don't save the type here because its
// particular spelling may participate in other driver choices.
llvm::Triple::ArchType Arch =
@@ -686,7 +670,7 @@ void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const {
//
// Otherwise emit an error but still use a valid type to avoid
// spurious errors (e.g., no inputs).
- if (!Args.hasArg(options::OPT_E, false))
+ if (!Args.hasArgNoClaim(options::OPT_E))
Diag(clang::diag::err_drv_unknown_stdin_type);
Ty = types::TY_C;
} else {
@@ -730,7 +714,7 @@ void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const {
// necessary.
Inputs.push_back(std::make_pair(types::TY_Object, A));
- } else if (A->getOption().getId() == options::OPT_x) {
+ } else if (A->getOption().matches(options::OPT_x)) {
InputTypeArg = A;
InputType = types::lookupTypeForTypeSpecifier(A->getValue(Args));
@@ -984,7 +968,7 @@ void Driver::BuildJobs(Compilation &C) const {
// FIXME: Use iterator.
for (ArgList::const_iterator it = C.getArgs().begin(),
ie = C.getArgs().end(); it != ie; ++it) {
- if ((*it)->isClaimed() && (*it)->getOption().matches(Opt.getId())) {
+ if ((*it)->isClaimed() && (*it)->getOption().matches(&Opt)) {
DuplicateClaimed = true;
break;
}
diff --git a/lib/Driver/DriverOptions.cpp b/lib/Driver/DriverOptions.cpp
new file mode 100644
index 000000000000..eddaee0546cc
--- /dev/null
+++ b/lib/Driver/DriverOptions.cpp
@@ -0,0 +1,42 @@
+//===--- DriverOptions.cpp - Driver Options Table -----------------------*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Options.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
+
+using namespace clang::driver;
+using namespace clang::driver::options;
+
+static OptTable::Info InfoTable[] = {
+ // The InputOption info
+ { "<input>", 0, 0, Option::InputClass, DriverOption, 0, OPT_INVALID, OPT_INVALID },
+ // The UnknownOption info
+ { "<unknown>", 0, 0, Option::UnknownClass, 0, 0, OPT_INVALID, OPT_INVALID },
+
+#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR) \
+ { NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
+ OPT_##GROUP, OPT_##ALIAS },
+#include "clang/Driver/Options.inc"
+};
+
+namespace {
+
+class DriverOptTable : public OptTable {
+public:
+ DriverOptTable()
+ : OptTable(InfoTable, sizeof(InfoTable) / sizeof(InfoTable[0])) {}
+};
+
+}
+
+OptTable *clang::driver::createDriverOptTable() {
+ return new DriverOptTable();
+}
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
index 08c4ef490017..ed73b17d75f1 100644
--- a/lib/Driver/HostInfo.cpp
+++ b/lib/Driver/HostInfo.cpp
@@ -122,7 +122,7 @@ ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args,
//
// FIXME: Should this information be in llvm::Triple?
if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
- if (A->getOption().getId() == options::OPT_m32) {
+ if (A->getOption().matches(options::OPT_m32)) {
if (Arch == llvm::Triple::x86_64)
Arch = llvm::Triple::x86;
if (Arch == llvm::Triple::ppc64)
@@ -205,11 +205,11 @@ ToolChain *UnknownHostInfo::CreateToolChain(const ArgList &Args,
if (Triple.getArch() == llvm::Triple::x86 ||
Triple.getArch() == llvm::Triple::x86_64) {
ArchName =
- (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
+ (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
} else if (Triple.getArch() == llvm::Triple::ppc ||
Triple.getArch() == llvm::Triple::ppc64) {
ArchName =
- (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
+ (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
}
}
@@ -478,11 +478,11 @@ ToolChain *LinuxHostInfo::CreateToolChain(const ArgList &Args,
if (Triple.getArch() == llvm::Triple::x86 ||
Triple.getArch() == llvm::Triple::x86_64) {
ArchName =
- (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
+ (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
} else if (Triple.getArch() == llvm::Triple::ppc ||
Triple.getArch() == llvm::Triple::ppc64) {
ArchName =
- (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
+ (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
}
}
diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
index affd1c5aa9e5..f68a1d8db77c 100644
--- a/lib/Driver/OptTable.cpp
+++ b/lib/Driver/OptTable.cpp
@@ -1,4 +1,4 @@
-//===--- Options.cpp - Option info table --------------------------------*-===//
+//===--- OptTable.cpp - Option Table Implementation ---------------------*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,8 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Driver/Options.h"
-
+#include "clang/Driver/OptTable.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Option.h"
@@ -18,18 +17,6 @@
using namespace clang::driver;
using namespace clang::driver::options;
-struct Info {
- const char *Name;
- const char *Flags;
- const char *HelpText;
- const char *MetaVar;
-
- Option::OptionClass Kind;
- unsigned GroupID;
- unsigned AliasID;
- unsigned Param;
-};
-
// Ordering on Info. The ordering is *almost* lexicographic, with two
// exceptions. First, '\0' comes at the end of the alphabet instead of
// the beginning (thus options preceed any other options which prefix
@@ -56,7 +43,9 @@ static int StrCmpOptionName(const char *A, const char *B) {
return (a < b) ? -1 : 1;
}
-static inline bool operator<(const Info &A, const Info &B) {
+namespace clang {
+namespace driver {
+static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) {
if (&A == &B)
return false;
@@ -70,57 +59,62 @@ static inline bool operator<(const Info &A, const Info &B) {
return B.Kind == Option::JoinedClass;
}
+// Support lower_bound between info and an option name.
+static inline bool operator<(const OptTable::Info &I, const char *Name) {
+ return StrCmpOptionName(I.Name, Name) == -1;
+}
+static inline bool operator<(const char *Name, const OptTable::Info &I) {
+ return StrCmpOptionName(Name, I.Name) == -1;
+}
+}
+}
+
//
-static Info OptionInfos[] = {
- // The InputOption info
- { "<input>", "d", 0, 0, Option::InputClass, OPT_INVALID, OPT_INVALID, 0 },
- // The UnknownOption info
- { "<unknown>", "", 0, 0, Option::UnknownClass, OPT_INVALID, OPT_INVALID, 0 },
-
-#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
- HELPTEXT, METAVAR) \
- { NAME, FLAGS, HELPTEXT, METAVAR, \
- Option::KIND##Class, OPT_##GROUP, OPT_##ALIAS, PARAM },
-#include "clang/Driver/Options.def"
-};
-static const unsigned numOptions = sizeof(OptionInfos) / sizeof(OptionInfos[0]);
-
-static Info &getInfo(unsigned id) {
- assert(id > 0 && id - 1 < numOptions && "Invalid Option ID.");
- return OptionInfos[id - 1];
-}
+OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {}
-OptTable::OptTable() : Options(new Option*[numOptions]) {
+//
+
+OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
+ : OptionInfos(_OptionInfos), NumOptionInfos(_NumOptionInfos),
+ Options(new Option*[NumOptionInfos]),
+ TheInputOption(0), TheUnknownOption(0), FirstSearchableIndex(0)
+{
// Explicitly zero initialize the error to work around a bug in array
// value-initialization on MinGW with gcc 4.3.5.
- memset(Options, 0, sizeof(*Options) * numOptions);
+ memset(Options, 0, sizeof(*Options) * NumOptionInfos);
// Find start of normal options.
- FirstSearchableOption = 0;
- for (unsigned i = OPT_UNKNOWN + 1; i < LastOption; ++i) {
- if (getInfo(i).Kind != Option::GroupClass) {
- FirstSearchableOption = i;
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
+ unsigned Kind = getInfo(i + 1).Kind;
+ if (Kind == Option::InputClass) {
+ assert(!TheInputOption && "Cannot have multiple input options!");
+ TheInputOption = getOption(i + 1);
+ } else if (Kind == Option::UnknownClass) {
+ assert(!TheUnknownOption && "Cannot have multiple input options!");
+ TheUnknownOption = getOption(i + 1);
+ } else if (Kind != Option::GroupClass) {
+ FirstSearchableIndex = i;
break;
}
}
- assert(FirstSearchableOption != 0 && "No searchable options?");
+ assert(FirstSearchableIndex != 0 && "No searchable options?");
#ifndef NDEBUG
// Check that everything after the first searchable option is a
// regular option class.
- for (unsigned i = FirstSearchableOption; i < LastOption; ++i) {
- Option::OptionClass Kind = getInfo(i).Kind;
+ for (unsigned i = FirstSearchableIndex, e = getNumOptions(); i != e; ++i) {
+ Option::OptionClass Kind = (Option::OptionClass) getInfo(i + 1).Kind;
assert((Kind != Option::InputClass && Kind != Option::UnknownClass &&
Kind != Option::GroupClass) &&
"Special options should be defined first!");
}
// Check that options are in order.
- for (unsigned i = FirstSearchableOption + 1; i < LastOption; ++i) {
- if (!(getInfo(i - 1) < getInfo(i))) {
- getOption((options::ID) (i - 1))->dump();
- getOption((options::ID) i)->dump();
+ for (unsigned i = FirstSearchableIndex+1, e = getNumOptions(); i != e; ++i) {
+ if (!(getInfo(i) < getInfo(i + 1))) {
+ getOption(i)->dump();
+ getOption(i + 1)->dump();
assert(0 && "Options are not in order!");
}
}
@@ -128,56 +122,23 @@ OptTable::OptTable() : Options(new Option*[numOptions]) {
}
OptTable::~OptTable() {
- for (unsigned i = 0; i < numOptions; ++i)
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
delete Options[i];
delete[] Options;
}
-unsigned OptTable::getNumOptions() const {
- return numOptions;
-}
-
-const char *OptTable::getOptionName(options::ID id) const {
- return getInfo(id).Name;
-}
-
-unsigned OptTable::getOptionKind(options::ID id) const {
- return getInfo(id).Kind;
-}
-
-const char *OptTable::getOptionHelpText(options::ID id) const {
- return getInfo(id).HelpText;
-}
-
-const char *OptTable::getOptionMetaVar(options::ID id) const {
- return getInfo(id).MetaVar;
-}
-
-const Option *OptTable::getOption(options::ID id) const {
- if (id == OPT_INVALID)
- return 0;
-
- assert((unsigned) (id - 1) < numOptions && "Invalid ID.");
-
- Option *&Entry = Options[id - 1];
- if (!Entry)
- Entry = constructOption(id);
-
- return Entry;
-}
-
-Option *OptTable::constructOption(options::ID id) const {
- Info &info = getInfo(id);
+Option *OptTable::CreateOption(unsigned id) const {
+ const Info &info = getInfo(id);
const OptionGroup *Group =
- cast_or_null<OptionGroup>(getOption((options::ID) info.GroupID));
- const Option *Alias = getOption((options::ID) info.AliasID);
+ cast_or_null<OptionGroup>(getOption(info.GroupID));
+ const Option *Alias = getOption(info.AliasID);
Option *Opt = 0;
switch (info.Kind) {
case Option::InputClass:
- Opt = new InputOption(); break;
+ Opt = new InputOption(id); break;
case Option::UnknownClass:
- Opt = new UnknownOption(); break;
+ Opt = new UnknownOption(id); break;
case Option::GroupClass:
Opt = new OptionGroup(id, info.Name, Group); break;
case Option::FlagClass:
@@ -196,44 +157,38 @@ Option *OptTable::constructOption(options::ID id) const {
Opt = new JoinedAndSeparateOption(id, info.Name, Group, Alias); break;
}
- for (const char *s = info.Flags; *s; ++s) {
- switch (*s) {
- default: assert(0 && "Invalid option flag.");
- case 'J':
- assert(info.Kind == Option::SeparateClass && "Invalid option.");
- Opt->setForceJoinedRender(true); break;
- case 'S':
- assert(info.Kind == Option::JoinedClass && "Invalid option.");
- Opt->setForceSeparateRender(true); break;
- case 'd': Opt->setDriverOption(true); break;
- case 'i': Opt->setNoOptAsInput(true); break;
- case 'l': Opt->setLinkerInput(true); break;
- case 'q': Opt->setNoArgumentUnused(true); break;
- case 'u': Opt->setUnsupported(true); break;
- }
+ if (info.Flags & DriverOption)
+ Opt->setDriverOption(true);
+ if (info.Flags & LinkerInput)
+ Opt->setLinkerInput(true);
+ if (info.Flags & NoArgumentUnused)
+ Opt->setNoArgumentUnused(true);
+ if (info.Flags & RenderAsInput)
+ Opt->setNoOptAsInput(true);
+ if (info.Flags & RenderJoined) {
+ assert(info.Kind == Option::SeparateClass && "Invalid option.");
+ Opt->setForceJoinedRender(true);
}
+ if (info.Flags & RenderSeparate) {
+ assert(info.Kind == Option::JoinedClass && "Invalid option.");
+ Opt->setForceSeparateRender(true);
+ }
+ if (info.Flags & Unsupported)
+ Opt->setUnsupported(true);
return Opt;
}
-// Support lower_bound between info and an option name.
-static inline bool operator<(struct Info &I, const char *Name) {
- return StrCmpOptionName(I.Name, Name) == -1;
-}
-static inline bool operator<(const char *Name, struct Info &I) {
- return StrCmpOptionName(Name, I.Name) == -1;
-}
-
Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
unsigned Prev = Index;
const char *Str = Args.getArgString(Index);
// Anything that doesn't start with '-' is an input, as is '-' itself.
if (Str[0] != '-' || Str[1] == '\0')
- return new PositionalArg(getOption(OPT_INPUT), Index++);
+ return new PositionalArg(TheInputOption, Index++);
- struct Info *Start = OptionInfos + FirstSearchableOption - 1;
- struct Info *End = OptionInfos + LastOption - 1;
+ const Info *Start = OptionInfos + FirstSearchableIndex;
+ const Info *End = OptionInfos + getNumOptions();
// Search for the first next option which could be a prefix.
Start = std::lower_bound(Start, End, Str);
@@ -255,8 +210,7 @@ Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
break;
// See if this option matches.
- options::ID id = (options::ID) (Start - OptionInfos + 1);
- if (Arg *A = getOption(id)->accept(Args, Index))
+ if (Arg *A = getOption(Start - OptionInfos + 1)->accept(Args, Index))
return A;
// Otherwise, see if this argument was missing values.
@@ -264,6 +218,40 @@ Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
return 0;
}
- return new PositionalArg(getOption(OPT_UNKNOWN), Index++);
+ return new PositionalArg(TheUnknownOption, Index++);
}
+InputArgList *OptTable::ParseArgs(const char **ArgBegin, const char **ArgEnd,
+ unsigned &MissingArgIndex,
+ unsigned &MissingArgCount) const {
+ InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
+
+ // FIXME: Handle '@' args (or at least error on them).
+
+ MissingArgIndex = MissingArgCount = 0;
+ unsigned Index = 0, End = ArgEnd - ArgBegin;
+ while (Index < End) {
+ // Ignore empty arguments (other things may still take them as arguments).
+ if (Args->getArgString(Index)[0] == '\0') {
+ ++Index;
+ continue;
+ }
+
+ unsigned Prev = Index;
+ Arg *A = ParseOneArg(*Args, Index);
+ assert(Index > Prev && "Parser failed to consume argument.");
+
+ // Check for missing argument error.
+ if (!A) {
+ assert(Index >= End && "Unexpected parser error.");
+ assert(Index - Prev - 1 && "No missing arguments!");
+ MissingArgIndex = Prev;
+ MissingArgCount = Index - Prev - 1;
+ break;
+ }
+
+ Args->append(A);
+ }
+
+ return Args;
+}
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
index c2ace05aa4d1..17d00f50aa6f 100644
--- a/lib/Driver/Option.cpp
+++ b/lib/Driver/Option.cpp
@@ -16,9 +16,9 @@
#include <algorithm>
using namespace clang::driver;
-Option::Option(OptionClass _Kind, options::ID _ID, const char *_Name,
+Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
const OptionGroup *_Group, const Option *_Alias)
- : Kind(_Kind), ID(_ID), Name(_Name), Group(_Group), Alias(_Alias),
+ : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
Unsupported(false), LinkerInput(false), NoOptAsInput(false),
ForceSeparateRender(false), ForceJoinedRender(false),
DriverOption(false), NoArgumentUnused(false) {
@@ -70,14 +70,13 @@ void Option::dump() const {
llvm::errs() << ">\n";
}
-bool Option::matches(const Option *Opt) const {
- // Aliases are never considered in matching.
- if (Opt->getAlias())
- return matches(Opt->getAlias());
+bool Option::matches(OptSpecifier Opt) const {
+ // Aliases are never considered in matching, look through them.
if (Alias)
return Alias->matches(Opt);
- if (this == Opt)
+ // Check exact match.
+ if (ID == Opt)
return true;
if (Group)
@@ -85,23 +84,7 @@ bool Option::matches(const Option *Opt) const {
return false;
}
-bool Option::matches(options::ID Id) const {
- // FIXME: Decide what to do here; we should either pull out the
- // handling of alias on the option for Id from the other matches, or
- // find some other solution (which hopefully doesn't require using
- // the option table).
- if (Alias)
- return Alias->matches(Id);
-
- if (ID == Id)
- return true;
-
- if (Group)
- return Group->matches(Id);
- return false;
-}
-
-OptionGroup::OptionGroup(options::ID ID, const char *Name,
+OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
const OptionGroup *Group)
: Option(Option::GroupClass, ID, Name, Group, 0) {
}
@@ -111,8 +94,8 @@ Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const {
return 0;
}
-InputOption::InputOption()
- : Option(Option::InputClass, options::OPT_INPUT, "<input>", 0, 0) {
+InputOption::InputOption(OptSpecifier ID)
+ : Option(Option::InputClass, ID, "<input>", 0, 0) {
}
Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
@@ -120,8 +103,8 @@ Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
return 0;
}
-UnknownOption::UnknownOption()
- : Option(Option::UnknownClass, options::OPT_UNKNOWN, "<unknown>", 0, 0) {
+UnknownOption::UnknownOption(OptSpecifier ID)
+ : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
}
Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
@@ -129,7 +112,7 @@ Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
return 0;
}
-FlagOption::FlagOption(options::ID ID, const char *Name,
+FlagOption::FlagOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias)
: Option(Option::FlagClass, ID, Name, Group, Alias) {
}
@@ -143,7 +126,7 @@ Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const {
return new FlagArg(this, Index++);
}
-JoinedOption::JoinedOption(options::ID ID, const char *Name,
+JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias)
: Option(Option::JoinedClass, ID, Name, Group, Alias) {
}
@@ -153,7 +136,7 @@ Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
return new JoinedArg(this, Index++);
}
-CommaJoinedOption::CommaJoinedOption(options::ID ID, const char *Name,
+CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group,
const Option *Alias)
: Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
@@ -170,7 +153,7 @@ Arg *CommaJoinedOption::accept(const InputArgList &Args,
return new CommaJoinedArg(this, Index++, Suffix);
}
-SeparateOption::SeparateOption(options::ID ID, const char *Name,
+SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias)
: Option(Option::SeparateClass, ID, Name, Group, Alias) {
}
@@ -188,7 +171,7 @@ Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const {
return new SeparateArg(this, Index - 2, 1);
}
-MultiArgOption::MultiArgOption(options::ID ID, const char *Name,
+MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group, const Option *Alias,
unsigned _NumArgs)
: Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
@@ -208,7 +191,7 @@ Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const {
return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
}
-JoinedOrSeparateOption::JoinedOrSeparateOption(options::ID ID, const char *Name,
+JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
const OptionGroup *Group,
const Option *Alias)
: Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
@@ -229,7 +212,7 @@ Arg *JoinedOrSeparateOption::accept(const InputArgList &Args,
return new SeparateArg(this, Index - 2, 1);
}
-JoinedAndSeparateOption::JoinedAndSeparateOption(options::ID ID,
+JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
const char *Name,
const OptionGroup *Group,
const Option *Alias)
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index ae8119d33d64..af639523f1d7 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -14,7 +14,9 @@
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/HostInfo.h"
+#include "clang/Driver/OptTable.h"
#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
@@ -303,9 +305,9 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
// and try to push it down into tool specific logic.
Arg *OSXVersion =
- Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false);
+ Args.getLastArgNoClaim(options::OPT_mmacosx_version_min_EQ);
Arg *iPhoneVersion =
- Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false);
+ Args.getLastArgNoClaim(options::OPT_miphoneos_version_min_EQ);
if (OSXVersion && iPhoneVersion) {
getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
<< OSXVersion->getAsString(Args)
@@ -365,8 +367,7 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
// Sob. These is strictly gcc compatible for the time being. Apple
// gcc translates options twice, which means that self-expanding
// options add duplicates.
- options::ID id = A->getOption().getId();
- switch (id) {
+ switch ((options::ID) A->getOption().getID()) {
default:
DAL->append(A);
break;
@@ -440,7 +441,7 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
if (getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64)
- if (!Args.hasArg(options::OPT_mtune_EQ, false))
+ if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
"core2"));
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 34154f3a3dce..5f0551b138ed 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -18,6 +18,7 @@
#include "clang/Driver/Job.h"
#include "clang/Driver/HostInfo.h"
#include "clang/Driver/Option.h"
+#include "clang/Driver/Options.h"
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Util.h"
@@ -81,8 +82,8 @@ void Clang::AddPreprocessingOptions(const Driver &D,
DepFile = Output.getFilename();
} else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
DepFile = MF->getValue(Args);
- } else if (A->getOption().getId() == options::OPT_M ||
- A->getOption().getId() == options::OPT_MM) {
+ } else if (A->getOption().matches(options::OPT_M) ||
+ A->getOption().matches(options::OPT_MM)) {
DepFile = "-";
} else {
DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
@@ -116,8 +117,8 @@ void Clang::AddPreprocessingOptions(const Driver &D,
CmdArgs.push_back(DepTarget);
}
- if (A->getOption().getId() == options::OPT_M ||
- A->getOption().getId() == options::OPT_MD)
+ if (A->getOption().matches(options::OPT_M) ||
+ A->getOption().matches(options::OPT_MD))
CmdArgs.push_back("-sys-header-deps");
}
@@ -778,12 +779,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
break;
}
- if (Args.hasFlag(options::OPT_fmath_errno,
+ // -fmath-errno is default.
+ if (!Args.hasFlag(options::OPT_fmath_errno,
options::OPT_fno_math_errno,
getToolChain().IsMathErrnoDefault()))
- CmdArgs.push_back("--fmath-errno=1");
- else
- CmdArgs.push_back("--fmath-errno=0");
+ CmdArgs.push_back("-fno-math-errno");
if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
CmdArgs.push_back("--limit-float-precision");
@@ -822,7 +822,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Manually translate -O to -O2 and -O4 to -O3; let clang reject
// others.
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
- if (A->getOption().getId() == options::OPT_O4)
+ if (A->getOption().matches(options::OPT_O4))
CmdArgs.push_back("-O3");
else if (A->getValue(Args)[0] == '\0')
CmdArgs.push_back("-O2");
@@ -864,7 +864,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue(Args));
}
- if (Args.hasArg(options::OPT__relocatable_pch, true))
+ if (Args.hasArg(options::OPT__relocatable_pch))
CmdArgs.push_back("--relocatable-pch");
if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
@@ -922,7 +922,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fbuiltin is default.
if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
- CmdArgs.push_back("-fbuiltin=0");
+ CmdArgs.push_back("-fno-builtin");
// -fblocks=0 is default.
if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
@@ -938,7 +938,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -frtti is default.
if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti))
- CmdArgs.push_back("-frtti=0");
+ CmdArgs.push_back("-fno-rtti");
// -fsigned-char is default.
if (!Args.hasFlag(options::OPT_fsigned_char,
@@ -2609,6 +2609,8 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
// FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
// the default system libraries. Just mimic this for now.
CmdArgs.push_back("-lgcc");
+ if (D.CCCIsCXX)
+ CmdArgs.push_back("-lstdc++");
if (Args.hasArg(options::OPT_static)) {
CmdArgs.push_back("-lgcc_eh");
} else {
@@ -2638,10 +2640,6 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
else
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
- // FIXME: g++ is more complicated here, it tries to put -lstdc++
- // before -lm, for example.
- if (D.CCCIsCXX)
- CmdArgs.push_back("-lstdc++");
}
const char *Exec =
diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp
index 30893e7cc0cc..750286b66c96 100644
--- a/lib/Driver/Types.cpp
+++ b/lib/Driver/Types.cpp
@@ -16,14 +16,14 @@
using namespace clang::driver;
using namespace clang::driver::types;
-struct Info {
+struct TypeInfo {
const char *Name;
const char *Flags;
const char *TempSuffix;
ID PreprocessedType;
};
-static Info TypeInfos[] = {
+static TypeInfo TypeInfos[] = {
#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \
{ NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, },
#include "clang/Driver/Types.def"
@@ -31,7 +31,7 @@ static Info TypeInfos[] = {
};
static const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]);
-static Info &getInfo(unsigned id) {
+static TypeInfo &getInfo(unsigned id) {
assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");
return TypeInfos[id - 1];
}
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index ed6d0b71a51b..b4a79c6d1efb 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -14,7 +14,6 @@ using namespace clang;
void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
const llvm::SmallVectorImpl<llvm::StringRef> &Args) {
- llvm::llvm_report_error("FIXME: Not yet implemented!");
}
static const char *getAnalysisName(Analyses Kind) {
@@ -83,8 +82,8 @@ static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
Res.push_back("-analyzer-display-progress");
if (Opts.EagerlyAssume)
Res.push_back("-analyzer-eagerly-assume");
- if (Opts.PurgeDead)
- Res.push_back("-analyzer-purge-dead");
+ if (!Opts.PurgeDead)
+ Res.push_back("-analyzer-no-purge-dead");
if (Opts.TrimGraph)
Res.push_back("-trim-egraph");
if (Opts.VisualizeEGDot)
@@ -238,7 +237,7 @@ static const char *getActionName(frontend::ActionKind Kind) {
static void FrontendOptsToArgs(const FrontendOptions &Opts,
std::vector<std::string> &Res) {
if (!Opts.DebugCodeCompletionPrinter)
- Res.push_back("-code-completion-debug-printer=0");
+ Res.push_back("-no-code-completion-debug-printer");
if (Opts.DisableFree)
Res.push_back("-disable-free");
if (Opts.EmptyInputOnly)
@@ -298,7 +297,7 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts,
static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
std::vector<std::string> &Res) {
- if (Opts.Sysroot.empty()) {
+ if (Opts.Sysroot != "/") {
Res.push_back("-isysroot");
Res.push_back(Opts.Sysroot);
}
@@ -394,8 +393,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
Res.push_back("-faltivec");
Res.push_back("-fexceptions");
Res.push_back(Opts.Exceptions ? "1" : "0");
- Res.push_back("-frtti");
- Res.push_back(Opts.Rtti ? "1" : "0");
+ if (!Opts.Rtti)
+ Res.push_back("-fno-rtti");
if (!Opts.NeXTRuntime)
Res.push_back("-fgnu-runtime");
if (Opts.Freestanding)
@@ -411,7 +410,7 @@ static void LangOptsToArgs(const LangOptions &Opts,
if (Opts.EmitAllDecls)
Res.push_back("-femit-all-decls");
if (!Opts.MathErrno)
- Res.push_back("-fmath-errno=0");
+ Res.push_back("-fno-math-errno");
if (Opts.OverflowChecking)
Res.push_back("-ftrapv");
if (Opts.HeinousExtensions)
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 4ee286dd265d..b77c24093f5f 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -237,6 +237,13 @@ static void DefineType(const char *MacroName, TargetInfo::IntType Ty,
DefineBuiltinMacro(Buf, MacroBuf);
}
+static void DefineTypeWidth(const char *MacroName, TargetInfo::IntType Ty,
+ const TargetInfo &TI, std::vector<char> &Buf) {
+ char MacroBuf[60];
+ sprintf(MacroBuf, "%s=%d", MacroName, TI.getTypeWidth(Ty));
+ DefineBuiltinMacro(Buf, MacroBuf);
+}
+
static void DefineExactWidthIntType(TargetInfo::IntType Ty,
const TargetInfo &TI, std::vector<char> &Buf) {
char MacroBuf[60];
@@ -381,10 +388,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
DefineTypeSize("__WCHAR_MAX__", TI.getWCharType(), TI, Buf);
DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Buf);
- DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Buf);
- DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Buf);
+ DefineTypeWidth("__INTMAX_WIDTH__", TI.getIntMaxType(), TI, Buf);
DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Buf);
DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Buf);
+ DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Buf);
DefineType("__SIZE_TYPE__", TI.getSizeType(), Buf);
DefineType("__WCHAR_TYPE__", TI.getWCharType(), Buf);
DefineType("__WINT_TYPE__", TI.getWIntType(), Buf);
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index ca7aa3260c62..c9679b7d1e7f 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -34,6 +34,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/System/Path.h"
#include <algorithm>
#include <iterator>
#include <cstdio>
@@ -1086,11 +1087,9 @@ void PCHReader::MaybeAddSystemRootToFilename(std::string &Filename) {
if (!RelocatablePCH)
return;
- if (Filename.empty() || Filename[0] == '/' || Filename[0] == '<')
+ if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
return;
- std::string FIXME = Filename;
-
if (isysroot == 0) {
// If no system root was given, default to '/'
Filename.insert(Filename.begin(), '/');
diff --git a/lib/Headers/stdint.h b/lib/Headers/stdint.h
index bb81a6a3386a..ccaf3499a425 100644
--- a/lib/Headers/stdint.h
+++ b/lib/Headers/stdint.h
@@ -213,16 +213,19 @@ typedef __uint_least8_t uint_fast8_t;
/* C99 7.18.1.4 Integer types capable of holding object pointers.
*/
+#define __stdint_join3(a,b,c) a ## b ## c
+#define __stdint_exjoin3(a,b,c) __stdint_join3(a,b,c)
+
#ifndef __intptr_t_defined
-typedef __INTPTR_TYPE__ intptr_t;
+typedef __stdint_exjoin3( int, __INTPTR_WIDTH__, _t) intptr_t;
#define __intptr_t_defined
#endif
-typedef unsigned __INTPTR_TYPE__ uintptr_t;
+typedef __stdint_exjoin3(uint, __INTPTR_WIDTH__, _t) uintptr_t;
/* C99 7.18.1.5 Greatest-width integer types.
*/
-typedef __INTMAX_TYPE__ intmax_t;
-typedef __UINTMAX_TYPE__ uintmax_t;
+typedef __stdint_exjoin3( int, __INTMAX_WIDTH__, _t) intmax_t;
+typedef __stdint_exjoin3(uint, __INTMAX_WIDTH__, _t) uintmax_t;
/* C99 7.18.4 Macros for minimum-width integer constants.
*
@@ -600,29 +603,24 @@ typedef __UINTMAX_TYPE__ uintmax_t;
/* C99 7.18.2.4 Limits of integer types capable of holding object pointers. */
/* C99 7.18.3 Limits of other integer types. */
+#define INTPTR_MIN __stdint_exjoin3( INT, __INTPTR_WIDTH__, _MIN)
+#define INTPTR_MAX __stdint_exjoin3( INT, __INTPTR_WIDTH__, _MAX)
+#define UINTPTR_MAX __stdint_exjoin3(UINT, __INTPTR_WIDTH__, _MAX)
+
#if __POINTER_WIDTH__ == 64
-#define INTPTR_MIN INT64_MIN
-#define INTPTR_MAX INT64_MAX
-#define UINTPTR_MAX UINT64_MAX
#define PTRDIFF_MIN INT64_MIN
#define PTRDIFF_MAX INT64_MAX
#define SIZE_MAX UINT64_MAX
#elif __POINTER_WIDTH__ == 32
-#define INTPTR_MIN INT32_MIN
-#define INTPTR_MAX INT32_MAX
-#define UINTPTR_MAX UINT32_MAX
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#define SIZE_MAX UINT32_MAX
#elif __POINTER_WIDTH__ == 16
-#define INTPTR_MIN INT16_MIN
-#define INTPTR_MAX INT16_MAX
-#define UINTPTR_MAX UINT16_MAX
#define PTRDIFF_MIN INT16_MIN
#define PTRDIFF_MAX INT16_MAX
#define SIZE_MAX UINT16_MAX
@@ -632,9 +630,9 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#endif
/* C99 7.18.2.5 Limits of greatest-width integer types. */
-#define INTMAX_MIN (-__INTMAX_MAX__-1)
-#define INTMAX_MAX __INTMAX_MAX__
-#define UINTMAX_MAX (__INTMAX_MAX__*2ULL+1ULL)
+#define INTMAX_MIN __stdint_exjoin3( INT, __INTMAX_WIDTH__, _MIN)
+#define INTMAX_MAX __stdint_exjoin3( INT, __INTMAX_WIDTH__, _MAX)
+#define UINTMAX_MAX __stdint_exjoin3(UINT, __INTMAX_WIDTH__, _MAX)
/* C99 7.18.3 Limits of other integer types. */
#define SIG_ATOMIC_MIN INT32_MIN
@@ -653,8 +651,8 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#endif
/* 7.18.4.2 Macros for greatest-width integer constants. */
-#define INTMAX_C(v) v##LL
-#define UINTMAX_C(v) v##ULL
+#define INTMAX_C(v) __stdint_exjoin3( INT, __INTMAX_WIDTH__, _C(v))
+#define UINTMAX_C(v) __stdint_exjoin3(UINT, __INTMAX_WIDTH__, _C(v))
#endif /* __STDC_HOSTED__ */
#endif /* __CLANG_STDINT_H */
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 95a0e989471e..d2b3b84eb7fc 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -341,17 +341,6 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
ColonLoc = ConsumeToken();
}
- if ((OpToken.is(tok::periodstar) || OpToken.is(tok::arrowstar))
- && Tok.is(tok::identifier)) {
- CXXScopeSpec SS;
- if (Actions.getTypeName(*Tok.getIdentifierInfo(),
- Tok.getLocation(), CurScope, &SS)) {
- const char *Opc = OpToken.is(tok::periodstar) ? "'.*'" : "'->*'";
- Diag(OpToken, diag::err_pointer_to_member_type) << Opc;
- return ExprError();
- }
-
- }
// Parse another leaf here for the RHS of the operator.
// ParseCastExpression works here because all RHS expressions in C have it
// as a prefix, at least. However, in C++, an assignment-expression could
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 65bd79d6b4f2..5ba1dd17bdf8 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -123,6 +123,12 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
"ParseObjCAtInterfaceDeclaration(): Expected @interface");
ConsumeToken(); // the "interface" identifier
+ // Code completion after '@interface'.
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCInterfaceDecl(CurScope);
+ ConsumeToken();
+ }
+
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing class or category name.
return DeclPtrTy();
@@ -137,6 +143,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
SourceLocation categoryLoc, rparenLoc;
IdentifierInfo *categoryId = 0;
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId);
+ ConsumeToken();
+ }
+
// For ObjC2, the category name is optional (not an error).
if (Tok.is(tok::identifier)) {
categoryId = Tok.getIdentifierInfo();
@@ -181,6 +192,13 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
if (Tok.is(tok::colon)) { // a super class is specified.
ConsumeToken();
+
+ // Code completion of superclass names.
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCSuperclass(CurScope, nameId);
+ ConsumeToken();
+ }
+
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing super class name.
return DeclPtrTy();
@@ -308,7 +326,8 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
ObjCDeclSpec OCDS;
// Parse property attribute list, if any.
if (Tok.is(tok::l_paren))
- ParseObjCPropertyAttribute(OCDS);
+ ParseObjCPropertyAttribute(OCDS, interfaceDecl,
+ allMethods.data(), allMethods.size());
struct ObjCPropertyCallback : FieldCallback {
Parser &P;
@@ -407,13 +426,15 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
/// copy
/// nonatomic
///
-void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
+void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods) {
assert(Tok.getKind() == tok::l_paren);
SourceLocation LHSLoc = ConsumeParen(); // consume '('
while (1) {
if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteObjCProperty(CurScope, DS);
+ Actions.CodeCompleteObjCPropertyFlags(CurScope, DS);
ConsumeToken();
}
const IdentifierInfo *II = Tok.getIdentifierInfo();
@@ -444,6 +465,16 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
tok::r_paren))
return;
+ if (Tok.is(tok::code_completion)) {
+ if (II->getNameStart()[0] == 's')
+ Actions.CodeCompleteObjCPropertySetter(CurScope, ClassDecl,
+ Methods, NumMethods);
+ else
+ Actions.CodeCompleteObjCPropertyGetter(CurScope, ClassDecl,
+ Methods, NumMethods);
+ ConsumeToken();
+ }
+
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
SkipUntil(tok::r_paren);
@@ -1078,6 +1109,12 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
"ParseObjCAtImplementationDeclaration(): Expected @implementation");
ConsumeToken(); // the "implementation" identifier
+ // Code completion after '@implementation'.
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCImplementationDecl(CurScope);
+ ConsumeToken();
+ }
+
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident); // missing class or category name.
return DeclPtrTy();
@@ -1092,6 +1129,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
SourceLocation categoryLoc, rparenLoc;
IdentifierInfo *categoryId = 0;
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCImplementationCategory(CurScope, nameId);
+ ConsumeToken();
+ }
+
if (Tok.is(tok::identifier)) {
categoryId = Tok.getIdentifierInfo();
categoryLoc = ConsumeToken();
@@ -1202,18 +1244,32 @@ Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
"ParseObjCPropertyDynamic(): Expected '@synthesize'");
SourceLocation loc = ConsumeToken(); // consume synthesize
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return DeclPtrTy();
- }
- while (Tok.is(tok::identifier)) {
+ while (true) {
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl);
+ ConsumeToken();
+ }
+
+ if (Tok.isNot(tok::identifier)) {
+ Diag(Tok, diag::err_synthesized_property_name);
+ SkipUntil(tok::semi);
+ return DeclPtrTy();
+ }
+
IdentifierInfo *propertyIvar = 0;
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
SourceLocation propertyLoc = ConsumeToken(); // consume property name
if (Tok.is(tok::equal)) {
// property '=' ivar-name
ConsumeToken(); // consume '='
+
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCPropertySynthesizeIvar(CurScope, propertyId,
+ ObjCImpDecl);
+ ConsumeToken();
+ }
+
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
break;
@@ -1227,8 +1283,10 @@ Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
break;
ConsumeToken(); // consume ','
}
- if (Tok.isNot(tok::semi))
+ if (Tok.isNot(tok::semi)) {
Diag(Tok, diag::err_expected_semi_after) << "@synthesize";
+ SkipUntil(tok::semi);
+ }
else
ConsumeToken(); // consume ';'
return DeclPtrTy();
@@ -1245,11 +1303,18 @@ Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
"ParseObjCPropertyDynamic(): Expected '@dynamic'");
SourceLocation loc = ConsumeToken(); // consume dynamic
- if (Tok.isNot(tok::identifier)) {
- Diag(Tok, diag::err_expected_ident);
- return DeclPtrTy();
- }
- while (Tok.is(tok::identifier)) {
+ while (true) {
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl);
+ ConsumeToken();
+ }
+
+ if (Tok.isNot(tok::identifier)) {
+ Diag(Tok, diag::err_expected_ident);
+ SkipUntil(tok::semi);
+ return DeclPtrTy();
+ }
+
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
SourceLocation propertyLoc = ConsumeToken(); // consume property name
Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
@@ -1580,11 +1645,14 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
ExprArg ReceiverExpr) {
if (Tok.is(tok::code_completion)) {
if (ReceiverName)
- Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc);
+ Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc,
+ 0, 0);
else
- Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get());
+ Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(),
+ 0, 0);
ConsumeToken();
}
+
// Parse objc-selector
SourceLocation Loc;
IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
@@ -1622,6 +1690,19 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
// We have a valid expression.
KeyExprs.push_back(Res.release());
+ // Code completion after each argument.
+ if (Tok.is(tok::code_completion)) {
+ if (ReceiverName)
+ Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc,
+ KeyIdents.data(),
+ KeyIdents.size());
+ else
+ Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(),
+ KeyIdents.data(),
+ KeyIdents.size());
+ ConsumeToken();
+ }
+
// Check for another keyword selector.
selIdent = ParseObjCSelectorPiece(Loc);
if (!selIdent && Tok.isNot(tok::colon))
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 88ac4e49cf9e..a9d83010576a 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -117,6 +117,33 @@ CodeCompletionString::Chunk::CreateCurrentParameter(
return Chunk(CK_CurrentParameter, CurrentParameter);
}
+CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const {
+ switch (Kind) {
+ case CK_TypedText:
+ case CK_Text:
+ case CK_Placeholder:
+ case CK_Informative:
+ case CK_CurrentParameter:
+ case CK_LeftParen:
+ case CK_RightParen:
+ case CK_LeftBracket:
+ case CK_RightBracket:
+ case CK_LeftBrace:
+ case CK_RightBrace:
+ case CK_LeftAngle:
+ case CK_RightAngle:
+ case CK_Comma:
+ return Chunk(Kind, Text);
+
+ case CK_Optional: {
+ std::auto_ptr<CodeCompletionString> Opt(Optional->Clone());
+ return CreateOptional(Opt);
+ }
+ }
+
+ // Silence GCC warning.
+ return Chunk();
+}
void
CodeCompletionString::Chunk::Destroy() {
@@ -168,6 +195,20 @@ std::string CodeCompletionString::getAsString() const {
return Result;
}
+const char *CodeCompletionString::getTypedText() const {
+ for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+ if (C->Kind == CK_TypedText)
+ return C->Text;
+
+ return 0;
+}
+
+CodeCompletionString *CodeCompletionString::Clone() const {
+ CodeCompletionString *Result = new CodeCompletionString;
+ for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+ Result->AddChunk(C->Clone());
+ return Result;
+}
namespace {
// Escape a string for XML-like formatting.
@@ -473,6 +514,13 @@ CodeCompletionString *CodeCompletionString::Deserialize(llvm::StringRef &Str) {
return Result;
}
+void CodeCompleteConsumer::Result::Destroy() {
+ if (Kind == RK_Pattern) {
+ delete Pattern;
+ Pattern = 0;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Code completion overload candidate implementation
//===----------------------------------------------------------------------===//
@@ -545,6 +593,12 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
OS << '\n';
break;
}
+
+ case Result::RK_Pattern: {
+ OS << "Pattern : " << Results[I].Rank << " : "
+ << Results[I].Pattern->getAsString() << '\n';
+ break;
+ }
}
}
@@ -627,6 +681,13 @@ CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
OS << '\n';
break;
}
+
+ case Result::RK_Pattern: {
+ OS << "Pattern:";
+ Results[I].Pattern->Serialize(OS);
+ OS << '\n';
+ break;
+ }
}
}
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
index 6e72dcef161a..10cc818b8baa 100644
--- a/lib/Sema/Lookup.h
+++ b/lib/Sema/Lookup.h
@@ -201,6 +201,13 @@ public:
return getResultKind() == Ambiguous;
}
+ /// Determines if this names a single result which is not an
+ /// unresolved value using decl. If so, it is safe to call
+ /// getFoundDecl().
+ bool isSingleResult() const {
+ return getResultKind() == Found;
+ }
+
LookupResultKind getResultKind() const {
sanity();
return ResultKind;
@@ -248,12 +255,24 @@ public:
Decls.set_size(N);
}
- /// \brief Resolves the kind of the lookup, possibly hiding decls.
+ /// \brief Resolves the result kind of the lookup, possibly hiding
+ /// decls.
///
/// This should be called in any environment where lookup might
/// generate multiple lookup results.
void resolveKind();
+ /// \brief Re-resolves the result kind of the lookup after a set of
+ /// removals has been performed.
+ void resolveKindAfterFilter() {
+ if (Decls.empty())
+ ResultKind = NotFound;
+ else {
+ ResultKind = Found;
+ resolveKind();
+ }
+ }
+
/// \brief Fetch this as an unambiguous single declaration
/// (possibly an overloaded one).
///
@@ -272,6 +291,12 @@ public:
return Decls[0]->getUnderlyingDecl();
}
+ /// Fetches a representative decl. Useful for lazy diagnostics.
+ NamedDecl *getRepresentativeDecl() const {
+ assert(!Decls.empty() && "cannot get representative of empty set");
+ return Decls[0];
+ }
+
/// \brief Asks if the result is a single tag decl.
bool isSingleTagDecl() const {
return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
@@ -337,6 +362,65 @@ public:
return NameLoc;
}
+ /// A class for iterating through a result set and possibly
+ /// filtering out results. The results returned are possibly
+ /// sugared.
+ class Filter {
+ LookupResult &Results;
+ unsigned I;
+ bool ErasedAny;
+#ifndef NDEBUG
+ bool CalledDone;
+#endif
+
+ friend class LookupResult;
+ Filter(LookupResult &Results)
+ : Results(Results), I(0), ErasedAny(false)
+#ifndef NDEBUG
+ , CalledDone(false)
+#endif
+ {}
+
+ public:
+#ifndef NDEBUG
+ ~Filter() {
+ assert(CalledDone &&
+ "LookupResult::Filter destroyed without done() call");
+ }
+#endif
+
+ bool hasNext() const {
+ return I != Results.Decls.size();
+ }
+
+ NamedDecl *next() {
+ assert(I < Results.Decls.size() && "next() called on empty filter");
+ return Results.Decls[I++];
+ }
+
+ /// Erase the last element returned from this iterator.
+ void erase() {
+ Results.Decls[--I] = Results.Decls.back();
+ Results.Decls.pop_back();
+ ErasedAny = true;
+ }
+
+ void done() {
+#ifndef NDEBUG
+ assert(!CalledDone && "done() called twice");
+ CalledDone = true;
+#endif
+
+ if (ErasedAny)
+ Results.resolveKindAfterFilter();
+ }
+ };
+
+ /// Create a filter for this result set.
+ Filter makeFilter() {
+ return Filter(*this);
+ }
+
private:
void diagnose() {
if (isAmbiguous())
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index b2bbac8bc2a9..fe2d7448b42f 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -319,7 +319,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
&Context.Idents.get("Protocol"),
SourceLocation(), true);
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
- PushOnScopeChains(ProtocolDecl, TUScope);
+ PushOnScopeChains(ProtocolDecl, TUScope, false);
}
// Create the built-in typedef for 'id'.
if (Context.getObjCIdType().isNull()) {
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 3e186b2b5be9..ad4c90bdc2a5 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -548,26 +548,32 @@ public:
DeclPtrTy HandleDeclarator(Scope *S, Declarator &D,
MultiTemplateParamsArg TemplateParameterLists,
bool IsFunctionDefinition);
- void RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
+ void RegisterLocallyScopedExternCDecl(NamedDecl *ND,
+ const LookupResult &Previous,
Scope *S);
void DiagnoseFunctionSpecifiers(Declarator& D);
+ bool CheckRedeclaration(DeclContext *DC,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ unsigned Diagnostic);
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
- NamedDecl* PrevDecl, bool &Redeclaration);
+ LookupResult &Previous, bool &Redeclaration);
NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
- NamedDecl* PrevDecl,
+ LookupResult &Previous,
MultiTemplateParamsArg TemplateParamLists,
bool &Redeclaration);
- void CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
+ void CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous,
bool &Redeclaration);
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
- NamedDecl* PrevDecl,
+ LookupResult &Previous,
MultiTemplateParamsArg TemplateParamLists,
bool IsFunctionDefinition,
bool &Redeclaration);
- void CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
+ void AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
+ void CheckFunctionDeclaration(FunctionDecl *NewFD, LookupResult &Previous,
bool IsExplicitSpecialization,
bool &Redeclaration,
bool &OverloadableAttrRequired);
@@ -779,15 +785,17 @@ public:
/// Subroutines of ActOnDeclarator().
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
DeclaratorInfo *DInfo);
- void MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
+ void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls);
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
- void MergeVarDecl(VarDecl *New, Decl *Old);
+ void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
/// C++ Overloading.
- bool IsOverload(FunctionDecl *New, Decl* OldD,
- OverloadedFunctionDecl::function_iterator &MatchedDecl);
+ bool IsOverload(FunctionDecl *New, LookupResult &OldDecls,
+ NamedDecl *&OldDecl);
+ bool IsOverload(FunctionDecl *New, FunctionDecl *Old);
+
ImplicitConversionSequence
TryImplicitConversion(Expr* From, QualType ToType,
bool SuppressUserConversions,
@@ -822,7 +830,7 @@ public:
bool AllowConversionFunctions,
bool AllowExplicit, bool ForceRValue,
bool UserCast = false);
- bool DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType);
+ bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
ImplicitConversionSequence::CompareKind
@@ -2324,8 +2332,8 @@ public:
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
- NamedDecl *&PrevDecl);
- bool CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl);
+ LookupResult &Previous);
+ bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
virtual DeclResult
ActOnExplicitInstantiation(Scope *S,
@@ -3638,14 +3646,38 @@ public:
virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
virtual void CodeCompleteOperatorName(Scope *S);
- virtual void CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS);
+ virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
+ virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods);
+ virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods);
+
virtual void CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
- SourceLocation FNameLoc);
- virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver);
+ SourceLocation FNameLoc,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents);
+ virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents);
virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
unsigned NumProtocols);
virtual void CodeCompleteObjCProtocolDecl(Scope *S);
- //@}
+ virtual void CodeCompleteObjCInterfaceDecl(Scope *S);
+ virtual void CodeCompleteObjCSuperclass(Scope *S,
+ IdentifierInfo *ClassName);
+ virtual void CodeCompleteObjCImplementationDecl(Scope *S);
+ virtual void CodeCompleteObjCInterfaceCategory(Scope *S,
+ IdentifierInfo *ClassName);
+ virtual void CodeCompleteObjCImplementationCategory(Scope *S,
+ IdentifierInfo *ClassName);
+ virtual void CodeCompleteObjCPropertyDefinition(Scope *S,
+ DeclPtrTy ObjCImpDecl);
+ virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
+ IdentifierInfo *PropertyName,
+ DeclPtrTy ObjCImpDecl);
+ //@}
//===--------------------------------------------------------------------===//
// Extra semantic analysis beyond the C type system
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index e5ad338502df..6b4f87ef1dfb 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -175,6 +175,30 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
return ExprError();
}
+/// UnwrapDissimilarPointerTypes - Like Sema::UnwrapSimilarPointerTypes,
+/// this removes one level of indirection from both types, provided that they're
+/// the same kind of pointer (plain or to-member). Unlike the Sema function,
+/// this one doesn't care if the two pointers-to-member don't point into the
+/// same class. This is because CastsAwayConstness doesn't care.
+bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
+ const PointerType *T1PtrType = T1->getAs<PointerType>(),
+ *T2PtrType = T2->getAs<PointerType>();
+ if (T1PtrType && T2PtrType) {
+ T1 = T1PtrType->getPointeeType();
+ T2 = T2PtrType->getPointeeType();
+ return true;
+ }
+
+ const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(),
+ *T2MPType = T2->getAs<MemberPointerType>();
+ if (T1MPType && T2MPType) {
+ T1 = T1MPType->getPointeeType();
+ T2 = T2MPType->getPointeeType();
+ return true;
+ }
+ return false;
+}
+
/// CastsAwayConstness - Check if the pointer conversion from SrcType to
/// DestType casts away constness as defined in C++ 5.2.11p8ff. This is used by
/// the cast checkers. Both arguments must denote pointer (possibly to member)
@@ -195,7 +219,7 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) {
llvm::SmallVector<Qualifiers, 8> cv1, cv2;
// Find the qualifications.
- while (Self.UnwrapSimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
+ while (UnwrapDissimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
cv1.push_back(UnwrappedSrcType.getQualifiers());
cv2.push_back(UnwrappedDestType.getQualifiers());
}
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 9cecdadc867e..6dbb4426c20c 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -944,26 +944,50 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
return Result;
}
- Result->AddTypedTextChunk(
- Sel.getIdentifierInfoForSlot(0)->getName().str() + std::string(":"));
+ std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
+ SelName += ':';
+ if (StartParameter == 0)
+ Result->AddTypedTextChunk(SelName);
+ else {
+ Result->AddInformativeChunk(SelName);
+
+ // If there is only one parameter, and we're past it, add an empty
+ // typed-text chunk since there is nothing to type.
+ if (Method->param_size() == 1)
+ Result->AddTypedTextChunk("");
+ }
unsigned Idx = 0;
for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
PEnd = Method->param_end();
P != PEnd; (void)++P, ++Idx) {
if (Idx > 0) {
- std::string Keyword = " ";
+ std::string Keyword;
+ if (Idx > StartParameter)
+ Keyword = " ";
if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
Keyword += II->getName().str();
Keyword += ":";
- Result->AddTextChunk(Keyword);
+ if (Idx < StartParameter || AllParametersAreInformative) {
+ Result->AddInformativeChunk(Keyword);
+ } else if (Idx == StartParameter)
+ Result->AddTypedTextChunk(Keyword);
+ else
+ Result->AddTextChunk(Keyword);
}
+
+ // If we're before the starting parameter, skip the placeholder.
+ if (Idx < StartParameter)
+ continue;
std::string Arg;
(*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
Arg = "(" + Arg + ")";
if (IdentifierInfo *II = (*P)->getIdentifier())
Arg += II->getName().str();
- Result->AddPlaceholderChunk(Arg);
+ if (AllParametersAreInformative)
+ Result->AddInformativeChunk(Arg);
+ else
+ Result->AddPlaceholderChunk(Arg);
}
return Result;
@@ -1066,6 +1090,17 @@ namespace {
else if (X.Rank > Y.Rank)
return false;
+ // We use a special ordering for keywords and patterns, based on the
+ // typed text.
+ if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
+ (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
+ const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
+ : X.Pattern->getTypedText();
+ const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
+ : Y.Pattern->getTypedText();
+ return strcmp(XStr, YStr) < 0;
+ }
+
// Result kinds are ordered by decreasing importance.
if (X.Kind < Y.Kind)
return true;
@@ -1087,12 +1122,14 @@ namespace {
return isEarlierDeclarationName(X.Declaration->getDeclName(),
Y.Declaration->getDeclName());
- case Result::RK_Keyword:
- return strcmp(X.Keyword, Y.Keyword) < 0;
-
case Result::RK_Macro:
return llvm::LowercaseString(X.Macro->getName()) <
llvm::LowercaseString(Y.Macro->getName());
+
+ case Result::RK_Keyword:
+ case Result::RK_Pattern:
+ llvm::llvm_unreachable("Result kinds handled above");
+ break;
}
// Silence GCC warning.
@@ -1120,6 +1157,9 @@ static void HandleCodeCompleteResults(Sema *S,
if (CodeCompleter)
CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
+
+ for (unsigned I = 0; I != NumResults; ++I)
+ Results[I].Destroy();
}
void Sema::CodeCompleteOrdinaryName(Scope *S) {
@@ -1132,6 +1172,7 @@ void Sema::CodeCompleteOrdinaryName(Scope *S) {
}
static void AddObjCProperties(ObjCContainerDecl *Container,
+ bool AllowCategories,
DeclContext *CurContext,
ResultBuilder &Results) {
typedef CodeCompleteConsumer::Result Result;
@@ -1148,29 +1189,32 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
PEnd = Protocol->protocol_end();
P != PEnd; ++P)
- AddObjCProperties(*P, CurContext, Results);
+ AddObjCProperties(*P, AllowCategories, CurContext, Results);
} else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
- // Look through categories.
- for (ObjCCategoryDecl *Category = IFace->getCategoryList();
- Category; Category = Category->getNextClassCategory())
- AddObjCProperties(Category, CurContext, Results);
+ if (AllowCategories) {
+ // Look through categories.
+ for (ObjCCategoryDecl *Category = IFace->getCategoryList();
+ Category; Category = Category->getNextClassCategory())
+ AddObjCProperties(Category, AllowCategories, CurContext, Results);
+ }
// Look through protocols.
for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
E = IFace->protocol_end();
I != E; ++I)
- AddObjCProperties(*I, CurContext, Results);
+ AddObjCProperties(*I, AllowCategories, CurContext, Results);
// Look in the superclass.
if (IFace->getSuperClass())
- AddObjCProperties(IFace->getSuperClass(), CurContext, Results);
+ AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
+ Results);
} else if (const ObjCCategoryDecl *Category
= dyn_cast<ObjCCategoryDecl>(Container)) {
// Look through protocols.
for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
PEnd = Category->protocol_end();
P != PEnd; ++P)
- AddObjCProperties(*P, CurContext, Results);
+ AddObjCProperties(*P, AllowCategories, CurContext, Results);
}
}
@@ -1234,13 +1278,13 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
const ObjCObjectPointerType *ObjCPtr
= BaseType->getAsObjCInterfacePointerType();
assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
- AddObjCProperties(ObjCPtr->getInterfaceDecl(), CurContext, Results);
+ AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
// Add properties from the protocols in a qualified interface.
for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
E = ObjCPtr->qual_end();
I != E; ++I)
- AddObjCProperties(*I, CurContext, Results);
+ AddObjCProperties(*I, true, CurContext, Results);
// FIXME: We could (should?) also look for "implicit" properties, identified
// only by the presence of nullary and unary selectors.
@@ -1611,34 +1655,104 @@ void Sema::CodeCompleteOperatorName(Scope *S) {
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
}
-void Sema::CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS) {
+/// \brief Determine whether the addition of the given flag to an Objective-C
+/// property's attributes will cause a conflict.
+static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
+ // Check if we've already added this flag.
+ if (Attributes & NewFlag)
+ return true;
+
+ Attributes |= NewFlag;
+
+ // Check for collisions with "readonly".
+ if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
+ (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
+ ObjCDeclSpec::DQ_PR_assign |
+ ObjCDeclSpec::DQ_PR_copy |
+ ObjCDeclSpec::DQ_PR_retain)))
+ return true;
+
+ // Check for more than one of { assign, copy, retain }.
+ unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
+ ObjCDeclSpec::DQ_PR_copy |
+ ObjCDeclSpec::DQ_PR_retain);
+ if (AssignCopyRetMask &&
+ AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
+ AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
+ AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
+ return true;
+
+ return false;
+}
+
+void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
if (!CodeCompleter)
return;
+
unsigned Attributes = ODS.getPropertyAttributes();
typedef CodeCompleteConsumer::Result Result;
ResultBuilder Results(*this);
Results.EnterNewScope();
- if (!(Attributes & ObjCDeclSpec::DQ_PR_readonly))
+ if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_assign))
+ if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_readwrite))
+ if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_retain))
+ if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_copy))
+ if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_nonatomic))
+ if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_setter))
- Results.MaybeAddResult(CodeCompleteConsumer::Result("setter", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_getter))
- Results.MaybeAddResult(CodeCompleteConsumer::Result("getter", 0));
+ if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
+ CodeCompletionString *Setter = new CodeCompletionString;
+ Setter->AddTypedTextChunk("setter");
+ Setter->AddTextChunk(" = ");
+ Setter->AddPlaceholderChunk("method");
+ Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
+ }
+ if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
+ CodeCompletionString *Getter = new CodeCompletionString;
+ Getter->AddTypedTextChunk("getter");
+ Getter->AddTextChunk(" = ");
+ Getter->AddPlaceholderChunk("method");
+ Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
+ }
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
}
+/// \brief Descripts the kind of Objective-C method that we want to find
+/// via code completion.
+enum ObjCMethodKind {
+ MK_Any, //< Any kind of method, provided it means other specified criteria.
+ MK_ZeroArgSelector, //< Zero-argument (unary) selector.
+ MK_OneArgSelector //< One-argument selector.
+};
+
+static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
+ ObjCMethodKind WantKind,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
+ Selector Sel = Method->getSelector();
+ if (NumSelIdents > Sel.getNumArgs())
+ return false;
+
+ switch (WantKind) {
+ case MK_Any: break;
+ case MK_ZeroArgSelector: return Sel.isUnarySelector();
+ case MK_OneArgSelector: return Sel.getNumArgs() == 1;
+ }
+
+ for (unsigned I = 0; I != NumSelIdents; ++I)
+ if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
+ return false;
+
+ return true;
+}
+
/// \brief Add all of the Objective-C methods in the given Objective-C
/// container to the set of results.
///
@@ -1658,14 +1772,26 @@ void Sema::CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS) {
/// \param Results the structure into which we'll add results.
static void AddObjCMethods(ObjCContainerDecl *Container,
bool WantInstanceMethods,
+ ObjCMethodKind WantKind,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents,
DeclContext *CurContext,
ResultBuilder &Results) {
typedef CodeCompleteConsumer::Result Result;
for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
MEnd = Container->meth_end();
M != MEnd; ++M) {
- if ((*M)->isInstanceMethod() == WantInstanceMethods)
- Results.MaybeAddResult(Result(*M, 0), CurContext);
+ if ((*M)->isInstanceMethod() == WantInstanceMethods) {
+ // Check whether the selector identifiers we've been given are a
+ // subset of the identifiers for this particular method.
+ if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
+ continue;
+
+ Result R = Result(*M, 0);
+ R.StartParameter = NumSelIdents;
+ R.AllParametersAreInformative = (WantKind != MK_Any);
+ Results.MaybeAddResult(R, CurContext);
+ }
}
ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
@@ -1677,12 +1803,14 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end();
I != E; ++I)
- AddObjCMethods(*I, WantInstanceMethods, CurContext, Results);
+ AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
+ CurContext, Results);
// Add methods in categories.
for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
CatDecl = CatDecl->getNextClassCategory()) {
- AddObjCMethods(CatDecl, WantInstanceMethods, CurContext, Results);
+ AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
+ NumSelIdents, CurContext, Results);
// Add a categories protocol methods.
const ObjCList<ObjCProtocolDecl> &Protocols
@@ -1690,25 +1818,110 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end();
I != E; ++I)
- AddObjCMethods(*I, WantInstanceMethods, CurContext, Results);
+ AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
+ NumSelIdents, CurContext, Results);
// Add methods in category implementations.
if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
- AddObjCMethods(Impl, WantInstanceMethods, CurContext, Results);
+ AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
+ NumSelIdents, CurContext, Results);
}
// Add methods in superclass.
if (IFace->getSuperClass())
- AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, CurContext,
- Results);
+ AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
+ SelIdents, NumSelIdents, CurContext, Results);
// Add methods in our implementation, if any.
if (ObjCImplementationDecl *Impl = IFace->getImplementation())
- AddObjCMethods(Impl, WantInstanceMethods, CurContext, Results);
+ AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
+ NumSelIdents, CurContext, Results);
+}
+
+
+void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods) {
+ typedef CodeCompleteConsumer::Result Result;
+
+ // Try to find the interface where getters might live.
+ ObjCInterfaceDecl *Class
+ = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
+ if (!Class) {
+ if (ObjCCategoryDecl *Category
+ = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
+ Class = Category->getClassInterface();
+
+ if (!Class)
+ return;
+ }
+
+ // Find all of the potential getters.
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // FIXME: We need to do this because Objective-C methods don't get
+ // pushed into DeclContexts early enough. Argh!
+ for (unsigned I = 0; I != NumMethods; ++I) {
+ if (ObjCMethodDecl *Method
+ = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
+ if (Method->isInstanceMethod() &&
+ isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
+ Result R = Result(Method, 0);
+ R.AllParametersAreInformative = true;
+ Results.MaybeAddResult(R, CurContext);
+ }
+ }
+
+ AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
+ DeclPtrTy *Methods,
+ unsigned NumMethods) {
+ typedef CodeCompleteConsumer::Result Result;
+
+ // Try to find the interface where setters might live.
+ ObjCInterfaceDecl *Class
+ = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
+ if (!Class) {
+ if (ObjCCategoryDecl *Category
+ = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
+ Class = Category->getClassInterface();
+
+ if (!Class)
+ return;
+ }
+
+ // Find all of the potential getters.
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // FIXME: We need to do this because Objective-C methods don't get
+ // pushed into DeclContexts early enough. Argh!
+ for (unsigned I = 0; I != NumMethods; ++I) {
+ if (ObjCMethodDecl *Method
+ = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
+ if (Method->isInstanceMethod() &&
+ isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
+ Result R = Result(Method, 0);
+ R.AllParametersAreInformative = true;
+ Results.MaybeAddResult(R, CurContext);
+ }
+ }
+
+ AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
+
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
}
void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
- SourceLocation FNameLoc) {
+ SourceLocation FNameLoc,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
typedef CodeCompleteConsumer::Result Result;
ObjCInterfaceDecl *CDecl = 0;
@@ -1734,7 +1947,8 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
SuperTy = Context.getObjCObjectPointerType(SuperTy);
OwningExprResult Super
= Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
- return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get());
+ return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
+ SelIdents, NumSelIdents);
}
// Okay, we're calling a factory method in our superclass.
@@ -1756,21 +1970,25 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
// probably calling an instance method.
OwningExprResult Super = ActOnDeclarationNameExpr(S, FNameLoc, FName,
false, 0, false);
- return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get());
+ return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
+ SelIdents, NumSelIdents);
}
// Add all of the factory methods in this Objective-C class, its protocols,
// superclasses, categories, implementation, etc.
ResultBuilder Results(*this);
Results.EnterNewScope();
- AddObjCMethods(CDecl, false, CurContext, Results);
+ AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
+ Results);
Results.ExitScope();
// This also suppresses remaining diagnostics.
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
}
-void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) {
+void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) {
typedef CodeCompleteConsumer::Result Result;
Expr *RecExpr = static_cast<Expr *>(Receiver);
@@ -1798,7 +2016,8 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) {
ReceiverType->isObjCQualifiedClassType()) {
if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
- AddObjCMethods(ClassDecl, false, CurContext, Results);
+ AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
+ CurContext, Results);
}
}
// Handle messages to a qualified ID ("id<foo>").
@@ -1808,19 +2027,22 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) {
for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
E = QualID->qual_end();
I != E; ++I)
- AddObjCMethods(*I, true, CurContext, Results);
+ AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
+ Results);
}
// Handle messages to a pointer to interface type.
else if (const ObjCObjectPointerType *IFacePtr
= ReceiverType->getAsObjCInterfacePointerType()) {
// Search the class, its superclasses, etc., for instance methods.
- AddObjCMethods(IFacePtr->getInterfaceDecl(), true, CurContext, Results);
+ AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
+ NumSelIdents, CurContext, Results);
// Search protocols for instance methods.
for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
E = IFacePtr->qual_end();
I != E; ++I)
- AddObjCMethods(*I, true, CurContext, Results);
+ AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
+ Results);
}
Results.ExitScope();
@@ -1885,3 +2107,210 @@ void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
}
+
+/// \brief Add all of the Objective-C interface declarations that we find in
+/// the given (translation unit) context.
+static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
+ bool OnlyForwardDeclarations,
+ bool OnlyUnimplemented,
+ ResultBuilder &Results) {
+ typedef CodeCompleteConsumer::Result Result;
+
+ for (DeclContext::decl_iterator D = Ctx->decls_begin(),
+ DEnd = Ctx->decls_end();
+ D != DEnd; ++D) {
+ // Record any interfaces we find.
+ if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
+ if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
+ (!OnlyUnimplemented || !Class->getImplementation()))
+ Results.MaybeAddResult(Result(Class, 0), CurContext);
+
+ // Record any forward-declared interfaces we find.
+ if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
+ for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
+ C != CEnd; ++C)
+ if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
+ (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
+ Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
+ }
+ }
+}
+
+void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // Add all classes.
+ AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
+ false, Results);
+
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // Make sure that we ignore the class we're currently defining.
+ NamedDecl *CurClass
+ = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
+ if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
+ Results.Ignore(CurClass);
+
+ // Add all classes.
+ AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
+ false, Results);
+
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ // Add all unimplemented classes.
+ AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
+ true, Results);
+
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
+ IdentifierInfo *ClassName) {
+ typedef CodeCompleteConsumer::Result Result;
+
+ ResultBuilder Results(*this);
+
+ // Ignore any categories we find that have already been implemented by this
+ // interface.
+ llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
+ NamedDecl *CurClass
+ = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
+ if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
+ for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
+ Category = Category->getNextClassCategory())
+ CategoryNames.insert(Category->getIdentifier());
+
+ // Add all of the categories we know about.
+ Results.EnterNewScope();
+ TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+ for (DeclContext::decl_iterator D = TU->decls_begin(),
+ DEnd = TU->decls_end();
+ D != DEnd; ++D)
+ if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
+ if (CategoryNames.insert(Category->getIdentifier()))
+ Results.MaybeAddResult(Result(Category, 0), CurContext);
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
+ IdentifierInfo *ClassName) {
+ typedef CodeCompleteConsumer::Result Result;
+
+ // Find the corresponding interface. If we couldn't find the interface, the
+ // program itself is ill-formed. However, we'll try to be helpful still by
+ // providing the list of all of the categories we know about.
+ NamedDecl *CurClass
+ = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
+ ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
+ if (!Class)
+ return CodeCompleteObjCInterfaceCategory(S, ClassName);
+
+ ResultBuilder Results(*this);
+
+ // Add all of the categories that have have corresponding interface
+ // declarations in this class and any of its superclasses, except for
+ // already-implemented categories in the class itself.
+ llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
+ Results.EnterNewScope();
+ bool IgnoreImplemented = true;
+ while (Class) {
+ for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
+ Category = Category->getNextClassCategory())
+ if ((!IgnoreImplemented || !Category->getImplementation()) &&
+ CategoryNames.insert(Category->getIdentifier()))
+ Results.MaybeAddResult(Result(Category, 0), CurContext);
+
+ Class = Class->getSuperClass();
+ IgnoreImplemented = false;
+ }
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
+ typedef CodeCompleteConsumer::Result Result;
+ ResultBuilder Results(*this);
+
+ // Figure out where this @synthesize lives.
+ ObjCContainerDecl *Container
+ = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+ if (!Container ||
+ (!isa<ObjCImplementationDecl>(Container) &&
+ !isa<ObjCCategoryImplDecl>(Container)))
+ return;
+
+ // Ignore any properties that have already been implemented.
+ for (DeclContext::decl_iterator D = Container->decls_begin(),
+ DEnd = Container->decls_end();
+ D != DEnd; ++D)
+ if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
+ Results.Ignore(PropertyImpl->getPropertyDecl());
+
+ // Add any properties that we find.
+ Results.EnterNewScope();
+ if (ObjCImplementationDecl *ClassImpl
+ = dyn_cast<ObjCImplementationDecl>(Container))
+ AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
+ Results);
+ else
+ AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
+ false, CurContext, Results);
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
+ IdentifierInfo *PropertyName,
+ DeclPtrTy ObjCImpDecl) {
+ typedef CodeCompleteConsumer::Result Result;
+ ResultBuilder Results(*this);
+
+ // Figure out where this @synthesize lives.
+ ObjCContainerDecl *Container
+ = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+ if (!Container ||
+ (!isa<ObjCImplementationDecl>(Container) &&
+ !isa<ObjCCategoryImplDecl>(Container)))
+ return;
+
+ // Figure out which interface we're looking into.
+ ObjCInterfaceDecl *Class = 0;
+ if (ObjCImplementationDecl *ClassImpl
+ = dyn_cast<ObjCImplementationDecl>(Container))
+ Class = ClassImpl->getClassInterface();
+ else
+ Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
+ ->getClassInterface();
+
+ // Add all of the instance variables in this class and its superclasses.
+ Results.EnterNewScope();
+ for(; Class; Class = Class->getSuperClass()) {
+ // FIXME: We could screen the type of each ivar for compatibility with
+ // the property, but is that being too paternal?
+ for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
+ IVarEnd = Class->ivar_end();
+ IVar != IVarEnd; ++IVar)
+ Results.MaybeAddResult(Result(*IVar, 0), CurContext);
+ }
+ Results.ExitScope();
+
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 57c101bd32ce..b5109f825e57 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -311,14 +311,16 @@ void Sema::ExitDeclaratorContext(Scope *S) {
/// extension, in C when the previous function is already an
/// overloaded function declaration or has the "overloadable"
/// attribute.
-static bool AllowOverloadingOfFunction(Decl *PrevDecl, ASTContext &Context) {
+static bool AllowOverloadingOfFunction(LookupResult &Previous,
+ ASTContext &Context) {
if (Context.getLangOptions().CPlusPlus)
return true;
- if (isa<OverloadedFunctionDecl>(PrevDecl))
+ if (Previous.getResultKind() == LookupResult::FoundOverloaded)
return true;
- return PrevDecl->getAttr<OverloadableAttr>() != 0;
+ return (Previous.getResultKind() == LookupResult::Found
+ && Previous.getFoundDecl()->hasAttr<OverloadableAttr>());
}
/// Add this decl to the scope shadowed decl chains.
@@ -396,6 +398,48 @@ bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S) {
return IdResolver.isDeclInScope(D, Ctx, Context, S);
}
+static bool isOutOfScopePreviousDeclaration(NamedDecl *,
+ DeclContext*,
+ ASTContext&);
+
+/// Filters out lookup results that don't fall within the given scope
+/// as determined by isDeclInScope.
+static void FilterLookupForScope(Sema &SemaRef, LookupResult &R,
+ DeclContext *Ctx, Scope *S,
+ bool ConsiderLinkage) {
+ LookupResult::Filter F = R.makeFilter();
+ while (F.hasNext()) {
+ NamedDecl *D = F.next();
+
+ if (SemaRef.isDeclInScope(D, Ctx, S))
+ continue;
+
+ if (ConsiderLinkage &&
+ isOutOfScopePreviousDeclaration(D, Ctx, SemaRef.Context))
+ continue;
+
+ F.erase();
+ }
+
+ F.done();
+}
+
+static bool isUsingDecl(NamedDecl *D) {
+ return isa<UsingShadowDecl>(D) ||
+ isa<UnresolvedUsingTypenameDecl>(D) ||
+ isa<UnresolvedUsingValueDecl>(D);
+}
+
+/// Removes using shadow declarations from the lookup results.
+static void RemoveUsingDecls(LookupResult &R) {
+ LookupResult::Filter F = R.makeFilter();
+ while (F.hasNext())
+ if (isUsingDecl(F.next()))
+ F.erase();
+
+ F.done();
+}
+
static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
if (D->isUsed() || D->hasAttr<UnusedAttr>())
return false;
@@ -572,11 +616,10 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
/// how to resolve this situation, merging decls or emitting
/// diagnostics as appropriate. If there was an error, set New to be invalid.
///
-void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
- // If either decl is known invalid already, set the new one to be invalid and
- // don't bother doing any merging checks.
- if (New->isInvalidDecl() || OldD->isInvalidDecl())
- return New->setInvalidDecl();
+void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) {
+ // If the new decl is known invalid already, don't bother doing any
+ // merging checks.
+ if (New->isInvalidDecl()) return;
// Allow multiple definitions for ObjC built-in typedefs.
// FIXME: Verify the underlying types are equivalent!
@@ -611,16 +654,25 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
}
// Fall through - the typedef name was not a builtin type.
}
+
// Verify the old decl was also a type.
- TypeDecl *Old = dyn_cast<TypeDecl>(OldD);
- if (!Old) {
+ TypeDecl *Old = 0;
+ if (!OldDecls.isSingleResult() ||
+ !(Old = dyn_cast<TypeDecl>(OldDecls.getFoundDecl()))) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
+
+ NamedDecl *OldD = OldDecls.getRepresentativeDecl();
if (OldD->getLocation().isValid())
Diag(OldD->getLocation(), diag::note_previous_definition);
+
return New->setInvalidDecl();
}
+ // If the old declaration is invalid, just give up here.
+ if (Old->isInvalidDecl())
+ return New->setInvalidDecl();
+
// Determine the "old" type we'll use for checking and diagnostics.
QualType OldType;
if (TypedefDecl *OldTypedef = dyn_cast<TypedefDecl>(Old))
@@ -977,18 +1029,19 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
/// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative
/// definitions here, since the initializer hasn't been attached.
///
-void Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
- // If either decl is invalid, make sure the new one is marked invalid and
- // don't do any other checking.
- if (New->isInvalidDecl() || OldD->isInvalidDecl())
- return New->setInvalidDecl();
+void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
+ // If the new decl is already invalid, don't do any other checking.
+ if (New->isInvalidDecl())
+ return;
// Verify the old decl was also a variable.
- VarDecl *Old = dyn_cast<VarDecl>(OldD);
- if (!Old) {
+ VarDecl *Old = 0;
+ if (!Previous.isSingleResult() ||
+ !(Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
- Diag(OldD->getLocation(), diag::note_previous_definition);
+ Diag(Previous.getRepresentativeDecl()->getLocation(),
+ diag::note_previous_definition);
return New->setInvalidDecl();
}
@@ -1403,6 +1456,33 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
return DeclPtrTy::make(Tag);
}
+/// We are trying to introduce the given name into the given context;
+/// check if there's an existing declaration that can't be overloaded.
+///
+/// \return true if this is a forbidden redeclaration
+bool Sema::CheckRedeclaration(DeclContext *DC,
+ DeclarationName Name,
+ SourceLocation NameLoc,
+ unsigned diagnostic) {
+ LookupResult R(*this, Name, NameLoc, LookupOrdinaryName,
+ ForRedeclaration);
+ LookupQualifiedName(R, DC);
+
+ if (R.empty()) return false;
+
+ if (R.getResultKind() == LookupResult::Found &&
+ isa<TagDecl>(R.getFoundDecl()))
+ return false;
+
+ // Pick a representative declaration.
+ NamedDecl *PrevDecl = (*R.begin())->getUnderlyingDecl();
+
+ Diag(NameLoc, diagnostic) << Name;
+ Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
+
+ return true;
+}
+
/// InjectAnonymousStructOrUnionMembers - Inject the members of the
/// anonymous struct or union AnonRecord into the owning context Owner
/// and scope S. This routine will be invoked just after we realize
@@ -1421,26 +1501,21 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
/// structs/unions into the owning context and scope as well.
bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
RecordDecl *AnonRecord) {
+ unsigned diagKind
+ = AnonRecord->isUnion() ? diag::err_anonymous_union_member_redecl
+ : diag::err_anonymous_struct_member_redecl;
+
bool Invalid = false;
for (RecordDecl::field_iterator F = AnonRecord->field_begin(),
FEnd = AnonRecord->field_end();
F != FEnd; ++F) {
if ((*F)->getDeclName()) {
- LookupResult R(*this, (*F)->getDeclName(), SourceLocation(),
- LookupOrdinaryName, ForRedeclaration);
- LookupQualifiedName(R, Owner);
- NamedDecl *PrevDecl = R.getAsSingleDecl(Context);
- if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
+ if (CheckRedeclaration(Owner, (*F)->getDeclName(),
+ (*F)->getLocation(), diagKind)) {
// C++ [class.union]p2:
// The names of the members of an anonymous union shall be
// distinct from the names of any other entity in the
// scope in which the anonymous union is declared.
- unsigned diagKind
- = AnonRecord->isUnion()? diag::err_anonymous_union_member_redecl
- : diag::err_anonymous_struct_member_redecl;
- Diag((*F)->getLocation(), diagKind)
- << (*F)->getDeclName();
- Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
Invalid = true;
} else {
// C++ [class.union]p2:
@@ -1765,19 +1840,20 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
}
DeclContext *DC;
- NamedDecl *PrevDecl;
NamedDecl *New;
DeclaratorInfo *DInfo = 0;
QualType R = GetTypeForDeclarator(D, S, &DInfo);
+ LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+ ForRedeclaration);
+
// See if this is a redefinition of a variable in the same scope.
if (D.getCXXScopeSpec().isInvalid()) {
DC = CurContext;
- PrevDecl = 0;
D.setInvalidType();
} else if (!D.getCXXScopeSpec().isSet()) {
- LookupNameKind NameKind = LookupOrdinaryName;
+ bool IsLinkageLookup = false;
// If the declaration we're planning to build will be a function
// or object with linkage, then look for another declaration with
@@ -1787,19 +1863,18 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
else if (R->isFunctionType()) {
if (CurContext->isFunctionOrMethod() ||
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)
- NameKind = LookupRedeclarationWithLinkage;
+ IsLinkageLookup = true;
} else if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern)
- NameKind = LookupRedeclarationWithLinkage;
+ IsLinkageLookup = true;
else if (CurContext->getLookupContext()->isTranslationUnit() &&
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)
- NameKind = LookupRedeclarationWithLinkage;
+ IsLinkageLookup = true;
- DC = CurContext;
- LookupResult R(*this, Name, D.getIdentifierLoc(), NameKind,
- ForRedeclaration);
+ if (IsLinkageLookup)
+ Previous.clear(LookupRedeclarationWithLinkage);
- LookupName(R, S, NameKind == LookupRedeclarationWithLinkage);
- PrevDecl = R.getAsSingleDecl(Context);
+ DC = CurContext;
+ LookupName(Previous, S, /* CreateBuiltins = */ IsLinkageLookup);
} else { // Something like "int foo::x;"
DC = computeDeclContext(D.getCXXScopeSpec(), true);
@@ -1819,10 +1894,11 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
RequireCompleteDeclContext(D.getCXXScopeSpec()))
return DeclPtrTy();
- LookupResult Res(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
- ForRedeclaration);
- LookupQualifiedName(Res, DC);
- PrevDecl = Res.getAsSingleDecl(Context);
+ LookupQualifiedName(Previous, DC);
+
+ // Don't consider using declarations as previous declarations for
+ // out-of-line members.
+ RemoveUsingDecls(Previous);
// C++ 7.3.1.2p2:
// Members (including explicit specializations of templates) of a named
@@ -1870,23 +1946,25 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
}
}
- if (PrevDecl && PrevDecl->isTemplateParameter()) {
+ if (Previous.isSingleResult() &&
+ Previous.getFoundDecl()->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
if (!D.isInvalidType())
- if (DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl))
+ if (DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
+ Previous.getFoundDecl()))
D.setInvalidType();
// Just pretend that we didn't see the previous declaration.
- PrevDecl = 0;
+ Previous.clear();
}
// In C++, the previous declaration we find might be a tag type
// (class or enum). In this case, the new declaration will hide the
// tag type. Note that this does does not apply if we're declaring a
// typedef (C++ [dcl.typedef]p4).
- if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag &&
+ if (Previous.isSingleTagDecl() &&
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef)
- PrevDecl = 0;
+ Previous.clear();
bool Redeclaration = false;
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
@@ -1895,13 +1973,13 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
return DeclPtrTy();
}
- New = ActOnTypedefDeclarator(S, D, DC, R, DInfo, PrevDecl, Redeclaration);
+ New = ActOnTypedefDeclarator(S, D, DC, R, DInfo, Previous, Redeclaration);
} else if (R->isFunctionType()) {
- New = ActOnFunctionDeclarator(S, D, DC, R, DInfo, PrevDecl,
+ New = ActOnFunctionDeclarator(S, D, DC, R, DInfo, Previous,
move(TemplateParamLists),
IsFunctionDefinition, Redeclaration);
} else {
- New = ActOnVariableDeclarator(S, D, DC, R, DInfo, PrevDecl,
+ New = ActOnVariableDeclarator(S, D, DC, R, DInfo, Previous,
move(TemplateParamLists),
Redeclaration);
}
@@ -1970,16 +2048,19 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T,
/// \brief Register the given locally-scoped external C declaration so
/// that it can be found later for redeclarations
void
-Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
+Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND,
+ const LookupResult &Previous,
Scope *S) {
assert(ND->getLexicalDeclContext()->isFunctionOrMethod() &&
"Decl is not a locally-scoped decl!");
// Note that we have a locally-scoped external with this name.
LocallyScopedExternalDecls[ND->getDeclName()] = ND;
- if (!PrevDecl)
+ if (!Previous.isSingleResult())
return;
+ NamedDecl *PrevDecl = Previous.getFoundDecl();
+
// If there was a previous declaration of this variable, it may be
// in our identifier chain. Update the identifier chain with the new
// declaration.
@@ -2015,7 +2096,7 @@ void Sema::DiagnoseFunctionSpecifiers(Declarator& D) {
NamedDecl*
Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
- NamedDecl* PrevDecl, bool &Redeclaration) {
+ LookupResult &Previous, bool &Redeclaration) {
// Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
if (D.getCXXScopeSpec().isSet()) {
Diag(D.getIdentifierLoc(), diag::err_qualified_typedef_declarator)
@@ -2040,11 +2121,13 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewTD, D);
+
// Merge the decl with the existing one if appropriate. If the decl is
// in an outer scope, it isn't the same thing.
- if (PrevDecl && isDeclInScope(PrevDecl, DC, S)) {
+ FilterLookupForScope(*this, Previous, DC, S, /*ConsiderLinkage*/ false);
+ if (!Previous.empty()) {
Redeclaration = true;
- MergeTypeDefDecl(NewTD, PrevDecl);
+ MergeTypeDefDecl(NewTD, Previous);
}
// C99 6.7.7p2: If a typedef name specifies a variably modified type
@@ -2155,7 +2238,7 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
NamedDecl*
Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
- NamedDecl* PrevDecl,
+ LookupResult &Previous,
MultiTemplateParamsArg TemplateParamLists,
bool &Redeclaration) {
DeclarationName Name = GetNameForDeclarator(D);
@@ -2285,22 +2368,21 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
SE->getByteLength())));
}
- // If name lookup finds a previous declaration that is not in the
- // same scope as the new declaration, this may still be an
- // acceptable redeclaration.
- if (PrevDecl && !isDeclInScope(PrevDecl, DC, S) &&
- !(NewVD->hasLinkage() &&
- isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
- PrevDecl = 0;
+ // Don't consider existing declarations that are in a different
+ // scope and are out-of-semantic-context declarations (if the new
+ // declaration has linkage).
+ FilterLookupForScope(*this, Previous, DC, S, NewVD->hasLinkage());
// Merge the decl with the existing one if appropriate.
- if (PrevDecl) {
- if (isa<FieldDecl>(PrevDecl) && D.getCXXScopeSpec().isSet()) {
+ if (!Previous.empty()) {
+ if (Previous.isSingleResult() &&
+ isa<FieldDecl>(Previous.getFoundDecl()) &&
+ D.getCXXScopeSpec().isSet()) {
// The user tried to define a non-static data member
// out-of-line (C++ [dcl.meaning]p1).
Diag(NewVD->getLocation(), diag::err_nonstatic_member_out_of_line)
<< D.getCXXScopeSpec().getRange();
- PrevDecl = 0;
+ Previous.clear();
NewVD->setInvalidDecl();
}
} else if (D.getCXXScopeSpec().isSet()) {
@@ -2311,17 +2393,18 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
NewVD->setInvalidDecl();
}
- CheckVariableDeclaration(NewVD, PrevDecl, Redeclaration);
+ CheckVariableDeclaration(NewVD, Previous, Redeclaration);
// This is an explicit specialization of a static data member. Check it.
if (isExplicitSpecialization && !NewVD->isInvalidDecl() &&
- CheckMemberSpecialization(NewVD, PrevDecl))
+ CheckMemberSpecialization(NewVD, Previous))
NewVD->setInvalidDecl();
-
+
// attributes declared post-definition are currently ignored
- if (PrevDecl) {
- const VarDecl *Def = 0, *PrevVD = dyn_cast<VarDecl>(PrevDecl);
- if (PrevVD->getDefinition(Def) && D.hasAttributes()) {
+ if (Previous.isSingleResult()) {
+ const VarDecl *Def = 0;
+ VarDecl *PrevDecl = dyn_cast<VarDecl>(Previous.getFoundDecl());
+ if (PrevDecl && PrevDecl->getDefinition(Def) && D.hasAttributes()) {
Diag(NewVD->getLocation(), diag::warn_attribute_precede_definition);
Diag(Def->getLocation(), diag::note_previous_definition);
}
@@ -2331,7 +2414,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// such variables.
if (CurContext->isFunctionOrMethod() && NewVD->isExternC() &&
!NewVD->isInvalidDecl())
- RegisterLocallyScopedExternCDecl(NewVD, PrevDecl, S);
+ RegisterLocallyScopedExternCDecl(NewVD, Previous, S);
return NewVD;
}
@@ -2346,7 +2429,8 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
/// that have been instantiated from a template.
///
/// Sets NewVD->isInvalidDecl() if an error was encountered.
-void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
+void Sema::CheckVariableDeclaration(VarDecl *NewVD,
+ LookupResult &Previous,
bool &Redeclaration) {
// If the decl is already known invalid, don't check it.
if (NewVD->isInvalidDecl())
@@ -2419,14 +2503,14 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
NewVD->setType(FixedTy);
}
- if (!PrevDecl && NewVD->isExternC()) {
+ if (Previous.empty() && NewVD->isExternC()) {
// Since we did not find anything by this name and we're declaring
// an extern "C" variable, look for a non-visible extern "C"
// declaration with the same name.
llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
= LocallyScopedExternalDecls.find(NewVD->getDeclName());
if (Pos != LocallyScopedExternalDecls.end())
- PrevDecl = Pos->second;
+ Previous.addDecl(Pos->second);
}
if (T->isVoidType() && !NewVD->hasExternalStorage()) {
@@ -2445,18 +2529,12 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
return NewVD->setInvalidDecl();
}
- if (PrevDecl) {
+ if (!Previous.empty()) {
Redeclaration = true;
- MergeVarDecl(NewVD, PrevDecl);
+ MergeVarDecl(NewVD, Previous);
}
}
-static bool isUsingDecl(Decl *D) {
- return isa<UsingDecl>(D) ||
- isa<UnresolvedUsingTypenameDecl>(D) ||
- isa<UnresolvedUsingValueDecl>(D);
-}
-
/// \brief Data used with FindOverriddenMethod
struct FindOverriddenMethodData {
Sema *S;
@@ -2477,8 +2555,7 @@ static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier,
Path.Decls.first != Path.Decls.second;
++Path.Decls.first) {
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*Path.Decls.first)) {
- OverloadedFunctionDecl::function_iterator MatchedDecl;
- if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD, MatchedDecl))
+ if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD))
return true;
}
}
@@ -2486,10 +2563,30 @@ static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier,
return false;
}
+/// AddOverriddenMethods - See if a method overrides any in the base classes,
+/// and if so, check that it's a valid override and remember it.
+void Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
+ // Look for virtual methods in base classes that this method might override.
+ CXXBasePaths Paths;
+ FindOverriddenMethodData Data;
+ Data.Method = MD;
+ Data.S = this;
+ if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) {
+ for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(),
+ E = Paths.found_decls_end(); I != E; ++I) {
+ if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
+ if (!CheckOverridingFunctionReturnType(MD, OldMD) &&
+ !CheckOverridingFunctionExceptionSpec(MD, OldMD))
+ MD->addOverriddenMethod(OldMD);
+ }
+ }
+ }
+}
+
NamedDecl*
Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, DeclaratorInfo *DInfo,
- NamedDecl* PrevDecl,
+ LookupResult &Previous,
MultiTemplateParamsArg TemplateParamLists,
bool IsFunctionDefinition, bool &Redeclaration) {
assert(R.getTypePtr()->isFunctionType());
@@ -2554,10 +2651,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
FunctionDecl *NewFD;
if (isFriend) {
- // DC is the namespace in which the function is being declared.
- assert((DC->isFileContext() || PrevDecl) && "previously-undeclared "
- "friend function being created in a non-namespace context");
-
// C++ [class.friend]p5
// A function can be defined in a friend declaration of a
// class . . . . Such a function is implicitly inline.
@@ -2733,37 +2826,29 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
}
+ // Filter out previous declarations that don't match the scope.
+ FilterLookupForScope(*this, Previous, DC, S, NewFD->hasLinkage());
+
if (isFriend) {
+ // DC is the namespace in which the function is being declared.
+ assert((DC->isFileContext() || !Previous.empty()) &&
+ "previously-undeclared friend function being created "
+ "in a non-namespace context");
+
if (FunctionTemplate) {
FunctionTemplate->setObjectOfFriendDecl(
- /* PreviouslyDeclared= */ PrevDecl != NULL);
+ /* PreviouslyDeclared= */ !Previous.empty());
FunctionTemplate->setAccess(AS_public);
}
else
- NewFD->setObjectOfFriendDecl(/* PreviouslyDeclared= */ PrevDecl != NULL);
+ NewFD->setObjectOfFriendDecl(/* PreviouslyDeclared= */ !Previous.empty());
NewFD->setAccess(AS_public);
}
- if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD)) {
- // Look for virtual methods in base classes that this method might override.
- CXXBasePaths Paths;
- FindOverriddenMethodData Data;
- Data.Method = NewMD;
- Data.S = this;
- if (cast<CXXRecordDecl>(DC)->lookupInBases(&FindOverriddenMethod, &Data,
- Paths)) {
- for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(),
- E = Paths.found_decls_end(); I != E; ++I) {
- if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
- if (!CheckOverridingFunctionReturnType(NewMD, OldMD) &&
- !CheckOverridingFunctionExceptionSpec(NewMD, OldMD))
- NewMD->addOverriddenMethod(OldMD);
- }
- }
- }
- }
+ if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD))
+ AddOverriddenMethods(cast<CXXRecordDecl>(DC), NewMD);
if (SC == FunctionDecl::Static && isa<CXXMethodDecl>(NewFD) &&
!CurContext->isRecord()) {
@@ -2847,14 +2932,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Finally, we know we have the right number of parameters, install them.
NewFD->setParams(Context, Params.data(), Params.size());
- // If name lookup finds a previous declaration that is not in the
- // same scope as the new declaration, this may still be an
- // acceptable redeclaration.
- if (PrevDecl && !isDeclInScope(PrevDecl, DC, S) &&
- !(NewFD->hasLinkage() &&
- isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
- PrevDecl = 0;
-
// If the declarator is a template-id, translate the parser's template
// argument list into our AST format.
bool HasExplicitTemplateArgs = false;
@@ -2891,22 +2968,26 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
isFunctionTemplateSpecialization = true;
}
}
-
+
if (isFunctionTemplateSpecialization) {
if (CheckFunctionTemplateSpecialization(NewFD, HasExplicitTemplateArgs,
LAngleLoc, TemplateArgs.data(),
TemplateArgs.size(), RAngleLoc,
- PrevDecl))
+ Previous))
NewFD->setInvalidDecl();
} else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD) &&
- CheckMemberSpecialization(NewFD, PrevDecl))
+ CheckMemberSpecialization(NewFD, Previous))
NewFD->setInvalidDecl();
// Perform semantic checking on the function declaration.
bool OverloadableAttrRequired = false; // FIXME: HACK!
- CheckFunctionDeclaration(NewFD, PrevDecl, isExplicitSpecialization,
+ CheckFunctionDeclaration(NewFD, Previous, isExplicitSpecialization,
Redeclaration, /*FIXME:*/OverloadableAttrRequired);
+ assert((NewFD->isInvalidDecl() || !Redeclaration ||
+ Previous.getResultKind() != LookupResult::FoundOverloaded) &&
+ "previous declaration set still overloaded");
+
if (D.getCXXScopeSpec().isSet() && !NewFD->isInvalidDecl()) {
// An out-of-line member function declaration must also be a
// definition (C++ [dcl.meaning]p1).
@@ -2918,7 +2999,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
<< D.getCXXScopeSpec().getRange();
NewFD->setInvalidDecl();
- } else if (!Redeclaration && (!PrevDecl || !isUsingDecl(PrevDecl))) {
+ } else if (!Redeclaration) {
// The user tried to provide an out-of-line definition for a
// function that is a member of a class or namespace, but there
// was no such member function declared (C++ [class.mfct]p2,
@@ -2948,8 +3029,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
isNearlyMatchingFunction(Context, cast<FunctionDecl>(*Func), NewFD))
Diag((*Func)->getLocation(), diag::note_member_def_close_match);
}
-
- PrevDecl = 0;
}
}
@@ -2960,8 +3039,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
ProcessDeclAttributes(S, NewFD, D);
// attributes declared post-definition are currently ignored
- if (Redeclaration && PrevDecl) {
- const FunctionDecl *Def, *PrevFD = dyn_cast<FunctionDecl>(PrevDecl);
+ if (Redeclaration && Previous.isSingleResult()) {
+ const FunctionDecl *Def;
+ FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
if (PrevFD && PrevFD->getBody(Def) && D.hasAttributes()) {
Diag(NewFD->getLocation(), diag::warn_attribute_precede_definition);
Diag(Def->getLocation(), diag::note_previous_definition);
@@ -2975,8 +3055,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
<< Redeclaration << NewFD;
- if (PrevDecl)
- Diag(PrevDecl->getLocation(),
+ if (!Previous.empty())
+ Diag(Previous.getRepresentativeDecl()->getLocation(),
diag::note_attribute_overloadable_prev_overload);
NewFD->addAttr(::new (Context) OverloadableAttr());
}
@@ -2985,7 +3065,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// map of such names.
if (CurContext->isFunctionOrMethod() && NewFD->isExternC()
&& !NewFD->isInvalidDecl())
- RegisterLocallyScopedExternCDecl(NewFD, PrevDecl, S);
+ RegisterLocallyScopedExternCDecl(NewFD, Previous, S);
// Set this FunctionDecl's range up to the right paren.
NewFD->setLocEnd(D.getSourceRange().getEnd());
@@ -3013,7 +3093,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
/// an explicit specialization of the previous declaration.
///
/// This sets NewFD->isInvalidDecl() to true if there was an error.
-void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
+void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD,
+ LookupResult &Previous,
bool IsExplicitSpecialization,
bool &Redeclaration,
bool &OverloadableAttrRequired) {
@@ -3032,27 +3113,26 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
CheckMain(NewFD);
// Check for a previous declaration of this name.
- if (!PrevDecl && NewFD->isExternC()) {
+ if (Previous.empty() && NewFD->isExternC()) {
// Since we did not find anything by this name and we're declaring
// an extern "C" function, look for a non-visible extern "C"
// declaration with the same name.
llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
= LocallyScopedExternalDecls.find(NewFD->getDeclName());
if (Pos != LocallyScopedExternalDecls.end())
- PrevDecl = Pos->second;
+ Previous.addDecl(Pos->second);
}
// Merge or overload the declaration with an existing declaration of
// the same name, if appropriate.
- if (PrevDecl) {
+ if (!Previous.empty()) {
// Determine whether NewFD is an overload of PrevDecl or
// a declaration that requires merging. If it's an overload,
// there's no more work to do here; we'll just add the new
// function to the scope.
- OverloadedFunctionDecl::function_iterator MatchedDecl;
if (!getLangOptions().CPlusPlus &&
- AllowOverloadingOfFunction(PrevDecl, Context)) {
+ AllowOverloadingOfFunction(Previous, Context)) {
OverloadableAttrRequired = true;
// Functions marked "overloadable" must have a prototype (that
@@ -3071,22 +3151,26 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
}
}
- if (PrevDecl &&
- (!AllowOverloadingOfFunction(PrevDecl, Context) ||
- !IsOverload(NewFD, PrevDecl, MatchedDecl)) && !isUsingDecl(PrevDecl)) {
- Redeclaration = true;
- Decl *OldDecl = PrevDecl;
-
- // If PrevDecl was an overloaded function, extract the
- // FunctionDecl that matched.
- if (isa<OverloadedFunctionDecl>(PrevDecl))
- OldDecl = *MatchedDecl;
+ NamedDecl *OldDecl = 0;
+ if (!Previous.empty()) {
+ if (!AllowOverloadingOfFunction(Previous, Context)) {
+ Redeclaration = true;
+ OldDecl = Previous.getFoundDecl();
+ } else if (!IsOverload(NewFD, Previous, OldDecl)) {
+ if (!isUsingDecl(OldDecl))
+ Redeclaration = true;
+ }
+ }
+ if (Redeclaration) {
// NewFD and OldDecl represent declarations that need to be
// merged.
if (MergeFunctionDecl(NewFD, OldDecl))
return NewFD->setInvalidDecl();
+ Previous.clear();
+ Previous.addDecl(OldDecl);
+
if (FunctionTemplateDecl *OldTemplateDecl
= dyn_cast<FunctionTemplateDecl>(OldDecl)) {
NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl());
@@ -4313,11 +4397,13 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
DeclContext *SearchDC = CurContext;
DeclContext *DC = CurContext;
- NamedDecl *PrevDecl = 0;
bool isStdBadAlloc = false;
bool Invalid = false;
- RedeclarationKind Redecl = (RedeclarationKind) (TUK != TUK_Reference);
+ RedeclarationKind Redecl = (TUK != TUK_Reference ? ForRedeclaration
+ : NotForRedeclaration);
+
+ LookupResult Previous(*this, Name, NameLoc, LookupTagName, Redecl);
if (Name && SS.isNotEmpty()) {
// We have a nested-name tag ('struct foo::bar').
@@ -4344,17 +4430,13 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
DC = computeDeclContext(SS, true);
SearchDC = DC;
// Look-up name inside 'foo::'.
- LookupResult R(*this, Name, NameLoc, LookupTagName, Redecl);
- LookupQualifiedName(R, DC);
+ LookupQualifiedName(Previous, DC);
- if (R.isAmbiguous())
+ if (Previous.isAmbiguous())
return DeclPtrTy();
- if (R.getResultKind() == LookupResult::Found)
- PrevDecl = dyn_cast<TagDecl>(R.getFoundDecl());
-
// A tag 'foo::bar' must already exist.
- if (!PrevDecl) {
+ if (Previous.empty()) {
Diag(NameLoc, diag::err_not_tag_in_scope) << Name << SS.getRange();
Name = 0;
Invalid = true;
@@ -4366,19 +4448,11 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// FIXME: We're looking into outer scopes here, even when we
// shouldn't be. Doing so can result in ambiguities that we
// shouldn't be diagnosing.
- LookupResult R(*this, Name, NameLoc, LookupTagName, Redecl);
- LookupName(R, S);
- if (R.isAmbiguous()) {
- // FIXME: This is not best way to recover from case like:
- //
- // struct S s;
- //
- // causes needless "incomplete type" error later.
- Name = 0;
- PrevDecl = 0;
- Invalid = true;
- } else
- PrevDecl = R.getAsSingleDecl(Context);
+ LookupName(Previous, S);
+
+ // Note: there used to be some attempt at recovery here.
+ if (Previous.isAmbiguous())
+ return DeclPtrTy();
if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
// FIXME: This makes sure that we ignore the contexts associated
@@ -4390,11 +4464,12 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
}
}
- if (PrevDecl && PrevDecl->isTemplateParameter()) {
+ if (Previous.isSingleResult() &&
+ Previous.getFoundDecl()->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
- DiagnoseTemplateParameterShadow(NameLoc, PrevDecl);
+ DiagnoseTemplateParameterShadow(NameLoc, Previous.getFoundDecl());
// Just pretend that we didn't see the previous declaration.
- PrevDecl = 0;
+ Previous.clear();
}
if (getLangOptions().CPlusPlus && Name && DC && StdNamespace &&
@@ -4402,15 +4477,17 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// This is a declaration of or a reference to "std::bad_alloc".
isStdBadAlloc = true;
- if (!PrevDecl && StdBadAlloc) {
+ if (Previous.empty() && StdBadAlloc) {
// std::bad_alloc has been implicitly declared (but made invisible to
// name lookup). Fill in this implicit declaration as the previous
// declaration, so that the declarations get chained appropriately.
- PrevDecl = StdBadAlloc;
+ Previous.addDecl(StdBadAlloc);
}
}
-
- if (PrevDecl) {
+
+ if (!Previous.empty()) {
+ assert(Previous.isSingleResult());
+ NamedDecl *PrevDecl = Previous.getFoundDecl();
if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) {
// If this is a use of a previous tag, or if the tag is already declared
// in the same scope (so that the definition/declaration completes or
@@ -4430,14 +4507,14 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
PrevTagDecl->getKindName());
else
Diag(KWLoc, diag::err_use_with_wrong_tag) << Name;
- Diag(PrevDecl->getLocation(), diag::note_previous_use);
+ Diag(PrevTagDecl->getLocation(), diag::note_previous_use);
if (SafeToContinue)
Kind = PrevTagDecl->getTagKind();
else {
// Recover by making this an anonymous redefinition.
Name = 0;
- PrevDecl = 0;
+ Previous.clear();
Invalid = true;
}
}
@@ -4450,7 +4527,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// For our current ASTs this shouldn't be a problem, but will
// need to be changed with DeclGroups.
if (TUK == TUK_Reference || TUK == TUK_Friend)
- return DeclPtrTy::make(PrevDecl);
+ return DeclPtrTy::make(PrevTagDecl);
// Diagnose attempts to redefine a tag.
if (TUK == TUK_Definition) {
@@ -4468,7 +4545,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// struct be anonymous, which will make any later
// references get the previous definition.
Name = 0;
- PrevDecl = 0;
+ Previous.clear();
Invalid = true;
}
} else {
@@ -4480,7 +4557,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Diag(PrevTagDecl->getLocation(),
diag::note_previous_definition);
Name = 0;
- PrevDecl = 0;
+ Previous.clear();
Invalid = true;
}
}
@@ -4497,7 +4574,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// scope, e.g. "struct foo; void bar() { struct foo; }", just create a
// new decl/type. We set PrevDecl to NULL so that the entities
// have distinct types.
- PrevDecl = 0;
+ Previous.clear();
}
// If we get here, we're going to create a new Decl. If PrevDecl
// is non-NULL, it's a definition of the tag declared by
@@ -4511,12 +4588,12 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
Name = 0;
- PrevDecl = 0;
+ Previous.clear();
Invalid = true;
} else {
// The existing declaration isn't relevant to us; we're in a
// new scope, so clear out the previous declaration.
- PrevDecl = 0;
+ Previous.clear();
}
}
} else if (TUK == TUK_Reference && SS.isEmpty() && Name &&
@@ -4570,6 +4647,10 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
CreateNewDecl:
+ TagDecl *PrevDecl = 0;
+ if (Previous.isSingleResult())
+ PrevDecl = cast<TagDecl>(Previous.getFoundDecl());
+
// If there is an identifier, use the location of the identifier as the
// location of the decl, otherwise use the location of the struct/union
// keyword.
@@ -4651,7 +4732,7 @@ CreateNewDecl:
// If this is a specialization of a member class (of a class template),
// check the specialization.
- if (isExplicitSpecialization && CheckMemberSpecialization(New, PrevDecl))
+ if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
Invalid = true;
if (Invalid)
@@ -4671,7 +4752,7 @@ CreateNewDecl:
// Mark this as a friend decl if applicable.
if (TUK == TUK_Friend)
- New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ PrevDecl != NULL);
+ New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ !Previous.empty());
// Set the access specifier.
if (!Invalid && TUK != TUK_Friend)
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 237a869f9084..bda1a6993934 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4668,7 +4668,8 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// FIXME: handle local classes
// Recover from invalid scope qualifiers as if they just weren't there.
- NamedDecl *PrevDecl = 0;
+ LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+ ForRedeclaration);
if (!ScopeQual.isInvalid() && ScopeQual.isSet()) {
// FIXME: RequireCompleteDeclContext
DC = computeDeclContext(ScopeQual);
@@ -4676,15 +4677,15 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// FIXME: handle dependent contexts
if (!DC) return DeclPtrTy();
- LookupResult R(*this, Name, Loc, LookupOrdinaryName, ForRedeclaration);
- LookupQualifiedName(R, DC);
- PrevDecl = R.getAsSingleDecl(Context);
+ LookupQualifiedName(Previous, DC);
// If searching in that context implicitly found a declaration in
// a different context, treat it like it wasn't found at all.
// TODO: better diagnostics for this case. Suggesting the right
// qualified scope would be nice...
- if (!PrevDecl || !PrevDecl->getDeclContext()->Equals(DC)) {
+ // FIXME: getRepresentativeDecl() is not right here at all
+ if (Previous.empty() ||
+ !Previous.getRepresentativeDecl()->getDeclContext()->Equals(DC)) {
D.setInvalidType();
Diag(Loc, diag::err_qualified_friend_not_found) << Name << T;
return DeclPtrTy();
@@ -4711,12 +4712,10 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
while (DC->isRecord())
DC = DC->getParent();
- LookupResult R(*this, Name, Loc, LookupOrdinaryName, ForRedeclaration);
- LookupQualifiedName(R, DC);
- PrevDecl = R.getAsSingleDecl(Context);
+ LookupQualifiedName(Previous, DC);
// TODO: decide what we think about using declarations.
- if (PrevDecl)
+ if (!Previous.empty())
break;
if (DC->isFileContext()) break;
@@ -4728,7 +4727,8 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// C++0x changes this for both friend types and functions.
// Most C++ 98 compilers do seem to give an error here, so
// we do, too.
- if (PrevDecl && DC->Equals(CurContext) && !getLangOptions().CPlusPlus0x)
+ if (!Previous.empty() && DC->Equals(CurContext)
+ && !getLangOptions().CPlusPlus0x)
Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
}
@@ -4745,7 +4745,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
}
bool Redeclaration = false;
- NamedDecl *ND = ActOnFunctionDeclarator(S, D, DC, T, DInfo, PrevDecl,
+ NamedDecl *ND = ActOnFunctionDeclarator(S, D, DC, T, DInfo, Previous,
move(TemplateParams),
IsDefinition,
Redeclaration);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 0c5569caff00..7da37affdc1e 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -828,9 +828,10 @@ void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
IM != EM; ++IM, ++IF) {
- if (Context.typesAreCompatible((*IF)->getType(), (*IM)->getType()) ||
- Context.QualifiedIdConformsQualifiedId((*IF)->getType(),
- (*IM)->getType()))
+ QualType ParmDeclTy = (*IF)->getType().getUnqualifiedType();
+ QualType ParmImpTy = (*IM)->getType().getUnqualifiedType();
+ if (Context.typesAreCompatible(ParmDeclTy, ParmImpTy) ||
+ Context.QualifiedIdConformsQualifiedId(ParmDeclTy, ParmImpTy))
continue;
Diag((*IM)->getLocation(), diag::warn_conflicting_param_types)
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 0eea169b0727..462bf13540eb 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1445,6 +1445,12 @@ QualType Sema::CheckPointerToMemberOperands(
}
}
+ if (isa<CXXZeroInitValueExpr>(rex->IgnoreParens())) {
+ // Diagnose use of pointer-to-member type which when used as
+ // the functional cast in a pointer-to-member expression.
+ Diag(Loc, diag::err_pointer_to_member_type) << isIndirect;
+ return QualType();
+ }
// C++ 5.5p2
// The result is an object or a function of the type specified by the
// second operand.
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 1f49b789d3f0..1957d7ff11b7 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -246,7 +246,11 @@ void LookupResult::resolveKind() {
unsigned N = Decls.size();
// Fast case: no possible ambiguity.
- if (N == 0) return;
+ if (N == 0) {
+ assert(ResultKind == NotFound);
+ return;
+ }
+
if (N == 1) {
if (isa<UnresolvedUsingValueDecl>(Decls[0]))
ResultKind = FoundUnresolvedValue;
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index adcd977e626d..daf5b7f36008 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -284,100 +284,102 @@ void ImplicitConversionSequence::DebugPrint() const {
// signature), IsOverload returns false and MatchedDecl will be set to
// point to the FunctionDecl for #2.
bool
-Sema::IsOverload(FunctionDecl *New, Decl* OldD,
- OverloadedFunctionDecl::function_iterator& MatchedDecl) {
- if (OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(OldD)) {
- // Is this new function an overload of every function in the
- // overload set?
- OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
- FuncEnd = Ovl->function_end();
- for (; Func != FuncEnd; ++Func) {
- if (!IsOverload(New, *Func, MatchedDecl)) {
- MatchedDecl = Func;
+Sema::IsOverload(FunctionDecl *New, LookupResult &Previous, NamedDecl *&Match) {
+ for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
+ I != E; ++I) {
+ NamedDecl *Old = (*I)->getUnderlyingDecl();
+ if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(Old)) {
+ if (!IsOverload(New, OldT->getTemplatedDecl())) {
+ Match = Old;
return false;
}
+ } else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(Old)) {
+ if (!IsOverload(New, OldF)) {
+ Match = Old;
+ return false;
+ }
+ } else {
+ // (C++ 13p1):
+ // Only function declarations can be overloaded; object and type
+ // declarations cannot be overloaded.
+ Match = Old;
+ return false;
}
+ }
- // This function overloads every function in the overload set.
- return true;
- } else if (FunctionTemplateDecl *Old = dyn_cast<FunctionTemplateDecl>(OldD))
- return IsOverload(New, Old->getTemplatedDecl(), MatchedDecl);
- else if (FunctionDecl* Old = dyn_cast<FunctionDecl>(OldD)) {
- FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
- FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
-
- // C++ [temp.fct]p2:
- // A function template can be overloaded with other function templates
- // and with normal (non-template) functions.
- if ((OldTemplate == 0) != (NewTemplate == 0))
- return true;
+ return true;
+}
- // Is the function New an overload of the function Old?
- QualType OldQType = Context.getCanonicalType(Old->getType());
- QualType NewQType = Context.getCanonicalType(New->getType());
+bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old) {
+ FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
+ FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
- // Compare the signatures (C++ 1.3.10) of the two functions to
- // determine whether they are overloads. If we find any mismatch
- // in the signature, they are overloads.
+ // C++ [temp.fct]p2:
+ // A function template can be overloaded with other function templates
+ // and with normal (non-template) functions.
+ if ((OldTemplate == 0) != (NewTemplate == 0))
+ return true;
- // If either of these functions is a K&R-style function (no
- // prototype), then we consider them to have matching signatures.
- if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
- isa<FunctionNoProtoType>(NewQType.getTypePtr()))
- return false;
+ // Is the function New an overload of the function Old?
+ QualType OldQType = Context.getCanonicalType(Old->getType());
+ QualType NewQType = Context.getCanonicalType(New->getType());
- FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
- FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
-
- // The signature of a function includes the types of its
- // parameters (C++ 1.3.10), which includes the presence or absence
- // of the ellipsis; see C++ DR 357).
- if (OldQType != NewQType &&
- (OldType->getNumArgs() != NewType->getNumArgs() ||
- OldType->isVariadic() != NewType->isVariadic() ||
- !std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
- NewType->arg_type_begin())))
- return true;
+ // Compare the signatures (C++ 1.3.10) of the two functions to
+ // determine whether they are overloads. If we find any mismatch
+ // in the signature, they are overloads.
- // C++ [temp.over.link]p4:
- // The signature of a function template consists of its function
- // signature, its return type and its template parameter list. The names
- // of the template parameters are significant only for establishing the
- // relationship between the template parameters and the rest of the
- // signature.
- //
- // We check the return type and template parameter lists for function
- // templates first; the remaining checks follow.
- if (NewTemplate &&
- (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
- OldTemplate->getTemplateParameters(),
- false, TPL_TemplateMatch) ||
- OldType->getResultType() != NewType->getResultType()))
- return true;
+ // If either of these functions is a K&R-style function (no
+ // prototype), then we consider them to have matching signatures.
+ if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
+ isa<FunctionNoProtoType>(NewQType.getTypePtr()))
+ return false;
- // If the function is a class member, its signature includes the
- // cv-qualifiers (if any) on the function itself.
- //
- // As part of this, also check whether one of the member functions
- // is static, in which case they are not overloads (C++
- // 13.1p2). While not part of the definition of the signature,
- // this check is important to determine whether these functions
- // can be overloaded.
- CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
- CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
- if (OldMethod && NewMethod &&
- !OldMethod->isStatic() && !NewMethod->isStatic() &&
- OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers())
- return true;
+ FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
+ FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
+
+ // The signature of a function includes the types of its
+ // parameters (C++ 1.3.10), which includes the presence or absence
+ // of the ellipsis; see C++ DR 357).
+ if (OldQType != NewQType &&
+ (OldType->getNumArgs() != NewType->getNumArgs() ||
+ OldType->isVariadic() != NewType->isVariadic() ||
+ !std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
+ NewType->arg_type_begin())))
+ return true;
- // The signatures match; this is not an overload.
- return false;
- } else {
- // (C++ 13p1):
- // Only function declarations can be overloaded; object and type
- // declarations cannot be overloaded.
- return false;
- }
+ // C++ [temp.over.link]p4:
+ // The signature of a function template consists of its function
+ // signature, its return type and its template parameter list. The names
+ // of the template parameters are significant only for establishing the
+ // relationship between the template parameters and the rest of the
+ // signature.
+ //
+ // We check the return type and template parameter lists for function
+ // templates first; the remaining checks follow.
+ if (NewTemplate &&
+ (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
+ OldTemplate->getTemplateParameters(),
+ false, TPL_TemplateMatch) ||
+ OldType->getResultType() != NewType->getResultType()))
+ return true;
+
+ // If the function is a class member, its signature includes the
+ // cv-qualifiers (if any) on the function itself.
+ //
+ // As part of this, also check whether one of the member functions
+ // is static, in which case they are not overloads (C++
+ // 13.1p2). While not part of the definition of the signature,
+ // this check is important to determine whether these functions
+ // can be overloaded.
+ CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
+ CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
+ if (OldMethod && NewMethod &&
+ !OldMethod->isStatic() && !NewMethod->isStatic() &&
+ OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers())
+ return true;
+
+ // The signatures match; this is not an overload.
+ return false;
}
/// TryImplicitConversion - Attempt to perform an implicit conversion
@@ -1545,18 +1547,23 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion(
}
bool
-Sema::DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType) {
+Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
ImplicitConversionSequence ICS;
OverloadCandidateSet CandidateSet;
OverloadingResult OvResult =
IsUserDefinedConversion(From, ToType, ICS.UserDefined,
CandidateSet, true, false, false);
- if (OvResult != OR_Ambiguous)
+ if (OvResult == OR_Ambiguous)
+ Diag(From->getSourceRange().getBegin(),
+ diag::err_typecheck_ambiguous_condition)
+ << From->getType() << ToType << From->getSourceRange();
+ else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty())
+ Diag(From->getSourceRange().getBegin(),
+ diag::err_typecheck_nonviable_condition)
+ << From->getType() << ToType << From->getSourceRange();
+ else
return false;
- Diag(From->getSourceRange().getBegin(),
- diag::err_typecheck_ambiguous_condition)
- << From->getType() << ToType << From->getSourceRange();
- PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
return true;
}
@@ -2072,7 +2079,7 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType,
if (!PerformImplicitConversion(From, ToType, Flavor,
/*AllowExplicit=*/false, Elidable))
return false;
- if (!DiagnoseAmbiguousUserDefinedConversion(From, ToType))
+ if (!DiagnoseMultipleUserDefinedConversion(From, ToType))
return Diag(From->getSourceRange().getBegin(),
diag::err_typecheck_convert_incompatible)
<< ToType << From->getType() << Flavor << From->getSourceRange();
@@ -2085,8 +2092,11 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType,
ImplicitConversionSequence
Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
QualType ClassType = Context.getTypeDeclType(Method->getParent());
- QualType ImplicitParamType
- = Context.getCVRQualifiedType(ClassType, Method->getTypeQualifiers());
+ // [class.dtor]p2: A destructor can be invoked for a const, volatile or
+ // const volatile object.
+ unsigned Quals = isa<CXXDestructorDecl>(Method) ?
+ Qualifiers::Const | Qualifiers::Volatile : Method->getTypeQualifiers();
+ QualType ImplicitParamType = Context.getCVRQualifiedType(ClassType, Quals);
// Set up the conversion sequence as a "bad" conversion, to allow us
// to exit early.
@@ -2101,7 +2111,7 @@ Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
assert(FromType->isRecordType());
- // The implicit object parmeter is has the type "reference to cv X",
+ // The implicit object parameter is has the type "reference to cv X",
// where X is the class of which the function is a member
// (C++ [over.match.funcs]p4). However, when finding an implicit
// conversion sequence for the argument, we are not allowed to
@@ -2192,7 +2202,7 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
if (!PerformImplicitConversion(From, Context.BoolTy, ICS, "converting"))
return false;
- if (!DiagnoseAmbiguousUserDefinedConversion(From, Context.BoolTy))
+ if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy))
return Diag(From->getSourceRange().getBegin(),
diag::err_typecheck_bool_condition)
<< From->getType() << From->getSourceRange();
@@ -3017,6 +3027,12 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
assert(PointerTy && "type was not a pointer type!");
QualType PointeeTy = PointerTy->getPointeeType();
+ // Don't add qualified variants of arrays. For one, they're not allowed
+ // (the qualifier would sink to the element type), and for another, the
+ // only overload situation where it matters is subscript or pointer +- int,
+ // and those shouldn't have qualifier variants anyway.
+ if (PointeeTy->isArrayType())
+ return true;
unsigned BaseCVR = PointeeTy.getCVRQualifiers();
if (const ConstantArrayType *Array =Context.getAsConstantArrayType(PointeeTy))
BaseCVR = Array->getElementType().getCVRQualifiers();
@@ -3057,6 +3073,12 @@ BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
assert(PointerTy && "type was not a member pointer type!");
QualType PointeeTy = PointerTy->getPointeeType();
+ // Don't add qualified variants of arrays. For one, they're not allowed
+ // (the qualifier would sink to the element type), and for another, the
+ // only overload situation where it matters is subscript or pointer +- int,
+ // and those shouldn't have qualifier variants anyway.
+ if (PointeeTy->isArrayType())
+ return true;
const Type *ClassTy = PointerTy->getClass();
// Iterate through all strict supersets of the pointee type's CVR
@@ -4873,11 +4895,13 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Opc == BinaryOperator::PtrMemD)
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
- // If this is one of the assignment operators, we only perform
- // overload resolution if the left-hand side is a class or
- // enumeration type (C++ [expr.ass]p3).
- if (Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign &&
- !Args[0]->getType()->isOverloadableType())
+ // If this is the assignment operator, we only perform overload resolution
+ // if the left-hand side is a class or enumeration type. This is actually
+ // a hack. The standard requires that we do overload resolution between the
+ // various built-in candidates, but as DR507 points out, this can lead to
+ // problems. So we do it this way, which pretty much follows what GCC does.
+ // Note that we go the traditional code path for compound assignment forms.
+ if (Opc==BinaryOperator::Assign && !Args[0]->getType()->isOverloadableType())
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
// Build an empty overload set.
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 466a0e37d49c..31cd30083ed4 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3538,15 +3538,17 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
const TemplateArgumentLoc *ExplicitTemplateArgs,
unsigned NumExplicitTemplateArgs,
SourceLocation RAngleLoc,
- NamedDecl *&PrevDecl) {
+ LookupResult &Previous) {
// The set of function template specializations that could match this
// explicit function template specialization.
typedef llvm::SmallVector<FunctionDecl *, 8> CandidateSet;
CandidateSet Candidates;
DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
- for (OverloadIterator Ovl(PrevDecl), OvlEnd; Ovl != OvlEnd; ++Ovl) {
- if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*Ovl)) {
+ for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
+ I != E; ++I) {
+ NamedDecl *Ovl = (*I)->getUnderlyingDecl();
+ if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Ovl)) {
// Only consider templates found within the same semantic lookup scope as
// FD.
if (!FDLookupContext->Equals(Ovl->getDeclContext()->getLookupContext()))
@@ -3637,7 +3639,8 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
// The "previous declaration" for this function template specialization is
// the prior function template specialization.
- PrevDecl = Specialization;
+ Previous.clear();
+ Previous.addDecl(Specialization);
return false;
}
@@ -3652,10 +3655,11 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
/// \param Member the member declaration, which will be updated to become a
/// specialization.
///
-/// \param PrevDecl the set of declarations, one of which may be specialized
-/// by this function specialization.
+/// \param Previous the set of declarations, one of which may be specialized
+/// by this function specialization; the set will be modified to contain the
+/// redeclared member.
bool
-Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
+Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
assert(!isa<TemplateDecl>(Member) && "Only for non-template members");
// Try to find the member we are instantiating.
@@ -3663,11 +3667,13 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
NamedDecl *InstantiatedFrom = 0;
MemberSpecializationInfo *MSInfo = 0;
- if (!PrevDecl) {
+ if (Previous.empty()) {
// Nowhere to look anyway.
} else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Member)) {
- for (OverloadIterator Ovl(PrevDecl), OvlEnd; Ovl != OvlEnd; ++Ovl) {
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Ovl)) {
+ for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
+ I != E; ++I) {
+ NamedDecl *D = (*I)->getUnderlyingDecl();
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
if (Context.hasSameType(Function->getType(), Method->getType())) {
Instantiation = Method;
InstantiatedFrom = Method->getInstantiatedFromMemberFunction();
@@ -3677,15 +3683,19 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
}
}
} else if (isa<VarDecl>(Member)) {
- if (VarDecl *PrevVar = dyn_cast<VarDecl>(PrevDecl))
+ VarDecl *PrevVar;
+ if (Previous.isSingleResult() &&
+ (PrevVar = dyn_cast<VarDecl>(Previous.getFoundDecl())))
if (PrevVar->isStaticDataMember()) {
- Instantiation = PrevDecl;
+ Instantiation = PrevVar;
InstantiatedFrom = PrevVar->getInstantiatedFromStaticDataMember();
MSInfo = PrevVar->getMemberSpecializationInfo();
}
} else if (isa<RecordDecl>(Member)) {
- if (CXXRecordDecl *PrevRecord = dyn_cast<CXXRecordDecl>(PrevDecl)) {
- Instantiation = PrevDecl;
+ CXXRecordDecl *PrevRecord;
+ if (Previous.isSingleResult() &&
+ (PrevRecord = dyn_cast<CXXRecordDecl>(Previous.getFoundDecl()))) {
+ Instantiation = PrevRecord;
InstantiatedFrom = PrevRecord->getInstantiatedFromMemberClass();
MSInfo = PrevRecord->getMemberSpecializationInfo();
}
@@ -3774,7 +3784,8 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
// Save the caller the trouble of having to figure out which declaration
// this specialization matches.
- PrevDecl = Instantiation;
+ Previous.clear();
+ Previous.addDecl(Instantiation);
return false;
}
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 7e618cd4faea..3f40ffcdc178 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -175,7 +175,10 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
// FIXME: In theory, we could have a previous declaration for variables that
// are not static data members.
bool Redeclaration = false;
- SemaRef.CheckVariableDeclaration(Var, 0, Redeclaration);
+ // FIXME: having to fake up a LookupResult is dumb.
+ LookupResult Previous(SemaRef, Var->getDeclName(), Var->getLocation(),
+ Sema::LookupOrdinaryName);
+ SemaRef.CheckVariableDeclaration(Var, Previous, Redeclaration);
if (D->isOutOfLine()) {
D->getLexicalDeclContext()->addDecl(Var);
@@ -680,27 +683,24 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
bool Redeclaration = false;
bool OverloadableAttrRequired = false;
- NamedDecl *PrevDecl = 0;
+ LookupResult Previous(SemaRef, Function->getDeclName(), SourceLocation(),
+ Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+
if (TemplateParams || !FunctionTemplate) {
// Look only into the namespace where the friend would be declared to
// find a previous declaration. This is the innermost enclosing namespace,
// as described in ActOnFriendFunctionDecl.
- LookupResult R(SemaRef, Function->getDeclName(), SourceLocation(),
- Sema::LookupOrdinaryName,
- Sema::ForRedeclaration);
- SemaRef.LookupQualifiedName(R, DC);
+ SemaRef.LookupQualifiedName(Previous, DC);
- PrevDecl = R.getAsSingleDecl(SemaRef.Context);
-
// In C++, the previous declaration we find might be a tag type
// (class or enum). In this case, the new declaration will hide the
// tag type. Note that this does does not apply if we're declaring a
// typedef (C++ [dcl.typedef]p4).
- if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
- PrevDecl = 0;
+ if (Previous.isSingleTagDecl())
+ Previous.clear();
}
- SemaRef.CheckFunctionDeclaration(Function, PrevDecl, false, Redeclaration,
+ SemaRef.CheckFunctionDeclaration(Function, Previous, false, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
// If the original function was part of a friend declaration,
@@ -709,6 +709,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
= TemplateParams? cast<NamedDecl>(D->getDescribedFunctionTemplate()) : D;
if (FromFriendD->getFriendObjectKind()) {
NamedDecl *ToFriendD = 0;
+ NamedDecl *PrevDecl;
if (TemplateParams) {
ToFriendD = cast<NamedDecl>(FunctionTemplate);
PrevDecl = FunctionTemplate->getPreviousDeclaration();
@@ -843,32 +844,31 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
if (InitMethodInstantiation(Method, D))
Method->setInvalidDecl();
- NamedDecl *PrevDecl = 0;
+ LookupResult Previous(SemaRef, Name, SourceLocation(),
+ Sema::LookupOrdinaryName, Sema::ForRedeclaration);
if (!FunctionTemplate || TemplateParams) {
- LookupResult R(SemaRef, Name, SourceLocation(),
- Sema::LookupOrdinaryName,
- Sema::ForRedeclaration);
- SemaRef.LookupQualifiedName(R, Owner);
- PrevDecl = R.getAsSingleDecl(SemaRef.Context);
+ SemaRef.LookupQualifiedName(Previous, Owner);
// In C++, the previous declaration we find might be a tag type
// (class or enum). In this case, the new declaration will hide the
// tag type. Note that this does does not apply if we're declaring a
// typedef (C++ [dcl.typedef]p4).
- if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
- PrevDecl = 0;
+ if (Previous.isSingleTagDecl())
+ Previous.clear();
}
bool Redeclaration = false;
bool OverloadableAttrRequired = false;
- SemaRef.CheckFunctionDeclaration(Method, PrevDecl, false, Redeclaration,
+ SemaRef.CheckFunctionDeclaration(Method, Previous, false, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
- if (!FunctionTemplate && (!Method->isInvalidDecl() || !PrevDecl) &&
+ if (!FunctionTemplate && (!Method->isInvalidDecl() || Previous.empty()) &&
!Method->getFriendObjectKind())
Owner->addDecl(Method);
+ SemaRef.AddOverriddenMethods(Record, Method);
+
return Method;
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 2bee32aa0fc8..ca680c279bdb 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -3037,18 +3037,21 @@ TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
template<typename Derived>
Sema::OwningStmtResult
TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
- // The case value expressions are not potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ OwningExprResult LHS(SemaRef), RHS(SemaRef);
+ {
+ // The case value expressions are not potentially evaluated.
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
- // Transform the left-hand case value.
- OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
- if (LHS.isInvalid())
- return SemaRef.StmtError();
+ // Transform the left-hand case value.
+ LHS = getDerived().TransformExpr(S->getLHS());
+ if (LHS.isInvalid())
+ return SemaRef.StmtError();
- // Transform the right-hand case value (for the GNU case-range extension).
- OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
- if (RHS.isInvalid())
- return SemaRef.StmtError();
+ // Transform the right-hand case value (for the GNU case-range extension).
+ RHS = getDerived().TransformExpr(S->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.StmtError();
+ }
// Build the case statement.
// Case statements are always rebuilt so that they will attached to their
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 4604db542980..f5c6a10ab3b9 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -1,6 +1,6 @@
// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic
// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic
-// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-purge-dead=false -verify %s
+// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-no-purge-dead -verify %s
// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
typedef unsigned uintptr_t;
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
index b32948b4a608..88bc813363fa 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
@@ -31,7 +31,7 @@ void test() {
}
namespace Numbers {
- struct Number {
+ struct Number { // expected-note 2 {{candidate}}
explicit Number(double d) : d(d) {}
double d;
};
@@ -57,9 +57,9 @@ void test3() {
int i = Ints::zero;
Numbers2::f(i);
- Numbers2::g(i); // expected-error {{incompatible type passing 'int'}}
+ Numbers2::g(i); // expected-error {{no viable conversion from 'int' to 'struct Numbers::Number' is possible}}
float f = Floats::zero;
Numbers2::f(f);
- Numbers2::g(f); // expected-error {{incompatible type passing 'float'}}
+ Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'struct Numbers::Number' is possible}}
}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
index 35e8c08a112f..9528c4b99cb8 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
@@ -4,7 +4,7 @@
template <unsigned N> class test {};
-class foo {};
+class foo {}; // expected-note {{candidate}}
test<0> foo(foo); // expected-note {{candidate}}
namespace Test0 {
@@ -38,7 +38,7 @@ namespace Test0 {
test<2> _1 = (foo)(a);
class Test0::foo b;
- test<2> _2 = (foo)(b); // expected-error {{incompatible type passing}}
+ test<2> _2 = (foo)(b); // expected-error {{no viable conversion from 'class Test0::foo' to 'class foo' is possible}}
}
}
}
diff --git a/test/CXX/special/class.dtor/p2.cpp b/test/CXX/special/class.dtor/p2.cpp
new file mode 100644
index 000000000000..c0e878fed2a5
--- /dev/null
+++ b/test/CXX/special/class.dtor/p2.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// PR5548
+struct A {~A();};
+void a(const A* x) {
+ x->~A();
+}
diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c
index cbbde8a9f3fd..32fc59f27fee 100644
--- a/test/CodeGen/libcalls.c
+++ b/test/CodeGen/libcalls.c
@@ -1,7 +1,7 @@
-// RUN: clang-cc -fmath-errno=1 -emit-llvm -o %t %s -triple i386-unknown-unknown
+// RUN: clang-cc -emit-llvm -o %t %s -triple i386-unknown-unknown
// RUN: grep "declare " %t | count 6
// RUN: grep "declare " %t | grep "@llvm." | count 1
-// RUN: clang-cc -fmath-errno=0 -emit-llvm -o %t %s -triple i386-unknown-unknown
+// RUN: clang-cc -fno-math-errno -emit-llvm -o %t %s -triple i386-unknown-unknown
// RUN: grep "declare " %t | count 6
// RUN: grep "declare " %t | grep -v "@llvm." | count 0
diff --git a/test/Driver/analyze.c b/test/Driver/analyze.c
index ff35cc57f1c0..bdbfbbfd88dd 100644
--- a/test/Driver/analyze.c
+++ b/test/Driver/analyze.c
@@ -6,4 +6,4 @@
// CHECK: "-analyze"
// CHECK: "-target-feature" "+sse"
-// CHECK: "--fmath-errno=0"
+// CHECK: "-fno-math-errno"
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
index c57a2b76246f..fe351843825f 100644
--- a/test/Driver/clang-translation.c
+++ b/test/Driver/clang-translation.c
@@ -5,7 +5,6 @@
// RUN: grep '"--relocation-model" "static"' %t.log
// RUN: grep '"--disable-fp-elim"' %t.log
// RUN: grep '"--unwind-tables=0"' %t.log
-// RUN: grep '"--fmath-errno=1"' %t.log
// RUN: grep '"-Os"' %t.log
// RUN: grep '"-o" .*clang-translation.*' %t.log
// RUN: grep '"--asm-verbose"' %t.log
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index b18f14758db1..3756a2f4d163 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -1,10 +1,9 @@
// RUN: clang -### -S -x c /dev/null -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fno-math-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings %s 2> %t
// RUN: grep -F '"-fblocks"' %t
-// RUN: grep -F '"--fmath-errno=1"' %t
// RUN: grep -F '"-fpascal-strings"' %t
// RUN: clang -### -S -x c /dev/null -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fno-math-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-wchar %s 2> %t
-// RUN: grep -F '"-fbuiltin=0"' %t
+// RUN: grep -F '"-fno-builtin"' %t
// RUN: grep -F '"-fno-common"' %t
-// RUN: grep -F '"--fmath-errno=0"' %t
+// RUN: grep -F '"-fno-math-errno"' %t
// RUN: grep -F '"-fno-show-source-location"' %t
// RUN: grep -F '"-fshort-wchar"' %t
diff --git a/test/Index/TestClassDecl.m b/test/Index/TestClassDecl.m
index 7256d2bffaf5..9009f78e574e 100644
--- a/test/Index/TestClassDecl.m
+++ b/test/Index/TestClassDecl.m
@@ -32,20 +32,20 @@ void function(Foo * arg)
// CHECK-scan: {start_line=13 start_col=24 end_line=16 end_col=1} FunctionDecl=function:13:6
// CHECK-scan: {start_line=16 start_col=2 end_line=52 end_col=1} Invalid Cursor => NoDeclFound
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=__int128_t:0:0 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=__uint128_t:0:0 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:0:0: StructDecl=objc_selector:0:0 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=SEL:0:0 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:0:0: ObjCInterfaceDecl=Protocol:0:0 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=id:0:0 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=Class:0:0 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:80:16: StructDecl=__va_list_tag:80:16 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:80:42: FieldDecl=gp_offset:80:42 [Context=__va_list_tag]
-// CHECK-load: <invalid loc>:80:63: FieldDecl=fp_offset:80:63 [Context=__va_list_tag]
-// CHECK-load: <invalid loc>:80:81: FieldDecl=overflow_arg_area:80:81 [Context=__va_list_tag]
-// CHECK-load: <invalid loc>:80:107: FieldDecl=reg_save_area:80:107 [Context=__va_list_tag]
-// CHECK-load: <invalid loc>:80:123: TypedefDecl=__va_list_tag:80:123 [Context=TestClassDecl.m]
-// CHECK-load: <invalid loc>:80:159: TypedefDecl=__builtin_va_list:80:159 [Context=TestClassDecl.m]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
// CHECK-load: TestClassDecl.m:10:12: ObjCInterfaceDecl=Foo:10:1 [Context=TestClassDecl.m]
// CHECK-load: TestClassDecl.m:13:6: FunctionDefn=function [Context=TestClassDecl.m]
// CHECK-load: TestClassDecl.m:13:21: ParmDecl=arg:13:21 [Context=function]
diff --git a/test/Index/TestClassForwardDecl.m b/test/Index/TestClassForwardDecl.m
index 4584445d0b9e..31b7c6c170c0 100644
--- a/test/Index/TestClassForwardDecl.m
+++ b/test/Index/TestClassForwardDecl.m
@@ -27,20 +27,20 @@ void function(Foo * arg)
// CHECK-scan: {start_line=10 start_col=24 end_line=13 end_col=1} FunctionDecl=function:10:6
// CHECK-scan: {start_line=13 start_col=2 end_line=46 end_col=1} Invalid Cursor => NoDeclFound
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=__int128_t:0:0 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=__uint128_t:0:0 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:0:0: StructDecl=objc_selector:0:0 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=SEL:0:0 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:0:0: ObjCInterfaceDecl=Protocol:0:0 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=id:0:0 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:0:0: TypedefDecl=Class:0:0 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:80:16: StructDecl=__va_list_tag:80:16 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:80:42: FieldDecl=gp_offset:80:42 [Context=__va_list_tag]
-// CHECK-load: <invalid loc>:80:63: FieldDecl=fp_offset:80:63 [Context=__va_list_tag]
-// CHECK-load: <invalid loc>:80:81: FieldDecl=overflow_arg_area:80:81 [Context=__va_list_tag]
-// CHECK-load: <invalid loc>:80:107: FieldDecl=reg_save_area:80:107 [Context=__va_list_tag]
-// CHECK-load: <invalid loc>:80:123: TypedefDecl=__va_list_tag:80:123 [Context=TestClassForwardDecl.m]
-// CHECK-load: <invalid loc>:80:159: TypedefDecl=__builtin_va_list:80:159 [Context=TestClassForwardDecl.m]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
// CHECK-load: TestClassForwardDecl.m:10:6: FunctionDefn=function [Context=TestClassForwardDecl.m]
// CHECK-load: TestClassForwardDecl.m:10:21: ParmDecl=arg:10:21 [Context=function]
diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m
index 5427764ab7a7..7ab143546df6 100644
--- a/test/Index/c-index-api-loadTU-test.m
+++ b/test/Index/c-index-api-loadTU-test.m
@@ -1,21 +1,21 @@
// RUN: clang-cc -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -o %t.ast
// RUN: c-index-test -test-load-tu %t.ast all | FileCheck %s
-// CHECK: <invalid loc>:0:0: TypedefDecl=__int128_t:0:0 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:0:0: TypedefDecl=__uint128_t:0:0 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:0:0: StructDecl=objc_selector:0:0 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:0:0: TypedefDecl=SEL:0:0 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:0:0: ObjCInterfaceDecl=Protocol:0:0 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:0:0: TypedefDecl=id:0:0 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:0:0: TypedefDecl=Class:0:0 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:80:16: StructDecl=__va_list_tag:80:16 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:80:42: FieldDecl=gp_offset:80:42 [Context=__va_list_tag]
-// CHECK: <invalid loc>:80:63: FieldDecl=fp_offset:80:63 [Context=__va_list_tag]
-// CHECK: <invalid loc>:80:81: FieldDecl=overflow_arg_area:80:81 [Context=__va_list_tag]
-// CHECK: <invalid loc>:80:107: FieldDecl=reg_save_area:80:107 [Context=__va_list_tag]
-// CHECK: <invalid loc>:80:123: TypedefDecl=__va_list_tag:80:123 [Context=c-index-api-loadTU-test.m]
-// CHECK: <invalid loc>:80:159: TypedefDecl=__builtin_va_list:80:159 [Context=c-index-api-loadTU-test.m]
-//
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@interface Foo
{
diff --git a/test/Index/complete-categories.m b/test/Index/complete-categories.m
new file mode 100644
index 000000000000..92b14db936f2
--- /dev/null
+++ b/test/Index/complete-categories.m
@@ -0,0 +1,39 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+ matter for this test. */
+
+@interface I1 @end
+@interface I2 @end
+@interface I3 : I2 @end
+
+@interface I1(Cat1) @end
+@interface I1(Cat2) @end
+@interface I1(Cat3) @end
+
+@interface I2 (Cat2) @end
+@interface I2 (Cat3) @end
+@interface I2 (Cat2) @end
+@interface I3 (Cat1) @end
+@interface I3 (Cat2) @end
+
+@implementation I1(Cat2) @end
+@implementation I1(Cat3) @end
+@implementation I3(Cat2) @end
+
+// RUN: c-index-test -code-completion-at=%s:12:16 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat2}
+// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat3}
+// RUN: c-index-test -code-completion-at=%s:13:16 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC2-NEXT: ObjCCategoryDecl:{TypedText Cat3}
+// RUN: c-index-test -code-completion-at=%s:18:20 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat2}
+// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat3}
+// RUN: c-index-test -code-completion-at=%s:19:20 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC4-NEXT: ObjCCategoryDecl:{TypedText Cat3}
+// RUN: c-index-test -code-completion-at=%s:20:20 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: ObjCCategoryDecl:{TypedText Cat1}
+// CHECK-CC5-NEXT: ObjCCategoryDecl:{TypedText Cat2}
+// CHECK-CC5-NEXT: ObjCCategoryDecl:{TypedText Cat3}
diff --git a/test/Index/complete-interfaces.m b/test/Index/complete-interfaces.m
new file mode 100644
index 000000000000..229ec2dcbe27
--- /dev/null
+++ b/test/Index/complete-interfaces.m
@@ -0,0 +1,43 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+ matter for this test. */
+
+@class Int1, Int2, Int3, Int4;
+
+@interface Int3
+{
+}
+@end
+
+@interface Int2 : Int3
+{
+}
+@end
+
+@implementation Int2
+@end
+
+@implementation Int3
+@end
+
+// RUN: c-index-test -code-completion-at=%s:6:12 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:11:19 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:16:17 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int2}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int4}
+// RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: ObjCInterfaceDecl:{TypedText Int1}
+// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int3}
+// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int4}
diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m
index 8f235d39bec2..b692986cfda9 100644
--- a/test/Index/complete-objc-message.m
+++ b/test/Index/complete-objc-message.m
@@ -82,6 +82,19 @@ void test_qual_id(id<FooTestProtocol,FooTestProtocol2> ptr) {
[ptr protocolInstanceMethod:1];
}
+@interface Overload
+- (int)Method:(int)i;
+- (int)Method;
+- (int)Method:(float)f Arg1:(int)i1 Arg2:(int)i2;
+- (int)Method:(float)f Arg1:(int)i1 OtherArg:(id)obj;
+- (int)Method:(float)f SomeArg:(int)i1 OtherArg:(id)obj;
+- (int)OtherMethod:(float)f Arg1:(int)i1 Arg2:(int)i2;
+@end
+
+void test_overload(Overload *ovl) {
+ [ovl Method:1 Arg1:1 OtherArg:ovl];
+}
+
// RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: {TypedText categoryClassMethod}
// CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)a}{Text withKeyword:}{Placeholder (int)b}
@@ -104,4 +117,18 @@ void test_qual_id(id<FooTestProtocol,FooTestProtocol2> ptr) {
// RUN: c-index-test -code-completion-at=%s:82:8 %s | FileCheck -check-prefix=CHECK-CC6 %s
// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText protocolInstanceMethod:}{Placeholder (int)value}
// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText secondProtocolInstanceMethod}
-
+// RUN: c-index-test -code-completion-at=%s:95:8 %s | FileCheck -check-prefix=CHECK-CC7 %s
+// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method}
+// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method:}{Placeholder (int)i}
+// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method:}{Placeholder (float)f}{Text SomeArg:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText OtherMethod:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2}
+// RUN: c-index-test -code-completion-at=%s:95:17 %s | FileCheck -check-prefix=CHECK-CC8 %s
+// CHECK-CC8: ObjCInstanceMethodDecl:{Informative Method:}{TypedText }
+// CHECK-CC8: ObjCInstanceMethodDecl:{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2}
+// CHECK-CC8: ObjCInstanceMethodDecl:{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj}
+// CHECK-CC8: ObjCInstanceMethodDecl:{Informative Method:}{TypedText SomeArg:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj}
+// RUN: c-index-test -code-completion-at=%s:95:24 %s | FileCheck -check-prefix=CHECK-CC9 %s
+// CHECK-CC9: ObjCInstanceMethodDecl:{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)i2}
+// CHECK-CC9: ObjCInstanceMethodDecl:{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)obj}
diff --git a/test/Index/complete-properties.m b/test/Index/complete-properties.m
new file mode 100644
index 000000000000..a99b1d1413d9
--- /dev/null
+++ b/test/Index/complete-properties.m
@@ -0,0 +1,40 @@
+/* Note: the RUN lines are near the end of the file, since line/column
+ matter for this test. */
+
+@interface I1
+{
+ id StoredProp3;
+ int RandomIVar;
+}
+@property int Prop0;
+@property int Prop1;
+@property float Prop2;
+@end
+
+@interface I2 : I1
+@property id Prop3;
+@property id Prop4;
+@end
+
+@implementation I2
+@synthesize Prop2, Prop1, Prop3 = StoredProp3;
+@dynamic Prop4;
+@end
+
+// RUN: c-index-test -code-completion-at=%s:20:13 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop0}
+// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop1}
+// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop2}
+// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop3}
+// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop4}
+// RUN: c-index-test -code-completion-at=%s:20:20 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCPropertyDecl:{TypedText Prop0}
+// CHECK-CC2: ObjCPropertyDecl:{TypedText Prop1}
+// CHECK-CC2-NEXT: ObjCPropertyDecl:{TypedText Prop3}
+// CHECK-CC2: ObjCPropertyDecl:{TypedText Prop4}
+// RUN: c-index-test -code-completion-at=%s:20:35 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCIvarDecl:{TypedText RandomIVar}
+// CHECK-CC3: ObjCIvarDecl:{TypedText StoredProp3}
+// RUN: c-index-test -code-completion-at=%s:21:10 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCPropertyDecl:{TypedText Prop0}
+// CHECK-CC4-NEXT: ObjCPropertyDecl:{TypedText Prop4}
diff --git a/test/Index/complete-property-flags.m b/test/Index/complete-property-flags.m
new file mode 100644
index 000000000000..cd3696f11c7d
--- /dev/null
+++ b/test/Index/complete-property-flags.m
@@ -0,0 +1,23 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@interface Foo {
+ void *isa;
+}
+@property(copy) Foo *myprop;
+@property(retain, nonatomic) id xx;
+// RUN: c-index-test -code-completion-at=%s:7:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText assign}
+// CHECK-CC1-NEXT: {TypedText copy}
+// CHECK-CC1-NEXT: {TypedText getter}{Text = }{Placeholder method}
+// CHECK-CC1-NEXT: {TypedText nonatomic}
+// CHECK-CC1-NEXT: {TypedText readonly}
+// CHECK-CC1-NEXT: {TypedText readwrite}
+// CHECK-CC1-NEXT: {TypedText retain}
+// CHECK-CC1-NEXT: {TypedText setter}{Text = }{Placeholder method}
+// RUN: c-index-test -code-completion-at=%s:8:18 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: {TypedText getter}{Text = }{Placeholder method}
+// CHECK-CC2-NEXT: {TypedText nonatomic}
+// CHECK-CC2-NEXT: {TypedText readwrite}
+// CHECK-CC2-NEXT: {TypedText setter}{Text = }{Placeholder method}
+@end
diff --git a/test/Index/complete-property-getset.m b/test/Index/complete-property-getset.m
new file mode 100644
index 000000000000..a2a80533a32b
--- /dev/null
+++ b/test/Index/complete-property-getset.m
@@ -0,0 +1,41 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@interface Super { }
+- (int)getter1;
++ (int)getter2_not_instance;
+- (int)getter2_not:(int)x;
+- (int)getter3;
+- (void)setter1:(int)x;
++ (void)setter2_not_inst:(int)x;
++ (void)setter2_many_args:(int)x second:(int)y;
+- (void)setter3:(int)y;
+@property (getter = getter1, setter = setter1:) int blah;
+@end
+
+@interface Sub : Super { }
+- (int)getter4;
+- (void)setter4:(int)x;
+@property (getter = getter4, setter = setter1:) int blarg;
+@end
+
+// RUN: c-index-test -code-completion-at=%s:13:21 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCInstanceMethodDecl:{TypedText getter1}
+// CHECK-CC1-NOT: getter2
+// CHECK-CC1: ObjCInstanceMethodDecl:{TypedText getter3}
+// RUN: c-index-test -code-completion-at=%s:13:39 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText getter2_not:}
+// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText setter1:}
+// CHECK-CC2-NOT: setter2
+// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText setter3:}
+// RUN: c-index-test -code-completion-at=%s:19:21 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText getter1}
+// CHECK-CC3-NOT: getter2
+// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText getter3}
+// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText getter4}
+// RUN: c-index-test -code-completion-at=%s:19:39 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText getter2_not:}{Informative (int)x}
+// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText setter1:}{Informative (int)x}
+// CHECK-CC4-NOT: setter2
+// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText setter3:}{Informative (int)y}
+// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText setter4:}{Informative (int)x}
diff --git a/test/Parser/objc-synthesized-recover.m b/test/Parser/objc-synthesized-recover.m
new file mode 100644
index 000000000000..7de1a5794222
--- /dev/null
+++ b/test/Parser/objc-synthesized-recover.m
@@ -0,0 +1,15 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+@interface I1
+{
+ int value;
+ int value2;
+}
+@property int value;
+@property int value2;
+@end
+
+@implementation I1
+@synthesize value, - value2; // expected-error{{expected a property name}}
+@synthesize value2;
+@end
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 2926900e78c5..aae218db46da 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -155,8 +155,9 @@
// ARM:#define __INT64_TYPE__ long long int
// ARM:#define __INT8_TYPE__ char
// ARM:#define __INTMAX_MAX__ 9223372036854775807LL
-// ARM:#define __INTMAX_TYPE__ long long int
+// ARM:#define __INTMAX_WIDTH__ 64
// ARM:#define __INTPTR_TYPE__ long int
+// ARM:#define __INTPTR_WIDTH__ 32
// ARM:#define __INT_MAX__ 2147483647
// ARM:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
// ARM:#define __LDBL_DIG__ 15
@@ -181,7 +182,6 @@
// ARM:#define __SHRT_MAX__ 32767
// ARM:#define __SIZE_TYPE__ unsigned int
// ARM:#define __THUMB_INTERWORK__ 1
-// ARM:#define __UINTMAX_TYPE__ long long unsigned int
// ARM:#define __USER_LABEL_PREFIX__ _
// ARM:#define __VFP_FP__ 1
// ARM:#define __WCHAR_MAX__ 2147483647
@@ -233,8 +233,9 @@
// BFIN:#define __INT64_TYPE__ long long int
// BFIN:#define __INT8_TYPE__ char
// BFIN:#define __INTMAX_MAX__ 9223372036854775807LL
-// BFIN:#define __INTMAX_TYPE__ long long int
+// BFIN:#define __INTMAX_WIDTH__ 64
// BFIN:#define __INTPTR_TYPE__ long int
+// BFIN:#define __INTPTR_WIDTH__ 32
// BFIN:#define __INT_MAX__ 2147483647
// BFIN:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
// BFIN:#define __LDBL_DIG__ 15
@@ -257,7 +258,6 @@
// BFIN:#define __SCHAR_MAX__ 127
// BFIN:#define __SHRT_MAX__ 32767
// BFIN:#define __SIZE_TYPE__ long unsigned int
-// BFIN:#define __UINTMAX_TYPE__ long long unsigned int
// BFIN:#define __USER_LABEL_PREFIX__ _
// BFIN:#define __WCHAR_MAX__ 2147483647
// BFIN:#define __WCHAR_TYPE__ int
@@ -304,8 +304,9 @@
// I386:#define __INT64_TYPE__ long long int
// I386:#define __INT8_TYPE__ char
// I386:#define __INTMAX_MAX__ 9223372036854775807LL
-// I386:#define __INTMAX_TYPE__ long long int
+// I386:#define __INTMAX_WIDTH__ 64
// I386:#define __INTPTR_TYPE__ int
+// I386:#define __INTPTR_WIDTH__ 32
// I386:#define __INT_MAX__ 2147483647
// I386:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
// I386:#define __LDBL_DIG__ 18
@@ -331,7 +332,6 @@
// I386:#define __SCHAR_MAX__ 127
// I386:#define __SHRT_MAX__ 32767
// I386:#define __SIZE_TYPE__ unsigned int
-// I386:#define __UINTMAX_TYPE__ long long unsigned int
// I386:#define __USER_LABEL_PREFIX__ _
// I386:#define __WCHAR_MAX__ 2147483647
// I386:#define __WCHAR_TYPE__ int
@@ -381,8 +381,9 @@
// MSP430:#define __INT32_TYPE__ long int
// MSP430:#define __INT8_TYPE__ char
// MSP430:#define __INTMAX_MAX__ 2147483647L
-// MSP430:#define __INTMAX_TYPE__ long int
+// MSP430:#define __INTMAX_WIDTH__ 32
// MSP430:#define __INTPTR_TYPE__ short
+// MSP430:#define __INTPTR_WIDTH__ 16
// MSP430:#define __INT_MAX__ 32767
// MSP430:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
// MSP430:#define __LDBL_DIG__ 15
@@ -406,7 +407,6 @@
// MSP430:#define __SCHAR_MAX__ 127
// MSP430:#define __SHRT_MAX__ 32767
// MSP430:#define __SIZE_TYPE__ unsigned int
-// MSP430:#define __UINTMAX_TYPE__ long unsigned int
// MSP430:#define __USER_LABEL_PREFIX__ _
// MSP430:#define __WCHAR_MAX__ 32767
// MSP430:#define __WCHAR_TYPE__ int
@@ -451,8 +451,9 @@
// PIC16:#define __INT32_TYPE__ long int
// PIC16:#define __INT8_TYPE__ char
// PIC16:#define __INTMAX_MAX__ 2147483647L
-// PIC16:#define __INTMAX_TYPE__ long int
+// PIC16:#define __INTMAX_WIDTH__ 32
// PIC16:#define __INTPTR_TYPE__ short
+// PIC16:#define __INTPTR_WIDTH__ 16
// PIC16:#define __INT_MAX__ 32767
// PIC16:#define __LDBL_DENORM_MIN__ 1.40129846e-45F
// PIC16:#define __LDBL_DIG__ 6
@@ -475,7 +476,6 @@
// PIC16:#define __SCHAR_MAX__ 127
// PIC16:#define __SHRT_MAX__ 32767
// PIC16:#define __SIZE_TYPE__ unsigned int
-// PIC16:#define __UINTMAX_TYPE__ long unsigned int
// PIC16:#define __USER_LABEL_PREFIX__ _
// PIC16:#define __WCHAR_MAX__ 32767
// PIC16:#define __WCHAR_TYPE__ int
@@ -533,8 +533,9 @@
// PPC64:#define __INT64_TYPE__ long int
// PPC64:#define __INT8_TYPE__ char
// PPC64:#define __INTMAX_MAX__ 9223372036854775807L
-// PPC64:#define __INTMAX_TYPE__ long int
+// PPC64:#define __INTMAX_WIDTH__ 64
// PPC64:#define __INTPTR_TYPE__ long int
+// PPC64:#define __INTPTR_WIDTH__ 64
// PPC64:#define __INT_MAX__ 2147483647
// PPC64:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
// PPC64:#define __LDBL_DIG__ 15
@@ -562,7 +563,6 @@
// PPC64:#define __SCHAR_MAX__ 127
// PPC64:#define __SHRT_MAX__ 32767
// PPC64:#define __SIZE_TYPE__ long unsigned int
-// PPC64:#define __UINTMAX_TYPE__ long unsigned int
// PPC64:#define __USER_LABEL_PREFIX__ _
// PPC64:#define __WCHAR_MAX__ 2147483647
// PPC64:#define __WCHAR_TYPE__ int
@@ -612,8 +612,9 @@
// PPC:#define __INT64_TYPE__ long long int
// PPC:#define __INT8_TYPE__ char
// PPC:#define __INTMAX_MAX__ 9223372036854775807LL
-// PPC:#define __INTMAX_TYPE__ long long int
+// PPC:#define __INTMAX_WIDTH__ 64
// PPC:#define __INTPTR_TYPE__ long int
+// PPC:#define __INTPTR_WIDTH__ 32
// PPC:#define __INT_MAX__ 2147483647
// PPC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
// PPC:#define __LDBL_DIG__ 15
@@ -640,7 +641,6 @@
// PPC:#define __SCHAR_MAX__ 127
// PPC:#define __SHRT_MAX__ 32767
// PPC:#define __SIZE_TYPE__ long unsigned int
-// PPC:#define __UINTMAX_TYPE__ long long unsigned int
// PPC:#define __USER_LABEL_PREFIX__ _
// PPC:#define __WCHAR_MAX__ 2147483647
// PPC:#define __WCHAR_TYPE__ int
@@ -686,8 +686,9 @@
// S390X:#define __INT64_TYPE__ long int
// S390X:#define __INT8_TYPE__ char
// S390X:#define __INTMAX_MAX__ 9223372036854775807LL
-// S390X:#define __INTMAX_TYPE__ long long int
+// S390X:#define __INTMAX_WIDTH__ 64
// S390X:#define __INTPTR_TYPE__ long int
+// S390X:#define __INTPTR_WIDTH__ 64
// S390X:#define __INT_MAX__ 2147483647
// S390X:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
// S390X:#define __LDBL_DIG__ 15
@@ -710,7 +711,6 @@
// S390X:#define __SCHAR_MAX__ 127
// S390X:#define __SHRT_MAX__ 32767
// S390X:#define __SIZE_TYPE__ long unsigned int
-// S390X:#define __UINTMAX_TYPE__ long long unsigned int
// S390X:#define __USER_LABEL_PREFIX__ _
// S390X:#define __WCHAR_MAX__ 2147483647
// S390X:#define __WCHAR_TYPE__ int
@@ -756,8 +756,9 @@
// SPARC:#define __INT64_TYPE__ long long int
// SPARC:#define __INT8_TYPE__ char
// SPARC:#define __INTMAX_MAX__ 9223372036854775807LL
-// SPARC:#define __INTMAX_TYPE__ long long int
+// SPARC:#define __INTMAX_WIDTH__ 64
// SPARC:#define __INTPTR_TYPE__ long int
+// SPARC:#define __INTPTR_WIDTH__ 32
// SPARC:#define __INT_MAX__ 2147483647
// SPARC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
// SPARC:#define __LDBL_DIG__ 15
@@ -781,7 +782,6 @@
// SPARC:#define __SCHAR_MAX__ 127
// SPARC:#define __SHRT_MAX__ 32767
// SPARC:#define __SIZE_TYPE__ long unsigned int
-// SPARC:#define __UINTMAX_TYPE__ long long unsigned int
// SPARC:#define __USER_LABEL_PREFIX__ _
// SPARC:#define __VERSION__ "4.2.1 Compatible Clang Compiler"
// SPARC:#define __WCHAR_MAX__ 2147483647
@@ -828,8 +828,9 @@
// TCE:#define __INT32_TYPE__ int
// TCE:#define __INT8_TYPE__ char
// TCE:#define __INTMAX_MAX__ 2147483647L
-// TCE:#define __INTMAX_TYPE__ long int
+// TCE:#define __INTMAX_WIDTH__ 32
// TCE:#define __INTPTR_TYPE__ int
+// TCE:#define __INTPTR_WIDTH__ 32
// TCE:#define __INT_MAX__ 2147483647
// TCE:#define __LDBL_DENORM_MIN__ 1.40129846e-45F
// TCE:#define __LDBL_DIG__ 6
@@ -854,7 +855,6 @@
// TCE:#define __SIZE_TYPE__ unsigned int
// TCE:#define __TCE_V1__ 1
// TCE:#define __TCE__ 1
-// TCE:#define __UINTMAX_TYPE__ long unsigned int
// TCE:#define __USER_LABEL_PREFIX__ _
// TCE:#define __WCHAR_MAX__ 2147483647
// TCE:#define __WCHAR_TYPE__ int
@@ -902,8 +902,9 @@
// X86_64:#define __INT64_TYPE__ long int
// X86_64:#define __INT8_TYPE__ char
// X86_64:#define __INTMAX_MAX__ 9223372036854775807L
-// X86_64:#define __INTMAX_TYPE__ long int
+// X86_64:#define __INTMAX_WIDTH__ 64
// X86_64:#define __INTPTR_TYPE__ long int
+// X86_64:#define __INTPTR_WIDTH__ 64
// X86_64:#define __INT_MAX__ 2147483647
// X86_64:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
// X86_64:#define __LDBL_DIG__ 18
@@ -935,7 +936,6 @@
// X86_64:#define __SSE2__ 1
// X86_64:#define __SSE_MATH__ 1
// X86_64:#define __SSE__ 1
-// X86_64:#define __UINTMAX_TYPE__ long unsigned int
// X86_64:#define __USER_LABEL_PREFIX__ _
// X86_64:#define __WCHAR_MAX__ 2147483647
// X86_64:#define __WCHAR_TYPE__ int
diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c
index 641f704e51d9..9c98e291664c 100644
--- a/test/Preprocessor/stdint.c
+++ b/test/Preprocessor/stdint.c
@@ -28,11 +28,11 @@
// ARM:typedef int8_t int_fast8_t;
// ARM:typedef uint8_t uint_fast8_t;
//
-// ARM:typedef long int intptr_t;
-// ARM:typedef unsigned long int uintptr_t;
+// ARM:typedef int32_t intptr_t;
+// ARM:typedef uint32_t uintptr_t;
//
-// ARM:typedef long long int intmax_t;
-// ARM:typedef long long unsigned int uintmax_t;
+// ARM:typedef int64_t intmax_t;
+// ARM:typedef uint64_t uintmax_t;
//
// ARM:INT8_MAX_ 127
// ARM:INT8_MIN_ (-127 -1)
@@ -83,7 +83,7 @@
//
// ARM:INTMAX_MIN_ (-9223372036854775807LL -1)
// ARM:INTMAX_MAX_ 9223372036854775807LL
-// ARM:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
+// ARM:UINTMAX_MAX_ 18446744073709551615ULL
//
// ARM:SIG_ATOMIC_MIN_ (-2147483647 -1)
// ARM:SIG_ATOMIC_MAX_ 2147483647
@@ -136,11 +136,11 @@
// BFIN:typedef int8_t int_fast8_t;
// BFIN:typedef uint8_t uint_fast8_t;
//
-// BFIN:typedef long int intptr_t;
-// BFIN:typedef unsigned long int uintptr_t;
+// BFIN:typedef int32_t intptr_t;
+// BFIN:typedef uint32_t uintptr_t;
//
-// BFIN:typedef long long int intmax_t;
-// BFIN:typedef long long unsigned int uintmax_t;
+// BFIN:typedef int64_t intmax_t;
+// BFIN:typedef uint64_t uintmax_t;
//
// BFIN:INT8_MAX_ 127
// BFIN:INT8_MIN_ (-127 -1)
@@ -191,7 +191,7 @@
//
// BFIN:INTMAX_MIN_ (-9223372036854775807LL -1)
// BFIN:INTMAX_MAX_ 9223372036854775807LL
-// BFIN:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
+// BFIN:UINTMAX_MAX_ 18446744073709551615ULL
//
// BFIN:SIG_ATOMIC_MIN_ (-2147483647 -1)
// BFIN:SIG_ATOMIC_MAX_ 2147483647
@@ -244,11 +244,11 @@
// I386:typedef int8_t int_fast8_t;
// I386:typedef uint8_t uint_fast8_t;
//
-// I386:typedef int intptr_t;
-// I386:typedef unsigned int uintptr_t;
+// I386:typedef int32_t intptr_t;
+// I386:typedef uint32_t uintptr_t;
//
-// I386:typedef long long int intmax_t;
-// I386:typedef long long unsigned int uintmax_t;
+// I386:typedef int64_t intmax_t;
+// I386:typedef uint64_t uintmax_t;
//
// I386:INT8_MAX_ 127
// I386:INT8_MIN_ (-127 -1)
@@ -299,7 +299,7 @@
//
// I386:INTMAX_MIN_ (-9223372036854775807LL -1)
// I386:INTMAX_MAX_ 9223372036854775807LL
-// I386:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
+// I386:UINTMAX_MAX_ 18446744073709551615ULL
//
// I386:SIG_ATOMIC_MIN_ (-2147483647 -1)
// I386:SIG_ATOMIC_MAX_ 2147483647
@@ -344,11 +344,11 @@
// MSP430:typedef int8_t int_fast8_t;
// MSP430:typedef uint8_t uint_fast8_t;
//
-// MSP430:typedef short intptr_t;
-// MSP430:typedef unsigned short uintptr_t;
+// MSP430:typedef int16_t intptr_t;
+// MSP430:typedef uint16_t uintptr_t;
//
-// MSP430:typedef long int intmax_t;
-// MSP430:typedef long unsigned int uintmax_t;
+// MSP430:typedef int32_t intmax_t;
+// MSP430:typedef uint32_t uintmax_t;
//
// MSP430:INT8_MAX_ 127
// MSP430:INT8_MIN_ (-127 -1)
@@ -399,7 +399,7 @@
//
// MSP430:INTMAX_MIN_ (-2147483647L -1)
// MSP430:INTMAX_MAX_ 2147483647L
-// MSP430:UINTMAX_MAX_ (2147483647L*2ULL +1ULL)
+// MSP430:UINTMAX_MAX_ 4294967295UL
//
// MSP430:SIG_ATOMIC_MIN_ (-2147483647L -1)
// MSP430:SIG_ATOMIC_MAX_ 2147483647L
@@ -418,8 +418,8 @@
// MSP430:INT64_C_(0) INT64_C(0)
// MSP430:UINT64_C_(0) UINT64_C(0)
//
-// MSP430:INTMAX_C_(0) 0LL
-// MSP430:UINTMAX_C_(0) 0ULL
+// MSP430:INTMAX_C_(0) 0L
+// MSP430:UINTMAX_C_(0) 0UL
//
// RUN: clang-cc -E -ffreestanding -triple=pic16-none-none %s | FileCheck -check-prefix PIC16 %s
//
@@ -444,11 +444,11 @@
// PIC16:typedef int8_t int_fast8_t;
// PIC16:typedef uint8_t uint_fast8_t;
//
-// PIC16:typedef short intptr_t;
-// PIC16:typedef unsigned short uintptr_t;
+// PIC16:typedef int16_t intptr_t;
+// PIC16:typedef uint16_t uintptr_t;
//
-// PIC16:typedef long int intmax_t;
-// PIC16:typedef long unsigned int uintmax_t;
+// PIC16:typedef int32_t intmax_t;
+// PIC16:typedef uint32_t uintmax_t;
//
// PIC16:INT8_MAX_ 127
// PIC16:INT8_MIN_ (-127 -1)
@@ -499,7 +499,7 @@
//
// PIC16:INTMAX_MIN_ (-2147483647L -1)
// PIC16:INTMAX_MAX_ 2147483647L
-// PIC16:UINTMAX_MAX_ (2147483647L*2ULL +1ULL)
+// PIC16:UINTMAX_MAX_ 4294967295UL
//
// PIC16:SIG_ATOMIC_MIN_ (-2147483647L -1)
// PIC16:SIG_ATOMIC_MAX_ 2147483647L
@@ -518,8 +518,8 @@
// PIC16:INT64_C_(0) INT64_C(0)
// PIC16:UINT64_C_(0) UINT64_C(0)
//
-// PIC16:INTMAX_C_(0) 0LL
-// PIC16:UINTMAX_C_(0) 0ULL
+// PIC16:INTMAX_C_(0) 0L
+// PIC16:UINTMAX_C_(0) 0UL
//
// RUN: clang-cc -E -ffreestanding -triple=powerpc64-none-none %s | FileCheck -check-prefix PPC64 %s
//
@@ -551,11 +551,11 @@
// PPC64:typedef int8_t int_fast8_t;
// PPC64:typedef uint8_t uint_fast8_t;
//
-// PPC64:typedef long int intptr_t;
-// PPC64:typedef unsigned long int uintptr_t;
+// PPC64:typedef int64_t intptr_t;
+// PPC64:typedef uint64_t uintptr_t;
//
-// PPC64:typedef long int intmax_t;
-// PPC64:typedef long unsigned int uintmax_t;
+// PPC64:typedef int64_t intmax_t;
+// PPC64:typedef uint64_t uintmax_t;
//
// PPC64:INT8_MAX_ 127
// PPC64:INT8_MIN_ (-127 -1)
@@ -606,7 +606,7 @@
//
// PPC64:INTMAX_MIN_ (-9223372036854775807L -1)
// PPC64:INTMAX_MAX_ 9223372036854775807L
-// PPC64:UINTMAX_MAX_ (9223372036854775807L*2ULL +1ULL)
+// PPC64:UINTMAX_MAX_ 18446744073709551615UL
//
// PPC64:SIG_ATOMIC_MIN_ (-2147483647 -1)
// PPC64:SIG_ATOMIC_MAX_ 2147483647
@@ -625,8 +625,8 @@
// PPC64:INT64_C_(0) 0L
// PPC64:UINT64_C_(0) 0UL
//
-// PPC64:INTMAX_C_(0) 0LL
-// PPC64:UINTMAX_C_(0) 0ULL
+// PPC64:INTMAX_C_(0) 0L
+// PPC64:UINTMAX_C_(0) 0UL
//
// RUN: clang-cc -E -ffreestanding -triple=powerpc-none-none %s | FileCheck -check-prefix PPC %s
//
@@ -659,11 +659,11 @@
// PPC:typedef int8_t int_fast8_t;
// PPC:typedef uint8_t uint_fast8_t;
//
-// PPC:typedef long int intptr_t;
-// PPC:typedef unsigned long int uintptr_t;
+// PPC:typedef int32_t intptr_t;
+// PPC:typedef uint32_t uintptr_t;
//
-// PPC:typedef long long int intmax_t;
-// PPC:typedef long long unsigned int uintmax_t;
+// PPC:typedef int64_t intmax_t;
+// PPC:typedef uint64_t uintmax_t;
//
// PPC:INT8_MAX_ 127
// PPC:INT8_MIN_ (-127 -1)
@@ -714,7 +714,7 @@
//
// PPC:INTMAX_MIN_ (-9223372036854775807LL -1)
// PPC:INTMAX_MAX_ 9223372036854775807LL
-// PPC:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
+// PPC:UINTMAX_MAX_ 18446744073709551615ULL
//
// PPC:SIG_ATOMIC_MIN_ (-2147483647 -1)
// PPC:SIG_ATOMIC_MAX_ 2147483647
@@ -766,11 +766,11 @@
// S390X:typedef int8_t int_fast8_t;
// S390X:typedef uint8_t uint_fast8_t;
//
-// S390X:typedef long int intptr_t;
-// S390X:typedef unsigned long int uintptr_t;
+// S390X:typedef int64_t intptr_t;
+// S390X:typedef uint64_t uintptr_t;
//
-// S390X:typedef long long int intmax_t;
-// S390X:typedef long long unsigned int uintmax_t;
+// S390X:typedef int64_t intmax_t;
+// S390X:typedef uint64_t uintmax_t;
//
// S390X:INT8_MAX_ 127
// S390X:INT8_MIN_ (-127 -1)
@@ -819,9 +819,9 @@
// S390X:PTRDIFF_MAX_ 9223372036854775807L
// S390X:SIZE_MAX_ 18446744073709551615UL
//
-// S390X:INTMAX_MIN_ (-9223372036854775807LL -1)
-// S390X:INTMAX_MAX_ 9223372036854775807LL
-// S390X:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
+// S390X:INTMAX_MIN_ (-9223372036854775807L -1)
+// S390X:INTMAX_MAX_ 9223372036854775807L
+// S390X:UINTMAX_MAX_ 18446744073709551615UL
//
// S390X:SIG_ATOMIC_MIN_ (-2147483647 -1)
// S390X:SIG_ATOMIC_MAX_ 2147483647
@@ -840,8 +840,8 @@
// S390X:INT64_C_(0) 0L
// S390X:UINT64_C_(0) 0UL
//
-// S390X:INTMAX_C_(0) 0LL
-// S390X:UINTMAX_C_(0) 0ULL
+// S390X:INTMAX_C_(0) 0L
+// S390X:UINTMAX_C_(0) 0UL
//
// RUN: clang-cc -E -ffreestanding -triple=sparc-none-none %s | FileCheck -check-prefix SPARC %s
//
@@ -873,11 +873,11 @@
// SPARC:typedef int8_t int_fast8_t;
// SPARC:typedef uint8_t uint_fast8_t;
//
-// SPARC:typedef long int intptr_t;
-// SPARC:typedef unsigned long int uintptr_t;
+// SPARC:typedef int32_t intptr_t;
+// SPARC:typedef uint32_t uintptr_t;
//
-// SPARC:typedef long long int intmax_t;
-// SPARC:typedef long long unsigned int uintmax_t;
+// SPARC:typedef int64_t intmax_t;
+// SPARC:typedef uint64_t uintmax_t;
//
// SPARC:INT8_MAX_ 127
// SPARC:INT8_MIN_ (-127 -1)
@@ -928,7 +928,7 @@
//
// SPARC:INTMAX_MIN_ (-9223372036854775807LL -1)
// SPARC:INTMAX_MAX_ 9223372036854775807LL
-// SPARC:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
+// SPARC:UINTMAX_MAX_ 18446744073709551615ULL
//
// SPARC:SIG_ATOMIC_MIN_ (-2147483647 -1)
// SPARC:SIG_ATOMIC_MAX_ 2147483647
@@ -973,11 +973,11 @@
// TCE:typedef int8_t int_fast8_t;
// TCE:typedef uint8_t uint_fast8_t;
//
-// TCE:typedef int intptr_t;
-// TCE:typedef unsigned int uintptr_t;
+// TCE:typedef int32_t intptr_t;
+// TCE:typedef uint32_t uintptr_t;
//
-// TCE:typedef long int intmax_t;
-// TCE:typedef long unsigned int uintmax_t;
+// TCE:typedef int32_t intmax_t;
+// TCE:typedef uint32_t uintmax_t;
//
// TCE:INT8_MAX_ 127
// TCE:INT8_MIN_ (-127 -1)
@@ -1026,9 +1026,9 @@
// TCE:PTRDIFF_MAX_ 2147483647
// TCE:SIZE_MAX_ 4294967295U
//
-// TCE:INTMAX_MIN_ (-2147483647L -1)
-// TCE:INTMAX_MAX_ 2147483647L
-// TCE:UINTMAX_MAX_ (2147483647L*2ULL +1ULL)
+// TCE:INTMAX_MIN_ (-2147483647 -1)
+// TCE:INTMAX_MAX_ 2147483647
+// TCE:UINTMAX_MAX_ 4294967295U
//
// TCE:SIG_ATOMIC_MIN_ (-2147483647 -1)
// TCE:SIG_ATOMIC_MAX_ 2147483647
@@ -1047,8 +1047,8 @@
// TCE:INT64_C_(0) INT64_C(0)
// TCE:UINT64_C_(0) UINT64_C(0)
//
-// TCE:INTMAX_C_(0) 0LL
-// TCE:UINTMAX_C_(0) 0ULL
+// TCE:INTMAX_C_(0) 0
+// TCE:UINTMAX_C_(0) 0U
//
// RUN: clang-cc -E -ffreestanding -triple=x86_64-none-none %s | FileCheck -check-prefix X86_64 %s
//
@@ -1081,11 +1081,11 @@
// X86_64:typedef int8_t int_fast8_t;
// X86_64:typedef uint8_t uint_fast8_t;
//
-// X86_64:typedef long int intptr_t;
-// X86_64:typedef unsigned long int uintptr_t;
+// X86_64:typedef int64_t intptr_t;
+// X86_64:typedef uint64_t uintptr_t;
//
-// X86_64:typedef long int intmax_t;
-// X86_64:typedef long unsigned int uintmax_t;
+// X86_64:typedef int64_t intmax_t;
+// X86_64:typedef uint64_t uintmax_t;
//
// X86_64:INT8_MAX_ 127
// X86_64:INT8_MIN_ (-127 -1)
@@ -1136,7 +1136,7 @@
//
// X86_64:INTMAX_MIN_ (-9223372036854775807L -1)
// X86_64:INTMAX_MAX_ 9223372036854775807L
-// X86_64:UINTMAX_MAX_ (9223372036854775807L*2ULL +1ULL)
+// X86_64:UINTMAX_MAX_ 18446744073709551615UL
//
// X86_64:SIG_ATOMIC_MIN_ (-2147483647 -1)
// X86_64:SIG_ATOMIC_MAX_ 2147483647
@@ -1155,8 +1155,8 @@
// X86_64:INT64_C_(0) 0L
// X86_64:UINT64_C_(0) 0UL
//
-// X86_64:INTMAX_C_(0) 0LL
-// X86_64:UINTMAX_C_(0) 0ULL
+// X86_64:INTMAX_C_(0) 0L
+// X86_64:UINTMAX_C_(0) 0UL
//
#include <stdint.h>
diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c
index acf488706f7e..522fda42a169 100644
--- a/test/Sema/unused-expr.c
+++ b/test/Sema/unused-expr.c
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify -fmath-errno=0 %s
+// RUN: clang-cc -fsyntax-only -verify -fno-math-errno %s
int foo(int X, int Y);
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index 42b8d7febe65..3db607a365c0 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -138,3 +138,20 @@ namespace PR5222 {
C c;
}
+
+// PR5550 - instantiating template didn't track overridden methods
+namespace PR5550 {
+ struct A {
+ virtual void a() = 0;
+ virtual void b() = 0;
+ };
+ template<typename T> struct B : public A {
+ virtual void b();
+ virtual void c() = 0;
+ };
+ struct C : public B<int> {
+ virtual void a();
+ virtual void c();
+ };
+ C x;
+}
diff --git a/test/SemaCXX/cxx-member-pointer-op.cpp b/test/SemaCXX/cxx-member-pointer-op.cpp
new file mode 100644
index 000000000000..63b29c723e07
--- /dev/null
+++ b/test/SemaCXX/cxx-member-pointer-op.cpp
@@ -0,0 +1,21 @@
+// RUN: clang-cc -fsyntax-only -pedantic -verify %s
+
+struct C {
+ static int (C::* a);
+};
+
+typedef void (C::*pmfc)();
+
+void g(pmfc) {
+ C *c;
+ c->*pmfc(); // expected-error {{invalid use of pointer to member type after ->*}}
+ C c1;
+ c1.*pmfc(); // expected-error {{invalid use of pointer to member type after .*}}
+ c->*(pmfc()); // expected-error {{invalid use of pointer to member type after ->*}}
+ c1.*((pmfc())); // expected-error {{invalid use of pointer to member type after .*}}
+}
+
+int a(C* x) {
+ return x->*C::a;
+}
+
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 7762667d1aba..16d37040f140 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -286,3 +286,41 @@ class RegAlloc {
}
int usepri[LastReg + 1];
};
+
+// PR5546: Don't generate incorrect and ambiguous overloads for multi-level
+// arrays.
+namespace pr5546
+{
+ enum { X };
+ extern const char *const sMoveCommands[][2][2];
+ const char* a() { return sMoveCommands[X][0][0]; }
+ const char* b() { return (*(sMoveCommands+X))[0][0]; }
+}
+
+// PR5512 and its discussion
+namespace pr5512 {
+ struct Y {
+ operator short();
+ operator float();
+ };
+ void g_test(Y y) {
+ short s = 0;
+ // DR507, this should be ambiguous, but we special-case assignment
+ s = y;
+ // Note: DR507, this is ambiguous as specified
+ //s += y;
+ }
+
+ struct S {};
+ void operator +=(int&, S);
+ void f(S s) {
+ int i = 0;
+ i += s;
+ }
+
+ struct A {operator int();};
+ int a;
+ void b(A x) {
+ a += x;
+ }
+}
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index 91b72cc02207..be960a3af8b5 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -88,3 +88,9 @@ void memptrs()
(void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (struct structure::*)()' is not allowed}}
(void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int struct structure::*' is not allowed}}
}
+
+// PR5545
+class A;
+class B;
+void (A::*a)();
+void (B::*b)() = reinterpret_cast<void (B::*)()>(a);
diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp
index a7d26bb4b0e1..5132c2a69beb 100644
--- a/test/SemaCXX/rval-references.cpp
+++ b/test/SemaCXX/rval-references.cpp
@@ -65,9 +65,9 @@ int&& should_not_warn(int&& i) { // But GCC 4.4 does
// Test the return dance. This also tests IsReturnCopyElidable.
struct MoveOnly {
MoveOnly();
- MoveOnly(const MoveOnly&) = delete;
- MoveOnly(MoveOnly&&);
- MoveOnly(int&&);
+ MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate function}}
+ MoveOnly(MoveOnly&&); // expected-note {{candidate function}}
+ MoveOnly(int&&); // expected-note {{candidate function}}
};
MoveOnly returning() {
@@ -87,5 +87,5 @@ MoveOnly returningNonEligible() {
else if (0) // Copy from reference can't be elided
return r; // expected-error {{incompatible type returning}}
else // Construction from different type can't be elided
- return i; // expected-error {{incompatible type returning}}
+ return i; // expected-error {{no viable conversion from 'int' to 'struct MoveOnly'}}
}
diff --git a/test/SemaCXX/using-directive.cpp b/test/SemaCXX/using-directive.cpp
index 78ad04293bf4..3b67c7a5b61f 100644
--- a/test/SemaCXX/using-directive.cpp
+++ b/test/SemaCXX/using-directive.cpp
@@ -45,22 +45,18 @@ namespace A {
using namespace E; // expected-error{{reference to 'E' is ambiguous}}
}
- struct K2 {}; // expected-note{{candidate found by name lookup is 'A::K2'}}
+ struct K2 {}; // expected-note 2{{candidate found by name lookup is 'A::K2'}}
}
-struct K2 {}; // expected-note{{candidate found by name lookup is 'K2'}}
+struct K2 {}; // expected-note 2{{candidate found by name lookup is 'K2'}}
using namespace A;
void K1::foo() {} // okay
-// FIXME: Do we want err_ovl_no_viable_function_in_init here?
-struct K2 k2; // expected-error{{reference to 'K2' is ambiguous}} \
- expected-error{{incomplete type}}
-
-// FIXME: This case is incorrectly diagnosed!
-//K2 k3;
+struct K2 *k2; // expected-error{{reference to 'K2' is ambiguous}}
+K2 *k3; // expected-error{{reference to 'K2' is ambiguous}}
class X { // expected-note{{candidate found by name lookup is 'X'}}
// FIXME: produce a suitable error message for this
diff --git a/test/SemaObjC/class-protocol.m b/test/SemaObjC/class-protocol.m
new file mode 100644
index 000000000000..12b638175137
--- /dev/null
+++ b/test/SemaObjC/class-protocol.m
@@ -0,0 +1,6 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+// pr5552
+
+@interface Protocol
+@end
+
diff --git a/test/SemaObjC/no-warn-qual-mismatch.m b/test/SemaObjC/no-warn-qual-mismatch.m
new file mode 100644
index 000000000000..3bd4dba545f5
--- /dev/null
+++ b/test/SemaObjC/no-warn-qual-mismatch.m
@@ -0,0 +1,16 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+// radar 7211563
+
+@interface X
+
++ (void)prototypeWithScalar:(int)aParameter;
++ (void)prototypeWithPointer:(void *)aParameter;
+
+@end
+
+@implementation X
+
++ (void)prototypeWithScalar:(const int)aParameter {}
++ (void)prototypeWithPointer:(void * const)aParameter {}
+
+@end
diff --git a/test/SemaTemplate/constructor-template.cpp b/test/SemaTemplate/constructor-template.cpp
index 12c6f8b9c101..203977e9edd7 100644
--- a/test/SemaTemplate/constructor-template.cpp
+++ b/test/SemaTemplate/constructor-template.cpp
@@ -53,7 +53,7 @@ struct B { A<int> x; B(B& a) : x(a.x) {} };
struct X2 {
X2();
- X2(X2&);
+ X2(X2&); // expected-note {{candidate function}}
template<typename T> X2(T);
};
@@ -61,7 +61,7 @@ X2 test(bool Cond, X2 x2) {
if (Cond)
return x2; // okay, uses copy constructor
- return X2(); // expected-error{{incompatible type}}
+ return X2(); // expected-error{{no viable conversion from 'struct X2' to 'struct X2' is possible}}
}
struct X3 {
@@ -73,12 +73,12 @@ template<> X3::X3(X3); // expected-error{{must pass its first argument by refere
struct X4 {
X4();
~X4();
- X4(X4&);
+ X4(X4&); // expected-note {{candidate function}}
template<typename T> X4(const T&, int = 17);
};
X4 test_X4(bool Cond, X4 x4) {
X4 a(x4, 17); // okay, constructor template
X4 b(x4); // okay, copy constructor
- return X4(); // expected-error{{incompatible type}}
+ return X4(); // expected-error{{no viable conversion}}
}
diff --git a/test/SemaTemplate/instantiate-case.cpp b/test/SemaTemplate/instantiate-case.cpp
new file mode 100644
index 000000000000..bed39d7ffb06
--- /dev/null
+++ b/test/SemaTemplate/instantiate-case.cpp
@@ -0,0 +1,21 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<class T>
+static int alpha(T c)
+{
+ return *c; // expected-error{{indirection requires pointer operand}}
+}
+
+template<class T>
+static void
+_shexp_match()
+{
+ switch(1) {
+ case 1:
+ alpha(1); // expected-note{{instantiation of function template}}
+ }
+}
+int main() {
+ _shexp_match<char>(); // expected-note{{instantiation of function template}}
+ return 0;
+}
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index ebdba29d92fb..46732de785bb 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -1219,7 +1219,7 @@ void clang_codeComplete(CXIndex CIdx,
argv.push_back("-Xclang");
argv.push_back(code_complete_at.c_str());
argv.push_back("-Xclang");
- argv.push_back("-code-completion-debug-printer=0");
+ argv.push_back("-no-code-completion-debug-printer");
// Add the source file name (FIXME: later, we'll want to build temporary
// file from the buffer, or just feed the source text via standard input).
diff --git a/tools/clang-cc/Options.cpp b/tools/clang-cc/Options.cpp
index b5190ebcae54..584f95709519 100644
--- a/tools/clang-cc/Options.cpp
+++ b/tools/clang-cc/Options.cpp
@@ -100,14 +100,12 @@ AnalyzeSpecificFunction("analyze-function",
static llvm::cl::opt<bool>
EagerlyAssume("analyzer-eagerly-assume",
- llvm::cl::init(false),
llvm::cl::desc("Eagerly assume the truth/falseness of some "
"symbolic constraints"));
static llvm::cl::opt<bool>
-PurgeDead("analyzer-purge-dead",
- llvm::cl::init(true),
- llvm::cl::desc("Remove dead symbols, bindings, and constraints before"
+NoPurgeDead("analyzer-no-purge-dead",
+ llvm::cl::desc("Don't remove dead symbols, bindings, and constraints before"
" processing a statement"));
static llvm::cl::opt<bool>
@@ -136,8 +134,7 @@ DisableLLVMOptimizations("disable-llvm-optzns",
static llvm::cl::opt<bool>
DisableRedZone("disable-red-zone",
- llvm::cl::desc("Do not emit code that uses the red zone."),
- llvm::cl::init(false));
+ llvm::cl::desc("Do not emit code that uses the red zone."));
static llvm::cl::opt<bool>
GenerateDebugInfo("g",
@@ -150,8 +147,7 @@ NoCommon("fno-common",
static llvm::cl::opt<bool>
NoImplicitFloat("no-implicit-float",
- llvm::cl::desc("Don't generate implicit floating point instructions (x86-only)"),
- llvm::cl::init(false));
+ llvm::cl::desc("Don't generate implicit floating point instructions (x86-only)"));
static llvm::cl::opt<bool>
NoMergeConstants("fno-merge-all-constants",
@@ -170,8 +166,7 @@ struct OptLevelParser : public llvm::cl::parser<unsigned> {
};
static llvm::cl::opt<unsigned, false, OptLevelParser>
OptLevel("O", llvm::cl::Prefix,
- llvm::cl::desc("Optimization level"),
- llvm::cl::init(0));
+ llvm::cl::desc("Optimization level"));
static llvm::cl::opt<bool>
OptSize("Os", llvm::cl::desc("Optimize for size"));
@@ -264,7 +259,7 @@ PrintColorDiagnostic("fcolor-diagnostics",
llvm::cl::desc("Use colors in diagnostics"));
static llvm::cl::opt<bool>
-SilenceRewriteMacroWarning("Wno-rewrite-macros", llvm::cl::init(false),
+SilenceRewriteMacroWarning("Wno-rewrite-macros",
llvm::cl::desc("Silence ObjC rewriting warnings"));
static llvm::cl::opt<bool>
@@ -287,9 +282,8 @@ CodeCompletionAt("code-completion-at",
llvm::cl::desc("Dump code-completion information at a location"));
static llvm::cl::opt<bool>
-CodeCompletionDebugPrinter("code-completion-debug-printer",
- llvm::cl::desc("Use the \"debug\" code-completion print"),
- llvm::cl::init(true));
+NoCodeCompletionDebugPrinter("no-code-completion-debug-printer",
+ llvm::cl::desc("Don't the \"debug\" code-completion print"));
static llvm::cl::opt<bool>
CodeCompletionWantsMacros("code-completion-macros",
@@ -297,8 +291,7 @@ CodeCompletionWantsMacros("code-completion-macros",
static llvm::cl::opt<bool>
DisableFree("disable-free",
- llvm::cl::desc("Disable freeing of memory on exit"),
- llvm::cl::init(false));
+ llvm::cl::desc("Disable freeing of memory on exit"));
static llvm::cl::opt<bool>
EmptyInputOnly("empty-input-only",
@@ -444,12 +437,11 @@ TimeReport("ftime-report",
namespace langoptions {
static llvm::cl::opt<bool>
-AllowBuiltins("fbuiltin", llvm::cl::init(true),
- llvm::cl::desc("Disable implicit builtin knowledge of functions"));
+NoBuiltin("fno-builtin",
+ llvm::cl::desc("Disable implicit builtin knowledge of functions"));
static llvm::cl::opt<bool>
-AltiVec("faltivec", llvm::cl::desc("Enable AltiVec vector initializer syntax"),
- llvm::cl::init(false));
+AltiVec("faltivec", llvm::cl::desc("Enable AltiVec vector initializer syntax"));
static llvm::cl::opt<bool>
AccessControl("faccess-control",
@@ -537,8 +529,8 @@ MainFileName("main-file-name",
llvm::cl::desc("Main file name to use for debug info"));
static llvm::cl::opt<bool>
-MathErrno("fmath-errno", llvm::cl::init(true),
- llvm::cl::desc("Require math functions to respect errno"));
+NoMathErrno("fno-math-errno",
+ llvm::cl::desc("Don't require math functions to respect errno"));
static llvm::cl::opt<bool>
NoElideConstructors("fno-elide-constructors",
@@ -581,15 +573,13 @@ ObjCNonFragileABI("fobjc-nonfragile-abi",
static llvm::cl::opt<bool>
OverflowChecking("ftrapv",
- llvm::cl::desc("Trap on integer overflow"),
- llvm::cl::init(false));
+ llvm::cl::desc("Trap on integer overflow"));
static llvm::cl::opt<unsigned>
PICLevel("pic-level", llvm::cl::desc("Value for __PIC__"));
static llvm::cl::opt<bool>
-PThread("pthread", llvm::cl::desc("Support POSIX threads in generated code"),
- llvm::cl::init(false));
+PThread("pthread", llvm::cl::desc("Support POSIX threads in generated code"));
static llvm::cl::opt<bool>
PascalStrings("fpascal-strings",
@@ -597,8 +587,8 @@ PascalStrings("fpascal-strings",
"string literals"));
static llvm::cl::opt<bool>
-Rtti("frtti", llvm::cl::init(true),
- llvm::cl::desc("Enable generation of rtti information"));
+NoRtti("fno-rtti",
+ llvm::cl::desc("Disable generation of rtti information"));
static llvm::cl::opt<bool>
ShortWChar("fshort-wchar",
@@ -609,8 +599,7 @@ StaticDefine("static-define", llvm::cl::desc("Should __STATIC__ be defined"));
static llvm::cl::opt<int>
StackProtector("stack-protector",
- llvm::cl::desc("Enable stack protectors"),
- llvm::cl::init(-1));
+ llvm::cl::desc("Enable stack protectors"));
static llvm::cl::opt<LangOptions::VisibilityMode>
SymbolVisibility("fvisibility",
@@ -625,7 +614,7 @@ SymbolVisibility("fvisibility",
clEnumValEnd));
static llvm::cl::opt<unsigned>
-TemplateDepth("ftemplate-depth", llvm::cl::init(99),
+TemplateDepth("ftemplate-depth",
llvm::cl::desc("Maximum depth of recursive template "
"instantiation"));
@@ -724,7 +713,7 @@ iwithprefixbefore_vals("iwithprefixbefore", llvm::cl::value_desc("dir"),
llvm::cl::desc("Set directory to include search path with prefix"));
static llvm::cl::opt<std::string>
-isysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::init("/"),
+isysroot("isysroot", llvm::cl::value_desc("dir"),
llvm::cl::desc("Set the system root directory (usually /)"));
static llvm::cl::opt<bool>
@@ -793,7 +782,7 @@ void clang::InitializeAnalyzerOptions(AnalyzerOptions &Opts) {
Opts.VisualizeEGUbi = VisualizeEGUbi;
Opts.AnalyzeAll = AnalyzeAll;
Opts.AnalyzerDisplayProgress = AnalyzerDisplayProgress;
- Opts.PurgeDead = PurgeDead;
+ Opts.PurgeDead = !NoPurgeDead;
Opts.EagerlyAssume = EagerlyAssume;
Opts.AnalyzeSpecificFunction = AnalyzeSpecificFunction;
Opts.EnableExperimentalChecks = AnalyzerExperimentalChecks;
@@ -807,7 +796,8 @@ void clang::InitializeCodeGenOptions(CodeGenOptions &Opts,
using namespace codegenoptions;
// -Os implies -O2
- Opts.OptimizationLevel = OptSize ? 2 : OptLevel;
+ unsigned Opt = OptLevel.getPosition() ? OptLevel : 0;
+ Opts.OptimizationLevel = OptSize ? 2 : Opt;
// We must always run at least the always inlining pass.
Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
@@ -875,7 +865,7 @@ void clang::InitializeFrontendOptions(FrontendOptions &Opts) {
}
Opts.CodeCompletionAt = CodeCompletionAt;
- Opts.DebugCodeCompletionPrinter = CodeCompletionDebugPrinter;
+ Opts.DebugCodeCompletionPrinter = !NoCodeCompletionDebugPrinter;
Opts.DisableFree = DisableFree;
Opts.EmptyInputOnly = EmptyInputOnly;
Opts.FixItLocations = FixItAtLocations;
@@ -907,7 +897,8 @@ void clang::InitializeHeaderSearchOptions(HeaderSearchOptions &Opts,
llvm::StringRef BuiltinIncludePath) {
using namespace headersearchoptions;
- Opts.Sysroot = isysroot;
+ if (isysroot.getPosition())
+ Opts.Sysroot = isysroot;
Opts.Verbose = Verbose;
// Handle -I... and -F... options, walking the lists in parallel.
@@ -1231,7 +1222,7 @@ void clang::InitializeLangOptions(LangOptions &Options,
if (NoLaxVectorConversions.getPosition())
Options.LaxVectorConversions = 0;
Options.Exceptions = Exceptions;
- Options.Rtti = Rtti;
+ Options.Rtti = !NoRtti;
if (EnableBlocks.getPosition())
Options.Blocks = EnableBlocks;
if (CharIsSigned.getPosition())
@@ -1239,8 +1230,7 @@ void clang::InitializeLangOptions(LangOptions &Options,
if (ShortWChar.getPosition())
Options.ShortWChar = ShortWChar;
- if (!AllowBuiltins)
- Options.NoBuiltin = 1;
+ Options.NoBuiltin = NoBuiltin;
if (Freestanding)
Options.Freestanding = Options.NoBuiltin = 1;
@@ -1255,9 +1245,10 @@ void clang::InitializeLangOptions(LangOptions &Options,
// OpenCL and C++ both have bool, true, false keywords.
Options.Bool = Options.OpenCL | Options.CPlusPlus;
- Options.MathErrno = MathErrno;
+ Options.MathErrno = !NoMathErrno;
- Options.InstantiationDepth = TemplateDepth;
+ if (TemplateDepth.getPosition())
+ Options.InstantiationDepth = TemplateDepth;
// Override the default runtime if the user requested it.
if (GNURuntime)
@@ -1273,8 +1264,10 @@ void clang::InitializeLangOptions(LangOptions &Options,
Options.EmitAllDecls = 1;
// The __OPTIMIZE_SIZE__ define is tied to -Oz, which we don't support.
+ unsigned Opt =
+ codegenoptions::OptLevel.getPosition() ? codegenoptions::OptLevel : 0;
Options.OptimizeSize = 0;
- Options.Optimize = codegenoptions::OptSize || codegenoptions::OptLevel;
+ Options.Optimize = codegenoptions::OptSize || Opt;
assert(PICLevel <= 2 && "Invalid value for -pic-level");
Options.PICLevel = PICLevel;
@@ -1286,17 +1279,18 @@ void clang::InitializeLangOptions(LangOptions &Options,
// inlining enabled.
//
// FIXME: This is affected by other options (-fno-inline).
- Options.NoInline = !codegenoptions::OptLevel;
+ Options.NoInline = !Opt;
Options.Static = StaticDefine;
- switch (StackProtector) {
- default:
- assert(StackProtector <= 2 && "Invalid value for -stack-protector");
- case -1: break;
- case 0: Options.setStackProtectorMode(LangOptions::SSPOff); break;
- case 1: Options.setStackProtectorMode(LangOptions::SSPOn); break;
- case 2: Options.setStackProtectorMode(LangOptions::SSPReq); break;
+ if (StackProtector.getPosition()) {
+ switch (StackProtector) {
+ default:
+ assert(0 && "Invalid value for -stack-protector");
+ case 0: Options.setStackProtectorMode(LangOptions::SSPOff); break;
+ case 1: Options.setStackProtectorMode(LangOptions::SSPOn); break;
+ case 2: Options.setStackProtectorMode(LangOptions::SSPReq); break;
+ }
}
if (MainFileName.getPosition())
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 1ad04c8dfde4..1a9538013e1b 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -3,15 +3,27 @@ set(LLVM_NO_RTTI 1)
set( LLVM_USED_LIBS
clangDriver
clangBasic
+ clangFrontend
)
set(LLVM_LINK_COMPONENTS system support bitreader bitwriter)
add_clang_executable(clang
driver.cpp
+ cc1_main.cpp
)
add_dependencies(clang clang-cc)
+# Create the clang++ symlink in the build directory.
+add_custom_target(clang++ ALL
+ ${CMAKE_COMMAND} -E create_symlink
+ "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}"
+ "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}"
+ DEPENDS clang)
+
install(TARGETS clang
RUNTIME DESTINATION bin)
+
+# Create the clang++ symlink at installation time.
+install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink \"${CMAKE_INSTALL_PREFIX}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}\" \"${CMAKE_INSTALL_PREFIX}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX}\")")
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
index 4b2fb4423445..19f93a29fa1c 100644
--- a/tools/driver/Makefile
+++ b/tools/driver/Makefile
@@ -9,6 +9,7 @@
LEVEL = ../../../..
TOOLNAME = clang
+TOOLALIAS = clang++
CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
CXXFLAGS = -fno-rtti
@@ -18,7 +19,7 @@ TOOL_NO_EXPORTS = 1
# FIXME: It is unfortunate we need to pull in the bitcode reader and
# writer just to get the serializer stuff used by clangBasic.
LINK_COMPONENTS := system support bitreader bitwriter
-USEDLIBS = clangDriver.a clangBasic.a
+USEDLIBS = clangDriver.a clangBasic.a clangFrontend.a
include $(LEVEL)/Makefile.common
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
new file mode 100644
index 000000000000..c5163592b42a
--- /dev/null
+++ b/tools/driver/cc1_main.cpp
@@ -0,0 +1,88 @@
+//===-- cc1_main.cpp - Clang CC1 Driver -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the entry point to the clang -cc1 functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
+#include "clang/Driver/CC1Options.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Option.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
+#include <vector>
+
+using namespace clang;
+using namespace clang::driver;
+
+int cc1_main(Diagnostic &Diags, const char **ArgBegin, const char **ArgEnd) {
+ llvm::errs() << "cc1 argv:";
+ for (const char **i = ArgBegin; i != ArgEnd; ++i)
+ llvm::errs() << " \"" << *i << '"';
+ llvm::errs() << "\n";
+
+ // Parse the arguments.
+ OptTable *Opts = createCC1OptTable();
+ unsigned MissingArgIndex, MissingArgCount;
+ InputArgList *Args = Opts->ParseArgs(ArgBegin, ArgEnd,
+ MissingArgIndex, MissingArgCount);
+
+ // Check for missing argument error.
+ if (MissingArgCount)
+ Diags.Report(clang::diag::err_drv_missing_argument)
+ << Args->getArgString(MissingArgIndex) << MissingArgCount;
+
+ // Dump the parsed arguments.
+ llvm::errs() << "cc1 parsed options:\n";
+ for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
+ it != ie; ++it)
+ (*it)->dump();
+
+ // Create a compiler invocation.
+ llvm::errs() << "cc1 creating invocation.\n";
+ CompilerInvocation Invocation;
+ CompilerInvocation::CreateFromArgs(Invocation,
+ llvm::SmallVector<llvm::StringRef, 32>(ArgBegin, ArgEnd));
+
+ // Convert the invocation back to argument strings.
+ std::vector<std::string> InvocationArgs;
+ Invocation.toArgs(InvocationArgs);
+
+ // Dump the converted arguments.
+ llvm::SmallVector<llvm::StringRef, 32> Invocation2Args;
+ llvm::errs() << "invocation argv:";
+ for (unsigned i = 0, e = InvocationArgs.size(); i != e; ++i) {
+ Invocation2Args.push_back(InvocationArgs[i]);
+ llvm::errs() << " \"" << InvocationArgs[i] << '"';
+ }
+ llvm::errs() << "\n";
+
+ // Convert those arguments to another invocation, and check that we got the
+ // same thing.
+ CompilerInvocation Invocation2;
+ CompilerInvocation::CreateFromArgs(Invocation2, Invocation2Args);
+
+ // FIXME: Implement CompilerInvocation comparison.
+ if (memcmp(&Invocation, &Invocation2, sizeof(Invocation)) != 0) {
+ llvm::errs() << "warning: Invocations differ!\n";
+
+ std::vector<std::string> Invocation2Args;
+ Invocation2.toArgs(Invocation2Args);
+ llvm::errs() << "invocation argv:";
+ for (unsigned i = 0, e = Invocation2Args.size(); i != e; ++i)
+ llvm::errs() << " \"" << Invocation2Args[i] << '"';
+ llvm::errs() << "\n";
+ }
+
+ return 0;
+}
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index fb7c6cc7b032..dbfc29365561 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -15,7 +15,6 @@
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Option.h"
-#include "clang/Driver/Options.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/OwningPtr.h"
@@ -179,6 +178,9 @@ void ApplyQAOverride(std::vector<const char*> &Args, const char *OverrideStr,
}
}
+extern int cc1_main(Diagnostic &Diags,
+ const char **ArgBegin, const char **ArgEnd);
+
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc, argv);
@@ -188,6 +190,10 @@ int main(int argc, const char **argv) {
Diagnostic Diags(&DiagClient);
+ // Dispatch to cc1_main if appropriate.
+ if (argc > 1 && llvm::StringRef(argv[1]) == "-cc1")
+ return cc1_main(Diags, argv+2, argv+argc);
+
#ifdef CLANG_IS_PRODUCTION
bool IsProduction = true;
#else